vlan.c (538793B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: vlan.c 8 * Purpose: Provide low-level access to Triumph VLAN resources 9 */ 10 #include <sal/core/boot.h> 11 12 #include <soc/defs.h> 13 #if defined(BCM_TRX_SUPPORT) 14 #include <soc/drv.h> 15 #include <soc/hash.h> 16 #include <soc/mem.h> 17 #include <soc/profile_mem.h> 18 #include <shared/bsl.h> 19 #include <bcm/error.h> 20 #include <bcm/vlan.h> 21 #include <bcm/stg.h> 22 #include <bcm/port.h> 23 #include <bcm/trunk.h> 24 #include <bcm/stack.h> 25 26 #include <bcm_int/esw/mbcm.h> 27 #include <bcm_int/esw/triumph.h> 28 #include <bcm_int/esw/vlan.h> 29 #include <bcm_int/esw/stack.h> 30 #include <bcm_int/esw/xgs3.h> 31 #include <bcm_int/esw/trx.h> 32 #include <bcm_int/esw/port.h> 33 #if defined(BCM_TRIUMPH2_SUPPORT) 34 #include <bcm_int/esw/triumph2.h> 35 #endif /* BCM_TRIUMPH2_SUPPORT */ 36 37 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 38 defined(BCM_GREYHOUND2_SUPPORT) 39 #include <bcm_int/esw/policer.h> 40 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 41 BCM_GREYHOUND2_SUPPORT */ 42 #include <bcm_int/esw_dispatch.h> 43 44 #if defined(BCM_TRIDENT_SUPPORT) 45 #include <bcm_int/esw/trident.h> 46 #endif 47 48 #if defined(BCM_TRIDENT2_SUPPORT) 49 #include <bcm/fcoe.h> 50 #include <bcm_int/esw/trident2.h> 51 #endif 52 53 #if defined(BCM_TRIDENT3_SUPPORT) 54 #include <bcm_int/esw/trident3.h> 55 #include <soc/esw/flow_db.h> 56 #endif 57 58 #if defined(BCM_KATANA2_SUPPORT) 59 #include <bcm_int/esw/katana2.h> 60 #endif 61 62 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 63 #include <soc/td2_td2p.h> 64 #endif 65 66 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT)) && defined(INCLUDE_L3) 67 #include <bcm_int/esw/virtual.h> 68 #endif 69 70 #if defined(BCM_HGPROXY_COE_SUPPORT) 71 #include <bcm_int/esw/subport.h> 72 #include <bcm_int/esw/xgs5.h> 73 #endif /* BCM_HGPROXY_COE_SUPPORT */ 74 75 #if defined(BCM_TOMAHAWK3_SUPPORT) 76 #include <bcm_int/esw/tomahawk3.h> 77 #endif 78 #ifdef BCM_GREYHOUND2_SUPPORT 79 #include <bcm_int/esw/greyhound2.h> 80 #endif /* BCM_GREYHOUND2_SUPPORT */ 81 82 #if defined(BCM_TOMAHAWK_SUPPORT) 83 STATIC int 84 _bcm_fast_egr_vlan_port_egress_default_action_set( 85 int unit, 86 bcm_port_t port, 87 bcm_vlan_action_set_t *action); 88 89 STATIC int 90 _bcm_fast_egr_vlan_port_egress_default_action_get( 91 int unit, 92 bcm_port_t port, 93 bcm_vlan_action_set_t *action); 94 #endif 95 96 /* Cache of Ingress Vlan Translate Action Profile Table */ 97 static soc_profile_mem_t *ing_action_profile[BCM_MAX_NUM_UNITS] = {NULL}; 98 static int ing_action_profile_def[BCM_MAX_NUM_UNITS] = {0}; 99 100 /* Cache of Engress Vlan Translate Action Profile Table */ 101 static soc_profile_mem_t *egr_action_profile[BCM_MAX_NUM_UNITS] = {NULL}; 102 #define EGR_ACTION_PROFILE_DEFAULT BCM_TRX_EGR_VLAN_ACTION_PROFILE_DEFAULT 103 104 /* Cache of Ingress Vlan Range Profile Table */ 105 static soc_profile_mem_t *vlan_range_profile[BCM_MAX_NUM_UNITS] = {NULL}; 106 #define VLAN_RANGE_PROFILE_DEFAULT 0 107 108 typedef struct _bcm_trx_vlan_subnet_entry_s { 109 bcm_ip6_t ip; 110 bcm_ip6_t mask; 111 int prefix; 112 bcm_vlan_t ovid; 113 bcm_vlan_t ivid; 114 uint8 opri; 115 uint8 ocfi; 116 uint8 ipri; 117 uint8 icfi; 118 int profile_idx; 119 }_bcm_trx_vlan_subnet_entry_t; 120 121 #if defined(BCM_TRIUMPH3_SUPPORT) 122 typedef int (*tr3_vxlate_extd_entry_update_func_t)(int unit, 123 vlan_xlate_entry_t *vent_in, 124 void *ctxt, 125 vlan_xlate_entry_t *vent_out, 126 vlan_xlate_extd_entry_t *vxent_out, 127 int *use_extd_tbl); 128 #endif 129 130 #define PKT_VLAN_OUTER_ACTION_SET(unit, mem, vent_ptr, _action) \ 131 do { \ 132 if ((_action->ot_outer == bcmVlanActionAdd ) ||\ 133 (_action->ot_outer == bcmVlanActionReplace ) ||\ 134 (_action->ot_outer == bcmVlanActionOuterAdd ) ||\ 135 (_action->dt_outer == bcmVlanActionAdd ) ||\ 136 (_action->dt_outer == bcmVlanActionReplace ) ||\ 137 (_action->dt_outer == bcmVlanActionOuterAdd ) ||\ 138 (_action->it_outer == bcmVlanActionAdd ) ||\ 139 (_action->it_outer == bcmVlanActionReplace ) ||\ 140 (_action->it_outer == bcmVlanActionOuterAdd ) ||\ 141 (_action->ut_outer == bcmVlanActionAdd ) ||\ 142 (_action->ut_outer == bcmVlanActionReplace )||\ 143 (_action->ut_outer == bcmVlanActionOuterAdd )) {\ 144 soc_mem_field32_set(unit, mem, vent_ptr, OPRI_CFI_SELf, 1);\ 145 }\ 146 } while(0) 147 148 #define PKT_VLAN_INNER_ACTION_SET(unit, mem, vent_ptr, _action) \ 149 do { \ 150 if ((_action->ot_inner == bcmVlanActionAdd ) ||\ 151 (_action->ot_inner == bcmVlanActionReplace ) ||\ 152 (_action->ot_inner == bcmVlanActionInnerAdd ) ||\ 153 (_action->dt_inner == bcmVlanActionAdd ) ||\ 154 (_action->dt_inner == bcmVlanActionReplace ) ||\ 155 (_action->dt_inner == bcmVlanActionInnerAdd ) ||\ 156 (_action->it_inner == bcmVlanActionAdd ) ||\ 157 (_action->it_inner == bcmVlanActionReplace ) ||\ 158 (_action->it_inner == bcmVlanActionInnerAdd ) ||\ 159 (_action->ut_inner == bcmVlanActionAdd ) ||\ 160 (_action->ut_inner == bcmVlanActionReplace )||\ 161 (_action->ut_inner == bcmVlanActionInnerAdd )) {\ 162 soc_mem_field32_set(unit, mem, vent_ptr, IPRI_CFI_SELf, 1);\ 163 }\ 164 } while(0) 165 166 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 167 #define SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(m_unit, m_mem, m_entry_data, m_field, m_field_data) \ 168 soc_meminfo_fieldinfo_field_get((uint32*)(m_entry_data), (&SOC_MEM_INFO(m_unit, m_mem)), \ 169 (m_field), (m_field_data)) 170 #define SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(m_unit, m_mem, m_entry_data, m_field, m_field_data) \ 171 soc_meminfo_fieldinfo_field_set((uint32*)(m_entry_data), (&SOC_MEM_INFO(m_unit, m_mem)), \ 172 (m_field), (m_field_data)) 173 #endif 174 175 #define ING_VLAN_TAG_ACTION_LOCK(unit) \ 176 do {\ 177 if (soc_mem_is_valid(unit, ING_VLAN_TAG_ACTION_PROFILEm)) {\ 178 soc_mem_lock(unit, ING_VLAN_TAG_ACTION_PROFILEm); \ 179 } else if (soc_mem_is_valid(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) {\ 180 soc_mem_lock(unit, ING_VLAN_TAG_ACTION_PROFILE_2m); \ 181 }\ 182 } while (0) 183 184 #define ING_VLAN_TAG_ACTION_UNLOCK(unit) \ 185 do {\ 186 if (soc_mem_is_valid(unit, ING_VLAN_TAG_ACTION_PROFILEm)) {\ 187 soc_mem_unlock(unit, ING_VLAN_TAG_ACTION_PROFILEm); \ 188 } else if (soc_mem_is_valid(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) {\ 189 soc_mem_unlock(unit, ING_VLAN_TAG_ACTION_PROFILE_2m); \ 190 }\ 191 } while (0) 192 193 #define EGR_VLAN_TAG_ACTION_LOCK(unit) \ 194 do {\ 195 if (soc_mem_is_valid(unit, EGR_VLAN_TAG_ACTION_PROFILEm)) {\ 196 soc_mem_lock(unit, EGR_VLAN_TAG_ACTION_PROFILEm); \ 197 } else if (soc_mem_is_valid(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m)) {\ 198 soc_mem_lock(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m); \ 199 }\ 200 } while (0) 201 202 #define EGR_VLAN_TAG_ACTION_UNLOCK(unit) \ 203 do {\ 204 if (soc_mem_is_valid(unit, EGR_VLAN_TAG_ACTION_PROFILEm)) {\ 205 soc_mem_unlock(unit, EGR_VLAN_TAG_ACTION_PROFILEm); \ 206 } else if (soc_mem_is_valid(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m)) {\ 207 soc_mem_unlock(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m); \ 208 }\ 209 } while (0) 210 211 #define VLAN_RANGE_LOCK(unit) \ 212 do {\ 213 if (soc_mem_is_valid(unit, ING_VLAN_RANGEm)) {\ 214 soc_mem_lock(unit, ING_VLAN_RANGEm); \ 215 }\ 216 } while (0) 217 218 #define VLAN_RANGE_UNLOCK(unit) \ 219 do {\ 220 if (soc_mem_is_valid(unit, ING_VLAN_RANGEm)) {\ 221 soc_mem_unlock(unit, ING_VLAN_RANGEm); \ 222 }\ 223 } while (0) 224 225 STATIC int _bcm_trx_vlan_range_profile_init(int unit); 226 227 #ifdef BCM_WARM_BOOT_SUPPORT 228 STATIC int _bcm_trx_vlan_port_protocol_action_reinit(int unit); 229 #endif /* BCM_WARM_BOOT_SUPPORT */ 230 231 #if defined(BCM_TRIUMPH3_SUPPORT) 232 /* 233 * Function : 234 * _bcm_tr3_vxlate_extd2vxlate 235 * 236 * Purpose : 237 * convert extended vlan translation table to regular vlan translation 238 * table for all applicable fields. 239 * 240 * Parameters: 241 * vxxent - (IN) extended vlan translation table 242 * vxent - (OUT) regular vlan translation table 243 * use_svp - (IN) Is SVP used in vxxent 244 */ 245 246 int 247 _bcm_tr3_vxlate_extd2vxlate(int unit, 248 vlan_xlate_extd_entry_t *vxxent, 249 vlan_xlate_entry_t *vxent, 250 int use_svp) 251 { 252 uint32 key[2]; 253 uint32 value; 254 255 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, VALID_0f); 256 soc_mem_field32_set(unit, VLAN_XLATEm, vxent, VALIDf,value); 257 258 soc_mem_field_get(unit, VLAN_XLATE_EXTDm, 259 (uint32 *)vxxent, XLATE__KEY_0f, key); 260 soc_mem_field_set(unit, VLAN_XLATEm, 261 (uint32 *)vxent, KEYf, key); 262 263 /* key type value for VLAN_XLATE_EXTDm: VLAN_XLATE_1 value + 1 */ 264 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, KEY_TYPE_0f); 265 value--; 266 soc_VLAN_XLATEm_field32_set(unit, vxent, KEY_TYPEf,value); 267 268 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 269 XLATE__TAG_ACTION_PROFILE_PTRf); 270 soc_VLAN_XLATEm_field32_set(unit, vxent, 271 TAG_ACTION_PROFILE_PTRf,value); 272 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 273 XLATE__NEW_OVIDf); 274 soc_VLAN_XLATEm_field32_set(unit, vxent, 275 NEW_OVIDf,value); 276 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 277 XLATE__NEW_OPRIf); 278 soc_VLAN_XLATEm_field32_set(unit, vxent, 279 NEW_OPRIf,value); 280 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 281 XLATE__NEW_OCFIf); 282 soc_VLAN_XLATEm_field32_set(unit, vxent, 283 NEW_OCFIf,value); 284 285 /* VLAN_XLATE source_vp and new_ivid are overlay fields while 286 * VLAN_XLATE_EXTD's are not 287 */ 288 if (use_svp) { 289 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 290 XLATE__SOURCE_VPf); 291 soc_VLAN_XLATEm_field32_set(unit, vxent, SOURCE_VPf,value); 292 soc_VLAN_XLATEm_field32_set(unit, vxent, SVP_VALIDf,1); 293 } else { 294 soc_VLAN_XLATEm_field32_set(unit, vxent, SVP_VALIDf,0); 295 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 296 XLATE__NEW_IVIDf); 297 soc_VLAN_XLATEm_field32_set(unit, vxent, 298 NEW_IVIDf,value); 299 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 300 XLATE__NEW_IPRIf); 301 soc_VLAN_XLATEm_field32_set(unit, vxent, 302 NEW_IPRIf,value); 303 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 304 XLATE__NEW_ICFIf); 305 soc_VLAN_XLATEm_field32_set(unit, vxent, 306 NEW_ICFIf,value); 307 } 308 309 if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, 310 ESM_SEARCH_OFFSETf)) { 311 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 312 XLATE__ESM_SEARCH_OFFSETf); 313 soc_VLAN_XLATEm_field32_set(unit, vxent, 314 ESM_SEARCH_OFFSETf,value); 315 } 316 if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, 317 ESM_SEARCH_PRIORITYf)) { 318 value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 319 XLATE__ESM_SEARCH_PRIORITYf); 320 soc_VLAN_XLATEm_field32_set(unit, vxent, 321 ESM_SEARCH_PRIORITYf,value); 322 } 323 324 return BCM_E_NONE; 325 } 326 327 /* 328 * Function : 329 * _bcm_tr3_vxlate2vxlate_extd 330 * 331 * Purpose : 332 * convert the regular vlan translation table to the extended vlan translation 333 * table for all applicable fields. 334 * 335 * Parameters: 336 * vxent - (IN) regular vlan translation table 337 * vxxent - (OUT) extended vlan translation table 338 */ 339 340 int 341 _bcm_tr3_vxlate2vxlate_extd(int unit, 342 vlan_xlate_entry_t *vxent, 343 vlan_xlate_extd_entry_t *vxxent) 344 { 345 uint32 key[2]; 346 uint32 value; 347 int svp_valid; 348 349 value = soc_mem_field32_get(unit, VLAN_XLATEm, vxent, VALIDf); 350 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, VALID_0f, value); 351 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, VALID_1f, value); 352 353 soc_mem_field_get(unit, VLAN_XLATEm, 354 (uint32 *)vxent, KEYf, key); 355 soc_mem_field_set(unit, VLAN_XLATE_EXTDm, 356 (uint32 *)vxxent, XLATE__KEY_0f, key); 357 358 value = soc_VLAN_XLATEm_field32_get(unit, vxent, KEY_TYPEf); 359 360 /* key type value for VLAN_XLATE_EXTDm: VLAN_XLATE_1 value + 1 */ 361 value++; 362 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, KEY_TYPE_0f, value); 363 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, KEY_TYPE_1f, value); 364 365 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 366 TAG_ACTION_PROFILE_PTRf); 367 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 368 XLATE__TAG_ACTION_PROFILE_PTRf, value); 369 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 370 NEW_OVIDf); 371 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 372 XLATE__NEW_OVIDf, value); 373 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 374 NEW_OPRIf); 375 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 376 XLATE__NEW_OPRIf, value); 377 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 378 NEW_OCFIf); 379 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 380 XLATE__NEW_OCFIf, value); 381 svp_valid = soc_VLAN_XLATEm_field32_get(unit, vxent, 382 SVP_VALIDf); 383 if (svp_valid) { 384 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 385 SOURCE_VPf); 386 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 387 XLATE__SOURCE_VPf, value); 388 } else { 389 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 390 NEW_IVIDf); 391 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 392 XLATE__NEW_IVIDf, value); 393 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 394 NEW_IPRIf); 395 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 396 XLATE__NEW_IPRIf, value); 397 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 398 NEW_ICFIf); 399 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 400 XLATE__NEW_ICFIf, value); 401 } 402 403 if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, 404 ESM_SEARCH_OFFSETf)) { 405 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 406 ESM_SEARCH_OFFSETf); 407 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 408 XLATE__ESM_SEARCH_OFFSETf, value); 409 } 410 if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, 411 ESM_SEARCH_PRIORITYf)) { 412 value = soc_VLAN_XLATEm_field32_get(unit, vxent, 413 ESM_SEARCH_PRIORITYf); 414 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 415 XLATE__ESM_SEARCH_PRIORITYf, value); 416 } 417 return BCM_E_NONE; 418 } 419 420 421 /* 422 * Function : 423 * _bcm_tr3_vxlate_entry_add 424 * 425 * Purpose : 426 * Add or update a vlan translation entry to the appropriate table. 427 * BCM56640 has two type of vlan translation tables, a regular sized 428 * table VLAN_XLATE and a extended sized table VLAN_XLATE_EXTD. This 429 * function takes a regular sized entry as input, add or update 430 * either in regular sized table or extended sized table if fields 431 * only in extended table are used. 432 * 433 * Parameters: 434 * vent - the regular sized entry to be added/updated 435 * ctxt - context used by update_func 436 * update_func - function determines whether to use regular or extd entry 437 */ 438 int 439 _bcm_tr3_vxlate_entry_add(int unit, 440 vlan_xlate_entry_t *vent, 441 void *ctxt, 442 tr3_vxlate_extd_entry_update_func_t update_func, 443 int *existing_updated) 444 { 445 vlan_xlate_entry_t vent_old; 446 vlan_xlate_extd_entry_t vxent; 447 vlan_xlate_extd_entry_t vxent_old; 448 vlan_xlate_extd_entry_t vxent_tmp; 449 int idx; 450 int use_extd_table = 0; 451 int rv; 452 453 sal_memset(&vent_old, 0, sizeof(vent_old)); 454 sal_memset(&vxent, 0, sizeof(vxent)); 455 sal_memset(&vxent_old, 0, sizeof(vxent_old)); 456 457 /* 458 * first searches the regular entry table VLAN_XLATEm, if a match is found, 459 * update and write it back if the entry can be added to this table. 460 * If not, delete this entry and add it to VLAN_XLATE_EXTDm. If no match is 461 * found, check VLAN_XLATE_EXTDm, if a match is found, update and write it 462 * back, if not, add it to either VLAN_XLATEm or VLAN_XLATE_EXTDm 463 * appropriately. 464 */ 465 466 /* look up existing entry */ 467 soc_mem_lock(unit, VLAN_XLATEm); 468 rv = soc_mem_search(unit, VLAN_XLATEm, MEM_BLOCK_ALL, &idx, vent, 469 &vent_old, 0); 470 soc_mem_unlock(unit, VLAN_XLATEm); 471 472 /* regular entry exist */ 473 if (rv == SOC_E_NONE) { 474 475 if (update_func) { 476 BCM_IF_ERROR_RETURN 477 (update_func(unit,vent,ctxt,&vent_old,&vxent_old, 478 &use_extd_table)); 479 480 if (use_extd_table) { 481 /* remove the existing entry */ 482 soc_mem_lock(unit, VLAN_XLATEm); 483 rv = (soc_mem_delete(unit, VLAN_XLATEm, MEM_BLOCK_ANY, 484 &vent_old)); 485 soc_mem_unlock(unit, VLAN_XLATEm); 486 487 if (rv != SOC_E_NONE) { 488 return rv; 489 } 490 491 /* search for the extd entry. It should not exist because 492 * we already found a regular one 493 */ 494 soc_mem_lock(unit, VLAN_XLATE_EXTDm); 495 rv = soc_mem_search(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 496 &idx, &vxent, &vxent_tmp, 0); 497 soc_mem_unlock(unit, VLAN_XLATE_EXTDm); 498 499 if (rv == SOC_E_NONE) { 500 return BCM_E_EXISTS; /* XXX ERROR message */ 501 } else if (rv != SOC_E_NOT_FOUND) { 502 return rv; 503 } else { 504 soc_mem_lock(unit, VLAN_XLATE_EXTDm); 505 506 /* no extry exists, insert */ 507 rv = soc_mem_insert(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 508 &vxent_old); 509 soc_mem_unlock(unit, VLAN_XLATE_EXTDm); 510 if (existing_updated != NULL) { 511 *existing_updated = 1; 512 } 513 return rv; 514 } 515 } /* use_extd_table */ 516 } /* update_func */ 517 518 /* regular entry */ 519 soc_mem_lock(unit, VLAN_XLATEm); 520 rv = soc_mem_write(unit, VLAN_XLATEm, MEM_BLOCK_ALL, 521 idx, update_func == NULL? vent: &vent_old); 522 soc_mem_unlock(unit, VLAN_XLATEm); 523 return BCM_E_NONE; 524 } else if (rv != SOC_E_NOT_FOUND) { 525 return rv; 526 } else { /* no regular entry found */ 527 BCM_IF_ERROR_RETURN 528 (_bcm_tr3_vxlate2vxlate_extd(unit,vent,&vxent)); 529 soc_mem_lock(unit, VLAN_XLATE_EXTDm); 530 rv = soc_mem_search(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, &idx, 531 &vxent, &vxent_old, 0); 532 soc_mem_unlock(unit, VLAN_XLATE_EXTDm); 533 if (rv == SOC_E_NONE) { 534 /* found extd entry */ 535 536 if (update_func) { 537 /* need update the entry before writing it back */ 538 BCM_IF_ERROR_RETURN 539 (update_func(unit,vent,ctxt,NULL,&vxent_old, 540 &use_extd_table)); 541 } 542 soc_mem_lock(unit, VLAN_XLATE_EXTDm); 543 rv = soc_mem_write(unit, VLAN_XLATE_EXTDm, 544 MEM_BLOCK_ALL, idx, &vxent_old); 545 soc_mem_unlock(unit, VLAN_XLATE_EXTDm); 546 if (existing_updated != NULL) { 547 *existing_updated = 1; 548 } 549 } else if (rv != SOC_E_NOT_FOUND) { 550 return rv; 551 } else { 552 /* both regular and extd table are not found */ 553 /* need update the entry before insert */ 554 BCM_IF_ERROR_RETURN 555 (_bcm_tr3_vxlate2vxlate_extd(unit,vent,&vxent)); 556 if (update_func) { 557 BCM_IF_ERROR_RETURN 558 (update_func(unit,vent,ctxt,NULL,&vxent, 559 &use_extd_table)); 560 } 561 562 if (use_extd_table) { 563 soc_mem_lock(unit, VLAN_XLATE_EXTDm); 564 rv = soc_mem_insert(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 565 &vxent); 566 soc_mem_unlock(unit, VLAN_XLATE_EXTDm); 567 } else { 568 soc_mem_lock(unit, VLAN_XLATEm); 569 rv = soc_mem_insert(unit, VLAN_XLATEm, MEM_BLOCK_ALL, 570 vent); 571 soc_mem_unlock(unit, VLAN_XLATEm); 572 } 573 } 574 } 575 return rv; 576 } 577 #endif /* BCM_TRIUMPH3_SUPPORT */ 578 579 /* 580 * Function : _bcm_trx_vlan_action_verify 581 * 582 * Purpose : to validate all members of action structure 583 */ 584 int 585 _bcm_trx_vlan_action_verify(int unit, bcm_vlan_action_set_t *action) 586 { 587 if (NULL == action) { 588 return BCM_E_PARAM; 589 } 590 VLAN_CHK_ID(unit, action->new_inner_vlan); 591 VLAN_CHK_ID(unit, action->new_outer_vlan); 592 593 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 594 if (action->priority < -1 || action->priority > 7 || 595 action->new_inner_pkt_prio > 7 || 596 action->new_outer_cfi > 1 || action->new_inner_cfi > 1) { 597 return BCM_E_PARAM; 598 } 599 } 600 601 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 602 if(soc_feature(unit, soc_feature_vlan_xlate_has_class_id)) { 603 /* The max value of CLASS_ID should not be greater than 0xff since 604 * length of IFP_KEY to qualify CLASS_ID is 8 bits. 605 */ 606 if(action->class_id) { 607 if(action->class_id > 0xff) { 608 return BCM_E_PARAM; 609 } 610 } 611 } 612 #endif 613 614 switch (action->dt_outer) { 615 case bcmVlanActionNone: 616 case bcmVlanActionAdd: 617 case bcmVlanActionReplace: 618 case bcmVlanActionDelete: 619 break; 620 case bcmVlanActionCopy: 621 if (!soc_feature(unit, soc_feature_vlan_copy_action)) { 622 return BCM_E_UNAVAIL; 623 } 624 break; 625 626 #if defined(BCM_TRIDENT2_SUPPORT) 627 case bcmVlanActionCopyVsan: 628 case bcmVlanActionReplaceVsan: 629 if (!soc_feature(unit, soc_feature_fcoe)) { 630 return BCM_E_UNAVAIL; 631 } 632 break; 633 #endif 634 default: 635 return BCM_E_PARAM; 636 } 637 638 switch (action->dt_outer_prio) { 639 case bcmVlanActionNone: 640 case bcmVlanActionAdd: 641 case bcmVlanActionReplace: 642 case bcmVlanActionDelete: 643 break; 644 case bcmVlanActionCopy: 645 if (!soc_feature(unit, soc_feature_vlan_copy_action)) { 646 return BCM_E_UNAVAIL; 647 } 648 break; 649 #if defined(BCM_TRIDENT2_SUPPORT) 650 case bcmVlanActionCopyVsan: 651 case bcmVlanActionReplaceVsan: 652 if (!soc_feature(unit, soc_feature_fcoe)) { 653 return BCM_E_UNAVAIL; 654 } 655 break; 656 #endif 657 default: 658 return BCM_E_PARAM; 659 } 660 661 switch (action->dt_outer_pkt_prio) { 662 case bcmVlanActionNone: 663 break; 664 case bcmVlanActionAdd: 665 case bcmVlanActionReplace: 666 case bcmVlanActionCopy: 667 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 668 return BCM_E_UNAVAIL; 669 } 670 break; 671 #if defined(BCM_TRIDENT2_SUPPORT) 672 case bcmVlanActionCopyVsan: 673 case bcmVlanActionReplaceVsan: 674 if (!soc_feature(unit, soc_feature_fcoe)) { 675 return BCM_E_UNAVAIL; 676 } 677 break; 678 #endif 679 default: 680 return BCM_E_PARAM; 681 } 682 683 switch (action->dt_outer_cfi) { 684 case bcmVlanActionNone: 685 break; 686 case bcmVlanActionAdd: 687 case bcmVlanActionReplace: 688 case bcmVlanActionCopy: 689 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 690 return BCM_E_UNAVAIL; 691 } 692 break; 693 default: 694 return BCM_E_PARAM; 695 } 696 697 switch (action->dt_inner) { 698 case bcmVlanActionNone: 699 case bcmVlanActionReplace: 700 case bcmVlanActionDelete: 701 break; 702 case bcmVlanActionCopy: 703 if (!soc_feature(unit, soc_feature_vlan_copy_action)) { 704 return BCM_E_UNAVAIL; 705 } 706 break; 707 #if defined(BCM_TRIDENT2_SUPPORT) 708 case bcmVlanActionCopyVsan: 709 case bcmVlanActionReplaceVsan: 710 if (!soc_feature(unit, soc_feature_fcoe)) { 711 return BCM_E_UNAVAIL; 712 } 713 break; 714 #endif 715 default: 716 return BCM_E_PARAM; 717 } 718 719 switch (action->dt_inner_prio) { 720 case bcmVlanActionNone: 721 case bcmVlanActionReplace: 722 case bcmVlanActionDelete: 723 break; 724 case bcmVlanActionCopy: 725 if (!soc_feature(unit, soc_feature_vlan_copy_action)) { 726 return BCM_E_UNAVAIL; 727 } 728 break; 729 #if defined(BCM_TRIDENT2_SUPPORT) 730 case bcmVlanActionCopyVsan: 731 case bcmVlanActionReplaceVsan: 732 if (!soc_feature(unit, soc_feature_fcoe)) { 733 return BCM_E_UNAVAIL; 734 } 735 break; 736 #endif 737 default: 738 return BCM_E_PARAM; 739 } 740 741 switch (action->dt_inner_pkt_prio) { 742 case bcmVlanActionNone: 743 break; 744 case bcmVlanActionReplace: 745 case bcmVlanActionCopy: 746 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 747 return BCM_E_UNAVAIL; 748 } 749 break; 750 #if defined(BCM_TRIDENT2_SUPPORT) 751 case bcmVlanActionCopyVsan: 752 case bcmVlanActionReplaceVsan: 753 if (!soc_feature(unit, soc_feature_fcoe)) { 754 return BCM_E_UNAVAIL; 755 } 756 break; 757 #endif 758 default: 759 return BCM_E_PARAM; 760 } 761 762 switch (action->dt_inner_cfi) { 763 case bcmVlanActionNone: 764 break; 765 case bcmVlanActionReplace: 766 case bcmVlanActionCopy: 767 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 768 return BCM_E_UNAVAIL; 769 } 770 break; 771 default: 772 return BCM_E_PARAM; 773 } 774 775 switch (action->ot_outer) { 776 case bcmVlanActionNone: 777 case bcmVlanActionAdd: 778 case bcmVlanActionReplace: 779 case bcmVlanActionDelete: 780 break; 781 #if defined(BCM_TRIDENT2_SUPPORT) 782 case bcmVlanActionCopyVsan: 783 case bcmVlanActionReplaceVsan: 784 if (!soc_feature(unit, soc_feature_fcoe)) { 785 return BCM_E_UNAVAIL; 786 } 787 break; 788 #endif 789 default: 790 return BCM_E_PARAM; 791 } 792 793 switch (action->ot_outer_prio) { 794 case bcmVlanActionNone: 795 case bcmVlanActionAdd: 796 case bcmVlanActionReplace: 797 case bcmVlanActionDelete: 798 break; 799 #if defined(BCM_TRIDENT2_SUPPORT) 800 case bcmVlanActionCopyVsan: 801 case bcmVlanActionReplaceVsan: 802 if (!soc_feature(unit, soc_feature_fcoe)) { 803 return BCM_E_UNAVAIL; 804 } 805 break; 806 #endif 807 default: 808 return BCM_E_PARAM; 809 } 810 811 switch (action->ot_outer_pkt_prio) { 812 case bcmVlanActionNone: 813 break; 814 case bcmVlanActionReplace: 815 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 816 return BCM_E_UNAVAIL; 817 } 818 break; 819 #if defined(BCM_TRIDENT2_SUPPORT) 820 case bcmVlanActionCopyVsan: 821 case bcmVlanActionReplaceVsan: 822 if (!soc_feature(unit, soc_feature_fcoe)) { 823 return BCM_E_UNAVAIL; 824 } 825 break; 826 #endif 827 default: 828 return BCM_E_PARAM; 829 } 830 831 switch (action->ot_outer_cfi) { 832 case bcmVlanActionNone: 833 break; 834 case bcmVlanActionReplace: 835 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 836 return BCM_E_UNAVAIL; 837 } 838 break; 839 default: 840 return BCM_E_PARAM; 841 } 842 843 switch (action->ot_inner) { 844 case bcmVlanActionNone: 845 case bcmVlanActionAdd: 846 break; 847 case bcmVlanActionCopy: 848 if (!soc_feature(unit, soc_feature_vlan_copy_action)) { 849 return BCM_E_UNAVAIL; 850 } 851 break; 852 #if defined(BCM_TRIDENT2_SUPPORT) 853 case bcmVlanActionCopyVsan: 854 case bcmVlanActionReplaceVsan: 855 if (!soc_feature(unit, soc_feature_fcoe)) { 856 return BCM_E_UNAVAIL; 857 } 858 break; 859 #endif 860 default: 861 return BCM_E_PARAM; 862 } 863 864 switch (action->ot_inner_pkt_prio) { 865 case bcmVlanActionNone: 866 break; 867 case bcmVlanActionAdd: 868 case bcmVlanActionCopy: 869 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 870 return BCM_E_UNAVAIL; 871 } 872 break; 873 #if defined(BCM_TRIDENT2_SUPPORT) 874 case bcmVlanActionCopyVsan: 875 case bcmVlanActionReplaceVsan: 876 if (!soc_feature(unit, soc_feature_fcoe)) { 877 return BCM_E_UNAVAIL; 878 } 879 break; 880 #endif 881 default: 882 return BCM_E_PARAM; 883 } 884 885 switch (action->ot_inner_cfi) { 886 case bcmVlanActionNone: 887 break; 888 case bcmVlanActionAdd: 889 case bcmVlanActionCopy: 890 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 891 return BCM_E_UNAVAIL; 892 } 893 break; 894 default: 895 return BCM_E_PARAM; 896 } 897 898 switch (action->it_outer) { 899 case bcmVlanActionNone: 900 case bcmVlanActionAdd: 901 break; 902 case bcmVlanActionCopy: 903 if (!soc_feature(unit, soc_feature_vlan_copy_action)) { 904 return BCM_E_UNAVAIL; 905 } 906 break; 907 #if defined(BCM_TRIDENT2_SUPPORT) 908 case bcmVlanActionCopyVsan: 909 case bcmVlanActionReplaceVsan: 910 if (!soc_feature(unit, soc_feature_fcoe)) { 911 return BCM_E_UNAVAIL; 912 } 913 break; 914 #endif 915 default: 916 return BCM_E_PARAM; 917 } 918 919 switch (action->it_outer_pkt_prio) { 920 case bcmVlanActionNone: 921 break; 922 case bcmVlanActionAdd: 923 case bcmVlanActionCopy: 924 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 925 return BCM_E_UNAVAIL; 926 } 927 break; 928 #if defined(BCM_TRIDENT2_SUPPORT) 929 case bcmVlanActionCopyVsan: 930 case bcmVlanActionReplaceVsan: 931 if (!soc_feature(unit, soc_feature_fcoe)) { 932 return BCM_E_UNAVAIL; 933 } 934 break; 935 #endif 936 default: 937 return BCM_E_PARAM; 938 } 939 940 switch (action->it_outer_cfi) { 941 case bcmVlanActionNone: 942 break; 943 case bcmVlanActionAdd: 944 case bcmVlanActionCopy: 945 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 946 return BCM_E_UNAVAIL; 947 } 948 break; 949 default: 950 return BCM_E_PARAM; 951 } 952 953 switch (action->it_inner) { 954 case bcmVlanActionNone: 955 case bcmVlanActionReplace: 956 case bcmVlanActionDelete: 957 break; 958 #if defined(BCM_TRIDENT2_SUPPORT) 959 case bcmVlanActionCopyVsan: 960 case bcmVlanActionReplaceVsan: 961 if (!soc_feature(unit, soc_feature_fcoe)) { 962 return BCM_E_UNAVAIL; 963 } 964 break; 965 #endif 966 default: 967 return BCM_E_PARAM; 968 } 969 970 switch (action->it_inner_prio) { 971 case bcmVlanActionNone: 972 case bcmVlanActionReplace: 973 case bcmVlanActionDelete: 974 break; 975 #if defined(BCM_TRIDENT2_SUPPORT) 976 case bcmVlanActionCopyVsan: 977 case bcmVlanActionReplaceVsan: 978 if (!soc_feature(unit, soc_feature_fcoe)) { 979 return BCM_E_UNAVAIL; 980 } 981 break; 982 #endif 983 default: 984 return BCM_E_PARAM; 985 } 986 987 switch (action->it_inner_pkt_prio) { 988 case bcmVlanActionNone: 989 break; 990 case bcmVlanActionReplace: 991 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 992 return BCM_E_UNAVAIL; 993 } 994 break; 995 #if defined(BCM_TRIDENT2_SUPPORT) 996 case bcmVlanActionCopyVsan: 997 case bcmVlanActionReplaceVsan: 998 if (!soc_feature(unit, soc_feature_fcoe)) { 999 return BCM_E_UNAVAIL; 1000 } 1001 break; 1002 #endif 1003 default: 1004 return BCM_E_PARAM; 1005 } 1006 1007 switch (action->it_inner_cfi) { 1008 case bcmVlanActionNone: 1009 break; 1010 case bcmVlanActionReplace: 1011 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 1012 return BCM_E_UNAVAIL; 1013 } 1014 break; 1015 default: 1016 return BCM_E_PARAM; 1017 } 1018 1019 switch (action->ut_outer) { 1020 case bcmVlanActionNone: 1021 case bcmVlanActionAdd: 1022 break; 1023 #if defined(BCM_TRIDENT2_SUPPORT) 1024 case bcmVlanActionCopyVsan: 1025 case bcmVlanActionReplaceVsan: 1026 if (!soc_feature(unit, soc_feature_fcoe)) { 1027 return BCM_E_UNAVAIL; 1028 } 1029 break; 1030 #endif 1031 default: 1032 return BCM_E_PARAM; 1033 } 1034 1035 switch (action->ut_outer_pkt_prio) { 1036 case bcmVlanActionNone: 1037 break; 1038 case bcmVlanActionAdd: 1039 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 1040 return BCM_E_UNAVAIL; 1041 } 1042 break; 1043 #if defined(BCM_TRIDENT2_SUPPORT) 1044 case bcmVlanActionCopyVsan: 1045 case bcmVlanActionReplaceVsan: 1046 if (!soc_feature(unit, soc_feature_fcoe)) { 1047 return BCM_E_UNAVAIL; 1048 } 1049 break; 1050 #endif 1051 default: 1052 return BCM_E_PARAM; 1053 } 1054 1055 switch (action->ut_outer_cfi) { 1056 case bcmVlanActionNone: 1057 break; 1058 case bcmVlanActionAdd: 1059 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 1060 return BCM_E_UNAVAIL; 1061 } 1062 break; 1063 default: 1064 return BCM_E_PARAM; 1065 } 1066 1067 switch (action->ut_inner) { 1068 case bcmVlanActionNone: 1069 case bcmVlanActionAdd: 1070 break; 1071 #if defined(BCM_TRIDENT2_SUPPORT) 1072 case bcmVlanActionCopyVsan: 1073 case bcmVlanActionReplaceVsan: 1074 if (!soc_feature(unit, soc_feature_fcoe)) { 1075 return BCM_E_UNAVAIL; 1076 } 1077 break; 1078 #endif 1079 default: 1080 return BCM_E_PARAM; 1081 } 1082 1083 switch (action->ut_inner_pkt_prio) { 1084 case bcmVlanActionNone: 1085 break; 1086 case bcmVlanActionAdd: 1087 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 1088 return BCM_E_UNAVAIL; 1089 } 1090 break; 1091 #if defined(BCM_TRIDENT2_SUPPORT) 1092 case bcmVlanActionCopyVsan: 1093 case bcmVlanActionReplaceVsan: 1094 if (!soc_feature(unit, soc_feature_fcoe)) { 1095 return BCM_E_UNAVAIL; 1096 } 1097 break; 1098 #endif 1099 default: 1100 return BCM_E_PARAM; 1101 } 1102 1103 switch (action->ut_inner_cfi) { 1104 case bcmVlanActionNone: 1105 break; 1106 case bcmVlanActionAdd: 1107 if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 1108 return BCM_E_UNAVAIL; 1109 } 1110 break; 1111 default: 1112 return BCM_E_PARAM; 1113 } 1114 1115 return BCM_E_NONE; 1116 } 1117 1118 /* 1119 * Function : _bcm_trx_egr_vlan_action_verify 1120 * 1121 * Purpose : to validate all members of action structure for egress vlan 1122 * more strict validation than ingress 1123 */ 1124 STATIC int 1125 _bcm_trx_egr_vlan_action_verify(int unit, bcm_vlan_action_set_t *action) 1126 { 1127 BCM_IF_ERROR_RETURN( 1128 _bcm_trx_vlan_action_verify(unit, action)); 1129 1130 if (action->dt_outer == bcmVlanActionAdd || 1131 action->dt_outer_prio == bcmVlanActionAdd || 1132 action->ot_outer == bcmVlanActionAdd || 1133 action->ot_outer_prio == bcmVlanActionAdd) { 1134 return BCM_E_PARAM; 1135 } 1136 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1137 /*Ensure that class_id doesnt overcross CLASS_IDf*/ 1138 if(soc_feature(unit, soc_feature_vlan_xlate_has_class_id)) { 1139 /* The max value of CLASS_ID should not be greater than 0xff since 1140 * length of IFP_KEY to qualify CLASS_ID is 8 bits. 1141 */ 1142 if(action->class_id) { 1143 if(action->class_id > 0xff) { 1144 return BCM_E_PARAM; 1145 } 1146 } 1147 } 1148 #endif 1149 /* Single inner tag modification is available for egress vlan actions */ 1150 if (!soc_feature(unit, soc_feature_vlan_egr_it_inner_replace)) { 1151 if (action->dt_outer_prio != bcmVlanActionNone) { 1152 return BCM_E_PARAM; 1153 } 1154 if (action->ot_outer_prio != bcmVlanActionNone) { 1155 return BCM_E_PARAM; 1156 } 1157 if (action->it_outer != bcmVlanActionNone) { 1158 return BCM_E_PARAM; 1159 } 1160 if (action->it_inner != bcmVlanActionNone) { 1161 return BCM_E_PARAM; 1162 } 1163 if (action->it_inner_prio != bcmVlanActionNone) { 1164 return BCM_E_PARAM; 1165 } 1166 if (action->ut_inner != bcmVlanActionNone) { 1167 return BCM_E_PARAM; 1168 } 1169 if (action->ut_outer != bcmVlanActionNone) { 1170 return BCM_E_PARAM; 1171 } 1172 } 1173 1174 return BCM_E_NONE; 1175 } 1176 1177 /* 1178 * Function : _bcm_trx_vlan_ip_verify 1179 * 1180 * Purpose : to validate members of vlan_ip structure 1181 */ 1182 STATIC int 1183 _bcm_trx_vlan_ip_verify(int unit, bcm_vlan_ip_t *vlan_ip) 1184 { 1185 if (NULL == vlan_ip) { 1186 return BCM_E_PARAM; 1187 } 1188 VLAN_CHK_ID(unit, vlan_ip->vid); 1189 VLAN_CHK_PRIO(unit, vlan_ip->prio); 1190 1191 return BCM_E_NONE; 1192 } 1193 1194 /* 1195 * Function : bcm_trx_vlan_action_profile_detach 1196 * 1197 * Purpose : to initialize hardware ING_VLAN_TAG_ACTION_PROFILE and 1198 * EGR_VLAN_TAG_ACTION_PROFILE tables and allocate memory 1199 * to cache hardware tables in RAM. 1200 * 1201 * Note: 1202 * Allocate memory to cache the profile tables and initialize. 1203 * If memory to cache the profile table is already allocated, just 1204 * initialize the table. 1205 */ 1206 int 1207 _bcm_trx_vlan_action_profile_detach(int unit) 1208 { 1209 int rv; 1210 soc_mem_t mem = ING_VLAN_TAG_ACTION_PROFILEm; 1211 if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) { 1212 mem = ING_VLAN_TAG_ACTION_PROFILE_2m; 1213 } 1214 if (SOC_MEM_IS_VALID(unit, mem)) { 1215 /* De-initialize the ING_VLAN_TAG_ACTION_PROFILE table */ 1216 ING_VLAN_TAG_ACTION_LOCK(unit); 1217 rv = soc_profile_mem_destroy(unit, ing_action_profile[unit]); 1218 if (BCM_SUCCESS(rv)) { 1219 sal_free(ing_action_profile[unit]); 1220 ing_action_profile[unit] = NULL; 1221 } 1222 ING_VLAN_TAG_ACTION_UNLOCK(unit); 1223 BCM_IF_ERROR_RETURN(rv); 1224 } 1225 1226 EGR_VLAN_TAG_ACTION_LOCK(unit); 1227 rv = soc_profile_mem_destroy(unit, egr_action_profile[unit]); 1228 if (BCM_SUCCESS(rv)) { 1229 sal_free(egr_action_profile[unit]); 1230 egr_action_profile[unit] = NULL; 1231 } 1232 EGR_VLAN_TAG_ACTION_UNLOCK(unit); 1233 BCM_IF_ERROR_RETURN(rv); 1234 1235 VLAN_RANGE_LOCK(unit); 1236 rv = soc_profile_mem_destroy(unit, vlan_range_profile[unit]); 1237 if (BCM_SUCCESS(rv)) { 1238 sal_free(vlan_range_profile[unit]); 1239 vlan_range_profile[unit] = NULL; 1240 } 1241 VLAN_RANGE_UNLOCK(unit); 1242 BCM_IF_ERROR_RETURN(rv); 1243 1244 return BCM_E_NONE; 1245 } 1246 1247 /* 1248 * Function : bcm_trx_vlan_action_profile_init 1249 * 1250 * Purpose : to initialize hardware ING_VLAN_TAG_ACTION_PROFILE and 1251 * EGR_VLAN_TAG_ACTION_PROFILE tables and allocate memory 1252 * to cache hardware tables in RAM. 1253 * 1254 * Note: 1255 * Allocate memory to cache the profile tables and initialize. 1256 * If memory to cache the profile table is already allocated, just 1257 * initialize the table. 1258 */ 1259 int 1260 _bcm_trx_vlan_action_profile_init(int unit) 1261 { 1262 int i, idx, num_ports; 1263 vlan_protocol_data_entry_t proto_entry; 1264 vlan_subnet_entry_t subnet_entry; 1265 vlan_mac_entry_t vlan_mac_entry; 1266 vlan_xlate_entry_t vx_ent; 1267 vlan_xlate_1_double_entry_t vx1d_ent; 1268 egr_vlan_xlate_entry_t evx_ent; 1269 egr_vlan_xlate_1_double_entry_t evx1d_ent; 1270 ing_vlan_tag_action_profile_entry_t ing_profile; 1271 egr_vlan_tag_action_profile_entry_t egr_profile_entry; 1272 uint32 rval, temp_index; 1273 soc_mem_t mem[2]; 1274 soc_mem_t mem_cnt = 1; 1275 int table_cnt = 1; 1276 int entry_idxmin[2], entry_idxmax[2]; 1277 int entry_words[2]; 1278 void *entries[2]; 1279 int key_type_value, key_type; 1280 #if defined(BCM_TRIUMPH2_SUPPORT) 1281 _bcm_flex_stat_handle_t handle; 1282 vlan_xlate_entry_t vent; 1283 egr_vlan_xlate_entry_t event; 1284 uint32 key[2]; 1285 int fs_idx; 1286 #endif 1287 ing_vlan_tag_action_profile_2_entry_t ing_profile_2; 1288 void *ing_profile_entry; 1289 uint32 ing_ent_sz; 1290 int rv; 1291 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 1292 uint32 entry[SOC_MAX_MEM_WORDS]; 1293 soc_field_info_t *field_info = NULL, *field_info_1 = NULL; 1294 int type; 1295 soc_field_t type_fld = ENTRY_TYPEf; 1296 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 1297 1298 soc_mem_t ing_mem = VLAN_XLATEm; 1299 soc_mem_t egr_mem = EGR_VLAN_XLATEm; 1300 soc_field_t vf = VALIDf; 1301 void *xlate_entry = &vx_ent; 1302 void *egr_xlate_entry = &evx_ent; 1303 ing_vlan_tag_action_profile_entry_t ing_vlan_tag_action_profile_mask; 1304 void *entry_mask[1]; 1305 1306 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 1307 ing_action_profile_def[unit] = 1; 1308 } 1309 1310 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 1311 ing_mem = VLAN_XLATE_1_DOUBLEm; 1312 egr_mem = EGR_VLAN_XLATE_1_DOUBLEm; 1313 vf = BASE_VALID_0f; 1314 xlate_entry = &vx1d_ent; 1315 egr_xlate_entry = &evx1d_ent; 1316 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 1317 type_fld = KEY_TYPEf; 1318 #endif 1319 } 1320 1321 /* Create profile table cache (or re-init if it already exists) */ 1322 if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) { 1323 mem[0] = ING_VLAN_TAG_ACTION_PROFILE_2m; 1324 mem[1] = ING_VLAN_TAG_ACTION_PROFILE_1m; 1325 ing_ent_sz = sizeof(ing_vlan_tag_action_profile_2_entry_t); 1326 ing_profile_entry = &ing_profile_2; 1327 table_cnt = 2; 1328 entry_idxmin[0] = entry_idxmin[1] = 1; 1329 } else { 1330 mem[0] = ING_VLAN_TAG_ACTION_PROFILEm; 1331 ing_ent_sz = sizeof(ing_vlan_tag_action_profile_entry_t); 1332 ing_profile_entry = &ing_profile; 1333 entry_idxmin[0] = entry_idxmin[1] = 0; 1334 sal_memset(&ing_vlan_tag_action_profile_mask, 0xff, 1335 sizeof(ing_vlan_tag_action_profile_mask)); 1336 } 1337 /* Create profile table cache (or re-init if it already exists) */ 1338 entry_words[0] = entry_words[1] = ing_ent_sz / sizeof(uint32); 1339 1340 if (SOC_MEM_IS_VALID(unit, mem[0])) { 1341 /* Initialize the ING_VLAN_TAG_ACTION_PROFILE table */ 1342 1343 if (ing_action_profile[unit] == NULL) { 1344 ing_action_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t), 1345 "Ing Action Profile Mem"); 1346 if (ing_action_profile[unit] == NULL) { 1347 return BCM_E_MEMORY; 1348 } 1349 soc_profile_mem_t_init(ing_action_profile[unit]); 1350 } 1351 1352 entry_idxmax[0] = entry_idxmax[1] = soc_mem_index_max(unit, mem[0]); 1353 if (mem[0] == ING_VLAN_TAG_ACTION_PROFILEm) { 1354 entry_mask[0] = &ing_vlan_tag_action_profile_mask; 1355 if (SOC_MEM_FIELD_VALID(unit, mem[0], ECCPf)) { 1356 soc_mem_field32_set(unit, mem[0], entry_mask[0], ECCPf, 0); 1357 } else if (SOC_MEM_FIELD_VALID(unit, mem[0], EVEN_PARITYf)) { 1358 soc_mem_field32_set(unit, mem[0], entry_mask[0], EVEN_PARITYf, 1359 0); 1360 } 1361 SOC_IF_ERROR_RETURN( 1362 soc_profile_mem_index_create(unit, mem, entry_words, 1363 entry_idxmin, entry_idxmax, entry_mask, 1364 table_cnt, ing_action_profile[unit])); 1365 } else { 1366 SOC_IF_ERROR_RETURN( 1367 soc_profile_mem_index_create(unit, mem, entry_words, 1368 entry_idxmin, entry_idxmax, NULL, 1369 table_cnt, ing_action_profile[unit])); 1370 } 1371 1372 if (SOC_WARM_BOOT(unit)) { 1373 soc_mem_t port_mem = PORT_TABm; 1374 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 1375 port_mem = ING_DEVICE_PORTm; 1376 } 1377 1378 /* Increment the ref count for all ports */ 1379 for (i = 0; i < soc_mem_index_count(unit, port_mem); i++) { 1380 if (!SOC_PORT_VALID(unit, i)) { 1381 continue; 1382 } 1383 SOC_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, i, 1384 TAG_ACTION_PROFILE_PTRf, &idx)); 1385 SOC_IF_ERROR_RETURN( 1386 soc_profile_mem_reference(unit, ing_action_profile[unit], 1387 idx, 1)); 1388 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit], 1389 idx - entry_idxmin[0], 1); 1390 } 1391 1392 /* TH/TH2/TD3/KT2 and some other chips need use another method to revocer 1393 * the reference count in _bcm_th_port_vlan_action_profile_reinit(). 1394 */ 1395 if (!SOC_IS_TOMAHAWK(unit) && !SOC_IS_TOMAHAWK2(unit) && 1396 !SOC_IS_KATANA2(unit)) { 1397 /* Increment the ref count for all Protocol-based VLANs */ 1398 for (i = 0; i < soc_mem_index_count(unit, VLAN_PROTOCOL_DATAm); 1399 i++) { 1400 SOC_IF_ERROR_RETURN( 1401 READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, i, 1402 &proto_entry)); 1403 idx = soc_mem_field32_get(unit, VLAN_PROTOCOL_DATAm, 1404 &proto_entry, 1405 TAG_ACTION_PROFILE_PTRf); 1406 if (!SOC_IS_TRIDENT3X(unit)) { 1407 SOC_IF_ERROR_RETURN( 1408 soc_profile_mem_reference(unit, 1409 ing_action_profile[unit], idx, 1)); 1410 SOC_PROFILE_MEM_ENTRIES_PER_SET( 1411 unit, ing_action_profile[unit], 1412 idx - entry_idxmin[0], 1); 1413 } 1414 if (idx < ing_action_profile_def[unit]) { 1415 SOC_IF_ERROR_RETURN( 1416 soc_profile_mem_reference(unit, 1417 ing_action_profile[unit], 1418 ing_action_profile_def[unit], 1)); 1419 } 1420 } 1421 } 1422 1423 /* Increment the ref count for all Subnet-based VLANs */ 1424 for (i = 0; i < soc_mem_index_count(unit, VLAN_SUBNETm); i++) { 1425 SOC_IF_ERROR_RETURN 1426 (READ_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, &subnet_entry)); 1427 if (!soc_mem_field32_get(unit, VLAN_SUBNETm, 1428 &subnet_entry, VALIDf)) { 1429 continue; 1430 } 1431 idx = soc_mem_field32_get(unit, VLAN_SUBNETm, 1432 &subnet_entry, TAG_ACTION_PROFILE_PTRf); 1433 if (idx >= entry_idxmin[0]) { 1434 SOC_IF_ERROR_RETURN( 1435 soc_profile_mem_reference(unit, ing_action_profile[unit], 1436 idx, 1)); 1437 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit], 1438 idx - entry_idxmin[0], 1); 1439 } 1440 } 1441 1442 /* Increment the ref count for all Mac-based VLANs & vlan translations */ 1443 if (SOC_MEM_IS_VALID(unit, VLAN_MACm)) { 1444 for (i = 0; i < soc_mem_index_count(unit, VLAN_MACm); i++) { 1445 SOC_IF_ERROR_RETURN 1446 (READ_VLAN_MACm(unit, MEM_BLOCK_ANY, i, 1447 &vlan_mac_entry)); 1448 if (!soc_mem_field32_get(unit, VLAN_MACm, 1449 &vlan_mac_entry, VALIDf)) { 1450 continue; 1451 } 1452 key_type_value = soc_mem_field32_get(unit, VLAN_MACm, 1453 &vlan_mac_entry, KEY_TYPEf); 1454 (void) _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value, 1455 &key_type); 1456 if (VLXLT_HASH_KEY_TYPE_VLAN_MAC == key_type) { 1457 idx = soc_mem_field32_get(unit, VLAN_MACm, &vlan_mac_entry, 1458 MAC__TAG_ACTION_PROFILE_PTRf); 1459 } else if (VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT == key_type) { 1460 idx = soc_mem_field32_get(unit, VLAN_MACm, &vlan_mac_entry, 1461 MAC_PORT__TAG_ACTION_PROFILE_PTRf); 1462 } else { 1463 continue; 1464 } 1465 SOC_IF_ERROR_RETURN( 1466 soc_profile_mem_reference(unit, ing_action_profile[unit], 1467 idx, 1)); 1468 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, 1469 ing_action_profile[unit], idx - entry_idxmin[0], 1); 1470 } 1471 } 1472 1473 for (i = 0; i < soc_mem_index_count(unit, ing_mem); i++) { 1474 SOC_IF_ERROR_RETURN 1475 (soc_mem_read(unit, ing_mem, MEM_BLOCK_ANY, i, xlate_entry)); 1476 if (!soc_mem_field32_get(unit, ing_mem, xlate_entry, vf)) { 1477 continue; 1478 } 1479 key_type_value = soc_mem_field32_get(unit, ing_mem, xlate_entry, 1480 KEY_TYPEf); 1481 1482 /* Here return value is not being checked (that is intentional); in case 1483 it returns BCM_E_UNAVAIL, will proceed with else condition below */ 1484 /* Coverity[unchecked_value] */ 1485 _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value, &key_type); 1486 if (key_type == VLXLT_HASH_KEY_TYPE_VIF || 1487 key_type == VLXLT_HASH_KEY_TYPE_VIF_VLAN || 1488 key_type == VLXLT_HASH_KEY_TYPE_VIF_CVLAN || 1489 key_type == VLXLT_HASH_KEY_TYPE_VIF_OTAG || 1490 key_type == VLXLT_HASH_KEY_TYPE_VIF_ITAG) { 1491 idx = soc_mem_field32_get(unit, ing_mem, xlate_entry, 1492 VIF__TAG_ACTION_PROFILE_PTRf); 1493 } else { 1494 idx = soc_mem_field32_get(unit, ing_mem, xlate_entry, 1495 TAG_ACTION_PROFILE_PTRf); 1496 #ifdef BCM_TRIDENT3_SUPPORT 1497 if (soc_feature(unit, soc_feature_flex_flow)) { 1498 soc_mem_t mem_view_id; 1499 uint32 data_type; 1500 int rv; 1501 1502 data_type = 0; 1503 if (SOC_MEM_FIELD_VALID(unit, ing_mem, DATA_TYPEf)) { 1504 data_type = soc_mem_field32_get(unit, ing_mem, 1505 xlate_entry,DATA_TYPEf); 1506 } 1507 rv = soc_flow_db_mem_to_view_id_get (unit, ing_mem, 1508 key_type_value, data_type, 0, NULL, 1509 (uint32 *)&mem_view_id); 1510 if (SOC_SUCCESS(rv)) { 1511 idx = 0; 1512 if (SOC_MEM_FIELD_VALID(unit, mem_view_id, 1513 TAG_ACTION_SETf)) { 1514 idx = soc_mem_field32_get(unit, mem_view_id, 1515 xlate_entry, TAG_ACTION_SETf); 1516 } 1517 } 1518 } 1519 #endif 1520 } 1521 rv = soc_profile_mem_reference(unit, ing_action_profile[unit], 1522 idx, 1); 1523 if (SOC_SUCCESS(rv)) { 1524 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit], 1525 idx - entry_idxmin[0], 1); 1526 } else { 1527 /* TAG_ACTION_PROFILE_PTR may not be used for all key types. 1528 * In this case, it has default value 0. Ignore it. 1529 */ 1530 if (idx) { 1531 return rv; 1532 } 1533 } 1534 1535 #if defined(BCM_TRIUMPH2_SUPPORT) 1536 if (soc_feature(unit, soc_feature_gport_service_counters)) { 1537 fs_idx = 1538 soc_mem_field32_get(unit, ing_mem, xlate_entry, VINTF_CTR_IDXf); 1539 if (SOC_MEM_FIELD_VALID(unit, ing_mem, USE_VINTF_CTR_IDXf)) { 1540 if (0 == soc_mem_field32_get(unit, ing_mem, 1541 xlate_entry, USE_VINTF_CTR_IDXf)) { 1542 fs_idx = 0; 1543 } 1544 } 1545 if (0 != fs_idx) { /* Recover flex stat counter */ 1546 sal_memset(&vent, 0, sizeof(vent)); 1547 /* Construct key-only entry, copy to FS handle */ 1548 soc_mem_field32_set(unit, ing_mem, &vent, KEY_TYPEf, 1549 soc_mem_field32_get(unit, ing_mem, xlate_entry, 1550 KEY_TYPEf)); 1551 soc_mem_field_get(unit, ing_mem, (uint32 *) xlate_entry, 1552 KEYf, (uint32 *) key); 1553 soc_mem_field_set(unit, ing_mem, (uint32 *) &vent, 1554 KEYf, (uint32 *) key); 1555 1556 _BCM_FLEX_STAT_HANDLE_CLEAR(handle); 1557 _BCM_FLEX_STAT_HANDLE_COPY(handle, vent); 1558 _bcm_esw_flex_stat_ext_reinit_add(unit, 1559 _bcmFlexStatTypeVxlt, fs_idx, handle); 1560 } 1561 } 1562 #endif 1563 } 1564 1565 /* One extra increment to preserve location 1566 * ING_ACTION_PROFILE_DEFAULT */ 1567 SOC_IF_ERROR_RETURN( 1568 soc_profile_mem_reference(unit, ing_action_profile[unit], 1569 ing_action_profile_def[unit], 1)); 1570 } else { 1571 /* Initialize the ING_ACTION_PROFILE_DEFAULT. For untagged and 1572 * inner-tagged packets, always add an outer tag. 1573 */ 1574 soc_mem_t port_mem = PORT_TABm; 1575 sal_memset(ing_profile_entry, 0, ing_ent_sz); 1576 soc_mem_field32_set(unit, mem[0], ing_profile_entry, UT_OTAG_ACTIONf, 1577 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionAdd)); 1578 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 1579 soc_mem_field32_set(unit, mem[0], ing_profile_entry, UT_OPRI_ACTIONf, 1580 _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd)); 1581 soc_mem_field32_set(unit, mem[0], ing_profile_entry, UT_OCFI_ACTIONf, 1582 _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd)); 1583 } 1584 soc_mem_field32_set(unit, mem[0], ing_profile_entry, SIT_OTAG_ACTIONf, 1585 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionAdd)); 1586 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 1587 soc_mem_field32_set(unit, mem[0], ing_profile_entry, SIT_OPRI_ACTIONf, 1588 _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd)); 1589 soc_mem_field32_set(unit, mem[0], ing_profile_entry, SIT_OCFI_ACTIONf, 1590 _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd)); 1591 } 1592 soc_mem_field32_set(unit, mem[0], ing_profile_entry, SIT_PITAG_ACTIONf, 1593 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionNone)); 1594 soc_mem_field32_set(unit, mem[0], ing_profile_entry, SOT_POTAG_ACTIONf, 1595 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionReplace)); 1596 soc_mem_field32_set(unit, mem[0], ing_profile_entry, DT_POTAG_ACTIONf, 1597 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionReplace)); 1598 entries[0] = ing_profile_entry; 1599 entries[1] = ing_profile_entry; 1600 SOC_IF_ERROR_RETURN 1601 (soc_profile_mem_add(unit, ing_action_profile[unit], 1602 (void *) &entries, 1, &temp_index)); 1603 1604 /* Increment the ref count for all ports */ 1605 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 1606 port_mem = ING_DEVICE_PORTm; 1607 } 1608 1609 for (i = 0; i < soc_mem_index_count(unit, port_mem); i++) { 1610 if (SOC_PORT_VALID(unit, i)) { 1611 SOC_IF_ERROR_RETURN( 1612 soc_profile_mem_reference(unit, ing_action_profile[unit], 1613 ing_action_profile_def[unit], 1)); 1614 } 1615 } 1616 1617 /* Increment the ref count for all Protocol-based VLANs */ 1618 for (i = 0; i < soc_mem_index_count(unit, VLAN_PROTOCOL_DATAm); 1619 i++) { 1620 #if 0 1621 vlan_protocol_data_entry_t vp_ent; 1622 sal_memset(&vp_ent, 0, sizeof(vp_ent)); 1623 if (ing_action_profile_def[unit] != 0) { 1624 soc_mem_field32_set(unit, VLAN_PROTOCOL_DATAm, &vp_ent, 1625 TAG_ACTION_PROFILE_PTRf, 1626 ing_action_profile_def[unit]); 1627 SOC_IF_ERROR_RETURN( 1628 soc_mem_write(unit, VLAN_PROTOCOL_DATAm, SOC_BLOCK_ALL, 1629 i, &vp_ent)); 1630 } 1631 #endif 1632 SOC_IF_ERROR_RETURN( 1633 soc_profile_mem_reference(unit, ing_action_profile[unit], 1634 ing_action_profile_def[unit], 1)); 1635 } 1636 } 1637 } 1638 1639 /* Initialize the EGR_VLAN_TAG_ACTION_PROFILE table */ 1640 if (egr_action_profile[unit] == NULL) { 1641 egr_action_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t), 1642 "Egr Action Profile Mem"); 1643 if (egr_action_profile[unit] == NULL) { 1644 return BCM_E_MEMORY; 1645 } 1646 soc_profile_mem_t_init(egr_action_profile[unit]); 1647 } 1648 1649 /* Create profile table cache (or re-init if it already exists) */ 1650 mem[0] = EGR_VLAN_TAG_ACTION_PROFILEm; 1651 entry_words[0] = sizeof(egr_vlan_tag_action_profile_entry_t) / sizeof(uint32); 1652 entry_idxmin[0] = soc_mem_index_min(unit, mem[0]); 1653 entry_idxmax[0] = soc_mem_index_max(unit, mem[0]); 1654 1655 mem[1] = EGR_VLAN_TAG_ACTION_PROFILE_2m; 1656 if (soc_mem_is_valid(unit, mem[1])) { 1657 entry_words[1] = sizeof(egr_vlan_tag_action_profile_entry_t) / sizeof(uint32); 1658 entry_idxmin[1] = soc_mem_index_min(unit, mem[1]); 1659 entry_idxmax[1] = soc_mem_index_max(unit, mem[1]) - 1; 1660 /* For EGR_VLAN_TAG_ACTION_PROFILE_2m device, 1661 * last entry (index 63) is reserved for VT_MISS_UNTAG */ 1662 entry_idxmax[0] --; 1663 mem_cnt = 2; 1664 } 1665 1666 SOC_IF_ERROR_RETURN( 1667 soc_profile_mem_index_create(unit, mem, entry_words, 1668 entry_idxmin, entry_idxmax, NULL, 1669 mem_cnt, egr_action_profile[unit])); 1670 1671 SOC_PBMP_COUNT(PBMP_ALL(unit), num_ports); 1672 if (SOC_WARM_BOOT(unit)) { 1673 /* Increment the ref count for all ports */ 1674 PBMP_ALL_ITER(unit, i) { 1675 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1676 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 1677 if (soc_feature(unit, soc_feature_egr_all_profile)) { 1678 soc_field_t fld = TAG_ACTION_PROFILE_PTRf; 1679 BCM_IF_ERROR_RETURN( 1680 bcm_esw_port_egr_lport_fields_get(unit, i, 1681 EGR_VLAN_CONTROL_3m, 1, &fld, (uint32 *)&idx)); 1682 } else { 1683 egr_vlan_control_3_entry_t entry; 1684 SOC_IF_ERROR_RETURN( 1685 READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, 1686 i, &entry)); 1687 idx = soc_EGR_VLAN_CONTROL_3m_field32_get(unit, &entry, 1688 TAG_ACTION_PROFILE_PTRf); 1689 } 1690 } else 1691 #endif 1692 { 1693 SOC_IF_ERROR_RETURN 1694 (READ_EGR_VLAN_CONTROL_3r(unit, i, &rval)); 1695 idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 1696 rval, TAG_ACTION_PROFILE_PTRf); 1697 } 1698 soc_profile_mem_reference(unit, egr_action_profile[unit], idx, 1); 1699 } 1700 1701 if (SOC_MEM_IS_VALID(unit, egr_mem)) { 1702 /* Increment the ref count for all egress vlan translations */ 1703 for (i = 0; i < soc_mem_index_count(unit, egr_mem); i++) { 1704 SOC_IF_ERROR_RETURN 1705 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, i, egr_xlate_entry)); 1706 if (!soc_mem_field32_get(unit, egr_mem, egr_xlate_entry, vf)) { 1707 continue; 1708 } 1709 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 1710 type = soc_mem_field32_get(unit, egr_mem, egr_xlate_entry, 1711 type_fld); 1712 if (type == TD2PLUS_EVLXLT_HASH_KEY_TYPE_VFI_DVP_GROUP) { 1713 field_info = soc_mem_fieldinfo_get( 1714 unit, egr_mem, 1715 VFI_DVP_GROUP__XLATE_DATAf); 1716 } else if (type == 1717 TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI) { 1718 field_info = soc_mem_fieldinfo_get( 1719 unit, egr_mem, 1720 VLAN_XLATE_VFI__XLATE_DATAf); 1721 } 1722 if (field_info) { 1723 sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32)); 1724 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET( 1725 unit, egr_mem, egr_xlate_entry, field_info, entry); 1726 field_info_1 = soc_mem_fieldinfo_get(unit, egr_mem, 1727 XLATE_DATAf); 1728 if (!field_info_1) { 1729 return BCM_E_UNAVAIL; 1730 } 1731 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET( 1732 unit, egr_mem, egr_xlate_entry, field_info_1, entry); 1733 } 1734 #endif 1735 idx = soc_mem_field32_get(unit, egr_mem, 1736 egr_xlate_entry, TAG_ACTION_PROFILE_PTRf); 1737 soc_profile_mem_reference(unit, egr_action_profile[unit], 1738 idx, 1); 1739 #if defined(BCM_TRIUMPH2_SUPPORT) 1740 if (soc_feature(unit, soc_feature_gport_service_counters)) { 1741 fs_idx = 1742 soc_mem_field32_get(unit, egr_mem, egr_xlate_entry, 1743 VINTF_CTR_IDXf); 1744 if (SOC_MEM_FIELD_VALID(unit, egr_mem, 1745 USE_VINTF_CTR_IDXf)) { 1746 if (0 == soc_mem_field32_get(unit, egr_mem, 1747 egr_xlate_entry, USE_VINTF_CTR_IDXf)) { 1748 fs_idx = 0; 1749 } 1750 } 1751 if (0 != fs_idx) { /* Recover flex stat counter */ 1752 sal_memset(&event, 0, sizeof(event)); 1753 /* Construct key-only entry, copy to FS handle */ 1754 soc_mem_field32_set(unit, egr_mem, &event, ENTRY_TYPEf, 1755 soc_mem_field32_get(unit, egr_mem, 1756 egr_xlate_entry, ENTRY_TYPEf)); 1757 soc_mem_field_get(unit, egr_mem, 1758 (uint32 *) egr_xlate_entry, 1759 KEYf, (uint32 *) key); 1760 soc_mem_field_set(unit, egr_mem, 1761 (uint32 *) &event, 1762 KEYf, (uint32 *) key); 1763 1764 _BCM_FLEX_STAT_HANDLE_CLEAR(handle); 1765 _BCM_FLEX_STAT_HANDLE_COPY(handle, event); 1766 _bcm_esw_flex_stat_ext_reinit_add(unit, 1767 _bcmFlexStatTypeVxlt, fs_idx, handle); 1768 } 1769 } 1770 #endif 1771 } 1772 } 1773 #if defined(BCM_TRIDENT3_SUPPORT) 1774 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 1775 uint32 entry_type; 1776 egr_l3_next_hop_entry_t egr_nh; 1777 egr_vlan_xlate_1_single_entry_t egr_single_entry; 1778 egr_mem = EGR_VLAN_XLATE_1_SINGLEm; 1779 for (i = 0; i < soc_mem_index_count(unit, egr_mem); i++) { 1780 SOC_IF_ERROR_RETURN 1781 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, i, &egr_single_entry)); 1782 if (soc_mem_field32_get(unit, egr_mem, &egr_single_entry, BASE_VALIDf)) { 1783 idx = soc_mem_field32_get(unit, egr_mem, 1784 &egr_single_entry, TAG_ACTION_PROFILE_PTRf); 1785 soc_profile_mem_reference(unit, egr_action_profile[unit], idx, 1); 1786 } 1787 } 1788 1789 egr_mem = EGR_L3_NEXT_HOPm; 1790 for (i = 0; i < soc_mem_index_count(unit, egr_mem); i++) { 1791 SOC_IF_ERROR_RETURN 1792 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, i, &egr_nh)); 1793 entry_type = soc_mem_field32_get(unit, egr_mem, &egr_nh, DATA_TYPEf); 1794 if (entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L2OTAG_VIEW) { 1795 idx = soc_mem_field32_get(unit, egr_mem, &egr_nh, 1796 L2_OTAG__TAG_ACTION_PROFILE_PTRf); 1797 soc_profile_mem_reference(unit, egr_action_profile[unit], idx, 1); 1798 } 1799 } 1800 } 1801 #endif 1802 /* One extra increment to preserve location EGR_ACTION_PROFILE_DEFAULT */ 1803 soc_profile_mem_reference(unit, egr_action_profile[unit], 1804 EGR_ACTION_PROFILE_DEFAULT, 1); 1805 } else { 1806 /* Initialize the EGR_ACTION_PROFILE_DEFAULT to have all 1807 * actions as NOP (0). 1808 */ 1809 sal_memset(&egr_profile_entry, 0, sizeof(egr_vlan_tag_action_profile_entry_t)); 1810 entries[0] = &egr_profile_entry; 1811 entries[1] = &egr_profile_entry; 1812 SOC_IF_ERROR_RETURN 1813 (soc_profile_mem_add(unit, egr_action_profile[unit], 1814 (void *) &entries, 1, &temp_index)); 1815 1816 /* Increment the ref count for all ports */ 1817 for (i = 0; i < num_ports; i++) { 1818 soc_profile_mem_reference(unit, egr_action_profile[unit], 1819 EGR_ACTION_PROFILE_DEFAULT, 1); 1820 } 1821 } 1822 1823 /* Initialize the VLAN range profile table */ 1824 _bcm_trx_vlan_range_profile_init(unit); 1825 1826 #ifdef BCM_WARM_BOOT_SUPPORT 1827 /* Reload VLAN protocol action data */ 1828 if (SOC_WARM_BOOT(unit)) { 1829 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_port_protocol_action_reinit(unit)); 1830 } 1831 #endif /* BCM_WARM_BOOT_SUPPORT */ 1832 1833 return BCM_E_NONE; 1834 } 1835 1836 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || \ 1837 defined(BCM_KATANA2_SUPPORT) 1838 /* 1839 * Function : _bcm_th_port_vlan_action_profile_reinit 1840 * 1841 * Purpose : 1842 * Recover 'vlan_prot_ptr' in port_info structure. 1843 * Recover reference count of ING_VLAN_TAG_ACTION_PROFILE 1844 * for all Protocol-based VLANs. 1845 * 1846 * Note: 1847 * 'vlan_prot_ptr' in port_info structure was recovered 1848 * from scache for TH2. 1849 */ 1850 int 1851 _bcm_th_port_vlan_action_profile_reinit(int unit) 1852 { 1853 int rv = BCM_E_NONE; 1854 int i, idx; 1855 int vlan_prot_entries; 1856 bcm_port_t port; 1857 uint32 vlan_protocol_data_index = 0; 1858 _bcm_port_info_t *pinfo; 1859 bcm_pbmp_t all_pbmp; 1860 uint32 action_profile_idx; 1861 vlan_protocol_data_entry_t vde; 1862 1863 BCM_PBMP_CLEAR(all_pbmp); 1864 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 1865 1866 vlan_prot_entries = soc_mem_index_count(unit, VLAN_PROTOCOLm); 1867 PBMP_ITER(all_pbmp, port) { 1868 if (!IS_LB_PORT(unit, port)) { 1869 /* update vlan port protocol data memory */ 1870 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 1871 1872 /* TH2/TD3X/KT2 have already recovered it from scache */ 1873 if (!SOC_IS_TOMAHAWK2(unit) && !SOC_IS_TRIDENT3X(unit) && 1874 !SOC_IS_KATANA2(unit)) { 1875 /* Get VLAN_PROTOCOL_DATA_INDEXf in PORT_TAB. */ 1876 SOC_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, port, 1877 VLAN_PROTOCOL_DATA_INDEXf, &idx)); 1878 vlan_protocol_data_index = idx * vlan_prot_entries; 1879 pinfo->vlan_prot_ptr = vlan_protocol_data_index; 1880 1881 BCM_IF_ERROR_RETURN( 1882 _bcm_port_vlan_protocol_data_entry_reference (unit, 1883 vlan_protocol_data_index, 16)); 1884 } 1885 1886 for (i = 0; i < vlan_prot_entries; i++) { 1887 rv = READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, 1888 pinfo->vlan_prot_ptr + i, &vde); 1889 if (BCM_FAILURE(rv)) { 1890 return (rv); 1891 } 1892 action_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, 1893 &vde, TAG_ACTION_PROFILE_PTRf); 1894 if (SOC_IS_TRIDENT3X(unit)) { 1895 if (action_profile_idx >= ing_action_profile_def[unit]) { 1896 SOC_IF_ERROR_RETURN( 1897 soc_profile_mem_reference(unit, ing_action_profile[unit], 1898 action_profile_idx, 1)); 1899 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit], 1900 action_profile_idx - ing_action_profile_def[unit], 1); 1901 } 1902 } else { 1903 SOC_IF_ERROR_RETURN( 1904 soc_profile_mem_reference(unit, ing_action_profile[unit], 1905 action_profile_idx, 1)); 1906 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit], 1907 action_profile_idx, 1); 1908 } 1909 } 1910 } 1911 } 1912 1913 return (rv); 1914 } 1915 #endif 1916 1917 /* 1918 * Function : _bcm_trx_vlan_action_profile_entry_add 1919 * 1920 * Purpose : add a new entry to vlan action profile table 1921 */ 1922 int 1923 _bcm_trx_vlan_action_profile_entry_add(int unit, 1924 bcm_vlan_action_set_t *action, 1925 uint32 *index) 1926 { 1927 int rv = BCM_E_NONE; 1928 ing_vlan_tag_action_profile_entry_t entry1; 1929 ing_vlan_tag_action_profile_2_entry_t entry2; 1930 void *entries[2]; 1931 void *entry; 1932 soc_mem_t vtap_mem = ING_VLAN_TAG_ACTION_PROFILEm; 1933 1934 if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) { 1935 vtap_mem = ING_VLAN_TAG_ACTION_PROFILE_2m; 1936 sal_memset(&entry2, 0, sizeof(ing_vlan_tag_action_profile_2_entry_t)); 1937 entry = &entry2; 1938 } else { 1939 sal_memset(&entry1, 0, sizeof(ing_vlan_tag_action_profile_entry_t)); 1940 entry = &entry1; 1941 } 1942 1943 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 1944 1945 soc_mem_field32_set(unit, vtap_mem, entry, DT_OTAG_ACTIONf, 1946 _BCM_TRX_TAG_ACTION_ENCODE(action->dt_outer)); 1947 soc_mem_field32_set(unit, vtap_mem, entry, DT_POTAG_ACTIONf, 1948 _BCM_TRX_TAG_ACTION_ENCODE(action->dt_outer_prio)); 1949 soc_mem_field32_set(unit, vtap_mem, entry, DT_ITAG_ACTIONf, 1950 _BCM_TRX_TAG_ACTION_ENCODE(action->dt_inner)); 1951 soc_mem_field32_set(unit, vtap_mem, entry, DT_PITAG_ACTIONf, 1952 _BCM_TRX_TAG_ACTION_ENCODE(action->dt_inner_prio)); 1953 soc_mem_field32_set(unit, vtap_mem, entry, SOT_OTAG_ACTIONf, 1954 _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer)); 1955 soc_mem_field32_set(unit, vtap_mem, entry, SOT_POTAG_ACTIONf, 1956 _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer_prio)); 1957 soc_mem_field32_set(unit, vtap_mem, entry, SOT_ITAG_ACTIONf, 1958 _BCM_TRX_TAG_ACTION_ENCODE(action->ot_inner)); 1959 soc_mem_field32_set(unit, vtap_mem, entry, SIT_OTAG_ACTIONf, 1960 _BCM_TRX_TAG_ACTION_ENCODE(action->it_outer)); 1961 soc_mem_field32_set(unit, vtap_mem, entry, SIT_ITAG_ACTIONf, 1962 _BCM_TRX_TAG_ACTION_ENCODE(action->it_inner)); 1963 soc_mem_field32_set(unit, vtap_mem, entry, SIT_PITAG_ACTIONf, 1964 _BCM_TRX_TAG_ACTION_ENCODE(action->it_inner_prio)); 1965 soc_mem_field32_set(unit, vtap_mem, entry, UT_OTAG_ACTIONf, 1966 _BCM_TRX_TAG_ACTION_ENCODE(action->ut_outer)); 1967 soc_mem_field32_set(unit, vtap_mem, entry, UT_ITAG_ACTIONf, 1968 _BCM_TRX_TAG_ACTION_ENCODE(action->ut_inner)); 1969 1970 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 1971 soc_mem_field32_set 1972 (unit, vtap_mem, entry, DT_OPRI_ACTIONf, 1973 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_outer_pkt_prio)); 1974 soc_mem_field32_set 1975 (unit, vtap_mem, entry, DT_OCFI_ACTIONf, 1976 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_outer_cfi)); 1977 soc_mem_field32_set 1978 (unit, vtap_mem, entry, DT_IPRI_ACTIONf, 1979 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_inner_pkt_prio)); 1980 soc_mem_field32_set 1981 (unit, vtap_mem, entry, DT_ICFI_ACTIONf, 1982 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_inner_cfi)); 1983 soc_mem_field32_set 1984 (unit, vtap_mem, entry, SOT_OPRI_ACTIONf, 1985 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_pkt_prio)); 1986 soc_mem_field32_set 1987 (unit, vtap_mem, entry, SOT_OCFI_ACTIONf, 1988 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_cfi)); 1989 soc_mem_field32_set 1990 (unit, vtap_mem, entry, SOT_IPRI_ACTIONf, 1991 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_inner_pkt_prio)); 1992 soc_mem_field32_set 1993 (unit, vtap_mem, entry, SOT_ICFI_ACTIONf, 1994 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_inner_cfi)); 1995 soc_mem_field32_set 1996 (unit, vtap_mem, entry, SIT_OPRI_ACTIONf, 1997 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_outer_pkt_prio)); 1998 soc_mem_field32_set 1999 (unit, vtap_mem, entry, SIT_OCFI_ACTIONf, 2000 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_outer_cfi)); 2001 soc_mem_field32_set 2002 (unit, vtap_mem, entry, SIT_IPRI_ACTIONf, 2003 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_inner_pkt_prio)); 2004 soc_mem_field32_set 2005 (unit, vtap_mem, entry, SIT_ICFI_ACTIONf, 2006 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_inner_cfi)); 2007 soc_mem_field32_set 2008 (unit, vtap_mem, entry, UT_OPRI_ACTIONf, 2009 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_pkt_prio)); 2010 soc_mem_field32_set 2011 (unit, vtap_mem, entry, UT_OCFI_ACTIONf, 2012 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_cfi)); 2013 soc_mem_field32_set 2014 (unit, vtap_mem, entry, UT_IPRI_ACTIONf, 2015 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_inner_pkt_prio)); 2016 soc_mem_field32_set 2017 (unit, vtap_mem, entry, UT_ICFI_ACTIONf, 2018 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_inner_cfi)); 2019 2020 #if defined(BCM_TRIDENT2_SUPPORT) 2021 if (soc_feature(unit, soc_feature_fcoe)) { 2022 2023 /* overwrite just fcoe related fields (pri)*/ 2024 soc_mem_field32_set 2025 (unit, vtap_mem, entry, DT_OPRI_ACTIONf, 2026 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2027 action->dt_outer_pkt_prio)); 2028 soc_mem_field32_set 2029 (unit, vtap_mem, entry, DT_IPRI_ACTIONf, 2030 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2031 action->dt_inner_pkt_prio)); 2032 soc_mem_field32_set 2033 (unit, vtap_mem, entry, SOT_OPRI_ACTIONf, 2034 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2035 action->ot_outer_pkt_prio)); 2036 soc_mem_field32_set 2037 (unit, vtap_mem, entry, SOT_IPRI_ACTIONf, 2038 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2039 action->ot_inner_pkt_prio)); 2040 soc_mem_field32_set 2041 (unit, vtap_mem, entry, SIT_OPRI_ACTIONf, 2042 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2043 action->it_outer_pkt_prio)); 2044 soc_mem_field32_set 2045 (unit, vtap_mem, entry, SIT_IPRI_ACTIONf, 2046 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2047 action->it_inner_pkt_prio)); 2048 soc_mem_field32_set 2049 (unit, vtap_mem, entry, UT_OPRI_ACTIONf, 2050 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2051 action->ut_outer_pkt_prio)); 2052 soc_mem_field32_set 2053 (unit, vtap_mem, entry, UT_IPRI_ACTIONf, 2054 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2055 action->ut_inner_pkt_prio)); 2056 } 2057 #endif /* BCM_TRIDENT2_SUPPORT */ 2058 } 2059 2060 entries[0] = entry; 2061 entries[1] = entry; 2062 ING_VLAN_TAG_ACTION_LOCK(unit); 2063 rv = soc_profile_mem_add(unit, ing_action_profile[unit], 2064 (void *) &entries, 1, index); 2065 ING_VLAN_TAG_ACTION_UNLOCK(unit); 2066 return rv; 2067 } 2068 2069 #if defined(BCM_TRIDENT2_SUPPORT) 2070 2071 /* 2072 * add a new entry to ingress vlan action profile table(without modification) 2073 */ 2074 int 2075 _bcm_trx_ing_vlan_action_profile_entry_no_mod_add( 2076 int unit, 2077 ing_vlan_tag_action_profile_entry_t *entry, 2078 uint32 *index) 2079 { 2080 int rv = BCM_E_NONE; 2081 void *entries[2]; 2082 2083 entries[0] = entry; 2084 entries[1] = entry; 2085 ING_VLAN_TAG_ACTION_LOCK(unit); 2086 rv = soc_profile_mem_add(unit, ing_action_profile[unit], 2087 (void *) &entries, 1, index); 2088 ING_VLAN_TAG_ACTION_UNLOCK(unit); 2089 return rv; 2090 } 2091 2092 /* 2093 * add a new entry to egress vlan action profile table(without modification) 2094 */ 2095 int 2096 _bcm_trx_egr_vlan_action_profile_entry_no_mod_add( 2097 int unit, 2098 egr_vlan_tag_action_profile_entry_t *entry, 2099 uint32 *index) 2100 { 2101 int rv = BCM_E_NONE; 2102 void *entries[2]; 2103 2104 entries[0] = entry; 2105 entries[1] = entry; 2106 EGR_VLAN_TAG_ACTION_LOCK(unit); 2107 rv = soc_profile_mem_add(unit, egr_action_profile[unit], 2108 (void *) &entries, 1, index); 2109 EGR_VLAN_TAG_ACTION_UNLOCK(unit); 2110 return rv; 2111 } 2112 2113 #endif 2114 2115 2116 /* 2117 * Function : _bcm_trx_vlan_action_profile_entry_increment 2118 * 2119 * Purpose : increment the refcount for a vlan action profile table entry 2120 */ 2121 void 2122 _bcm_trx_vlan_action_profile_entry_increment(int unit, uint32 index) 2123 { 2124 /* In case other module try to increase default index */ 2125 if (index == 0) { 2126 index = ing_action_profile_def[unit]; 2127 } 2128 ING_VLAN_TAG_ACTION_LOCK(unit); 2129 (void)soc_profile_mem_reference(unit, ing_action_profile[unit], index, 1); 2130 ING_VLAN_TAG_ACTION_UNLOCK(unit); 2131 } 2132 2133 /* 2134 * Function : _bcm_trx_vlan_action_profile_entry_get 2135 * 2136 * Purpose : get a copy of cached vlan action profile table 2137 */ 2138 void 2139 _bcm_trx_vlan_action_profile_entry_get(int unit, 2140 bcm_vlan_action_set_t *action, 2141 uint32 index) 2142 { 2143 ing_vlan_tag_action_profile_entry_t p1; 2144 ing_vlan_tag_action_profile_2_entry_t p2; 2145 void *entries[2]; 2146 uint32 *entry; 2147 uint32 val; 2148 soc_mem_t mem = ING_VLAN_TAG_ACTION_PROFILEm; 2149 2150 if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) { 2151 mem = ING_VLAN_TAG_ACTION_PROFILE_2m; 2152 entries[0] = &p2; 2153 entries[1] = &p2; 2154 } else { 2155 entries[0] = &p1; 2156 } 2157 2158 ING_VLAN_TAG_ACTION_LOCK(unit); 2159 (void) soc_profile_mem_get(unit, ing_action_profile[unit], 2160 index, 1, entries); 2161 entry = entries[0]; 2162 2163 val = soc_mem_field32_get(unit, mem, entry, DT_OTAG_ACTIONf); 2164 action->dt_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 2165 2166 val = soc_mem_field32_get(unit, mem, entry, DT_POTAG_ACTIONf); 2167 action->dt_outer_prio = _BCM_TRX_TAG_ACTION_DECODE(val); 2168 2169 val = soc_mem_field32_get(unit, mem, entry, DT_ITAG_ACTIONf); 2170 action->dt_inner = _BCM_TRX_TAG_ACTION_DECODE(val); 2171 2172 val = soc_mem_field32_get(unit, mem, entry, DT_PITAG_ACTIONf); 2173 action->dt_inner_prio = _BCM_TRX_TAG_ACTION_DECODE(val); 2174 2175 val = soc_mem_field32_get(unit, mem, entry, SOT_OTAG_ACTIONf); 2176 action->ot_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 2177 2178 val = soc_mem_field32_get(unit, mem, entry, SOT_POTAG_ACTIONf); 2179 action->ot_outer_prio = _BCM_TRX_TAG_ACTION_DECODE(val); 2180 2181 val = soc_mem_field32_get(unit, mem, entry, SOT_ITAG_ACTIONf); 2182 action->ot_inner = _BCM_TRX_TAG_ACTION_DECODE(val); 2183 2184 val = soc_mem_field32_get(unit, mem, entry, SIT_OTAG_ACTIONf); 2185 action->it_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 2186 2187 val = soc_mem_field32_get(unit, mem, entry, SIT_ITAG_ACTIONf); 2188 action->it_inner = _BCM_TRX_TAG_ACTION_DECODE(val); 2189 2190 val = soc_mem_field32_get(unit, mem, entry, SIT_PITAG_ACTIONf); 2191 action->it_inner_prio = _BCM_TRX_TAG_ACTION_DECODE(val); 2192 2193 val = soc_mem_field32_get(unit, mem, entry, UT_OTAG_ACTIONf); 2194 action->ut_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 2195 2196 val = soc_mem_field32_get(unit, mem, entry, UT_ITAG_ACTIONf); 2197 action->ut_inner = _BCM_TRX_TAG_ACTION_DECODE(val); 2198 2199 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 2200 val = soc_mem_field32_get(unit, mem, entry, DT_OPRI_ACTIONf); 2201 action->dt_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2202 2203 val = soc_mem_field32_get(unit, mem, entry, DT_OCFI_ACTIONf); 2204 action->dt_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2205 2206 val = soc_mem_field32_get(unit, mem, entry, DT_IPRI_ACTIONf); 2207 action->dt_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2208 2209 val = soc_mem_field32_get(unit, mem, entry, DT_ICFI_ACTIONf); 2210 action->dt_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2211 2212 val = soc_mem_field32_get(unit, mem, entry, SOT_OPRI_ACTIONf); 2213 action->ot_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2214 2215 val = soc_mem_field32_get(unit, mem, entry, SOT_OCFI_ACTIONf); 2216 action->ot_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2217 2218 val = soc_mem_field32_get(unit, mem, entry, SOT_IPRI_ACTIONf); 2219 action->ot_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2220 2221 val = soc_mem_field32_get(unit, mem, entry, SOT_ICFI_ACTIONf); 2222 action->ot_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2223 2224 val = soc_mem_field32_get(unit, mem, entry, SIT_OPRI_ACTIONf); 2225 action->it_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2226 2227 val = soc_mem_field32_get(unit, mem, entry, SIT_OCFI_ACTIONf); 2228 action->it_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2229 2230 val = soc_mem_field32_get(unit, mem, entry, SIT_IPRI_ACTIONf); 2231 action->it_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2232 2233 val = soc_mem_field32_get(unit, mem, entry, SIT_ICFI_ACTIONf); 2234 action->it_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2235 2236 val = soc_mem_field32_get(unit, mem, entry, UT_OPRI_ACTIONf); 2237 action->ut_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2238 2239 val = soc_mem_field32_get(unit, mem, entry, UT_OCFI_ACTIONf); 2240 action->ut_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2241 2242 val = soc_mem_field32_get(unit, mem, entry, UT_IPRI_ACTIONf); 2243 action->ut_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2244 2245 val = soc_mem_field32_get(unit, mem, entry, UT_ICFI_ACTIONf); 2246 action->ut_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2247 2248 #if defined(BCM_TRIDENT2_SUPPORT) 2249 2250 if (soc_feature(unit, soc_feature_fcoe)) { 2251 2252 /* overwrite only fcoe related values (pri) */ 2253 2254 val = soc_mem_field32_get(unit, mem, entry, DT_OPRI_ACTIONf); 2255 action->dt_outer_pkt_prio = 2256 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2257 2258 val = soc_mem_field32_get(unit, mem, entry, DT_IPRI_ACTIONf); 2259 action->dt_inner_pkt_prio = 2260 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2261 2262 val = soc_mem_field32_get(unit, mem, entry, SOT_OPRI_ACTIONf); 2263 action->ot_outer_pkt_prio = 2264 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2265 2266 val = soc_mem_field32_get(unit, mem, entry, SOT_IPRI_ACTIONf); 2267 action->ot_inner_pkt_prio = 2268 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2269 2270 val = soc_mem_field32_get(unit, mem, entry, SIT_OPRI_ACTIONf); 2271 action->it_outer_pkt_prio = 2272 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2273 2274 val = soc_mem_field32_get(unit, mem, entry, SIT_IPRI_ACTIONf); 2275 action->it_inner_pkt_prio = 2276 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2277 2278 val = soc_mem_field32_get(unit, mem, entry, UT_OPRI_ACTIONf); 2279 action->ut_outer_pkt_prio = 2280 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2281 2282 val = soc_mem_field32_get(unit, mem, entry, UT_IPRI_ACTIONf); 2283 action->ut_inner_pkt_prio = 2284 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2285 2286 } 2287 #endif /* BCM_TRIDENT2_SUPPORT */ 2288 2289 } else { 2290 action->dt_outer_pkt_prio = bcmVlanActionNone; 2291 action->dt_outer_cfi = bcmVlanActionNone; 2292 action->dt_inner_pkt_prio = bcmVlanActionNone; 2293 action->dt_inner_cfi = bcmVlanActionNone; 2294 action->ot_outer_pkt_prio = bcmVlanActionNone; 2295 action->ot_outer_cfi = bcmVlanActionNone; 2296 action->ot_inner_pkt_prio = bcmVlanActionNone; 2297 action->ot_inner_cfi = bcmVlanActionNone; 2298 action->it_outer_pkt_prio = bcmVlanActionNone; 2299 action->it_outer_cfi = bcmVlanActionNone; 2300 action->it_inner_pkt_prio = bcmVlanActionNone; 2301 action->it_inner_cfi = bcmVlanActionNone; 2302 action->ut_outer_pkt_prio = bcmVlanActionNone; 2303 action->ut_outer_cfi = bcmVlanActionNone; 2304 action->ut_inner_pkt_prio = bcmVlanActionNone; 2305 action->ut_inner_cfi = bcmVlanActionNone; 2306 } 2307 ING_VLAN_TAG_ACTION_UNLOCK(unit); 2308 2309 } 2310 2311 /* 2312 * Function : _bcm_trx_vlan_action_profile_entry_delete 2313 * 2314 * Purpose : remove an entry from vlan action profile table 2315 */ 2316 int 2317 _bcm_trx_vlan_action_profile_entry_delete(int unit, uint32 index) 2318 { 2319 int rv = BCM_E_NONE; 2320 2321 if (index >= ing_action_profile_def[unit]) { 2322 ING_VLAN_TAG_ACTION_LOCK(unit); 2323 rv = soc_profile_mem_delete(unit, ing_action_profile[unit], index); 2324 ING_VLAN_TAG_ACTION_UNLOCK(unit); 2325 } 2326 return rv; 2327 } 2328 2329 /* 2330 * Function : _bcm_trx_egr_vlan_action_profile_entry_add 2331 * 2332 * Purpose : add a new entry to egress vlan action profile table 2333 */ 2334 int 2335 _bcm_trx_egr_vlan_action_profile_entry_add(int unit, 2336 bcm_vlan_action_set_t *action, 2337 uint32 *index) 2338 { 2339 int rv = BCM_E_NONE; 2340 egr_vlan_tag_action_profile_entry_t entry1; 2341 egr_vlan_tag_action_profile_2_entry_t entry2; 2342 void *entries[2]; 2343 void *entry; 2344 soc_mem_t mem = EGR_VLAN_TAG_ACTION_PROFILEm; 2345 2346 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m)) { 2347 mem = EGR_VLAN_TAG_ACTION_PROFILE_2m; 2348 sal_memset(&entry2, 0, sizeof(entry2)); 2349 entry = &entry2; 2350 } else { 2351 sal_memset(&entry1, 0, sizeof(entry1)); 2352 entry = &entry1; 2353 } 2354 2355 soc_mem_field32_set(unit, mem, entry, DT_OTAG_ACTIONf, 2356 _BCM_TRX_TAG_ACTION_ENCODE(action->dt_outer)); 2357 soc_mem_field32_set(unit, mem, entry, DT_ITAG_ACTIONf, 2358 _BCM_TRX_TAG_ACTION_ENCODE(action->dt_inner)); 2359 soc_mem_field32_set(unit, mem, entry, DT_PITAG_ACTIONf, 2360 _BCM_TRX_TAG_ACTION_ENCODE(action->dt_inner_prio)); 2361 soc_mem_field32_set(unit, mem, entry, SOT_OTAG_ACTIONf, 2362 _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer)); 2363 soc_mem_field32_set(unit, mem, entry, SOT_ITAG_ACTIONf, 2364 _BCM_TRX_TAG_ACTION_ENCODE(action->ot_inner)); 2365 2366 #if defined(BCM_TRIDENT2_SUPPORT) 2367 2368 if (soc_feature(unit, soc_feature_fcoe)) { 2369 soc_mem_field32_set(unit, mem, entry, DT_OTAG_ACTIONf, 2370 _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT( 2371 action->dt_outer)); 2372 soc_mem_field32_set(unit, mem, entry, DT_ITAG_ACTIONf, 2373 _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT( 2374 action->dt_inner)); 2375 soc_mem_field32_set(unit, mem, entry, DT_PITAG_ACTIONf, 2376 _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT( 2377 action->dt_inner_prio)); 2378 soc_mem_field32_set(unit, mem, entry, SOT_OTAG_ACTIONf, 2379 _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT( 2380 action->ot_outer)); 2381 soc_mem_field32_set(unit, mem, entry, SOT_ITAG_ACTIONf, 2382 _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT( 2383 action->ot_inner)); 2384 } 2385 2386 #endif /* BCM_TRIDENT2_SUPPORT */ 2387 2388 if (soc_feature(unit, soc_feature_vlan_egr_it_inner_replace)) { 2389 soc_mem_field32_set(unit, mem, entry, DT_POTAG_ACTIONf, 2390 _BCM_TRX_TAG_ACTION_ENCODE(action->dt_outer_prio)); 2391 soc_mem_field32_set(unit, mem, entry, SOT_POTAG_ACTIONf, 2392 _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer_prio)); 2393 soc_mem_field32_set(unit, mem, entry, SIT_OTAG_ACTIONf, 2394 _BCM_TRX_TAG_ACTION_ENCODE(action->it_outer)); 2395 soc_mem_field32_set(unit, mem, entry, SIT_ITAG_ACTIONf, 2396 _BCM_TRX_TAG_ACTION_ENCODE(action->it_inner)); 2397 soc_mem_field32_set(unit, mem, entry, SIT_PITAG_ACTIONf, 2398 _BCM_TRX_TAG_ACTION_ENCODE(action->it_inner_prio)); 2399 soc_mem_field32_set(unit, mem, entry, UT_OTAG_ACTIONf, 2400 _BCM_TRX_TAG_ACTION_ENCODE(action->ut_outer)); 2401 soc_mem_field32_set(unit, mem, entry, UT_ITAG_ACTIONf, 2402 _BCM_TRX_TAG_ACTION_ENCODE(action->ut_inner)); 2403 } 2404 2405 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 2406 soc_mem_field32_set 2407 (unit, mem, entry, DT_OPRI_ACTIONf, 2408 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_outer_pkt_prio)); 2409 soc_mem_field32_set 2410 (unit, mem, entry, DT_OCFI_ACTIONf, 2411 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_outer_cfi)); 2412 soc_mem_field32_set 2413 (unit, mem, entry, DT_IPRI_ACTIONf, 2414 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_inner_pkt_prio)); 2415 soc_mem_field32_set 2416 (unit, mem, entry, DT_ICFI_ACTIONf, 2417 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_inner_cfi)); 2418 soc_mem_field32_set 2419 (unit, mem, entry, SOT_OPRI_ACTIONf, 2420 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_pkt_prio)); 2421 soc_mem_field32_set 2422 (unit, mem, entry, SOT_OCFI_ACTIONf, 2423 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_cfi)); 2424 soc_mem_field32_set 2425 (unit, mem, entry, SOT_IPRI_ACTIONf, 2426 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_inner_pkt_prio)); 2427 soc_mem_field32_set 2428 (unit, mem, entry, SOT_ICFI_ACTIONf, 2429 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_inner_cfi)); 2430 soc_mem_field32_set 2431 (unit, mem, entry, SIT_OPRI_ACTIONf, 2432 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_outer_pkt_prio)); 2433 soc_mem_field32_set 2434 (unit, mem, entry, SIT_OCFI_ACTIONf, 2435 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_outer_cfi)); 2436 soc_mem_field32_set 2437 (unit, mem, entry, SIT_IPRI_ACTIONf, 2438 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_inner_pkt_prio)); 2439 soc_mem_field32_set 2440 (unit, mem, entry, SIT_ICFI_ACTIONf, 2441 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_inner_cfi)); 2442 soc_mem_field32_set 2443 (unit, mem, entry, UT_OPRI_ACTIONf, 2444 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_pkt_prio)); 2445 soc_mem_field32_set 2446 (unit, mem, entry, UT_OCFI_ACTIONf, 2447 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_cfi)); 2448 soc_mem_field32_set 2449 (unit, mem, entry, UT_IPRI_ACTIONf, 2450 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_inner_pkt_prio)); 2451 soc_mem_field32_set 2452 (unit, mem, entry, UT_ICFI_ACTIONf, 2453 _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_inner_cfi)); 2454 2455 #if defined(BCM_TRIDENT2_SUPPORT) 2456 2457 if (soc_feature(unit, soc_feature_fcoe)) { 2458 2459 /* overwrite fcoe related fields (pri) */ 2460 soc_mem_field32_set 2461 (unit, mem, entry, DT_OPRI_ACTIONf, 2462 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2463 action->dt_outer_pkt_prio)); 2464 soc_mem_field32_set 2465 (unit, mem, entry, DT_IPRI_ACTIONf, 2466 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2467 action->dt_inner_pkt_prio)); 2468 soc_mem_field32_set 2469 (unit, mem, entry, SOT_OPRI_ACTIONf, 2470 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2471 action->ot_outer_pkt_prio)); 2472 soc_mem_field32_set 2473 (unit, mem, entry, SOT_IPRI_ACTIONf, 2474 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2475 action->ot_inner_pkt_prio)); 2476 soc_mem_field32_set 2477 (unit, mem, entry, SIT_OPRI_ACTIONf, 2478 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2479 action->it_outer_pkt_prio)); 2480 soc_mem_field32_set 2481 (unit, mem, entry, SIT_IPRI_ACTIONf, 2482 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2483 action->it_inner_pkt_prio)); 2484 soc_mem_field32_set 2485 (unit, mem, entry, UT_OPRI_ACTIONf, 2486 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2487 action->ut_outer_pkt_prio)); 2488 soc_mem_field32_set 2489 (unit, mem, entry, UT_IPRI_ACTIONf, 2490 _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT( 2491 action->ut_inner_pkt_prio)); 2492 } 2493 #endif /* BCM_TRIDENT2_SUPPORT */ 2494 } 2495 2496 #if defined(BCM_TRIDENT3_SUPPORT) 2497 if (soc_mem_field_valid(unit, mem, OTPID_ACTIONf)) { 2498 soc_mem_field32_set 2499 (unit, mem, entry, OTPID_ACTIONf, 2500 _BCM_TD3_TPID_ACTION_ENCODE(action->outer_tpid_action)); 2501 } 2502 #endif 2503 2504 entries[0] = entry; 2505 entries[1] = entry; 2506 EGR_VLAN_TAG_ACTION_LOCK(unit); 2507 rv = soc_profile_mem_add(unit, egr_action_profile[unit], 2508 (void *) &entries, 1, index); 2509 EGR_VLAN_TAG_ACTION_UNLOCK(unit); 2510 return rv; 2511 } 2512 2513 /* 2514 * Function : _bcm_trx_egr_vlan_action_profile_entry_increment 2515 * 2516 * Purpose : increment the refcount for an egress vlan action profile table entry 2517 */ 2518 void 2519 _bcm_trx_egr_vlan_action_profile_entry_increment(int unit, uint32 index) 2520 { 2521 #if defined(BCM_TOMAHAWK3_SUPPORT) 2522 if (SOC_IS_TOMAHAWK3(unit)) { 2523 _bcm_th3_egr_vlan_action_profile_entry_increment(unit, index); 2524 return; 2525 } 2526 #endif/* BCM_TOMAHAWK3_SUPPORT */ 2527 EGR_VLAN_TAG_ACTION_LOCK(unit); 2528 soc_profile_mem_reference(unit, egr_action_profile[unit], 2529 index, 1); 2530 EGR_VLAN_TAG_ACTION_UNLOCK(unit); 2531 } 2532 2533 /* 2534 * Function : _bcm_trx_egr_vlan_action_profile_entry_get 2535 * 2536 * Purpose : get a copy of cached egress vlan action profile table 2537 */ 2538 void 2539 _bcm_trx_egr_vlan_action_profile_entry_get(int unit, 2540 bcm_vlan_action_set_t *action, 2541 uint32 index) 2542 { 2543 egr_vlan_tag_action_profile_entry_t p1; 2544 egr_vlan_tag_action_profile_2_entry_t p2; 2545 void *entries[2]; 2546 uint32 *entry; 2547 uint32 val; 2548 soc_mem_t mem = EGR_VLAN_TAG_ACTION_PROFILEm; 2549 2550 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m)) { 2551 mem = EGR_VLAN_TAG_ACTION_PROFILE_2m; 2552 entries[0] = &p1; 2553 entries[1] = &p2; 2554 } else { 2555 entries[0] = &p1; 2556 } 2557 2558 EGR_VLAN_TAG_ACTION_LOCK(unit); 2559 (void) soc_profile_mem_get(unit, egr_action_profile[unit], 2560 index, 1, entries); 2561 entry = entries[0]; 2562 2563 val = soc_mem_field32_get(unit, mem, entry, DT_OTAG_ACTIONf); 2564 action->dt_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 2565 2566 val = soc_mem_field32_get(unit, mem, entry, DT_ITAG_ACTIONf); 2567 action->dt_inner = _BCM_TRX_TAG_ACTION_DECODE(val); 2568 2569 val = soc_mem_field32_get(unit, mem, entry, DT_PITAG_ACTIONf); 2570 action->dt_inner_prio = _BCM_TRX_TAG_ACTION_DECODE(val); 2571 2572 val = soc_mem_field32_get(unit, mem, entry, SOT_OTAG_ACTIONf); 2573 action->ot_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 2574 2575 val = soc_mem_field32_get(unit, mem, entry, SOT_ITAG_ACTIONf); 2576 action->ot_inner = _BCM_TRX_TAG_ACTION_DECODE(val); 2577 2578 #if defined(BCM_TRIDENT3_SUPPORT) 2579 if (soc_mem_field_valid(unit, mem, OTPID_ACTIONf)) { 2580 val = soc_mem_field32_get(unit, mem, entry, OTPID_ACTIONf); 2581 action->outer_tpid_action = _BCM_TD3_TPID_ACTION_DECODE(val); 2582 } 2583 #endif 2584 2585 #if defined(BCM_TRIDENT2_SUPPORT) 2586 2587 if (soc_feature(unit, soc_feature_fcoe)) { 2588 val = soc_mem_field32_get(unit, mem, entry, DT_OTAG_ACTIONf); 2589 action->dt_outer = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val); 2590 2591 val = soc_mem_field32_get(unit, mem, entry, DT_ITAG_ACTIONf); 2592 action->dt_inner = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val); 2593 2594 val = soc_mem_field32_get(unit, mem, entry, DT_PITAG_ACTIONf); 2595 action->dt_inner_prio = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val); 2596 2597 val = soc_mem_field32_get(unit, mem, entry, SOT_OTAG_ACTIONf); 2598 action->ot_outer = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val); 2599 2600 val = soc_mem_field32_get(unit, mem, entry, SOT_ITAG_ACTIONf); 2601 action->ot_inner = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val); 2602 } 2603 2604 #endif /* BCM_TRIDENT2_SUPPORT */ 2605 2606 if (soc_feature(unit, soc_feature_vlan_egr_it_inner_replace)) { 2607 val = soc_mem_field32_get(unit, mem, entry, DT_POTAG_ACTIONf); 2608 action->dt_outer_prio = _BCM_TRX_TAG_ACTION_DECODE(val); 2609 2610 val = soc_mem_field32_get(unit, mem, entry, SOT_POTAG_ACTIONf); 2611 action->ot_outer_prio = _BCM_TRX_TAG_ACTION_DECODE(val); 2612 2613 val = soc_mem_field32_get(unit, mem, entry, SIT_OTAG_ACTIONf); 2614 action->it_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 2615 2616 val = soc_mem_field32_get(unit, mem, entry, SIT_ITAG_ACTIONf); 2617 action->it_inner = _BCM_TRX_TAG_ACTION_DECODE(val); 2618 2619 val = soc_mem_field32_get(unit, mem, entry, SIT_PITAG_ACTIONf); 2620 action->it_inner_prio = _BCM_TRX_TAG_ACTION_DECODE(val); 2621 2622 val = soc_mem_field32_get(unit, mem, entry, UT_OTAG_ACTIONf); 2623 action->ut_outer = _BCM_TRX_TAG_ACTION_DECODE(val); 2624 2625 val = soc_mem_field32_get(unit, mem, entry, UT_ITAG_ACTIONf); 2626 action->ut_inner = _BCM_TRX_TAG_ACTION_DECODE(val); 2627 } else { 2628 action->it_outer = bcmVlanActionNone; 2629 action->it_inner = bcmVlanActionNone; 2630 action->it_inner_prio = bcmVlanActionNone; 2631 action->ut_outer = bcmVlanActionNone; 2632 action->ut_inner = bcmVlanActionNone; 2633 } 2634 2635 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 2636 val = soc_mem_field32_get(unit, mem, entry, DT_OPRI_ACTIONf); 2637 action->dt_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2638 2639 val = soc_mem_field32_get(unit, mem, entry, DT_OCFI_ACTIONf); 2640 action->dt_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2641 2642 val = soc_mem_field32_get(unit, mem, entry, DT_IPRI_ACTIONf); 2643 action->dt_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2644 2645 val = soc_mem_field32_get(unit, mem, entry, DT_ICFI_ACTIONf); 2646 action->dt_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2647 2648 val = soc_mem_field32_get(unit, mem, entry, SOT_OPRI_ACTIONf); 2649 action->ot_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2650 2651 val = soc_mem_field32_get(unit, mem, entry, SOT_OCFI_ACTIONf); 2652 action->ot_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2653 2654 val = soc_mem_field32_get(unit, mem, entry, SOT_IPRI_ACTIONf); 2655 action->ot_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2656 2657 val = soc_mem_field32_get(unit, mem, entry, SOT_ICFI_ACTIONf); 2658 action->ot_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2659 2660 val = soc_mem_field32_get(unit, mem, entry, SIT_OPRI_ACTIONf); 2661 action->it_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2662 2663 val = soc_mem_field32_get(unit, mem, entry, SIT_OCFI_ACTIONf); 2664 action->it_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2665 2666 val = soc_mem_field32_get(unit, mem, entry, SIT_IPRI_ACTIONf); 2667 action->it_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2668 2669 val = soc_mem_field32_get(unit, mem, entry, SIT_ICFI_ACTIONf); 2670 action->it_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2671 2672 val = soc_mem_field32_get(unit, mem, entry, UT_OPRI_ACTIONf); 2673 action->ut_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2674 2675 val = soc_mem_field32_get(unit, mem, entry, UT_OCFI_ACTIONf); 2676 action->ut_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2677 2678 val = soc_mem_field32_get(unit, mem, entry, UT_IPRI_ACTIONf); 2679 action->ut_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2680 2681 val = soc_mem_field32_get(unit, mem, entry, UT_ICFI_ACTIONf); 2682 action->ut_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val); 2683 2684 #if defined(BCM_TRIDENT2_SUPPORT) 2685 2686 if (soc_feature(unit, soc_feature_fcoe)) { 2687 2688 /* overwrite fcoe related values (pri) */ 2689 val = soc_mem_field32_get(unit, mem, entry, DT_OPRI_ACTIONf); 2690 action->dt_outer_pkt_prio = 2691 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2692 2693 val = soc_mem_field32_get(unit, mem, entry, DT_IPRI_ACTIONf); 2694 action->dt_inner_pkt_prio = 2695 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2696 2697 val = soc_mem_field32_get(unit, mem, entry, SOT_OPRI_ACTIONf); 2698 action->ot_outer_pkt_prio = 2699 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2700 2701 val = soc_mem_field32_get(unit, mem, entry, SOT_IPRI_ACTIONf); 2702 action->ot_inner_pkt_prio = 2703 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2704 2705 val = soc_mem_field32_get(unit, mem, entry, SIT_OPRI_ACTIONf); 2706 action->it_outer_pkt_prio = 2707 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2708 2709 val = soc_mem_field32_get(unit, mem, entry, SIT_IPRI_ACTIONf); 2710 action->it_inner_pkt_prio = 2711 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2712 2713 val = soc_mem_field32_get(unit, mem, entry, UT_OPRI_ACTIONf); 2714 action->ut_outer_pkt_prio = 2715 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2716 2717 val = soc_mem_field32_get(unit, mem, entry, 2718 UT_IPRI_ACTIONf); 2719 action->ut_inner_pkt_prio = 2720 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val); 2721 2722 } 2723 2724 #endif /* BCM_TRIDENT2_SUPPORT */ 2725 2726 } else { 2727 action->dt_outer_pkt_prio = bcmVlanActionNone; 2728 action->dt_outer_cfi = bcmVlanActionNone; 2729 action->dt_inner_pkt_prio = bcmVlanActionNone; 2730 action->dt_inner_cfi = bcmVlanActionNone; 2731 action->ot_outer_pkt_prio = bcmVlanActionNone; 2732 action->ot_outer_cfi = bcmVlanActionNone; 2733 action->ot_inner_pkt_prio = bcmVlanActionNone; 2734 action->ot_inner_cfi = bcmVlanActionNone; 2735 action->it_outer_pkt_prio = bcmVlanActionNone; 2736 action->it_outer_cfi = bcmVlanActionNone; 2737 action->it_inner_pkt_prio = bcmVlanActionNone; 2738 action->it_inner_cfi = bcmVlanActionNone; 2739 action->ut_outer_pkt_prio = bcmVlanActionNone; 2740 action->ut_outer_cfi = bcmVlanActionNone; 2741 action->ut_inner_pkt_prio = bcmVlanActionNone; 2742 action->ut_inner_cfi = bcmVlanActionNone; 2743 } 2744 EGR_VLAN_TAG_ACTION_UNLOCK(unit); 2745 } 2746 2747 /* 2748 * Function : _bcm_trx_egr_vlan_action_profile_entry_delete 2749 * 2750 * Purpose : remove an entry from egress vlan action profile table 2751 */ 2752 int 2753 _bcm_trx_egr_vlan_action_profile_entry_delete(int unit, uint32 index) 2754 { 2755 int rv = BCM_E_NONE; 2756 2757 EGR_VLAN_TAG_ACTION_LOCK(unit); 2758 rv = soc_profile_mem_delete(unit, egr_action_profile[unit], index); 2759 EGR_VLAN_TAG_ACTION_UNLOCK(unit); 2760 return rv; 2761 } 2762 2763 STATIC soc_field_t _tr_range_min_f[] = {VLAN_MIN_0f, VLAN_MIN_1f, 2764 VLAN_MIN_2f, VLAN_MIN_3f, 2765 VLAN_MIN_4f, VLAN_MIN_5f, 2766 VLAN_MIN_6f, VLAN_MIN_7f}; 2767 STATIC soc_field_t _tr_range_max_f[] = {VLAN_MAX_0f, VLAN_MAX_1f, 2768 VLAN_MAX_2f, VLAN_MAX_3f, 2769 VLAN_MAX_4f, VLAN_MAX_5f, 2770 VLAN_MAX_6f, VLAN_MAX_7f}; 2771 2772 /* 2773 * Function : bcm_trx_vlan_range_profile_init 2774 * 2775 * Purpose : to initialize hardware ING_VLAN_RANGE table 2776 * allocate memory to cache hardware tables in RAM. 2777 * 2778 * Note: 2779 * Allocate memory to cache the profile tables and initialize. 2780 * If memory to cache the profile table is already allocated, just 2781 * initialize the table. 2782 */ 2783 STATIC int 2784 _bcm_trx_vlan_range_profile_init(int unit) 2785 { 2786 int i, idx, inner_idx; 2787 source_trunk_map_table_entry_t stm_entry; 2788 trunk32_port_table_entry_t trunk32_entry; 2789 ing_vlan_range_entry_t profile_entry; 2790 uint32 temp_index, temp_inner_index; 2791 soc_mem_t mem; 2792 int entry_words; 2793 void *entries[1]; 2794 soc_field_t field; 2795 2796 /* Initialize the ING_VLAN_RANGE table */ 2797 2798 if (vlan_range_profile[unit] == NULL) { 2799 vlan_range_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t), 2800 "Vlan Range Profile Mem"); 2801 if (vlan_range_profile[unit] == NULL) { 2802 return BCM_E_MEMORY; 2803 } 2804 soc_profile_mem_t_init(vlan_range_profile[unit]); 2805 } 2806 2807 /* Create profile table cache (or re-init if it already exists) */ 2808 mem = ING_VLAN_RANGEm; 2809 entry_words = sizeof(ing_vlan_range_entry_t) / sizeof(uint32); 2810 SOC_IF_ERROR_RETURN(soc_profile_mem_create(unit, &mem, &entry_words, 1, 2811 vlan_range_profile[unit])); 2812 2813 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 2814 OUTER_VLAN_RANGE_IDXf)) { 2815 field = OUTER_VLAN_RANGE_IDXf; 2816 } else { 2817 field = VLAN_RANGE_IDXf; 2818 } 2819 if (SOC_WARM_BOOT(unit)) { 2820 /* Increment the ref count for all ports */ 2821 for (i = 0; 2822 i < soc_mem_index_count(unit, SOURCE_TRUNK_MAP_TABLEm); i++) { 2823 SOC_IF_ERROR_RETURN 2824 (READ_SOURCE_TRUNK_MAP_TABLEm(unit, 2825 MEM_BLOCK_ANY, i, &stm_entry)); 2826 2827 idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 2828 &stm_entry, field); 2829 SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], idx, 1); 2830 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, vlan_range_profile[unit], 2831 idx, 1); 2832 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 2833 INNER_VLAN_RANGE_IDXf)) { 2834 inner_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 2835 &stm_entry, INNER_VLAN_RANGE_IDXf); 2836 SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], 2837 inner_idx, 1); 2838 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, vlan_range_profile[unit], 2839 inner_idx, 1); 2840 } 2841 } 2842 2843 if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) { 2844 if (!soc_property_get(unit, spn_TRUNK_EXTEND, 1)) { 2845 for (i = 0; 2846 i < soc_mem_index_count(unit, TRUNK32_PORT_TABLEm); i++) { 2847 SOC_IF_ERROR_RETURN 2848 (READ_TRUNK32_PORT_TABLEm(unit, 2849 MEM_BLOCK_ANY, i, &trunk32_entry)); 2850 idx = soc_mem_field32_get(unit, TRUNK32_PORT_TABLEm, 2851 &trunk32_entry, VLAN_RANGE_IDXf); 2852 SOC_PROFILE_MEM_REFERENCE(unit, 2853 vlan_range_profile[unit], idx, 1); 2854 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, 2855 vlan_range_profile[unit], idx, 1); 2856 } 2857 } 2858 } 2859 2860 /* One extra increment to preserve location VLAN_RANGE_PROFILE_DEFAULT */ 2861 SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], 2862 VLAN_RANGE_PROFILE_DEFAULT, 1); 2863 2864 } else { 2865 int rv, size; 2866 source_trunk_map_table_entry_t *ent; 2867 uint8 *mbuf; 2868 2869 sal_memset(&profile_entry, 0, sizeof(ing_vlan_range_entry_t)); 2870 for (i = 0; i < 8; i++) { 2871 soc_mem_field32_set(unit, ING_VLAN_RANGEm, 2872 &profile_entry, _tr_range_min_f[i], 1); 2873 soc_mem_field32_set(unit, ING_VLAN_RANGEm, 2874 &profile_entry, _tr_range_max_f[i], 0); 2875 } 2876 2877 /* Initialize the VLAN_RANGE_PROFILE_DEFAULT to have 2878 * all ranges unused (min == 1, max == 0). 2879 */ 2880 entries[0] = &profile_entry; 2881 SOC_IF_ERROR_RETURN 2882 (soc_profile_mem_add(unit, vlan_range_profile[unit], 2883 (void *) &entries, 1, &temp_index)); 2884 2885 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 2886 INNER_VLAN_RANGE_IDXf)) { 2887 SOC_IF_ERROR_RETURN 2888 (soc_profile_mem_add(unit, vlan_range_profile[unit], 2889 (void *) &entries, 1, &temp_inner_index)); 2890 } 2891 2892 size = SOC_MEM_TABLE_BYTES(unit, SOURCE_TRUNK_MAP_TABLEm); 2893 mbuf = soc_cm_salloc(unit, size, "SOURCE_TRUNK_MAP_TABLE"); 2894 if (NULL == mbuf) { 2895 return BCM_E_MEMORY; 2896 } 2897 2898 soc_mem_lock(unit, SOURCE_TRUNK_MAP_TABLEm); 2899 rv = soc_mem_read_range(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY, 2900 soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm), 2901 soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm), 2902 mbuf); 2903 if (BCM_FAILURE(rv)) { 2904 soc_cm_sfree(unit, mbuf); 2905 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 2906 return rv; 2907 } 2908 /* Increment the ref count for all ports */ 2909 for (i = 0; 2910 i < soc_mem_index_count(unit, SOURCE_TRUNK_MAP_TABLEm); i++) { 2911 ent = soc_mem_table_idx_to_pointer(unit, 2912 SOURCE_TRUNK_MAP_TABLEm, 2913 source_trunk_map_table_entry_t *, mbuf, i); 2914 2915 soc_mem_field32_set(unit, SOURCE_TRUNK_MAP_TABLEm, ent, field, 2916 temp_index); 2917 2918 SOC_PROFILE_MEM_REFERENCE(unit, 2919 vlan_range_profile[unit], temp_index, 1); 2920 2921 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 2922 INNER_VLAN_RANGE_IDXf)) { 2923 soc_mem_field32_set(unit, SOURCE_TRUNK_MAP_TABLEm, ent, 2924 INNER_VLAN_RANGE_IDXf, temp_inner_index); 2925 SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], 2926 temp_inner_index, 1); 2927 } 2928 } 2929 rv = soc_mem_write_range(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY, 2930 soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm), 2931 soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm), 2932 mbuf); 2933 soc_cm_sfree(unit, mbuf); 2934 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 2935 if (BCM_FAILURE(rv)) { 2936 return rv; 2937 } 2938 2939 if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) { 2940 if (!soc_property_get(unit, spn_TRUNK_EXTEND, 1)) { 2941 for (i = 0; 2942 i < soc_mem_index_count(unit, TRUNK32_PORT_TABLEm); i++) { 2943 if (soc_mem_field32_modify(unit, TRUNK32_PORT_TABLEm, i, 2944 VLAN_RANGE_IDXf, temp_index) != BCM_E_NONE) { 2945 continue; 2946 } 2947 SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], 2948 temp_index, 1); 2949 } 2950 } 2951 } 2952 } 2953 2954 return BCM_E_NONE; 2955 } 2956 2957 /* 2958 * Function : _bcm_trx_vlan_range_profile_entry_add 2959 * 2960 * Purpose : add a new entry to vlan range profile table 2961 */ 2962 int 2963 _bcm_trx_vlan_range_profile_entry_add(int unit, bcm_vlan_t *min_vlan, 2964 bcm_vlan_t *max_vlan, uint32 *index) 2965 { 2966 ing_vlan_range_entry_t profile_entry; 2967 void *entries[1]; 2968 int i, rv = BCM_E_NONE; 2969 2970 sal_memset(&profile_entry, 0, sizeof(ing_vlan_range_entry_t)); 2971 2972 for (i = 0; i < 8; i++) { 2973 soc_mem_field32_set(unit, ING_VLAN_RANGEm, 2974 &profile_entry, _tr_range_min_f[i], min_vlan[i]); 2975 soc_mem_field32_set(unit, ING_VLAN_RANGEm, 2976 &profile_entry, _tr_range_max_f[i], max_vlan[i]); 2977 } 2978 entries[0] = &profile_entry; 2979 VLAN_RANGE_LOCK(unit); 2980 rv = soc_profile_mem_add(unit, vlan_range_profile[unit], 2981 (void *) &entries, 1, index); 2982 VLAN_RANGE_UNLOCK(unit); 2983 return rv; 2984 } 2985 2986 /* 2987 * Function : _bcm_trx_vlan_range_profile_entry_increment 2988 * 2989 * Purpose : increment the refcount for a vlan range profile table entry 2990 */ 2991 void 2992 _bcm_trx_vlan_range_profile_entry_increment(int unit, uint32 index) 2993 { 2994 VLAN_RANGE_LOCK(unit); 2995 SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], index, 1); 2996 VLAN_RANGE_UNLOCK(unit); 2997 } 2998 2999 /* 3000 * Function : _bcm_trx_vlan_range_profile_entry_get 3001 * 3002 * Purpose : get a copy of cached vlan range profile table 3003 */ 3004 void 3005 _bcm_trx_vlan_range_profile_entry_get(int unit, bcm_vlan_t *min_vlan, 3006 bcm_vlan_t *max_vlan, uint32 index) 3007 { 3008 int i; 3009 ing_vlan_range_entry_t *profile_entry; 3010 3011 VLAN_RANGE_LOCK(unit); 3012 profile_entry = SOC_PROFILE_MEM_ENTRY(unit, vlan_range_profile[unit], 3013 ing_vlan_range_entry_t *, 3014 index); 3015 for (i = 0; i < 8; i++) { 3016 min_vlan[i] = soc_mem_field32_get(unit, ING_VLAN_RANGEm, 3017 profile_entry, _tr_range_min_f[i]); 3018 max_vlan[i] = soc_mem_field32_get(unit, ING_VLAN_RANGEm, 3019 profile_entry, _tr_range_max_f[i]); 3020 } 3021 VLAN_RANGE_UNLOCK(unit); 3022 } 3023 3024 /* 3025 * Function : _bcm_trx_vlan_range_profile_entry_delete 3026 * 3027 * Purpose : remove an entry from vlan range profile table 3028 */ 3029 int 3030 _bcm_trx_vlan_range_profile_entry_delete(int unit, uint32 index) 3031 { 3032 int rv = BCM_E_NONE; 3033 VLAN_RANGE_LOCK(unit); 3034 rv = soc_profile_mem_delete(unit, vlan_range_profile[unit], index); 3035 VLAN_RANGE_UNLOCK(unit); 3036 return rv; 3037 } 3038 3039 /* 3040 * On XGS3, VLAN_SUBNET.IP_ADDR stores only a top half (64 bits) of 3041 * the IPV6 address. Comparing it against a full length of a parameter 3042 * will have certainly result in a mismatch. There should be a 3043 * special type for a stored part of the address; meanwhile, a 3044 * symbolic constant is used. 3045 */ 3046 3047 #define VLAN_SUBNET_IP_ADDR_LENGTH 8 3048 3049 /* 3050 * Function: 3051 * _trx_vlan_ip_addr_mask_get 3052 * Purpose: 3053 * Get IPV6 address and mask from vlan_ip structure 3054 * Parameters: 3055 * vlan_ip - structure specifying IP address and other info 3056 * ip6addr - IPv6 address to retrieve 3057 * ip6mask - IPv6 mask to retrieve 3058 * Returns: 3059 * BCM_E_XXX 3060 */ 3061 3062 STATIC int 3063 _trx_vlan_ip_addr_mask_get(bcm_vlan_ip_t *vlan_ip, bcm_ip6_t ip6addr, 3064 bcm_ip6_t ip6mask) 3065 { 3066 if (vlan_ip->flags & BCM_VLAN_SUBNET_IP6) { 3067 if (vlan_ip->prefix > 64) { 3068 return BCM_E_PARAM; 3069 } 3070 3071 bcm_ip6_mask_create(ip6mask, vlan_ip->prefix); 3072 sal_memcpy(ip6addr, vlan_ip->ip6, sizeof(bcm_ip6_t)); 3073 } else { /* IPv4 entry */ 3074 sal_memcpy(ip6addr, "\xff\xff\x00\x00", 4); 3075 ip6addr[4] = vlan_ip->ip4 >> 24; 3076 ip6addr[5] = (vlan_ip->ip4 >> 16) & 0xff; 3077 ip6addr[6] = (vlan_ip->ip4 >> 8) & 0xff; 3078 ip6addr[7] = vlan_ip->ip4 & 0xff; 3079 3080 sal_memcpy(ip6mask, "\xff\xff\xff\xff", 4); 3081 ip6mask[4] = vlan_ip->mask >> 24; 3082 ip6mask[5] = (vlan_ip->mask >> 16) & 0xff; 3083 ip6mask[6] = (vlan_ip->mask >> 8) & 0xff; 3084 ip6mask[7] = vlan_ip->mask & 0xff; 3085 } 3086 3087 return BCM_E_NONE; 3088 } 3089 3090 /* 3091 * Function: 3092 * _tr_vlan_subnet_mem_read 3093 * Purpose: 3094 * Helper function to allocated memory and read by range all 3095 * VLAN_SUBNET memory 3096 * Parameters: 3097 * unit - (IN) BCM Device unit 3098 * vstab - (OUT) pointer to memory 3099 * nent - (OUT) total number of entries in the memory 3100 * Returns: 3101 * BCM_E_XXX 3102 * Note: 3103 * This routine will allocate a memory, it is up to caller responsibility 3104 * to free it 3105 */ 3106 STATIC int 3107 _tr_vlan_subnet_mem_read(int unit, vlan_subnet_entry_t **vstab, int *nent) 3108 { 3109 int imin, imax, vsbytes, rv; 3110 3111 imin = soc_mem_index_min(unit, VLAN_SUBNETm); 3112 imax = soc_mem_index_max(unit, VLAN_SUBNETm); 3113 *nent = soc_mem_index_count(unit, VLAN_SUBNETm); 3114 vsbytes = soc_mem_entry_words(unit, VLAN_SUBNETm); 3115 vsbytes = WORDS2BYTES(vsbytes); 3116 *vstab = soc_cm_salloc(unit, *nent * sizeof(vlan_subnet_entry_t), "vlan_subnet"); 3117 if (*vstab == NULL) { 3118 return BCM_E_MEMORY; 3119 } 3120 3121 rv = soc_mem_read_range(unit, VLAN_SUBNETm, MEM_BLOCK_ANY, 3122 imin, imax, *vstab); 3123 return rv; 3124 } 3125 3126 /* 3127 * Function: 3128 * _trx_vlan_subnet_entry_parse 3129 * Purpose: 3130 * Helper function to parse all information fields from 3131 * VLAN_SUBNET memory entry 3132 * Parameters: 3133 * unit - (IN) BCM Device unit 3134 * ventry - (IN) pointer to a vlan subnet entry 3135 * subnet_fields - (OUT) Structure contains all entry fields 3136 * Returns: 3137 * none 3138 * Note: 3139 */ 3140 STATIC void 3141 _trx_vlan_subnet_entry_parse(int unit, vlan_subnet_entry_t *ventry, 3142 _bcm_trx_vlan_subnet_entry_t *subnet_fields) 3143 { 3144 bcm_ip6_t ip6tmp; 3145 vlan_subnet_entry_t entry; 3146 uint32 fval[SOC_MAX_MEM_WORDS]; 3147 3148 soc_mem_ip6_addr_get(unit, VLAN_SUBNETm, ventry, IP_ADDRf, 3149 subnet_fields->ip, SOC_MEM_IP6_UPPER_ONLY); 3150 3151 if (soc_mem_field_valid(unit, VLAN_SUBNETm, KEYf)) { 3152 soc_mem_field_get(unit, VLAN_SUBNETm, (uint32 *)ventry, MASKf, fval); 3153 soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)&entry, KEYf, fval); 3154 soc_mem_ip6_addr_get(unit, VLAN_SUBNETm, &entry, IP_ADDRf, 3155 ip6tmp, SOC_MEM_IP6_UPPER_ONLY); 3156 } else { 3157 soc_mem_ip6_addr_get(unit, VLAN_SUBNETm, ventry, MASKf, 3158 ip6tmp, SOC_MEM_IP6_UPPER_ONLY); 3159 } 3160 subnet_fields->prefix = bcm_ip6_mask_length(ip6tmp); 3161 3162 subnet_fields->ovid = soc_VLAN_SUBNETm_field32_get(unit, ventry, OVIDf); 3163 subnet_fields->ivid = soc_VLAN_SUBNETm_field32_get(unit, ventry, IVIDf); 3164 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3165 subnet_fields->opri = 3166 soc_VLAN_SUBNETm_field32_get(unit, ventry, OPRIf); 3167 subnet_fields->ocfi = 3168 soc_VLAN_SUBNETm_field32_get(unit, ventry, OCFIf); 3169 subnet_fields->ipri = 3170 soc_VLAN_SUBNETm_field32_get(unit, ventry, IPRIf); 3171 subnet_fields->icfi = 3172 soc_VLAN_SUBNETm_field32_get(unit, ventry, ICFIf); 3173 } else { 3174 subnet_fields->opri = soc_VLAN_SUBNETm_field32_get(unit, ventry, PRIf); 3175 } 3176 subnet_fields->profile_idx = soc_VLAN_SUBNETm_field32_get(unit, ventry, 3177 TAG_ACTION_PROFILE_PTRf); 3178 } 3179 3180 /* 3181 * Function: 3182 * _trx_vlan_subnet_entry_set 3183 * Purpose: 3184 * Helper function to write all fields to 3185 * VLAN_SUBNET memory entry 3186 * Parameters: 3187 * unit - (IN) BCM Device unit 3188 * ventry - (IN) pointer to a vlan subnet entry 3189 * subnet_fields - (IN) Structure contains all entry fields 3190 * Returns: 3191 * none 3192 * Note: 3193 * This routine assumes that all rovided fields has correct values 3194 */ 3195 3196 STATIC void 3197 _trx_vlan_subnet_entry_set(int unit, vlan_subnet_entry_t *ventry, 3198 _bcm_trx_vlan_subnet_entry_t *subnet_fields) 3199 { 3200 uint32 fval[SOC_MAX_MEM_WORDS]; 3201 3202 sal_memset(fval, 0, sizeof(fval)); 3203 if (soc_mem_field_valid(unit, VLAN_SUBNETm, KEYf)) { 3204 soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)ventry, KEYf, fval); 3205 soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, ventry, IP_ADDRf, 3206 subnet_fields->mask, SOC_MEM_IP6_UPPER_ONLY); 3207 soc_mem_field_get(unit, VLAN_SUBNETm, (uint32 *)ventry, KEYf, fval); 3208 soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)ventry, MASKf, fval); 3209 } else { 3210 soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, ventry, MASKf, 3211 subnet_fields->mask, SOC_MEM_IP6_UPPER_ONLY); 3212 } 3213 soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, ventry, IP_ADDRf, 3214 subnet_fields->ip, SOC_MEM_IP6_UPPER_ONLY); 3215 soc_VLAN_SUBNETm_field32_set(unit, ventry, OVIDf, subnet_fields->ovid); 3216 soc_VLAN_SUBNETm_field32_set(unit, ventry, IVIDf, subnet_fields->ivid); 3217 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3218 soc_VLAN_SUBNETm_field32_set(unit, ventry, OPRIf, subnet_fields->opri); 3219 soc_VLAN_SUBNETm_field32_set(unit, ventry, OCFIf, subnet_fields->ocfi); 3220 soc_VLAN_SUBNETm_field32_set(unit, ventry, IPRIf, subnet_fields->ipri); 3221 soc_VLAN_SUBNETm_field32_set(unit, ventry, ICFIf, subnet_fields->icfi); 3222 } else { 3223 soc_VLAN_SUBNETm_field32_set(unit, ventry, PRIf, subnet_fields->opri); 3224 } 3225 soc_VLAN_SUBNETm_field32_set(unit, ventry, TAG_ACTION_PROFILE_PTRf, 3226 subnet_fields->profile_idx); 3227 soc_VLAN_SUBNETm_field32_set(unit, ventry, VALIDf, 1); 3228 } 3229 3230 /* 3231 * Function: 3232 * _trx_vlan_subnet_lookup 3233 * Purpose: 3234 * Get index into table with settings matching to subnet 3235 * Parameters: 3236 * unit (IN) BCM Device unit 3237 * vstab (IN) pointer to memory 3238 * nent (IN) number of entries in the memory 3239 * ip (IN) IP address 3240 * ip_mask (IN) IP address mask 3241 * entry_index (OUT) target entry index (if BCM_E_NONE) 3242 * index to be used for insert or -1 when full 3243 * (if BCM_E_NOT_FOUND) 3244 * free_index (OUT) (optional) index of last used entry + 1 3245 * Returns: 3246 * BCM_E_XXX 3247 */ 3248 STATIC int 3249 _trx_vlan_subnet_lookup(int unit, vlan_subnet_entry_t *vstab, int nent, 3250 bcm_ip6_t ip, bcm_ip6_t ip_mask, int *entry_index, 3251 int *free_index) 3252 { 3253 bcm_ip6_t ip_key, ip6_full_mask; 3254 vlan_subnet_entry_t *vstabp, entry0, entry1, entry2, mask0, mask1; 3255 int index_min, index_max; 3256 int index, i, entry_words, rv; 3257 uint32 fval[SOC_MAX_MEM_WORDS]; 3258 3259 sal_memcpy(ip_key, ip, VLAN_SUBNET_IP_ADDR_LENGTH); 3260 #ifdef BCM_TRIDENT_SUPPORT 3261 3262 if (soc_feature(unit, soc_feature_xy_tcam)) { 3263 for (i = 0; i < VLAN_SUBNET_IP_ADDR_LENGTH; i++) { 3264 ip_key[i] &= ip_mask[i]; 3265 } 3266 } 3267 #endif /* BCM_TRIDENT_SUPPORT */ 3268 3269 sal_memset(&ip6_full_mask, 0xff, sizeof(ip6_full_mask)); 3270 entry_words = soc_mem_entry_words(unit, VLAN_SUBNETm); 3271 3272 /* entry2 is for checking VALID bit */ 3273 sal_memset(&entry2, 0, sizeof(entry2)); 3274 soc_mem_field32_set(unit, VLAN_SUBNETm, &entry2, VALIDf, 1); 3275 3276 /* entry1 and mask1 are for prefix length check */ 3277 entry1 = entry2; 3278 if (soc_mem_field_valid(unit, VLAN_SUBNETm, KEYf)) { 3279 sal_memset(&entry0, 0, sizeof(entry0)); 3280 soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &entry0, IP_ADDRf, ip_mask, 3281 SOC_MEM_IP6_UPPER_ONLY); 3282 soc_mem_field_get(unit, VLAN_SUBNETm, (uint32 *)&entry0, KEYf, fval); 3283 soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)&entry1, MASKf, fval); 3284 mask1 = entry1; 3285 soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &entry0, IP_ADDRf, 3286 ip6_full_mask, SOC_MEM_IP6_UPPER_ONLY); 3287 soc_mem_field_get(unit, VLAN_SUBNETm, (uint32 *)&entry0, KEYf, fval); 3288 soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)&mask1, MASKf, fval); 3289 } else { 3290 soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &entry1, MASKf, ip_mask, 3291 SOC_MEM_IP6_UPPER_ONLY); 3292 mask1 = entry1; 3293 soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &mask1, MASKf, 3294 ip6_full_mask, SOC_MEM_IP6_UPPER_ONLY); 3295 } 3296 3297 /* entry0 and mask0 are for target entry matching */ 3298 entry0 = entry1; 3299 soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &entry0, IP_ADDRf, ip_key, 3300 SOC_MEM_IP6_UPPER_ONLY); 3301 mask0 = mask1; 3302 soc_mem_field32_set(unit, VLAN_SUBNETm, &mask0, VALIDf, 1); 3303 soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &mask0, IP_ADDRf, ip_mask, 3304 SOC_MEM_IP6_UPPER_ONLY); 3305 3306 /* Do binary search to find the first entry whose prefix length 3307 * is shorter than or equal to the target entry */ 3308 index_min = 0; 3309 index_max = nent - 1; 3310 while (index_min < index_max) { 3311 index = (index_min + index_max) / 2; 3312 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3313 vlan_subnet_entry_t *, 3314 vstab, index); 3315 3316 /* Check if the entry has longer prefix */ 3317 for (i = 0; i < entry_words; i++) { 3318 if ((vstabp->entry_data[i] & mask1.entry_data[i]) > 3319 entry1.entry_data[i]) { 3320 break; 3321 } 3322 } 3323 if (i != entry_words) { /* prefix length is longer than target entry */ 3324 index_min = index + 1; 3325 } else { /* prefix length is shorter than or equal to target entry */ 3326 index_max = index; 3327 } 3328 } 3329 3330 /* Match against entries with the same prefix length as target entry */ 3331 rv = BCM_E_NOT_FOUND; 3332 *entry_index = -1; 3333 for (index = index_min; index < nent; index++) { 3334 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3335 vlan_subnet_entry_t *, 3336 vstab, index); 3337 /* Try matching the entry */ 3338 for (i = 0; i < entry_words; i++) { 3339 if ((vstabp->entry_data[i] ^ entry0.entry_data[i]) & 3340 mask0.entry_data[i]) { 3341 break; 3342 } 3343 } 3344 if (i == entry_words) { 3345 rv = BCM_E_NONE; 3346 *entry_index = index; 3347 break; 3348 } 3349 3350 /* Find the first shorter prefix entry */ 3351 for (i = 0; i < entry_words; i++) { 3352 if ((vstabp->entry_data[i] & mask1.entry_data[i]) < 3353 entry1.entry_data[i]) { 3354 break; 3355 } 3356 } 3357 if (i != entry_words) { 3358 *entry_index = index; 3359 break; 3360 } 3361 } 3362 3363 3364 if (free_index == NULL) { 3365 return rv; 3366 } 3367 3368 /* Do binary search to find the index after the last used entry */ 3369 index_min = index; 3370 index_max = nent - 1; 3371 while (index_min <= index_max) { 3372 index = (index_min + index_max) / 2; 3373 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3374 vlan_subnet_entry_t *, 3375 vstab, index); 3376 3377 /* Check if the entry is valid */ 3378 for (i = 0; i < entry_words; i++) { 3379 if (vstabp->entry_data[i] & entry2.entry_data[i]) { 3380 break; 3381 } 3382 } 3383 if (i == entry_words) { /* free entry */ 3384 if (index_min == index_max) { 3385 break; 3386 } 3387 index_max = index; 3388 } else { /* entry in used */ 3389 index_min = index + 1; 3390 } 3391 } 3392 3393 *free_index = index_min; 3394 return rv; 3395 } 3396 3397 /* 3398 * Function: 3399 * _trx_vlan_subnet_entry_add 3400 * Purpose: 3401 * Add vlan settings for given subnet 3402 * Parameters: 3403 * unit - (IN) BCM Device unit 3404 * entry_fields - (IN) Entry fields to add 3405 * Returns: 3406 * BCM_E_XXX 3407 */ 3408 STATIC int 3409 _trx_vlan_subnet_entry_add(int unit, 3410 _bcm_trx_vlan_subnet_entry_t *entry_fields) 3411 { 3412 int rv, nent, i; 3413 vlan_subnet_entry_t *vstab, *vstabp; 3414 uint32 old_profile_idx; 3415 int entry_index, free_index; 3416 3417 soc_mem_lock(unit, VLAN_SUBNETm); 3418 3419 rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent); 3420 if (BCM_FAILURE(rv)) { 3421 if (NULL != vstab) { 3422 soc_cm_sfree(unit, vstab); 3423 } 3424 soc_mem_unlock(unit, VLAN_SUBNETm); 3425 return rv; 3426 } 3427 3428 rv = _trx_vlan_subnet_lookup(unit, vstab, nent, entry_fields->ip, 3429 entry_fields->mask, &entry_index, 3430 &free_index); 3431 if (rv == BCM_E_NOT_FOUND && entry_index == -1) { 3432 rv = BCM_E_FULL; 3433 } 3434 3435 if (BCM_SUCCESS(rv)) { /* found an exact match */ 3436 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3437 vlan_subnet_entry_t *, vstab, 3438 entry_index); 3439 3440 /* retrieve old vlan action profile pointer */ 3441 old_profile_idx = soc_VLAN_SUBNETm_field32_get 3442 (unit, vstabp, TAG_ACTION_PROFILE_PTRf); 3443 _trx_vlan_subnet_entry_set(unit, vstabp, entry_fields); 3444 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL, entry_index, vstabp); 3445 if (BCM_SUCCESS(rv)) { 3446 /* Delete the old vlan action profile entry */ 3447 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, 3448 old_profile_idx); 3449 } 3450 } else if (rv == BCM_E_NOT_FOUND) { 3451 /* shift down entries starting at the insert point to create hole */ 3452 for (i = free_index - 1; i >= entry_index; i--) { 3453 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3454 vlan_subnet_entry_t *, vstab, 3455 i); 3456 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i + 1, vstabp); 3457 if (BCM_FAILURE(rv)) { 3458 break; 3459 } 3460 } 3461 if (i < entry_index) { 3462 /* insert new entry at the created hole */ 3463 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3464 vlan_subnet_entry_t *, vstab, 3465 entry_index); 3466 sal_memset(vstabp, 0, 3467 WORDS2BYTES(soc_mem_entry_words(unit, VLAN_SUBNETm))); 3468 _trx_vlan_subnet_entry_set(unit, vstabp, entry_fields); 3469 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL, entry_index, vstabp); 3470 } 3471 } 3472 soc_mem_unlock(unit, VLAN_SUBNETm); 3473 soc_cm_sfree(unit, vstab); 3474 return rv; 3475 } 3476 3477 3478 3479 /* 3480 * Function: 3481 * _trx_vlan_subnet_entry_get 3482 * Purpose: 3483 * Get vlan settings for given subnet 3484 * Parameters: 3485 * unit - (IN) BCM Device unit 3486 * subnet_fields - (IN/OUT) Structure contains all entry fields 3487 * Returns: 3488 * BCM_E_XXX 3489 */ 3490 STATIC int 3491 _trx_vlan_subnet_entry_get(int unit, 3492 _bcm_trx_vlan_subnet_entry_t *entry_fields) 3493 { 3494 vlan_subnet_entry_t *vstab, *vstabp; 3495 int entry_index, rv, nent; 3496 3497 if (NULL == entry_fields) { 3498 return (BCM_E_PARAM); 3499 } 3500 soc_mem_lock(unit, VLAN_SUBNETm); 3501 3502 rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent); 3503 if (BCM_FAILURE(rv)) { 3504 if (NULL != vstab) { 3505 soc_cm_sfree(unit, vstab); 3506 } 3507 soc_mem_unlock(unit, VLAN_SUBNETm); 3508 return rv; 3509 } 3510 3511 rv = _trx_vlan_subnet_lookup(unit, vstab, nent, entry_fields->ip, 3512 entry_fields->mask, &entry_index, NULL); 3513 if (BCM_SUCCESS(rv)) { 3514 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3515 vlan_subnet_entry_t *, vstab, 3516 entry_index); 3517 _trx_vlan_subnet_entry_parse(unit, vstabp, entry_fields); 3518 } 3519 3520 soc_cm_sfree(unit, vstab); 3521 soc_mem_unlock(unit, VLAN_SUBNETm); 3522 return (BCM_E_NONE); 3523 } 3524 3525 3526 /* 3527 * Function: 3528 * _trx_vlan_subnet_entry_delete 3529 * Purpose: 3530 * Delete vlan settings for given subnet 3531 * Parameters: 3532 * unit - (IN) BCM Device unit 3533 * ip - (IN) IP address 3534 * mask - (IN) IP mask 3535 * Returns: 3536 * BCM_E_XXX 3537 */ 3538 static int 3539 _trx_vlan_subnet_entry_delete(int unit, bcm_ip6_t ip, bcm_ip6_t mask) 3540 { 3541 int rv, nent, i; 3542 vlan_subnet_entry_t *vstab, *vstabp; 3543 uint32 old_profile_idx; 3544 int entry_index, free_index; 3545 3546 soc_mem_lock(unit, VLAN_SUBNETm); 3547 rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent); 3548 if (BCM_FAILURE(rv)) { 3549 if (NULL != vstab) { 3550 soc_cm_sfree(unit, vstab); 3551 } 3552 soc_mem_unlock(unit, VLAN_SUBNETm); 3553 return rv; 3554 } 3555 3556 rv = _trx_vlan_subnet_lookup(unit, vstab, nent, ip, mask, &entry_index, 3557 &free_index); 3558 if (BCM_FAILURE(rv)) { 3559 soc_cm_sfree(unit, vstab); 3560 soc_mem_unlock(unit, VLAN_SUBNETm); 3561 return (rv); 3562 } 3563 3564 /* Get the old vlan action profile pointer */ 3565 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3566 vlan_subnet_entry_t *, vstab, 3567 entry_index); 3568 old_profile_idx = soc_mem_field32_get(unit, VLAN_SUBNETm, vstabp, 3569 TAG_ACTION_PROFILE_PTRf); 3570 3571 for (i = entry_index; i < free_index - 1; i++) { 3572 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3573 vlan_subnet_entry_t *, vstab, 3574 (i + 1)); 3575 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, vstabp); 3576 if (BCM_FAILURE(rv)) { 3577 break; 3578 } 3579 } 3580 if (i >= free_index - 1) { 3581 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, free_index - 1, 3582 soc_mem_entry_null(unit, VLAN_SUBNETm)); 3583 if (BCM_SUCCESS(rv)) { 3584 /* Delete the old vlan action profile entry */ 3585 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, 3586 old_profile_idx); 3587 } 3588 } 3589 3590 soc_mem_unlock(unit, VLAN_SUBNETm); 3591 soc_cm_sfree(unit, vstab); 3592 return rv; 3593 } 3594 3595 /* 3596 * Function: 3597 * _bcm_trx_vlan_ip_action_add 3598 * Purpose: 3599 * Add a subnet lookup to select vlan and priority for 3600 * untagged packets 3601 * Parameters: 3602 * unit - device number 3603 * vlan_ip - structure specifying IP address and other info 3604 * action - structure VLAN tag actions 3605 * Returns: 3606 * BCM_E_XXX 3607 */ 3608 int 3609 _bcm_trx_vlan_ip_action_add(int unit, bcm_vlan_ip_t *vlan_ip, 3610 bcm_vlan_action_set_t *action) 3611 { 3612 int rv; 3613 _bcm_trx_vlan_subnet_entry_t entry_fields; 3614 3615 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 3616 3617 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_ip_verify(unit, vlan_ip)); 3618 3619 sal_memset(&entry_fields, 0, sizeof(_bcm_trx_vlan_subnet_entry_t)); 3620 BCM_IF_ERROR_RETURN(_trx_vlan_ip_addr_mask_get(vlan_ip, entry_fields.ip, 3621 entry_fields.mask)); 3622 3623 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_add 3624 (unit, action, (uint32 *)&entry_fields.profile_idx)); 3625 3626 entry_fields.ovid = action->new_outer_vlan; 3627 entry_fields.ivid = action->new_inner_vlan; 3628 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3629 entry_fields.opri = action->priority; 3630 entry_fields.ocfi = action->new_outer_cfi; 3631 entry_fields.ipri = action->new_inner_pkt_prio; 3632 entry_fields.icfi = action->new_inner_cfi; 3633 } else { 3634 entry_fields.opri = action->priority; 3635 } 3636 3637 rv = _trx_vlan_subnet_entry_add(unit, &entry_fields); 3638 if (BCM_FAILURE(rv)) { 3639 /* Add failed, back out the new profile entry */ 3640 (void)_bcm_trx_vlan_action_profile_entry_delete 3641 (unit, entry_fields.profile_idx); 3642 } 3643 3644 return rv; 3645 } 3646 3647 /* 3648 * Function: 3649 * _bcm_trx_vlan_ip_action_get 3650 * Purpose: 3651 * Helper funtion for the API, implementation for TRX 3652 * Parameters: 3653 * unit - (IN) device number 3654 * vlan_ip - (IN) structure specifying IP address and other info 3655 * action - (OUT) structure VLAN tag actions 3656 * Returns: 3657 * BCM_E_XXX 3658 */ 3659 int 3660 _bcm_trx_vlan_ip_action_get(int unit, bcm_vlan_ip_t *vlan_ip, 3661 bcm_vlan_action_set_t *action) 3662 { 3663 _bcm_trx_vlan_subnet_entry_t entry_fields; 3664 3665 /* Parameter check */ 3666 if (NULL == action) { 3667 return (BCM_E_PARAM); 3668 } 3669 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_ip_verify(unit, vlan_ip)); 3670 3671 sal_memset(&entry_fields, 0, sizeof(_bcm_trx_vlan_subnet_entry_t)); 3672 BCM_IF_ERROR_RETURN( 3673 _trx_vlan_ip_addr_mask_get(vlan_ip, entry_fields.ip, entry_fields.mask)); 3674 3675 BCM_IF_ERROR_RETURN( 3676 _trx_vlan_subnet_entry_get(unit, &entry_fields)); 3677 3678 action->new_outer_vlan = entry_fields.ovid; 3679 action->new_inner_vlan = entry_fields.ivid; 3680 action->priority = entry_fields.opri; 3681 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3682 action->new_outer_cfi = entry_fields.ocfi; 3683 action->new_inner_pkt_prio = entry_fields.ipri; 3684 action->new_inner_cfi = entry_fields.icfi; 3685 } 3686 3687 _bcm_trx_vlan_action_profile_entry_get(unit, action, 3688 entry_fields.profile_idx); 3689 3690 return (BCM_E_NONE); 3691 } 3692 3693 /* 3694 * Function: 3695 * _bcm_trx_vlan_ip_action_traverse 3696 * Purpose: 3697 * Helper funtion for the API, implementation for TRX 3698 * Parameters: 3699 * unit - (IN) device number 3700 * cb - (IN) user specified call back function 3701 * user_data - (IN) pointer to user_data 3702 * Returns: 3703 * BCM_E_XXX 3704 */ 3705 int 3706 _bcm_trx_vlan_ip_action_traverse(int unit, 3707 bcm_vlan_ip_action_traverse_cb cb, 3708 void * user_data) 3709 { 3710 vlan_subnet_entry_t *vstab, *vstabp; 3711 int nent, rv, i; 3712 bcm_vlan_action_set_t action; 3713 bcm_vlan_ip_t vlan_ip; 3714 _bcm_trx_vlan_subnet_entry_t entry_fields; 3715 3716 /* Input parameters check. */ 3717 if (NULL == cb) { 3718 return (BCM_E_PARAM); 3719 } 3720 sal_memset(&entry_fields, 0, sizeof(_bcm_trx_vlan_subnet_entry_t)); 3721 3722 3723 rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent); 3724 if (BCM_FAILURE(rv)) { 3725 if (NULL != vstab) { 3726 soc_cm_sfree(unit, vstab); 3727 } 3728 return rv; 3729 } 3730 3731 for(i = 0; i < nent; i++) { 3732 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 3733 sal_memset(&vlan_ip, 0, sizeof(bcm_vlan_ip_t)); 3734 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3735 vlan_subnet_entry_t *, 3736 vstab, i); 3737 if (0 == soc_VLAN_SUBNETm_field32_get(unit, vstabp, VALIDf)){ 3738 continue; 3739 } 3740 _trx_vlan_subnet_entry_parse(unit, vstabp, &entry_fields); 3741 3742 if (*(uint32*)entry_fields.ip == 0xffff0000) { 3743 /* IPv4 case */ 3744 bcm_ip6_t ip6tmp; 3745 3746 vlan_ip.ip4 = (entry_fields.ip[4] << 24) | 3747 (entry_fields.ip[5] << 16) | (entry_fields.ip[6] << 8) | 3748 entry_fields.ip[7]; 3749 bcm_ip6_mask_create(ip6tmp, entry_fields.prefix); 3750 vlan_ip.mask = (ip6tmp[4] << 24) | (ip6tmp[5] << 16) | 3751 (ip6tmp[6] << 8) | ip6tmp[7]; 3752 } else { 3753 /* IPv6 case */ 3754 sal_memcpy(vlan_ip.ip6, entry_fields.ip, sizeof(bcm_ip6_t)); 3755 vlan_ip.prefix = entry_fields.prefix; 3756 vlan_ip.flags |= BCM_VLAN_SUBNET_IP6; 3757 } 3758 3759 vlan_ip.prefix = entry_fields.prefix; 3760 vlan_ip.vid = entry_fields.ovid; 3761 action.new_outer_vlan = entry_fields.ovid; 3762 action.new_inner_vlan = entry_fields.ivid; 3763 action.priority = entry_fields.opri; 3764 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3765 action.new_outer_cfi = entry_fields.ocfi; 3766 action.new_inner_pkt_prio = entry_fields.ipri; 3767 action.new_inner_cfi = entry_fields.icfi; 3768 } 3769 3770 /* Read action profile data. */ 3771 _bcm_trx_vlan_action_profile_entry_get(unit, &action, 3772 entry_fields.profile_idx); 3773 /* Call traverse callback with the data. */ 3774 rv = cb(unit, &vlan_ip, &action, user_data); 3775 if (BCM_FAILURE(rv)) { 3776 soc_cm_sfree(unit, vstab); 3777 return rv; 3778 } 3779 } 3780 3781 soc_cm_sfree(unit, vstab); 3782 return rv; 3783 3784 } 3785 3786 /* 3787 * Function: 3788 * bcm_vlan_ip_delete 3789 * Purpose: 3790 * Delete a subnet lookup entry. 3791 * Parameters: 3792 * unit - device number 3793 * vlan_ip - structure specifying IP address and other info 3794 * Returns: 3795 * BCM_E_XXX 3796 */ 3797 int 3798 _bcm_trx_vlan_ip_delete(int unit, bcm_vlan_ip_t *vlan_ip) 3799 { 3800 bcm_ip6_t ip6addr, ip6mask; 3801 3802 BCM_IF_ERROR_RETURN( 3803 _bcm_trx_vlan_ip_verify(unit, vlan_ip)); 3804 3805 BCM_IF_ERROR_RETURN( 3806 _trx_vlan_ip_addr_mask_get(vlan_ip, ip6addr, ip6mask)); 3807 return _trx_vlan_subnet_entry_delete(unit, ip6addr, ip6mask); 3808 } 3809 3810 /* 3811 * Function: 3812 * bcm_vlan_ip_delete_all 3813 * Purpose: 3814 * Delete all subnet lookup entries. 3815 * Parameters: 3816 * unit - device number 3817 * Returns: 3818 * BCM_E_XXX 3819 */ 3820 int 3821 _bcm_trx_vlan_ip_delete_all(int unit) 3822 { 3823 int i, nent, rv; 3824 uint32 old_profile_idx; 3825 vlan_subnet_entry_t *vstab, *vsnull, *vstabp; 3826 3827 rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent); 3828 if (BCM_FAILURE(rv)) { 3829 if (NULL != vstab) { 3830 soc_cm_sfree(unit, vstab); 3831 } 3832 return rv; 3833 } 3834 3835 vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm); 3836 3837 soc_mem_lock(unit, VLAN_SUBNETm); 3838 for(i = 0; i < nent; i++) { 3839 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 3840 vlan_subnet_entry_t *, vstab, i); 3841 3842 if (!soc_VLAN_SUBNETm_field32_get(unit, vstabp, VALIDf)) { 3843 continue; 3844 } 3845 old_profile_idx = soc_VLAN_SUBNETm_field32_get(unit, vstabp, 3846 TAG_ACTION_PROFILE_PTRf); 3847 3848 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, vsnull); 3849 3850 /* Increment the vlan action profile refcount for the cleared entry */ 3851 _bcm_trx_vlan_action_profile_entry_increment(unit, ing_action_profile_def[unit]); 3852 3853 if (rv >= 0) { 3854 /* Delete the old vlan action profile entry */ 3855 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx); 3856 } 3857 } 3858 3859 soc_mem_unlock(unit, VLAN_SUBNETm); 3860 soc_cm_sfree(unit, vstab); 3861 return rv; 3862 } 3863 3864 #if defined(BCM_TRIUMPH3_SUPPORT) 3865 STATIC int 3866 _bcm_tr3_vlan_mac_action_add(int unit, 3867 bcm_mac_t mac, 3868 bcm_vlan_action_set_t *action) 3869 { 3870 int rv; 3871 uint32 profile_idx; 3872 vlan_xlate_entry_t vxent; 3873 3874 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 3875 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3876 if (action->priority == -1) { 3877 return BCM_E_PARAM; /* no default priority action to take*/ 3878 } 3879 } 3880 BCM_IF_ERROR_RETURN 3881 (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx)); 3882 3883 sal_memset(&vxent, 0, sizeof(vxent)); 3884 soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent), 3885 VLAN_MAC__MAC_ADDRf, mac); 3886 3887 soc_VLAN_XLATEm_field32_set(unit, &vxent, KEY_TYPEf, 3888 TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC); 3889 soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OVIDf, 3890 action->new_outer_vlan); 3891 soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__IVIDf, 3892 action->new_inner_vlan); 3893 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3894 soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OPRIf, 3895 action->priority); 3896 soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OCFIf, 3897 action->new_outer_cfi); 3898 soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__IPRIf, 3899 action->new_inner_pkt_prio); 3900 soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__ICFIf, 3901 action->new_inner_cfi); 3902 } else { 3903 if (action->priority >= BCM_PRIO_MIN && 3904 action->priority <= BCM_PRIO_MAX) { 3905 soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OPRIf, 3906 action->priority); 3907 } 3908 } 3909 soc_VLAN_XLATEm_field32_set(unit, &vxent, VALIDf, 1); 3910 soc_VLAN_XLATEm_field32_set(unit, &vxent, 3911 VLAN_MAC__TAG_ACTION_PROFILE_PTRf, profile_idx); 3912 3913 rv = soc_mem_insert_return_old(unit, VLAN_XLATEm, MEM_BLOCK_ALL, 3914 &vxent, &vxent); 3915 3916 if (rv == SOC_E_EXISTS) { 3917 /* Delete the old vlan action profile entry */ 3918 profile_idx = soc_VLAN_XLATEm_field32_get(unit, &vxent, 3919 VLAN_MAC__TAG_ACTION_PROFILE_PTRf); 3920 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 3921 } 3922 3923 return rv; 3924 } 3925 #endif /* BCM_TRIUMPH3_SUPPORT */ 3926 3927 /* 3928 * Function: 3929 * bcm_vlan_mac_action_add 3930 * Description : 3931 * Add association from MAC address to VLAN. 3932 * If the entry already exists, update the action. 3933 * Parameters : 3934 * unit (IN) BCM unit number 3935 * mac (IN) MAC address 3936 * action (IN) Action for outer and inner tag 3937 * Note: 3938 * Program VLAN_XLATEm. 3939 */ 3940 int _bcm_trx_vlan_mac_action_add(int unit, 3941 bcm_mac_t mac, 3942 bcm_vlan_action_set_t *action) 3943 { 3944 #if defined(BCM_TRIUMPH3_SUPPORT) 3945 if (SOC_IS_TRIUMPH3(unit)) { 3946 BCM_IF_ERROR_RETURN 3947 (_bcm_tr3_vlan_mac_action_add(unit,mac,action)); 3948 return BCM_E_NONE; 3949 } else 3950 #endif /* BCM_TRIUMPH3_SUPPORT */ 3951 { 3952 int rv; 3953 uint32 profile_idx; 3954 vlan_mac_entry_t vment; 3955 3956 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 3957 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3958 if (action->priority == -1) { 3959 return BCM_E_PARAM; /* no default priority action to take*/ 3960 } 3961 } 3962 3963 BCM_IF_ERROR_RETURN 3964 (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx)); 3965 3966 sal_memset(&vment, 0, sizeof(vment)); 3967 soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac); 3968 soc_VLAN_MACm_field32_set(unit, &vment, KEY_TYPEf, 3969 TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC); 3970 soc_VLAN_MACm_field32_set(unit, &vment, OVIDf, action->new_outer_vlan); 3971 soc_VLAN_MACm_field32_set(unit, &vment, IVIDf, action->new_inner_vlan); 3972 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3973 soc_VLAN_MACm_field32_set(unit, &vment, OPRIf, action->priority); 3974 soc_VLAN_MACm_field32_set(unit, &vment, OCFIf, action->new_outer_cfi); 3975 soc_VLAN_MACm_field32_set(unit, &vment, IPRIf, 3976 action->new_inner_pkt_prio); 3977 soc_VLAN_MACm_field32_set(unit, &vment, ICFIf, action->new_inner_cfi); 3978 } else { 3979 if (action->priority >= BCM_PRIO_MIN && 3980 action->priority <= BCM_PRIO_MAX) { 3981 soc_VLAN_MACm_field32_set(unit, &vment, PRIf, action->priority); 3982 } 3983 } 3984 soc_VLAN_MACm_field32_set(unit, &vment, TAG_ACTION_PROFILE_PTRf, 3985 profile_idx); 3986 if (SOC_MEM_FIELD_VALID(unit, VLAN_MACm, VLAN_ACTION_VALIDf)) { 3987 soc_VLAN_MACm_field32_set(unit, &vment, VLAN_ACTION_VALIDf, 1); 3988 } 3989 soc_VLAN_MACm_field32_set(unit, &vment, VALIDf, 1); 3990 3991 rv = soc_mem_insert_return_old(unit, VLAN_MACm, MEM_BLOCK_ALL, &vment, &vment); 3992 3993 if (rv == SOC_E_EXISTS) { 3994 /* Delete the old vlan action profile entry */ 3995 profile_idx = soc_VLAN_MACm_field32_get(unit, &vment, 3996 TAG_ACTION_PROFILE_PTRf); 3997 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 3998 } 3999 4000 return rv; 4001 } 4002 } 4003 4004 #if defined(BCM_TRIUMPH3_SUPPORT) 4005 STATIC int 4006 _bcm_tr3_vlan_mac_action_get(int unit, bcm_mac_t mac, 4007 bcm_vlan_action_set_t *action) 4008 { 4009 vlan_xlate_entry_t vxent; /* Lookup key hw buffer. */ 4010 vlan_xlate_entry_t res_vxent; /* Lookup result buffer. */ 4011 uint32 profile_idx; /* Vlan action profile index. */ 4012 int rv; /* Operation return status. */ 4013 int idx = 0; /* Lookup result entry index. */ 4014 4015 /* Input parameters check. */ 4016 if (NULL == action) { 4017 return (BCM_E_PARAM); 4018 } 4019 4020 /* Reset lookup key and result destination buffer. */ 4021 sal_memset(&vxent, 0, sizeof(vlan_xlate_entry_t)); 4022 sal_memset(&res_vxent, 0, sizeof(vlan_xlate_entry_t)); 4023 4024 /* Initialize lookup key. */ 4025 soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent), 4026 VLAN_MAC__MAC_ADDRf, mac); 4027 4028 soc_VLAN_XLATEm_field32_set(unit, &vxent, KEY_TYPEf, 4029 TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC); 4030 4031 /* Perform VLAN_MAC table search by mac address. */ 4032 soc_mem_lock(unit, VLAN_XLATEm); 4033 rv = soc_mem_search(unit, VLAN_XLATEm, MEM_BLOCK_ALL, &idx, 4034 &vxent, &res_vxent, 0); 4035 soc_mem_unlock(unit, VLAN_XLATEm); 4036 BCM_IF_ERROR_RETURN(rv); 4037 4038 action->new_outer_vlan = 4039 soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__OVIDf); 4040 action->new_inner_vlan = 4041 soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__IVIDf); 4042 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 4043 action->priority = soc_VLAN_XLATEm_field32_get(unit, &res_vxent, 4044 VLAN_MAC__OPRIf); 4045 action->new_outer_cfi = 4046 soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__OCFIf); 4047 action->new_inner_pkt_prio = 4048 soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__IPRIf); 4049 action->new_inner_cfi = 4050 soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__ICFIf); 4051 } else { 4052 action->priority = soc_VLAN_XLATEm_field32_get(unit, &res_vxent, 4053 VLAN_MAC__OPRIf); 4054 } 4055 4056 /* Read action profile data. */ 4057 profile_idx = soc_VLAN_XLATEm_field32_get(unit, &res_vxent, 4058 VLAN_MAC__TAG_ACTION_PROFILE_PTRf); 4059 _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 4060 4061 return (BCM_E_NONE); 4062 } 4063 #endif /* BCM_TRIUMPH3_SUPPORT */ 4064 4065 /* 4066 * Function: 4067 * _bcm_trx_vlan_mac_action_get 4068 * Description : 4069 * Get association from MAC address to VLAN tag actions. 4070 * Parameters : 4071 * unit (IN) BCM unit number 4072 * mac (IN) MAC address 4073 * action (OUT) Action for outer and inner tag 4074 * Returns: 4075 * BCM_E_XXX 4076 */ 4077 int 4078 _bcm_trx_vlan_mac_action_get(int unit, bcm_mac_t mac, 4079 bcm_vlan_action_set_t *action) 4080 { 4081 #if defined(BCM_TRIUMPH3_SUPPORT) 4082 if (SOC_IS_TRIUMPH3(unit)) { 4083 BCM_IF_ERROR_RETURN 4084 (_bcm_tr3_vlan_mac_action_get(unit,mac,action)); 4085 return BCM_E_NONE; 4086 } else 4087 #endif /* BCM_TRIUMPH3_SUPPORT */ 4088 { 4089 vlan_mac_entry_t vment; /* Lookup key hw buffer. */ 4090 vlan_mac_entry_t res_vment; /* Lookup result buffer. */ 4091 uint32 profile_idx; /* Vlan action profile index. */ 4092 int rv; /* Operation return status. */ 4093 int idx = 0; /* Lookup result entry index. */ 4094 4095 /* Input parameters check. */ 4096 if (NULL == action) { 4097 return (BCM_E_PARAM); 4098 } 4099 4100 /* Reset lookup key and result destination buffer. */ 4101 sal_memset(&vment, 0, sizeof(vlan_mac_entry_t)); 4102 sal_memset(&res_vment, 0, sizeof(vlan_mac_entry_t)); 4103 4104 /* Initialize lookup key. */ 4105 soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac); 4106 soc_VLAN_MACm_field32_set(unit, &vment, KEY_TYPEf, 4107 TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC); 4108 4109 /* Perform VLAN_MAC table search by mac address. */ 4110 soc_mem_lock(unit, VLAN_MACm); 4111 rv = soc_mem_search(unit, VLAN_MACm, MEM_BLOCK_ALL, &idx, 4112 &vment, &res_vment, 0); 4113 soc_mem_unlock(unit, VLAN_MACm); 4114 BCM_IF_ERROR_RETURN(rv); 4115 4116 action->new_outer_vlan = 4117 soc_VLAN_MACm_field32_get(unit, &res_vment, OVIDf); 4118 action->new_inner_vlan = 4119 soc_VLAN_MACm_field32_get(unit, &res_vment, IVIDf); 4120 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 4121 action->priority = soc_VLAN_MACm_field32_get(unit, &res_vment, OPRIf); 4122 action->new_outer_cfi = 4123 soc_VLAN_MACm_field32_get(unit, &res_vment, OCFIf); 4124 action->new_inner_pkt_prio = 4125 soc_VLAN_MACm_field32_get(unit, &res_vment, IPRIf); 4126 action->new_inner_cfi = 4127 soc_VLAN_MACm_field32_get(unit, &res_vment, ICFIf); 4128 } else { 4129 action->priority = soc_VLAN_MACm_field32_get(unit, &res_vment, PRIf); 4130 } 4131 4132 /* Read action profile data. */ 4133 profile_idx = 4134 soc_VLAN_MACm_field32_get(unit, &res_vment, TAG_ACTION_PROFILE_PTRf); 4135 _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 4136 4137 return (BCM_E_NONE); 4138 } 4139 } 4140 4141 #if defined(BCM_TRIUMPH3_SUPPORT) 4142 STATIC int 4143 _bcm_tr3_vlan_mac_delete(int unit, bcm_mac_t mac) 4144 { 4145 vlan_xlate_entry_t vxent; 4146 int rv; 4147 uint32 profile_idx; 4148 4149 sal_memset(&vxent, 0, sizeof(vxent)); 4150 soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent), 4151 VLAN_MAC__MAC_ADDRf, mac); 4152 soc_VLAN_XLATEm_field32_set(unit, &vxent, KEY_TYPEf, 4153 TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC); 4154 soc_mem_lock(unit, VLAN_XLATEm); 4155 rv = soc_mem_delete_return_old(unit, VLAN_XLATEm, MEM_BLOCK_ALL, 4156 &vxent, &vxent); 4157 soc_mem_unlock(unit, VLAN_XLATEm); 4158 if (rv == SOC_E_NOT_FOUND) { 4159 rv = SOC_E_NONE; 4160 } else if ((rv == SOC_E_NONE) && soc_VLAN_XLATEm_field32_get(unit, 4161 &vxent, VALIDf)) { 4162 profile_idx = soc_VLAN_XLATEm_field32_get(unit, &vxent, 4163 VLAN_MAC__TAG_ACTION_PROFILE_PTRf); 4164 /* Delete the old vlan action profile entry */ 4165 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 4166 } 4167 return rv; 4168 } 4169 #endif /* BCM_TRIUMPH3_SUPPORT */ 4170 4171 /* 4172 * Function: 4173 * bcm_vlan_mac_delete 4174 * Purpose: 4175 * Delete a vlan mac lookup entry. 4176 * Parameters: 4177 * unit (IN) BCM unit number 4178 * mac (IN) MAC address 4179 * Returns: 4180 * BCM_E_XXX 4181 */ 4182 int 4183 _bcm_trx_vlan_mac_delete(int unit, bcm_mac_t mac) 4184 { 4185 #if defined(BCM_TRIUMPH3_SUPPORT) 4186 if (SOC_IS_TRIUMPH3(unit)) { 4187 BCM_IF_ERROR_RETURN 4188 (_bcm_tr3_vlan_mac_delete(unit,mac)); 4189 return BCM_E_NONE; 4190 } else 4191 #endif /* BCM_TRIUMPH3_SUPPORT */ 4192 { 4193 vlan_mac_entry_t vment; 4194 int rv; 4195 uint32 profile_idx; 4196 4197 sal_memset(&vment, 0, sizeof(vment)); 4198 soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac); 4199 soc_VLAN_MACm_field32_set(unit, &vment, KEY_TYPEf, 4200 TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC); 4201 soc_mem_lock(unit, VLAN_MACm); 4202 rv = soc_mem_delete_return_old(unit, VLAN_MACm, MEM_BLOCK_ALL, 4203 &vment, &vment); 4204 soc_mem_unlock(unit, VLAN_MACm); 4205 if (rv == SOC_E_NOT_FOUND) { 4206 rv = SOC_E_NONE; 4207 } else if ((rv == SOC_E_NONE) && soc_VLAN_MACm_field32_get(unit, &vment, VALIDf)) { 4208 profile_idx = soc_VLAN_MACm_field32_get(unit, &vment, 4209 TAG_ACTION_PROFILE_PTRf); 4210 /* Delete the old vlan action profile entry */ 4211 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 4212 } 4213 return rv; 4214 } 4215 } 4216 4217 #if defined(BCM_TRIUMPH3_SUPPORT) 4218 STATIC int 4219 _bcm_tr3_vlan_mac_delete_all(int unit) 4220 { 4221 int i, imin, imax, nent, vmbytes, rv; 4222 uint32 old_profile_idx; 4223 vlan_xlate_entry_t *vxtab, *vmnull, *vxtabp; 4224 4225 imin = soc_mem_index_min(unit, VLAN_XLATEm); 4226 imax = soc_mem_index_max(unit, VLAN_XLATEm); 4227 nent = soc_mem_index_count(unit, VLAN_XLATEm); 4228 vmbytes = soc_mem_entry_words(unit, VLAN_XLATEm); 4229 vmbytes = WORDS2BYTES(vmbytes); 4230 4231 vxtab = soc_cm_salloc(unit, nent * vmbytes, "vlan_xlate"); 4232 4233 if (vxtab == NULL) { 4234 return BCM_E_MEMORY; 4235 } 4236 4237 vmnull = soc_mem_entry_null(unit, VLAN_XLATEm); 4238 4239 soc_mem_lock(unit, VLAN_XLATEm); 4240 rv = soc_mem_read_range(unit, VLAN_XLATEm, MEM_BLOCK_ANY, 4241 imin, imax, vxtab); 4242 if (rv < 0) { 4243 soc_mem_unlock(unit, VLAN_XLATEm); 4244 soc_cm_sfree(unit, vxtab); 4245 return rv; 4246 } 4247 4248 for(i = 0; i < nent; i++) { 4249 vxtabp = soc_mem_table_idx_to_pointer(unit, VLAN_XLATEm, 4250 vlan_xlate_entry_t *, vxtab, i); 4251 4252 if (!soc_VLAN_XLATEm_field32_get(unit, vxtabp, VALIDf) || 4253 (soc_VLAN_XLATEm_field32_get(unit, vxtabp, KEY_TYPEf) != 4254 TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC)) { 4255 continue; 4256 } 4257 old_profile_idx = soc_VLAN_XLATEm_field32_get(unit, vxtabp, 4258 VLAN_MAC__TAG_ACTION_PROFILE_PTRf); 4259 4260 rv = WRITE_VLAN_XLATEm(unit, MEM_BLOCK_ANY, i, vmnull); 4261 4262 if (rv >= 0) { 4263 /* Delete the old vlan action profile entry */ 4264 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx); 4265 } 4266 } 4267 4268 soc_mem_unlock(unit, VLAN_XLATEm); 4269 soc_cm_sfree(unit, vxtab); 4270 return rv; 4271 } 4272 #endif /* BCM_TRIUMPH3_SUPPORT */ 4273 4274 /* 4275 * Function: 4276 * bcm_vlan_mac_delete_all 4277 * Purpose: 4278 * Delete all vlan mac lookup entries. 4279 * Parameters: 4280 * unit (IN) BCM unit number 4281 * Returns: 4282 * BCM_E_XXX 4283 */ 4284 int 4285 _bcm_trx_vlan_mac_delete_all(int unit) 4286 { 4287 #if defined(BCM_TRIUMPH3_SUPPORT) 4288 if (SOC_IS_TRIUMPH3(unit)) { 4289 BCM_IF_ERROR_RETURN 4290 (_bcm_tr3_vlan_mac_delete_all(unit)); 4291 return BCM_E_NONE; 4292 } else 4293 #endif /* BCM_TRIUMPH3_SUPPORT */ 4294 #if defined(BCM_TRIDENT3_SUPPORT) 4295 if (SOC_IS_TRIDENT3X(unit)) { 4296 BCM_IF_ERROR_RETURN 4297 (_bcm_td3_vlan_mac_delete_all(unit)); 4298 return BCM_E_NONE; 4299 } else 4300 #endif /* BCM_TRIDENT3_SUPPORT */ 4301 4302 { 4303 int i, imin, imax, nent, vmbytes, rv; 4304 uint32 old_profile_idx; 4305 vlan_mac_entry_t *vmtab, *vmnull, *vmtabp; 4306 4307 imin = soc_mem_index_min(unit, VLAN_MACm); 4308 imax = soc_mem_index_max(unit, VLAN_MACm); 4309 nent = soc_mem_index_count(unit, VLAN_MACm); 4310 vmbytes = soc_mem_entry_words(unit, VLAN_MACm); 4311 vmbytes = WORDS2BYTES(vmbytes); 4312 4313 vmtab = soc_cm_salloc(unit, nent * vmbytes, "vlan_mac"); 4314 4315 if (vmtab == NULL) { 4316 return BCM_E_MEMORY; 4317 } 4318 4319 vmnull = soc_mem_entry_null(unit, VLAN_MACm); 4320 4321 soc_mem_lock(unit, VLAN_MACm); 4322 rv = soc_mem_read_range(unit, VLAN_MACm, MEM_BLOCK_ANY, 4323 imin, imax, vmtab); 4324 soc_mem_unlock(unit, VLAN_MACm); 4325 4326 if (rv < 0) { 4327 soc_cm_sfree(unit, vmtab); 4328 return rv; 4329 } 4330 4331 soc_mem_lock(unit, VLAN_MACm); 4332 for(i = 0; i < nent; i++) { 4333 vmtabp = soc_mem_table_idx_to_pointer(unit, VLAN_MACm, 4334 vlan_mac_entry_t *, vmtab, i); 4335 4336 if (!soc_VLAN_MACm_field32_get(unit, vmtabp, VALIDf) || 4337 (soc_VLAN_MACm_field32_get(unit, vmtabp, KEY_TYPEf) != 4338 TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC)) { 4339 continue; 4340 } 4341 old_profile_idx = soc_VLAN_MACm_field32_get(unit, vmtabp, 4342 TAG_ACTION_PROFILE_PTRf); 4343 4344 rv = WRITE_VLAN_MACm(unit, MEM_BLOCK_ANY, i, vmnull); 4345 4346 if (rv >= 0) { 4347 /* Delete the old vlan action profile entry */ 4348 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx); 4349 } 4350 } 4351 4352 soc_mem_unlock(unit, VLAN_MACm); 4353 soc_cm_sfree(unit, vmtab); 4354 return rv; 4355 } 4356 } 4357 4358 #if defined(BCM_TRIUMPH3_SUPPORT) 4359 STATIC int 4360 _bcm_tr3_vlan_mac_action_traverse(int unit, 4361 bcm_vlan_mac_action_traverse_cb cb, 4362 void *user_data) 4363 { 4364 int idx, imin, imax, nent, vmbytes, rv; 4365 uint32 profile_idx; 4366 bcm_mac_t mac; 4367 bcm_vlan_action_set_t action; 4368 vlan_xlate_entry_t * vxtab, *vxtabp; 4369 4370 /* Input parameters check. */ 4371 if (NULL == cb) { 4372 return (BCM_E_PARAM); 4373 } 4374 4375 imin = soc_mem_index_min(unit, VLAN_XLATEm); 4376 imax = soc_mem_index_max(unit, VLAN_XLATEm); 4377 nent = soc_mem_index_count(unit, VLAN_XLATEm); 4378 vmbytes = soc_mem_entry_words(unit, VLAN_XLATEm); 4379 vmbytes = WORDS2BYTES(vmbytes); 4380 vxtab = soc_cm_salloc(unit, nent * sizeof(*vxtab), "vlan_xlate"); 4381 4382 if (vxtab == NULL) { 4383 return BCM_E_MEMORY; 4384 } 4385 4386 soc_mem_lock(unit, VLAN_XLATEm); 4387 rv = soc_mem_read_range(unit, VLAN_XLATEm, MEM_BLOCK_ANY, 4388 imin, imax, vxtab); 4389 if (BCM_FAILURE(rv)) { 4390 soc_mem_unlock(unit, VLAN_XLATEm); 4391 soc_cm_sfree(unit, vxtab); 4392 return rv; 4393 } 4394 4395 for(idx = 0; idx < nent; idx++) { 4396 sal_memset(mac, 0, sizeof(bcm_mac_t)); 4397 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 4398 vxtabp = soc_mem_table_idx_to_pointer(unit, VLAN_XLATEm, 4399 vlan_xlate_entry_t *, 4400 vxtab, idx); 4401 4402 if ((0 == soc_VLAN_XLATEm_field32_get(unit, vxtabp, VALIDf)) || 4403 (TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC != 4404 soc_VLAN_XLATEm_field32_get(unit, vxtabp, KEY_TYPEf))) { 4405 continue; 4406 } 4407 4408 /* Get entry mac address. */ 4409 soc_mem_mac_addr_get(unit, VLAN_XLATEm, (uint32 *)vxtabp, 4410 VLAN_MAC__MAC_ADDRf, mac); 4411 4412 action.new_outer_vlan = 4413 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__OVIDf); 4414 action.new_inner_vlan = 4415 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__IVIDf); 4416 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 4417 action.priority = soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__OPRIf); 4418 action.new_outer_cfi = 4419 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__OCFIf); 4420 action.new_inner_pkt_prio = 4421 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__IPRIf); 4422 action.new_inner_cfi = 4423 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__ICFIf); 4424 } else { 4425 action.priority = 4426 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__OPRIf); 4427 } 4428 4429 /* Read action profile data. */ 4430 profile_idx = 4431 soc_VLAN_XLATEm_field32_get(unit, vxtabp, 4432 VLAN_MAC__TAG_ACTION_PROFILE_PTRf); 4433 _bcm_trx_vlan_action_profile_entry_get(unit, &action, profile_idx); 4434 4435 /* Call traverse callback with the data. */ 4436 rv = cb(unit, mac, &action, user_data); 4437 if (BCM_FAILURE(rv)) { 4438 soc_mem_unlock(unit, VLAN_XLATEm); 4439 soc_cm_sfree(unit, vxtab); 4440 return rv; 4441 } 4442 } 4443 4444 soc_mem_unlock(unit, VLAN_XLATEm); 4445 soc_cm_sfree(unit, vxtab); 4446 return rv; 4447 } 4448 #endif /* BCM_TRIUMPH3_SUPPORT */ 4449 4450 /* 4451 * Function: 4452 * _bcm_trx_vlan_mac_action_traverse 4453 * Description : 4454 * Traverse over vlan mac actions, which are used for VLAN 4455 * tag/s assignment to untagged packets. 4456 * Parameters : 4457 * unit (IN) BCM unit number 4458 * cb (IN) Call back function 4459 * user_data (IN) User provided data to pass to a call back 4460 * Returns: 4461 * BCM_E_XXX 4462 */ 4463 int 4464 _bcm_trx_vlan_mac_action_traverse(int unit, 4465 bcm_vlan_mac_action_traverse_cb cb, 4466 void *user_data) 4467 { 4468 #if defined(BCM_TRIUMPH3_SUPPORT) 4469 if (SOC_IS_TRIUMPH3(unit)) { 4470 BCM_IF_ERROR_RETURN 4471 (_bcm_tr3_vlan_mac_action_traverse(unit,cb,user_data)); 4472 return BCM_E_NONE; 4473 } else 4474 #endif /* BCM_TRIUMPH3_SUPPORT */ 4475 { 4476 int idx, imin, imax, nent, vmbytes, rv; 4477 uint32 profile_idx; 4478 bcm_mac_t mac; 4479 bcm_vlan_action_set_t action; 4480 vlan_mac_entry_t * vmtab, *vmtabp; 4481 4482 /* Input parameters check. */ 4483 if (NULL == cb) { 4484 return (BCM_E_PARAM); 4485 } 4486 4487 imin = soc_mem_index_min(unit, VLAN_MACm); 4488 imax = soc_mem_index_max(unit, VLAN_MACm); 4489 nent = soc_mem_index_count(unit, VLAN_MACm); 4490 vmbytes = soc_mem_entry_words(unit, VLAN_MACm); 4491 vmbytes = WORDS2BYTES(vmbytes); 4492 vmtab = soc_cm_salloc(unit, nent * sizeof(*vmtab), "vlan_mac"); 4493 4494 if (vmtab == NULL) { 4495 return BCM_E_MEMORY; 4496 } 4497 4498 soc_mem_lock(unit, VLAN_MACm); 4499 rv = soc_mem_read_range(unit, VLAN_MACm, MEM_BLOCK_ANY, 4500 imin, imax, vmtab); 4501 if (BCM_FAILURE(rv)) { 4502 soc_mem_unlock(unit, VLAN_MACm); 4503 soc_cm_sfree(unit, vmtab); 4504 return rv; 4505 } 4506 4507 for(idx = 0; idx < nent; idx++) { 4508 sal_memset(mac, 0, sizeof(bcm_mac_t)); 4509 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 4510 vmtabp = soc_mem_table_idx_to_pointer(unit, VLAN_MACm, 4511 vlan_mac_entry_t *, 4512 vmtab, idx); 4513 4514 if ((0 == soc_VLAN_MACm_field32_get(unit, vmtabp, VALIDf)) || 4515 (TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC != 4516 soc_VLAN_MACm_field32_get(unit, vmtabp, KEY_TYPEf))) { 4517 continue; 4518 } 4519 4520 /* Get entry mac address. */ 4521 soc_VLAN_MACm_mac_addr_get(unit, vmtabp, MAC_ADDRf, mac); 4522 4523 action.new_outer_vlan = 4524 soc_VLAN_MACm_field32_get(unit, vmtabp, OVIDf); 4525 action.new_inner_vlan = 4526 soc_VLAN_MACm_field32_get(unit, vmtabp, IVIDf); 4527 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 4528 action.priority = soc_VLAN_MACm_field32_get(unit, vmtabp, OPRIf); 4529 action.new_outer_cfi = 4530 soc_VLAN_MACm_field32_get(unit, vmtabp, OCFIf); 4531 action.new_inner_pkt_prio = 4532 soc_VLAN_MACm_field32_get(unit, vmtabp, IPRIf); 4533 action.new_inner_cfi = 4534 soc_VLAN_MACm_field32_get(unit, vmtabp, ICFIf); 4535 } else { 4536 action.priority = 4537 soc_VLAN_MACm_field32_get(unit, vmtabp, PRIf); 4538 } 4539 4540 /* Read action profile data. */ 4541 profile_idx = 4542 soc_VLAN_MACm_field32_get(unit, vmtabp, TAG_ACTION_PROFILE_PTRf); 4543 _bcm_trx_vlan_action_profile_entry_get(unit, &action, profile_idx); 4544 4545 /* Call traverse callback with the data. */ 4546 rv = cb(unit, mac, &action, user_data); 4547 if (BCM_FAILURE(rv)) { 4548 soc_mem_unlock(unit, VLAN_MACm); 4549 soc_cm_sfree(unit, vmtab); 4550 return rv; 4551 } 4552 } 4553 4554 soc_mem_unlock(unit, VLAN_MACm); 4555 soc_cm_sfree(unit, vmtab); 4556 return rv; 4557 } 4558 } 4559 4560 /* 4561 * Function: 4562 * _bcm_trx_vif_vlan_translate_entry_parse 4563 * Purpose: 4564 * Parses vlan translate entry by given key_type, for inner and outer vlans 4565 * Parameters: 4566 * unit (IN) BCM unit number 4567 * mem (IN) Vlan translate memory id. 4568 * vent (IN) vlan translate entry to parse 4569 * action (OUT) Action to fill 4570 * Returns: 4571 * BCM_E_XXX 4572 */ 4573 STATIC int 4574 _bcm_trx_vif_vlan_translate_entry_parse(int unit, soc_mem_t mem, uint32 *vent, 4575 bcm_vlan_action_set_t *action) 4576 { 4577 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 4578 if (soc_feature(unit, soc_feature_niv)) { 4579 action->new_outer_vlan = soc_mem_field32_get(unit, VLAN_XLATEm, 4580 vent, VIF__NEW_OVIDf); 4581 action->new_inner_vlan = soc_mem_field32_get (unit, VLAN_XLATEm, 4582 vent, VIF__NEW_IVIDf); 4583 4584 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 4585 action->priority = soc_mem_field32_get(unit, VLAN_XLATEm, 4586 vent, VIF__NEW_OPRIf); 4587 action->new_outer_cfi = soc_mem_field32_get(unit, VLAN_XLATEm, 4588 vent, VIF__NEW_OCFIf); 4589 action->new_inner_pkt_prio = soc_mem_field32_get(unit, VLAN_XLATEm, 4590 vent, VIF__NEW_IPRIf); 4591 action->new_inner_cfi = soc_mem_field32_get(unit, VLAN_XLATEm, 4592 vent, VIF__NEW_ICFIf); 4593 } else { 4594 action->priority = soc_mem_field32_get(unit, VLAN_XLATEm, 4595 vent, VIF__PRIf); 4596 } 4597 4598 if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, VIF__L3_IIF_VALIDf) && 4599 soc_mem_field32_get(unit, VLAN_XLATEm, vent, VIF__L3_IIF_VALIDf)) { 4600 action->ingress_if = soc_mem_field32_get(unit, VLAN_XLATEm, 4601 vent, VIF__L3_IIFf); 4602 } 4603 return BCM_E_NONE; 4604 } 4605 #endif /* defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) */ 4606 return BCM_E_UNAVAIL; 4607 } 4608 4609 /* 4610 * Function: 4611 * _bcm_trx_vlan_translate_entry_parse 4612 * Purpose: 4613 * Parses vlan translate entry by given key_type, for inner and outer vlans 4614 * Parameters: 4615 * unit (IN) BCM unit number 4616 * mem (IN) Vlan translate memory id. 4617 * vent (IN) vlan translate entry to parse 4618 * action (OUT) Action to fill 4619 * Returns: 4620 * BCM_E_XXX 4621 */ 4622 STATIC int 4623 _bcm_trx_vlan_translate_entry_parse(int unit, soc_mem_t mem, uint32 *vent, 4624 bcm_vlan_action_set_t *action) 4625 { 4626 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 4627 defined(BCM_APACHE_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 4628 int offset = 0, index = 0; 4629 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 4630 BCM_APACHE_SUPPORT || BCM_GREYHOUND2_SUPPORT */ 4631 if ((NULL == vent) || (NULL == action) || (INVALIDm == mem)) { 4632 return BCM_E_PARAM; 4633 } 4634 4635 action->new_outer_vlan = soc_mem_field32_get(unit, mem, vent, NEW_OVIDf); 4636 action->new_inner_vlan = soc_mem_field32_get (unit, mem, vent, NEW_IVIDf); 4637 4638 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 4639 action->priority = soc_mem_field32_get(unit, mem, vent, NEW_OPRIf); 4640 action->new_outer_cfi = 4641 soc_mem_field32_get(unit, mem, vent, NEW_OCFIf); 4642 action->new_inner_pkt_prio = 4643 soc_mem_field32_get(unit, mem, vent, NEW_IPRIf); 4644 action->new_inner_cfi = 4645 soc_mem_field32_get(unit, mem, vent, NEW_ICFIf); 4646 } else { 4647 action->priority = soc_mem_field32_get(unit, mem, vent, PRIf); 4648 } 4649 4650 if (SOC_MEM_FIELD_VALID(unit, mem, DISABLE_VLAN_CHECKSf) && 4651 soc_mem_field32_get(unit, mem, vent, DISABLE_VLAN_CHECKSf)) { 4652 action->flags |= BCM_VLAN_ACTION_SET_VLAN_CHECKS_DISABLE; 4653 } 4654 4655 #if defined(BCM_TSN_SR_SUPPORT) 4656 if (soc_feature(unit, soc_feature_tsn_sr)) { 4657 if (soc_mem_field32_get(unit, mem, vent, SR_ENABLEf)) { 4658 action->flags |= BCM_VLAN_ACTION_SET_SR_ENABLE; 4659 if (soc_mem_field32_get(unit, mem, vent, SR_LAN_IDf)) { 4660 action->flags |= BCM_VLAN_ACTION_SET_SR_LAN_ID; 4661 } 4662 } 4663 } 4664 #endif /* BCM_TSN_SR_SUPPORT*/ 4665 4666 #if defined(BCM_TSN_SUPPORT) 4667 if (soc_feature(unit, soc_feature_tsn_taf) && 4668 SOC_MEM_FIELD_VALID(unit, mem, TAF_GATE_ID_PROFILEf)) { 4669 uint32 value = 4670 soc_mem_field32_get(unit, mem, vent, TAF_GATE_ID_PROFILEf); 4671 if (0 != value) { 4672 bcm_tsn_pri_map_t sw_index; 4673 4674 BCM_IF_ERROR_RETURN( 4675 bcmi_esw_tsn_pri_map_map_id_get(unit, bcmTsnPriMapTypeTafGate, 4676 value, &sw_index)); 4677 action->taf_gate_primap = sw_index; 4678 } else { 4679 action->taf_gate_primap = BCM_TSN_PRI_MAP_INVALID; 4680 } 4681 } else 4682 #endif /* BCM_TSN_SUPPORT */ 4683 { 4684 action->taf_gate_primap = BCM_TSN_PRI_MAP_INVALID; 4685 } 4686 4687 if (SOC_IS_TR_VL(unit) && (!(SOC_IS_HURRICANE(unit) || 4688 SOC_IS_HURRICANE2(unit)))) { 4689 if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) { 4690 if (soc_mem_field32_get(unit, mem, vent, MPLS_ACTIONf) == 0x2) { 4691 action->ingress_if = 4692 soc_mem_field32_get(unit, mem, vent, L3_IIFf); 4693 } 4694 #if defined(BCM_TRIDENT2_SUPPORT) 4695 else if (soc_mem_field32_get(unit, mem, vent, MPLS_ACTIONf) == 0x3) { 4696 if (soc_feature(unit, soc_feature_vlan_xlate_iif_with_dummy_vp) && 4697 soc_property_get(unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0) && 4698 soc_mem_field32_get(unit, mem, vent, SOURCE_VPf) == _BCM_VLAN_XLATE_DUMMY_PORT) { 4699 action->flags |= BCM_VLAN_ACTION_SET_DUMMY_VP; 4700 action->ingress_if = 4701 soc_mem_field32_get(unit, mem, vent, L3_IIFf); 4702 } 4703 4704 } 4705 #endif /* BCM_TRIDENT2_SUPPORT */ 4706 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4707 else if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf)) { 4708 action->class_id = soc_mem_field32_get(unit, mem, vent, CLASS_IDf); 4709 } 4710 #endif 4711 } 4712 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4713 else if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_ID_VALIDf)) { 4714 if (soc_mem_field32_get(unit, mem, vent, CLASS_ID_VALIDf)) { 4715 action->class_id = soc_mem_field32_get(unit, mem, vent, CLASS_IDf); 4716 } 4717 } 4718 #endif 4719 } 4720 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 4721 defined(BCM_APACHE_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 4722 if (soc_feature(unit, soc_feature_global_meter)) { 4723 if (SOC_IS_KATANAX(unit) || SOC_IS_GREYHOUND2(unit) || 4724 (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit))) { 4725 4726 if (SOC_MEM_FIELD_VALID(unit, mem, SVC_METER_OFFSET_MODEf)) { 4727 offset = soc_mem_field32_get(unit, mem, vent, 4728 SVC_METER_OFFSET_MODEf); 4729 } 4730 if (SOC_MEM_FIELD_VALID(unit, mem, SVC_METER_INDEXf)) { 4731 index = soc_mem_field32_get(unit, mem, vent, SVC_METER_INDEXf); 4732 } 4733 } else if (SOC_IS_TRIUMPH3(unit)) { 4734 if (SOC_MEM_FIELD_VALID(unit, mem, 4735 XLATE__SVC_METER_OFFSET_MODEf)) { 4736 offset = soc_mem_field32_get(unit, mem, vent, 4737 XLATE__SVC_METER_OFFSET_MODEf); 4738 } 4739 if (SOC_MEM_FIELD_VALID(unit, mem, XLATE__SVC_METER_INDEXf)) { 4740 index = soc_mem_field32_get(unit, mem, vent, 4741 XLATE__SVC_METER_INDEXf); 4742 } 4743 } 4744 _bcm_esw_get_policer_id_from_index_offset(unit, index, offset, 4745 &action->policer_id); 4746 } 4747 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 4748 BCM_APACHE_SUPPORT || BCM_GREYHOUND2_SUPPORT */ 4749 4750 return BCM_E_NONE; 4751 } 4752 4753 /* 4754 * Function: 4755 * _bcm_trx_vif_vlan_translate_entry_assemble 4756 * Purpose: 4757 * Constructs vif vlan translate entry from given key_type, inner and outer vlans 4758 * Parameters: 4759 * unit (IN) BCM unit number 4760 * vent (IN/OUT) vlan translate entry to construct 4761 * key_type (IN) Key Type : bcmVlanTranslateKey* 4762 * inner_vlan (IN) inner VLAN ID 4763 * outer_vlan (IN) outer VLAN ID 4764 * Returns: 4765 * BCM_E_XXX 4766 */ 4767 int 4768 _bcm_trx_vif_vlan_translate_entry_assemble(int unit, void *vent, 4769 bcm_gport_t niv_port_id, 4770 bcm_vlan_translate_key_t key_type, 4771 bcm_vlan_t inner_vlan, 4772 bcm_vlan_t outer_vlan) 4773 { 4774 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 4775 if (soc_feature(unit, soc_feature_niv)) { 4776 int tmp_id; 4777 bcm_module_t mod_out; 4778 bcm_port_t port_out; 4779 bcm_trunk_t trunk_out; 4780 int key_type_value; 4781 bcm_niv_port_t niv_port; 4782 bcm_niv_egress_t niv_egress; 4783 int rv = BCM_E_NONE; 4784 uint16 virtual_interface_id = 0; 4785 bcm_gport_t gport; 4786 int count; 4787 4788 soc_mem_t mem = VLAN_XLATEm; 4789 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 4790 mem = VLAN_XLATE_1_DOUBLEm; 4791 } 4792 4793 if (!BCM_GPORT_IS_NIV_PORT(niv_port_id)) { 4794 return BCM_E_PORT; 4795 } 4796 4797 switch (key_type) { 4798 case bcmVlanTranslateKeyPortOuterTag: 4799 key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG; 4800 soc_mem_field32_set(unit, mem, vent, VIF__OTAGf, outer_vlan); 4801 break; 4802 4803 case bcmVlanTranslateKeyPortInnerTag: 4804 key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG; 4805 soc_mem_field32_set(unit, mem, vent, VIF__ITAGf, inner_vlan); 4806 break; 4807 4808 case bcmVlanTranslateKeyPortOuter: 4809 key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN; 4810 soc_mem_field32_set(unit, mem, vent, VIF__VLANf, outer_vlan); 4811 break; 4812 4813 case bcmVlanTranslateKeyPortInner: 4814 key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN; 4815 soc_mem_field32_set(unit, mem, vent, VIF__CVLANf,inner_vlan); 4816 break; 4817 4818 default: 4819 return BCM_E_PARAM; 4820 } 4821 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_xlate_key_type_value_get(unit, 4822 key_type, &key_type_value)); 4823 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 4824 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 4825 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 4826 } 4827 4828 niv_port.niv_port_id = niv_port_id; 4829 BCM_IF_ERROR_RETURN(bcm_esw_niv_port_get(unit,&niv_port)); 4830 if (niv_port.flags & BCM_NIV_PORT_MATCH_NONE) { 4831 bcm_niv_egress_t_init(&niv_egress); 4832 rv = bcm_trident_niv_egress_get(unit, niv_port.niv_port_id, 4833 1, &niv_egress, &count); 4834 if (BCM_FAILURE(rv)) { 4835 return BCM_E_PARAM; 4836 } 4837 4838 if (niv_egress.flags & BCM_NIV_EGRESS_MULTICAST) { 4839 return BCM_E_PARAM; 4840 } else { 4841 virtual_interface_id = niv_egress.virtual_interface_id; 4842 gport = niv_egress.port; 4843 } 4844 } else { 4845 virtual_interface_id = niv_port.virtual_interface_id; 4846 gport = niv_port.port; 4847 } 4848 4849 soc_mem_field32_set(unit, mem, vent, VIF__SRC_VIFf, 4850 virtual_interface_id); 4851 4852 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 4853 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 4854 } 4855 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, 4856 &mod_out, &port_out, &trunk_out, &tmp_id)); 4857 if (BCM_GPORT_IS_TRUNK(gport)) { 4858 soc_mem_field32_set(unit, mem, vent, VIF__Tf, 1); 4859 soc_mem_field32_set(unit, mem, vent, VIF__TGIDf, trunk_out); 4860 } else { 4861 soc_mem_field32_set(unit, mem, vent, VIF__MODULE_IDf, mod_out); 4862 soc_mem_field32_set(unit, mem, vent, VIF__PORT_NUMf, port_out); 4863 } 4864 return BCM_E_NONE; 4865 } 4866 #endif /* defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) */ 4867 return BCM_E_UNAVAIL; 4868 } 4869 4870 /* 4871 * Function: 4872 * _bcm_trx_lltag_vlan_translate_entry_assemble 4873 * Purpose: 4874 * Constructs lltag vlan translate entry from given key_type, lltag vlan and other vlans 4875 * Parameters: 4876 * unit (IN) BCM unit number 4877 * vent (IN/OUT) vlan translate entry to construct 4878 * key_type (IN) Key Type : bcmVlanTranslateKey* 4879 * lltag_vlan (IN) LLTAG VLAN ID 4880 * other_vlan (IN) other VLAN ID denpends on the key_type 4881 * Returns: 4882 * BCM_E_XXX 4883 */ 4884 int 4885 _bcm_trx_lltag_vlan_translate_entry_assemble(int unit, void *vent, 4886 bcm_gport_t port, 4887 bcm_vlan_translate_key_t key_type, 4888 bcm_vlan_t lltag_vlan, 4889 bcm_vlan_t other_vlan) 4890 { 4891 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3) 4892 if (soc_feature(unit, soc_feature_lltag)) { 4893 int use_glp = 1; /* By default incoming port used in lookup key */ 4894 int tmp_id; 4895 bcm_module_t mod_out; 4896 bcm_port_t port_out; 4897 bcm_trunk_t trunk_out; 4898 int key_type_value; 4899 soc_mem_t mem = VLAN_XLATEm; 4900 4901 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 4902 mem = VLAN_XLATE_1_DOUBLEm; 4903 } 4904 4905 switch (key_type) { 4906 case bcmVlanTranslateKeyPortPonTunnel: 4907 use_glp = 1; 4908 VLAN_CHK_ID(unit, lltag_vlan); 4909 BCM_IF_ERROR_RETURN 4910 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 4911 VLXLT_HASH_KEY_TYPE_LLVID, 4912 &key_type_value)); 4913 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 4914 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 4915 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 4916 } 4917 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan); 4918 break; 4919 case bcmVlanTranslateKeyPortPonTunnelOuter: 4920 use_glp = 1; 4921 VLAN_CHK_ID(unit, lltag_vlan); 4922 VLAN_CHK_ID(unit, other_vlan); 4923 BCM_IF_ERROR_RETURN 4924 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 4925 VLXLT_HASH_KEY_TYPE_LLVID_OVID, 4926 &key_type_value)); 4927 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 4928 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 4929 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 4930 } 4931 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan); 4932 soc_mem_field32_set(unit, mem, vent, LLTAG__OVIDf, other_vlan); 4933 break; 4934 case bcmVlanTranslateKeyPortPonTunnelInner: 4935 use_glp = 1; 4936 VLAN_CHK_ID(unit, lltag_vlan); 4937 VLAN_CHK_ID(unit, other_vlan); 4938 BCM_IF_ERROR_RETURN 4939 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 4940 VLXLT_HASK_KEY_TYPE_LLVID_IVID, 4941 &key_type_value)); 4942 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 4943 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 4944 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 4945 } 4946 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan); 4947 soc_mem_field32_set(unit, mem, vent, LLTAG__IVIDf, other_vlan); 4948 break; 4949 default: 4950 return BCM_E_PARAM; 4951 } 4952 4953 if (use_glp) { 4954 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 4955 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 4956 } 4957 BCM_IF_ERROR_RETURN 4958 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, 4959 &trunk_out, &tmp_id)); 4960 if (BCM_GPORT_IS_TRUNK(port)) { 4961 soc_mem_field32_set(unit, mem, vent, LLTAG__Tf, 1); 4962 soc_mem_field32_set(unit, mem, vent, LLTAG__TGIDf, trunk_out); 4963 } else { 4964 soc_mem_field32_set(unit, mem, vent, LLTAG__MODULE_IDf, mod_out); 4965 soc_mem_field32_set(unit, mem, vent, LLTAG__PORT_NUMf, port_out); 4966 } 4967 } else { 4968 /* SOURCE_TYPE field in vent is 0 */ 4969 4970 /* incoming port not used in lookup key, set field to all 1's */ 4971 /* coverity[dead_error_line : FALSE] */ 4972 soc_mem_field32_set(unit, mem, vent, LLTAG__GLPf, 4973 SOC_VLAN_XLATE_GLP_WILDCARD(unit)); 4974 } 4975 return BCM_E_NONE; 4976 } 4977 #endif 4978 return BCM_E_UNAVAIL; 4979 } 4980 4981 #define PORT_GROUP_MAX 0xffff 4982 4983 /* 4984 * Function: 4985 * _bcm_trx_vlan_translate_entry_assemble 4986 * Purpose: 4987 * Constructs vlan translate entry from given key_type, inner and outer vlans 4988 * Parameters: 4989 * unit (IN) BCM unit number 4990 * vent (IN/OUT) vlan translate entry to construct 4991 * key_type (IN) Key Type : bcmVlanTranslateKey* 4992 * inner_vlan (IN) inner VLAN ID 4993 * outer_vlan (IN) outer VLAN ID 4994 * Returns: 4995 * BCM_E_XXX 4996 */ 4997 int 4998 _bcm_trx_vlan_translate_entry_assemble(int unit, void *vent, 4999 bcm_gport_t port, 5000 bcm_vlan_translate_key_t key_type, 5001 bcm_vlan_t inner_vlan, 5002 bcm_vlan_t outer_vlan) 5003 { 5004 int use_glp = 1; /* By default incoming port used in lookup key */ 5005 int tmp_id; 5006 bcm_module_t mod_out; 5007 bcm_port_t port_out; 5008 bcm_trunk_t trunk_out = -1; 5009 int key_type_value; 5010 soc_mem_t mem = VLAN_XLATEm; 5011 5012 #if defined(BCM_TRIDENT2_SUPPORT) 5013 int use_port_group = 0; 5014 uint32 port_group; 5015 #endif 5016 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 5017 mem = VLAN_XLATE_1_DOUBLEm; 5018 } 5019 5020 switch (key_type) { 5021 #if defined(BCM_TRIDENT2_SUPPORT) 5022 case bcmVlanTranslateKeyPortGroupDouble: 5023 use_port_group = 1; 5024 /* Fall through */ 5025 #endif 5026 case bcmVlanTranslateKeyDouble: 5027 use_glp = 0; 5028 /* Fall through */ 5029 case bcmVlanTranslateKeyPortDouble: 5030 VLAN_CHK_ID(unit, inner_vlan); 5031 VLAN_CHK_ID(unit, outer_vlan); 5032 BCM_IF_ERROR_RETURN 5033 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5034 VLXLT_HASH_KEY_TYPE_IVID_OVID, 5035 &key_type_value)); 5036 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5037 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5038 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5039 } 5040 soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan); 5041 soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan); 5042 break; 5043 #if defined(BCM_TRIDENT2_SUPPORT) 5044 case bcmVlanTranslateKeyPortGroupOuterTag: 5045 use_port_group = 1; 5046 /* Fall through */ 5047 #endif 5048 case bcmVlanTranslateKeyOuterTag: 5049 use_glp = 0; 5050 /* Fall through */ 5051 case bcmVlanTranslateKeyPortOuterTag: 5052 /* allow 16 bit VLAN id */ 5053 BCM_IF_ERROR_RETURN 5054 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5055 VLXLT_HASH_KEY_TYPE_OTAG, 5056 &key_type_value)); 5057 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5058 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5059 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5060 } 5061 soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan); 5062 break; 5063 #if defined(BCM_TRIDENT2_SUPPORT) 5064 case bcmVlanTranslateKeyPortGroupInnerTag: 5065 use_port_group = 1; 5066 /* Fall through */ 5067 #endif 5068 case bcmVlanTranslateKeyInnerTag: 5069 use_glp = 0; 5070 /* Fall through */ 5071 case bcmVlanTranslateKeyPortInnerTag: 5072 /* Allow 16 bit VLAN id */ 5073 BCM_IF_ERROR_RETURN 5074 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5075 VLXLT_HASH_KEY_TYPE_ITAG, 5076 &key_type_value)); 5077 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5078 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5079 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5080 } 5081 soc_mem_field32_set(unit, mem, vent, ITAGf, inner_vlan); 5082 break; 5083 #if defined(BCM_TRIDENT2_SUPPORT) 5084 case bcmVlanTranslateKeyPortGroupOuter: 5085 use_port_group = 1; 5086 /* Fall through */ 5087 #endif 5088 case bcmVlanTranslateKeyOuter: 5089 use_glp = 0; 5090 /* Fall through */ 5091 case bcmVlanTranslateKeyPortOuter: 5092 VLAN_CHK_ID(unit, outer_vlan); 5093 BCM_IF_ERROR_RETURN 5094 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5095 VLXLT_HASH_KEY_TYPE_OVID, 5096 &key_type_value)); 5097 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5098 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5099 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5100 } 5101 soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan); 5102 break; 5103 #if defined(BCM_TRIDENT2_SUPPORT) 5104 case bcmVlanTranslateKeyPortGroupInner: 5105 use_port_group = 1; 5106 /* Fall through */ 5107 #endif 5108 case bcmVlanTranslateKeyInner: 5109 use_glp = 0; 5110 /* Fall through */ 5111 case bcmVlanTranslateKeyPortInner: 5112 VLAN_CHK_ID(unit, inner_vlan); 5113 BCM_IF_ERROR_RETURN 5114 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5115 VLXLT_HASH_KEY_TYPE_IVID, 5116 &key_type_value)); 5117 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5118 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5119 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5120 } 5121 soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan); 5122 break; 5123 #if defined(BCM_TRIDENT2_SUPPORT) 5124 case bcmVlanTranslateKeyPortGroupOuterPri: 5125 use_port_group = 1; 5126 /* Fall through */ 5127 #endif 5128 case bcmVlanTranslateKeyOuterPri: 5129 use_glp = 0; 5130 /* Fall through */ 5131 case bcmVlanTranslateKeyPortOuterPri: 5132 /* Allow Hi 4 bits in 16 bit VLAN tag */ 5133 BCM_IF_ERROR_RETURN 5134 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5135 VLXLT_HASH_KEY_TYPE_PRI_CFI, 5136 &key_type_value)); 5137 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5138 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5139 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5140 } 5141 /* outer_vlan: Bits 12-15 contains VLAN_PRI + CFI, vlan=BCM_VLAN_NONE */ 5142 soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan); 5143 break; 5144 case bcmVlanTranslateKeyCapwapPayloadDouble: 5145 use_glp = 0; 5146 /* Fall through */ 5147 case bcmVlanTranslateKeyPortCapwapPayloadDouble: 5148 VLAN_CHK_ID(unit, inner_vlan); 5149 VLAN_CHK_ID(unit, outer_vlan); 5150 BCM_IF_ERROR_RETURN 5151 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5152 VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID, 5153 &key_type_value)); 5154 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5155 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5156 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5157 } 5158 soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan); 5159 soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan); 5160 break; 5161 case bcmVlanTranslateKeyCapwapPayloadOuter: 5162 use_glp = 0; 5163 /* Fall through */ 5164 case bcmVlanTranslateKeyPortCapwapPayloadOuter: 5165 VLAN_CHK_ID(unit, outer_vlan); 5166 BCM_IF_ERROR_RETURN 5167 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5168 VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID, 5169 &key_type_value)); 5170 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5171 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5172 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5173 } 5174 soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan); 5175 break; 5176 case bcmVlanTranslateKeyCapwapPayloadInner: 5177 use_glp = 0; 5178 /* Fall through */ 5179 case bcmVlanTranslateKeyPortCapwapPayloadInner: 5180 VLAN_CHK_ID(unit, inner_vlan); 5181 BCM_IF_ERROR_RETURN 5182 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5183 VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID, 5184 &key_type_value)); 5185 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5186 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5187 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5188 } 5189 soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan); 5190 break; 5191 case bcmVlanTranslateKeyCapwapPayloadOuterTag: 5192 use_glp = 0; 5193 /* Fall through */ 5194 case bcmVlanTranslateKeyPortCapwapPayloadOuterTag: 5195 /* allow 16 bit VLAN id */ 5196 BCM_IF_ERROR_RETURN 5197 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5198 VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG, 5199 &key_type_value)); 5200 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5201 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5202 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5203 } 5204 soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan); 5205 break; 5206 case bcmVlanTranslateKeyCapwapPayloadInnerTag: 5207 use_glp = 0; 5208 /* Fall through */ 5209 case bcmVlanTranslateKeyPortCapwapPayloadInnerTag: 5210 /* Allow 16 bit VLAN id */ 5211 BCM_IF_ERROR_RETURN 5212 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 5213 VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG, 5214 &key_type_value)); 5215 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 5216 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5217 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value); 5218 } 5219 soc_mem_field32_set(unit, mem, vent, ITAGf, inner_vlan); 5220 break; 5221 default: 5222 return BCM_E_PARAM; 5223 } 5224 5225 #if defined(BCM_TRIDENT2_SUPPORT) 5226 if (use_port_group) { 5227 if (!soc_feature(unit, soc_feature_port_group_for_ivxlt)) { 5228 return BCM_E_UNAVAIL; 5229 } 5230 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 3); 5231 if((port < 0) || (port > PORT_GROUP_MAX)) { 5232 return BCM_E_PARAM; 5233 } 5234 port_group = port; 5235 soc_mem_field32_set(unit, mem, vent, SOURCE_FIELDf, port_group); 5236 } else 5237 #endif /* BCM_TRIDENT2_SUPPORT */ 5238 if (use_glp) { 5239 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 5240 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 5241 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 5242 } 5243 #endif 5244 BCM_IF_ERROR_RETURN 5245 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, 5246 &trunk_out, &tmp_id)); 5247 /* In case of extended queuing on KTX, tgid_out gets updated with 5248 * extended queue value. So set it to invalid value. 5249 */ 5250 #ifdef BCM_KATANA_SUPPORT 5251 if (soc_feature(unit, soc_feature_extended_queueing)) { 5252 if ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(port)) || 5253 (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port)) || 5254 (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port))) { 5255 trunk_out = BCM_TRUNK_INVALID; 5256 } 5257 } 5258 #endif 5259 if (trunk_out >= 0) { 5260 soc_mem_field32_set(unit, mem, vent, Tf, 1); 5261 soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_out); 5262 } else { 5263 soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out); 5264 soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out); 5265 } 5266 } else { 5267 /* SOURCE_TYPE field in vent is 0 */ 5268 5269 /* incoming port not used in lookup key, set field to all 1's */ 5270 soc_mem_field32_set(unit, mem, vent, GLPf, 5271 SOC_VLAN_XLATE_GLP_WILDCARD(unit)); 5272 } 5273 return BCM_E_NONE; 5274 } 5275 5276 /* 5277 * Function: 5278 * _bcm_trx_vlan_translate_action_entry_update 5279 * Purpose: 5280 * Update Vlan_xlate Entry. 5281 * Currently it only updates the fields by the actions 5282 * specified in bcm_vlan_action_set_t. 5283 * Parameters: 5284 * IN : Unit 5285 * IN : vlan_xlate_entry 5286 * OUT : vlan_xlate_entry 5287 5288 */ 5289 5290 STATIC int 5291 _bcm_trx_vlan_translate_action_entry_update(int unit, void *vent, 5292 void *return_ent) 5293 { 5294 uint32 key_type, value; 5295 uint32 l3_iif_valid = 0; 5296 uint32 ret_svp_valid = 0; 5297 #if defined(BCM_TRIDENT2_SUPPORT) 5298 uint32 svp_valid = 0; 5299 uint32 ret_svp = 0; 5300 uint32 svp = 0; 5301 uint32 dummy_svp_chk = 0; 5302 uint32 svp_dummy = 0; 5303 #endif /* BCM_TRIDENT2_SUPPORT */ 5304 5305 bcm_vlan_t outer_vlan, inner_vlan; 5306 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) || \ 5307 defined(BCM_GREYHOUND2_SUPPORT) 5308 bcm_policer_t current_policer = 0; 5309 int rv = BCM_E_NONE; 5310 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT || 5311 BCM_GREYHOUND2_SUPPORT */ 5312 5313 soc_mem_t mem = VLAN_XLATEm; 5314 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 5315 mem = VLAN_XLATE_1_DOUBLEm; 5316 } 5317 5318 /* Check if Key_Type identical */ 5319 key_type = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf); 5320 value = soc_mem_field32_get(unit, mem, return_ent, KEY_TYPEf); 5321 if (key_type != value) { 5322 return BCM_E_PARAM; 5323 } 5324 5325 /* Retain original Keys -- Update data only */ 5326 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 5327 value = soc_mem_field32_get(unit, mem, vent, NEW_OPRIf); 5328 soc_mem_field32_set(unit, mem, return_ent, NEW_OPRIf, value); 5329 value = soc_mem_field32_get(unit, mem, vent, NEW_OCFIf); 5330 soc_mem_field32_set(unit, mem, return_ent, NEW_OCFIf, value); 5331 value = soc_mem_field32_get(unit, mem, vent, NEW_IPRIf); 5332 soc_mem_field32_set(unit, mem, return_ent, NEW_IPRIf, value); 5333 value = soc_mem_field32_get(unit, mem, vent, NEW_ICFIf); 5334 soc_mem_field32_set(unit, mem, return_ent, NEW_ICFIf, value); 5335 } else { 5336 value = soc_mem_field32_get(unit, mem, vent, RPEf); 5337 soc_mem_field32_set(unit, mem, return_ent, RPEf, value); 5338 if (value) { 5339 value = soc_mem_field32_get(unit, mem, vent, PRIf); 5340 soc_mem_field32_set(unit, mem, return_ent, PRIf, value); 5341 } 5342 } 5343 5344 value = soc_mem_field32_get(unit, mem, vent, TAG_ACTION_PROFILE_PTRf); 5345 soc_mem_field32_set(unit, mem, return_ent, TAG_ACTION_PROFILE_PTRf, value); 5346 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_ACTION_VALIDf)) { 5347 value = soc_mem_field32_get(unit, mem, vent, VLAN_ACTION_VALIDf); 5348 soc_mem_field32_set(unit, mem, return_ent, VLAN_ACTION_VALIDf,value); 5349 } 5350 5351 if (SOC_MEM_FIELD_VALID(unit, mem, DISABLE_VLAN_CHECKSf)) { 5352 value = soc_mem_field32_get(unit, mem, vent, DISABLE_VLAN_CHECKSf); 5353 soc_mem_field32_set(unit, mem, return_ent, 5354 DISABLE_VLAN_CHECKSf, value); 5355 } 5356 5357 inner_vlan = soc_mem_field32_get(unit, mem, vent, NEW_IVIDf); 5358 soc_mem_field32_set(unit, mem, return_ent, NEW_IVIDf, inner_vlan); 5359 outer_vlan = soc_mem_field32_get(unit, mem, vent, NEW_OVIDf); 5360 soc_mem_field32_set(unit, mem, return_ent, NEW_OVIDf, outer_vlan); 5361 5362 #if defined(BCM_TRIDENT2_SUPPORT) 5363 if (soc_feature(unit, soc_feature_vlan_xlate_iif_with_dummy_vp) && 5364 soc_property_get(unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0)) { 5365 svp = soc_mem_field32_get(unit, mem, vent, SOURCE_VPf); 5366 ret_svp = soc_mem_field32_get(unit, mem, return_ent, SOURCE_VPf); 5367 if (svp == _BCM_VLAN_XLATE_DUMMY_PORT || 5368 ret_svp == _BCM_VLAN_XLATE_DUMMY_PORT) { 5369 dummy_svp_chk = 1; 5370 } 5371 } 5372 #endif /* defined(BCM_TRIDENT2_SUPPORT) */ 5373 5374 if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) { 5375 /* Only carry forward the L3_IIF encoding and leave L2_SVP as is */ 5376 l3_iif_valid = soc_mem_field32_get(unit, mem, vent, MPLS_ACTIONf) & 0x2; 5377 ret_svp_valid = 0x1 & 5378 soc_mem_field32_get(unit, mem, return_ent, MPLS_ACTIONf); 5379 5380 /* If the device supports MPLS_ACTION value 0x3 i.e. both L3_IIF and 5381 * L2_SVP simultaneously then retain the SVP_VALID bit. To check if 5382 * the device supports both actions simultaneously, use existence 5383 * of L3_IIF_VALID field as this field is only present in chips which 5384 * has the support. 5385 */ 5386 if (SOC_MEM_FIELD_VALID(unit, mem, L3_IIF_VALIDf)) { 5387 #if defined(BCM_TRIDENT2_SUPPORT) 5388 if (soc_feature(unit, soc_feature_vlan_xlate_iif_with_dummy_vp) && 5389 soc_property_get(unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0) && 5390 dummy_svp_chk) { 5391 5392 svp_valid = 5393 soc_mem_field32_get(unit, mem, vent, MPLS_ACTIONf) & 0x1; 5394 if ((svp_valid == 1) && (svp == _BCM_VLAN_XLATE_DUMMY_PORT)) { 5395 /* svp is either invalid or a dummy VP */ 5396 svp_dummy = 1; 5397 } 5398 5399 if (svp_dummy && 5400 (ret_svp_valid && ret_svp != _BCM_VLAN_XLATE_DUMMY_PORT)) { 5401 /* svp information conflicts */ 5402 return BCM_E_PARAM; 5403 } 5404 5405 if (!ret_svp_valid || (ret_svp == _BCM_VLAN_XLATE_DUMMY_PORT)) { 5406 /* 5407 * In this case, the ret_svp is either invalid or a dummy vp 5408 * configured with L3 IIF, it should be updated. 5409 */ 5410 value = l3_iif_valid | svp_valid; 5411 soc_mem_field32_set(unit, mem, return_ent, SOURCE_VPf, svp); 5412 } 5413 } else 5414 #endif /* defined(BCM_TRIDENT2_SUPPORT) */ 5415 { 5416 value = l3_iif_valid | ret_svp_valid; 5417 } 5418 } else if (l3_iif_valid) { 5419 /* The device does not support setting simultaneously L3_IIF and 5420 * L2_SVP, and if L3_IIF_VALID bit is set then it takes precedence 5421 * over L2_SVP. 5422 */ 5423 value = l3_iif_valid; 5424 } else { 5425 /* If L3_IIF_VALID bit is not set then retain the SVP_VALID */ 5426 value = ret_svp_valid; 5427 } 5428 5429 soc_mem_field32_set(unit, mem, return_ent, MPLS_ACTIONf, value); 5430 } 5431 5432 /* Retreive the resolved L3_IIF_VALID field status */ 5433 if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) { 5434 /* The second bit as it corresponds to L3_IIF_VALID */ 5435 l3_iif_valid = 5436 0x2 & soc_mem_field32_get(unit, mem, return_ent, MPLS_ACTIONf); 5437 } else { 5438 /* L3_IIF_VALID bit couldnt be retrieved hence assume not valid */ 5439 l3_iif_valid = 0; 5440 } 5441 5442 5443 if (l3_iif_valid) { 5444 if (SOC_MEM_FIELD_VALID(unit, mem, L3_IIFf)) { 5445 /* Update the L3_IIF field if the corresponding valid bit is set */ 5446 value = soc_mem_field32_get(unit, mem, vent, L3_IIFf); 5447 soc_mem_field32_set(unit, mem, return_ent, L3_IIFf, value); 5448 } 5449 } 5450 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5451 else if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf)) { 5452 /* If the L3_IIF is not valid and CLASS_ID field exists, though 5453 * overlaid on L3_IIF field, then perform update on CLASS_ID field. 5454 */ 5455 value = soc_mem_field32_get(unit, mem, vent, CLASS_IDf); 5456 soc_mem_field32_set(unit, mem, return_ent, CLASS_IDf, value); 5457 } 5458 #endif 5459 5460 #if defined(BCM_GREYHOUND2_SUPPORT) 5461 if (soc_feature(unit, soc_feature_global_meter) && 5462 SOC_IS_GREYHOUND2(unit)) { 5463 rv = _bcm_esw_get_policer_from_table(unit, mem, 0, return_ent, 5464 ¤t_policer, 1); 5465 BCM_IF_ERROR_RETURN(rv); 5466 5467 /* decrement current policer ref count - if any */ 5468 rv = _bcm_esw_policer_validate(unit, ¤t_policer); 5469 if (BCM_SUCCESS(rv)) { 5470 rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer); 5471 BCM_IF_ERROR_RETURN(rv); 5472 } 5473 5474 value = soc_mem_field32_get(unit, mem, vent, SVC_METER_OFFSET_MODEf); 5475 soc_mem_field32_set(unit, mem, return_ent, 5476 SVC_METER_OFFSET_MODEf, value); 5477 value = soc_mem_field32_get(unit, mem, vent, SVC_METER_INDEXf); 5478 soc_mem_field32_set(unit, mem, return_ent, SVC_METER_INDEXf, value); 5479 } 5480 #endif /* BCM_GREYHOUND2_SUPPORT */ 5481 5482 #if defined(BCM_GREYHOUND2_SUPPORT) 5483 if (soc_feature(unit, soc_feature_global_meter) && 5484 SOC_IS_GREYHOUND2(unit)) { 5485 rv = _bcm_esw_get_policer_from_table(unit, mem, 0, return_ent, 5486 ¤t_policer, 1); 5487 BCM_IF_ERROR_RETURN(rv); 5488 5489 /* decrement current policer ref count - if any */ 5490 rv = _bcm_esw_policer_validate(unit, ¤t_policer); 5491 if (BCM_SUCCESS(rv)) { 5492 rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer); 5493 BCM_IF_ERROR_RETURN(rv); 5494 } 5495 5496 value = soc_mem_field32_get(unit, mem, vent, SVC_METER_OFFSET_MODEf); 5497 soc_mem_field32_set(unit, mem, return_ent, 5498 SVC_METER_OFFSET_MODEf, value); 5499 value = soc_mem_field32_get(unit, mem, vent, SVC_METER_INDEXf); 5500 soc_mem_field32_set(unit, mem, return_ent, SVC_METER_INDEXf, value); 5501 } 5502 #endif /* BCM_GREYHOUND2_SUPPORT */ 5503 5504 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) 5505 if (soc_feature(unit, soc_feature_global_meter) && 5506 (SOC_IS_KATANAX(unit) || (SOC_IS_APACHE(unit) 5507 && !SOC_IS_MONTEREY(unit)))) { 5508 rv = _bcm_esw_get_policer_from_table(unit, mem, 0, return_ent, 5509 ¤t_policer, 1); 5510 BCM_IF_ERROR_RETURN(rv); 5511 /* decrement current policer ref count - if any */ 5512 if ((current_policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0) { 5513 rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer); 5514 BCM_IF_ERROR_RETURN(rv); 5515 } 5516 value = soc_mem_field32_get(unit, mem, vent, SVC_METER_OFFSET_MODEf); 5517 soc_mem_field32_set(unit, mem, return_ent, 5518 SVC_METER_OFFSET_MODEf, value); 5519 value = soc_mem_field32_get(unit, mem, vent, SVC_METER_INDEXf); 5520 soc_mem_field32_set(unit, mem, return_ent, SVC_METER_INDEXf, value); 5521 } 5522 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT */ 5523 5524 #if defined(BCM_TSN_SUPPORT) 5525 #if defined(BCM_TSN_SR_SUPPORT) 5526 if (soc_feature(unit, soc_feature_tsn_sr)) { 5527 value = soc_mem_field32_get(unit, mem, vent, SR_ENABLEf); 5528 soc_mem_field32_set(unit, mem, return_ent, SR_ENABLEf, value); 5529 value = soc_mem_field32_get(unit, mem, vent, SR_LAN_ID_VALIDf); 5530 soc_mem_field32_set(unit, mem, return_ent, SR_LAN_ID_VALIDf, value); 5531 value = soc_mem_field32_get(unit, mem, vent, SR_LAN_IDf); 5532 soc_mem_field32_set(unit, mem, return_ent, SR_LAN_IDf, value); 5533 } 5534 #endif /* BCM_TSN_SR_SUPPORT*/ 5535 if (soc_feature(unit, soc_feature_tsn_taf) && 5536 SOC_MEM_FIELD_VALID(unit, mem, TAF_GATE_ID_PROFILEf)) { 5537 value = soc_mem_field32_get(unit, mem, vent, TAF_GATE_ID_PROFILEf); 5538 soc_mem_field32_set(unit, mem, return_ent, TAF_GATE_ID_PROFILEf, value); 5539 } 5540 #endif /* BCM_TSN_SUPPORT */ 5541 return BCM_E_NONE; 5542 } 5543 5544 #if defined(BCM_TRIUMPH3_SUPPORT) 5545 STATIC int 5546 _bcm_tr3_vxlate_extd_action_entry_update(int unit, 5547 vlan_xlate_entry_t *vent_in, /* update entry */ 5548 void *ctxt, 5549 vlan_xlate_entry_t *vent_out, /* entry read from mem */ 5550 vlan_xlate_extd_entry_t *vxent_out, /* entry read from mem or 5551 converted from vent_out if not null */ 5552 int *use_extd_tbl) 5553 { 5554 vlan_xlate_entry_t vent_new; 5555 bcm_vlan_action_set_t *action; 5556 #ifdef INCLUDE_L3 5557 int intf_map_mode = 0; 5558 int min_l3_iif; 5559 int max_l3_iif; 5560 #endif 5561 5562 *use_extd_tbl = FALSE; 5563 action = (bcm_vlan_action_set_t *)ctxt; 5564 sal_memset(&vent_new, 0, sizeof(vent_new)); 5565 5566 /* if a regular entry from memory table is given, then update it */ 5567 if (vent_out) { 5568 BCM_IF_ERROR_RETURN( 5569 _bcm_trx_vlan_translate_action_entry_update (unit, 5570 vent_in, vent_out)); 5571 5572 BCM_IF_ERROR_RETURN 5573 (_bcm_tr3_vxlate2vxlate_extd(unit,vent_out,vxent_out)); 5574 } else { 5575 /* if a regular entry isn't given instead a extd entry, then 5576 * first convert to a regular entry, update it and convert back 5577 * to a extd entry. This is to utilize the existing regular entry 5578 * update function 5579 */ 5580 BCM_IF_ERROR_RETURN 5581 (_bcm_tr3_vxlate_extd2vxlate(unit,vxent_out,&vent_new,0)); 5582 BCM_IF_ERROR_RETURN( 5583 _bcm_trx_vlan_translate_action_entry_update (unit, 5584 vent_in, &vent_new)); 5585 BCM_IF_ERROR_RETURN 5586 (_bcm_tr3_vxlate2vxlate_extd(unit,&vent_new,vxent_out)); 5587 } 5588 #ifdef INCLUDE_L3 5589 max_l3_iif = BCM_XGS3_L3_ING_IF_TBL_SIZE(unit); 5590 5591 #if defined(BCM_TRIUMPH_SUPPORT) 5592 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 5593 BCM_IF_ERROR_RETURN (bcm_xgs3_l3_ingress_intf_map_get(unit, 5594 &intf_map_mode)); 5595 } 5596 #endif 5597 5598 if (intf_map_mode) { 5599 min_l3_iif = 0; 5600 } else { 5601 min_l3_iif = BCM_VLAN_MAX + 1; 5602 } 5603 5604 if ((action->ingress_if >= min_l3_iif) && 5605 (action->ingress_if < max_l3_iif)) { 5606 *use_extd_tbl = TRUE; 5607 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out, 5608 XLATE__MPLS_ACTIONf, 0x2); /* L3_IIF */ 5609 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out, XLATE__L3_IIFf, 5610 action->ingress_if); 5611 } 5612 #endif /* INCLUDE_L3 */ 5613 5614 if (SOC_IS_TRIUMPH3(unit) && action->policer_id) { 5615 BCM_IF_ERROR_RETURN( 5616 _bcm_esw_add_policer_to_table(unit, action->policer_id, 5617 VLAN_XLATE_EXTDm, 0, vxent_out)); 5618 *use_extd_tbl = TRUE; 5619 } 5620 return BCM_E_NONE; 5621 } 5622 5623 /* 5624 * Function: 5625 * _bcm_tr3_vlan_translate_action_entry_set 5626 * Purpose: 5627 * Set Vlan Translate Entry 5628 * Parameters: 5629 * IN : Unit 5630 * IN : vlan_xlate_entry 5631 * Returns: 5632 * BCM_E_XXX 5633 */ 5634 5635 STATIC int 5636 _bcm_tr3_vlan_translate_action_entry_set(int unit, vlan_xlate_entry_t *vent, 5637 bcm_vlan_action_set_t *action) 5638 { 5639 5640 BCM_IF_ERROR_RETURN( 5641 _bcm_tr3_vxlate_entry_add(unit, vent,(void *)action, 5642 _bcm_tr3_vxlate_extd_action_entry_update, NULL)); 5643 return BCM_E_NONE; 5644 } 5645 #endif /* BCM_TRIUMPH3_SUPPORT */ 5646 5647 /* 5648 * Function: 5649 * _bcm_trx_vlan_translate_action_entry_set 5650 * Purpose: 5651 * Set Vlan Translate Entry 5652 * Parameters: 5653 * IN : Unit 5654 * IN : vlan_xlate_entry 5655 * Returns: 5656 * BCM_E_XXX 5657 */ 5658 5659 STATIC int 5660 _bcm_trx_vlan_translate_action_entry_set(int unit, void *vent) 5661 { 5662 vlan_xlate_entry_t return_vxent; 5663 vlan_xlate_1_double_entry_t return_vx1dent; 5664 int rv = BCM_E_UNAVAIL; 5665 int index; 5666 uint32 old_profile_idx = 0; 5667 soc_mem_t mem = VLAN_XLATEm; 5668 void *return_ent = &return_vxent; 5669 5670 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 5671 mem = VLAN_XLATE_1_DOUBLEm; 5672 return_ent = &return_vx1dent; 5673 } 5674 5675 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 5676 vent, return_ent, 0); 5677 5678 if (rv == SOC_E_NONE) { 5679 /* Keep the old vlan translate profile index */ 5680 old_profile_idx = soc_mem_field32_get(unit, mem, return_ent, 5681 TAG_ACTION_PROFILE_PTRf); 5682 BCM_IF_ERROR_RETURN( 5683 _bcm_trx_vlan_translate_action_entry_update (unit, 5684 vent, return_ent)); 5685 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, return_ent); 5686 5687 /* Delete the old vlan translate profile entry */ 5688 if ((rv == SOC_E_NONE) && 5689 (old_profile_idx != ing_action_profile_def[unit])) { 5690 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx); 5691 5692 if (BCM_FAILURE(rv)) { 5693 /* ignore if the non-used hardware default value */ 5694 if ((!old_profile_idx) && (rv == SOC_E_PARAM || 5695 rv == SOC_E_NOT_FOUND)) { 5696 rv = BCM_E_NONE; 5697 } else { 5698 BCM_IF_ERROR_RETURN(rv); 5699 } 5700 } 5701 } 5702 } else if (rv != SOC_E_NOT_FOUND) { 5703 return rv; 5704 } else { 5705 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent); 5706 } 5707 5708 return rv; 5709 } 5710 5711 5712 /* 5713 * Function : 5714 * _bcm_trx_vif_vlan_translate_action_add 5715 * Description : 5716 * Add an entry to ingress VLAN translation table. 5717 * Parameters : 5718 * unit (IN) BCM unit number 5719 * port (IN) Ingress generic port 5720 * key_type (IN) Key Type : bcmVlanTranslateKey* 5721 * outer_vlan (IN) Packet outer VLAN ID 5722 * inner_vlan (IN) Packet inner VLAN ID 5723 * action (IN) Action for outer and inner tag 5724 */ 5725 STATIC int 5726 _bcm_trx_vif_vlan_translate_action_add(int unit, 5727 bcm_gport_t port, 5728 bcm_vlan_translate_key_t key_type, 5729 bcm_vlan_t outer_vlan, 5730 bcm_vlan_t inner_vlan, 5731 bcm_vlan_action_set_t *action) 5732 { 5733 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 5734 if (soc_feature(unit, soc_feature_niv)) { 5735 uint32 profile_idx; 5736 int rv = BCM_E_NONE; 5737 int search_rv; 5738 vlan_xlate_entry_t vx_ent; 5739 vlan_xlate_entry_t search_vx_ent; 5740 vlan_xlate_1_double_entry_t vx1d_ent; 5741 vlan_xlate_1_double_entry_t search_vx1d_ent; 5742 int key_type_value; 5743 int old_profile_idx = 0; 5744 int index; 5745 5746 soc_mem_t mem = VLAN_XLATEm; 5747 soc_field_t vf = VALIDf; 5748 void *vent = &vx_ent; 5749 void *search_vent = &search_vx_ent; 5750 uint32 ent_sz = sizeof(vlan_xlate_entry_t); 5751 5752 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 5753 mem = VLAN_XLATE_1_DOUBLEm; 5754 vf = BASE_VALID_0f; /* TD3TBD */ 5755 vent = &vx1d_ent; 5756 search_vent= &search_vx1d_ent; 5757 ent_sz = sizeof(vlan_xlate_1_double_entry_t); 5758 } 5759 5760 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 5761 5762 sal_memset(vent, 0, ent_sz); 5763 BCM_IF_ERROR_RETURN(_bcm_trx_vif_vlan_translate_entry_assemble(unit, 5764 vent, port, key_type, inner_vlan, outer_vlan)); 5765 5766 sal_memcpy(search_vent, vent, ent_sz); 5767 5768 /* NIV port vxlate key type */ 5769 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_xlate_key_type_value_get(unit, 5770 VLXLT_HASH_KEY_TYPE_VIF, &key_type_value)); 5771 soc_mem_field32_set(unit, mem, search_vent, KEY_TYPEf, 5772 key_type_value); 5773 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 5774 soc_mem_field32_set(unit, mem, search_vent, DATA_TYPEf, key_type_value); 5775 } 5776 soc_mem_field32_set(unit, mem, search_vent, VIF__VLANf, 0); 5777 5778 search_rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 5779 search_vent, vent, 0); 5780 5781 /* an entry should already exist */ 5782 if (search_rv != SOC_E_NONE) { 5783 return search_rv; 5784 } 5785 5786 /* re-initialize the key */ 5787 BCM_IF_ERROR_RETURN(_bcm_trx_vif_vlan_translate_entry_assemble(unit, 5788 vent, port, key_type, inner_vlan, outer_vlan)); 5789 sal_memcpy(search_vent, vent, ent_sz); 5790 search_rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 5791 search_vent, vent, 0); 5792 5793 if (!(search_rv == SOC_E_NONE || search_rv == SOC_E_NOT_FOUND)) { 5794 return search_rv; 5795 } 5796 if (search_rv == SOC_E_NONE) { 5797 old_profile_idx = soc_mem_field32_get(unit, mem, vent, 5798 VIF__TAG_ACTION_PROFILE_PTRf); 5799 } 5800 5801 /* update or fill in the vlan xlate entry*/ 5802 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_add(unit, 5803 action, &profile_idx)); 5804 soc_mem_field32_set(unit, mem, vent, VIF__TAG_ACTION_PROFILE_PTRf, 5805 profile_idx); 5806 if (SOC_MEM_FIELD_VALID(unit, mem, VIF__VLAN_ACTION_VALIDf)) { 5807 soc_mem_field32_set(unit, mem, vent, VIF__VLAN_ACTION_VALIDf, 1); 5808 } 5809 5810 soc_mem_field32_set(unit, mem, vent, VIF__NEW_IVIDf, 5811 action->new_inner_vlan); 5812 soc_mem_field32_set(unit, mem, vent, VIF__NEW_OVIDf, 5813 action->new_outer_vlan); 5814 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 5815 if (action->priority >= BCM_PRIO_MIN && 5816 action->priority <= BCM_PRIO_MAX) { 5817 soc_mem_field32_set(unit, mem, vent, VIF__NEW_OPRIf, 5818 action->priority); 5819 } 5820 soc_mem_field32_set(unit, mem, vent, VIF__NEW_OCFIf, 5821 action->new_outer_cfi); 5822 soc_mem_field32_set(unit, mem, vent, VIF__NEW_IPRIf, 5823 action->new_inner_pkt_prio); 5824 soc_mem_field32_set(unit, mem, vent, VIF__NEW_ICFIf, 5825 action->new_inner_cfi); 5826 } 5827 if (mem == VLAN_XLATEm) { 5828 soc_mem_field32_set(unit, mem, vent, vf, 1); 5829 } else { 5830 soc_mem_field32_set(unit, mem, vent, vf, 3); 5831 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 5832 } 5833 5834 /* Program L3_IIF */ 5835 if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, VIF__L3_IIF_VALIDf)) { 5836 int intf_map_mode = 0; 5837 int min_l3_iif; 5838 int max_l3_iif; 5839 max_l3_iif = BCM_XGS3_L3_ING_IF_TBL_SIZE(unit) - 1; 5840 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 5841 BCM_IF_ERROR_RETURN( 5842 bcm_xgs3_l3_ingress_intf_map_get(unit, &intf_map_mode)); 5843 } 5844 5845 if (intf_map_mode) { 5846 if (soc_feature(unit, soc_feature_l3_iif_zero_invalid)){ 5847 min_l3_iif = 1; 5848 } else { 5849 min_l3_iif = 0; 5850 } 5851 } else { 5852 min_l3_iif = BCM_VLAN_MAX + 1; 5853 } 5854 if ((action->ingress_if >= min_l3_iif) && 5855 (action->ingress_if <= max_l3_iif)) { 5856 soc_mem_field32_set(unit, mem, vent, VIF__L3_IIF_VALIDf, 1); 5857 soc_mem_field32_set(unit, mem, vent, VIF__L3_IIFf, 5858 action->ingress_if); 5859 } 5860 } 5861 5862 if (search_rv == SOC_E_NONE) { 5863 /* overrides existing one */ 5864 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, vent); 5865 } else { /* case search_rv == SOC_E_NOT_FOUND */ 5866 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent); 5867 } 5868 5869 if (BCM_FAILURE(rv)) { 5870 /* Delete the allocated vlan translate profile entry */ 5871 profile_idx = soc_mem_field32_get(unit, mem, vent, 5872 VIF__TAG_ACTION_PROFILE_PTRf); 5873 (void) _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 5874 } else { 5875 /* delete t the old profile entry */ 5876 if ((search_rv == SOC_E_NONE) && 5877 (old_profile_idx != ing_action_profile_def[unit])) { 5878 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, 5879 old_profile_idx); 5880 } 5881 } 5882 return rv; 5883 } 5884 #endif /* defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) */ 5885 return BCM_E_UNAVAIL; 5886 5887 } 5888 5889 5890 /* 5891 * Function : 5892 * _bcm_trx_lltag_vlan_translate_action_add 5893 * Description : 5894 * Add an entry to ingress VLAN translation table for LLTAG based VLAN port. 5895 * Parameters : 5896 * unit (IN) BCM unit number 5897 * port (IN) Ingress generic port 5898 * key_type (IN) Key Type : bcmVlanTranslateKey* 5899 * outer_vlan (IN) Packet outer VLAN ID 5900 * inner_vlan (IN) Packet inner VLAN ID 5901 * action (IN) Action for outer and inner tag 5902 */ 5903 int 5904 _bcm_trx_lltag_vlan_translate_action_add(int unit, 5905 bcm_gport_t port, 5906 bcm_vlan_translate_key_t key_type, 5907 bcm_vlan_t outer_vlan, 5908 bcm_vlan_t inner_vlan, 5909 bcm_vlan_action_set_t *action) 5910 { 5911 uint32 profile_idx; 5912 int rv; 5913 vlan_xlate_entry_t vx_ent; 5914 vlan_xlate_1_double_entry_t vx1d_ent; 5915 ing_dvp_table_entry_t dvp_entry; 5916 egr_l3_next_hop_entry_t egr_nh; 5917 uint16 llvid, other_vlan; 5918 int vp, nh_index; 5919 soc_mem_t mem = VLAN_XLATEm; 5920 soc_field_t vf = VALIDf; 5921 void *vent = &vx_ent; 5922 uint32 ent_sz = sizeof(vlan_xlate_entry_t); 5923 5924 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 5925 mem = VLAN_XLATE_1_DOUBLEm; 5926 vf = BASE_VALID_0f; /* TD3TBD */ 5927 vent = &vx1d_ent; 5928 ent_sz = sizeof(vlan_xlate_1_double_entry_t); 5929 } 5930 5931 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 5932 5933 if (!BCM_GPORT_IS_VLAN_PORT(port)) { 5934 return BCM_E_PARAM; 5935 } 5936 5937 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 5938 5939 if (vp >= soc_mem_index_count(unit, SOURCE_VPm)) { 5940 return BCM_E_PARAM; 5941 } 5942 5943 /* For existing vlan vp, NH entry already exists */ 5944 BCM_IF_ERROR_RETURN 5945 (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 5946 5947 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, 5948 NEXT_HOP_INDEXf); 5949 5950 BCM_IF_ERROR_RETURN 5951 (READ_EGR_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, &egr_nh)); 5952 5953 llvid = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 5954 SD_TAG__LLTAG_VIDf); 5955 5956 sal_memset(vent, 0, ent_sz); 5957 5958 switch (key_type) { 5959 case bcmVlanTranslateKeyPortPonTunnel: 5960 other_vlan = 0; 5961 break; 5962 case bcmVlanTranslateKeyPortPonTunnelOuter: 5963 other_vlan = outer_vlan; 5964 break; 5965 case bcmVlanTranslateKeyPortPonTunnelInner: 5966 other_vlan = inner_vlan; 5967 break; 5968 default: 5969 return BCM_E_PARAM; 5970 break; 5971 } 5972 5973 BCM_IF_ERROR_RETURN( 5974 _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 5975 llvid, other_vlan)); 5976 5977 BCM_IF_ERROR_RETURN 5978 (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx)); 5979 soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf, profile_idx); 5980 if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, VLAN_ACTION_VALIDf)) { 5981 soc_mem_field32_set(unit, mem, vent, VLAN_ACTION_VALIDf, 1); 5982 } 5983 5984 soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, action->new_inner_vlan); 5985 soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, action->new_outer_vlan); 5986 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 5987 if (action->priority >= BCM_PRIO_MIN && 5988 action->priority <= BCM_PRIO_MAX) { 5989 soc_mem_field32_set(unit, mem, vent, NEW_OPRIf, action->priority); 5990 } 5991 soc_mem_field32_set(unit, mem, vent, NEW_OCFIf, action->new_outer_cfi); 5992 soc_mem_field32_set(unit, mem, vent, NEW_IPRIf, action->new_inner_pkt_prio); 5993 soc_mem_field32_set(unit, mem, vent, NEW_ICFIf, action->new_inner_cfi); 5994 } else { 5995 if (action->priority >= BCM_PRIO_MIN && 5996 action->priority <= BCM_PRIO_MAX) { 5997 soc_mem_field32_set(unit, mem, vent, RPEf, 1); 5998 soc_mem_field32_set(unit, mem, vent, PRIf, action->priority); 5999 } 6000 } 6001 6002 if (mem == VLAN_XLATEm) { 6003 soc_mem_field32_set(unit, mem, vent, vf, 1); 6004 } else { 6005 soc_mem_field32_set(unit, mem, vent, vf, 3); 6006 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 6007 } 6008 6009 #ifdef INCLUDE_L3 6010 if (SOC_IS_TR_VL(unit) && (!SOC_IS_HURRICANEX(unit))) { 6011 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6012 if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf) && 6013 (action->class_id)) { 6014 soc_mem_field32_set(unit, mem, vent, CLASS_IDf, action->class_id); 6015 } else 6016 #endif 6017 if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) { 6018 int intf_map_mode = 0; 6019 int min_l3_iif; 6020 int max_l3_iif; 6021 6022 max_l3_iif = BCM_XGS3_L3_ING_IF_TBL_SIZE(unit); 6023 #if defined(BCM_TRIUMPH_SUPPORT) 6024 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 6025 BCM_IF_ERROR_RETURN (bcm_xgs3_l3_ingress_intf_map_get(unit, 6026 &intf_map_mode)); 6027 } 6028 #endif 6029 6030 if (intf_map_mode) { 6031 min_l3_iif = 0; 6032 } else { 6033 min_l3_iif = BCM_VLAN_MAX + 1; 6034 } 6035 6036 if ((action->ingress_if >= min_l3_iif) && 6037 (action->ingress_if < max_l3_iif)) { 6038 /* L3_IIF */ 6039 soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x2); 6040 soc_mem_field32_set(unit, mem, vent, L3_IIFf, action->ingress_if); 6041 } 6042 } 6043 } 6044 #endif /* INCLUDE_L3 */ 6045 6046 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) 6047 if (SOC_IS_KATANAX(unit)) { 6048 rv = _bcm_esw_add_policer_to_table(unit, action->policer_id, 6049 mem, 0, vent); 6050 BCM_IF_ERROR_RETURN(rv); 6051 } 6052 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT */ 6053 rv = _bcm_trx_vlan_translate_action_entry_set(unit, vent); 6054 6055 if (BCM_FAILURE(rv)) { 6056 /* Delete the old vlan translate profile entry */ 6057 profile_idx = soc_mem_field32_get(unit, mem, vent, 6058 TAG_ACTION_PROFILE_PTRf); 6059 (void) _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 6060 } 6061 6062 return rv; 6063 } 6064 6065 /* 6066 * Function : 6067 * _bcm_trx_vlan_translate_action_add 6068 * Description : 6069 * Add an entry to ingress VLAN translation table. 6070 * Parameters : 6071 * unit (IN) BCM unit number 6072 * port (IN) Ingress generic port 6073 * key_type (IN) Key Type : bcmVlanTranslateKey* 6074 * outer_vlan (IN) Packet outer VLAN ID 6075 * inner_vlan (IN) Packet inner VLAN ID 6076 * action (IN) Action for outer and inner tag 6077 */ 6078 int 6079 _bcm_trx_vlan_translate_action_add(int unit, 6080 bcm_gport_t port, 6081 bcm_vlan_translate_key_t key_type, 6082 bcm_vlan_t outer_vlan, 6083 bcm_vlan_t inner_vlan, 6084 bcm_vlan_action_set_t *action) 6085 { 6086 uint32 profile_idx; 6087 int rv, vp = 0; 6088 vlan_xlate_entry_t vx_ent; 6089 vlan_xlate_1_double_entry_t vx1d_ent; 6090 uint16 llvid = 0; 6091 soc_mem_t mem = VLAN_XLATEm; 6092 soc_field_t vf = VALIDf; 6093 void *vent = &vx_ent; 6094 uint32 ent_sz = sizeof(vlan_xlate_entry_t); 6095 6096 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 6097 mem = VLAN_XLATE_1_DOUBLEm; 6098 vf = BASE_VALID_0f; /* TD3TBD */ 6099 vent = &vx1d_ent; 6100 ent_sz = sizeof(vlan_xlate_1_double_entry_t); 6101 } 6102 6103 if ((key_type == bcmVlanTranslateKeyPortPonTunnel || 6104 key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 6105 key_type == bcmVlanTranslateKeyPortPonTunnelInner) && 6106 !soc_feature(unit, soc_feature_lltag)) { 6107 return BCM_E_UNAVAIL; 6108 } 6109 6110 #if defined(BCM_TRIDENT2_SUPPORT) 6111 if ((!soc_feature(unit, soc_feature_vlan_xlate_iif_with_dummy_vp) || 6112 !soc_property_get(unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0)) && 6113 (action->flags & BCM_VLAN_ACTION_SET_DUMMY_VP)) { 6114 return BCM_E_UNAVAIL; 6115 } 6116 #endif /* BCM_TRIDENT2_SUPPORT */ 6117 6118 /* process the NIV type of gport */ 6119 if (BCM_GPORT_IS_NIV_PORT(port)) { 6120 int rv; 6121 rv = _bcm_trx_vif_vlan_translate_action_add(unit, 6122 port,key_type,outer_vlan,inner_vlan,action); 6123 return rv; 6124 } else if (BCM_GPORT_IS_VLAN_PORT(port)) { 6125 if (key_type == bcmVlanTranslateKeyPortPonTunnel || 6126 key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 6127 key_type == bcmVlanTranslateKeyPortPonTunnelInner) { 6128 ing_dvp_table_entry_t dvp_entry; 6129 egr_l3_next_hop_entry_t egr_nh; 6130 int nh_index; 6131 6132 if (!soc_feature(unit, soc_feature_lltag)) { 6133 return BCM_E_UNAVAIL; 6134 } 6135 6136 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 6137 /* For existing vlan vp, NH entry already exists */ 6138 BCM_IF_ERROR_RETURN 6139 (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 6140 6141 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, 6142 NEXT_HOP_INDEXf); 6143 6144 BCM_IF_ERROR_RETURN 6145 (READ_EGR_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, &egr_nh)); 6146 6147 llvid = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 6148 SD_TAG__LLTAG_VIDf); 6149 } 6150 } 6151 6152 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 6153 6154 sal_memset(vent, 0, ent_sz); 6155 switch (key_type) { 6156 case bcmVlanTranslateKeyPortPonTunnel: 6157 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 6158 llvid, 0); 6159 break; 6160 case bcmVlanTranslateKeyPortPonTunnelOuter: 6161 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 6162 llvid, outer_vlan); 6163 break; 6164 case bcmVlanTranslateKeyPortPonTunnelInner: 6165 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 6166 llvid, inner_vlan); 6167 break; 6168 default: 6169 rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, port, key_type, 6170 inner_vlan, outer_vlan); 6171 break; 6172 } 6173 6174 BCM_IF_ERROR_RETURN(rv); 6175 6176 if (key_type == bcmVlanTranslateKeyPortPonTunnel || 6177 key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 6178 key_type == bcmVlanTranslateKeyPortPonTunnelInner) { 6179 soc_mem_field32_set(unit, mem, vent, LLTAG__SOURCE_VPf, vp); 6180 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 6181 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 6182 } 6183 if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) { 6184 soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 1); 6185 } 6186 } 6187 BCM_IF_ERROR_RETURN 6188 (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx)); 6189 soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf, 6190 profile_idx); 6191 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_ACTION_VALIDf)) { 6192 soc_mem_field32_set(unit, mem, vent, VLAN_ACTION_VALIDf, 1); 6193 } 6194 6195 if (SOC_MEM_FIELD_VALID(unit, mem, DISABLE_VLAN_CHECKSf)) { 6196 if (action->flags & BCM_VLAN_ACTION_SET_VLAN_CHECKS_DISABLE) { 6197 soc_mem_field32_set(unit, mem, vent, DISABLE_VLAN_CHECKSf, 1); 6198 } 6199 } 6200 #if defined(BCM_TSN_SR_SUPPORT) 6201 if (soc_feature(unit, soc_feature_tsn_sr)) { 6202 if ((!(action->flags & BCM_VLAN_ACTION_SET_SR_ENABLE)) && 6203 (action->flags & BCM_VLAN_ACTION_SET_SR_LAN_ID)) { 6204 return BCM_E_PARAM; 6205 } 6206 6207 if (action->flags & BCM_VLAN_ACTION_SET_SR_ENABLE) { 6208 soc_mem_field32_set(unit, mem, vent, SR_ENABLEf, 1); 6209 soc_mem_field32_set(unit, mem, vent, SR_LAN_ID_VALIDf, 1); 6210 if (action->flags & BCM_VLAN_ACTION_SET_SR_LAN_ID) { 6211 soc_mem_field32_set(unit, mem, vent, SR_LAN_IDf, 1); 6212 } 6213 } 6214 } 6215 #endif /* BCM_TSN_SR_SUPPORT*/ 6216 6217 #if defined(BCM_TSN_SUPPORT) 6218 if (soc_feature(unit, soc_feature_tsn_taf) && 6219 SOC_MEM_FIELD_VALID(unit, mem, TAF_GATE_ID_PROFILEf)) { 6220 uint32 hw_index; 6221 6222 if (BCM_TSN_PRI_MAP_INVALID != action->taf_gate_primap) { 6223 bcm_tsn_pri_map_type_t map; 6224 6225 BCM_IF_ERROR_RETURN( 6226 bcmi_esw_tsn_pri_map_hw_index_get(unit, action->taf_gate_primap, 6227 &map, &hw_index)); 6228 6229 if (map != bcmTsnPriMapTypeTafGate) { 6230 return BCM_E_PARAM; 6231 } 6232 } else { 6233 hw_index = 0; 6234 } 6235 soc_mem_field32_set(unit, mem, vent, 6236 TAF_GATE_ID_PROFILEf, hw_index); 6237 } 6238 #endif /* BCM_TSN_SUPPORT */ 6239 6240 soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, action->new_inner_vlan); 6241 soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, action->new_outer_vlan); 6242 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 6243 if (action->priority >= BCM_PRIO_MIN && 6244 action->priority <= BCM_PRIO_MAX) { 6245 soc_mem_field32_set(unit, mem, vent, NEW_OPRIf, action->priority); 6246 } 6247 soc_mem_field32_set(unit, mem, vent, NEW_OCFIf, action->new_outer_cfi); 6248 soc_mem_field32_set(unit, mem, vent, NEW_IPRIf, 6249 action->new_inner_pkt_prio); 6250 soc_mem_field32_set(unit, mem, vent, NEW_ICFIf, action->new_inner_cfi); 6251 } else { 6252 if (action->priority >= BCM_PRIO_MIN && 6253 action->priority <= BCM_PRIO_MAX) { 6254 soc_mem_field32_set(unit, mem, vent, RPEf, 1); 6255 soc_mem_field32_set(unit, mem, vent, PRIf, action->priority); 6256 } 6257 } 6258 if (mem == VLAN_XLATEm) { 6259 soc_mem_field32_set(unit, mem, vent, vf, 1); 6260 } else { 6261 soc_mem_field32_set(unit, mem, vent, vf, 3); 6262 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 6263 } 6264 6265 #if defined(BCM_TRIUMPH3_SUPPORT) 6266 if (SOC_IS_TRIUMPH3(unit)) { 6267 rv = _bcm_tr3_vlan_translate_action_entry_set(unit, vent, action); 6268 if (BCM_FAILURE(rv)) { 6269 /* Delete the old vlan translate profile entry */ 6270 profile_idx = soc_mem_field32_get(unit, mem, vent, 6271 TAG_ACTION_PROFILE_PTRf); 6272 (void) _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 6273 } 6274 } else 6275 #endif /* BCM_TRIUMPH3_SUPPORT */ 6276 { 6277 #ifdef INCLUDE_L3 6278 if (SOC_IS_TR_VL(unit) && 6279 (!SOC_IS_HURRICANE(unit) || !SOC_IS_HURRICANE2(unit))) { 6280 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6281 if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf) && action->class_id) { 6282 soc_mem_field32_set( 6283 unit, mem, vent, CLASS_IDf, action->class_id); 6284 } else 6285 #endif 6286 if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) { 6287 int intf_map_mode = 0; 6288 int min_l3_iif; /* the minimum valid l3_iif index */ 6289 int max_l3_iif; /* the maximum valid l3_iif index */ 6290 6291 max_l3_iif = BCM_XGS3_L3_ING_IF_TBL_SIZE(unit) - 1; 6292 #if defined(BCM_TRIUMPH_SUPPORT) 6293 if (soc_feature(unit, soc_feature_l3_ingress_interface)) { 6294 BCM_IF_ERROR_RETURN ( 6295 bcm_xgs3_l3_ingress_intf_map_get(unit, &intf_map_mode)); 6296 } 6297 #endif 6298 6299 if (intf_map_mode) { 6300 if (soc_feature(unit, soc_feature_l3_iif_zero_invalid)){ 6301 min_l3_iif = 1; 6302 } else { 6303 min_l3_iif = 0; 6304 } 6305 } else { 6306 min_l3_iif = BCM_VLAN_MAX + 1; 6307 } 6308 6309 if ((action->ingress_if >= min_l3_iif) && 6310 (action->ingress_if <= max_l3_iif)) { 6311 /* L3_IIF */ 6312 #if defined(BCM_TRIDENT2_SUPPORT) 6313 if ((action->flags & BCM_VLAN_ACTION_SET_DUMMY_VP) && 6314 soc_feature(unit, 6315 soc_feature_vlan_xlate_iif_with_dummy_vp) && 6316 soc_property_get( 6317 unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0)) { 6318 soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x3); 6319 soc_mem_field32_set(unit, mem, vent, L3_IIFf, 6320 action->ingress_if); 6321 soc_mem_field32_set(unit, mem, vent, SOURCE_VPf, 6322 _BCM_VLAN_XLATE_DUMMY_PORT); 6323 } else 6324 #endif /* BCM_TRIDENT2_SUPPORT */ 6325 { 6326 soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x2); 6327 soc_mem_field32_set(unit, mem, vent, L3_IIFf, 6328 action->ingress_if); 6329 } 6330 } 6331 } 6332 } 6333 #endif /* INCLUDE_L3 */ 6334 6335 #if defined(BCM_GREYHOUND2_SUPPORT) 6336 if (soc_feature(unit, soc_feature_global_meter) && 6337 SOC_IS_GREYHOUND2(unit)) { 6338 rv = _bcm_esw_policer_validate(unit, &action->policer_id); 6339 if (BCM_SUCCESS(rv)) { 6340 rv = _bcm_esw_add_policer_to_table( 6341 unit, action->policer_id, 6342 mem, 0, vent); 6343 BCM_IF_ERROR_RETURN(rv); 6344 } 6345 } 6346 #endif /* BCM_GREYHOUND2_SUPPORT */ 6347 6348 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) 6349 if (soc_feature(unit, soc_feature_global_meter) && 6350 (SOC_IS_KATANAX(unit) || SOC_IS_APACHE(unit))) { 6351 rv = _bcm_esw_add_policer_to_table(unit, action->policer_id, 6352 mem, 0, vent); 6353 BCM_IF_ERROR_RETURN(rv); 6354 } 6355 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT */ 6356 rv = _bcm_trx_vlan_translate_action_entry_set(unit, vent); 6357 6358 if (BCM_FAILURE(rv)) { 6359 /* Delete the old vlan translate profile entry */ 6360 profile_idx = soc_mem_field32_get(unit, mem, vent, 6361 TAG_ACTION_PROFILE_PTRf); 6362 (void) _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 6363 } 6364 } 6365 return rv; 6366 } 6367 6368 /* 6369 * Function: 6370 * _bcm_trx_vlan_translate_get 6371 * Purpose: 6372 * Gets a vlan translate entry. 6373 * Parameters: 6374 * unit (IN) BCM unit number 6375 * port (IN) Ingress generic port 6376 * key_type (IN) Key Type : bcmVlanTranslateKey* 6377 * old_vlan (IN) Packet old VLAN ID 6378 * new_vlan (OUT) Packet new VLAN ID 6379 * prio (OUT) Packet prio 6380 */ 6381 int 6382 _bcm_trx_vlan_translate_action_get (int unit, 6383 bcm_gport_t port, 6384 bcm_vlan_translate_key_t key_type, 6385 bcm_vlan_t outer_vid, 6386 bcm_vlan_t inner_vid, 6387 bcm_vlan_action_set_t *action) 6388 { 6389 vlan_xlate_entry_t vx_ent, res_vx_ent; 6390 vlan_xlate_1_double_entry_t vx1d_ent, res_vx1d_ent; 6391 int rv; 6392 int idx = 0; 6393 uint32 profile_idx = 0; 6394 uint16 llvid = 0; 6395 6396 soc_mem_t mem = VLAN_XLATEm; 6397 void *vent = &vx_ent; 6398 void *res_vent = &res_vx_ent; 6399 uint32 ent_sz = sizeof(vlan_xlate_entry_t); 6400 6401 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 6402 mem = VLAN_XLATE_1_DOUBLEm; 6403 vent = &vx1d_ent; 6404 res_vent = &res_vx1d_ent; 6405 ent_sz = sizeof(vlan_xlate_1_double_entry_t); 6406 } 6407 6408 if ((key_type == bcmVlanTranslateKeyPortPonTunnel || 6409 key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 6410 key_type == bcmVlanTranslateKeyPortPonTunnelInner) && 6411 !soc_feature(unit, soc_feature_lltag)) { 6412 return BCM_E_PARAM; 6413 } 6414 6415 sal_memset(vent, 0, ent_sz); 6416 sal_memset(res_vent, 0, ent_sz); 6417 if (BCM_GPORT_IS_NIV_PORT(port)) { 6418 BCM_IF_ERROR_RETURN( 6419 _bcm_trx_vif_vlan_translate_entry_assemble(unit, vent, port, 6420 key_type,inner_vid, outer_vid)); 6421 6422 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, 6423 vent, res_vent, 0); 6424 BCM_IF_ERROR_RETURN(rv); 6425 profile_idx = soc_mem_field32_get(unit, mem, res_vent, 6426 VIF__TAG_ACTION_PROFILE_PTRf); 6427 _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 6428 return _bcm_trx_vif_vlan_translate_entry_parse(unit, mem, 6429 (uint32 *)res_vent, action); 6430 } else if (BCM_GPORT_IS_VLAN_PORT(port)) { 6431 if (key_type == bcmVlanTranslateKeyPortPonTunnel || 6432 key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 6433 key_type == bcmVlanTranslateKeyPortPonTunnelInner) { 6434 ing_dvp_table_entry_t dvp_entry; 6435 egr_l3_next_hop_entry_t egr_nh; 6436 int vp, nh_index; 6437 6438 if (!soc_feature(unit, soc_feature_lltag)) { 6439 return BCM_E_UNAVAIL; 6440 } 6441 6442 vp = BCM_GPORT_VLAN_PORT_ID_GET(port);; 6443 /* For existing vlan vp, NH entry already exists */ 6444 BCM_IF_ERROR_RETURN 6445 (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 6446 6447 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, 6448 NEXT_HOP_INDEXf); 6449 6450 BCM_IF_ERROR_RETURN 6451 (READ_EGR_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, &egr_nh)); 6452 6453 llvid = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 6454 SD_TAG__LLTAG_VIDf); 6455 } 6456 } 6457 6458 switch (key_type) { 6459 case bcmVlanTranslateKeyPortPonTunnel: 6460 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 6461 llvid, 0); 6462 break; 6463 case bcmVlanTranslateKeyPortPonTunnelOuter: 6464 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 6465 llvid, outer_vid); 6466 break; 6467 case bcmVlanTranslateKeyPortPonTunnelInner: 6468 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 6469 llvid, inner_vid); 6470 break; 6471 default: 6472 rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, port, key_type, 6473 inner_vid, outer_vid); 6474 break; 6475 } 6476 6477 BCM_IF_ERROR_RETURN(rv); 6478 6479 soc_mem_lock(unit, mem); 6480 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, vent, res_vent, 0); 6481 soc_mem_unlock(unit, mem); 6482 6483 #if defined(BCM_TRIUMPH3_SUPPORT) 6484 if (SOC_IS_TRIUMPH3(unit)) { 6485 vlan_xlate_extd_entry_t vxent; 6486 vlan_xlate_extd_entry_t res_vxent; 6487 6488 /* check the extd table */ 6489 if (rv == SOC_E_NOT_FOUND) { 6490 BCM_IF_ERROR_RETURN 6491 (_bcm_tr3_vxlate2vxlate_extd(unit, vent, &vxent)); 6492 6493 soc_mem_lock(unit, VLAN_XLATE_EXTDm); 6494 rv = soc_mem_search(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, &idx, 6495 &vxent, &res_vxent, 0); 6496 soc_mem_unlock(unit, VLAN_XLATE_EXTDm); 6497 BCM_IF_ERROR_RETURN(rv); 6498 profile_idx = soc_VLAN_XLATE_EXTDm_field32_get(unit, &res_vxent, 6499 TAG_ACTION_PROFILE_PTRf); 6500 _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 6501 6502 return _bcm_trx_vlan_translate_entry_parse(unit, VLAN_XLATE_EXTDm, 6503 (uint32 *)&res_vxent, action); 6504 6505 } 6506 } 6507 #endif 6508 BCM_IF_ERROR_RETURN(rv); 6509 profile_idx = soc_mem_field32_get(unit, mem, res_vent, 6510 TAG_ACTION_PROFILE_PTRf); 6511 _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 6512 6513 return _bcm_trx_vlan_translate_entry_parse(unit, mem, 6514 res_vent, action); 6515 } 6516 6517 6518 /* 6519 * Function: 6520 * bcm_vlan_translate_action_delete 6521 * Purpose: 6522 * Delete a vlan translate lookup entry. 6523 * Parameters: 6524 * unit (IN) BCM unit number 6525 * port (IN) Ingress generic port 6526 * key_type (IN) Key Type : bcmVlanTranslateKey* 6527 * outer_vlan (IN) Packet outer VLAN ID 6528 * inner_vlan (IN) Packet inner VLAN ID 6529 */ 6530 int 6531 _bcm_trx_vlan_translate_action_delete(int unit, 6532 bcm_gport_t port, 6533 bcm_vlan_translate_key_t key_type, 6534 bcm_vlan_t outer_vlan, 6535 bcm_vlan_t inner_vlan) 6536 { 6537 vlan_xlate_entry_t vx_ent; 6538 vlan_xlate_1_double_entry_t vx1d_ent; 6539 uint32 profile_idx; 6540 int rv; 6541 #if defined(BCM_TRIUMPH3_SUPPORT) 6542 int rv_vxlate_delete; 6543 #endif 6544 uint16 llvid = 0; 6545 6546 soc_mem_t mem = VLAN_XLATEm; 6547 soc_field_t vf = VALIDf; 6548 void *vent = &vx_ent; 6549 uint32 ent_sz = sizeof(vx_ent); 6550 6551 #if defined(BCM_TRIUMPH2_SUPPORT) 6552 _bcm_flex_stat_handle_t handle; 6553 _BCM_FLEX_STAT_HANDLE_CLEAR(handle); 6554 #endif 6555 6556 6557 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 6558 mem = VLAN_XLATE_1_DOUBLEm; 6559 vf = BASE_VALID_0f; /* TD3TBD */ 6560 vent = &vx1d_ent; 6561 ent_sz = sizeof(vx1d_ent); 6562 } 6563 6564 if ((key_type == bcmVlanTranslateKeyPortPonTunnel || 6565 key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 6566 key_type == bcmVlanTranslateKeyPortPonTunnelInner) && 6567 !soc_feature(unit, soc_feature_lltag)) { 6568 return BCM_E_PARAM; 6569 } 6570 6571 sal_memset(vent, 0, ent_sz); 6572 6573 if (BCM_GPORT_IS_NIV_PORT(port)) { 6574 BCM_IF_ERROR_RETURN( 6575 _bcm_trx_vif_vlan_translate_entry_assemble(unit, vent, port, 6576 key_type,inner_vlan, outer_vlan)); 6577 rv = soc_mem_delete_return_old(unit, mem, MEM_BLOCK_ALL, 6578 vent, vent); 6579 if ((rv == SOC_E_NONE) && 6580 (soc_mem_field32_get(unit, mem, vent, vf) == 3) && 6581 (soc_mem_field32_get(unit, mem, vent, BASE_VALID_1f) == 7)) { 6582 profile_idx = soc_mem_field32_get(unit, mem, vent, 6583 VIF__TAG_ACTION_PROFILE_PTRf); 6584 /* Delete the old vlan action profile entry */ 6585 if (profile_idx != ing_action_profile_def[unit]) { 6586 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, 6587 profile_idx); 6588 } 6589 } 6590 return rv; 6591 } else if (BCM_GPORT_IS_VLAN_PORT(port)) { 6592 if (key_type == bcmVlanTranslateKeyPortPonTunnel || 6593 key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 6594 key_type == bcmVlanTranslateKeyPortPonTunnelInner) { 6595 ing_dvp_table_entry_t dvp_entry; 6596 egr_l3_next_hop_entry_t egr_nh; 6597 int vp, nh_index; 6598 6599 if (!soc_feature(unit, soc_feature_lltag)) { 6600 return BCM_E_UNAVAIL; 6601 } 6602 6603 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 6604 /* For existing vlan vp, NH entry already exists */ 6605 BCM_IF_ERROR_RETURN 6606 (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 6607 6608 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry, 6609 NEXT_HOP_INDEXf); 6610 6611 BCM_IF_ERROR_RETURN 6612 (READ_EGR_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, &egr_nh)); 6613 6614 llvid = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh, 6615 SD_TAG__LLTAG_VIDf); 6616 } 6617 } 6618 6619 switch (key_type) { 6620 case bcmVlanTranslateKeyPortPonTunnel: 6621 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 6622 llvid, 0); 6623 break; 6624 case bcmVlanTranslateKeyPortPonTunnelOuter: 6625 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 6626 llvid, outer_vlan); 6627 break; 6628 case bcmVlanTranslateKeyPortPonTunnelInner: 6629 rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type, 6630 llvid, inner_vlan); 6631 break; 6632 default: 6633 rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, port, key_type, 6634 inner_vlan, outer_vlan); 6635 break; 6636 } 6637 6638 BCM_IF_ERROR_RETURN(rv); 6639 6640 6641 #if defined(BCM_TRIUMPH2_SUPPORT) 6642 if (soc_feature(unit, soc_feature_gport_service_counters)) { 6643 /* Record flex stat info before the returned entry 6644 * includes non-key info. */ 6645 6646 /* _BCM_FLEX_STAT_HANDLE_COPY(handle, vent); */ 6647 memcpy(&handle, vent, sizeof(_bcm_flex_stat_handle_t)); 6648 } 6649 #endif 6650 6651 rv = soc_mem_delete_return_old(unit, mem, MEM_BLOCK_ALL, vent, vent); 6652 #if defined(BCM_TRIUMPH3_SUPPORT) 6653 rv_vxlate_delete = rv; 6654 #endif 6655 if ((rv == SOC_E_NONE) && soc_mem_field32_get(unit, mem, vent, vf)) { 6656 profile_idx = soc_mem_field32_get(unit, mem, vent, 6657 TAG_ACTION_PROFILE_PTRf); 6658 /* Delete the old vlan action profile entry */ 6659 if (profile_idx != ing_action_profile_def[unit]) { 6660 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 6661 } 6662 6663 #if defined(BCM_TRIUMPH2_SUPPORT) 6664 if (soc_feature(unit, soc_feature_gport_service_counters) && 6665 (0 != soc_mem_field32_get(unit, mem, vent, VINTF_CTR_IDXf))) { 6666 /* Release Service counter */ 6667 _bcm_esw_flex_stat_ext_handle_free(unit, _bcmFlexStatTypeVxlt, 6668 handle); 6669 } 6670 #endif 6671 } 6672 #if defined(BCM_GREYHOUND2_SUPPORT) 6673 if (soc_feature(unit, soc_feature_global_meter) && 6674 SOC_IS_GREYHOUND2(unit)) { 6675 bcm_policer_t current_policer_id; 6676 int policer_rv = 0; 6677 policer_rv = _bcm_esw_get_policer_from_table(unit, VLAN_XLATEm, 0, vent, 6678 ¤t_policer_id, 1); 6679 BCM_IF_ERROR_RETURN(policer_rv); 6680 policer_rv = _bcm_esw_policer_validate(unit, ¤t_policer_id); 6681 if (BCM_SUCCESS(policer_rv)) { 6682 policer_rv = _bcm_esw_policer_decrement_ref_count( 6683 unit, current_policer_id); 6684 BCM_IF_ERROR_RETURN(policer_rv); 6685 } 6686 } 6687 #endif /* BCM_GREYHOUND2_SUPPORT */ 6688 6689 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) 6690 if (soc_feature(unit, soc_feature_global_meter) && 6691 (SOC_IS_KATANAX(unit) || SOC_IS_APACHE(unit))) { 6692 bcm_policer_t current_policer; 6693 int policer_rv = 0; 6694 policer_rv = _bcm_esw_get_policer_from_table(unit, VLAN_XLATEm, 0, vent, 6695 ¤t_policer, 1); 6696 if (current_policer != 0) { 6697 if ((current_policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0) { 6698 policer_rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer); 6699 BCM_IF_ERROR_RETURN(policer_rv); 6700 } 6701 } 6702 } 6703 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT */ 6704 6705 #if defined(BCM_TRIUMPH3_SUPPORT) 6706 if (SOC_IS_TRIUMPH3(unit)) { 6707 vlan_xlate_extd_entry_t vxent; 6708 6709 /* check the extend table */ 6710 sal_memset(&vxent, 0, sizeof(vxent)); 6711 BCM_IF_ERROR_RETURN 6712 (_bcm_tr3_vxlate2vxlate_extd(unit, vent, &vxent)); 6713 rv = soc_mem_delete_return_old(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 6714 &vxent, &vxent); 6715 if ((rv == SOC_E_NONE) && soc_VLAN_XLATE_EXTDm_field32_get(unit, 6716 &vxent, VALID_0f)) { 6717 profile_idx = soc_VLAN_XLATE_EXTDm_field32_get(unit, &vxent, 6718 TAG_ACTION_PROFILE_PTRf); 6719 /* Delete the old vlan action profile entry */ 6720 if (profile_idx != ing_action_profile_def[unit]) { 6721 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, 6722 profile_idx); 6723 } 6724 } else { 6725 /* if an entry is already found in regular table, then reset ret code*/ 6726 if (rv == BCM_E_NOT_FOUND) { 6727 if (rv_vxlate_delete == BCM_E_NONE) { 6728 rv = BCM_E_NONE; 6729 } 6730 } 6731 } 6732 } 6733 #endif 6734 6735 return rv; 6736 } 6737 6738 #if defined(BCM_TRIUMPH3_SUPPORT) 6739 /* 6740 * Function: 6741 * _bcm_tr3_vxlate_action_delete_extd_tbl 6742 * Purpose: 6743 * Delete all vlan translate lookup entries. 6744 * Parameters: 6745 * unit (IN) BCM unit number 6746 * Returns: 6747 * BCM_E_XXX 6748 */ 6749 STATIC int 6750 _bcm_tr3_vxlate_action_delete_extd_tbl(int unit) 6751 { 6752 int i, imin, imax, nent, vbytes, rv, mpls; 6753 vlan_xlate_extd_entry_t * vtab, * vnull, *vtabp; 6754 6755 imin = soc_mem_index_min(unit, VLAN_XLATE_EXTDm); 6756 imax = soc_mem_index_max(unit, VLAN_XLATE_EXTDm); 6757 nent = soc_mem_index_count(unit, VLAN_XLATE_EXTDm); 6758 vbytes = soc_mem_entry_words(unit, VLAN_XLATE_EXTDm); 6759 vbytes = WORDS2BYTES(vbytes); 6760 vtab = soc_cm_salloc(unit, nent * sizeof(*vtab), "vlan_xlate_extd"); 6761 6762 if (vtab == NULL) { 6763 return BCM_E_MEMORY; 6764 } 6765 6766 vnull = soc_mem_entry_null(unit, VLAN_XLATE_EXTDm); 6767 6768 soc_mem_lock(unit, VLAN_XLATE_EXTDm); 6769 rv = soc_mem_read_range(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ANY, 6770 imin, imax, vtab); 6771 if (rv < 0) { 6772 soc_mem_unlock(unit, VLAN_XLATE_EXTDm); 6773 soc_cm_sfree(unit, vtab); 6774 return rv; 6775 } 6776 6777 for(i = 0; i < nent; i++) { 6778 vtabp = soc_mem_table_idx_to_pointer(unit, VLAN_XLATE_EXTDm, 6779 vlan_xlate_extd_entry_t *, vtab, i); 6780 6781 mpls = soc_VLAN_XLATE_EXTDm_field32_get(unit, vtabp, 6782 XLATE__MPLS_ACTIONf); 6783 6784 if (!soc_VLAN_XLATE_EXTDm_field32_get(unit, vtabp, VALID_0f) || 6785 (mpls != 0)) { 6786 continue; 6787 } 6788 6789 rv = WRITE_VLAN_XLATE_EXTDm(unit, MEM_BLOCK_ANY, i, vnull); 6790 } 6791 6792 soc_mem_unlock(unit, VLAN_XLATE_EXTDm); 6793 soc_cm_sfree(unit, vtab); 6794 return rv; 6795 } 6796 #endif /*BCM_TRIUMPH3_SUPPORT */ 6797 6798 /* 6799 * Function: 6800 * _bcm_trx_vlan_translate_action_delete_all 6801 * Purpose: 6802 * Delete all vlan translate lookup entries. 6803 * Parameters: 6804 * unit (IN) BCM unit number 6805 * Returns: 6806 * BCM_E_XXX 6807 */ 6808 int 6809 _bcm_trx_vlan_translate_action_delete_all(int unit) 6810 { 6811 int i, imin, imax, nent, vbytes, rv, mpls; 6812 uint32 old_profile_idx; 6813 void * vtab, * vnull, *vtabp; 6814 int vx_key_type; 6815 int vx_key_value; 6816 #if defined(BCM_TRIUMPH2_SUPPORT) 6817 _bcm_flex_stat_handle_t handle; 6818 vlan_xlate_entry_t vent; 6819 uint32 key[2]; 6820 #endif 6821 soc_mem_t mem = VLAN_XLATEm; 6822 soc_field_t vf = VALIDf; 6823 uint32 ent_sz = sizeof(vlan_xlate_entry_t); 6824 6825 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 6826 mem = VLAN_XLATE_1_DOUBLEm; 6827 vf = BASE_VALID_0f; /* TD3TBD */ 6828 ent_sz = sizeof(vlan_xlate_1_double_entry_t); 6829 } 6830 6831 imin = soc_mem_index_min(unit, mem); 6832 imax = soc_mem_index_max(unit, mem); 6833 nent = soc_mem_index_count(unit, mem); 6834 vbytes = soc_mem_entry_words(unit, mem); 6835 vbytes = WORDS2BYTES(vbytes); 6836 vtab = soc_cm_salloc(unit, nent * ent_sz, "vlan_xlate"); 6837 6838 if (vtab == NULL) { 6839 return BCM_E_MEMORY; 6840 } 6841 6842 vnull = soc_mem_entry_null(unit, mem); 6843 6844 soc_mem_lock(unit, mem); 6845 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 6846 imin, imax, vtab); 6847 if (rv < 0) { 6848 soc_mem_unlock(unit, mem); 6849 soc_cm_sfree(unit, vtab); 6850 return rv; 6851 } 6852 6853 for(i = 0; i < nent; i++) { 6854 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 6855 vtabp = soc_mem_table_idx_to_pointer(unit, mem, 6856 vlan_xlate_1_double_entry_t *, vtab, i); 6857 } else { 6858 vtabp = soc_mem_table_idx_to_pointer(unit, mem, 6859 vlan_xlate_entry_t *, vtab, i); 6860 } 6861 6862 #if defined(BCM_TRIUMPH3_SUPPORT) 6863 if (SOC_IS_TRIUMPH3(unit)) { 6864 mpls = 0; 6865 } else 6866 #endif 6867 { 6868 if (SOC_IS_TR_VL(unit) && (!(SOC_IS_HURRICANE(unit) || 6869 SOC_IS_HURRICANE2(unit))) && 6870 SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) { 6871 mpls = soc_mem_field32_get(unit, mem, vtabp, MPLS_ACTIONf); 6872 } else { 6873 mpls = 0; 6874 } 6875 } 6876 6877 vx_key_value = soc_mem_field32_get(unit, mem, vtabp, KEY_TYPEf); 6878 rv = _bcm_esw_vlan_xlate_key_type_get(unit,vx_key_value,&vx_key_type); 6879 if (rv != BCM_E_NONE) { 6880 /* not valid key type, must be for extend entry */ 6881 continue; 6882 } 6883 6884 if (!soc_mem_field32_get(unit, mem, vtabp, vf) || 6885 (mpls != 0) || 6886 (vx_key_type == VLXLT_HASH_KEY_TYPE_VLAN_MAC) || 6887 (vx_key_type == VLXLT_HASH_KEY_TYPE_LLVID) || 6888 (vx_key_type == VLXLT_HASH_KEY_TYPE_LLVID_OVID) || 6889 (vx_key_type == VLXLT_HASK_KEY_TYPE_LLVID_IVID)) { 6890 continue; 6891 } 6892 6893 old_profile_idx = soc_mem_field32_get(unit, mem, vtabp, 6894 TAG_ACTION_PROFILE_PTRf); 6895 6896 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, i, vnull); 6897 6898 if ((rv >= 0) && (old_profile_idx != ing_action_profile_def[unit])) { 6899 /* Delete the old vlan action profile entry */ 6900 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx); 6901 } 6902 6903 #if defined(BCM_TRIUMPH2_SUPPORT) 6904 if (soc_feature(unit, soc_feature_gport_service_counters) && 6905 (0 != soc_mem_field32_get(unit, mem, vtabp, VINTF_CTR_IDXf))) { 6906 sal_memset(&vent, 0, sizeof(vent)); 6907 /* Construct key-only entry, copy to FS handle */ 6908 soc_mem_field32_set(unit, mem, &vent, KEY_TYPEf, 6909 soc_mem_field32_get(unit, mem, vtabp, KEY_TYPEf)); 6910 soc_mem_field_get(unit, mem, (uint32 *) vtabp, 6911 KEYf, (uint32 *) key); 6912 soc_mem_field_set(unit, mem, (uint32 *) &vent, 6913 KEYf, (uint32 *) key); 6914 6915 _BCM_FLEX_STAT_HANDLE_CLEAR(handle); 6916 _BCM_FLEX_STAT_HANDLE_COPY(handle, vent); 6917 6918 /* Release Service counter */ 6919 _bcm_esw_flex_stat_ext_handle_free(unit, _bcmFlexStatTypeVxlt, 6920 handle); 6921 } 6922 #endif 6923 } 6924 6925 soc_mem_unlock(unit, mem); 6926 soc_cm_sfree(unit, vtab); 6927 6928 #if defined(BCM_TRIUMPH3_SUPPORT) 6929 if (SOC_IS_TRIUMPH3(unit)) { 6930 BCM_IF_ERROR_RETURN 6931 (_bcm_tr3_vxlate_action_delete_extd_tbl(unit)); 6932 } 6933 #endif 6934 return rv; 6935 } 6936 6937 /* 6938 * Function : 6939 * _bcm_trx_vlan_translate_action_range_add 6940 * Description : 6941 * Add a range of VLANs and an entry to ingress VLAN translation table. 6942 * Parameters : 6943 * unit (IN) BCM unit number 6944 * port (IN) Ingress generic port 6945 * outer_vlan_low (IN) Packet outer VLAN ID low 6946 * outer_vlan_high (IN) Packet outer VLAN ID high 6947 * inner_vlan_low (IN) Packet inner VLAN ID low 6948 * inner_vlan_high (IN) Packet inner VLAN ID high 6949 * action (IN) Action for outer and inner tag 6950 */ 6951 int 6952 _bcm_trx_vlan_translate_action_range_add(int unit, 6953 bcm_gport_t port, 6954 bcm_vlan_t outer_vlan_low, 6955 bcm_vlan_t outer_vlan_high, 6956 bcm_vlan_t inner_vlan_low, 6957 bcm_vlan_t inner_vlan_high, 6958 bcm_vlan_action_set_t *action) 6959 { 6960 int i, key_type = 0, rv, gport_id, old_idx = 0, stm_idx = 0; 6961 uint32 new_idx = 0; 6962 source_trunk_map_table_entry_t stm_entry; 6963 bcm_module_t mod_out; 6964 bcm_port_t port_out; 6965 bcm_trunk_t trunk_id, tid; 6966 bcm_vlan_t min_vlan[8], max_vlan[8]; 6967 bcm_vlan_t min_inner_vlan[8], max_inner_vlan[8]; 6968 int port_count; 6969 bcm_trunk_member_t *member_array = NULL; 6970 bcm_module_t *mod_array = NULL; 6971 bcm_port_t *port_array = NULL; 6972 int trunk128; 6973 soc_field_t field; 6974 int old_inner_idx = 0; 6975 uint32 new_inner_idx = 0; 6976 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3) 6977 int pon_tunnel = FALSE; 6978 int nh_index, vp; 6979 ing_l3_next_hop_entry_t ing_nh; 6980 ing_dvp_table_entry_t dvp; 6981 #endif 6982 6983 if ((outer_vlan_low != BCM_VLAN_INVALID) && 6984 (inner_vlan_low != BCM_VLAN_INVALID)) { 6985 if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) { 6986 key_type = bcmVlanTranslateKeyPortDouble; 6987 VLAN_CHK_ID(unit, inner_vlan_low); 6988 VLAN_CHK_ID(unit, inner_vlan_high); 6989 VLAN_CHK_ID(unit, outer_vlan_low); 6990 VLAN_CHK_ID(unit, outer_vlan_high); 6991 } else { 6992 /* For an incoming double tagged packet, hardware currently supports 6993 * VLAN range matching for outer VLAN ID only, not for inner VLAN ID 6994 * Hence, outer VLAN range and inner VLAN range cannot be specified 6995 * simultaneously. 6996 */ 6997 return BCM_E_PARAM; 6998 } 6999 } else if (outer_vlan_low != BCM_VLAN_INVALID) { 7000 key_type = bcmVlanTranslateKeyPortOuter; 7001 VLAN_CHK_ID(unit, outer_vlan_low); 7002 VLAN_CHK_ID(unit, outer_vlan_high); 7003 } else if (inner_vlan_low != BCM_VLAN_INVALID) { 7004 key_type = bcmVlanTranslateKeyPortInner; 7005 VLAN_CHK_ID(unit, inner_vlan_low); 7006 VLAN_CHK_ID(unit, inner_vlan_high); 7007 } else { 7008 return BCM_E_PARAM; 7009 } 7010 7011 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3) 7012 if (soc_feature(unit, soc_feature_lltag)) { 7013 if (BCM_GPORT_IS_VLAN_PORT(port)) { 7014 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 7015 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 7016 return BCM_E_NOT_FOUND; 7017 } 7018 BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, 7019 vp, &dvp)); 7020 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 7021 NEXT_HOP_INDEXf); 7022 BCM_IF_ERROR_RETURN (READ_ING_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, 7023 nh_index, &ing_nh)); 7024 7025 if ((soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, ENTRY_TYPEf) 7026 == 0x3)) { 7027 pon_tunnel = TRUE; 7028 } 7029 } 7030 } 7031 7032 if (pon_tunnel == TRUE) { 7033 if (inner_vlan_low != BCM_VLAN_INVALID) { 7034 key_type = bcmVlanTranslateKeyPortPonTunnelInner; 7035 VLAN_CHK_ID(unit, inner_vlan_low); 7036 VLAN_CHK_ID(unit, inner_vlan_high); 7037 } else if (outer_vlan_low != BCM_VLAN_INVALID) { 7038 key_type = bcmVlanTranslateKeyPortPonTunnelOuter; 7039 VLAN_CHK_ID(unit, outer_vlan_low); 7040 VLAN_CHK_ID(unit, outer_vlan_high); 7041 } 7042 } 7043 #endif 7044 7045 BCM_IF_ERROR_RETURN( 7046 _bcm_trx_vlan_action_verify(unit, action)); 7047 7048 BCM_IF_ERROR_RETURN 7049 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id, 7050 &gport_id)); 7051 7052 if (BCM_GPORT_IS_TRUNK(port)) { 7053 if (BCM_TRUNK_INVALID == trunk_id) { 7054 return BCM_E_PORT; 7055 } 7056 7057 BCM_IF_ERROR_RETURN 7058 (bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, 7059 &port_count)); 7060 7061 if (port_count <= 0) { 7062 return BCM_E_PORT; 7063 } 7064 7065 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 7066 "trunk member array"); 7067 if (member_array == NULL) { 7068 rv = BCM_E_MEMORY; 7069 goto cleanup; 7070 } 7071 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 7072 7073 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 7074 member_array, &port_count); 7075 if (BCM_FAILURE(rv)) { 7076 goto cleanup; 7077 } 7078 7079 mod_array = sal_alloc(sizeof(bcm_module_t) * port_count, 7080 "module ID array"); 7081 if (mod_array == NULL) { 7082 rv = BCM_E_MEMORY; 7083 goto cleanup; 7084 } 7085 sal_memset(mod_array, 0, sizeof(bcm_module_t) * port_count); 7086 7087 port_array = sal_alloc(sizeof(bcm_port_t) * port_count, 7088 "port ID array"); 7089 if (port_array == NULL) { 7090 rv = BCM_E_MEMORY; 7091 goto cleanup; 7092 } 7093 sal_memset(port_array, 0, sizeof(bcm_port_t) * port_count); 7094 7095 for (i = 0; i < port_count; i++) { 7096 rv = _bcm_esw_gport_resolve(unit, member_array[i].gport, 7097 &mod_array[i], &port_array[i], &tid, &gport_id); 7098 if (BCM_FAILURE(rv)) { 7099 goto cleanup; 7100 } 7101 } 7102 } else { 7103 if ((-1 == mod_out) || (-1 == port_out)) { 7104 return BCM_E_PORT; 7105 } 7106 7107 port_count = 1; 7108 7109 mod_array = sal_alloc(sizeof(bcm_module_t) * port_count, 7110 "module ID array"); 7111 if (mod_array == NULL) { 7112 rv = BCM_E_MEMORY; 7113 goto cleanup; 7114 } 7115 mod_array[0] = mod_out; 7116 7117 port_array = sal_alloc(sizeof(bcm_port_t) * port_count, 7118 "port ID array"); 7119 if (port_array == NULL) { 7120 rv = BCM_E_MEMORY; 7121 goto cleanup; 7122 } 7123 port_array[0] = port_out; 7124 } 7125 7126 rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[0], 7127 port_array[0], &stm_idx); 7128 if (BCM_FAILURE(rv)) { 7129 goto cleanup; 7130 } 7131 7132 soc_mem_lock(unit, ING_VLAN_RANGEm); 7133 7134 rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry); 7135 if (rv < 0) { 7136 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7137 goto cleanup; 7138 } 7139 7140 /* For devices supporting vlan double tag range compression 7141 * and if inner_vlan_low is valid 7142 */ 7143 if (inner_vlan_low != BCM_VLAN_INVALID) { 7144 if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) { 7145 field = INNER_VLAN_RANGE_IDXf; 7146 } else { 7147 field = VLAN_RANGE_IDXf; 7148 } 7149 old_inner_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 7150 &stm_entry, field); 7151 7152 /* Get the profile table entry for this port/trunk */ 7153 _bcm_trx_vlan_range_profile_entry_get(unit, 7154 min_inner_vlan, max_inner_vlan, old_inner_idx); 7155 7156 /* Find the first unused min/max range. Unused ranges are 7157 * identified by { min == 1, max == 0 } 7158 */ 7159 for (i = 0 ; i < 8 ; i++) { 7160 if ((min_inner_vlan[i] == 1) && (max_inner_vlan[i] == 0)) { 7161 break; 7162 } else if (min_inner_vlan[i] == inner_vlan_low) { 7163 /* Can't have multiple ranges with the same min */ 7164 rv = BCM_E_EXISTS; 7165 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7166 goto cleanup; 7167 } 7168 } 7169 if (i == 8) { 7170 /* All ranges are taken */ 7171 rv = BCM_E_FULL; 7172 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7173 goto cleanup; 7174 } 7175 7176 /* Insert the new range into the table entry sorted by min VID */ 7177 for ( ; i > 0 ; i--) { 7178 if (min_inner_vlan[i - 1] > inner_vlan_low) { 7179 /* Move existing min/max down */ 7180 min_inner_vlan[i] = min_inner_vlan[i - 1]; 7181 max_inner_vlan[i] = max_inner_vlan[i - 1]; 7182 } else { 7183 break; 7184 } 7185 } 7186 min_inner_vlan[i] = inner_vlan_low; 7187 max_inner_vlan[i] = inner_vlan_high; 7188 7189 /* Adding the new profile table entry and update profile pointer */ 7190 for (i = 0; i < port_count; i++) { 7191 rv = _bcm_trx_vlan_range_profile_entry_add(unit, 7192 min_inner_vlan, max_inner_vlan, &new_inner_idx); 7193 if (BCM_FAILURE(rv)) { 7194 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7195 goto cleanup; 7196 } 7197 rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[i], 7198 port_array[i], &stm_idx); 7199 if (BCM_SUCCESS(rv)) { 7200 rv = soc_mem_field32_modify(unit, 7201 SOURCE_TRUNK_MAP_TABLEm, stm_idx, field, new_inner_idx); 7202 } 7203 if (BCM_FAILURE(rv)) { 7204 _bcm_trx_vlan_range_profile_entry_delete(unit, new_inner_idx); 7205 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7206 goto cleanup; 7207 } 7208 } 7209 } 7210 7211 /* For devices supporting vlan double tag range compression 7212 * and entry is for outer tag or double tag vlan range compression 7213 * OR 7214 * Other devices not supporting double tag range compression feature 7215 */ 7216 if (outer_vlan_low != BCM_VLAN_INVALID) { 7217 field = VLAN_RANGE_IDXf; 7218 if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) { 7219 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 7220 OUTER_VLAN_RANGE_IDXf)) { 7221 field = OUTER_VLAN_RANGE_IDXf; 7222 } 7223 } 7224 7225 old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 7226 &stm_entry, field); 7227 7228 /* Get the profile table entry for this port/trunk */ 7229 _bcm_trx_vlan_range_profile_entry_get(unit, 7230 min_vlan, max_vlan, old_idx); 7231 7232 /* Find the first unused min/max range. Unused ranges are 7233 * identified by { min == 1, max == 0 } 7234 */ 7235 for (i = 0 ; i < 8 ; i++) { 7236 if ((min_vlan[i] == 1) && (max_vlan[i] == 0)) { 7237 break; 7238 } else if (min_vlan[i] == outer_vlan_low) { 7239 /* Can't have multiple ranges with the same min */ 7240 rv = BCM_E_EXISTS; 7241 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7242 goto cleanup; 7243 } 7244 } 7245 if (i == 8) { 7246 /* All ranges are taken */ 7247 rv = BCM_E_FULL; 7248 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7249 goto cleanup; 7250 } 7251 7252 /* Insert the new range into the table entry sorted by min VID */ 7253 for ( ; i > 0 ; i--) { 7254 if (min_vlan[i - 1] > outer_vlan_low) { 7255 /* Move existing min/max down */ 7256 min_vlan[i] = min_vlan[i - 1]; 7257 max_vlan[i] = max_vlan[i - 1]; 7258 } else { 7259 break; 7260 } 7261 } 7262 min_vlan[i] = outer_vlan_low; 7263 max_vlan[i] = outer_vlan_high; 7264 7265 /* Adding the new profile table entry and update profile pointer */ 7266 for (i = 0; i < port_count; i++) { 7267 rv = _bcm_trx_vlan_range_profile_entry_add(unit, min_vlan, max_vlan, 7268 &new_idx); 7269 if (BCM_FAILURE(rv)) { 7270 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7271 goto cleanup; 7272 } 7273 rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[i], 7274 port_array[i], &stm_idx); 7275 if (BCM_SUCCESS(rv)) { 7276 rv = soc_mem_field32_modify(unit, 7277 SOURCE_TRUNK_MAP_TABLEm, stm_idx, field, new_idx); 7278 } 7279 if (BCM_FAILURE(rv)) { 7280 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 7281 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7282 goto cleanup; 7283 } 7284 } 7285 } 7286 7287 /* Add an entry in the vlan translate table for the low VID */ 7288 rv = _bcm_trx_vlan_translate_action_add(unit, port, key_type, 7289 outer_vlan_low, inner_vlan_low, 7290 action); 7291 if (rv != BCM_E_NONE) { 7292 for (i = 0; i < port_count; i++) { 7293 if (outer_vlan_low != BCM_VLAN_INVALID) { 7294 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 7295 } 7296 if (inner_vlan_low != BCM_VLAN_INVALID) { 7297 _bcm_trx_vlan_range_profile_entry_delete(unit, new_inner_idx); 7298 } 7299 } 7300 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7301 goto cleanup; 7302 } 7303 7304 /* Delete the old profile entry */ 7305 for (i = 0; i < port_count; i++) { 7306 if (outer_vlan_low != BCM_VLAN_INVALID) { 7307 rv = _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx); 7308 if (BCM_FAILURE(rv)) { 7309 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7310 goto cleanup; 7311 } 7312 } 7313 if (inner_vlan_low != BCM_VLAN_INVALID) { 7314 rv = _bcm_trx_vlan_range_profile_entry_delete(unit, old_inner_idx); 7315 if (BCM_FAILURE(rv)) { 7316 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7317 goto cleanup; 7318 } 7319 } 7320 } 7321 7322 if (BCM_GPORT_IS_TRUNK(port)) { 7323 if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) { 7324 trunk128 = soc_property_get(unit, spn_TRUNK_EXTEND, 1); 7325 if (!trunk128) { 7326 rv = _bcm_trx_vlan_range_profile_entry_add(unit, 7327 min_vlan, max_vlan, &new_idx); 7328 if (BCM_FAILURE(rv)) { 7329 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7330 goto cleanup; 7331 } 7332 rv = soc_mem_field32_modify(unit, 7333 TRUNK32_PORT_TABLEm, trunk_id, 7334 VLAN_RANGE_IDXf, new_idx); 7335 if (BCM_FAILURE(rv)) { 7336 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 7337 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7338 goto cleanup; 7339 } 7340 if (outer_vlan_low != BCM_VLAN_INVALID) { 7341 rv = _bcm_trx_vlan_range_profile_entry_delete(unit, 7342 old_idx); 7343 if (BCM_FAILURE(rv)) { 7344 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7345 goto cleanup; 7346 } 7347 } 7348 if (inner_vlan_low != BCM_VLAN_INVALID) { 7349 rv = _bcm_trx_vlan_range_profile_entry_delete(unit, 7350 old_inner_idx); 7351 if (BCM_FAILURE(rv)) { 7352 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7353 goto cleanup; 7354 } 7355 } 7356 } 7357 } 7358 } 7359 7360 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7361 7362 cleanup: 7363 if (NULL != member_array) { 7364 sal_free(member_array); 7365 } 7366 if (NULL != mod_array) { 7367 sal_free(mod_array); 7368 } 7369 if (NULL != port_array) { 7370 sal_free(port_array); 7371 } 7372 7373 return rv; 7374 } 7375 7376 /* 7377 * Function : 7378 * _bcm_trx_vlan_range_profile_index_get 7379 * Description : 7380 * Get the index for profile entry in the ING_VLAN_RANGE memory. 7381 * Parameters : 7382 * unit (IN) BCM unit number 7383 * gport (IN) Ingress generic port 7384 * profile_idx (OUT) index to profile entry 7385 */ 7386 int 7387 _bcm_trx_vlan_range_profile_index_get(int unit, bcm_gport_t gport, 7388 int *profile_idx) 7389 { 7390 int idx = 0, gport_id = 0; 7391 bcm_port_t port_out; 7392 bcm_module_t mod_out; 7393 bcm_trunk_t trunk_id; 7394 int stm_idx; /* Source Trunk Map index */ 7395 source_trunk_map_table_entry_t stm_entry; 7396 bcm_trunk_member_t trunk_member; 7397 int port_count; 7398 7399 BCM_IF_ERROR_RETURN 7400 (_bcm_esw_gport_resolve(unit, gport, &mod_out, &port_out, &trunk_id, 7401 &gport_id)); 7402 7403 if (BCM_GPORT_IS_TRUNK(gport)) { 7404 if (BCM_TRUNK_INVALID == trunk_id) { 7405 return BCM_E_PORT; 7406 } 7407 7408 BCM_IF_ERROR_RETURN 7409 (bcm_esw_trunk_get(unit, trunk_id, NULL, 1, &trunk_member, 7410 &port_count)); 7411 BCM_IF_ERROR_RETURN 7412 (_bcm_esw_gport_resolve(unit, trunk_member.gport, 7413 &mod_out, &port_out, &trunk_id, &gport_id)); 7414 } else { 7415 if ((-1 == mod_out) || (-1 == port_out)) { 7416 return BCM_E_PORT; 7417 } 7418 } 7419 7420 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, mod_out, 7421 port_out, &stm_idx)); 7422 7423 BCM_IF_ERROR_RETURN( 7424 READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry)); 7425 7426 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 7427 OUTER_VLAN_RANGE_IDXf)) { 7428 idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 7429 &stm_entry, OUTER_VLAN_RANGE_IDXf); 7430 } else { 7431 idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 7432 &stm_entry, VLAN_RANGE_IDXf); 7433 } 7434 *profile_idx = idx; 7435 return BCM_E_NONE; 7436 } 7437 7438 /* 7439 * Function : 7440 * _bcm_trx_vlan_range_profile_inner_index_get 7441 * Description : 7442 * Get the inner index for profile entry in the ING_VLAN_RANGE memory. 7443 * Parameters : 7444 * unit (IN) BCM unit number 7445 * gport (IN) Ingress generic port 7446 * profile_idx (OUT) inner vlan range index to profile entry 7447 */ 7448 int 7449 _bcm_trx_vlan_range_profile_inner_index_get(int unit, bcm_gport_t gport, 7450 int *profile_idx) 7451 { 7452 int idx = 0, gport_id = 0; 7453 bcm_port_t port_out; 7454 bcm_module_t mod_out; 7455 bcm_trunk_t trunk_id; 7456 int stm_idx; /* Source Trunk Map index */ 7457 source_trunk_map_table_entry_t stm_entry; 7458 bcm_trunk_info_t tinfo; 7459 bcm_trunk_member_t trunk_member; 7460 int port_count; 7461 7462 BCM_IF_ERROR_RETURN 7463 (_bcm_esw_gport_resolve(unit, gport, &mod_out, &port_out, &trunk_id, 7464 &gport_id)); 7465 7466 if (BCM_GPORT_IS_TRUNK(gport)) { 7467 if (BCM_TRUNK_INVALID == trunk_id) { 7468 return BCM_E_PORT; 7469 } 7470 BCM_IF_ERROR_RETURN(bcm_esw_trunk_get(unit, trunk_id, &tinfo, 1, 7471 &trunk_member, &port_count)); 7472 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, trunk_member.gport, 7473 &mod_out, &port_out, &trunk_id, &gport_id)); 7474 } else { 7475 if ((-1 == mod_out) || (-1 == port_out)) { 7476 return BCM_E_PORT; 7477 } 7478 } 7479 7480 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, mod_out, 7481 port_out, &stm_idx)); 7482 7483 BCM_IF_ERROR_RETURN( 7484 READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry)); 7485 7486 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 7487 INNER_VLAN_RANGE_IDXf)) { 7488 idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 7489 &stm_entry, INNER_VLAN_RANGE_IDXf); 7490 *profile_idx = idx; 7491 } 7492 return BCM_E_NONE; 7493 } 7494 7495 /* 7496 * Function : 7497 * _bcm_trx_vlan_translate_action_range_get 7498 * Description : 7499 * Get a range of VLANs and an entry to ingress VLAN translation table. 7500 * for Triumph 7501 * Parameters : 7502 * unit (IN) BCM unit number 7503 * port (IN) Ingress generic port 7504 * outer_vlan_low (IN) Packet outer VLAN ID low 7505 * outer_vlan_high (IN) Packet outer VLAN ID high 7506 * inner_vlan_low (IN) Packet inner VLAN ID low 7507 * inner_vlan_high (IN) Packet inner VLAN ID high 7508 * action (OUT) Action for outer and inner tag 7509 */ 7510 int 7511 _bcm_trx_vlan_translate_action_range_get(int unit, 7512 bcm_gport_t port, 7513 bcm_vlan_t outer_vlan_low, 7514 bcm_vlan_t outer_vlan_high, 7515 bcm_vlan_t inner_vlan_low, 7516 bcm_vlan_t inner_vlan_high, 7517 bcm_vlan_action_set_t *action) 7518 { 7519 int key_type = 0, profile_idx, i; 7520 bcm_vlan_t min_vlan[8], max_vlan[8]; 7521 int rv; 7522 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3) 7523 int pon_tunnel = FALSE; 7524 int nh_index, vp; 7525 ing_l3_next_hop_entry_t ing_nh; 7526 ing_dvp_table_entry_t dvp; 7527 #endif 7528 7529 if ((outer_vlan_low != BCM_VLAN_INVALID) && 7530 (inner_vlan_low != BCM_VLAN_INVALID)) { 7531 if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) { 7532 key_type = bcmVlanTranslateKeyPortDouble; 7533 VLAN_CHK_ID(unit, inner_vlan_low); 7534 VLAN_CHK_ID(unit, inner_vlan_high); 7535 VLAN_CHK_ID(unit, outer_vlan_low); 7536 VLAN_CHK_ID(unit, outer_vlan_high); 7537 } else { 7538 /* For an incoming double tagged packet, hardware currently supports 7539 * VLAN range matching for outer VLAN ID only, not for inner VLAN ID 7540 * Hence, outer VLAN range and inner VLAN range cannot be specified 7541 * simultaneously. 7542 */ 7543 return BCM_E_PARAM; 7544 } 7545 } else if (outer_vlan_low != BCM_VLAN_INVALID) { 7546 key_type = bcmVlanTranslateKeyPortOuter; 7547 VLAN_CHK_ID(unit, outer_vlan_low); 7548 VLAN_CHK_ID(unit, outer_vlan_high); 7549 } else if (inner_vlan_low != BCM_VLAN_INVALID) { 7550 key_type = bcmVlanTranslateKeyPortInner; 7551 VLAN_CHK_ID(unit, inner_vlan_low); 7552 VLAN_CHK_ID(unit, inner_vlan_high); 7553 } else { 7554 return BCM_E_PARAM; 7555 } 7556 7557 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3) 7558 if (soc_feature(unit, soc_feature_lltag)) { 7559 if (BCM_GPORT_IS_VLAN_PORT(port)) { 7560 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 7561 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 7562 return BCM_E_NOT_FOUND; 7563 } 7564 BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, 7565 vp, &dvp)); 7566 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 7567 NEXT_HOP_INDEXf); 7568 BCM_IF_ERROR_RETURN (READ_ING_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, 7569 nh_index, &ing_nh)); 7570 7571 if ((soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, ENTRY_TYPEf) 7572 == 0x3)) { 7573 pon_tunnel = TRUE; 7574 } 7575 } 7576 } 7577 7578 if (pon_tunnel == TRUE) { 7579 if (inner_vlan_low != BCM_VLAN_INVALID) { 7580 key_type = bcmVlanTranslateKeyPortPonTunnelInner; 7581 VLAN_CHK_ID(unit, inner_vlan_low); 7582 VLAN_CHK_ID(unit, inner_vlan_high); 7583 } else if (outer_vlan_low != BCM_VLAN_INVALID) { 7584 key_type = bcmVlanTranslateKeyPortPonTunnelOuter; 7585 VLAN_CHK_ID(unit, outer_vlan_low); 7586 VLAN_CHK_ID(unit, outer_vlan_high); 7587 } 7588 } 7589 #endif 7590 7591 /* For devices supporting vlan double tag range compression 7592 * and if inner_vlan_low is valid 7593 */ 7594 if (inner_vlan_low != BCM_VLAN_INVALID) { 7595 if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) { 7596 rv = _bcm_trx_vlan_range_profile_inner_index_get(unit, 7597 port, &profile_idx); 7598 } else { 7599 rv = _bcm_trx_vlan_range_profile_index_get(unit, port, &profile_idx); 7600 } 7601 BCM_IF_ERROR_RETURN(rv); 7602 7603 /* Get the profile table entry for this port/trunk */ 7604 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 7605 max_vlan, profile_idx); 7606 /* Find range match */ 7607 for (i = 0 ; i < 8 ; i++) { 7608 if ((min_vlan[i] == inner_vlan_low) && 7609 (max_vlan[i] == inner_vlan_high)) { 7610 break; 7611 } 7612 } 7613 if (i == 8) { 7614 return BCM_E_NOT_FOUND; 7615 } 7616 } 7617 7618 /* For devices supporting vlan double tag range compression 7619 * and entry is for outer tag or double tag range compression 7620 * OR 7621 * Other devices not supporting double tag range compression feature 7622 */ 7623 if (outer_vlan_low != BCM_VLAN_INVALID) { 7624 rv = _bcm_trx_vlan_range_profile_index_get(unit, port, &profile_idx); 7625 BCM_IF_ERROR_RETURN(rv); 7626 7627 /* Get the profile table entry for this port/trunk */ 7628 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 7629 max_vlan, profile_idx); 7630 /* Find range match */ 7631 for (i = 0 ; i < 8 ; i++) { 7632 if ((min_vlan[i] == outer_vlan_low) && 7633 (max_vlan[i] == outer_vlan_high)) { 7634 break; 7635 } 7636 } 7637 if (i == 8) { 7638 return BCM_E_NOT_FOUND; 7639 } 7640 } 7641 /* Get an entry in the vlan translate table for the low VID */ 7642 rv = _bcm_trx_vlan_translate_action_get(unit,port, key_type, 7643 outer_vlan_low, inner_vlan_low, action); 7644 if (rv == BCM_E_NOT_FOUND) { 7645 int mod_out; 7646 int port_out; 7647 int trunk_id; 7648 int gport_id; 7649 int stm_idx = 0; 7650 source_trunk_map_table_entry_t stm_entry; 7651 int port_type; 7652 soc_mem_t mem = VLAN_XLATEm; 7653 soc_field_t tgid_fld = TGIDf; 7654 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 7655 mem = VLAN_XLATE_1_DOUBLEm; 7656 } 7657 7658 /* check if the port belongs to a trunk group and whether 7659 * a xlat entry for that TGID exist 7660 */ 7661 if (SOC_MEM_FIELD_VALID(unit, mem, Tf)) { 7662 if (BCM_GPORT_IS_MODPORT(port)) { 7663 BCM_IF_ERROR_RETURN 7664 (_bcm_esw_gport_resolve(unit, port, &mod_out, 7665 &port_out, &trunk_id, &gport_id)); 7666 7667 /* Get index to source trunk map table */ 7668 BCM_IF_ERROR_RETURN 7669 (_bcm_esw_src_mod_port_table_index_get(unit, 7670 mod_out, port_out, &stm_idx)); 7671 7672 /* read the entry */ 7673 BCM_IF_ERROR_RETURN( 7674 READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 7675 stm_idx, &stm_entry)); 7676 7677 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 7678 SRC_TGIDf)) { 7679 tgid_fld = SRC_TGIDf; 7680 } 7681 7682 trunk_id = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 7683 &stm_entry, tgid_fld); 7684 port_type = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 7685 &stm_entry, PORT_TYPEf); 7686 7687 if (port_type == 1) { 7688 BCM_GPORT_TRUNK_SET(gport_id, trunk_id); 7689 rv = _bcm_trx_vlan_translate_action_get(unit,gport_id, 7690 key_type,outer_vlan_low, inner_vlan_low, action); 7691 } 7692 } 7693 } 7694 } 7695 return (rv); 7696 } 7697 7698 /* 7699 * Function : 7700 * _bcm_trx_vlan_translate_action_range_delete 7701 * Description : 7702 * Delete a range of VLANs and an entry from ingress VLAN translation table 7703 * Parameters : 7704 * unit (IN) BCM unit number 7705 * port (IN) Ingress generic port 7706 * outer_vlan_low (IN) Packet outer VLAN ID low 7707 * outer_vlan_high (IN) Packet outer VLAN ID high 7708 * inner_vlan_low (IN) Packet inner VLAN ID low 7709 * inner_vlan_high (IN) Packet inner VLAN ID high 7710 */ 7711 int 7712 _bcm_trx_vlan_translate_action_range_delete(int unit, 7713 bcm_gport_t port, 7714 bcm_vlan_t outer_vlan_low, 7715 bcm_vlan_t outer_vlan_high, 7716 bcm_vlan_t inner_vlan_low, 7717 bcm_vlan_t inner_vlan_high) 7718 { 7719 int i, key_type = 0, rv, gport_id, old_idx = 0, stm_idx = 0; 7720 uint32 new_idx = 0; 7721 source_trunk_map_table_entry_t stm_entry; 7722 bcm_module_t mod_out; 7723 bcm_port_t port_out; 7724 bcm_trunk_t trunk_id, tid; 7725 bcm_vlan_t min_vlan[8], max_vlan[8]; 7726 bcm_vlan_t min_inner_vlan[8], max_inner_vlan[8]; 7727 int port_count; 7728 bcm_trunk_member_t *member_array = NULL; 7729 bcm_module_t *mod_array = NULL; 7730 bcm_port_t *port_array = NULL; 7731 int trunk128; 7732 soc_field_t field; 7733 int old_inner_idx = 0; 7734 uint32 new_inner_idx = 0; 7735 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3) 7736 int pon_tunnel = FALSE; 7737 int nh_index, vp; 7738 ing_l3_next_hop_entry_t ing_nh; 7739 ing_dvp_table_entry_t dvp; 7740 #endif 7741 7742 if ((outer_vlan_low != BCM_VLAN_INVALID) && 7743 (inner_vlan_low != BCM_VLAN_INVALID)) { 7744 if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) { 7745 key_type = bcmVlanTranslateKeyPortDouble; 7746 VLAN_CHK_ID(unit, outer_vlan_low); 7747 VLAN_CHK_ID(unit, outer_vlan_high); 7748 VLAN_CHK_ID(unit, inner_vlan_low); 7749 VLAN_CHK_ID(unit, inner_vlan_high); 7750 } else { 7751 /* For an incoming double tagged packet, hardware currently supports 7752 * VLAN range matching for outer VLAN ID only, not for inner VLAN ID 7753 * Hence, outer VLAN range and inner VLAN range cannot be specified 7754 * simultaneously. 7755 */ 7756 return BCM_E_PARAM; 7757 } 7758 } else if (outer_vlan_low != BCM_VLAN_INVALID) { 7759 key_type = bcmVlanTranslateKeyPortOuter; 7760 VLAN_CHK_ID(unit, outer_vlan_low); 7761 VLAN_CHK_ID(unit, outer_vlan_high); 7762 } else if (inner_vlan_low != BCM_VLAN_INVALID) { 7763 key_type = bcmVlanTranslateKeyPortInner; 7764 VLAN_CHK_ID(unit, inner_vlan_low); 7765 VLAN_CHK_ID(unit, inner_vlan_high); 7766 } else { 7767 return BCM_E_PARAM; 7768 } 7769 7770 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3) 7771 if (soc_feature(unit, soc_feature_lltag)) { 7772 if (BCM_GPORT_IS_VLAN_PORT(port)) { 7773 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 7774 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 7775 return BCM_E_NOT_FOUND; 7776 } 7777 BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, 7778 vp, &dvp)); 7779 nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, 7780 NEXT_HOP_INDEXf); 7781 BCM_IF_ERROR_RETURN (READ_ING_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, 7782 nh_index, &ing_nh)); 7783 7784 if ((soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, ENTRY_TYPEf) 7785 == 0x3)) { 7786 pon_tunnel = TRUE; 7787 } 7788 } 7789 } 7790 7791 if (pon_tunnel == TRUE) { 7792 if (inner_vlan_low != BCM_VLAN_INVALID) { 7793 key_type = bcmVlanTranslateKeyPortPonTunnelInner; 7794 VLAN_CHK_ID(unit, inner_vlan_low); 7795 VLAN_CHK_ID(unit, inner_vlan_high); 7796 } else if (outer_vlan_low != BCM_VLAN_INVALID) { 7797 key_type = bcmVlanTranslateKeyPortPonTunnelOuter; 7798 VLAN_CHK_ID(unit, outer_vlan_low); 7799 VLAN_CHK_ID(unit, outer_vlan_high); 7800 } 7801 } 7802 #endif 7803 7804 BCM_IF_ERROR_RETURN 7805 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id, 7806 &gport_id)); 7807 7808 if (BCM_GPORT_IS_TRUNK(port)) { 7809 if (BCM_TRUNK_INVALID == trunk_id) { 7810 return BCM_E_PORT; 7811 } 7812 7813 BCM_IF_ERROR_RETURN 7814 (bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, &port_count)); 7815 7816 if (port_count > 0) { 7817 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 7818 "trunk member array"); 7819 if (member_array == NULL) { 7820 rv = BCM_E_MEMORY; 7821 goto cleanup; 7822 } 7823 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 7824 7825 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 7826 member_array, &port_count); 7827 if (BCM_FAILURE(rv)) { 7828 goto cleanup; 7829 } 7830 7831 mod_array = sal_alloc(sizeof(bcm_module_t) * port_count, 7832 "module ID array"); 7833 if (mod_array == NULL) { 7834 rv = BCM_E_MEMORY; 7835 goto cleanup; 7836 } 7837 sal_memset(mod_array, 0, sizeof(bcm_module_t) * port_count); 7838 7839 port_array = sal_alloc(sizeof(bcm_port_t) * port_count, 7840 "port ID array"); 7841 if (port_array == NULL) { 7842 rv = BCM_E_MEMORY; 7843 goto cleanup; 7844 } 7845 sal_memset(port_array, 0, sizeof(bcm_port_t) * port_count); 7846 } 7847 7848 for (i = 0; i < port_count; i++) { 7849 rv = _bcm_esw_gport_resolve(unit, member_array[i].gport, 7850 &mod_array[i], &port_array[i], &tid, &gport_id); 7851 if (BCM_FAILURE(rv)) { 7852 goto cleanup; 7853 } 7854 } 7855 } else { 7856 if ((-1 == mod_out) || (-1 == port_out)) { 7857 return BCM_E_PORT; 7858 } 7859 7860 port_count = 1; 7861 7862 mod_array = sal_alloc(sizeof(bcm_module_t) * port_count, 7863 "module ID array"); 7864 if (mod_array == NULL) { 7865 rv = BCM_E_MEMORY; 7866 goto cleanup; 7867 } 7868 mod_array[0] = mod_out; 7869 7870 port_array = sal_alloc(sizeof(bcm_port_t) * port_count, 7871 "port ID array"); 7872 if (port_array == NULL) { 7873 rv = BCM_E_MEMORY; 7874 goto cleanup; 7875 } 7876 port_array[0] = port_out; 7877 } 7878 7879 if (port_count > 0) { 7880 rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[0], 7881 port_array[0], &stm_idx); 7882 if (BCM_FAILURE(rv)) { 7883 goto cleanup; 7884 } 7885 7886 soc_mem_lock(unit, ING_VLAN_RANGEm); 7887 rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry); 7888 if (rv < 0) { 7889 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7890 goto cleanup; 7891 } 7892 7893 /* If vlan double tag range compression feature is supported and 7894 * entry type is for inner tag range translation */ 7895 if (inner_vlan_low != BCM_VLAN_INVALID) { 7896 if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) { 7897 field = INNER_VLAN_RANGE_IDXf; 7898 } else { 7899 field = VLAN_RANGE_IDXf; 7900 } 7901 7902 old_inner_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 7903 &stm_entry, field); 7904 7905 /* Get the profile table entry for this port/trunk */ 7906 _bcm_trx_vlan_range_profile_entry_get(unit, 7907 min_inner_vlan, max_inner_vlan, old_inner_idx); 7908 7909 /* Find the min/max range. */ 7910 for (i = 0 ; i < 8 ; i++) { 7911 if ((min_inner_vlan[i] == inner_vlan_low) && 7912 (max_inner_vlan[i] == inner_vlan_high)) { 7913 break; 7914 } 7915 } 7916 if (i == 8) { 7917 rv = BCM_E_NOT_FOUND; 7918 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7919 goto cleanup; 7920 } 7921 7922 /* Remove the range from the table entry and fill in the gap */ 7923 for ( ; i < 7 ; i++) { 7924 /* Move existing min/max UP */ 7925 min_inner_vlan[i] = min_inner_vlan[i + 1]; 7926 max_inner_vlan[i] = max_inner_vlan[i + 1]; 7927 } 7928 /* Mark last min/max range as unused. Unused ranges are 7929 * identified by { min == 1, max == 0 } 7930 */ 7931 min_inner_vlan[i] = 1; 7932 max_inner_vlan[i] = 0; 7933 7934 /* Adding the new profile table entry and update profile pointer */ 7935 for (i = 0; i < port_count; i++) { 7936 rv = _bcm_trx_vlan_range_profile_entry_add(unit, 7937 min_inner_vlan, max_inner_vlan, &new_inner_idx); 7938 if (BCM_FAILURE(rv)) { 7939 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7940 goto cleanup; 7941 } 7942 rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[i], 7943 port_array[i], &stm_idx); 7944 if (BCM_SUCCESS(rv)) { 7945 rv = soc_mem_field32_modify(unit, 7946 SOURCE_TRUNK_MAP_TABLEm, stm_idx, 7947 field, new_inner_idx); 7948 } 7949 if (BCM_FAILURE(rv)) { 7950 _bcm_trx_vlan_range_profile_entry_delete(unit, new_inner_idx); 7951 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7952 goto cleanup; 7953 } 7954 } 7955 } 7956 7957 /* If vlan double tag range compression feature is supported and 7958 * entry type is for double tag range compression */ 7959 if (outer_vlan_low != BCM_VLAN_INVALID) { 7960 field = VLAN_RANGE_IDXf; 7961 if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) { 7962 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 7963 OUTER_VLAN_RANGE_IDXf)) { 7964 field = OUTER_VLAN_RANGE_IDXf; 7965 } 7966 } 7967 7968 old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 7969 &stm_entry, field); 7970 7971 /* Get the profile table entry for this port/trunk */ 7972 _bcm_trx_vlan_range_profile_entry_get(unit, 7973 min_vlan, max_vlan, old_idx); 7974 7975 7976 /* Find the min/max range. */ 7977 for (i = 0 ; i < 8 ; i++) { 7978 if ((min_vlan[i] == outer_vlan_low) && 7979 (max_vlan[i] == outer_vlan_high)) { 7980 break; 7981 } 7982 } 7983 if (i == 8) { 7984 rv = BCM_E_NOT_FOUND; 7985 soc_mem_unlock(unit, ING_VLAN_RANGEm); 7986 goto cleanup; 7987 } 7988 7989 /* Remove the range from the table entry and fill in the gap */ 7990 for ( ; i < 7 ; i++) { 7991 /* Move existing min/max UP */ 7992 min_vlan[i] = min_vlan[i + 1]; 7993 max_vlan[i] = max_vlan[i + 1]; 7994 } 7995 /* Mark last min/max range as unused. Unused ranges are 7996 * identified by { min == 1, max == 0 } 7997 */ 7998 min_vlan[i] = 1; 7999 max_vlan[i] = 0; 8000 8001 /* Adding the new profile table entry and update profile pointer */ 8002 for (i = 0; i < port_count; i++) { 8003 rv = _bcm_trx_vlan_range_profile_entry_add(unit, 8004 min_vlan, max_vlan, &new_idx); 8005 if (BCM_FAILURE(rv)) { 8006 soc_mem_unlock(unit, ING_VLAN_RANGEm); 8007 goto cleanup; 8008 } 8009 rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[i], 8010 port_array[i], &stm_idx); 8011 if (BCM_SUCCESS(rv)) { 8012 rv = soc_mem_field32_modify(unit, 8013 SOURCE_TRUNK_MAP_TABLEm, stm_idx, 8014 field, new_idx); 8015 } 8016 if (BCM_FAILURE(rv)) { 8017 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 8018 soc_mem_unlock(unit, ING_VLAN_RANGEm); 8019 goto cleanup; 8020 } 8021 } 8022 } 8023 } 8024 8025 /* Delete the entry from the vlan translate table for the low VID */ 8026 rv = _bcm_trx_vlan_translate_action_delete(unit, port, key_type, 8027 outer_vlan_low, inner_vlan_low); 8028 if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)){ 8029 for (i = 0; i < port_count; i++) { 8030 if (outer_vlan_low != BCM_VLAN_INVALID) { 8031 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 8032 } 8033 if (inner_vlan_low != BCM_VLAN_INVALID) { 8034 _bcm_trx_vlan_range_profile_entry_delete(unit, new_inner_idx); 8035 } 8036 } 8037 if (port_count > 0) { 8038 soc_mem_unlock(unit, ING_VLAN_RANGEm); 8039 } 8040 goto cleanup; 8041 } 8042 8043 /* Delete the old profile entry */ 8044 for (i = 0; i < port_count; i++) { 8045 if (outer_vlan_low != BCM_VLAN_INVALID) { 8046 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx); 8047 } 8048 if (inner_vlan_low != BCM_VLAN_INVALID) { 8049 _bcm_trx_vlan_range_profile_entry_delete(unit, old_inner_idx); 8050 } 8051 } 8052 8053 if (BCM_GPORT_IS_TRUNK(port)) { 8054 if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) { 8055 trunk128 = soc_property_get(unit, spn_TRUNK_EXTEND, 1); 8056 if (!trunk128) { 8057 rv = _bcm_trx_vlan_range_profile_entry_add(unit, 8058 min_vlan, max_vlan, &new_idx); 8059 if (BCM_FAILURE(rv)) { 8060 soc_mem_unlock(unit, ING_VLAN_RANGEm); 8061 goto cleanup; 8062 } 8063 rv = soc_mem_field32_modify(unit, TRUNK32_PORT_TABLEm, trunk_id, 8064 VLAN_RANGE_IDXf, new_idx); 8065 if (BCM_FAILURE(rv)) { 8066 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 8067 soc_mem_unlock(unit, ING_VLAN_RANGEm); 8068 goto cleanup; 8069 } 8070 if (outer_vlan_low != BCM_VLAN_INVALID) { 8071 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx); 8072 } 8073 if (inner_vlan_low != BCM_VLAN_INVALID) { 8074 _bcm_trx_vlan_range_profile_entry_delete(unit, old_inner_idx); 8075 } 8076 } 8077 } 8078 } 8079 if (port_count > 0) { 8080 soc_mem_unlock(unit, ING_VLAN_RANGEm); 8081 } 8082 8083 cleanup: 8084 if (NULL != member_array) { 8085 sal_free(member_array); 8086 } 8087 if (NULL != mod_array) { 8088 sal_free(mod_array); 8089 } 8090 if (NULL != port_array) { 8091 sal_free(port_array); 8092 } 8093 8094 return rv; 8095 } 8096 8097 /* 8098 * Function : 8099 * bcm_vlan_translate_action_range_delete_all 8100 * Description : 8101 * Delete all ranges of VLANs and entries from ingress 8102 * VLAN translation table. 8103 * Parameters : 8104 * unit (IN) BCM unit number 8105 */ 8106 int 8107 _bcm_trx_vlan_translate_action_range_delete_all(int unit) 8108 { 8109 int rv; 8110 8111 rv = _bcm_trx_vlan_range_profile_init(unit); 8112 if (rv == BCM_E_NONE) { 8113 rv = _bcm_trx_vlan_translate_action_delete_all(unit); 8114 } 8115 return rv; 8116 } 8117 8118 /* 8119 * Function: 8120 * _bcm_trx_vlan_translate_stm_index_to_gport 8121 * Description: 8122 * Translate index of SOURCE_TRUNK_MAP_TABLE into gport 8123 * Parameters: 8124 * unit device number 8125 * stm_index Index to SOURCE_TRUNK_MAP_TABLE 8126 * gport (OUT) gport 8127 * Return: 8128 * BCM_E_XXX 8129 */ 8130 STATIC int 8131 _bcm_trx_vlan_translate_stm_index_to_gport(int unit, int stm_index, 8132 bcm_gport_t *gport) 8133 { 8134 bcm_module_t modid; 8135 bcm_port_t port; 8136 _bcm_gport_dest_t gport_dest; 8137 8138 if (NULL == gport) { 8139 return BCM_E_PARAM; 8140 } 8141 8142 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 8143 if (soc_feature(unit, soc_feature_src_modid_base_index)) { 8144 BCM_IF_ERROR_RETURN 8145 (_bcm_esw_src_modid_port_get(unit, stm_index, 8146 &modid,&port)); 8147 } else 8148 #endif 8149 { 8150 modid = stm_index / (SOC_PORT_ADDR_MAX(unit) + 1) ; 8151 port = stm_index - modid * (SOC_PORT_ADDR_MAX(unit) + 1); 8152 } 8153 8154 if (!SOC_MODID_ADDRESSABLE(unit, modid)) { 8155 return BCM_E_PARAM; 8156 } 8157 8158 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 8159 return BCM_E_PARAM; 8160 } 8161 8162 gport_dest.port = port; 8163 gport_dest.modid = modid; 8164 gport_dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 8165 BCM_IF_ERROR_RETURN(_bcm_esw_gport_construct(unit, &gport_dest, gport)); 8166 8167 return BCM_E_NONE; 8168 } 8169 8170 /* 8171 * Function : 8172 * _bcm_trx_vlan_translate_action_range_traverse 8173 * Description : 8174 * Traverses over range of ingress VLAN translation table. 8175 * Parameters : 8176 * unit (IN) BCM unit number 8177 * trvs_info (IN/OUT) Traverse Structure to opertae on 8178 */ 8179 int 8180 _bcm_trx_vlan_translate_action_range_traverse(int unit, 8181 _bcm_vlan_translate_traverse_t *trvs_info) 8182 { 8183 /* Indexes to iterate over memories, chunks and entries */ 8184 int chnk_idx, ent_idx, chnk_idx_max, mem_idx_max; 8185 int buf_size, chunksize, chnk_end; 8186 /* Buffer to store chunks of memory table we currently work on */ 8187 uint32 *stm_tbl_chnk; 8188 source_trunk_map_table_entry_t *stm_ent; 8189 soc_mem_t mem; 8190 int stop, rv = BCM_E_NONE; 8191 /* Index to point to table of vlan ranges. */ 8192 int range_idx, stm_index, i; 8193 bcm_gport_t gport; 8194 bcm_vlan_t min_vlan[8], max_vlan[8]; 8195 soc_field_t field; 8196 bcm_vlan_t min_inner_vlan[8], max_inner_vlan[8]; 8197 int range_inner_idx, j; 8198 8199 mem = SOURCE_TRUNK_MAP_TABLEm; 8200 if (!soc_mem_index_count(unit, mem)) { 8201 return BCM_E_NONE; 8202 } 8203 8204 chunksize = soc_property_get(unit, spn_VLANDELETE_CHUNKS, 8205 VLAN_MEM_CHUNKS_DEFAULT); 8206 8207 buf_size = 4 * SOC_MAX_MEM_FIELD_WORDS * chunksize; 8208 stm_tbl_chnk = soc_cm_salloc(unit, buf_size, 8209 "vlan translate range traverse"); 8210 if (NULL == stm_tbl_chnk) { 8211 return BCM_E_MEMORY; 8212 } 8213 8214 mem_idx_max = soc_mem_index_max(unit, mem); 8215 for (chnk_idx = soc_mem_index_min(unit, mem); 8216 chnk_idx <= mem_idx_max; 8217 chnk_idx += chunksize) { 8218 sal_memset((void *)stm_tbl_chnk, 0, buf_size); 8219 8220 chnk_idx_max = 8221 ((chnk_idx + chunksize) <= mem_idx_max) ? 8222 chnk_idx + chunksize - 1: mem_idx_max; 8223 8224 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 8225 chnk_idx, chnk_idx_max, stm_tbl_chnk); 8226 if (SOC_FAILURE(rv)) { 8227 break; 8228 } 8229 chnk_end = (chnk_idx_max - chnk_idx); 8230 8231 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 8232 OUTER_VLAN_RANGE_IDXf)) { 8233 field = OUTER_VLAN_RANGE_IDXf; 8234 } else { 8235 field = VLAN_RANGE_IDXf; 8236 } 8237 8238 for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) { 8239 stm_ent = soc_mem_table_idx_to_pointer(unit, mem, 8240 source_trunk_map_table_entry_t *, 8241 stm_tbl_chnk, ent_idx); 8242 8243 if (soc_feature(unit, soc_feature_vlan_double_tag_range_compress)) { 8244 range_idx = soc_mem_field32_get(unit, mem, stm_ent, field); 8245 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, 8246 range_idx); 8247 8248 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 8249 INNER_VLAN_RANGE_IDXf)) { 8250 range_inner_idx = soc_mem_field32_get(unit, mem, stm_ent, 8251 INNER_VLAN_RANGE_IDXf); 8252 _bcm_trx_vlan_range_profile_entry_get(unit, min_inner_vlan, 8253 max_inner_vlan, range_inner_idx); 8254 if ((1 == min_vlan[0]) && (0 == max_vlan[0]) && 8255 (1 == min_inner_vlan[0]) && (0 == max_inner_vlan[0])) { 8256 continue; 8257 } 8258 } else { 8259 if ((1 == min_vlan[0]) && (0 == max_vlan[0])) { 8260 continue; 8261 } 8262 } 8263 stm_index = chnk_idx + ent_idx; 8264 rv = _bcm_trx_vlan_translate_stm_index_to_gport(unit, stm_index, 8265 &gport); 8266 if (BCM_FAILURE(rv)) { 8267 break; 8268 } 8269 trvs_info->gport = gport; 8270 8271 for (i = 0; i < 8; i++) { 8272 if ((1 == min_vlan[i]) && (0 == max_vlan[i])) { 8273 continue; 8274 } 8275 trvs_info->inner_vlan = BCM_VLAN_INVALID; 8276 trvs_info->inner_vlan_high = BCM_VLAN_INVALID; 8277 trvs_info->outer_vlan = BCM_VLAN_INVALID; 8278 trvs_info->outer_vlan_high = BCM_VLAN_INVALID; 8279 /* check if entry key_type is 8280 bcmVlanTranslateKeyPortOuter */ 8281 rv = _bcm_trx_vlan_translate_action_range_get( 8282 unit, gport, 8283 min_vlan[i], max_vlan[i], 8284 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 8285 trvs_info->action); 8286 if (BCM_SUCCESS (rv)) { 8287 trvs_info->key_type = bcmVlanTranslateKeyPortOuter; 8288 trvs_info->outer_vlan = min_vlan[i]; 8289 trvs_info->outer_vlan_high = max_vlan[i]; 8290 rv = trvs_info->int_cb(unit, trvs_info, &stop); 8291 if (BCM_FAILURE(rv) || TRUE == stop) { 8292 break; 8293 } 8294 } else { 8295 if (BCM_E_NOT_FOUND == rv) { 8296 if (SOC_MEM_FIELD_VALID(unit, 8297 SOURCE_TRUNK_MAP_TABLEm, 8298 INNER_VLAN_RANGE_IDXf)) { 8299 for (j = 0; j < 8; j++) { 8300 if ((1 == min_inner_vlan[j]) && 8301 (0 == max_inner_vlan[j])) { 8302 continue; 8303 } 8304 trvs_info->inner_vlan = BCM_VLAN_INVALID; 8305 trvs_info->inner_vlan_high = 8306 BCM_VLAN_INVALID; 8307 trvs_info->outer_vlan = BCM_VLAN_INVALID; 8308 trvs_info->outer_vlan_high = 8309 BCM_VLAN_INVALID; 8310 /* check if entry key_type is 8311 * bcmVlanTranslateKeyPortDouble */ 8312 rv = 8313 _bcm_trx_vlan_translate_action_range_get( 8314 unit, gport, 8315 min_vlan[i], max_vlan[i], 8316 min_inner_vlan[j], 8317 max_inner_vlan[j], 8318 trvs_info->action); 8319 if (BCM_SUCCESS (rv)) { 8320 trvs_info->key_type = 8321 bcmVlanTranslateKeyPortDouble; 8322 trvs_info->outer_vlan = min_vlan[i]; 8323 trvs_info->outer_vlan_high = 8324 max_vlan[i]; 8325 trvs_info->inner_vlan = 8326 min_inner_vlan[j]; 8327 trvs_info->inner_vlan_high = 8328 max_inner_vlan[j]; 8329 rv = trvs_info->int_cb(unit, 8330 trvs_info, &stop); 8331 if (BCM_FAILURE(rv) || TRUE == stop) { 8332 break; 8333 } 8334 } else { 8335 if (BCM_E_NOT_FOUND != rv) { 8336 soc_cm_sfree(unit, stm_tbl_chnk); 8337 return rv; 8338 } 8339 } 8340 } /*endof for j=0;j<8;j++*/ 8341 } 8342 } else { 8343 soc_cm_sfree(unit, stm_tbl_chnk); 8344 return rv; 8345 } 8346 } 8347 } /*endof for i=0;i<8;i++ */ 8348 8349 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 8350 INNER_VLAN_RANGE_IDXf)) { 8351 for (j = 0; j < 8; j++) { 8352 if ((1 == min_inner_vlan[j]) && 8353 (0 == max_inner_vlan[j])) { 8354 continue; 8355 } 8356 trvs_info->inner_vlan = BCM_VLAN_INVALID; 8357 trvs_info->inner_vlan_high = BCM_VLAN_INVALID; 8358 trvs_info->outer_vlan = BCM_VLAN_INVALID; 8359 trvs_info->outer_vlan_high = BCM_VLAN_INVALID; 8360 /* check if entry key_type is 8361 bcmVlanTranslateKeyPortInner */ 8362 rv = _bcm_trx_vlan_translate_action_range_get( 8363 unit, gport, 8364 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 8365 min_inner_vlan[j], max_inner_vlan[j], 8366 trvs_info->action); 8367 if (BCM_SUCCESS (rv)) { 8368 trvs_info->key_type = bcmVlanTranslateKeyPortInner; 8369 trvs_info->inner_vlan = min_inner_vlan[j]; 8370 trvs_info->inner_vlan_high = max_inner_vlan[j]; 8371 rv = trvs_info->int_cb(unit, trvs_info, &stop); 8372 if (BCM_FAILURE(rv) || TRUE == stop) { 8373 break; 8374 } 8375 } else { 8376 if (BCM_E_NOT_FOUND != rv) { 8377 soc_cm_sfree(unit, stm_tbl_chnk); 8378 return rv; 8379 } 8380 } 8381 } 8382 } 8383 } else { 8384 range_idx = soc_mem_field32_get(unit, mem, stm_ent, field); 8385 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, 8386 range_idx); 8387 8388 if ((1 == min_vlan[0]) && (0 == max_vlan[0])) { 8389 continue; 8390 } 8391 8392 stm_index = chnk_idx + ent_idx; 8393 rv = _bcm_trx_vlan_translate_stm_index_to_gport(unit, stm_index, 8394 &gport); 8395 if (BCM_FAILURE(rv)) { 8396 break; 8397 } 8398 trvs_info->gport = gport; 8399 8400 for (i = 0; i < 8; i++) { 8401 if ((1 == min_vlan[i]) && (0 == max_vlan[i])) { 8402 continue; 8403 } 8404 trvs_info->inner_vlan = BCM_VLAN_INVALID; 8405 trvs_info->inner_vlan_high = BCM_VLAN_INVALID; 8406 trvs_info->outer_vlan = BCM_VLAN_INVALID; 8407 trvs_info->outer_vlan_high = BCM_VLAN_INVALID; 8408 8409 /* check if entry key_type is 8410 * bcmVlanTranslateKeyPortOuter */ 8411 rv = _bcm_trx_vlan_translate_action_range_get(unit, 8412 gport, 8413 min_vlan[i], 8414 max_vlan[i], 8415 BCM_VLAN_INVALID, 8416 BCM_VLAN_INVALID, 8417 trvs_info->action); 8418 if (BCM_SUCCESS (rv)) { 8419 trvs_info->key_type = bcmVlanTranslateKeyPortOuter; 8420 trvs_info->outer_vlan = min_vlan[i]; 8421 trvs_info->outer_vlan_high = max_vlan[i]; 8422 } else { 8423 if (BCM_E_NOT_FOUND == rv) { 8424 /* check if entry key_type is 8425 bcmVlanTranslateKeyPortInner */ 8426 rv = _bcm_trx_vlan_translate_action_range_get(unit, 8427 gport, 8428 BCM_VLAN_INVALID, 8429 BCM_VLAN_INVALID, 8430 min_vlan[i], 8431 max_vlan[i], 8432 trvs_info->action); 8433 if (BCM_FAILURE(rv)) { 8434 soc_cm_sfree(unit, stm_tbl_chnk); 8435 return rv; 8436 } 8437 trvs_info->key_type = bcmVlanTranslateKeyPortInner; 8438 trvs_info->inner_vlan = min_vlan[i]; 8439 trvs_info->inner_vlan_high = max_vlan[i]; 8440 } else { 8441 soc_cm_sfree(unit, stm_tbl_chnk); 8442 return rv; 8443 } 8444 } 8445 8446 rv = trvs_info->int_cb(unit, trvs_info, &stop); 8447 if (BCM_FAILURE(rv) || TRUE == stop) { 8448 break; 8449 } 8450 } 8451 } 8452 } 8453 } 8454 soc_cm_sfree(unit, stm_tbl_chnk); 8455 return rv; 8456 8457 } 8458 8459 /* 8460 * Function: 8461 * _bcm_trx_vlan_translate_egress_entry_assemble 8462 * Purpose: 8463 * Constructs vlan translate egress entry from given port class, 8464 * inner and outer vlans 8465 * Parameters: 8466 * unit (IN) BCM unit number 8467 * vent (IN/OUT) vlan translate egress entry to construct 8468 * port_class (IN) Group ID of ingress port 8469 * outer_vlan (IN) Packet outer VLAN ID 8470 * inner_vlan (IN) Packet inner VLAN ID 8471 * Returns: 8472 * BCM_E_XXX 8473 */ 8474 int 8475 _bcm_trx_vlan_translate_egress_entry_assemble(int unit, 8476 void *vent, 8477 int port_class, 8478 bcm_vlan_t outer_vlan, 8479 bcm_vlan_t inner_vlan) 8480 { 8481 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 8482 int id = -1; 8483 bcm_module_t modid = -1; 8484 bcm_trunk_t tgid = -1; 8485 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 8486 8487 #ifdef BCM_TRIUMPH2_SUPPORT 8488 int tunnel_id = 0; 8489 int dvp_id = BCM_GPORT_INVALID; 8490 #endif 8491 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8492 int vfi_index = 0; 8493 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 8494 #if defined(BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3) 8495 int rv = BCM_E_NONE; 8496 int ecmp = -1, nh_ecmp_index = -1; 8497 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */ 8498 8499 soc_mem_t egr_mem = EGR_VLAN_XLATEm; 8500 uint32 ent_sz = sizeof(egr_vlan_xlate_entry_t); 8501 8502 #ifdef BCM_TRIUMPH2_SUPPORT 8503 soc_field_t kt_fld = ENTRY_TYPEf; 8504 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 8505 egr_mem = EGR_VLAN_XLATE_1_DOUBLEm; 8506 ent_sz = sizeof(egr_vlan_xlate_1_double_entry_t); 8507 kt_fld = KEY_TYPEf; 8508 } 8509 #endif 8510 8511 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8512 if (soc_feature(unit, soc_feature_vp_sharing)) { 8513 if (_BCM_VPN_VFI_IS_SET(outer_vlan)) 8514 { 8515 /* only invalid inner VLAN is allowed for VFI case */ 8516 if (inner_vlan == BCM_VLAN_INVALID) { 8517 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, outer_vlan); 8518 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeAny)) { 8519 return BCM_E_NOT_FOUND; 8520 } 8521 } else { 8522 return BCM_E_PARAM; 8523 } 8524 } else { 8525 VLAN_CHK_ID(unit, outer_vlan); 8526 VLAN_CHK_ID(unit, inner_vlan); 8527 } 8528 } else 8529 #endif 8530 { 8531 VLAN_CHK_ID(unit, outer_vlan); 8532 VLAN_CHK_ID(unit, inner_vlan); 8533 } 8534 #ifdef BCM_TRIUMPH2_SUPPORT 8535 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8536 if (inner_vlan == BCM_VLAN_INVALID) { 8537 if (BCM_GPORT_IS_VXLAN_PORT(port_class)) { 8538 if (soc_feature(unit, soc_feature_vxlan)) { 8539 dvp_id = BCM_GPORT_VXLAN_PORT_ID_GET(port_class); 8540 } else { 8541 return BCM_E_PORT; 8542 } 8543 } else if (BCM_GPORT_IS_MIM_PORT(port_class)) { 8544 if (soc_feature(unit, soc_feature_mim)) { 8545 dvp_id = BCM_GPORT_MIM_PORT_ID_GET(port_class); 8546 } else { 8547 return BCM_E_PORT; 8548 } 8549 } else if (BCM_GPORT_IS_MPLS_PORT(port_class)) { 8550 if (soc_feature(unit, soc_feature_mpls)) { 8551 dvp_id = BCM_GPORT_MPLS_PORT_ID_GET(port_class); 8552 } else { 8553 return BCM_E_PORT; 8554 } 8555 } else if (BCM_GPORT_IS_L2GRE_PORT(port_class)) { 8556 if (soc_feature(unit, soc_feature_l2gre)) { 8557 dvp_id = BCM_GPORT_L2GRE_PORT_ID_GET(port_class); 8558 } else { 8559 return BCM_E_PORT; 8560 } 8561 } else if (BCM_GPORT_IS_TUNNEL(port_class) || 8562 BCM_GPORT_IS_SUBPORT_PORT(port_class) || 8563 BCM_GPORT_IS_WLAN_PORT(port_class) || 8564 BCM_GPORT_IS_VLAN_PORT(port_class) || 8565 BCM_GPORT_IS_NIV_PORT(port_class)){ 8566 return BCM_E_PORT; 8567 } 8568 } else 8569 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 8570 if (BCM_GPORT_IS_TUNNEL(port_class)) { 8571 if (soc_feature(unit, soc_feature_wlan)) { 8572 tunnel_id = BCM_GPORT_TUNNEL_ID_GET(port_class); 8573 } else { 8574 return BCM_E_PORT; 8575 } 8576 } else if (BCM_GPORT_IS_SUBPORT_PORT(port_class)) { 8577 if (soc_feature(unit, soc_feature_subport)) { 8578 bcm_module_t modid = -1; 8579 bcm_trunk_t tgid = -1; 8580 int port = -1; 8581 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port_class, 8582 &modid, &port, &tgid, &dvp_id)); 8583 } else { 8584 return BCM_E_PORT; 8585 } 8586 } else if (BCM_GPORT_IS_MIM_PORT(port_class)) { 8587 if (soc_feature(unit, soc_feature_mim)) { 8588 dvp_id = BCM_GPORT_MIM_PORT_ID_GET(port_class); 8589 } else { 8590 return BCM_E_PORT; 8591 } 8592 8593 } else if (BCM_GPORT_IS_WLAN_PORT(port_class)) { 8594 if (soc_feature(unit, soc_feature_wlan)) { 8595 dvp_id = BCM_GPORT_WLAN_PORT_ID_GET(port_class); 8596 } else { 8597 return BCM_E_PORT; 8598 } 8599 } else if (BCM_GPORT_IS_VLAN_PORT(port_class)) { 8600 if (soc_feature(unit, soc_feature_vlan_vp)) { 8601 dvp_id = BCM_GPORT_VLAN_PORT_ID_GET(port_class); 8602 } else { 8603 return BCM_E_PORT; 8604 } 8605 } else if (BCM_GPORT_IS_NIV_PORT(port_class)) { 8606 if (soc_feature(unit, soc_feature_niv)) { 8607 dvp_id = BCM_GPORT_NIV_PORT_ID_GET(port_class); 8608 } else { 8609 return BCM_E_PORT; 8610 } 8611 } else if (BCM_GPORT_IS_EXTENDER_PORT(port_class)) { 8612 if (soc_feature(unit, soc_feature_port_extension)) { 8613 dvp_id = BCM_GPORT_EXTENDER_PORT_ID_GET(port_class); 8614 } else { 8615 return BCM_E_PORT; 8616 } 8617 } else if (BCM_GPORT_IS_MPLS_PORT(port_class)) { 8618 if (soc_feature(unit, soc_feature_mpls)) { 8619 dvp_id = BCM_GPORT_MPLS_PORT_ID_GET(port_class); 8620 } else { 8621 return BCM_E_PORT; 8622 } 8623 } else if (BCM_GPORT_IS_VXLAN_PORT(port_class)) { 8624 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 8625 if (soc_feature(unit, soc_feature_vxlan)) { 8626 ing_dvp_table_entry_t dvp; 8627 dvp_id = BCM_GPORT_VXLAN_PORT_ID_GET(port_class); 8628 BCM_IF_ERROR_RETURN( 8629 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, dvp_id, &dvp)); 8630 if (soc_ING_DVP_TABLEm_field32_get(unit, &dvp, VP_TYPEf) == 0x3) { 8631 return BCM_E_PORT; 8632 } 8633 } else 8634 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 8635 #if defined(BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3) 8636 if (soc_feature(unit, soc_feature_vxlan_lite)) { 8637 dvp_id = BCM_GPORT_VXLAN_PORT_ID_GET(port_class); 8638 rv = bcmi_gh2_vxlan_port_to_nh_ecmp_index(unit, dvp_id, 8639 &ecmp, &nh_ecmp_index); 8640 if (BCM_FAILURE(rv) || (ecmp)) { 8641 return BCM_E_PORT; 8642 } 8643 } else 8644 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */ 8645 { 8646 return BCM_E_PORT; 8647 } 8648 } else if (BCM_GPORT_IS_L2GRE_PORT(port_class)) { 8649 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 8650 if (soc_feature(unit, soc_feature_l2gre)) { 8651 ing_dvp_table_entry_t dvp; 8652 dvp_id = BCM_GPORT_L2GRE_PORT_ID_GET(port_class); 8653 BCM_IF_ERROR_RETURN( 8654 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, dvp_id, &dvp)); 8655 if (soc_ING_DVP_TABLEm_field32_get(unit, &dvp, VP_TYPEf) == 0x2) { 8656 return BCM_E_PORT; 8657 } 8658 } else 8659 #endif 8660 { 8661 return BCM_E_PORT; 8662 } 8663 } 8664 #endif /* BCM_TRIUMPH2_SUPPORT */ 8665 8666 sal_memset(vent, 0, ent_sz); 8667 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8668 if (inner_vlan == BCM_VLAN_INVALID) { 8669 soc_mem_field32_set(unit, egr_mem, vent, 8670 VLAN_XLATE_VFI__VFIf, vfi_index); 8671 8672 } else 8673 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 8674 { 8675 soc_mem_field32_set(unit, egr_mem, vent, OVIDf, outer_vlan); 8676 soc_mem_field32_set(unit, egr_mem, vent, IVIDf, inner_vlan); 8677 } 8678 #ifdef BCM_TRIUMPH2_SUPPORT 8679 if (BCM_GPORT_IS_TUNNEL(port_class)) { 8680 soc_mem_field32_set(unit, egr_mem, vent, kt_fld, 2); /* WLAN */ 8681 if (soc_mem_field_valid(unit, egr_mem, DATA_TYPEf)) { 8682 soc_mem_field32_set(unit, egr_mem, vent, DATA_TYPEf, 2); 8683 } 8684 soc_mem_field32_set(unit, egr_mem, vent, TUNNEL_IDf, tunnel_id); 8685 } else if (BCM_GPORT_INVALID != dvp_id) { 8686 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8687 if (inner_vlan == BCM_VLAN_INVALID) { 8688 soc_mem_field32_set(unit, egr_mem, vent, kt_fld, 8689 TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI); /* VFI + DVP */ 8690 #ifdef BCM_TRIDENT3_SUPPORT 8691 if (soc_mem_field_valid(unit, egr_mem, DATA_TYPEf)) { 8692 soc_mem_field32_set(unit, egr_mem, vent, DATA_TYPEf, 8693 TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI); 8694 } 8695 #endif 8696 soc_mem_field32_set(unit, egr_mem, vent, 8697 VLAN_XLATE_VFI__DVPf, dvp_id); 8698 } else 8699 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 8700 #if defined(BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3) 8701 if (soc_feature(unit, soc_feature_vxlan_lite)) { 8702 /* ENTRY_TYPEf: NHI */ 8703 soc_mem_field32_set(unit, egr_mem, vent, ENTRY_TYPEf, 0x7); 8704 /* NHI for NHI view */ 8705 soc_mem_field32_set(unit, egr_mem, vent, NHI__NHIf, nh_ecmp_index); 8706 } else 8707 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */ 8708 { 8709 #ifdef BCM_TRIUMPH3_SUPPORT 8710 if(SOC_IS_TRIUMPH3(unit)) { 8711 soc_mem_field32_set(unit, egr_mem, vent, KEY_TYPEf, 1); /* DVP */ 8712 } else 8713 #endif /* BCM_TRIUMPH3_SUPPORT */ 8714 { 8715 soc_mem_field32_set(unit, egr_mem, vent, kt_fld, 1); /* DVP */ 8716 if (soc_mem_field_valid(unit, egr_mem, DATA_TYPEf)) { 8717 soc_mem_field32_set(unit, egr_mem, vent, DATA_TYPEf, 1); 8718 } 8719 } 8720 soc_mem_field32_set(unit, egr_mem, vent, DVPf, dvp_id); 8721 } 8722 } else 8723 #endif 8724 { 8725 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8726 if (inner_vlan == BCM_VLAN_INVALID) { 8727 soc_mem_field32_set(unit, egr_mem, vent, kt_fld, /* VFI + DVP Group*/ 8728 TD2PLUS_EVLXLT_HASH_KEY_TYPE_VFI_DVP_GROUP); 8729 if (soc_mem_field_valid(unit, egr_mem, DATA_TYPEf)) { 8730 soc_mem_field32_set(unit, egr_mem, vent, DATA_TYPEf, 8731 TD2PLUS_EVLXLT_HASH_KEY_TYPE_VFI_DVP_GROUP); 8732 } 8733 soc_mem_field32_set(unit, egr_mem, vent, 8734 VFI_DVP_GROUP__VT_DVP_GROUP_IDf, port_class); 8735 8736 if (soc_mem_field_valid(unit, egr_mem, 8737 VFI_DVP_GROUP__DATA_OVERLAY_TYPEf)) { 8738 soc_mem_field32_set(unit, egr_mem, vent, 8739 VFI_DVP_GROUP__DATA_OVERLAY_TYPEf, 1); 8740 } else if (soc_mem_field_valid(unit, egr_mem, 8741 VFI_DVP_GROUP__DATA_TYPEf)) { 8742 soc_mem_field32_set(unit, egr_mem, vent, 8743 VFI_DVP_GROUP__DATA_TYPEf, 1); 8744 } 8745 } else 8746 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 8747 { 8748 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 8749 if ((BCM_GPORT_IS_MODPORT(port_class) || 8750 BCM_GPORT_IS_SUBPORT_PORT(port_class)) && 8751 soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) { 8752 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port_class, 8753 &modid, &port_class, &tgid, &id)); 8754 if (modid != -1 && port_class != -1) { 8755 soc_mem_field32_set(unit, egr_mem, vent, DST_MODIDf, 8756 modid); 8757 soc_mem_field32_set(unit, egr_mem, vent, DST_PORTf, 8758 port_class); 8759 if (SOC_MEM_FIELD_VALID(unit, egr_mem, 8760 PORT_TYPE_DGPPf)) { 8761 soc_mem_field32_set(unit, egr_mem, vent, 8762 PORT_TYPE_DGPPf, TRUE); 8763 } 8764 } else { 8765 return BCM_E_PORT; 8766 } 8767 } else 8768 #endif 8769 { 8770 soc_mem_field32_set(unit, egr_mem, vent, PORT_GROUP_IDf, 8771 port_class); 8772 } 8773 } 8774 } 8775 return BCM_E_NONE; 8776 } 8777 8778 /* 8779 * Function : 8780 * bcm_vlan_translate_egress_action_add 8781 * Description : 8782 * Add an entry to egress VLAN translation table. 8783 * Parameters : 8784 * unit (IN) BCM unit number 8785 * port_class (IN) Group ID of ingress port 8786 * outer_vlan (IN) Packet outer VLAN ID 8787 * inner_vlan (IN) Packet inner VLAN ID 8788 * action (IN) Action for outer and inner tag 8789 */ 8790 int 8791 _bcm_trx_vlan_translate_egress_action_add(int unit, int port_class, 8792 bcm_vlan_t outer_vlan, 8793 bcm_vlan_t inner_vlan, 8794 bcm_vlan_action_set_t *action) 8795 { 8796 int rv; 8797 uint32 profile_idx; 8798 uint32 old_profile_idx = 0; 8799 egr_vlan_xlate_entry_t evx_ent; 8800 egr_vlan_xlate_entry_t evx_ent_old; 8801 8802 egr_vlan_xlate_1_double_entry_t evx1d_ent; 8803 egr_vlan_xlate_1_double_entry_t evx1d_ent_old; 8804 8805 void *vent = &evx_ent, *vent_old = &evx_ent_old; 8806 8807 void *vent_ptr; 8808 8809 int index; 8810 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8811 uint32 entry[SOC_MAX_MEM_WORDS]; 8812 soc_field_info_t *field_info = NULL, *field_info_1 = NULL; 8813 void *vent_tmp_p = NULL; 8814 egr_vlan_xlate_entry_t evx_ent_tmp; 8815 egr_vlan_xlate_1_double_entry_t evx1d_ent_tmp; 8816 void *vent_tmp = &evx_ent_tmp; 8817 uint32 ent_sz = sizeof(egr_vlan_xlate_entry_t); 8818 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 8819 8820 soc_mem_t mem = EGR_VLAN_XLATEm; 8821 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 8822 mem = EGR_VLAN_XLATE_1_DOUBLEm; 8823 vent = &evx1d_ent; 8824 vent_old = &evx1d_ent_old; 8825 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8826 vent_tmp = &evx1d_ent_tmp; 8827 ent_sz = sizeof(egr_vlan_xlate_1_double_entry_t); 8828 #endif 8829 } 8830 8831 BCM_IF_ERROR_RETURN(_bcm_trx_egr_vlan_action_verify(unit, action)); 8832 8833 vent_ptr = vent; 8834 BCM_IF_ERROR_RETURN 8835 (_bcm_trx_vlan_translate_egress_entry_assemble(unit, vent_ptr, 8836 port_class, 8837 outer_vlan, 8838 inner_vlan)); 8839 8840 soc_mem_lock(unit, mem); 8841 /* check if the entry with same key already exists */ 8842 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 8843 vent_ptr, vent_old, 0); 8844 8845 if (rv == SOC_E_NONE) { 8846 /* alredy exists, update on the existing one, so the flex 8847 * counter related fields in TR3/Katana can be preserved. 8848 */ 8849 vent_ptr = vent_old; 8850 old_profile_idx = soc_mem_field32_get(unit, mem, vent_ptr, 8851 TAG_ACTION_PROFILE_PTRf); 8852 } else if (rv != SOC_E_NOT_FOUND) { 8853 soc_mem_unlock(unit, mem); 8854 return rv; /* error condition */ 8855 } else { 8856 /* doesn't exist, update the new entry */ 8857 vent_ptr = vent; 8858 } 8859 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8860 if (inner_vlan == BCM_VLAN_INVALID) { 8861 sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32)); 8862 if (BCM_GPORT_IS_SET(port_class) && 8863 !BCM_GPORT_IS_MODPORT(port_class)) { 8864 field_info = soc_mem_fieldinfo_get(unit, mem, 8865 VLAN_XLATE_VFI__XLATE_DATAf); 8866 } else { 8867 field_info = soc_mem_fieldinfo_get(unit, mem, 8868 VFI_DVP_GROUP__XLATE_DATAf); 8869 } 8870 if (!field_info) { 8871 return BCM_E_UNAVAIL; 8872 } 8873 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, vent_ptr, 8874 field_info, entry); 8875 /* Reuse the format of field XLATE_DATA in XLATE view 8876 * for VLAN_XLATE_VFI and VFI_DVP view. 8877 */ 8878 vent_tmp_p = vent_ptr; 8879 field_info_1 = soc_mem_fieldinfo_get(unit, mem, 8880 XLATE_DATAf); 8881 if (!field_info_1) { 8882 return BCM_E_UNAVAIL; 8883 } 8884 sal_memset(vent_tmp, 0, ent_sz); 8885 vent_ptr = vent_tmp; 8886 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, vent_ptr, 8887 field_info_1, entry); 8888 if ( rv == SOC_E_NONE) { 8889 old_profile_idx = soc_mem_field32_get(unit, mem, vent_ptr, 8890 TAG_ACTION_PROFILE_PTRf); 8891 } 8892 } 8893 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 8894 soc_mem_field32_set(unit, mem, vent_ptr, NEW_IVIDf, 8895 action->new_inner_vlan); 8896 soc_mem_field32_set(unit, mem, vent_ptr, NEW_OVIDf, 8897 action->new_outer_vlan); 8898 8899 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 8900 bcm_vlan_action_set_t action1; 8901 sal_memcpy(&action1, action, sizeof(bcm_vlan_action_set_t)); 8902 if (action->priority == -1) { 8903 /* point to the default mapping table(0) for default priority action */ 8904 PKT_VLAN_OUTER_ACTION_SET(unit, mem, vent_ptr, action); 8905 PKT_VLAN_INNER_ACTION_SET(unit, mem, vent_ptr, action); 8906 8907 #define PKT_PRI_DFLT_ACTION(_action_tag) \ 8908 do { \ 8909 if (((_action_tag) == bcmVlanActionReplace) || \ 8910 ((_action_tag) == bcmVlanActionAdd) ) { \ 8911 _action_tag ## _pkt_prio = _action_tag; \ 8912 } \ 8913 } while(0) 8914 PKT_PRI_DFLT_ACTION(action1.dt_outer); 8915 PKT_PRI_DFLT_ACTION(action1.dt_inner); 8916 PKT_PRI_DFLT_ACTION(action1.ot_outer); 8917 PKT_PRI_DFLT_ACTION(action1.ot_inner); 8918 PKT_PRI_DFLT_ACTION(action1.it_outer); 8919 PKT_PRI_DFLT_ACTION(action1.it_inner); 8920 PKT_PRI_DFLT_ACTION(action1.ut_outer); 8921 PKT_PRI_DFLT_ACTION(action1.ut_inner); 8922 #undef PKT_PRI_DFLT_ACTION 8923 } else { 8924 soc_mem_field32_set(unit, mem, vent_ptr, NEW_OPRIf, 8925 action->priority); 8926 soc_mem_field32_set(unit, mem, vent_ptr, NEW_OCFIf, 8927 action->new_outer_cfi); 8928 soc_mem_field32_set(unit, mem, vent_ptr, NEW_IPRIf, 8929 action->new_inner_pkt_prio); 8930 soc_mem_field32_set(unit, mem, vent_ptr, NEW_ICFIf, 8931 action->new_inner_cfi); 8932 } 8933 BCM_IF_ERROR_RETURN 8934 (_bcm_trx_egr_vlan_action_profile_entry_add(unit, &action1, 8935 &profile_idx)); 8936 } else { 8937 if (action->priority >= BCM_PRIO_MIN && 8938 action->priority <= BCM_PRIO_MAX) { 8939 soc_mem_field32_set(unit, mem, vent_ptr, RPEf, 1); 8940 soc_mem_field32_set(unit, mem, vent_ptr, PRIf, 8941 action->priority); 8942 if (bcmVlanActionNone != action->it_inner_prio || 8943 bcmVlanActionNone != action->dt_inner_prio) { 8944 soc_mem_field32_set(unit, mem, vent_ptr, NEW_IRPEf, 1); 8945 soc_mem_field32_set(unit, mem, vent_ptr, NEW_IPRIf, 8946 action->priority); 8947 } 8948 } 8949 BCM_IF_ERROR_RETURN 8950 (_bcm_trx_egr_vlan_action_profile_entry_add(unit, action, 8951 &profile_idx)); 8952 } 8953 soc_mem_field32_set(unit, mem, vent_ptr, TAG_ACTION_PROFILE_PTRf, 8954 profile_idx); 8955 soc_mem_field32_set(unit, mem, vent_ptr, NEW_OTAG_VPTAG_SELf, 0); 8956 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 8957 if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf) && 8958 (action->class_id)) { 8959 soc_mem_field32_set(unit, mem, vent_ptr, CLASS_IDf, action->class_id); 8960 soc_mem_field32_set(unit, mem, vent_ptr, CLASS_ID_VALIDf,1); 8961 } 8962 #endif 8963 if (soc_feature(unit, soc_feature_base_valid)) { 8964 soc_mem_field32_set(unit, mem, vent_ptr, BASE_VALID_0f, 3); 8965 soc_mem_field32_set(unit, mem, vent_ptr, BASE_VALID_1f, 7); 8966 } else { 8967 soc_mem_field32_set(unit, mem, vent_ptr, VALIDf, 1); 8968 } 8969 8970 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 8971 if (inner_vlan == BCM_VLAN_INVALID) { 8972 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, vent_ptr, 8973 field_info_1, entry); 8974 /* Restore the old pointer */ 8975 vent_ptr = vent_tmp_p; 8976 /* Update the whole XLATE_DATAf for VLAN_XLATE_VFI and VFI_DVP view. */ 8977 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, vent_ptr, 8978 field_info, entry); 8979 if (soc_feature(unit, soc_feature_base_valid)) { 8980 soc_mem_field32_set(unit, mem, vent_ptr, BASE_VALID_0f, 3); 8981 soc_mem_field32_set(unit, mem, vent_ptr, BASE_VALID_1f, 7); 8982 } else { 8983 soc_mem_field32_set(unit, mem, vent_ptr, VALIDf, 1); 8984 } 8985 } 8986 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 8987 #if defined(BCM_TSN_SR_SUPPORT) 8988 if (soc_feature(unit, soc_feature_tsn_sr)) { 8989 if ((!(action->flags & BCM_VLAN_ACTION_SET_SR_ENABLE)) && 8990 (action->flags & BCM_VLAN_ACTION_SET_SR_LAN_ID)) { 8991 return BCM_E_PARAM; 8992 } 8993 8994 if (action->flags & BCM_VLAN_ACTION_SET_SR_ENABLE) { 8995 soc_mem_field32_set(unit, mem, vent_ptr, SR_ENABLEf, 1); 8996 soc_mem_field32_set(unit, mem, vent_ptr, SR_LAN_ID_VALIDf, 1); 8997 if (action->flags & BCM_VLAN_ACTION_SET_SR_LAN_ID) { 8998 soc_mem_field32_set(unit, mem, vent_ptr, SR_LAN_IDf, 1); 8999 } 9000 } else { 9001 soc_mem_field32_set(unit, mem, vent_ptr, SR_ENABLEf, 0); 9002 soc_mem_field32_set(unit, mem, vent_ptr, SR_LAN_ID_VALIDf, 0); 9003 } 9004 } 9005 #endif /* BCM_TSN_SR_SUPPORT*/ 9006 if (rv == SOC_E_NONE) { 9007 /* write back the existing one */ 9008 rv = soc_mem_write(unit, mem, 9009 MEM_BLOCK_ALL, index, vent_ptr); 9010 if (rv == SOC_E_NONE) { 9011 /* Preserve ref_count for default profile in case deleting old profile */ 9012 if (old_profile_idx == EGR_ACTION_PROFILE_DEFAULT) { 9013 soc_profile_mem_reference(unit, egr_action_profile[unit], 9014 EGR_ACTION_PROFILE_DEFAULT, 1); 9015 } 9016 rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit, 9017 old_profile_idx); 9018 } 9019 } else { 9020 /* insert new one */ 9021 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent_ptr); 9022 } 9023 soc_mem_unlock(unit, mem); 9024 9025 return rv; 9026 } 9027 9028 /* 9029 * Function: 9030 * _bcm_trx_vlan_translate_egress_action_get 9031 * Purpose: 9032 * Get an egress vlan translate entry. 9033 * Parameters: 9034 * unit (IN) BCM unit number 9035 * port_class (IN) Group ID of ingress port 9036 * old_vid (IN) Packet old VLAN ID to match 9037 * new_vid (OUT) Packet new VLAN ID 9038 * prio (OUT) Translation priority 9039 */ 9040 extern int 9041 _bcm_trx_vlan_translate_egress_action_get(int unit, int port_class, 9042 bcm_vlan_t outer_vlan, 9043 bcm_vlan_t inner_vlan, 9044 bcm_vlan_action_set_t *action) 9045 { 9046 egr_vlan_xlate_entry_t evx_ent; 9047 egr_vlan_xlate_entry_t res_evx_ent; 9048 9049 egr_vlan_xlate_1_double_entry_t evx1d_ent; 9050 egr_vlan_xlate_1_double_entry_t res_evx1d_ent; 9051 9052 int rv; 9053 int idx = 0, profile_idx; 9054 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9055 uint32 entry[SOC_MAX_MEM_WORDS]; 9056 soc_field_info_t *field_info = NULL, *field_info_1 = NULL; 9057 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 9058 9059 void *vent = &evx_ent; 9060 void *res_vent = &res_evx_ent; 9061 soc_mem_t mem = EGR_VLAN_XLATEm; 9062 uint32 ent_sz = sizeof(egr_vlan_xlate_entry_t); 9063 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 9064 mem = EGR_VLAN_XLATE_1_DOUBLEm; 9065 ent_sz = sizeof(egr_vlan_xlate_1_double_entry_t); 9066 vent = &evx1d_ent; 9067 res_vent = &res_evx1d_ent; 9068 } 9069 9070 BCM_IF_ERROR_RETURN 9071 (_bcm_trx_vlan_translate_egress_entry_assemble(unit, vent, 9072 port_class, 9073 outer_vlan, 9074 inner_vlan)); 9075 9076 sal_memset(res_vent, 0, ent_sz); 9077 soc_mem_lock(unit, mem); 9078 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, 9079 vent, res_vent, 0); 9080 soc_mem_unlock(unit, mem); 9081 BCM_IF_ERROR_RETURN(rv); 9082 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9083 if (inner_vlan == BCM_VLAN_INVALID) { 9084 sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32)); 9085 if (BCM_GPORT_IS_SET(port_class) && 9086 !BCM_GPORT_IS_MODPORT(port_class)) { 9087 field_info = soc_mem_fieldinfo_get(unit, mem, 9088 VLAN_XLATE_VFI__XLATE_DATAf); 9089 } else { 9090 field_info = soc_mem_fieldinfo_get(unit, mem, 9091 VFI_DVP_GROUP__XLATE_DATAf); 9092 } 9093 if (!field_info) { 9094 return BCM_E_UNAVAIL; 9095 } 9096 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, res_vent, 9097 field_info, entry); 9098 field_info_1 = soc_mem_fieldinfo_get(unit, mem, 9099 XLATE_DATAf); 9100 if (!field_info_1) { 9101 return BCM_E_UNAVAIL; 9102 } 9103 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, res_vent, 9104 field_info_1, entry); 9105 } 9106 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 9107 profile_idx = soc_mem_field32_get(unit, mem, res_vent, 9108 TAG_ACTION_PROFILE_PTRf); 9109 _bcm_trx_egr_vlan_action_profile_entry_get(unit, action, profile_idx); 9110 9111 BCM_IF_ERROR_RETURN( 9112 _bcm_trx_vlan_translate_entry_parse(unit, mem, 9113 (uint32 *)res_vent, action)); 9114 return BCM_E_NONE; 9115 } 9116 9117 /* 9118 * Function: 9119 * bcm_vlan_translate_egress_action_delete 9120 * Purpose: 9121 * Delete an egress vlan translate lookup entry. 9122 * Parameters: 9123 * unit (IN) BCM unit number 9124 * port_class (IN) Group ID of ingress port 9125 * outer_vlan (IN) Packet outer VLAN ID 9126 * inner_vlan (IN) Packet inner VLAN ID 9127 */ 9128 int 9129 _bcm_trx_vlan_translate_egress_action_delete(int unit, int port_class, 9130 bcm_vlan_t outer_vlan, 9131 bcm_vlan_t inner_vlan) 9132 { 9133 egr_vlan_xlate_entry_t evx_ent; 9134 egr_vlan_xlate_1_double_entry_t evx1d_ent; 9135 int rv; 9136 uint32 profile_idx; 9137 void *vent = (void *)&evx_ent; 9138 soc_mem_t mem = EGR_VLAN_XLATEm; 9139 soc_field_t vld_fld = VALIDf; 9140 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9141 uint32 entry[SOC_MAX_MEM_WORDS]; 9142 soc_field_info_t *field_info = NULL, *field_info_1 = NULL; 9143 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 9144 9145 #if defined(BCM_TRIUMPH2_SUPPORT) 9146 _bcm_flex_stat_handle_t handle; 9147 _BCM_FLEX_STAT_HANDLE_CLEAR(handle); 9148 #endif 9149 9150 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 9151 mem = EGR_VLAN_XLATE_1_DOUBLEm; 9152 vld_fld = BASE_VALID_0f; 9153 vent = (void *)&evx1d_ent; 9154 } 9155 9156 BCM_IF_ERROR_RETURN 9157 (_bcm_trx_vlan_translate_egress_entry_assemble(unit, vent, 9158 port_class, 9159 outer_vlan, 9160 inner_vlan)); 9161 9162 #if defined(BCM_TRIUMPH2_SUPPORT) 9163 if (soc_feature(unit, soc_feature_gport_service_counters)) { 9164 /* Record flex stat info before the returned entry 9165 * includes non-key info. */ 9166 9167 memcpy(&handle, vent, sizeof(_bcm_flex_stat_handle_t)); 9168 } 9169 #endif 9170 9171 rv = soc_mem_delete_return_old(unit, mem, MEM_BLOCK_ALL, vent, vent); 9172 if ((rv == SOC_E_NONE) && soc_mem_field32_get(unit, mem, vent, vld_fld)) { 9173 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9174 if (inner_vlan == BCM_VLAN_INVALID) { 9175 sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32)); 9176 if (BCM_GPORT_IS_SET(port_class) && 9177 !BCM_GPORT_IS_MODPORT(port_class)) { 9178 field_info = soc_mem_fieldinfo_get(unit, mem, 9179 VLAN_XLATE_VFI__XLATE_DATAf); 9180 } else { 9181 field_info = soc_mem_fieldinfo_get(unit, mem, 9182 VFI_DVP_GROUP__XLATE_DATAf); 9183 } 9184 if (!field_info) { 9185 return BCM_E_UNAVAIL; 9186 } 9187 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, vent, 9188 field_info, entry); 9189 field_info_1 = soc_mem_fieldinfo_get(unit, mem, 9190 XLATE_DATAf); 9191 if (!field_info_1) { 9192 return BCM_E_UNAVAIL; 9193 } 9194 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, vent, 9195 field_info_1, entry); 9196 } 9197 #endif 9198 profile_idx = soc_mem_field32_get(unit, mem, vent, 9199 TAG_ACTION_PROFILE_PTRf); 9200 /* Preserve ref_count for default profile in case deleting old profile */ 9201 if (profile_idx == EGR_ACTION_PROFILE_DEFAULT) { 9202 soc_profile_mem_reference(unit, egr_action_profile[unit], 9203 EGR_ACTION_PROFILE_DEFAULT, 1); 9204 } 9205 /* Delete the old vlan action profile entry */ 9206 rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx); 9207 9208 #if defined(BCM_TRIUMPH2_SUPPORT) 9209 if (soc_feature(unit, soc_feature_gport_service_counters) && 9210 (0 != soc_mem_field32_get(unit, mem, vent, VINTF_CTR_IDXf))) { 9211 /* Release Service counter */ 9212 _bcm_esw_flex_stat_ext_handle_free(unit, _bcmFlexStatTypeVxlt, 9213 handle); 9214 } 9215 #endif 9216 } 9217 return rv; 9218 } 9219 9220 /* 9221 * Function: 9222 * bcm_vlan_translate_egress_action_delete_all 9223 * Purpose: 9224 * Delete all egress vlan translate lookup entries. 9225 * Parameters: 9226 * unit (IN) BCM unit number 9227 * Returns: 9228 * BCM_E_XXX 9229 */ 9230 int 9231 _bcm_trx_vlan_translate_egress_action_delete_all(int unit) 9232 { 9233 int i, imin, imax, nent, vbytes, rv; 9234 uint32 old_profile_idx; 9235 void *vtab, *vtabp, *vnull; 9236 #if defined(BCM_TRIUMPH2_SUPPORT) 9237 _bcm_flex_stat_handle_t handle; 9238 egr_vlan_xlate_entry_t vent; 9239 uint32 key[2]; 9240 #endif 9241 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9242 uint32 entry[SOC_MAX_MEM_WORDS]; 9243 soc_field_info_t *field_info = NULL, *field_info_1 = NULL; 9244 int type; 9245 soc_field_t type_fld = ENTRY_TYPEf; 9246 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 9247 int rv1 = BCM_E_NONE; /* To capture first failure in loop */ 9248 soc_mem_t mem = EGR_VLAN_XLATEm; 9249 soc_field_t vld_fld = VALIDf; 9250 uint32 ent_sz = sizeof(egr_vlan_xlate_entry_t); 9251 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 9252 mem = EGR_VLAN_XLATE_1_DOUBLEm; 9253 vld_fld = BASE_VALID_0f; 9254 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9255 type_fld = KEY_TYPEf; 9256 #endif 9257 ent_sz = sizeof(egr_vlan_xlate_1_double_entry_t); 9258 } 9259 imin = soc_mem_index_min(unit, mem); 9260 imax = soc_mem_index_max(unit, mem); 9261 nent = soc_mem_index_count(unit, mem); 9262 vbytes = soc_mem_entry_words(unit, mem); 9263 9264 vbytes = WORDS2BYTES(vbytes); 9265 vtab = soc_cm_salloc(unit, nent * ent_sz, "egr_vlan_xlate"); 9266 9267 if (vtab == NULL) { 9268 return BCM_E_MEMORY; 9269 } 9270 9271 vnull = soc_mem_entry_null(unit, mem); 9272 9273 soc_mem_lock(unit, mem); 9274 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 9275 imin, imax, vtab); 9276 if (rv < 0) { 9277 soc_mem_unlock(unit, mem); 9278 soc_cm_sfree(unit, vtab); 9279 return rv; 9280 } 9281 9282 for(i = 0; i < nent; i++) { 9283 9284 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 9285 vtabp = soc_mem_table_idx_to_pointer(unit, mem, 9286 egr_vlan_xlate_1_double_entry_t *, vtab, i); 9287 } else { 9288 vtabp = soc_mem_table_idx_to_pointer(unit, mem, 9289 egr_vlan_xlate_entry_t *, vtab, i); 9290 } 9291 9292 if (!soc_mem_field32_get(unit, mem, vtabp, vld_fld)) { 9293 continue; 9294 } 9295 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9296 type = soc_mem_field32_get(unit, mem, vtabp, type_fld); 9297 if (type == TD2PLUS_EVLXLT_HASH_KEY_TYPE_VFI_DVP_GROUP) { 9298 field_info = soc_mem_fieldinfo_get(unit, mem, 9299 VFI_DVP_GROUP__XLATE_DATAf); 9300 } else if (type == TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI) { 9301 field_info = soc_mem_fieldinfo_get(unit, mem, 9302 VLAN_XLATE_VFI__XLATE_DATAf); 9303 } 9304 9305 if (field_info) { 9306 sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32)); 9307 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, vtabp, 9308 field_info, entry); 9309 field_info_1 = soc_mem_fieldinfo_get(unit, mem, 9310 XLATE_DATAf); 9311 if (!field_info_1) { 9312 return BCM_E_UNAVAIL; 9313 } 9314 SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, vtabp, 9315 field_info_1, entry); 9316 } 9317 #endif 9318 old_profile_idx = 9319 soc_mem_field32_get(unit, mem, vtabp, 9320 TAG_ACTION_PROFILE_PTRf); 9321 9322 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, i, vnull); 9323 9324 /* Delete the old vlan action profile entry */ 9325 if (rv == SOC_E_NONE) { 9326 /* Preserve ref_count for default profile in case deleting old profile*/ 9327 if (old_profile_idx == EGR_ACTION_PROFILE_DEFAULT) { 9328 soc_profile_mem_reference(unit, egr_action_profile[unit], 9329 EGR_ACTION_PROFILE_DEFAULT, 1); 9330 } 9331 rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit, 9332 old_profile_idx); 9333 if (BCM_FAILURE(rv) && BCM_SUCCESS(rv1)) { 9334 rv1 = rv; 9335 } 9336 #if defined(BCM_TRIUMPH2_SUPPORT) 9337 if (soc_feature(unit, soc_feature_gport_service_counters) && 9338 (0 != soc_mem_field32_get(unit, mem, vtabp, VINTF_CTR_IDXf))) { 9339 sal_memset(&vent, 0, sizeof(vent)); 9340 /* Construct key-only entry, copy to FS handle */ 9341 soc_mem_field32_set(unit, mem, &vent, ENTRY_TYPEf, 9342 soc_mem_field32_get(unit, mem, vtabp, ENTRY_TYPEf)); 9343 soc_mem_field_get(unit, mem, (uint32 *) vtabp, 9344 KEYf, (uint32 *) key); 9345 soc_mem_field_set(unit, mem, (uint32 *) &vent, 9346 KEYf, (uint32 *) key); 9347 9348 _BCM_FLEX_STAT_HANDLE_CLEAR(handle); 9349 _BCM_FLEX_STAT_HANDLE_COPY(handle, vent); 9350 9351 /* Release Service counter */ 9352 _bcm_esw_flex_stat_ext_handle_free(unit, _bcmFlexStatTypeVxlt, 9353 handle); 9354 } 9355 #endif 9356 } else if (BCM_SUCCESS(rv1)) { 9357 rv1 = rv; 9358 } 9359 } 9360 9361 soc_mem_unlock(unit, mem); 9362 soc_cm_sfree(unit, vtab); 9363 return rv1; 9364 } 9365 9366 /* 9367 * Function : 9368 * _bcm_trx_vlan_translate_old_vlan_get 9369 * Description : 9370 * Helper function to get an old vid from vlan translate entry 9371 * Parameters : 9372 * unit (IN) BCM unit number 9373 * mem (IN) Vlan translate memory id. 9374 * vent (IN) Vlan translate entry 9375 * key_type (IN) Key type to determine which old vid to get 9376 * outer_vlan (OUT) outer vlan to retrieve 9377 * inner_vlan (OUT) inner vlan to retrieve 9378 */ 9379 9380 STATIC int 9381 _bcm_trx_vlan_translate_old_vlan_get(int unit, soc_mem_t mem, 9382 uint32 *vent, uint32 key_type, 9383 bcm_vlan_t *outer_vlan, 9384 bcm_vlan_t *inner_vlan) 9385 { 9386 bcm_vlan_t tmp_o_vlan = BCM_VLAN_INVALID; 9387 bcm_vlan_t tmp_i_vlan = BCM_VLAN_INVALID; 9388 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9389 soc_field_t type_field = ENTRY_TYPEf; 9390 soc_mem_t egr_mem = EGR_VLAN_XLATEm; 9391 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 9392 egr_mem = EGR_VLAN_XLATE_1_DOUBLEm; 9393 type_field = KEY_TYPEf; 9394 } 9395 #endif 9396 9397 /* Input parameters check. */ 9398 if ((NULL == vent) || (NULL == outer_vlan) || 9399 (INVALIDm == mem) || (NULL == inner_vlan)) { 9400 return (BCM_E_PARAM); 9401 } 9402 9403 switch (key_type) { 9404 case bcmVlanTranslateKeyDouble: 9405 case bcmVlanTranslateKeyPortDouble: 9406 case bcmVlanTranslateKeyPortGroupDouble: 9407 case bcmVlanTranslateKeyCapwapPayloadDouble: 9408 case bcmVlanTranslateKeyPortCapwapPayloadDouble: 9409 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9410 if ((mem == egr_mem) && soc_feature(unit, soc_feature_vp_sharing) && 9411 (soc_mem_field32_get_def(unit, mem, vent, type_field, FALSE) == 9412 TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI)) { 9413 _BCM_VPN_SET(tmp_o_vlan, _BCM_VPN_TYPE_VFI, 9414 soc_mem_field32_get(unit, mem, vent, VLAN_XLATE_VFI__VFIf)); 9415 tmp_i_vlan = BCM_VLAN_INVALID; 9416 } else 9417 #endif 9418 { 9419 tmp_o_vlan = soc_mem_field32_get(unit, mem, vent, OVIDf); 9420 tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, IVIDf); 9421 } 9422 break; 9423 case bcmVlanTranslateKeyOuterTag: 9424 case bcmVlanTranslateKeyPortOuterTag: 9425 case bcmVlanTranslateKeyPortGroupOuterTag: 9426 case bcmVlanTranslateKeyCapwapPayloadOuterTag: 9427 case bcmVlanTranslateKeyPortCapwapPayloadOuterTag: 9428 tmp_o_vlan = soc_mem_field32_get(unit, mem, vent, OTAGf); 9429 break; 9430 case bcmVlanTranslateKeyInnerTag: 9431 case bcmVlanTranslateKeyPortInnerTag: 9432 case bcmVlanTranslateKeyPortGroupInnerTag: 9433 case bcmVlanTranslateKeyCapwapPayloadInnerTag: 9434 case bcmVlanTranslateKeyPortCapwapPayloadInnerTag: 9435 tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, ITAGf); 9436 break; 9437 case bcmVlanTranslateKeyOuter: 9438 case bcmVlanTranslateKeyPortOuter: 9439 case bcmVlanTranslateKeyPortGroupOuter: 9440 case bcmVlanTranslateKeyCapwapPayloadOuter: 9441 case bcmVlanTranslateKeyPortCapwapPayloadOuter: 9442 tmp_o_vlan = soc_mem_field32_get(unit, mem, vent, OVIDf); 9443 break; 9444 case bcmVlanTranslateKeyInner: 9445 case bcmVlanTranslateKeyPortInner: 9446 case bcmVlanTranslateKeyPortGroupInner: 9447 case bcmVlanTranslateKeyCapwapPayloadInner: 9448 case bcmVlanTranslateKeyPortCapwapPayloadInner: 9449 tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, IVIDf); 9450 break; 9451 case bcmVlanTranslateKeyPortPonTunnel: 9452 case bcmVlanTranslateKeyPortPonTunnelOuter: 9453 case bcmVlanTranslateKeyPortPonTunnelInner: 9454 if (!soc_feature(unit, soc_feature_lltag)) { 9455 return BCM_E_PARAM; 9456 } 9457 tmp_o_vlan = soc_mem_field32_get(unit, mem, vent, LLTAG__LLVIDf); 9458 if (key_type == bcmVlanTranslateKeyPortPonTunnelOuter) { 9459 tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, LLTAG__OVIDf); 9460 } else if (key_type == bcmVlanTranslateKeyPortPonTunnelInner) { 9461 tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, LLTAG__IVIDf); 9462 } 9463 break; 9464 default: 9465 return BCM_E_PARAM; 9466 } 9467 9468 *outer_vlan = tmp_o_vlan; 9469 *inner_vlan = tmp_i_vlan; 9470 9471 return BCM_E_NONE; 9472 } 9473 9474 /* 9475 * Function : 9476 * _bcm_trx_vlan_translate_gport_get 9477 * Description : 9478 * Helper function to get a gport from vlan translate entry 9479 * Parameters : 9480 * unit (IN) BCM unit number 9481 * mem (IN) Vlan translate memory id. 9482 * vent (IN) Vlan translate entry 9483 * gport (OUT) gport to retrieve 9484 */ 9485 9486 STATIC int 9487 _bcm_trx_vlan_translate_gport_get(int unit, soc_mem_t mem, 9488 uint32 *vent, bcm_gport_t *gport) 9489 { 9490 bcm_gport_t tmp_gport = 0; 9491 uint32 modid; 9492 uint32 port; 9493 int glp_wildcard; 9494 9495 9496 /* Input parameters check. */ 9497 if ((NULL == vent) || (NULL == gport) || (INVALIDm == mem)) { 9498 return (BCM_E_PARAM); 9499 } 9500 9501 glp_wildcard = (soc_mem_field32_get(unit, mem, vent, GLPf) == 9502 SOC_VLAN_XLATE_GLP_WILDCARD(unit)); 9503 if (glp_wildcard) { 9504 tmp_gport = BCM_GPORT_INVALID; 9505 } else { 9506 if (soc_mem_field32_get(unit, mem, vent, Tf)) { 9507 port = soc_mem_field32_get(unit, mem, vent, TGIDf); 9508 BCM_GPORT_TRUNK_SET(tmp_gport, port); 9509 } else { 9510 port = soc_mem_field32_get(unit, mem, vent, PORT_NUMf); 9511 modid = soc_mem_field32_get(unit, mem, vent, MODULE_IDf); 9512 BCM_GPORT_MODPORT_SET(tmp_gport, modid, port); 9513 } 9514 } 9515 9516 *gport = tmp_gport; 9517 return BCM_E_NONE; 9518 } 9519 9520 /* 9521 * Function : 9522 * _bcm_trx_vlan_translate_key_type_get 9523 * Description : 9524 * Helper function to get a key_type from vlan translate entry 9525 * Parameters : 9526 * unit (IN) BCM unit number 9527 * mem (IN) Vlan translate memory id. 9528 * vent (IN) Vlan translate entry 9529 * key_type (OUT) Key type to retrieve 9530 */ 9531 9532 STATIC int 9533 _bcm_trx_vlan_translate_key_type_get(int unit, soc_mem_t mem, 9534 uint32 *vent, uint32 *key_type) 9535 { 9536 uint32 key_val, glp_wildcard; 9537 int vt_key; 9538 uint32 source_type = 0; 9539 9540 /* Input parameters check. */ 9541 if ((NULL == vent) || (NULL == key_type) || (INVALIDm == mem)) { 9542 return (BCM_E_PARAM); 9543 } 9544 9545 #ifdef BCM_TRIUMPH3_SUPPORT 9546 if (SOC_IS_TRIUMPH3(unit)) { 9547 if (mem == VLAN_XLATE_EXTDm) { 9548 key_val = soc_mem_field32_get(unit, mem, vent, KEY_TYPE_0f); 9549 key_val &= ~1; /*remove extd entry indication */ 9550 } else { 9551 key_val = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf); 9552 } 9553 } else 9554 #endif /* BCM_TRIUMPH3_SUPPORT */ 9555 { 9556 key_val = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf); 9557 } 9558 glp_wildcard = (soc_mem_field32_get(unit, mem, vent, GLPf) == 9559 SOC_VLAN_XLATE_GLP_WILDCARD(unit)); 9560 if ((mem == VLAN_XLATEm) && SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 9561 source_type = soc_mem_field32_get(unit, mem, vent, SOURCE_TYPEf); 9562 } 9563 BCM_IF_ERROR_RETURN 9564 (_bcm_esw_vlan_xlate_key_type_get(unit,key_val,&vt_key)); 9565 switch (vt_key) { 9566 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 9567 { 9568 if (source_type == 3) { 9569 *key_type = bcmVlanTranslateKeyPortGroupDouble; 9570 } else if (glp_wildcard) { 9571 *key_type = bcmVlanTranslateKeyDouble; 9572 } else { 9573 *key_type = bcmVlanTranslateKeyPortDouble; 9574 } 9575 break; 9576 } 9577 case VLXLT_HASH_KEY_TYPE_OTAG: 9578 { 9579 if (source_type == 3) { 9580 *key_type = bcmVlanTranslateKeyPortGroupOuterTag; 9581 } else if (glp_wildcard) { 9582 *key_type = bcmVlanTranslateKeyOuterTag; 9583 } else { 9584 *key_type = bcmVlanTranslateKeyPortOuterTag; 9585 } 9586 break; 9587 } 9588 case VLXLT_HASH_KEY_TYPE_ITAG: 9589 { 9590 if (source_type == 3) { 9591 *key_type = bcmVlanTranslateKeyPortGroupInnerTag; 9592 } else if (glp_wildcard) { 9593 *key_type = bcmVlanTranslateKeyInnerTag; 9594 } else { 9595 *key_type = bcmVlanTranslateKeyPortInnerTag; 9596 } 9597 break; 9598 } 9599 case VLXLT_HASH_KEY_TYPE_OVID: 9600 { 9601 if (source_type == 3) { 9602 *key_type = bcmVlanTranslateKeyPortGroupOuter; 9603 } else if (glp_wildcard) { 9604 *key_type = bcmVlanTranslateKeyOuter; 9605 } else { 9606 *key_type = bcmVlanTranslateKeyPortOuter; 9607 } 9608 break; 9609 } 9610 case VLXLT_HASH_KEY_TYPE_IVID: 9611 { 9612 if (source_type == 3) { 9613 *key_type = bcmVlanTranslateKeyPortGroupInner; 9614 } else if (glp_wildcard) { 9615 *key_type = bcmVlanTranslateKeyInner; 9616 } else { 9617 *key_type = bcmVlanTranslateKeyPortInner; 9618 } 9619 break; 9620 } 9621 case VLXLT_HASH_KEY_TYPE_LLVID: 9622 { 9623 if (glp_wildcard) { 9624 return BCM_E_NOT_FOUND; 9625 } else { 9626 *key_type = bcmVlanTranslateKeyPortPonTunnel; 9627 } 9628 break; 9629 } 9630 case VLXLT_HASH_KEY_TYPE_LLVID_OVID: 9631 { 9632 if (glp_wildcard) { 9633 return BCM_E_NOT_FOUND; 9634 } else { 9635 *key_type = bcmVlanTranslateKeyPortPonTunnelOuter; 9636 } 9637 break; 9638 } 9639 case VLXLT_HASK_KEY_TYPE_LLVID_IVID: 9640 { 9641 if (glp_wildcard) { 9642 return BCM_E_NOT_FOUND; 9643 } else { 9644 *key_type = bcmVlanTranslateKeyPortPonTunnelInner; 9645 } 9646 break; 9647 } 9648 break; 9649 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID: 9650 { 9651 if (glp_wildcard) { 9652 *key_type = bcmVlanTranslateKeyCapwapPayloadDouble; 9653 } else { 9654 *key_type = bcmVlanTranslateKeyPortCapwapPayloadDouble; 9655 } 9656 break; 9657 } 9658 break; 9659 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG: 9660 { 9661 if (glp_wildcard) { 9662 *key_type = bcmVlanTranslateKeyCapwapPayloadOuterTag; 9663 } else { 9664 *key_type = bcmVlanTranslateKeyPortCapwapPayloadOuterTag; 9665 } 9666 break; 9667 } 9668 break; 9669 case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG: 9670 { 9671 if (glp_wildcard) { 9672 *key_type = bcmVlanTranslateKeyCapwapPayloadInnerTag; 9673 } else { 9674 *key_type = bcmVlanTranslateKeyPortCapwapPayloadInnerTag; 9675 } 9676 break; 9677 } 9678 break; 9679 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID: 9680 { 9681 if (glp_wildcard) { 9682 *key_type = bcmVlanTranslateKeyCapwapPayloadOuter; 9683 } else { 9684 *key_type = bcmVlanTranslateKeyPortCapwapPayloadOuter; 9685 } 9686 break; 9687 } 9688 break; 9689 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID: 9690 { 9691 if (glp_wildcard) { 9692 *key_type = bcmVlanTranslateKeyCapwapPayloadInner; 9693 } else { 9694 *key_type = bcmVlanTranslateKeyPortCapwapPayloadInner; 9695 } 9696 break; 9697 } 9698 break; 9699 default: 9700 return BCM_E_NOT_FOUND; 9701 break; 9702 } 9703 9704 return BCM_E_NONE; 9705 } 9706 9707 /* 9708 * Function : 9709 * _bcm_trx_vlan_translate_parse 9710 * Description : 9711 * Helper function for an API to parse a vlan translate 9712 * entry for Triumph and call given call back. 9713 * Parameters : 9714 * unit (IN) BCM unit number 9715 * mem (IN) Vlan translation memory id. 9716 * vent (IN) HW entry. 9717 * trvs_info (IN/OUT) Traverse structure that contain all relevant info 9718 */ 9719 int 9720 _bcm_trx_vlan_translate_parse(int unit, soc_mem_t mem, uint32 *vent, 9721 _bcm_vlan_translate_traverse_t *trvs_info) 9722 { 9723 uint32 profile_idx = 0; /* Vlan profile index. */ 9724 soc_mem_t egr_mem = EGR_VLAN_XLATEm; 9725 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9726 soc_field_t type_field = ENTRY_TYPEf; 9727 #endif 9728 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 9729 soc_mem_t ing_mem = VLAN_XLATEm; 9730 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 9731 ing_mem = VLAN_XLATE_1_DOUBLEm; 9732 } 9733 9734 if (soc_feature(unit, soc_feature_niv) && (mem == ing_mem)) { 9735 uint32 key_val; 9736 int vt_key; 9737 int vif_hit = TRUE; 9738 int niv_port_id; 9739 int vp; 9740 9741 key_val = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf); 9742 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_xlate_key_type_get(unit, 9743 key_val,&vt_key)); 9744 switch (vt_key) { 9745 case VLXLT_HASH_KEY_TYPE_VIF_OTAG: 9746 trvs_info->key_type = bcmVlanTranslateKeyPortOuterTag; 9747 trvs_info->outer_vlan = soc_mem_field32_get(unit, mem, 9748 vent, VIF__OTAGf); 9749 break; 9750 9751 case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 9752 trvs_info->key_type = bcmVlanTranslateKeyPortInnerTag; 9753 trvs_info->inner_vlan = soc_mem_field32_get(unit, mem, 9754 vent, VIF__ITAGf); 9755 break; 9756 9757 case VLXLT_HASH_KEY_TYPE_VIF_VLAN: 9758 trvs_info->key_type = bcmVlanTranslateKeyPortOuter; 9759 trvs_info->outer_vlan = soc_mem_field32_get(unit, mem, 9760 vent, VIF__VLANf); 9761 break; 9762 9763 case VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 9764 trvs_info->key_type = bcmVlanTranslateKeyPortInner; 9765 trvs_info->inner_vlan = soc_mem_field32_get(unit, mem, 9766 vent, VIF__CVLANf); 9767 break; 9768 default: 9769 vif_hit = FALSE; 9770 break; 9771 } 9772 if (vif_hit == TRUE) { 9773 vp = soc_mem_field32_get(unit, mem, vent, VIF__SOURCE_VPf); 9774 BCM_GPORT_NIV_PORT_ID_SET(niv_port_id, vp); 9775 profile_idx = soc_mem_field32_get(unit, mem, vent, 9776 VIF__TAG_ACTION_PROFILE_PTRf); 9777 _bcm_trx_vlan_action_profile_entry_get(unit, trvs_info->action, 9778 profile_idx); 9779 trvs_info->gport = niv_port_id; 9780 BCM_IF_ERROR_RETURN(_bcm_trx_vif_vlan_translate_entry_parse(unit, 9781 mem, vent, trvs_info->action)); 9782 return BCM_E_NONE; 9783 } 9784 } 9785 #endif /* defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) */ 9786 9787 profile_idx = soc_mem_field32_get(unit, mem, vent, 9788 TAG_ACTION_PROFILE_PTRf); 9789 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9790 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 9791 egr_mem = EGR_VLAN_XLATE_1_DOUBLEm; 9792 type_field = KEY_TYPEf; 9793 } 9794 #endif 9795 if (mem == egr_mem) { 9796 _bcm_trx_egr_vlan_action_profile_entry_get(unit, 9797 trvs_info->action, 9798 profile_idx); 9799 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9800 if (soc_feature(unit, soc_feature_vp_sharing) && 9801 (soc_mem_field32_get_def(unit, mem, vent, type_field, FALSE) == 9802 TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI)) { 9803 int dvp = 0; 9804 dvp = soc_mem_field32_get(unit, mem, vent, VLAN_XLATE_VFI__DVPf); 9805 if (_bcm_vp_used_get(unit, dvp, _bcmVpTypeVxlan)) { 9806 BCM_GPORT_VXLAN_PORT_ID_SET(trvs_info->port_class, dvp); 9807 } 9808 } else 9809 #endif 9810 { 9811 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9812 if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) { 9813 if (soc_mem_field32_get(unit, mem, vent, PORT_TYPE_DGPPf)) { 9814 bcm_module_t modid = 9815 soc_mem_field32_get(unit, mem, vent, DST_MODIDf); 9816 bcm_port_t port = 9817 soc_mem_field32_get(unit, mem, vent, DST_PORTf); 9818 9819 BCM_GPORT_MODPORT_SET(trvs_info->port_class, modid, port); 9820 } else { 9821 trvs_info->port_class = 9822 soc_mem_field32_get(unit, mem, vent, PORT_GROUP_IDf); 9823 } 9824 } else 9825 #endif 9826 { 9827 trvs_info->port_class = 9828 soc_mem_field32_get(unit, mem, vent, PORT_GROUP_IDf); 9829 } 9830 } 9831 trvs_info->gport = BCM_GPORT_INVALID; 9832 9833 trvs_info->key_type = bcmVlanTranslateKeyPortDouble; 9834 } else { 9835 _bcm_trx_vlan_action_profile_entry_get(unit, trvs_info->action, 9836 profile_idx); 9837 9838 BCM_IF_ERROR_RETURN( 9839 _bcm_trx_vlan_translate_key_type_get(unit, mem, vent, 9840 &(trvs_info->key_type))); 9841 BCM_IF_ERROR_RETURN( 9842 _bcm_trx_vlan_translate_gport_get(unit, mem, vent, 9843 &(trvs_info->gport))); 9844 trvs_info->port_class = BCM_GPORT_INVALID; 9845 } 9846 9847 BCM_IF_ERROR_RETURN( 9848 _bcm_trx_vlan_translate_entry_parse(unit, mem, vent, 9849 trvs_info->action)); 9850 9851 return _bcm_trx_vlan_translate_old_vlan_get(unit, mem, vent, 9852 trvs_info->key_type, 9853 &(trvs_info->outer_vlan), 9854 &(trvs_info->inner_vlan)); 9855 } 9856 9857 /* 9858 * VLAN PORT PROTOCOL 9859 */ 9860 9861 /* 9862 * Function: 9863 * _bcm_trx_vlan_port_protocol_entry_parse 9864 * Purpose: 9865 * Parses VLAN protocol entry and extracts frame type and ethertype 9866 * Parameters: 9867 * unit - (IN) BCM Device unit 9868 * vpe - (IN) VLAN protocol entry to parse 9869 * frame - (OUT) Frame type from the entry 9870 * ether - (IN) Ethertype from the entry 9871 * Returns: 9872 * None 9873 */ 9874 STATIC void 9875 _bcm_trx_vlan_port_protocol_entry_parse(int unit, vlan_protocol_entry_t *vpe, 9876 bcm_port_frametype_t *frame, 9877 bcm_port_ethertype_t *ether) 9878 { 9879 *frame = 0; 9880 if (soc_VLAN_PROTOCOLm_field32_get(unit, vpe, ETHERIIf)) { 9881 *frame |= BCM_PORT_FRAMETYPE_ETHER2; 9882 } 9883 if (soc_VLAN_PROTOCOLm_field32_get(unit, vpe, SNAPf)) { 9884 *frame |= BCM_PORT_FRAMETYPE_8023; 9885 } 9886 if (soc_VLAN_PROTOCOLm_field32_get(unit, vpe, LLCf)) { 9887 *frame |= BCM_PORT_FRAMETYPE_LLC; 9888 } 9889 *ether = soc_VLAN_PROTOCOLm_field32_get(unit, vpe, ETHERTYPEf); 9890 } 9891 9892 /* 9893 * Function: 9894 * _bcm_trx_vlan_port_prot_match_get 9895 * Purpose: 9896 * Get index into table with settings matching to port protocol 9897 * Parameters: 9898 * unit - (IN) BCM Device unit 9899 * frame - (IN) Frmae to match 9900 * ether - (IN) Ethertype to match 9901 * match_idx - (OUT) index to the table entry if match, -1 otherwise 9902 * Returns: 9903 * BCM_E_XXX 9904 */ 9905 int 9906 _bcm_trx_vlan_port_prot_match_get(int unit, bcm_port_frametype_t frame, 9907 bcm_port_ethertype_t ether, int *match_idx) 9908 { 9909 int i, idxmin, idxmax; 9910 vlan_protocol_entry_t vpe; 9911 bcm_port_frametype_t ft; 9912 bcm_port_ethertype_t et; 9913 9914 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 9915 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 9916 9917 *match_idx = -1; 9918 9919 for (i = idxmin; i <= idxmax; i++) { 9920 SOC_IF_ERROR_RETURN 9921 (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, i, &vpe)); 9922 _bcm_trx_vlan_port_protocol_entry_parse(unit, &vpe, &ft, &et); 9923 if (ft == frame && et == ether) { 9924 *match_idx = i; 9925 break; 9926 } 9927 } 9928 9929 return (*match_idx < 0) ? BCM_E_NOT_FOUND : BCM_E_NONE ; 9930 } 9931 9932 /* 9933 * Function: 9934 * _bcm_trx_vlan_port_prot_match_get 9935 * Purpose: 9936 * Get index into first empty entry in the table 9937 * Parameters: 9938 * unit - (IN) BCM Device unit 9939 * empty_idx - (OUT) index to the table entry if match, -1 otherwise 9940 * Returns: 9941 * BCM_E_XXX 9942 */ 9943 int 9944 _bcm_trx_vlan_port_prot_empty_get(int unit, int *empty_idx) 9945 { 9946 int i, idxmin, idxmax; 9947 vlan_protocol_entry_t vpe; 9948 bcm_port_frametype_t ft; 9949 9950 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 9951 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 9952 9953 *empty_idx = -1; 9954 9955 for (i = idxmin; i <= idxmax; i++) { 9956 SOC_IF_ERROR_RETURN 9957 (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, i, &vpe)); 9958 ft = 0; 9959 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, ETHERIIf)) { 9960 ft |= BCM_PORT_FRAMETYPE_ETHER2; 9961 } 9962 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, SNAPf)) { 9963 ft |= BCM_PORT_FRAMETYPE_8023; 9964 } 9965 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, LLCf)) { 9966 ft |= BCM_PORT_FRAMETYPE_LLC; 9967 } 9968 if (0 == ft) { 9969 *empty_idx = i; 9970 break; 9971 } 9972 } 9973 9974 return (*empty_idx < 0) ? BCM_E_FULL : BCM_E_NONE ; 9975 } 9976 9977 /* 9978 * Function : 9979 * _bcm_trx_vlan_protocol_data_entry_set 9980 * Description : 9981 * Helper function to set vlan_protocol_data entry 9982 * Parameters : 9983 * unit (IN) BCM unit number 9984 * ventry (IN / OUT) Entry to setup 9985 * action (IN) vlan action to be used 9986 * profile_idx (IN) profile index to set 9987 */ 9988 STATIC void 9989 _bcm_trx_vlan_protocol_data_entry_set(int unit, 9990 vlan_protocol_data_entry_t *ventry, 9991 bcm_vlan_action_set_t *action, 9992 int profile_idx) 9993 { 9994 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, OVIDf, 9995 action->new_outer_vlan); 9996 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, IVIDf, 9997 action->new_inner_vlan); 9998 9999 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 10000 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, OPRIf, 10001 action->priority); 10002 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, OCFIf, 10003 action->new_outer_cfi); 10004 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, IPRIf, 10005 action->new_inner_pkt_prio); 10006 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, ICFIf, 10007 action->new_inner_cfi); 10008 } else { 10009 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, PRIf, 10010 action->priority); 10011 } 10012 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, TAG_ACTION_PROFILE_PTRf, 10013 profile_idx); 10014 } 10015 10016 /* 10017 * Function : 10018 * _bcm_trx_vlan_protocol_data_entry_parse 10019 * Description : 10020 * Helper function to parse vlan_protocol_data entry into action 10021 * Parameters : 10022 * unit (IN) BCM unit number 10023 * ventry (IN) Entry to setup 10024 * action (OUT) vlan action to be used 10025 * profile_idx (OUT) profile index 10026 */ 10027 STATIC void 10028 _bcm_trx_vlan_protocol_data_entry_parse(int unit, 10029 vlan_protocol_data_entry_t *ventry, 10030 bcm_vlan_action_set_t *action, 10031 int *profile_idx) 10032 { 10033 action->new_outer_vlan = 10034 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, OVIDf); 10035 10036 action->new_inner_vlan = 10037 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, IVIDf); 10038 10039 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 10040 action->priority = 10041 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, OPRIf); 10042 action->new_outer_cfi = 10043 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, OCFIf); 10044 action->new_inner_pkt_prio = 10045 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, IPRIf); 10046 action->new_inner_cfi = 10047 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, ICFIf); 10048 } else { 10049 action->priority = 10050 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, PRIf); 10051 } 10052 *profile_idx = 10053 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, 10054 TAG_ACTION_PROFILE_PTRf); 10055 } 10056 10057 #ifdef BCM_WARM_BOOT_SUPPORT 10058 /* 10059 * Function: 10060 * _bcm_trx_vlan_port_protocol_action_reinit 10061 * Description: 10062 * Recover data for 'vd_pbvl' in port_info structure. 10063 * Parameters: 10064 * unit (IN) BCM unit number 10065 * Notes: 10066 * Assumes: 10067 * - 'vd_pbvl' data in port_info structure is clear 10068 * - 'vlan_prot_ptr' in port_info structure is initialized 10069 */ 10070 STATIC int 10071 _bcm_trx_vlan_port_protocol_action_reinit(int unit) 10072 { 10073 int idxmin, idxmax, i, data_idx; 10074 vlan_protocol_entry_t vpe; 10075 vlan_protocol_data_entry_t vde; 10076 bcm_port_frametype_t ft; 10077 bcm_port_ethertype_t et; 10078 bcm_pbmp_t pbmp; 10079 bcm_port_t port; 10080 bcm_vlan_action_set_t def_action; 10081 bcm_vlan_t def_ovid, def_ivid; 10082 bcm_port_config_t pconf; 10083 _bcm_port_info_t *pinfo; 10084 10085 #ifdef BCM_KATANA2_SUPPORT 10086 if (SOC_IS_KATANA2(unit)) { 10087 /* KT2 devices recovery happens from scache in _bcm_esw_port_wb_recover */ 10088 return BCM_E_NONE; 10089 } 10090 #endif 10091 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 10092 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 10093 10094 BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &pconf)); 10095 pbmp = pconf.e; 10096 if (soc_feature(unit, soc_feature_cpuport_switched)) { 10097 BCM_PBMP_OR(pbmp, pconf.cpu); 10098 } 10099 10100 for (i = idxmin; i <= idxmax; i++) { 10101 SOC_IF_ERROR_RETURN 10102 (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, i, &vpe)); 10103 _bcm_trx_vlan_port_protocol_entry_parse(unit, &vpe, &ft, &et); 10104 if (0 == ft) { 10105 continue; 10106 } 10107 10108 PBMP_ITER(pbmp, port) { 10109 BCM_IF_ERROR_RETURN( 10110 bcm_esw_vlan_port_default_action_get(unit, port, &def_action)); 10111 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 10112 data_idx = pinfo->vlan_prot_ptr + i; 10113 SOC_IF_ERROR_RETURN( 10114 READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, data_idx, &vde)); 10115 def_ovid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, OVIDf); 10116 def_ivid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, IVIDf); 10117 if (def_ivid == def_action.new_inner_vlan && 10118 def_ovid == def_action.new_outer_vlan) { 10119 continue; 10120 } 10121 10122 _BCM_PORT_VD_PBVL_SET(pinfo, i); 10123 } 10124 } 10125 10126 return BCM_E_NONE; 10127 } 10128 #endif /* BCM_WARM_BOOT_SUPPORT */ 10129 10130 10131 /* 10132 * Function : 10133 * _bcm_trx_vlan_protocol_data_update 10134 * Description : 10135 * Helper function for an API to update lan port protocol data memory 10136 * for specific ports. 10137 * Parameters : 10138 * unit (IN) BCM unit number 10139 * update_pbm (IN) BCM port bitmap to update 10140 * prot_idx (IN) Index to Port Protocol table 10141 * action (IN) VLAN action to be used to update all ports in pbmp 10142 */ 10143 STATIC int 10144 _bcm_trx_vlan_protocol_data_update(int unit, bcm_pbmp_t update_pbm, int prot_idx, 10145 bcm_vlan_action_set_t *action) 10146 { 10147 bcm_port_t p; 10148 vlan_protocol_data_entry_t vde; 10149 int data_idx, profile_idx; 10150 int c_profile_idx, use_default = 0; 10151 bcm_vlan_action_set_t def_action, *action_p; 10152 _bcm_port_info_t *pinfo; 10153 10154 10155 /* if action is NULL then default action should be used for each port */ 10156 if (NULL == action) { 10157 use_default = 1; 10158 action_p = &def_action; 10159 } else { 10160 BCM_IF_ERROR_RETURN( 10161 _bcm_trx_vlan_action_verify(unit, action)); 10162 action_p = action; 10163 } 10164 10165 BCM_PBMP_ITER(update_pbm, p) { 10166 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo)); 10167 data_idx = pinfo->vlan_prot_ptr + prot_idx; 10168 10169 if (use_default) { 10170 BCM_IF_ERROR_RETURN( 10171 bcm_esw_vlan_port_default_action_get(unit, p, action_p)); 10172 } 10173 BCM_IF_ERROR_RETURN( 10174 _bcm_trx_vlan_action_profile_entry_add(unit, action_p, 10175 (uint32 *)&profile_idx)); 10176 BCM_IF_ERROR_RETURN( 10177 READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, data_idx, &vde)); 10178 10179 c_profile_idx = 10180 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, 10181 TAG_ACTION_PROFILE_PTRf); 10182 sal_memset(&vde, 0, sizeof(vde)); 10183 _bcm_trx_vlan_protocol_data_entry_set(unit, &vde, action_p, 10184 profile_idx); 10185 BCM_IF_ERROR_RETURN( 10186 WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, data_idx, &vde)); 10187 BCM_IF_ERROR_RETURN( 10188 _bcm_trx_vlan_action_profile_entry_delete(unit, c_profile_idx)); 10189 } 10190 return BCM_E_NONE; 10191 } 10192 10193 /* 10194 * Function : 10195 * _bcm_trx_vlan_protocol_data_entry_delete_by_idx 10196 * Description : 10197 * Helper function to delete a vlan_protocol_data entry from memory by 10198 * protocol index 10199 * Parameters : 10200 * unit (IN) BCM unit number 10201 * port (IN) Port 10202 * vp_idx (IN) Index to protcol id 10203 */ 10204 STATIC int 10205 _bcm_trx_vlan_protocol_data_entry_delete_by_idx(int unit, bcm_port_t port, 10206 int vp_idx) 10207 { 10208 bcm_pbmp_t switched_pbm, update_pbm; 10209 bcm_port_config_t pconf; 10210 _bcm_port_info_t *pinfo; 10211 bcm_port_t p; 10212 int in_use = 0; 10213 vlan_protocol_entry_t *vpnull; 10214 10215 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 10216 BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &pconf)); 10217 10218 BCM_PBMP_CLEAR(update_pbm); 10219 BCM_PBMP_PORT_ADD(update_pbm, port); 10220 10221 switched_pbm = pconf.e; 10222 if (soc_feature(unit, soc_feature_cpuport_switched)) { 10223 BCM_PBMP_OR(switched_pbm, pconf.cpu); 10224 } 10225 #ifdef BCM_KATANA2_SUPPORT 10226 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 10227 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &switched_pbm)); 10228 } 10229 if (soc_feature(unit, soc_feature_linkphy_coe) || 10230 soc_feature(unit, soc_feature_subtag_coe)) { 10231 _bcm_kt2_subport_pbmp_update(unit, &switched_pbm); 10232 } 10233 #endif 10234 10235 BCM_PBMP_ITER(switched_pbm, p) { 10236 if (p == port) { /* skip the port we just added */ 10237 continue; 10238 } 10239 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo)); 10240 /* Check for explicit VID entry */ 10241 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, vp_idx)) { 10242 BCM_PBMP_PORT_ADD(update_pbm, p); 10243 } else { 10244 in_use = 1; 10245 } 10246 } 10247 10248 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 10249 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 10250 BCM_IF_ERROR_RETURN( 10251 _bcm_trx_vlan_protocol_data_profile_update(unit, update_pbm, vp_idx, NULL)); 10252 } else 10253 #endif 10254 { 10255 BCM_IF_ERROR_RETURN( 10256 _bcm_trx_vlan_protocol_data_update(unit, update_pbm, vp_idx, NULL)); 10257 } 10258 if (!in_use) { 10259 vpnull = soc_mem_entry_null(unit, VLAN_PROTOCOLm); 10260 WRITE_VLAN_PROTOCOLm(unit, MEM_BLOCK_ALL, vp_idx, vpnull); 10261 } 10262 10263 return BCM_E_NONE; 10264 } 10265 10266 /* 10267 * Function : 10268 * _bcm_trx_vlan_port_protocol_action_add 10269 * Description : 10270 * Helper function for an API to add vlan port protocol action 10271 * For TRX 10272 * Parameters : 10273 * unit (IN) BCM unit number 10274 * port (IN) BCM port number 10275 * frame (IN) Frame type 10276 * ethr (IN) Ethertype 10277 * action (IN) vlan action to be used 10278 */ 10279 int 10280 _bcm_trx_vlan_port_protocol_action_add(int unit, 10281 bcm_port_t port, 10282 bcm_port_frametype_t frame, 10283 bcm_port_ethertype_t ether, 10284 bcm_vlan_action_set_t *action) 10285 { 10286 10287 bcm_port_t p; 10288 vlan_protocol_entry_t vpe; 10289 int vpentry, empty, rv_m, rv_e; 10290 bcm_pbmp_t switched_pbm, update_pbm, clear_pbm; 10291 _bcm_port_info_t *pinfo; 10292 bcm_port_config_t pconf; 10293 10294 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 10295 10296 /* Verifying supported frame types */ 10297 if ((0 == frame) || (BCM_PORT_FRAMETYPE_SNAP_PRIVATE < frame) || 10298 (frame & (frame - 1))) { 10299 return BCM_E_PARAM; 10300 } 10301 rv_m = _bcm_trx_vlan_port_prot_match_get(unit, frame, ether, &vpentry); 10302 rv_e = _bcm_trx_vlan_port_prot_empty_get(unit, &empty); 10303 10304 if ((BCM_E_NOT_FOUND == rv_m) && (BCM_E_FULL == rv_e)) { 10305 return BCM_E_FULL; 10306 } 10307 if (BCM_E_NOT_FOUND == rv_m) { 10308 sal_memset(&vpe, 0, sizeof(vpe)); 10309 soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, ETHERTYPEf, ether); 10310 if (frame & BCM_PORT_FRAMETYPE_ETHER2) { 10311 soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, ETHERIIf, 1); 10312 } 10313 if (frame & BCM_PORT_FRAMETYPE_8023) { 10314 soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, SNAPf, 1); 10315 } 10316 if (frame & BCM_PORT_FRAMETYPE_LLC) { 10317 soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, LLCf, 1); 10318 } 10319 soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, MATCHUPPERf, 1); 10320 soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, MATCHLOWERf, 1); 10321 /* Actual writing into the memory will be last in this routine */ 10322 vpentry = empty; 10323 } 10324 10325 /* 10326 * Set VLAN ID for target port. For all other ethernet ports, 10327 * make sure entries indexed by the matched entry in VLAN_PROTOCOL 10328 * have initialized values (either default or explicit VID). 10329 */ 10330 BCM_PBMP_CLEAR(update_pbm); 10331 BCM_PBMP_CLEAR(clear_pbm); 10332 BCM_IF_ERROR_RETURN( 10333 bcm_esw_port_config_get(unit, &pconf)); 10334 switched_pbm = pconf.e; 10335 if (soc_feature(unit, soc_feature_cpuport_switched)) { 10336 BCM_PBMP_OR(switched_pbm, pconf.cpu); 10337 } 10338 #ifdef BCM_KATANA2_SUPPORT 10339 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 10340 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &switched_pbm)); 10341 } 10342 if (soc_feature(unit, soc_feature_linkphy_coe) || 10343 soc_feature(unit, soc_feature_subtag_coe)) { 10344 _bcm_kt2_subport_pbmp_update(unit, &switched_pbm); 10345 } 10346 #endif 10347 10348 BCM_PBMP_ITER(switched_pbm, p) { 10349 BCM_IF_ERROR_RETURN( 10350 _bcm_port_info_get(unit, p, &pinfo)); 10351 if (p == port) { 10352 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry)) { 10353 return BCM_E_EXISTS; 10354 } 10355 /* Set as explicit VID */ 10356 _BCM_PORT_VD_PBVL_SET(pinfo, vpentry); 10357 BCM_PBMP_PORT_ADD(update_pbm, p); 10358 } else { 10359 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry)) { 10360 continue; 10361 } 10362 /* Set to default VLAN ID and vlan actions */ 10363 BCM_PBMP_PORT_ADD(clear_pbm, p); 10364 } 10365 } 10366 10367 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 10368 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 10369 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_protocol_data_profile_update(unit, 10370 clear_pbm, vpentry, NULL)); 10371 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_protocol_data_profile_update(unit, 10372 update_pbm, vpentry, action)); 10373 } else 10374 #endif 10375 { 10376 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_protocol_data_update(unit, 10377 clear_pbm, vpentry, NULL)); 10378 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_protocol_data_update(unit, 10379 update_pbm, vpentry, action)); 10380 } 10381 10382 if (BCM_E_NOT_FOUND == rv_m) { 10383 BCM_IF_ERROR_RETURN( 10384 WRITE_VLAN_PROTOCOLm(unit, MEM_BLOCK_ALL, vpentry, &vpe)); 10385 } 10386 10387 return BCM_E_NONE; 10388 } 10389 10390 /* 10391 * Function : 10392 * _bcm_trx_vlan_port_protocol_action_get 10393 * Description : 10394 * Helper function for an API to get vlan port protocol action 10395 * For TRX 10396 * Parameters : 10397 * unit (IN) BCM unit number 10398 * port (IN) BCM port number 10399 * frame (IN) Frame type 10400 * ethr (IN) Ethertype 10401 * action (OUT) vlan action to get 10402 */ 10403 int 10404 _bcm_trx_vlan_port_protocol_action_get(int unit, bcm_port_t port, 10405 bcm_port_frametype_t frame, 10406 bcm_port_ethertype_t ether, 10407 bcm_vlan_action_set_t *action) 10408 { 10409 int match_prot_idx, match_data_idx, profile_idx; 10410 vlan_protocol_data_entry_t vde; 10411 _bcm_port_info_t *pinfo; 10412 10413 if (NULL == action) { 10414 return (BCM_E_PARAM); 10415 } 10416 10417 BCM_IF_ERROR_RETURN( 10418 _bcm_trx_vlan_port_prot_match_get(unit, frame, ether, &match_prot_idx)); 10419 10420 BCM_IF_ERROR_RETURN( 10421 _bcm_port_info_get(unit, port, &pinfo)); 10422 10423 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, match_prot_idx)) { 10424 return BCM_E_NOT_FOUND; 10425 } 10426 10427 match_data_idx = pinfo->vlan_prot_ptr + match_prot_idx; 10428 10429 BCM_IF_ERROR_RETURN( 10430 READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, match_data_idx, &vde)); 10431 10432 _bcm_trx_vlan_protocol_data_entry_parse(unit, &vde, action, &profile_idx); 10433 _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 10434 10435 return BCM_E_NONE; 10436 } 10437 10438 /* 10439 * Function : 10440 * _bcm_trx_vlan_port_protocol_delete 10441 * Description : 10442 * Helper function for an API to delete vlan port protocol action 10443 * For TRX 10444 * Parameters : 10445 * unit (IN) BCM unit number 10446 * port (IN) BCM port number 10447 * frame (IN) Frame type 10448 * ethr (IN) Ethertype 10449 */ 10450 10451 int 10452 _bcm_trx_vlan_port_protocol_delete(int unit, bcm_port_t port, 10453 bcm_port_frametype_t frame, 10454 bcm_port_ethertype_t ether) 10455 { 10456 int vpentry, rv; 10457 _bcm_port_info_t *pinfo; 10458 10459 BCM_IF_ERROR_RETURN( 10460 _bcm_trx_vlan_port_prot_match_get(unit, frame, ether, &vpentry)); 10461 10462 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 10463 10464 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry)) { 10465 return BCM_E_NOT_FOUND; 10466 } 10467 10468 rv = _bcm_trx_vlan_protocol_data_entry_delete_by_idx(unit, port, vpentry); 10469 if (BCM_SUCCESS(rv)) { 10470 _BCM_PORT_VD_PBVL_CLEAR(pinfo, vpentry); 10471 } 10472 10473 return rv; 10474 } 10475 10476 10477 /* 10478 * Function : 10479 * _bcm_trx_vlan_port_protocol_delete_all 10480 * Description : 10481 * Helper function for an API to delete all actions for all 10482 * vlan port protocols for TRX 10483 * Parameters : 10484 * unit (IN) BCM unit number 10485 * port (IN) BCM port number 10486 */ 10487 int 10488 _bcm_trx_vlan_port_protocol_delete_all(int unit, bcm_port_t port) 10489 { 10490 int i, idxmin, idxmax, rv; 10491 _bcm_port_info_t *pinfo; 10492 10493 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 10494 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 10495 10496 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 10497 10498 rv = BCM_E_NONE; 10499 10500 for (i = idxmin; i <= idxmax; i++) { 10501 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 10502 rv = _bcm_trx_vlan_protocol_data_entry_delete_by_idx(unit, port, i); 10503 if (BCM_FAILURE(rv)) { 10504 break; 10505 } else { 10506 _BCM_PORT_VD_PBVL_CLEAR(pinfo, i); 10507 } 10508 } 10509 } 10510 10511 return rv; 10512 } 10513 10514 10515 /* 10516 * Function : 10517 * _bcm_trx_vlan_port_protocol_action_traverse 10518 * Description : 10519 * Helper function for an API to traverse over all 10520 * vlan port protocols and call given callback routine for TRX 10521 * Parameters : 10522 * unit (IN) BCM unit number 10523 * cb (IN) user callback function 10524 * user_data (IN) pointer to user data 10525 */ 10526 int 10527 _bcm_trx_vlan_port_protocol_action_traverse(int unit, 10528 bcm_vlan_port_protocol_action_traverse_cb cb, 10529 void *user_data) 10530 { 10531 int idxmin, idxmax, i, data_idx, profile_idx; 10532 vlan_protocol_entry_t vpe; 10533 vlan_protocol_data_entry_t vde; 10534 bcm_port_frametype_t ft; 10535 bcm_port_ethertype_t et; 10536 bcm_pbmp_t pbmp; 10537 bcm_port_t port; 10538 bcm_vlan_action_set_t action; 10539 bcm_port_config_t pconf; 10540 _bcm_port_info_t *pinfo; 10541 10542 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 10543 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 10544 10545 BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &pconf)); 10546 pbmp = pconf.e; 10547 if (soc_feature(unit, soc_feature_cpuport_switched)) { 10548 BCM_PBMP_OR(pbmp, pconf.cpu); 10549 } 10550 #ifdef BCM_KATANA2_SUPPORT 10551 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 10552 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &pbmp)); 10553 } 10554 if (soc_feature(unit, soc_feature_linkphy_coe) || 10555 soc_feature(unit, soc_feature_subtag_coe)) { 10556 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 10557 } 10558 #endif 10559 10560 for (i = idxmin; i <= idxmax; i++) { 10561 SOC_IF_ERROR_RETURN( 10562 READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, i, &vpe)); 10563 _bcm_trx_vlan_port_protocol_entry_parse(unit, &vpe, &ft, &et); 10564 if (0 == ft) { 10565 continue; 10566 } 10567 PBMP_ITER(pbmp, port) { 10568 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 10569 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 10570 data_idx = pinfo->vlan_prot_ptr + i; 10571 SOC_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm(unit, 10572 MEM_BLOCK_ANY, data_idx, &vde)); 10573 profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, 10574 TAG_ACTION_PROFILE_PTRf); 10575 action.new_inner_vlan = 10576 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, IVIDf); 10577 action.new_outer_vlan = 10578 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, OVIDf); 10579 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 10580 action.priority = 10581 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, OPRIf); 10582 action.new_outer_cfi = 10583 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, OCFIf); 10584 action.new_inner_pkt_prio = 10585 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, IPRIf); 10586 action.new_inner_cfi = 10587 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, ICFIf); 10588 } else { 10589 action.priority = 10590 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, PRIf); 10591 } 10592 /* Read action profile data. */ 10593 _bcm_trx_vlan_action_profile_entry_get(unit, &action, profile_idx); 10594 BCM_IF_ERROR_RETURN(cb(unit, port, ft, et, &action, user_data)); 10595 } 10596 } 10597 } 10598 10599 return (BCM_E_NONE); 10600 } 10601 10602 /* 10603 * Function: 10604 * _bcm_trx_vlan_port_default_action_set 10605 * Purpose: 10606 * Set the port's default vlan tag actions 10607 * Parameters: 10608 * unit - (IN) BCM unit. 10609 * port - (IN) Port number. 10610 * action - (IN) Vlan tag actions 10611 * Returns: 10612 * BCM_E_XXX 10613 */ 10614 int 10615 _bcm_trx_vlan_port_default_action_set(int unit, bcm_port_t port, 10616 bcm_vlan_action_set_t *action) 10617 { 10618 uint32 profile_idx, old_profile_idx, vp_profile_idx; 10619 bcm_port_cfg_t pcfg; 10620 vlan_protocol_data_entry_t vde; 10621 int vlan_prot_entries, vlan_data_prot_start, i; 10622 _bcm_port_info_t *pinfo; 10623 #ifdef BCM_HGPROXY_COE_SUPPORT 10624 int rv = BCM_E_NONE; 10625 #endif 10626 10627 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 10628 BCM_IF_ERROR_RETURN 10629 (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx)); 10630 10631 #ifdef BCM_HGPROXY_COE_SUPPORT 10632 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 10633 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 10634 uint32 values[5]; 10635 soc_field_t fields[] = { 10636 TAG_ACTION_PROFILE_PTRf, 10637 PORT_PRIf, 10638 OCFIf, 10639 IPRIf, 10640 ICFIf 10641 }; 10642 10643 PORT_LOCK(unit); 10644 rv = bcm_esw_port_lport_fields_get(unit, port, LPORT_PROFILE_LPORT_TAB, 10645 5, fields, values); 10646 PORT_UNLOCK(unit); 10647 if (BCM_FAILURE(rv)) { 10648 return rv; 10649 } 10650 10651 old_profile_idx = values[0]; 10652 pcfg.pc_new_opri = values[1]; 10653 pcfg.pc_new_ocfi = values[2]; 10654 pcfg.pc_new_ipri = values[3]; 10655 pcfg.pc_new_icfi = values[4]; 10656 } else 10657 #endif 10658 { 10659 BCM_IF_ERROR_RETURN 10660 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 10661 old_profile_idx = pcfg.pc_vlan_action; 10662 } 10663 10664 pcfg.pc_vlan = action->new_outer_vlan; 10665 pcfg.pc_ivlan = action->new_inner_vlan; 10666 pcfg.pc_vlan_action = profile_idx; 10667 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 10668 if (action->priority >= BCM_PRIO_MIN && 10669 action->priority <= BCM_PRIO_MAX) { 10670 pcfg.pc_new_opri = action->priority; 10671 } 10672 pcfg.pc_new_ocfi = action->new_outer_cfi; 10673 pcfg.pc_new_ipri = action->new_inner_pkt_prio; 10674 pcfg.pc_new_icfi = action->new_inner_cfi; 10675 } else { 10676 if (action->priority >= BCM_PRIO_MIN && 10677 action->priority <= BCM_PRIO_MAX) { 10678 pcfg.pc_new_opri = action->priority; 10679 } 10680 } 10681 10682 #ifdef BCM_HGPROXY_COE_SUPPORT 10683 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 10684 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 10685 uint32 values[7]; 10686 soc_field_t fields[] = { 10687 PORT_VIDf, 10688 IVIDf, 10689 TAG_ACTION_PROFILE_PTRf, 10690 PORT_PRIf, 10691 OCFIf, 10692 IPRIf, 10693 ICFIf 10694 }; 10695 10696 values[0] = pcfg.pc_vlan; 10697 values[1] = pcfg.pc_ivlan; 10698 values[2] = pcfg.pc_vlan_action; 10699 values[3] = pcfg.pc_new_opri; 10700 values[4] = pcfg.pc_new_ocfi; 10701 values[5] = pcfg.pc_new_ipri; 10702 values[6] = pcfg.pc_new_icfi; 10703 10704 PORT_LOCK(unit); 10705 rv = bcm_esw_port_lport_fields_set(unit, port, LPORT_PROFILE_LPORT_TAB, 10706 7, fields, values); 10707 PORT_UNLOCK(unit); 10708 if (BCM_FAILURE(rv)) { 10709 return rv; 10710 } 10711 }else 10712 #endif 10713 { 10714 BCM_IF_ERROR_RETURN 10715 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 10716 } 10717 10718 SOC_IF_ERROR_RETURN 10719 (_bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx)); 10720 10721 BCM_IF_ERROR_RETURN( 10722 _bcm_esw_port_gport_validate(unit, port, &port)); 10723 10724 /* 10725 * Update default VLAN ID in VLAN_PROTOCOL_DATA 10726 */ 10727 vlan_prot_entries = soc_mem_index_count(unit, VLAN_PROTOCOLm); 10728 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 10729 vlan_data_prot_start = pinfo->vlan_prot_ptr; 10730 10731 if (pinfo->p_vd_pbvl == 0) { 10732 /* Avoid one crash in kt2 tr 18 test case in linux environment */ 10733 return (BCM_E_NONE); 10734 } 10735 10736 10737 for (i = 0; i < vlan_prot_entries; i++) { 10738 10739 BCM_IF_ERROR_RETURN( 10740 READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, 10741 vlan_data_prot_start + i, &vde)); 10742 vp_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, 10743 TAG_ACTION_PROFILE_PTRf); 10744 10745 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 10746 10747 BCM_IF_ERROR_RETURN( 10748 _bcm_trx_vlan_action_profile_entry_add(unit, action, 10749 &profile_idx)); 10750 _bcm_trx_vlan_protocol_data_entry_set(unit, &vde, action, 10751 profile_idx); 10752 10753 BCM_IF_ERROR_RETURN( 10754 WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, 10755 vlan_data_prot_start + i, &vde)); 10756 BCM_IF_ERROR_RETURN( 10757 _bcm_trx_vlan_action_profile_entry_delete(unit, 10758 vp_profile_idx)); 10759 } 10760 } 10761 10762 return (BCM_E_NONE); 10763 } 10764 10765 /* 10766 * Function: 10767 * _bcm_trx_vlan_port_default_action_get 10768 * Purpose: 10769 * Get the port's default vlan tag actions 10770 * Parameters: 10771 * unit - (IN) BCM unit. 10772 * port - (IN) Port number. 10773 * action - (IN) Vlan tag actions 10774 * Returns: 10775 * BCM_E_XXX 10776 */ 10777 int 10778 _bcm_trx_vlan_port_default_action_get(int unit, bcm_port_t port, 10779 bcm_vlan_action_set_t *action) 10780 { 10781 uint32 profile_idx; 10782 bcm_port_cfg_t pcfg; 10783 int vid; 10784 int ivid; 10785 #ifdef BCM_HGPROXY_COE_SUPPORT 10786 int rv = BCM_E_NONE; 10787 #endif 10788 10789 bcm_vlan_action_set_t_init(action); 10790 10791 #ifdef BCM_HGPROXY_COE_SUPPORT 10792 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 10793 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 10794 uint32 values[7]; 10795 soc_field_t fields[] = { 10796 PORT_VIDf, 10797 IVIDf, 10798 TAG_ACTION_PROFILE_PTRf, 10799 PORT_PRIf, 10800 OCFIf, 10801 IPRIf, 10802 ICFIf 10803 }; 10804 10805 PORT_LOCK(unit); 10806 rv = bcm_esw_port_lport_fields_get(unit, port, LPORT_PROFILE_LPORT_TAB, 10807 7, fields, values); 10808 PORT_UNLOCK(unit); 10809 if (BCM_FAILURE(rv)) { 10810 return rv; 10811 } 10812 10813 vid = values[0]; 10814 ivid = values[1]; 10815 profile_idx = values[2]; 10816 pcfg.pc_new_opri = values[3]; 10817 pcfg.pc_new_ocfi = values[4]; 10818 pcfg.pc_new_ipri = values[5]; 10819 pcfg.pc_new_icfi = values[6]; 10820 } else 10821 #endif 10822 { 10823 BCM_IF_ERROR_RETURN 10824 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 10825 profile_idx = pcfg.pc_vlan_action; 10826 vid = pcfg.pc_vlan; 10827 ivid = pcfg.pc_ivlan; 10828 } 10829 10830 _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 10831 10832 action->new_outer_vlan = vid; 10833 action->new_inner_vlan = ivid; 10834 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 10835 action->priority = pcfg.pc_new_opri; 10836 action->new_outer_cfi = pcfg.pc_new_ocfi; 10837 action->new_inner_pkt_prio = pcfg.pc_new_ipri; 10838 action->new_inner_cfi = pcfg.pc_new_icfi; 10839 } else { 10840 action->priority = pcfg.pc_new_opri; 10841 } 10842 10843 return BCM_E_NONE; 10844 } 10845 10846 10847 /* 10848 * Function: 10849 * _bcm_tr_vlan_port_default_action_delete 10850 * Purpose: 10851 * Deletes the port's default vlan tag actions 10852 * Parameters: 10853 * unit - (IN) BCM unit. 10854 * port - (IN) Port number. 10855 * Returns: 10856 * BCM_E_XXX 10857 */ 10858 int 10859 _bcm_trx_vlan_port_default_action_delete(int unit, bcm_port_t port) 10860 { 10861 uint32 old_profile_idx; 10862 uint32 vp_profile_idx; 10863 bcm_port_cfg_t pcfg; 10864 _bcm_port_info_t *pinfo; 10865 int num_ent, start, i; 10866 vlan_protocol_data_entry_t vde; 10867 10868 BCM_IF_ERROR_RETURN 10869 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 10870 old_profile_idx = pcfg.pc_vlan_action; 10871 10872 pcfg.pc_vlan = BCM_VLAN_DEFAULT; 10873 pcfg.pc_ivlan = 0; 10874 pcfg.pc_vlan_action = ing_action_profile_def[unit]; 10875 BCM_IF_ERROR_RETURN 10876 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 10877 10878 _bcm_trx_vlan_action_profile_entry_increment(unit, 10879 ing_action_profile_def[unit]); 10880 BCM_IF_ERROR_RETURN 10881 (_bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx)); 10882 10883 BCM_IF_ERROR_RETURN( 10884 _bcm_port_info_get(unit,port, &pinfo)); 10885 10886 num_ent = soc_mem_index_count(unit, VLAN_PROTOCOLm); 10887 start = pinfo->vlan_prot_ptr; 10888 for (i = 0; i < num_ent; i++) { 10889 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 10890 BCM_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, 10891 start + i, &vde)); 10892 vp_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, 10893 TAG_ACTION_PROFILE_PTRf); 10894 10895 sal_memset(&vde, 0, sizeof(vlan_protocol_data_entry_t)); 10896 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, OVIDf, 10897 BCM_VLAN_DEFAULT); 10898 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, 10899 TAG_ACTION_PROFILE_PTRf, ing_action_profile_def[unit]); 10900 BCM_IF_ERROR_RETURN(WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, 10901 start + i, &vde)); 10902 10903 _bcm_trx_vlan_action_profile_entry_increment(unit, 10904 ing_action_profile_def[unit]); 10905 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_delete(unit, 10906 vp_profile_idx)); 10907 } 10908 } 10909 return (BCM_E_NONE); 10910 } 10911 10912 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 10913 /* 10914 * Function: 10915 * _bcm_td2p_vlan_port_egress_default_action_set 10916 * Purpose: 10917 * Set the egress port's default vlan tag actions 10918 * Parameters: 10919 * unit - (IN) BCM unit. 10920 * port - (IN) Port number. 10921 * action - (IN) Vlan tag actions 10922 * Returns: 10923 * BCM_E_XXX 10924 */ 10925 STATIC int 10926 _bcm_td2p_vlan_port_egress_default_action_set(int unit, bcm_port_t port, 10927 bcm_vlan_action_set_t *action, 10928 uint32 profile_idx) 10929 { 10930 int rv; 10931 uint32 old_profile_idx; 10932 egr_vlan_control_3_entry_t entry_3; 10933 egr_vlan_control_2_entry_t entry_2; 10934 10935 if (soc_feature(unit, soc_feature_egr_all_profile)) { 10936 int field_cnt = 0; 10937 soc_field_t fields[6]; 10938 uint32 values[6]; 10939 10940 if (-1 == action->priority) { 10941 fields[field_cnt] = OPRI_CFI_SELf; 10942 values[field_cnt++] = 1; 10943 } else { 10944 fields[field_cnt] = OPRI_CFI_SELf; 10945 values[field_cnt++] = 0; 10946 fields[field_cnt] = OPRIf; 10947 values[field_cnt++] = action->priority; 10948 fields[field_cnt] = OCFIf; 10949 values[field_cnt++] = action->new_outer_cfi; 10950 } 10951 fields[field_cnt] = OVIDf; 10952 values[field_cnt++] = action->new_outer_vlan; 10953 rv = bcm_esw_port_egr_lport_fields_set(unit, port, EGR_VLAN_CONTROL_2m, 10954 field_cnt, fields, values); 10955 if (rv < 0) { 10956 goto error; 10957 } 10958 10959 /* EGR_VLAN_CONTROL_3m */ 10960 field_cnt = 0; 10961 rv = bcm_esw_port_egr_lport_field_get(unit, port, EGR_VLAN_CONTROL_3m, 10962 TAG_ACTION_PROFILE_PTRf, &old_profile_idx); 10963 if (rv < 0) { 10964 goto error; 10965 } 10966 fields[field_cnt] = TAG_ACTION_PROFILE_PTRf; 10967 values[field_cnt++] = profile_idx; 10968 fields[field_cnt] = IVIDf; 10969 values[field_cnt++] = action->new_inner_vlan; 10970 if (-1 == action->priority) { 10971 fields[field_cnt] = IPRI_CFI_SELf; 10972 values[field_cnt++] = 1; 10973 } else { 10974 fields[field_cnt] = IPRI_CFI_SELf; 10975 values[field_cnt++] = 0; 10976 fields[field_cnt] = IPRIf; 10977 values[field_cnt++] = action->new_inner_pkt_prio; 10978 fields[field_cnt] = ICFIf; 10979 values[field_cnt++] = action->new_inner_cfi; 10980 } 10981 rv = bcm_esw_port_egr_lport_fields_set(unit, port, EGR_VLAN_CONTROL_3m, 10982 field_cnt, fields, values); 10983 if (rv < 0) { 10984 goto error; 10985 } 10986 /* Delete the old profile only if it is different the a new one. */ 10987 if (profile_idx != old_profile_idx) { 10988 rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit, 10989 old_profile_idx); 10990 if (rv < 0) { 10991 goto error; 10992 } 10993 } 10994 10995 return BCM_E_NONE; 10996 } 10997 10998 rv = READ_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry_2); 10999 if (rv < 0) { 11000 goto error; 11001 } 11002 if (-1 == action->priority) { 11003 /* point to default map profile(0) for default priority action */ 11004 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, 11005 &entry_2, OPRI_CFI_SELf, 1); 11006 } else { 11007 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, 11008 &entry_2, OPRI_CFI_SELf, 0); 11009 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, 11010 &entry_2, OPRIf, action->priority); 11011 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, &entry_2, OCFIf, 11012 action->new_outer_cfi); 11013 } 11014 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, &entry_2, 11015 OVIDf, action->new_outer_vlan); 11016 rv = WRITE_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry_2); 11017 if (rv < 0) { 11018 goto error; 11019 } 11020 11021 rv = READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3); 11022 if (rv < 0) { 11023 goto error; 11024 } 11025 old_profile_idx = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, 11026 &entry_3, TAG_ACTION_PROFILE_PTRf); 11027 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry_3, 11028 TAG_ACTION_PROFILE_PTRf, profile_idx); 11029 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry_3, 11030 IVIDf, action->new_inner_vlan); 11031 11032 if ( -1 == action->priority) { 11033 /* point to default map profile(0) for default priority action */ 11034 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, 11035 &entry_3, IPRI_CFI_SELf, 1); 11036 } else { 11037 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, 11038 &entry_3, IPRI_CFI_SELf, 0); 11039 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry_3, IPRIf, 11040 action->new_inner_pkt_prio); 11041 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry_3, ICFIf, 11042 action->new_inner_cfi); 11043 } 11044 rv = WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3); 11045 if (rv < 0) { 11046 goto error; 11047 } 11048 11049 /* Delete the old profile only if it is different the a new one. */ 11050 if (profile_idx != old_profile_idx) { 11051 rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit, 11052 old_profile_idx); 11053 if (rv < 0) { 11054 goto error; 11055 } 11056 } 11057 11058 return BCM_E_NONE; 11059 11060 error: 11061 /* Undo action profile entry addition */ 11062 if (_bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx) != BCM_E_NONE) { 11063 LOG_INFO(BSL_LS_SOC_VLAN, 11064 (BSL_META_U(unit, 11065 "Failed to undo profile entry addition\n"))); 11066 } 11067 return rv; 11068 } 11069 11070 /* 11071 * Function: 11072 * _bcm_td2pvlan_port_egress_default_action_get 11073 * Purpose: 11074 * Get the egress port's default vlan tag actions 11075 * Parameters: 11076 * unit - (IN) BCM unit. 11077 * port - (IN) Port number. 11078 * action - (IN) Vlan tag actions 11079 * Returns: 11080 * BCM_E_XXX 11081 */ 11082 STATIC int 11083 _bcm_td2p_vlan_port_egress_default_action_get(int unit, bcm_port_t port, 11084 bcm_vlan_action_set_t *action) 11085 { 11086 uint32 profile_idx; 11087 egr_vlan_control_3_entry_t entry_3; 11088 egr_vlan_control_2_entry_t entry_2; 11089 11090 if (soc_feature(unit, soc_feature_egr_all_profile)) { 11091 int field_count = 5; 11092 soc_field_t fields[5] = { 11093 TAG_ACTION_PROFILE_PTRf, 11094 IVIDf, 11095 IPRI_CFI_SELf, 11096 IPRIf, 11097 ICFIf 11098 }; 11099 uint32 values[5]; 11100 BCM_IF_ERROR_RETURN( 11101 bcm_esw_port_egr_lport_fields_get(unit, port, EGR_VLAN_CONTROL_3m, 11102 field_count, fields, values)); 11103 profile_idx = values[0]; 11104 _bcm_trx_egr_vlan_action_profile_entry_get(unit, action, profile_idx); 11105 action->new_inner_vlan = values[1]; 11106 if (!values[2]) { 11107 action->new_inner_pkt_prio = values[3]; 11108 action->new_inner_cfi = values[4]; 11109 } 11110 11111 /* EGR_VLAN_CONTROL_2m */ 11112 field_count = 4; 11113 fields[0] = OVIDf; 11114 fields[1] = OPRI_CFI_SELf; 11115 fields[2] = OPRIf; 11116 fields[3] = OCFIf; 11117 BCM_IF_ERROR_RETURN( 11118 bcm_esw_port_egr_lport_fields_get(unit, port, EGR_VLAN_CONTROL_2m, 11119 field_count, fields, values)); 11120 action->new_outer_vlan = values[0]; 11121 if (!values[1]) { 11122 action->priority = values[2]; 11123 action->new_outer_cfi = values[3]; 11124 } 11125 11126 return BCM_E_NONE; 11127 } 11128 BCM_IF_ERROR_RETURN 11129 (READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3)); 11130 profile_idx = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, 11131 &entry_3, TAG_ACTION_PROFILE_PTRf); 11132 _bcm_trx_egr_vlan_action_profile_entry_get(unit, action, profile_idx); 11133 action->new_inner_vlan = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, 11134 &entry_3, IVIDf); 11135 if (!soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, &entry_3, 11136 IPRI_CFI_SELf)) { 11137 action->new_inner_pkt_prio = 11138 soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, &entry_3, IPRIf); 11139 action->new_inner_cfi = 11140 soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, &entry_3, ICFIf); 11141 } 11142 11143 BCM_IF_ERROR_RETURN 11144 (READ_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry_2)); 11145 action->new_outer_vlan = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_2m, 11146 &entry_2, OVIDf); 11147 if (!soc_mem_field32_get(unit, EGR_VLAN_CONTROL_2m, &entry_2, 11148 OPRI_CFI_SELf)) { 11149 action->priority = 11150 soc_mem_field32_get(unit, EGR_VLAN_CONTROL_2m, &entry_2, OPRIf); 11151 action->new_outer_cfi = 11152 soc_mem_field32_get(unit, EGR_VLAN_CONTROL_2m, &entry_2, OCFIf); 11153 } 11154 11155 return BCM_E_NONE; 11156 } 11157 11158 /* 11159 * Function: 11160 * _bcm_td2p_vlan_port_egress_default_action_delete 11161 * Purpose: 11162 * Deletes the egress port's default vlan tag actions 11163 * Parameters: 11164 * unit - (IN) BCM unit. 11165 * port - (IN) Port number. 11166 * Returns: 11167 * BCM_E_XXX 11168 */ 11169 STATIC int 11170 _bcm_td2p_vlan_port_egress_default_action_delete(int unit, bcm_port_t port) 11171 { 11172 uint32 profile_idx; 11173 egr_vlan_control_3_entry_t entry_3; 11174 egr_vlan_control_2_entry_t entry_2; 11175 11176 if (soc_feature(unit, soc_feature_egr_all_profile)) { 11177 BCM_IF_ERROR_RETURN( 11178 bcm_esw_port_egr_lport_field_get(unit, port, EGR_VLAN_CONTROL_3m, 11179 TAG_ACTION_PROFILE_PTRf, &profile_idx)); 11180 } else { 11181 BCM_IF_ERROR_RETURN 11182 (READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3)); 11183 profile_idx = soc_EGR_VLAN_CONTROL_3m_field32_get(unit, &entry_3, 11184 TAG_ACTION_PROFILE_PTRf); 11185 } 11186 11187 if (!SOC_IS_TRIDENT3X(unit)) { 11188 BCM_IF_ERROR_RETURN( 11189 _bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx)); 11190 } 11191 11192 if (soc_feature(unit, soc_feature_egr_all_profile)) { 11193 BCM_IF_ERROR_RETURN( 11194 bcm_esw_port_egr_lport_fields_clear(unit, port, EGR_VLAN_CONTROL_2m)); 11195 BCM_IF_ERROR_RETURN( 11196 bcm_esw_port_egr_lport_fields_clear(unit, port, EGR_VLAN_CONTROL_3m)); 11197 } else { 11198 sal_memset(&entry_3, 0, sizeof(entry_3)); 11199 sal_memset(&entry_2, 0, sizeof(entry_2)); 11200 BCM_IF_ERROR_RETURN( 11201 WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3)); 11202 BCM_IF_ERROR_RETURN( 11203 WRITE_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry_2)); 11204 } 11205 return BCM_E_NONE; 11206 } 11207 11208 /* 11209 * Function: 11210 * _bcm_td2p_vlan_port_egress_action_profile_clear 11211 * Purpose: 11212 * Clear the egress port's default vlan tag profile pointer 11213 * Parameters: 11214 * unit - (IN) BCM unit. 11215 * port - (IN) Port number. 11216 * Returns: 11217 * BCM_E_XXX 11218 */ 11219 STATIC int 11220 _bcm_td2p_vlan_port_egress_action_profile_clear(int unit, bcm_port_t port) 11221 { 11222 if (soc_feature(unit, soc_feature_egr_all_profile)) { 11223 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit, 11224 port, EGR_VLAN_CONTROL_3m, TAG_ACTION_PROFILE_PTRf, 0)); 11225 } else { 11226 egr_vlan_control_3_entry_t entry_3; 11227 11228 BCM_IF_ERROR_RETURN 11229 (READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3)); 11230 soc_EGR_VLAN_CONTROL_3m_field32_set(unit, &entry_3, 11231 TAG_ACTION_PROFILE_PTRf, 0); 11232 BCM_IF_ERROR_RETURN( 11233 WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3)); 11234 } 11235 return BCM_E_NONE; 11236 } 11237 #endif 11238 11239 /* 11240 * Function: 11241 * _bcm_tr_vlan_port_egress_default_action_set 11242 * Purpose: 11243 * Set the egress port's default vlan tag actions 11244 * Parameters: 11245 * unit - (IN) BCM unit. 11246 * port - (IN) Port number. 11247 * action - (IN) Vlan tag actions 11248 * Returns: 11249 * BCM_E_XXX 11250 */ 11251 int 11252 _bcm_trx_vlan_port_egress_default_action_set(int unit, bcm_port_t port, 11253 bcm_vlan_action_set_t *action) 11254 { 11255 int rv; 11256 uint32 rval, profile_idx, old_profile_idx; 11257 11258 #if defined(BCM_TOMAHAWK3_SUPPORT) 11259 if (SOC_IS_TOMAHAWK3(unit)) { 11260 return( 11261 _bcm_th3_vlan_port_egress_default_action_set(unit, port, action)); 11262 } 11263 #endif/* BCM_TOMAHAWK3_SUPPORT */ 11264 11265 #if defined(BCM_TOMAHAWK_SUPPORT) 11266 /* Tomahawk low latency mode */ 11267 if (soc_feature(unit, soc_feature_fast_egr_vlan_action)) { 11268 rval = _bcm_fast_egr_vlan_port_egress_default_action_set(unit, 11269 port, action); 11270 return rval; 11271 } 11272 #endif 11273 11274 BCM_IF_ERROR_RETURN(_bcm_trx_egr_vlan_action_verify(unit, action)); 11275 BCM_IF_ERROR_RETURN( 11276 _bcm_trx_egr_vlan_action_profile_entry_add(unit, action, &profile_idx)); 11277 11278 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 11279 if(soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 11280 return _bcm_td2p_vlan_port_egress_default_action_set(unit, port, 11281 action, profile_idx); 11282 } else 11283 #endif 11284 { 11285 rv = READ_EGR_VLAN_CONTROL_2r(unit, port, &rval); 11286 if (rv < 0) { 11287 goto error; 11288 } 11289 11290 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 11291 if (-1 == action->priority) { 11292 /* point to default map profile(0) for default priority action */ 11293 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRI_CFI_SELf, 1); 11294 } else { 11295 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRI_CFI_SELf, 0); 11296 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRIf, 11297 action->priority); 11298 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OCFIf, 11299 action->new_outer_cfi); 11300 } 11301 } else { 11302 /* -1 reserved value */ 11303 if (-1 == action->priority) { 11304 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, ORPEf, 0); 11305 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRIf, 0); 11306 } else if (action->priority <= BCM_PRIO_MAX){ 11307 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, ORPEf, 1); 11308 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRIf, 11309 action->priority); 11310 } else { 11311 rv = BCM_E_PARAM; 11312 goto error; 11313 } 11314 } 11315 11316 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, 11317 OVIDf, action->new_outer_vlan); 11318 rv = WRITE_EGR_VLAN_CONTROL_2r(unit, port, rval); 11319 if (rv < 0) { 11320 goto error; 11321 } 11322 11323 rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval); 11324 if (rv < 0) { 11325 goto error; 11326 } 11327 old_profile_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 11328 rval, TAG_ACTION_PROFILE_PTRf); 11329 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, 11330 TAG_ACTION_PROFILE_PTRf, profile_idx); 11331 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, 11332 IVIDf, action->new_inner_vlan); 11333 11334 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 11335 if ( -1 == action->priority) { 11336 /* point to default map profile(0) for default priority action */ 11337 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRI_CFI_SELf, 1); 11338 } else { 11339 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRI_CFI_SELf, 0); 11340 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRIf, 11341 action->new_inner_pkt_prio); 11342 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, ICFIf, 11343 action->new_inner_cfi); 11344 } 11345 } else { 11346 if ( -1 == action->priority) { 11347 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IRPEf, 0); 11348 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRIf, 0); 11349 } else if (action->priority <= BCM_PRIO_MAX){ 11350 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IRPEf, 1); 11351 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRIf, 11352 action->priority); 11353 } else { 11354 rv = BCM_E_PARAM; 11355 goto error; 11356 } 11357 } 11358 11359 rv = WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval); 11360 if (rv < 0) { 11361 goto error; 11362 } 11363 /* Delete the old profile only if it is different the a new one. */ 11364 if (profile_idx != old_profile_idx) { 11365 BCM_IF_ERROR_RETURN 11366 (_bcm_trx_egr_vlan_action_profile_entry_delete(unit, old_profile_idx)); 11367 } 11368 11369 return BCM_E_NONE; 11370 11371 error: 11372 /* Undo action profile entry addition */ 11373 BCM_IF_ERROR_RETURN 11374 (_bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx)); 11375 return rv; 11376 } 11377 } 11378 11379 /* 11380 * Function: 11381 * _bcm_tr_vlan_port_egress_default_action_get 11382 * Purpose: 11383 * Get the egress port's default vlan tag actions 11384 * Parameters: 11385 * unit - (IN) BCM unit. 11386 * port - (IN) Port number. 11387 * action - (IN) Vlan tag actions 11388 * Returns: 11389 * BCM_E_XXX 11390 */ 11391 int 11392 _bcm_trx_vlan_port_egress_default_action_get(int unit, bcm_port_t port, 11393 bcm_vlan_action_set_t *action) 11394 { 11395 uint32 profile_idx, rval; 11396 11397 #if defined(BCM_TOMAHAWK3_SUPPORT) 11398 if (SOC_IS_TOMAHAWK3(unit)) { 11399 return( 11400 _bcm_th3_vlan_port_egress_default_action_get(unit, port, action)); 11401 } 11402 #endif/* BCM_TOMAHAWK3_SUPPORT */ 11403 11404 bcm_vlan_action_set_t_init(action); 11405 #if defined(BCM_TOMAHAWK_SUPPORT) 11406 /* Tomahawk low latency mode */ 11407 if (soc_feature(unit, soc_feature_fast_egr_vlan_action)) { 11408 rval = _bcm_fast_egr_vlan_port_egress_default_action_get(unit, 11409 port, action); 11410 return rval; 11411 } 11412 #endif 11413 11414 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 11415 if(soc_feature(unit, soc_feature_egr_vlan_control_is_memory)){ 11416 return _bcm_td2p_vlan_port_egress_default_action_get(unit, port, 11417 action); 11418 } else 11419 #endif 11420 { 11421 BCM_IF_ERROR_RETURN 11422 (READ_EGR_VLAN_CONTROL_3r(unit, port, &rval)); 11423 profile_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 11424 rval, TAG_ACTION_PROFILE_PTRf); 11425 _bcm_trx_egr_vlan_action_profile_entry_get(unit, action, profile_idx); 11426 action->new_inner_vlan = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 11427 rval, IVIDf); 11428 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 11429 if (!soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, rval, 11430 IPRI_CFI_SELf)) { 11431 action->new_inner_pkt_prio = 11432 soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, rval, IPRIf); 11433 action->new_inner_cfi = 11434 soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, rval, ICFIf); 11435 } 11436 } 11437 11438 BCM_IF_ERROR_RETURN 11439 (READ_EGR_VLAN_CONTROL_2r(unit, port, &rval)); 11440 action->new_outer_vlan = soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, 11441 rval, OVIDf); 11442 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 11443 if (!soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, 11444 OPRI_CFI_SELf)) { 11445 action->priority = 11446 soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, OPRIf); 11447 action->new_outer_cfi = 11448 soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, OCFIf); 11449 } 11450 } else { 11451 if (soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, ORPEf)) { 11452 action->priority = soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, 11453 rval, OPRIf); 11454 } else { 11455 action->priority = -1; 11456 } 11457 } 11458 } 11459 11460 return BCM_E_NONE; 11461 } 11462 11463 /* 11464 * Function: 11465 * _bcm_tr_vlan_port_egress_default_action_delete 11466 * Purpose: 11467 * Deletes the egress port's default vlan tag actions 11468 * Parameters: 11469 * unit - (IN) BCM unit. 11470 * port - (IN) Port number. 11471 * Returns: 11472 * BCM_E_XXX 11473 */ 11474 int 11475 _bcm_trx_vlan_port_egress_default_action_delete(int unit, bcm_port_t port) 11476 { 11477 uint32 profile_idx, rval; 11478 11479 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 11480 if(soc_feature(unit, soc_feature_egr_vlan_control_is_memory)){ 11481 return _bcm_td2p_vlan_port_egress_default_action_delete(unit, port); 11482 } else 11483 #endif 11484 #if defined(BCM_TOMAHAWK3_SUPPORT) 11485 if (SOC_IS_TOMAHAWK3(unit)) { 11486 return(_bcm_th3_vlan_port_egress_default_action_delete(unit, port)); 11487 } else 11488 #endif/* BCM_TOMAHAWK3_SUPPORT */ 11489 { 11490 BCM_IF_ERROR_RETURN( 11491 READ_EGR_VLAN_CONTROL_3r(unit, port, &rval)); 11492 profile_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 11493 rval, TAG_ACTION_PROFILE_PTRf); 11494 11495 if (!SOC_IS_TRIDENT3X(unit)) { 11496 BCM_IF_ERROR_RETURN( 11497 _bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx)); 11498 } 11499 sal_memset(&rval, 0, sizeof(uint32)); 11500 BCM_IF_ERROR_RETURN( 11501 WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval)); 11502 BCM_IF_ERROR_RETURN( 11503 WRITE_EGR_VLAN_CONTROL_2r(unit, port, rval)); 11504 } 11505 11506 return BCM_E_NONE; 11507 } 11508 11509 int 11510 _bcm_trx_vlan_port_egress_action_profile_clear(int unit, bcm_port_t port) 11511 { 11512 uint32 rval; 11513 11514 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 11515 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 11516 return _bcm_td2p_vlan_port_egress_action_profile_clear(unit, port); 11517 } else 11518 #endif 11519 { 11520 BCM_IF_ERROR_RETURN( 11521 READ_EGR_VLAN_CONTROL_3r(unit, port, &rval)); 11522 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, 11523 &rval, TAG_ACTION_PROFILE_PTRf, 0); 11524 11525 BCM_IF_ERROR_RETURN( 11526 WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval)); 11527 } 11528 11529 return BCM_E_NONE; 11530 } 11531 11532 #if defined(BCM_TOMAHAWK_SUPPORT) 11533 /* 11534 * Function: 11535 * _bcm_fast_egr_vlan_port_egress_default_action_set 11536 * Purpose: 11537 * Set the egress port's default vlan tag actions in Low latency mode 11538 * Parameters: 11539 * unit - (IN) BCM unit. 11540 * port - (IN) Port number. 11541 * action - (IN) Vlan tag actions 11542 * Returns: 11543 * BCM_E_XXX 11544 */ 11545 STATIC int 11546 _bcm_fast_egr_vlan_port_egress_default_action_set( 11547 int unit, 11548 bcm_port_t port, 11549 bcm_vlan_action_set_t *action) 11550 { 11551 uint32 rval; 11552 11553 /* Verify vlan_action */ 11554 if (NULL == action) 11555 return BCM_E_PARAM; 11556 11557 switch(action->ot_outer) { 11558 case bcmVlanActionNone: 11559 case bcmVlanActionDelete: 11560 break; 11561 default: 11562 return BCM_E_PARAM; 11563 } 11564 switch(action->ot_outer_prio) { 11565 case bcmVlanActionNone: 11566 case bcmVlanActionDelete: 11567 break; 11568 default: 11569 return BCM_E_PARAM; 11570 } 11571 switch(action->ut_outer) { 11572 case bcmVlanActionNone: 11573 break; 11574 default: 11575 return BCM_E_PARAM; 11576 } 11577 11578 /* Check for non-zero value on other fields */ 11579 if ((action->new_outer_vlan) | (action->new_inner_vlan) | (action->new_inner_pkt_prio) 11580 | (action->new_outer_cfi) | (action->new_inner_cfi) | (action->ingress_if) 11581 | (action->priority) | (action->dt_outer) | (action->dt_outer_prio) 11582 | (action->dt_outer_pkt_prio) | (action->dt_outer_cfi) | (action->dt_inner)) { 11583 return BCM_E_UNAVAIL; 11584 } 11585 if ((action->dt_inner_prio) | (action->dt_inner_pkt_prio) | (action->dt_inner_cfi) 11586 | (action->ot_outer_pkt_prio) | (action->ot_outer_cfi) | (action->ot_inner) 11587 | (action->ot_inner_pkt_prio) | (action->ot_inner_cfi) | (action->it_outer) 11588 | (action->it_outer_pkt_prio) | (action->it_outer_cfi) | (action->it_inner) 11589 | (action->it_inner_prio) | (action->it_inner_pkt_prio) | (action->it_inner_cfi)) { 11590 return BCM_E_UNAVAIL; 11591 } 11592 if ((action->ut_outer_pkt_prio) | (action->ut_outer_cfi) | (action->ut_inner) 11593 | (action->ut_inner_pkt_prio) | (action->ut_inner_cfi) | (action->outer_pcp) 11594 | (action->inner_pcp) | (action->policer_id) | (action->outer_tpid) 11595 | (action->inner_tpid) | (action->outer_tpid_action) | (action->inner_tpid_action) 11596 | (action->action_id) | (action->class_id) | (action->flags)) { 11597 return BCM_E_UNAVAIL; 11598 } 11599 11600 SOC_IF_ERROR_RETURN( 11601 READ_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, port, &rval)); 11602 11603 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval, 11604 SOT_OTAG_ACTIONf, _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer)); 11605 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval, 11606 SOT_POTAG_ACTIONf, _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_prio)); 11607 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval, 11608 UT_OTAG_ACTIONf, _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer)); 11609 11610 SOC_IF_ERROR_RETURN( 11611 WRITE_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, port, rval)); 11612 11613 return BCM_E_NONE; 11614 } 11615 11616 /* 11617 * Function: 11618 * _bcm_fast_egr_vlan_port_egress_default_action_get 11619 * Purpose: 11620 * Get the egress port's default vlan tag actions in Low latency mode 11621 * Parameters: 11622 * unit - (IN) BCM unit. 11623 * port - (IN) Port number. 11624 * action - (IN) Vlan tag actions 11625 * Returns: 11626 * BCM_E_XXX 11627 */ 11628 STATIC int 11629 _bcm_fast_egr_vlan_port_egress_default_action_get( 11630 int unit, 11631 bcm_port_t port, 11632 bcm_vlan_action_set_t *action) 11633 { 11634 uint32 rval; 11635 11636 /* Verify output param */ 11637 if (NULL == action) 11638 return BCM_E_PARAM; 11639 11640 SOC_IF_ERROR_RETURN( 11641 READ_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, port, &rval)); 11642 11643 action->ot_outer = _BCM_TRX_PRI_CFI_ACTION_ENCODE(soc_reg_field_get(unit, 11644 EGR_VLAN_TAG_ACTION_FOR_BYPASSr, rval, SOT_OTAG_ACTIONf)); 11645 action->ot_outer_prio = _BCM_TRX_PRI_CFI_ACTION_ENCODE(soc_reg_field_get(unit, 11646 EGR_VLAN_TAG_ACTION_FOR_BYPASSr, rval, SOT_POTAG_ACTIONf)); 11647 action->ut_outer = _BCM_TRX_PRI_CFI_ACTION_ENCODE(soc_reg_field_get(unit, 11648 EGR_VLAN_TAG_ACTION_FOR_BYPASSr, rval, UT_OTAG_ACTIONf)); 11649 11650 return BCM_E_NONE; 11651 } 11652 #endif 11653 11654 /* 11655 * Function: 11656 * _bcm_tr_vlan_translate_entry_update 11657 * Purpose: 11658 * Update VLAN XLATE Entry 11659 * Parameters: 11660 * IN : Unit 11661 * IN : vlan_xlate_entry 11662 * OUT : vlan_xlate_entry 11663 11664 */ 11665 11666 STATIC int 11667 _bcm_tr_vlan_translate_entry_update(int unit, void *vent, void *return_ent) 11668 { 11669 uint32 vp, key_type, value; 11670 soc_mem_t mem = VLAN_XLATEm; 11671 11672 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 11673 mem = VLAN_XLATE_1_DOUBLEm; 11674 } 11675 11676 /* Check if Key_Type identical */ 11677 key_type = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf); 11678 value = soc_mem_field32_get(unit, mem, return_ent, KEY_TYPEf); 11679 if (key_type != value) { 11680 return BCM_E_PARAM; 11681 } 11682 11683 soc_mem_field32_set(unit, mem, return_ent, MPLS_ACTIONf, 0x1); 11684 soc_mem_field32_set(unit, mem, return_ent, DISABLE_VLAN_CHECKSf, 1); 11685 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_VPf)) { 11686 vp = soc_mem_field32_get(unit, mem, vent, SOURCE_VPf); 11687 soc_mem_field32_set(unit, mem, return_ent, SOURCE_VPf, vp); 11688 } 11689 return BCM_E_NONE; 11690 } 11691 11692 /* 11693 * Function: 11694 * _bcm_tr3_vlan_translate_entry_update 11695 * Purpose: 11696 * Update VLAN XLATE Entry 11697 * Parameters: 11698 * IN : Unit 11699 * IN : vlan_xlate_extd_entry 11700 * OUT : vlan_xlate_extd_entry 11701 */ 11702 11703 #if defined(BCM_TRIUMPH3_SUPPORT) 11704 STATIC int 11705 _bcm_tr3_vxlate_extd_entry_vp_update(int unit, 11706 vlan_xlate_entry_t *vent_in, /* update entry */ 11707 void *ctxt, 11708 vlan_xlate_entry_t *vent_out, /* entry read from mem */ 11709 vlan_xlate_extd_entry_t *vxent_out, /* entry read from mem or 11710 converted from vent_out if not null */ 11711 int *use_extd_tbl) 11712 { 11713 uint32 vp; 11714 11715 vp = PTR_TO_INT(ctxt); 11716 11717 if (vent_out) { 11718 BCM_IF_ERROR_RETURN 11719 (_bcm_tr3_vxlate2vxlate_extd(unit,vent_out,vxent_out)); 11720 } 11721 11722 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out,XLATE__MPLS_ACTIONf, 0x1); 11723 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out, DISABLE_VLAN_CHECKSf, 1); 11724 soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out, SOURCE_VPf, vp); 11725 *use_extd_tbl = TRUE; 11726 return BCM_E_NONE; 11727 } 11728 #endif 11729 11730 11731 int 11732 _bcm_tr_vlan_translate_vp_add(int unit, 11733 bcm_gport_t port, 11734 bcm_vlan_translate_key_t key_type, 11735 bcm_vlan_t outer_vlan, 11736 bcm_vlan_t inner_vlan, 11737 int vp, bcm_vlan_action_set_t *action, 11738 int *existing_updated) 11739 { 11740 int rv, gport_id; 11741 vlan_xlate_entry_t vx_ent, vx_ent_old; 11742 vlan_xlate_1_double_entry_t vx1d_ent, vx1d_ent_old; 11743 bcm_module_t mod_out; 11744 bcm_port_t port_out; 11745 bcm_trunk_t trunk_id; 11746 int idx; 11747 int key_type_value; 11748 uint32 vxlate_action_profile_idx; 11749 uint32 vxlate_action_profile_idx_old; 11750 11751 soc_mem_t mem = VLAN_XLATEm; 11752 soc_field_t vf = VALIDf; 11753 void *vent = &vx_ent; 11754 void *vent_old = &vx_ent_old; 11755 uint32 ent_sz = sizeof(vx_ent); 11756 11757 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 11758 mem = VLAN_XLATE_1_DOUBLEm; 11759 vf = BASE_VALID_0f; /* TD3TBD */ 11760 vent = &vx1d_ent; 11761 vent_old = &vx1d_ent_old; 11762 ent_sz = sizeof(vx1d_ent); 11763 } 11764 11765 rv = BCM_E_NONE; 11766 sal_memset(vent, 0, ent_sz); 11767 switch (key_type) { 11768 case bcmVlanTranslateKeyPortOuter: 11769 BCM_IF_ERROR_RETURN 11770 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 11771 VLXLT_HASH_KEY_TYPE_OVID, 11772 &key_type_value)); 11773 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 11774 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 11775 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 11776 key_type_value); 11777 } 11778 soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan); 11779 break; 11780 case bcmVlanTranslateKeyPortInner: 11781 BCM_IF_ERROR_RETURN 11782 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 11783 VLXLT_HASH_KEY_TYPE_IVID, 11784 &key_type_value)); 11785 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 11786 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 11787 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 11788 key_type_value); 11789 } 11790 soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan); 11791 break; 11792 case bcmVlanTranslateKeyPortDouble: 11793 BCM_IF_ERROR_RETURN 11794 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 11795 VLXLT_HASH_KEY_TYPE_IVID_OVID, 11796 &key_type_value)); 11797 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 11798 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 11799 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 11800 key_type_value); 11801 } 11802 soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan); 11803 soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan); 11804 break; 11805 case bcmVlanTranslateKeyPortOuterPri: 11806 BCM_IF_ERROR_RETURN 11807 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 11808 VLXLT_HASH_KEY_TYPE_PRI_CFI, 11809 &key_type_value)); 11810 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 11811 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 11812 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 11813 key_type_value); 11814 } 11815 /* outer_vlan: Bits 12-15 contains VLAN_PRI + CFI, vlan=BCM_E_NONE */ 11816 soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan); 11817 break; 11818 case bcmVlanTranslateKeyPortOuterTag: 11819 /* allow 16 bit VLAN id */ 11820 BCM_IF_ERROR_RETURN 11821 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 11822 VLXLT_HASH_KEY_TYPE_OTAG, 11823 &key_type_value)); 11824 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 11825 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 11826 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 11827 key_type_value); 11828 } 11829 soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan); 11830 break; 11831 default: 11832 return BCM_E_PARAM; 11833 } 11834 BCM_IF_ERROR_RETURN 11835 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id, 11836 &gport_id)); 11837 11838 if (BCM_GPORT_IS_TRUNK(port)) { 11839 soc_mem_field32_set(unit, mem, vent, Tf, 1); 11840 soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_id); 11841 } else { 11842 soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out); 11843 soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out); 11844 } 11845 11846 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_VPf)) { 11847 soc_mem_field32_set(unit, mem, vent, SOURCE_VPf, vp); 11848 } 11849 11850 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 11851 /* set default vlan_xlate key source_type as SGLP */ 11852 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 11853 } 11854 11855 if (mem == VLAN_XLATEm) { 11856 soc_mem_field32_set(unit, mem, vent, vf, 1); 11857 } else { 11858 soc_mem_field32_set(unit, mem, vent, vf, 3); 11859 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 11860 } 11861 11862 if (action) { 11863 vxlate_action_profile_idx = 0; 11864 BCM_IF_ERROR_RETURN( 11865 _bcm_trx_vlan_action_verify(unit, action)); 11866 vxlate_action_profile_idx_old = 11867 soc_mem_field32_get(unit, mem, vent, TAG_ACTION_PROFILE_PTRf); 11868 /* Add new tag action profile table ptr */ 11869 BCM_IF_ERROR_RETURN 11870 (_bcm_trx_vlan_action_profile_entry_add(unit, action, 11871 &vxlate_action_profile_idx)); 11872 soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf, 11873 vxlate_action_profile_idx); 11874 /* Delete old tag action profile table ptr expect entry zero 11875 * It contains initialize cache hardware ING_VLAN_TAG_ACTION_PROFILE 11876 * and EGR_VLAN_TAG_ACTION_PROFILE tables in RAM. 11877 * ING_VLAN profile contains PORT_TAB and VLAN_PROTOCOL_DATA 11878 * EGR_VLAN profile contains all ports, sub ports and vlan subnets */ 11879 if (vxlate_action_profile_idx_old != ING_ACTION_PROFILE_DEFAULT) { 11880 BCM_IF_ERROR_RETURN 11881 (_bcm_trx_vlan_action_profile_entry_delete(unit, 11882 vxlate_action_profile_idx_old)); 11883 } 11884 /* Set new OVID and IVID from the 'action' specified */ 11885 soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, action->new_outer_vlan); 11886 soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, action->new_inner_vlan); 11887 11888 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) || \ 11889 defined(BCM_GREYHOUND2_SUPPORT) 11890 if (soc_feature(unit, soc_feature_global_meter) && 11891 (SOC_IS_KATANAX(unit) || SOC_IS_APACHE(unit) || 11892 SOC_IS_GREYHOUND2(unit))) { 11893 rv = _bcm_esw_add_policer_to_table(unit, action->policer_id, 11894 mem,0, vent); 11895 BCM_IF_ERROR_RETURN(rv); 11896 } 11897 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT || 11898 BCM_GREYHOUND2_SUPPORT */ 11899 } 11900 11901 #if defined(BCM_TRIUMPH3_SUPPORT) 11902 if (SOC_IS_TRIUMPH3(unit)) { 11903 BCM_IF_ERROR_RETURN 11904 (_bcm_tr3_vxlate_entry_add(unit,vent, 11905 (void *)INT_TO_PTR(vp), 11906 _bcm_tr3_vxlate_extd_entry_vp_update, 11907 existing_updated)); 11908 } else 11909 #endif 11910 { 11911 soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x1); /* SVP */ 11912 if (action) { 11913 if (action->flags & BCM_VLAN_ACTION_SET_VLAN_CHECKS_DISABLE) { 11914 soc_mem_field32_set(unit, mem, vent, DISABLE_VLAN_CHECKSf, 1); 11915 } 11916 } 11917 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_ACTION_VALIDf)) { 11918 soc_mem_field32_set(unit, mem, vent, VLAN_ACTION_VALIDf, 1); 11919 } 11920 11921 /* look up existing entry */ 11922 soc_mem_lock(unit, mem); 11923 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, vent, vent_old, 0); 11924 if(rv == SOC_E_NONE) { 11925 BCM_IF_ERROR_RETURN( 11926 _bcm_tr_vlan_translate_entry_update (unit, vent, vent_old)); 11927 rv = soc_mem_write(unit, mem, 11928 MEM_BLOCK_ALL, idx, vent_old); 11929 if (existing_updated != NULL) { 11930 *existing_updated = 1; 11931 } 11932 soc_mem_unlock(unit, mem); 11933 return BCM_E_EXISTS; 11934 } else if (rv != SOC_E_NOT_FOUND) { 11935 soc_mem_unlock(unit, mem); 11936 return rv; 11937 } 11938 11939 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent); 11940 soc_mem_unlock(unit, mem); 11941 } 11942 return rv; 11943 } 11944 11945 int 11946 _bcm_tr_lltag_vlan_translate_vp_add(int unit, 11947 bcm_gport_t port, 11948 bcm_vlan_translate_key_t key_type, 11949 bcm_vlan_t lltag_vlan, 11950 bcm_vlan_t other_vlan, 11951 int vp, bcm_vlan_action_set_t *action) 11952 { 11953 int rv, gport_id; 11954 vlan_xlate_entry_t vx_ent, vx_ent_old; 11955 vlan_xlate_1_double_entry_t v1dent, v1dent_old; 11956 bcm_module_t mod_out; 11957 bcm_port_t port_out; 11958 bcm_trunk_t trunk_id; 11959 int idx; 11960 int key_type_value; 11961 uint32 vxlate_action_profile_idx; 11962 uint32 vxlate_action_profile_idx_old; 11963 soc_mem_t mem = VLAN_XLATEm; 11964 soc_field_t vf = VALIDf; 11965 void *vent = &vx_ent; 11966 void *vent_old = &vx_ent_old; 11967 uint32 ent_sz = sizeof(vx_ent); 11968 11969 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 11970 mem = VLAN_XLATE_1_DOUBLEm; 11971 vf = BASE_VALID_0f; /* TD3TBD */ 11972 vent = &v1dent; 11973 vent_old = &v1dent_old; 11974 ent_sz = sizeof(v1dent); 11975 } 11976 11977 rv = BCM_E_NONE; 11978 11979 if (!soc_feature(unit, soc_feature_lltag)) { 11980 return BCM_E_UNAVAIL; 11981 } 11982 11983 sal_memset(vent, 0, ent_sz); 11984 switch (key_type) { 11985 case bcmVlanTranslateKeyPortPonTunnel: 11986 BCM_IF_ERROR_RETURN 11987 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 11988 VLXLT_HASH_KEY_TYPE_LLVID, 11989 &key_type_value)); 11990 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 11991 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 11992 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 11993 key_type_value); 11994 } 11995 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan); 11996 break; 11997 case bcmVlanTranslateKeyPortPonTunnelOuter: 11998 BCM_IF_ERROR_RETURN 11999 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12000 VLXLT_HASH_KEY_TYPE_LLVID_OVID, 12001 &key_type_value)); 12002 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12003 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12004 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12005 key_type_value); 12006 } 12007 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan); 12008 soc_mem_field32_set(unit, mem, vent, LLTAG__OVIDf, other_vlan); 12009 break; 12010 case bcmVlanTranslateKeyPortPonTunnelInner: 12011 BCM_IF_ERROR_RETURN 12012 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12013 VLXLT_HASK_KEY_TYPE_LLVID_IVID, 12014 &key_type_value)); 12015 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12016 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12017 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12018 key_type_value); 12019 } 12020 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan); 12021 soc_mem_field32_set(unit, mem, vent, LLTAG__IVIDf, other_vlan); 12022 break; 12023 default: 12024 return BCM_E_PARAM; 12025 } 12026 BCM_IF_ERROR_RETURN 12027 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id, 12028 &gport_id)); 12029 12030 if (BCM_GPORT_IS_TRUNK(port)) { 12031 soc_mem_field32_set(unit, mem, vent, Tf, 1); 12032 soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_id); 12033 } else { 12034 soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out); 12035 soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out); 12036 } 12037 12038 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_VPf)) { 12039 soc_mem_field32_set(unit, mem, vent, SOURCE_VPf, vp); 12040 } 12041 12042 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 12043 /* set default vlan_xlate key source_type as SGLP */ 12044 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 12045 } 12046 12047 if (mem == VLAN_XLATEm) { 12048 soc_mem_field32_set(unit, mem, vent, vf, 1); 12049 } else { 12050 soc_mem_field32_set(unit, mem, vent, vf, 3); 12051 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 12052 } 12053 12054 if (action) { 12055 vxlate_action_profile_idx = 0; 12056 BCM_IF_ERROR_RETURN( 12057 _bcm_trx_vlan_action_verify(unit, action)); 12058 vxlate_action_profile_idx_old = 12059 soc_mem_field32_get(unit, mem, vent, TAG_ACTION_PROFILE_PTRf); 12060 /* Add new tag action profile table ptr */ 12061 BCM_IF_ERROR_RETURN 12062 (_bcm_trx_vlan_action_profile_entry_add(unit, action, 12063 &vxlate_action_profile_idx)); 12064 soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf, 12065 vxlate_action_profile_idx); 12066 /* Delete old tag action profile table ptr expect entry zero 12067 * It contains initialize cache hardware ING_VLAN_TAG_ACTION_PROFILE 12068 * and EGR_VLAN_TAG_ACTION_PROFILE tables in RAM. 12069 * ING_VLAN profile contains PORT_TAB and VLAN_PROTOCOL_DATA 12070 * EGR_VLAN profile contains all ports, sub ports and vlan subnets 12071 */ 12072 if (vxlate_action_profile_idx_old != 0) { 12073 BCM_IF_ERROR_RETURN 12074 (_bcm_trx_vlan_action_profile_entry_delete(unit, 12075 vxlate_action_profile_idx_old)); 12076 } 12077 /* Set new OVID and IVID from the 'action' specified */ 12078 soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, action->new_outer_vlan); 12079 soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, action->new_inner_vlan); 12080 } 12081 12082 soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x1); /* SVP */ 12083 soc_mem_field32_set(unit, mem, vent, DISABLE_VLAN_CHECKSf, 1); 12084 if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_ACTION_VALIDf)) { 12085 soc_mem_field32_set(unit, mem, vent, VLAN_ACTION_VALIDf, 1); 12086 } 12087 12088 /* look up existing entry */ 12089 soc_mem_lock(unit, mem); 12090 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, vent, vent_old, 0); 12091 if(rv == SOC_E_NONE) { 12092 BCM_IF_ERROR_RETURN( 12093 _bcm_tr_vlan_translate_entry_update (unit, vent, vent_old)); 12094 rv = soc_mem_write(unit, mem, 12095 MEM_BLOCK_ALL, idx, vent_old); 12096 soc_mem_unlock(unit, mem); 12097 return BCM_E_EXISTS; 12098 } else if (rv != SOC_E_NOT_FOUND) { 12099 soc_mem_unlock(unit, mem); 12100 return rv; 12101 } 12102 12103 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent); 12104 soc_mem_unlock(unit, mem); 12105 12106 return rv; 12107 } 12108 12109 12110 int 12111 _bcm_tr_vlan_translate_vp_delete(int unit, 12112 bcm_gport_t port, 12113 bcm_vlan_translate_key_t key_type, 12114 bcm_vlan_t outer_vlan, 12115 bcm_vlan_t inner_vlan, 12116 int vp) 12117 { 12118 int rv, gport_id; 12119 vlan_xlate_entry_t vx_ent; 12120 vlan_xlate_1_double_entry_t vx1d_ent; 12121 bcm_module_t mod_out; 12122 bcm_port_t port_out; 12123 bcm_trunk_t trunk_id; 12124 int key_type_value; 12125 12126 soc_mem_t mem = VLAN_XLATEm; 12127 soc_field_t vf = VALIDf; 12128 void *vent = &vx_ent; 12129 uint32 ent_sz = sizeof(vx_ent); 12130 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) || \ 12131 defined(BCM_GREYHOUND2_SUPPORT) 12132 vlan_xlate_entry_t current_vent; 12133 bcm_policer_t current_policer = 0; 12134 int idx; 12135 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT || 12136 BCM_GREYHOUND2_SUPPORT */ 12137 12138 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 12139 mem = VLAN_XLATE_1_DOUBLEm; 12140 vf = BASE_VALID_0f; /* TD3TBD */ 12141 vent = &vx1d_ent; 12142 ent_sz = sizeof(vx1d_ent); 12143 } 12144 12145 sal_memset(vent, 0, ent_sz); 12146 switch (key_type) { 12147 case bcmVlanTranslateKeyPortOuter: 12148 BCM_IF_ERROR_RETURN 12149 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12150 VLXLT_HASH_KEY_TYPE_OVID, 12151 &key_type_value)); 12152 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12153 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12154 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12155 key_type_value); 12156 } 12157 soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan); 12158 break; 12159 case bcmVlanTranslateKeyPortInner: 12160 BCM_IF_ERROR_RETURN 12161 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12162 VLXLT_HASH_KEY_TYPE_IVID, 12163 &key_type_value)); 12164 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12165 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12166 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12167 key_type_value); 12168 } 12169 soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan); 12170 break; 12171 case bcmVlanTranslateKeyPortDouble: 12172 BCM_IF_ERROR_RETURN 12173 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12174 VLXLT_HASH_KEY_TYPE_IVID_OVID, 12175 &key_type_value)); 12176 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12177 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12178 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12179 key_type_value); 12180 } 12181 soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan); 12182 soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan); 12183 break; 12184 case bcmVlanTranslateKeyPortOuterPri: 12185 BCM_IF_ERROR_RETURN 12186 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12187 VLXLT_HASH_KEY_TYPE_PRI_CFI, 12188 &key_type_value)); 12189 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12190 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12191 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12192 key_type_value); 12193 } 12194 soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan); 12195 break; 12196 case bcmVlanTranslateKeyPortOuterTag: 12197 /* allow 16 bit VLAN id */ 12198 BCM_IF_ERROR_RETURN 12199 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12200 VLXLT_HASH_KEY_TYPE_OTAG, 12201 &key_type_value)); 12202 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12203 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12204 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12205 key_type_value); 12206 } 12207 soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan); 12208 break; 12209 default: 12210 return BCM_E_PARAM; 12211 } 12212 BCM_IF_ERROR_RETURN 12213 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id, 12214 &gport_id)); 12215 12216 if (BCM_GPORT_IS_TRUNK(port)) { 12217 soc_mem_field32_set(unit, mem, vent, Tf, 1); 12218 soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_id); 12219 } else { 12220 soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out); 12221 soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out); 12222 } 12223 12224 if (mem == VLAN_XLATEm) { 12225 soc_mem_field32_set(unit, mem, vent, vf, 1); 12226 } else { 12227 soc_mem_field32_set(unit, mem, vent, vf, 3); 12228 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 12229 } 12230 12231 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 12232 /* set default vlan_xlate key source_type as SGLP */ 12233 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 12234 } 12235 12236 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) || \ 12237 defined(BCM_GREYHOUND2_SUPPORT) 12238 if (soc_feature(unit, soc_feature_global_meter) && 12239 (SOC_IS_KATANAX(unit) || SOC_IS_APACHE(unit) || 12240 SOC_IS_GREYHOUND2(unit))) { 12241 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, vent, ¤t_vent, 0); 12242 if (rv == BCM_E_NONE) { 12243 rv = _bcm_esw_get_policer_from_table(unit, mem, 0, ¤t_vent, 12244 ¤t_policer, 1); 12245 if (current_policer) { 12246 rv = _bcm_esw_policer_decrement_ref_count(unit, 12247 current_policer); 12248 BCM_IF_ERROR_RETURN(rv); 12249 } 12250 } 12251 } 12252 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT || 12253 BCM_GREYHOUND2_SUPPORT */ 12254 12255 soc_mem_lock(unit, mem); 12256 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent); 12257 soc_mem_unlock(unit, mem); 12258 12259 #if defined(BCM_TRIUMPH3_SUPPORT) 12260 if (SOC_IS_TRIUMPH3(unit)) { 12261 vlan_xlate_extd_entry_t vxent; 12262 12263 if (rv == BCM_E_NOT_FOUND) { /* serarch for extend table */ 12264 sal_memset(&vxent, 0, sizeof(vxent)); 12265 BCM_IF_ERROR_RETURN 12266 (_bcm_tr3_vxlate2vxlate_extd(unit,vent,&vxent)); 12267 soc_mem_lock(unit, VLAN_XLATE_EXTDm); 12268 rv = soc_mem_delete(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ANY, &vxent); 12269 soc_mem_unlock(unit, VLAN_XLATE_EXTDm); 12270 return rv; 12271 } 12272 } 12273 #endif 12274 return rv; 12275 } 12276 12277 int 12278 _bcm_tr_lltag_vlan_translate_vp_delete(int unit, 12279 bcm_gport_t port, 12280 bcm_vlan_translate_key_t key_type, 12281 bcm_vlan_t lltag_vlan, 12282 bcm_vlan_t other_vlan, 12283 int vp) 12284 { 12285 int rv, gport_id; 12286 vlan_xlate_entry_t vx_ent; 12287 vlan_xlate_1_double_entry_t vx1d_ent; 12288 bcm_module_t mod_out; 12289 bcm_port_t port_out; 12290 bcm_trunk_t trunk_id; 12291 int key_type_value; 12292 12293 soc_mem_t mem = VLAN_XLATEm; 12294 soc_field_t vf = VALIDf; 12295 void *vent = &vx_ent; 12296 uint32 ent_sz = sizeof(vx_ent); 12297 12298 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 12299 mem = VLAN_XLATE_1_DOUBLEm; 12300 vf = BASE_VALID_0f; /* TD3TBD */ 12301 vent = &vx1d_ent; 12302 ent_sz = sizeof(vx1d_ent); 12303 } 12304 12305 if (!soc_feature(unit, soc_feature_lltag)) { 12306 return BCM_E_UNAVAIL; 12307 } 12308 12309 sal_memset(vent, 0, ent_sz); 12310 switch (key_type) { 12311 case bcmVlanTranslateKeyPortPonTunnel: 12312 BCM_IF_ERROR_RETURN 12313 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12314 VLXLT_HASH_KEY_TYPE_LLVID, 12315 &key_type_value)); 12316 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12317 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12318 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12319 key_type_value); 12320 } 12321 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan); 12322 break; 12323 case bcmVlanTranslateKeyPortPonTunnelOuter: 12324 BCM_IF_ERROR_RETURN 12325 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12326 VLXLT_HASH_KEY_TYPE_LLVID_OVID, 12327 &key_type_value)); 12328 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12329 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12330 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12331 key_type_value); 12332 } 12333 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan); 12334 soc_mem_field32_set(unit, mem, vent, LLTAG__OVIDf, other_vlan); 12335 break; 12336 case bcmVlanTranslateKeyPortPonTunnelInner: 12337 BCM_IF_ERROR_RETURN 12338 (_bcm_esw_vlan_xlate_key_type_value_get(unit, 12339 VLXLT_HASK_KEY_TYPE_LLVID_IVID, 12340 &key_type_value)); 12341 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value); 12342 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) { 12343 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, 12344 key_type_value); 12345 } 12346 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan); 12347 soc_mem_field32_set(unit, mem, vent, LLTAG__OVIDf, other_vlan); 12348 break; 12349 default: 12350 return BCM_E_PARAM; 12351 } 12352 BCM_IF_ERROR_RETURN 12353 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id, 12354 &gport_id)); 12355 12356 if (BCM_GPORT_IS_TRUNK(port)) { 12357 soc_mem_field32_set(unit, mem, vent, Tf, 1); 12358 soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_id); 12359 } else { 12360 soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out); 12361 soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out); 12362 } 12363 12364 if (mem == VLAN_XLATEm) { 12365 soc_mem_field32_set(unit, mem, vent, vf, 1); 12366 } else { 12367 soc_mem_field32_set(unit, mem, vent, vf, 3); 12368 soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7); 12369 } 12370 12371 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 12372 /* set default vlan_xlate key source_type as SGLP */ 12373 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1); 12374 } 12375 12376 soc_mem_lock(unit, mem); 12377 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent); 12378 soc_mem_unlock(unit, mem); 12379 12380 return rv; 12381 } 12382 12383 12384 #ifdef BCM_TRIUMPH2_SUPPORT 12385 #define _BCM_OUTER_VLAN_RANGE_TYPE 0 12386 #define _BCM_INNER_VLAN_RANGE_TYPE 1 12387 12388 int 12389 _bcm_tr2_vlan_tranlate_range_data_insert(bcm_vlan_t vlan_low, bcm_vlan_t vlan_high, 12390 bcm_vlan_t *min_vlan, bcm_vlan_t *max_vlan) 12391 { 12392 int i = 0; 12393 /* Find the first unused min/max range. Unused ranges are 12394 * identified by { min == 1, max == 0 } 12395 */ 12396 for (i = 0 ; i < 8 ; i++) { 12397 if ((min_vlan[i] == 1) && (max_vlan[i] == 0)) { 12398 break; 12399 } else if (min_vlan[i] == vlan_low) { 12400 /* Can't have multiple ranges with the same min */ 12401 return BCM_E_EXISTS; 12402 } 12403 } 12404 if (i == 8) { 12405 /* All ranges are taken */ 12406 return BCM_E_FULL; 12407 } 12408 12409 /* Insert the new range into the table entry sorted by min VID */ 12410 for ( ; i > 0 ; i--) { 12411 if (min_vlan[i - 1] > vlan_low) { 12412 /* Move existing min/max down */ 12413 min_vlan[i] = min_vlan[i - 1]; 12414 max_vlan[i] = max_vlan[i - 1]; 12415 } else { 12416 break; 12417 } 12418 } 12419 min_vlan[i] = vlan_low; 12420 max_vlan[i] = vlan_high; 12421 return BCM_E_NONE; 12422 } 12423 12424 int 12425 _bcm_tr2_vlan_tranlate_range_data_delete(bcm_vlan_t vlan_low, bcm_vlan_t vlan_high, 12426 bcm_vlan_t *min_vlan, bcm_vlan_t *max_vlan) 12427 { 12428 int i = 0; 12429 /* Find the min/max range. */ 12430 for (i = 0; i < 8; i++) { 12431 if ((min_vlan[i] == vlan_low) && (max_vlan[i] == vlan_high)) { 12432 break; 12433 } 12434 } 12435 if (i == 8) { 12436 return BCM_E_NOT_FOUND; 12437 } 12438 12439 /* Remove the range from the table entry and fill in the gap */ 12440 for (; i < 7; i++) { 12441 /* Move existing min/max UP */ 12442 min_vlan[i] = min_vlan[i + 1]; 12443 max_vlan[i] = max_vlan[i + 1]; 12444 } 12445 /* Mark last min/max range as unused. Unused ranges are 12446 * identified by { min == 1, max == 0 } 12447 */ 12448 min_vlan[i] = 1; 12449 max_vlan[i] = 0; 12450 return BCM_E_NONE; 12451 } 12452 12453 12454 int 12455 _bcm_tr2_port_vlan_translate_range_profile_update(int unit, bcm_vlan_t *min_vlan, bcm_vlan_t *max_vlan, 12456 bcm_module_t module, bcm_port_t port, int vt_range_type, 12457 uint32 *new_idx) 12458 { 12459 int rv = BCM_E_NONE; 12460 uint32 new_idx_local; 12461 int stm_idx; 12462 rv = _bcm_trx_vlan_range_profile_entry_add(unit, min_vlan, max_vlan, 12463 &new_idx_local); 12464 if (BCM_FAILURE(rv)) { 12465 return rv; 12466 } 12467 rv = _bcm_esw_src_mod_port_table_index_get(unit, module, port, &stm_idx); 12468 if (BCM_SUCCESS(rv)) { 12469 soc_field_t field; 12470 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 12471 OUTER_VLAN_RANGE_IDXf) & (vt_range_type == _BCM_OUTER_VLAN_RANGE_TYPE)) { 12472 field = OUTER_VLAN_RANGE_IDXf; 12473 } else if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 12474 INNER_VLAN_RANGE_IDXf) & (vt_range_type == _BCM_INNER_VLAN_RANGE_TYPE)) { 12475 field = INNER_VLAN_RANGE_IDXf; 12476 } else { 12477 field = VLAN_RANGE_IDXf; 12478 } 12479 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, stm_idx, 12480 field, new_idx_local); 12481 } 12482 if (BCM_FAILURE(rv)) { 12483 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx_local); 12484 return rv; 12485 } 12486 *new_idx = new_idx_local; 12487 return rv; 12488 } 12489 12490 int 12491 _bcm_tr2_vlan_translate_range_vp_add(int unit, 12492 bcm_gport_t port, 12493 bcm_vlan_t outer_vlan_low, 12494 bcm_vlan_t outer_vlan_high, 12495 bcm_vlan_t inner_vlan_low, 12496 bcm_vlan_t inner_vlan_high, 12497 int vp, 12498 bcm_vlan_action_set_t *action) 12499 { 12500 int i, key_type = 0, rv, gport_id, old_idx = -1, old_idx_inner = -1, stm_idx = 0; 12501 uint32 new_idx = -1, new_idx_inner = -1; 12502 source_trunk_map_table_entry_t stm_entry; 12503 bcm_module_t mod_out; 12504 bcm_port_t port_out; 12505 bcm_trunk_t trunk_id, tid; 12506 bcm_vlan_t min_vlan[8], max_vlan[8]; 12507 int port_count; 12508 bcm_trunk_member_t *member_array = NULL; 12509 bcm_module_t *mod_array = NULL; 12510 bcm_port_t *port_array = NULL; 12511 int trunk128; 12512 if (outer_vlan_low != BCM_VLAN_INVALID && 12513 inner_vlan_low != BCM_VLAN_INVALID) { 12514 key_type = bcmVlanTranslateKeyPortDouble; 12515 } else if (outer_vlan_low != BCM_VLAN_INVALID) { 12516 key_type = bcmVlanTranslateKeyPortOuter; 12517 } else if (inner_vlan_low != BCM_VLAN_INVALID) { 12518 key_type = bcmVlanTranslateKeyPortInner; 12519 } else { 12520 return BCM_E_PARAM; 12521 } 12522 12523 BCM_IF_ERROR_RETURN 12524 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id, 12525 &gport_id)); 12526 12527 if (BCM_GPORT_IS_TRUNK(port)) { 12528 if (BCM_TRUNK_INVALID == trunk_id) { 12529 return BCM_E_PORT; 12530 } 12531 12532 BCM_IF_ERROR_RETURN 12533 (bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, &port_count)); 12534 12535 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 12536 "trunk member array"); 12537 if (member_array == NULL) { 12538 rv = BCM_E_MEMORY; 12539 goto cleanup; 12540 } 12541 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 12542 12543 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 12544 member_array, &port_count); 12545 if (BCM_FAILURE(rv)) { 12546 goto cleanup; 12547 } 12548 12549 mod_array = sal_alloc(sizeof(bcm_module_t) * port_count, 12550 "module ID array"); 12551 if (mod_array == NULL) { 12552 rv = BCM_E_MEMORY; 12553 goto cleanup; 12554 } 12555 sal_memset(mod_array, 0, sizeof(bcm_module_t) * port_count); 12556 12557 port_array = sal_alloc(sizeof(bcm_port_t) * port_count, 12558 "port ID array"); 12559 if (port_array == NULL) { 12560 rv = BCM_E_MEMORY; 12561 goto cleanup; 12562 } 12563 sal_memset(port_array, 0, sizeof(bcm_port_t) * port_count); 12564 12565 for (i = 0; i < port_count; i++) { 12566 rv = _bcm_esw_gport_resolve(unit, member_array[i].gport, 12567 &mod_array[i], &port_array[i], &tid, &gport_id); 12568 if (BCM_FAILURE(rv)) { 12569 goto cleanup; 12570 } 12571 } 12572 } else { 12573 if ((-1 == mod_out) || (-1 == port_out)) { 12574 return BCM_E_PORT; 12575 } 12576 12577 port_count = 1; 12578 12579 mod_array = sal_alloc(sizeof(bcm_module_t) * port_count, 12580 "module ID array"); 12581 if (mod_array == NULL) { 12582 rv = BCM_E_MEMORY; 12583 goto cleanup; 12584 } 12585 mod_array[0] = mod_out; 12586 12587 port_array = sal_alloc(sizeof(bcm_port_t) * port_count, 12588 "port ID array"); 12589 if (port_array == NULL) { 12590 rv = BCM_E_MEMORY; 12591 goto cleanup; 12592 } 12593 port_array[0] = port_out; 12594 } 12595 12596 rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[0], 12597 port_array[0], &stm_idx); 12598 if (BCM_FAILURE(rv)) { 12599 goto cleanup; 12600 } 12601 12602 soc_mem_lock(unit, ING_VLAN_RANGEm); 12603 12604 rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry); 12605 if (rv < 0) { 12606 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12607 goto cleanup; 12608 } 12609 if (outer_vlan_low != BCM_VLAN_INVALID && outer_vlan_high != BCM_VLAN_INVALID) { 12610 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 12611 OUTER_VLAN_RANGE_IDXf)) { 12612 old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 12613 &stm_entry, OUTER_VLAN_RANGE_IDXf); 12614 } else { 12615 old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 12616 &stm_entry, VLAN_RANGE_IDXf); 12617 } 12618 12619 /* Get the profile table entry for this port/trunk */ 12620 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, old_idx); 12621 12622 rv = _bcm_tr2_vlan_tranlate_range_data_insert(outer_vlan_low, outer_vlan_high, 12623 min_vlan, max_vlan); 12624 if (BCM_FAILURE(rv)) { 12625 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12626 goto cleanup; 12627 } 12628 /* Adding the new profile table entry and update profile pointer */ 12629 for (i = 0; i < port_count; i++) { 12630 rv = _bcm_tr2_port_vlan_translate_range_profile_update(unit, min_vlan, 12631 max_vlan, mod_array[i], 12632 port_array[i], 12633 _BCM_OUTER_VLAN_RANGE_TYPE, 12634 &new_idx); 12635 if (BCM_FAILURE(rv)) { 12636 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12637 goto cleanup; 12638 } 12639 } 12640 } 12641 if (inner_vlan_low != BCM_VLAN_INVALID && inner_vlan_high != BCM_VLAN_INVALID) { 12642 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 12643 INNER_VLAN_RANGE_IDXf)) { 12644 old_idx_inner = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 12645 &stm_entry, INNER_VLAN_RANGE_IDXf); 12646 } else { 12647 old_idx_inner = -1; 12648 } 12649 if (old_idx_inner >= 0 && inner_vlan_low != BCM_VLAN_INVALID && inner_vlan_high != BCM_VLAN_INVALID) { 12650 /* Get the profile table entry for this port/trunk */ 12651 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, old_idx_inner); 12652 12653 rv =_bcm_tr2_vlan_tranlate_range_data_insert(inner_vlan_low, inner_vlan_high, 12654 min_vlan, max_vlan); 12655 if (BCM_FAILURE(rv)) { 12656 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12657 goto cleanup; 12658 } 12659 /* Adding the new profile table entry and update profile pointer */ 12660 for (i = 0; i < port_count; i++) { 12661 rv = _bcm_tr2_port_vlan_translate_range_profile_update(unit, min_vlan, 12662 max_vlan, mod_array[i], 12663 port_array[i], 12664 _BCM_INNER_VLAN_RANGE_TYPE, 12665 &new_idx_inner); 12666 if (BCM_FAILURE(rv)) { 12667 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12668 goto cleanup; 12669 } 12670 } 12671 } 12672 } 12673 if (BCM_GPORT_IS_TRUNK(port)) { 12674 if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) { 12675 trunk128 = soc_property_get(unit, spn_TRUNK_EXTEND, 1); 12676 if (!trunk128) { 12677 rv = _bcm_trx_vlan_range_profile_entry_add(unit, min_vlan, max_vlan, 12678 &new_idx); 12679 if (BCM_FAILURE(rv)) { 12680 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12681 goto cleanup; 12682 } 12683 rv = soc_mem_field32_modify(unit, TRUNK32_PORT_TABLEm, trunk_id, 12684 VLAN_RANGE_IDXf, new_idx); 12685 if (BCM_FAILURE(rv)) { 12686 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 12687 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12688 goto cleanup; 12689 } 12690 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx); 12691 } 12692 } 12693 } 12694 12695 /* Add an entry in the vlan translate table for the low VID */ 12696 rv = _bcm_tr_vlan_translate_vp_add(unit, port, key_type, 12697 outer_vlan_low, inner_vlan_low, 12698 vp, action, NULL); 12699 if (rv != BCM_E_NONE) { 12700 for (i = 0; i < port_count; i++) { 12701 /* coverity[unsigned_compare] */ 12702 if (new_idx >= 0) { 12703 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 12704 } 12705 /* coverity[unsigned_compare] */ 12706 if (new_idx_inner >= 0) { 12707 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx_inner); 12708 } 12709 } 12710 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12711 goto cleanup; 12712 } 12713 12714 /* Delete the old profile entry */ 12715 for (i = 0; i < port_count; i++) { 12716 if (new_idx >= 0) { 12717 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx); 12718 } 12719 if (new_idx_inner >= 0) { 12720 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx_inner); 12721 } 12722 } 12723 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12724 12725 cleanup: 12726 if (NULL != member_array) { 12727 sal_free(member_array); 12728 } 12729 if (NULL != mod_array) { 12730 sal_free(mod_array); 12731 } 12732 if (NULL != port_array) { 12733 sal_free(port_array); 12734 } 12735 12736 return rv; 12737 } 12738 12739 int 12740 _bcm_tr2_vlan_translate_range_vp_delete(int unit, 12741 bcm_gport_t port, 12742 bcm_vlan_t outer_vlan_low, 12743 bcm_vlan_t outer_vlan_high, 12744 bcm_vlan_t inner_vlan_low, 12745 bcm_vlan_t inner_vlan_high, 12746 int vp) 12747 { 12748 int i, key_type = 0, rv, gport_id, old_idx = -1, old_idx_inner= -1, stm_idx = 0; 12749 uint32 new_idx = 0, new_idx_inner = 0; 12750 source_trunk_map_table_entry_t stm_entry; 12751 bcm_module_t mod_out; 12752 bcm_port_t port_out; 12753 bcm_trunk_t trunk_id, tid; 12754 bcm_vlan_t min_vlan[8], max_vlan[8]; 12755 int port_count; 12756 bcm_trunk_member_t *member_array = NULL; 12757 bcm_module_t *mod_array = NULL; 12758 bcm_port_t *port_array = NULL; 12759 int trunk128; 12760 12761 if (outer_vlan_low != BCM_VLAN_INVALID && 12762 inner_vlan_low != BCM_VLAN_INVALID) { 12763 key_type = bcmVlanTranslateKeyPortDouble; 12764 } else if (outer_vlan_low != BCM_VLAN_INVALID) { 12765 key_type = bcmVlanTranslateKeyPortOuter; 12766 } else if (inner_vlan_low != BCM_VLAN_INVALID) { 12767 key_type = bcmVlanTranslateKeyPortInner; 12768 } else { 12769 return BCM_E_PARAM; 12770 } 12771 12772 BCM_IF_ERROR_RETURN 12773 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id, 12774 &gport_id)); 12775 12776 if (BCM_GPORT_IS_TRUNK(port)) { 12777 if (BCM_TRUNK_INVALID == trunk_id) { 12778 return BCM_E_PORT; 12779 } 12780 12781 BCM_IF_ERROR_RETURN 12782 (bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, &port_count)); 12783 12784 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 12785 "trunk member array"); 12786 if (member_array == NULL) { 12787 rv = BCM_E_MEMORY; 12788 goto cleanup; 12789 } 12790 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 12791 12792 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 12793 member_array, &port_count); 12794 if (BCM_FAILURE(rv)) { 12795 goto cleanup; 12796 } 12797 12798 mod_array = sal_alloc(sizeof(bcm_module_t) * port_count, 12799 "module ID array"); 12800 if (mod_array == NULL) { 12801 rv = BCM_E_MEMORY; 12802 goto cleanup; 12803 } 12804 sal_memset(mod_array, 0, sizeof(bcm_module_t) * port_count); 12805 12806 port_array = sal_alloc(sizeof(bcm_port_t) * port_count, 12807 "port ID array"); 12808 if (port_array == NULL) { 12809 rv = BCM_E_MEMORY; 12810 goto cleanup; 12811 } 12812 sal_memset(port_array, 0, sizeof(bcm_port_t) * port_count); 12813 12814 for (i = 0; i < port_count; i++) { 12815 rv = _bcm_esw_gport_resolve(unit, member_array[i].gport, 12816 &mod_array[i], &port_array[i], &tid, &gport_id); 12817 if (BCM_FAILURE(rv)) { 12818 goto cleanup; 12819 } 12820 } 12821 } else { 12822 if ((-1 == mod_out) || (-1 == port_out)) { 12823 return BCM_E_PORT; 12824 } 12825 12826 port_count = 1; 12827 12828 mod_array = sal_alloc(sizeof(bcm_module_t) * port_count, 12829 "module ID array"); 12830 if (mod_array == NULL) { 12831 rv = BCM_E_MEMORY; 12832 goto cleanup; 12833 } 12834 mod_array[0] = mod_out; 12835 12836 port_array = sal_alloc(sizeof(bcm_port_t) * port_count, 12837 "port ID array"); 12838 if (port_array == NULL) { 12839 rv = BCM_E_MEMORY; 12840 goto cleanup; 12841 } 12842 port_array[0] = port_out; 12843 } 12844 12845 rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[0], 12846 port_array[0], &stm_idx); 12847 if (BCM_FAILURE(rv)) { 12848 goto cleanup; 12849 } 12850 12851 soc_mem_lock(unit, ING_VLAN_RANGEm); 12852 rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry); 12853 if (rv < 0) { 12854 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12855 goto cleanup; 12856 } 12857 if (outer_vlan_low != BCM_VLAN_INVALID && outer_vlan_high != BCM_VLAN_INVALID) { 12858 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 12859 OUTER_VLAN_RANGE_IDXf)) { 12860 old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 12861 &stm_entry, OUTER_VLAN_RANGE_IDXf); 12862 } else { 12863 old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 12864 &stm_entry, VLAN_RANGE_IDXf); 12865 } 12866 12867 /* Get the profile table entry for this port/trunk */ 12868 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, old_idx); 12869 12870 rv = _bcm_tr2_vlan_tranlate_range_data_delete(outer_vlan_low, outer_vlan_high, 12871 min_vlan, max_vlan); 12872 if (BCM_FAILURE(rv)) { 12873 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12874 goto cleanup; 12875 } 12876 /* Adding the new profile table entry and update profile pointer */ 12877 for (i = 0; i < port_count; i++) { 12878 rv = _bcm_tr2_port_vlan_translate_range_profile_update(unit, min_vlan, 12879 max_vlan, mod_array[i], 12880 port_array[i], 12881 _BCM_OUTER_VLAN_RANGE_TYPE, 12882 &new_idx); 12883 if (BCM_FAILURE(rv)) { 12884 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12885 goto cleanup; 12886 } 12887 } 12888 } 12889 if (inner_vlan_low != BCM_VLAN_INVALID && inner_vlan_high != BCM_VLAN_INVALID) { 12890 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 12891 INNER_VLAN_RANGE_IDXf)) { 12892 old_idx_inner = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 12893 &stm_entry, INNER_VLAN_RANGE_IDXf); 12894 } else { 12895 old_idx_inner = -1; 12896 } 12897 if (old_idx_inner >= 0 && inner_vlan_low != BCM_VLAN_INVALID && inner_vlan_high != BCM_VLAN_INVALID) { 12898 /* Get the profile table entry for this port/trunk */ 12899 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, old_idx_inner); 12900 12901 rv =_bcm_tr2_vlan_tranlate_range_data_delete(inner_vlan_low, inner_vlan_high, 12902 min_vlan, max_vlan); 12903 if (BCM_FAILURE(rv)) { 12904 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12905 goto cleanup; 12906 } 12907 /* Adding the new profile table entry and update profile pointer */ 12908 for (i = 0; i < port_count; i++) { 12909 rv = _bcm_tr2_port_vlan_translate_range_profile_update(unit, min_vlan, 12910 max_vlan, mod_array[i], 12911 port_array[i], 12912 _BCM_INNER_VLAN_RANGE_TYPE, 12913 &new_idx_inner); 12914 if (BCM_FAILURE(rv)) { 12915 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12916 goto cleanup; 12917 } 12918 } 12919 } 12920 } 12921 12922 if (BCM_GPORT_IS_TRUNK(port)) { 12923 if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) { 12924 trunk128 = soc_property_get(unit, spn_TRUNK_EXTEND, 1); 12925 if (!trunk128) { 12926 rv = _bcm_trx_vlan_range_profile_entry_add(unit, min_vlan, max_vlan, 12927 &new_idx); 12928 if (BCM_FAILURE(rv)) { 12929 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12930 goto cleanup; 12931 } 12932 rv = soc_mem_field32_modify(unit, TRUNK32_PORT_TABLEm, trunk_id, 12933 VLAN_RANGE_IDXf, new_idx); 12934 if (BCM_FAILURE(rv)) { 12935 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 12936 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12937 goto cleanup; 12938 } 12939 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx); 12940 } 12941 } 12942 } 12943 12944 /* Delete the entry from the vlan translate table for the low VID */ 12945 rv = _bcm_tr_vlan_translate_vp_delete(unit, port, key_type, 12946 outer_vlan_low, inner_vlan_low, vp); 12947 if (rv != BCM_E_NONE) { 12948 for (i = 0; i < port_count; i++) { 12949 /* coverity[unsigned_compare] */ 12950 if (new_idx >= 0) { 12951 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx); 12952 } 12953 /* coverity[unsigned_compare] */ 12954 if (new_idx_inner >= 0) { 12955 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx_inner); 12956 } 12957 } 12958 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12959 goto cleanup; 12960 } 12961 12962 /* Delete the old profile entry */ 12963 for (i = 0; i < port_count; i++) { 12964 /* coverity[unsigned_compare] */ 12965 if (new_idx >= 0) { 12966 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx); 12967 } 12968 /* coverity[unsigned_compare] */ 12969 if (new_idx_inner >= 0) { 12970 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx_inner); 12971 } 12972 } 12973 soc_mem_unlock(unit, ING_VLAN_RANGEm); 12974 12975 cleanup: 12976 if (NULL != member_array) { 12977 sal_free(member_array); 12978 } 12979 if (NULL != mod_array) { 12980 sal_free(mod_array); 12981 } 12982 if (NULL != port_array) { 12983 sal_free(port_array); 12984 } 12985 12986 return rv; 12987 } 12988 #endif 12989 12990 /* 12991 * Function: 12992 * _bcm_trx_system_reserved_vlan_ing_set 12993 * Purpose: 12994 * Set ingress system reserved VLAN 12995 * Parameters: 12996 * unit - Device unit number 12997 * flags - Operation flags 12998 * vlan - VLAN 12999 * Returns: 13000 * BCM_E_XXX 13001 */ 13002 int 13003 _bcm_trx_system_reserved_vlan_ing_set(int unit, int arg) 13004 { 13005 uint32 rval; 13006 int rv; 13007 int valid = (arg != BCM_VLAN_INVALID); 13008 int vid = valid ? arg : 0; 13009 13010 rval = 0; 13011 soc_reg_field_set(unit, ING_SYS_RSVD_VIDr, &rval, VALIDf, valid); 13012 soc_reg_field_set(unit, ING_SYS_RSVD_VIDr, &rval, VIDf, vid); 13013 rv = WRITE_ING_SYS_RSVD_VIDr(unit, rval); 13014 13015 return rv; 13016 } 13017 13018 /* 13019 * Function: 13020 * _bcm_trx_system_reserved_vlan_egr_set 13021 * Purpose: 13022 * Set egress system reserved VLAN 13023 * Parameters: 13024 * unit - Device unit number 13025 * flags - Operation flags 13026 * vlan - VLAN 13027 * Returns: 13028 * BCM_E_XXX 13029 */ 13030 int 13031 _bcm_trx_system_reserved_vlan_egr_set(int unit, int arg) 13032 { 13033 uint32 rval; 13034 int rv; 13035 int vid = (arg != BCM_VLAN_INVALID) ? arg : 0; 13036 13037 rval = 0; 13038 soc_reg_field_set(unit, EGR_SYS_RSVD_VIDr, &rval, VIDf, vid); 13039 rv = WRITE_EGR_SYS_RSVD_VIDr(unit, rval); 13040 13041 return rv; 13042 } 13043 13044 /* 13045 * Function: 13046 * _bcm_trx_system_reserved_vlan_ing_get 13047 * Purpose: 13048 * Get ingress system reserved VLAN 13049 * Parameters: 13050 * unit - Device unit number 13051 * vlan - VLAN 13052 * Returns: 13053 * BCM_E_XXX 13054 */ 13055 int 13056 _bcm_trx_system_reserved_vlan_ing_get(int unit, int *arg) 13057 { 13058 uint32 rval; 13059 int rv = BCM_E_UNAVAIL; 13060 13061 rv = READ_ING_SYS_RSVD_VIDr(unit, &rval); 13062 if (SOC_SUCCESS(rv)) { 13063 if (soc_reg_field_get(unit, ING_SYS_RSVD_VIDr, rval, VALIDf)) { 13064 bcm_vlan_t vlan; 13065 13066 vlan = soc_reg_field_get(unit, ING_SYS_RSVD_VIDr, rval, VIDf); 13067 *arg = vlan; 13068 } else { 13069 *arg = BCM_VLAN_INVALID; 13070 } 13071 } 13072 return rv; 13073 } 13074 13075 13076 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 13077 #define _BCM_VLAN_PROTOCOL_DATA_CHUNK 16 13078 #define _BCM_VLAN_ACTION_PROFILE_DEFAULT 0 13079 #define _BCM_VLAN_PROTOCOL_DATA_PROFILE_DEFAULT 0 13080 13081 STATIC 13082 int 13083 _bcm_trx_port_vlan_protocol_data_profile_index_set(int unit, 13084 bcm_port_t port, int vlan_prot_offset, int action_profile_idx, 13085 bcm_vlan_action_set_t *action) 13086 { 13087 int i, alloc_size = 0; 13088 int vlan_prot_idx, rv = BCM_E_NONE; 13089 vlan_protocol_data_entry_t *vlan_prot_data; 13090 vlan_protocol_data_entry_t data[_BCM_VLAN_PROTOCOL_DATA_CHUNK]; 13091 void *entries[1]; 13092 _bcm_port_info_t *pinfo; 13093 13094 13095 if ((vlan_prot_offset < 0) || 13096 (vlan_prot_offset >= _BCM_VLAN_PROTOCOL_DATA_CHUNK)) { 13097 return BCM_E_PARAM; 13098 } 13099 13100 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 13101 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 13102 vlan_prot_idx = pinfo->vlan_prot_ptr; 13103 13104 if (SOC_IS_TOMAHAWKX(unit)) { 13105 sal_memset(data, 0, sizeof(data)); 13106 for (i = 0; i < _BCM_VLAN_PROTOCOL_DATA_CHUNK; i++) { 13107 BCM_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm( 13108 unit, MEM_BLOCK_ANY, vlan_prot_idx + i, &data[i])); 13109 } 13110 vlan_prot_data = data; 13111 } else { 13112 /* Allocate memory for DMA */ 13113 alloc_size = _BCM_VLAN_PROTOCOL_DATA_CHUNK * 13114 sizeof(vlan_protocol_data_entry_t); 13115 vlan_prot_data = soc_cm_salloc(unit, alloc_size, 13116 "VLAN protocol data table"); 13117 if (NULL == vlan_prot_data) { 13118 return (BCM_E_MEMORY); 13119 } 13120 sal_memset(vlan_prot_data, 0, alloc_size); 13121 13122 /* Read the old profile chunk */ 13123 13124 rv = soc_mem_read_range(unit, VLAN_PROTOCOL_DATAm, 13125 MEM_BLOCK_ANY, vlan_prot_idx, 13126 vlan_prot_idx + (_BCM_VLAN_PROTOCOL_DATA_CHUNK - 1), 13127 vlan_prot_data); 13128 if (BCM_FAILURE(rv)) { 13129 soc_cm_sfree(unit, vlan_prot_data); 13130 return (rv); 13131 } 13132 } 13133 13134 /* Modify what's needed */ 13135 /* coverity[uninit_use_in_call: FALSE] */ 13136 _bcm_trx_vlan_protocol_data_entry_set(unit, 13137 &vlan_prot_data[vlan_prot_offset], action, action_profile_idx); 13138 13139 /* Delete the old profile chunk */ 13140 rv = _bcm_port_vlan_protocol_data_entry_delete(unit, vlan_prot_idx); 13141 if (BCM_FAILURE(rv)) { 13142 if (alloc_size > 0) { 13143 soc_cm_sfree(unit, vlan_prot_data); 13144 } 13145 return (rv); 13146 } 13147 13148 /* Add new chunk and store new HW index */ 13149 entries[0] = vlan_prot_data; 13150 rv = _bcm_port_vlan_protocol_data_entry_add(unit, entries, 13151 _BCM_VLAN_PROTOCOL_DATA_CHUNK, (uint32 *)&vlan_prot_idx); 13152 /* Free the DMA memory */ 13153 if (alloc_size > 0) { 13154 soc_cm_sfree(unit, vlan_prot_data); 13155 } 13156 if (BCM_FAILURE(rv)) { 13157 return (rv); 13158 } 13159 13160 rv = _bcm_esw_port_tab_set(unit, port, 13161 _BCM_CPU_TABS_ETHER, VLAN_PROTOCOL_DATA_INDEXf, vlan_prot_idx / 16); 13162 if (BCM_SUCCESS(rv)) { 13163 pinfo->vlan_prot_ptr = vlan_prot_idx; 13164 } 13165 13166 return (rv); 13167 } 13168 13169 STATIC 13170 int 13171 _bcm_trx_port_vlan_protocol_data_profile_set(int unit, 13172 bcm_port_t port, void **entries) 13173 { 13174 int vlan_prot_idx, rv = BCM_E_NONE; 13175 _bcm_port_info_t *pinfo; 13176 13177 PORT_LOCK(unit); 13178 13179 /* Delete the old profile chunk */ 13180 rv = _bcm_port_info_get(unit, port, &pinfo); 13181 if (BCM_FAILURE(rv)) { 13182 goto cleanup; 13183 } 13184 13185 rv = _bcm_port_vlan_protocol_data_entry_delete(unit, pinfo->vlan_prot_ptr); 13186 if (BCM_FAILURE(rv)) { 13187 goto cleanup; 13188 } 13189 13190 /* Add new chunk and store new HW index */ 13191 rv = _bcm_port_vlan_protocol_data_entry_add(unit, entries, 13192 _BCM_VLAN_PROTOCOL_DATA_CHUNK, (uint32 *)&vlan_prot_idx); 13193 if (BCM_FAILURE(rv)) { 13194 goto cleanup; 13195 } 13196 13197 /* Set VLAN_PROTOCOL_DATA_INDEXf in PORT_TAB. */ 13198 rv = _bcm_esw_port_tab_set_without_portlock(unit, port, 13199 _BCM_CPU_TABS_ETHER, VLAN_PROTOCOL_DATA_INDEXf, vlan_prot_idx / 16); 13200 if (BCM_FAILURE(rv)) { 13201 goto cleanup; 13202 } 13203 /* Update vlan_prot_ptr in SW port info */ 13204 pinfo->vlan_prot_ptr = vlan_prot_idx; 13205 13206 cleanup: 13207 PORT_UNLOCK(unit); 13208 return (rv); 13209 13210 } 13211 13212 13213 /* 13214 * Function : 13215 * _bcm_trx_vlan_protocol_data_profile_update 13216 * Description : 13217 * Helper function for an API to update vlan port protocol data memory 13218 * for specific ports. 13219 * Parameters : 13220 * unit (IN) BCM unit number 13221 * update_pbm (IN) BCM port bitmap to update 13222 * prot_idx (IN) Index to Port Protocol table 13223 * action (IN) VLAN action to be used to update all ports in pbmp 13224 */ 13225 int 13226 _bcm_trx_vlan_protocol_data_profile_update( 13227 int unit, bcm_pbmp_t update_pbm, int prot_idx, 13228 bcm_vlan_action_set_t *action) 13229 { 13230 bcm_port_t p; 13231 int data_idx; 13232 uint32 action_profile_idx, old_action_profile_idx; 13233 int use_default = 0; 13234 bcm_vlan_action_set_t def_action, *action_p; 13235 _bcm_port_info_t *pinfo; 13236 vlan_protocol_data_entry_t vde; 13237 13238 /* if action is NULL then default action should be used for each port */ 13239 if (NULL == action) { 13240 use_default = 1; 13241 action_p = &def_action; 13242 } else { 13243 BCM_IF_ERROR_RETURN( 13244 _bcm_trx_vlan_action_verify(unit, action)); 13245 action_p = action; 13246 } 13247 13248 BCM_PBMP_ITER(update_pbm, p) { 13249 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo)); 13250 data_idx = pinfo->vlan_prot_ptr + prot_idx; 13251 13252 if (use_default) { 13253 BCM_IF_ERROR_RETURN( 13254 bcm_esw_vlan_port_default_action_get(unit, p, action_p)); 13255 if(soc_feature(unit, soc_feature_decouple_protocol_vlan)){ 13256 action_p->new_outer_vlan = BCM_VLAN_DEFAULT; 13257 } 13258 } 13259 13260 BCM_IF_ERROR_RETURN( 13261 READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, data_idx, &vde)); 13262 13263 old_action_profile_idx = 13264 soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, 13265 TAG_ACTION_PROFILE_PTRf); 13266 13267 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_add(unit, 13268 action_p, &action_profile_idx)); 13269 13270 /* Update VLAN_PROTOCOL_DATA profile and 13271 * PORT.VLAN_PROTOCOL_DATA_INDEX */ 13272 BCM_IF_ERROR_RETURN( 13273 _bcm_trx_port_vlan_protocol_data_profile_index_set(unit, 13274 p, prot_idx, action_profile_idx, action_p)); 13275 13276 if (old_action_profile_idx >= ing_action_profile_def[unit]) { 13277 BCM_IF_ERROR_RETURN( 13278 _bcm_trx_vlan_action_profile_entry_delete(unit, 13279 old_action_profile_idx)); 13280 } 13281 } 13282 return BCM_E_NONE; 13283 } 13284 13285 13286 /* 13287 * Function: 13288 * _bcm_trx_vlan_port_default_action_profile_set 13289 * Purpose: 13290 * Set the port's default vlan tag actions 13291 * Parameters: 13292 * unit - (IN) BCM unit. 13293 * port - (IN) Port number. 13294 * action - (IN) Vlan tag actions 13295 * Returns: 13296 * BCM_E_XXX 13297 */ 13298 int 13299 _bcm_trx_vlan_port_default_action_profile_set(int unit, bcm_port_t port, 13300 bcm_vlan_action_set_t *action) 13301 { 13302 uint32 action_profile_idx, old_action_profile_idx; 13303 bcm_port_cfg_t pcfg; 13304 vlan_protocol_data_entry_t vde; 13305 int vlan_prot_entries, vlan_data_prot_start, i, rv; 13306 int alloc_size = 0; 13307 _bcm_port_info_t *pinfo; 13308 vlan_protocol_data_entry_t *vlan_prot_data; 13309 vlan_protocol_data_entry_t data[_BCM_VLAN_PROTOCOL_DATA_CHUNK]; 13310 void *entries[1]; 13311 13312 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action)); 13313 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_add(unit, 13314 action, &action_profile_idx)); 13315 13316 BCM_IF_ERROR_RETURN 13317 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 13318 13319 old_action_profile_idx = pcfg.pc_vlan_action; 13320 pcfg.pc_vlan = action->new_outer_vlan; 13321 pcfg.pc_ivlan = action->new_inner_vlan; 13322 pcfg.pc_vlan_action = action_profile_idx; 13323 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 13324 if (action->priority >= BCM_PRIO_MIN && 13325 action->priority <= BCM_PRIO_MAX) { 13326 pcfg.pc_new_opri = action->priority; 13327 } 13328 pcfg.pc_new_ocfi = action->new_outer_cfi; 13329 pcfg.pc_new_ipri = action->new_inner_pkt_prio; 13330 pcfg.pc_new_icfi = action->new_inner_cfi; 13331 } else { 13332 if (action->priority >= BCM_PRIO_MIN && 13333 action->priority <= BCM_PRIO_MAX) { 13334 pcfg.pc_new_opri = action->priority; 13335 } 13336 } 13337 13338 BCM_IF_ERROR_RETURN 13339 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 13340 13341 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_delete(unit, 13342 old_action_profile_idx)); 13343 13344 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 13345 vlan_data_prot_start = pinfo->vlan_prot_ptr; 13346 13347 if (pinfo->p_vd_pbvl == 0) { 13348 /* Avoid one crash in kt2 tr 18 test case in linux environment */ 13349 return (BCM_E_NONE); 13350 } 13351 13352 if (SOC_IS_TOMAHAWKX(unit)) { 13353 sal_memset(data, 0, sizeof(data)); 13354 for (i = 0; i < _BCM_VLAN_PROTOCOL_DATA_CHUNK; i++) { 13355 BCM_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm( 13356 unit, MEM_BLOCK_ANY, vlan_data_prot_start + i, &data[i])); 13357 } 13358 vlan_prot_data = data; 13359 } else { 13360 /* Allocate memory for DMA */ 13361 alloc_size = _BCM_VLAN_PROTOCOL_DATA_CHUNK * 13362 sizeof(vlan_protocol_data_entry_t); 13363 vlan_prot_data = soc_cm_salloc(unit, alloc_size, 13364 "VLAN protocol data table"); 13365 if (NULL == vlan_prot_data) { 13366 return (BCM_E_MEMORY); 13367 } 13368 sal_memset(vlan_prot_data, 0, alloc_size); 13369 13370 /* Read the old profile chunk */ 13371 rv = soc_mem_read_range(unit, VLAN_PROTOCOL_DATAm, 13372 MEM_BLOCK_ANY, vlan_data_prot_start, 13373 vlan_data_prot_start + (_BCM_VLAN_PROTOCOL_DATA_CHUNK - 1), 13374 vlan_prot_data); 13375 if (BCM_FAILURE(rv)) { 13376 soc_cm_sfree(unit, vlan_prot_data); 13377 return (rv); 13378 } 13379 } 13380 13381 /* Update TAG_ACTION_PROFILE_PTR in VLAN_PROTOCOL_DATA */ 13382 vlan_prot_entries = soc_mem_index_count(unit, VLAN_PROTOCOLm); 13383 for (i = 0; i < vlan_prot_entries; i++) { 13384 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 13385 rv = READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, 13386 vlan_data_prot_start + i, &vde); 13387 if (BCM_FAILURE(rv)) { 13388 if (alloc_size > 0) { 13389 soc_cm_sfree(unit, vlan_prot_data); 13390 } 13391 return (rv); 13392 } 13393 13394 old_action_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, 13395 &vde, TAG_ACTION_PROFILE_PTRf); 13396 13397 rv = _bcm_trx_vlan_action_profile_entry_add(unit, 13398 action, &action_profile_idx); 13399 if (BCM_FAILURE(rv)) { 13400 if (alloc_size > 0) { 13401 soc_cm_sfree(unit, vlan_prot_data); 13402 } 13403 return (rv); 13404 } 13405 13406 /* Modify what's needed */ 13407 /* coverity[uninit_use_in_call: FALSE] */ 13408 _bcm_trx_vlan_protocol_data_entry_set(unit, 13409 &vlan_prot_data[i], action, action_profile_idx); 13410 13411 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, 13412 old_action_profile_idx); 13413 if (BCM_FAILURE(rv)) { 13414 if (alloc_size > 0) { 13415 soc_cm_sfree(unit, vlan_prot_data); 13416 } 13417 return (rv); 13418 } 13419 } 13420 } 13421 entries[0] = vlan_prot_data; 13422 13423 /* Update VLAN_PROTOCOL_DATA profile and 13424 * PORT.VLAN_PROTOCOL_DATA_INDEX */ 13425 rv =_bcm_trx_port_vlan_protocol_data_profile_set(unit, port, entries); 13426 if (alloc_size > 0) { 13427 soc_cm_sfree(unit, vlan_prot_data); 13428 } 13429 return (rv); 13430 } 13431 13432 13433 /* 13434 * Function: 13435 * _bcm_tr_vlan_port_default_action_delete 13436 * Purpose: 13437 * Deletes the port's default vlan tag actions 13438 * Parameters: 13439 * unit - (IN) BCM unit. 13440 * port - (IN) Port number. 13441 * Returns: 13442 * BCM_E_XXX 13443 */ 13444 int 13445 _bcm_trx_vlan_port_default_action_profile_delete(int unit, bcm_port_t port) 13446 { 13447 uint32 old_action_profile_idx; 13448 uint32 action_profile_idx; 13449 bcm_port_cfg_t pcfg; 13450 int num_ent, start, i; 13451 _bcm_port_info_t *pinfo; 13452 vlan_protocol_data_entry_t vde; 13453 int rv = BCM_E_NONE; 13454 13455 BCM_IF_ERROR_RETURN 13456 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 13457 old_action_profile_idx = pcfg.pc_vlan_action; 13458 13459 pcfg.pc_vlan = BCM_VLAN_DEFAULT; 13460 pcfg.pc_ivlan = 0; 13461 pcfg.pc_vlan_action = ing_action_profile_def[unit]; 13462 BCM_IF_ERROR_RETURN 13463 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 13464 13465 _bcm_trx_vlan_action_profile_entry_increment(unit, 13466 _BCM_VLAN_ACTION_PROFILE_DEFAULT); 13467 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_delete(unit, 13468 old_action_profile_idx)); 13469 13470 num_ent = soc_mem_index_count(unit, VLAN_PROTOCOLm); 13471 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 13472 start = pinfo->vlan_prot_ptr; 13473 13474 if (start == 0) { 13475 /* Decrease ref count of default profile and return */ 13476 rv = _bcm_port_vlan_protocol_data_entry_delete(unit, start); 13477 return rv; 13478 } 13479 13480 for (i = 0; i < num_ent; i++) { 13481 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 13482 BCM_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, 13483 start + i, &vde)); 13484 action_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, 13485 TAG_ACTION_PROFILE_PTRf); 13486 13487 _bcm_trx_vlan_action_profile_entry_increment(unit, 13488 _BCM_VLAN_ACTION_PROFILE_DEFAULT); 13489 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_delete(unit, 13490 action_profile_idx)); 13491 } 13492 } 13493 13494 /* Delete the VLAN_PROTOCOL_DATA profile */ 13495 BCM_IF_ERROR_RETURN(_bcm_port_vlan_protocol_data_entry_delete(unit, start)); 13496 13497 /* Increase ref count of default profile and return */ 13498 BCM_IF_ERROR_RETURN(_bcm_port_vlan_protocol_data_entry_reference(unit, 13499 _BCM_VLAN_PROTOCOL_DATA_PROFILE_DEFAULT, 13500 _BCM_VLAN_PROTOCOL_DATA_CHUNK)); 13501 pinfo->vlan_prot_ptr = _BCM_VLAN_PROTOCOL_DATA_PROFILE_DEFAULT; 13502 13503 return rv; 13504 } 13505 13506 #endif /*BCM_KATANA2_SUPPORT */ 13507 13508 /* 13509 * Function: 13510 * _bcm_trx_vlan_action_profile_ref_count_get 13511 * Purpose: 13512 * Get vlan action profile entry use count. 13513 * Parameters: 13514 * unit - (IN) BCM device number. 13515 * index - (IN) Profile entry index. 13516 * ref_count - (OUT) Vlan Action profile use count. 13517 * Returns: 13518 * BCM_E_XXX 13519 */ 13520 int 13521 _bcm_trx_vlan_action_profile_ref_count_get(int unit, int index, int *ref_count) 13522 { 13523 int rv = BCM_E_NONE; 13524 if (NULL == ref_count) { 13525 return (BCM_E_PARAM); 13526 } 13527 13528 ING_VLAN_TAG_ACTION_LOCK(unit); 13529 rv = soc_profile_mem_ref_count_get(unit, ing_action_profile[unit], 13530 index, ref_count); 13531 ING_VLAN_TAG_ACTION_UNLOCK(unit); 13532 return rv; 13533 } 13534 13535 13536 #ifndef BCM_SW_STATE_DUMP_DISABLE 13537 /* 13538 * Function: 13539 * _bcm_trx_vlan_sw_dump 13540 * Purpose: 13541 * Displays VLAN information maintained by software. 13542 * Parameters: 13543 * unit - Device unit number 13544 * Returns: 13545 * None 13546 */ 13547 void 13548 _bcm_trx_vlan_sw_dump(int unit) 13549 { 13550 int num_entries; 13551 int ref_count; 13552 int entries_per_set; 13553 int index; 13554 ing_vlan_tag_action_profile_entry_t *ing_entry; 13555 egr_vlan_tag_action_profile_entry_t *egr_entry; 13556 ing_vlan_range_entry_t *range_entry; 13557 13558 /* Display entries with reference count > 0 */ 13559 13560 if (ing_action_profile[unit] != NULL) { 13561 LOG_CLI((BSL_META_U(unit, 13562 "\nSW Information Ingress VLAN Action Profile - " 13563 "Unit %d\n"), unit)); 13564 13565 num_entries = soc_mem_index_count 13566 (unit, ing_action_profile[unit]->tables[0].mem); 13567 LOG_CLI((BSL_META_U(unit, 13568 " Number of entries: %d\n\n"), num_entries)); 13569 13570 for (index = 0; index < num_entries; index ++) { 13571 ING_VLAN_TAG_ACTION_LOCK(unit); 13572 if (SOC_FAILURE 13573 (soc_profile_mem_ref_count_get(unit, 13574 ing_action_profile[unit], 13575 index, &ref_count))) { 13576 ING_VLAN_TAG_ACTION_UNLOCK(unit); 13577 break; 13578 } 13579 13580 if (ref_count <= 0) { 13581 ING_VLAN_TAG_ACTION_UNLOCK(unit); 13582 continue; 13583 } 13584 13585 entries_per_set = 13586 ing_action_profile[unit]->tables[0].entries[index].entries_per_set; 13587 ing_entry = 13588 SOC_PROFILE_MEM_ENTRY(unit, 13589 ing_action_profile[unit], 13590 ing_vlan_tag_action_profile_entry_t *, 13591 index); 13592 LOG_CLI((BSL_META_U(unit, 13593 " Index = 0x%x\n"), index)); 13594 LOG_CLI((BSL_META_U(unit, 13595 " Reference count = %d\n"), ref_count)); 13596 LOG_CLI((BSL_META_U(unit, 13597 " Entries per set = %d\n"), entries_per_set)); 13598 soc_mem_entry_dump(unit, ing_action_profile[unit]->tables[0].mem, 13599 ing_entry, BSL_LSS_CLI); 13600 LOG_CLI((BSL_META_U(unit, "\n\n"))); 13601 ING_VLAN_TAG_ACTION_UNLOCK(unit); 13602 } 13603 } 13604 13605 if (egr_action_profile[unit] != NULL) { 13606 LOG_CLI((BSL_META_U(unit, 13607 "\nSW Information Egress VLAN Action Profile - " 13608 "Unit %d\n"), unit)); 13609 13610 num_entries = soc_mem_index_count 13611 (unit, egr_action_profile[unit]->tables[0].mem); 13612 LOG_CLI((BSL_META_U(unit, 13613 " Number of entries: %d\n\n"), num_entries)); 13614 13615 for (index = 0; index < num_entries; index ++) { 13616 EGR_VLAN_TAG_ACTION_LOCK(unit); 13617 if (SOC_FAILURE 13618 (soc_profile_mem_ref_count_get(unit, 13619 egr_action_profile[unit], 13620 index, &ref_count))) { 13621 EGR_VLAN_TAG_ACTION_UNLOCK(unit); 13622 break; 13623 } 13624 13625 if (ref_count <= 0) { 13626 EGR_VLAN_TAG_ACTION_UNLOCK(unit); 13627 continue; 13628 } 13629 13630 entries_per_set = 13631 egr_action_profile[unit]->tables[0].entries[index].entries_per_set; 13632 egr_entry = 13633 SOC_PROFILE_MEM_ENTRY(unit, 13634 egr_action_profile[unit], 13635 egr_vlan_tag_action_profile_entry_t *, 13636 index); 13637 LOG_CLI((BSL_META_U(unit, 13638 " Index = 0x%x\n"), index)); 13639 LOG_CLI((BSL_META_U(unit, 13640 " Reference count = %d\n"), ref_count)); 13641 LOG_CLI((BSL_META_U(unit, 13642 " Entries per set = %d\n"), entries_per_set)); 13643 soc_mem_entry_dump(unit, egr_action_profile[unit]->tables[0].mem, 13644 egr_entry, BSL_LSS_CLI); 13645 LOG_CLI((BSL_META_U(unit, "\n\n"))); 13646 EGR_VLAN_TAG_ACTION_UNLOCK(unit); 13647 } 13648 } 13649 13650 if (vlan_range_profile[unit] != NULL) { 13651 LOG_CLI((BSL_META_U(unit, 13652 "\nSW Information VLAN Range Profile - Unit %d\n"), 13653 unit)); 13654 13655 num_entries = soc_mem_index_count 13656 (unit, vlan_range_profile[unit]->tables[0].mem); 13657 13658 LOG_CLI((BSL_META_U(unit, 13659 " Number of entries: %d\n\n"), num_entries)); 13660 13661 for (index = 0; index < num_entries; index ++) { 13662 VLAN_RANGE_LOCK(unit); 13663 if (SOC_FAILURE 13664 (soc_profile_mem_ref_count_get(unit, 13665 vlan_range_profile[unit], 13666 index, &ref_count))) { 13667 VLAN_RANGE_UNLOCK(unit); 13668 break; 13669 } 13670 13671 if (ref_count <= 0) { 13672 VLAN_RANGE_UNLOCK(unit); 13673 continue; 13674 } 13675 13676 entries_per_set = 13677 vlan_range_profile[unit]->tables[0].entries[index].entries_per_set; 13678 range_entry = 13679 SOC_PROFILE_MEM_ENTRY(unit, 13680 vlan_range_profile[unit], 13681 ing_vlan_range_entry_t *, 13682 index); 13683 LOG_CLI((BSL_META_U(unit, 13684 " Index = 0x%x\n"), index)); 13685 LOG_CLI((BSL_META_U(unit, 13686 " Reference count = %d\n"), ref_count)); 13687 LOG_CLI((BSL_META_U(unit, 13688 " Entries per set = %d\n"), entries_per_set)); 13689 soc_mem_entry_dump(unit, vlan_range_profile[unit]->tables[0].mem, 13690 range_entry, BSL_LSS_CLI); 13691 LOG_CLI((BSL_META_U(unit, "\n\n"))); 13692 VLAN_RANGE_UNLOCK(unit); 13693 } 13694 } 13695 13696 return; 13697 } 13698 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 13699 13700 /* 13701 * Function: 13702 * _bcm_trx_vlan_mac_port_key_fields_set 13703 * Description : 13704 * Set Key Fields in VLAM_MACm entry hw buffer for MAC+PORT View. 13705 * Parameters : 13706 * unit (IN) BCM unit number 13707 * mac (IN) MAC address 13708 * port (IN) gport number 13709 * vment (OUT) VLAN_MACm entry hw buffer 13710 */ 13711 int _bcm_trx_vlan_mac_port_key_fields_set( 13712 int unit, 13713 bcm_vlan_match_info_t *match_info, 13714 vlan_mac_entry_t *vment) 13715 { 13716 int rv = BCM_E_NONE; 13717 int gport_id; 13718 int source_type; 13719 int max_bits; 13720 bcm_trunk_t trunk_id; 13721 bcm_module_t mod_out; 13722 bcm_port_t port_out; 13723 13724 /* Set Key Type */ 13725 soc_VLAN_MACm_field32_set(unit, vment, KEY_TYPEf, 13726 TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT); 13727 13728 /* Set entry MAC address */ 13729 soc_VLAN_MACm_mac_addr_set(unit, vment, MAC_PORT__MAC_ADDRf, 13730 match_info->src_mac); 13731 13732 switch(match_info->match) { 13733 case BCM_VLAN_MATCH_MAC_PORT: 13734 if (BCM_GPORT_IS_SET(match_info->port)) { 13735 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, 13736 match_info->port, &mod_out, &port_out, 13737 &trunk_id, &gport_id)); 13738 if (BCM_GPORT_IS_TRUNK(match_info->port)) { 13739 rv = _bcm_trunk_id_validate(unit, trunk_id); 13740 if (BCM_FAILURE(rv)) { 13741 return BCM_E_PORT; 13742 } 13743 source_type = 1; 13744 soc_VLAN_MACm_field32_set(unit, vment, MAC_PORT__Tf, 1); 13745 soc_VLAN_MACm_field32_set(unit, vment, MAC_PORT__TGIDf, 13746 trunk_id); 13747 } else if BCM_GPORT_IS_MODPORT(match_info->port) { 13748 if ((-1 == mod_out) || (-1 == port_out)) { 13749 return BCM_E_PORT; 13750 } 13751 source_type = 1; 13752 soc_VLAN_MACm_field32_set(unit, vment, 13753 MAC_PORT__PORT_NUMf, port_out); 13754 soc_VLAN_MACm_field32_set(unit, vment, 13755 MAC_PORT__MODULE_IDf, mod_out); 13756 } else { 13757 if (gport_id == -1) { 13758 return BCM_E_PORT; 13759 } 13760 source_type = 2; 13761 soc_VLAN_MACm_field32_set(unit, vment, 13762 MAC_PORT__SOURCE_FIELDf, gport_id); 13763 } 13764 } else { 13765 return BCM_E_PORT; 13766 } 13767 break; 13768 case BCM_VLAN_MATCH_MAC_PORT_CLASS: 13769 max_bits =soc_mem_field_length(unit, 13770 VLAN_MACm, MAC_PORT__SOURCE_FIELDf); 13771 if (match_info->port_class < (1 << max_bits)) { 13772 source_type = 3; 13773 soc_VLAN_MACm_field32_set(unit, vment, MAC_PORT__SOURCE_FIELDf, 13774 match_info->port_class); 13775 } else { 13776 return BCM_E_PORT; 13777 } 13778 break; 13779 default: 13780 return BCM_E_PARAM; 13781 } 13782 13783 /* Set entry Source Field */ 13784 if (SOC_MEM_FIELD_VALID(unit, VLAN_MACm, SOURCE_TYPEf)) { 13785 soc_VLAN_MACm_field32_set(unit, vment, SOURCE_TYPEf, source_type); 13786 } 13787 13788 return rv; 13789 } 13790 13791 /* 13792 * Function: 13793 * _bcm_trx_vlan_mac_port_key_fields_get 13794 * Description : 13795 * Get Key Fields from VLAM_MACm entry hw buffer for MAC+PORT View. 13796 * Parameters : 13797 * unit (IN) BCM unit number 13798 * vment (IN) VLAN_MACm entry hw buffer 13799 * mac (OUT) MAC address 13800 * port (OUT) gport number 13801 */ 13802 int _bcm_trx_vlan_mac_port_key_fields_get(int unit, 13803 vlan_mac_entry_t *vment, 13804 bcm_vlan_match_info_t *match_info) 13805 { 13806 int rv = BCM_E_NONE; 13807 uint32 port_in, mod_in; 13808 uint32 trunk_id; 13809 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 13810 uint32 vp; 13811 _bcm_gport_dest_t gport_dest; 13812 #endif 13813 13814 /* Get entry mac address. */ 13815 soc_VLAN_MACm_mac_addr_get(unit, vment, MAC_PORT__MAC_ADDRf, match_info->src_mac); 13816 13817 /* Get Source Type */ 13818 switch(soc_VLAN_MACm_field32_get(unit, vment, SOURCE_TYPEf)) { 13819 case 1: /* Port or Trunk */ 13820 match_info->match = BCM_VLAN_MATCH_MAC_PORT; 13821 if (soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__Tf)) { 13822 trunk_id = 13823 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__TGIDf); 13824 BCM_GPORT_TRUNK_SET(match_info->port, trunk_id); 13825 } else { 13826 port_in = 13827 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__PORT_NUMf); 13828 mod_in = 13829 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__MODULE_IDf); 13830 BCM_GPORT_MODPORT_SET(match_info->port, mod_in, port_in); 13831 } 13832 break; 13833 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 13834 case 2: /* Virtual Port */ 13835 match_info->match = BCM_VLAN_MATCH_MAC_PORT; 13836 vp = soc_VLAN_MACm_field32_get(unit, 13837 vment, MAC_PORT__SOURCE_FIELDf); 13838 _bcm_gport_dest_t_init(&gport_dest); 13839 rv = _bcm_vp_gport_dest_fill(unit, vp, &gport_dest); 13840 BCM_IF_ERROR_RETURN(rv); 13841 13842 rv = _bcm_esw_gport_construct(unit, &gport_dest, &match_info->port); 13843 BCM_IF_ERROR_RETURN(rv); 13844 break; 13845 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 13846 case 3: /* Port Group */ 13847 match_info->match = BCM_VLAN_MATCH_MAC_PORT_CLASS; 13848 match_info->port_class = 13849 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SOURCE_FIELDf); 13850 break; 13851 default: 13852 match_info->match = BCM_VLAN_MATCH_INVALID; 13853 break; 13854 } 13855 13856 return rv; 13857 } 13858 13859 /* 13860 * Function: 13861 * _bcm_trx_vlan_match_action_add 13862 * Description : 13863 * Add action for match criteria for Vlan assignment. 13864 * Parameters : 13865 * unit (IN) BCM unit number 13866 * options (IN) Options for creating vlan match and assignment. 13867 * svp_port (IN) Source VP gport. 13868 * match_info (IN) Vlan match criteria. 13869 * action_set (IN) Action Set. 13870 */ 13871 int 13872 _bcm_trx_vlan_match_action_add( 13873 int unit, 13874 uint32 options, 13875 bcm_gport_t port, 13876 bcm_vlan_match_info_t *match_info, 13877 bcm_vlan_action_set_t *action_set) 13878 { 13879 int rv; 13880 int idx = 0; 13881 int gport_id; 13882 int svp_valid; 13883 bcm_trunk_t trunk_id; 13884 bcm_module_t mod_out; 13885 bcm_port_t port_out; 13886 uint32 profile_idx; 13887 vlan_mac_entry_t vment; 13888 vlan_mac_entry_t res_vment; 13889 13890 if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) { 13891 return BCM_E_UNAVAIL; 13892 } 13893 13894 if (action_set != NULL) { 13895 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action_set)); 13896 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 13897 if (action_set->priority == -1) { 13898 return BCM_E_PARAM; /* no default priority action to take*/ 13899 } 13900 } 13901 } 13902 13903 sal_memset(&vment, 0, sizeof(vlan_mac_entry_t)); 13904 sal_memset(&res_vment, 0, sizeof(vlan_mac_entry_t)); 13905 13906 /* Set Key Fields */ 13907 BCM_IF_ERROR_RETURN 13908 (_bcm_trx_vlan_mac_port_key_fields_set(unit, match_info, &vment)); 13909 13910 soc_mem_lock(unit, VLAN_MACm); 13911 rv = soc_mem_search(unit, VLAN_MACm, MEM_BLOCK_ALL, &idx, 13912 &vment, &res_vment, 0); 13913 soc_mem_unlock(unit, VLAN_MACm); 13914 13915 /* If Entry exists, check svp configuration */ 13916 if (rv == BCM_E_NONE) { 13917 svp_valid = FALSE; 13918 if (soc_VLAN_MACm_field32_get(unit, &vment, MAC_PORT__SVP_VALIDf)) { 13919 svp_valid = TRUE; 13920 } 13921 if (((port == BCM_GPORT_INVALID) && (svp_valid == TRUE)) || 13922 ((port != BCM_GPORT_INVALID) && (svp_valid == FALSE))) { 13923 return BCM_E_EXISTS; 13924 } 13925 if (!options & BCM_VLAN_MATCH_ACTION_REPLACE) { 13926 return BCM_E_EXISTS; 13927 } 13928 } 13929 13930 /* If Entry does not exists and want to replace */ 13931 if ((rv == BCM_E_NOT_FOUND) && (options & BCM_VLAN_MATCH_ACTION_REPLACE)) { 13932 return rv; 13933 } 13934 13935 /* Set SVP Port */ 13936 if (BCM_GPORT_IS_SET(port)) { 13937 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, 13938 port, &mod_out, &port_out, &trunk_id, &gport_id)); 13939 if (SOC_MEM_FIELD_VALID(unit, VLAN_MACm, MAC_PORT__SVPf)) { 13940 soc_VLAN_MACm_field32_set(unit, &vment, MAC_PORT__SVP_VALIDf, 1); 13941 soc_VLAN_MACm_field32_set(unit, &vment, MAC_PORT__SVPf, gport_id); 13942 } 13943 } 13944 13945 if (action_set != NULL) { 13946 BCM_IF_ERROR_RETURN 13947 (_bcm_trx_vlan_action_profile_entry_add(unit, action_set, &profile_idx)); 13948 13949 /* Set Data Fields */ 13950 soc_VLAN_MACm_field32_set(unit, &vment, 13951 MAC_PORT__OVIDf, action_set->new_outer_vlan); 13952 soc_VLAN_MACm_field32_set(unit, &vment, 13953 MAC_PORT__IVIDf, action_set->new_inner_vlan); 13954 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 13955 soc_VLAN_MACm_field32_set(unit, &vment, 13956 MAC_PORT__OPRIf, action_set->priority); 13957 soc_VLAN_MACm_field32_set(unit, &vment, 13958 MAC_PORT__OCFIf, action_set->new_outer_cfi); 13959 soc_VLAN_MACm_field32_set(unit, &vment, 13960 MAC_PORT__IPRIf, action_set->new_inner_pkt_prio); 13961 soc_VLAN_MACm_field32_set(unit, &vment, 13962 MAC_PORT__ICFIf, action_set->new_inner_cfi); 13963 } else { 13964 if (action_set->priority >= BCM_PRIO_MIN && 13965 action_set->priority <= BCM_PRIO_MAX) { 13966 soc_VLAN_MACm_field32_set(unit, &vment, 13967 MAC_PORT__PRIf, action_set->priority); 13968 } 13969 } 13970 soc_VLAN_MACm_field32_set(unit, &vment, 13971 MAC_PORT__TAG_ACTION_PROFILE_PTRf, profile_idx); 13972 if (SOC_MEM_FIELD_VALID(unit, VLAN_MACm, MAC_PORT__VLAN_ACTION_VALIDf)) { 13973 soc_VLAN_MACm_field32_set(unit, &vment, 13974 MAC_PORT__VLAN_ACTION_VALIDf, 1); 13975 } 13976 } 13977 soc_VLAN_MACm_field32_set(unit, &vment, VALIDf, 1); 13978 13979 /* Insert to VLAN_MACm */ 13980 rv = soc_mem_insert_return_old(unit, VLAN_MACm, 13981 MEM_BLOCK_ALL, &vment, &vment); 13982 if (rv == SOC_E_EXISTS) { 13983 /* Delete the old vlan action profile entry */ 13984 if (soc_VLAN_MACm_field32_get(unit, &vment, 13985 MAC_PORT__VLAN_ACTION_VALIDf)) { 13986 profile_idx = soc_VLAN_MACm_field32_get(unit, &vment, 13987 MAC_PORT__TAG_ACTION_PROFILE_PTRf); 13988 rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 13989 } 13990 } 13991 13992 return rv; 13993 } 13994 13995 /* 13996 * Function: 13997 * _bcm_trx_vlan_match_action_get 13998 * Purpose: 13999 * Get action for given match criteria. 14000 * Parameters: 14001 * unit (IN) Device Number 14002 * svp_port (IN) source vp port 14003 * match_info - (IN) Match criteria info 14004 * action_set - (OUT) Action Set. 14005 * Returns: 14006 * BCM_E_XXX 14007 */ 14008 int 14009 _bcm_trx_vlan_match_action_get( 14010 int unit, 14011 bcm_gport_t port, 14012 bcm_vlan_match_info_t *match_info, 14013 bcm_vlan_action_set_t *action_set) 14014 { 14015 int matched, svp_assigned, vp; 14016 vlan_mac_entry_t vment; /* Lookup key hw buffer. */ 14017 vlan_mac_entry_t res_vment; /* Lookup result buffer. */ 14018 uint32 profile_idx; /* Vlan action profile index. */ 14019 int rv; /* Operation return status. */ 14020 int idx = 0; /* Lookup result entry index. */ 14021 14022 if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) { 14023 return BCM_E_UNAVAIL; 14024 } 14025 14026 /* Input parameters check. */ 14027 if (NULL == match_info) { 14028 return (BCM_E_PARAM); 14029 } 14030 14031 sal_memset(&vment, 0, sizeof(vlan_mac_entry_t)); 14032 sal_memset(&res_vment, 0, sizeof(vlan_mac_entry_t)); 14033 14034 /* Set Key fields */ 14035 BCM_IF_ERROR_RETURN 14036 (_bcm_trx_vlan_mac_port_key_fields_set(unit, match_info, &vment)); 14037 14038 /* Perform VLAN_MAC table search by mac address and port. */ 14039 soc_mem_lock(unit, VLAN_MACm); 14040 rv = soc_mem_search(unit, VLAN_MACm, MEM_BLOCK_ALL, &idx, 14041 &vment, &res_vment, 0); 14042 soc_mem_unlock(unit, VLAN_MACm); 14043 BCM_IF_ERROR_RETURN(rv); 14044 14045 /* Evaluate svp */ 14046 matched = FALSE; 14047 svp_assigned = soc_VLAN_MACm_field32_get(unit, &vment, MAC_PORT__SVP_VALIDf); 14048 14049 if ((port != BCM_GPORT_INVALID) && (svp_assigned == TRUE)) { 14050 vp = soc_VLAN_MACm_field32_get(unit, &vment, MAC_PORT__SVPf); 14051 matched = _bcm_esw_port_vp_gport_check(port, vp); 14052 } else if ((port == BCM_GPORT_INVALID) && (svp_assigned == FALSE)) { 14053 matched = TRUE; 14054 } else { 14055 /* (((port != BCM_GPORT_INVALID) && (svp_assigned == FALSE)) || 14056 ((port == BCM_GPORT_INVALID) && (svp_assigned == TRUE))) */ 14057 matched = FALSE; 14058 } 14059 if (matched == FALSE) { 14060 return BCM_E_NOT_FOUND; 14061 } 14062 14063 14064 /* Read Action Fields */ 14065 if (soc_VLAN_MACm_field32_get(unit, &res_vment, 14066 MAC_PORT__VLAN_ACTION_VALIDf)) { 14067 if (NULL == action_set) { 14068 return BCM_E_PARAM; 14069 } 14070 14071 action_set->new_outer_vlan = 14072 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__OVIDf); 14073 action_set->new_inner_vlan = 14074 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__IVIDf); 14075 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 14076 action_set->priority = 14077 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__OPRIf); 14078 action_set->new_outer_cfi = 14079 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__OCFIf); 14080 action_set->new_inner_pkt_prio = 14081 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__IPRIf); 14082 action_set->new_inner_cfi = 14083 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__ICFIf); 14084 } else { 14085 action_set->priority = 14086 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__PRIf); 14087 } 14088 14089 /* Read action profile data. */ 14090 profile_idx = soc_VLAN_MACm_field32_get(unit, 14091 &res_vment, MAC_PORT__TAG_ACTION_PROFILE_PTRf); 14092 _bcm_trx_vlan_action_profile_entry_get(unit, action_set, profile_idx); 14093 } 14094 14095 return (BCM_E_NONE); 14096 } 14097 14098 /* 14099 * Function: 14100 * _bcm_trx_vlan_match_action_delete 14101 * Purpose: 14102 * Remove action for a match criteria 14103 * Parameters: 14104 * unit (IN) Device Number 14105 * match_info (IN) Match criteria info. 14106 * Returns: 14107 * BCM_E_XXX 14108 */ 14109 int 14110 _bcm_trx_vlan_match_action_delete( 14111 int unit, 14112 bcm_gport_t port, 14113 bcm_vlan_match_info_t *vlan_match_info) 14114 { 14115 int rv, vp, svp_valid; 14116 int matched; 14117 vlan_mac_entry_t vment; /* Lookup key hw buffer. */ 14118 vlan_mac_entry_t res_vment; /* Lookup result buffer. */ 14119 uint32 profile_idx; /* Vlan action profile index. */ 14120 int idx = 0; /* Lookup result entry index. */ 14121 14122 sal_memset(&vment, 0, sizeof(vlan_mac_entry_t)); 14123 sal_memset(&res_vment, 0, sizeof(vlan_mac_entry_t)); 14124 14125 if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) { 14126 return BCM_E_UNAVAIL; 14127 } 14128 14129 /* Set Key fields */ 14130 BCM_IF_ERROR_RETURN 14131 (_bcm_trx_vlan_mac_port_key_fields_set(unit, vlan_match_info, &vment)); 14132 14133 /* Perform VLAN_MAC table search by mac address and port. */ 14134 soc_mem_lock(unit, VLAN_MACm); 14135 rv = soc_mem_search(unit, VLAN_MACm, MEM_BLOCK_ALL, &idx, 14136 &vment, &res_vment, 0); 14137 soc_mem_unlock(unit, VLAN_MACm); 14138 BCM_IF_ERROR_RETURN(rv); 14139 14140 /* Evaluate SVP */ 14141 matched = FALSE; 14142 svp_valid = soc_VLAN_MACm_field32_get(unit, &res_vment, 14143 MAC_PORT__SVP_VALIDf); 14144 if ((port != BCM_GPORT_INVALID) && (svp_valid == TRUE)) { 14145 vp = soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__SVPf); 14146 matched = _bcm_esw_port_vp_gport_check(port, vp); 14147 } else if ((port == BCM_GPORT_INVALID) && (svp_valid == FALSE)) { 14148 matched = TRUE; 14149 } else { 14150 /* (((port != BCM_GPORT_INVALID) && (svp_valid == FALSE)) || 14151 ((port == BCM_GPORT_INVALID) && (svp_valid == TRUE))) */ 14152 matched = FALSE; 14153 } 14154 14155 if (matched == FALSE) { 14156 return BCM_E_NOT_FOUND; 14157 } 14158 14159 /* Read action profile data. */ 14160 if (soc_VLAN_MACm_field32_get(unit, &res_vment, 14161 MAC_PORT__VLAN_ACTION_VALIDf)) { 14162 profile_idx = soc_VLAN_MACm_field32_get(unit, 14163 &res_vment, MAC_PORT__TAG_ACTION_PROFILE_PTRf); 14164 _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 14165 } 14166 14167 soc_mem_lock(unit, VLAN_MACm); 14168 rv = soc_mem_delete_return_old(unit, VLAN_MACm, MEM_BLOCK_ALL, 14169 &vment, &vment); 14170 soc_mem_unlock(unit, VLAN_MACm); 14171 14172 return (BCM_E_NONE); 14173 } 14174 14175 /* 14176 * Function: 14177 * _bcm_trx_vlan_match_action_multi_get 14178 * Purpose: 14179 * Get all actions and match criteria for given vlan match. 14180 * Parameters: 14181 * unit (IN) Device Number 14182 * match (IN) vlan match 14183 * port (IN) gport number 14184 * size (IN) Number of elements in match_info_array 14185 * match_info_array (OUT) Vlan match info array 14186 * action_set (OUT) Action Set 14187 * count (OUT) Actual number of elements in match_info_array 14188 * Returns: 14189 * BCM_E_XXX 14190 */ 14191 int 14192 _bcm_trx_vlan_match_action_multi_get(int unit, bcm_vlan_match_t match, 14193 bcm_gport_t port, int size, bcm_vlan_match_info_t *match_info_array, 14194 bcm_vlan_action_set_t *action_set, int *count) 14195 { 14196 int vp, svp_valid; 14197 int rv, i, matched, ctr; 14198 int imin, imax, nent, vmbytes; 14199 int key_type_value, key_type; 14200 uint32 profile_idx; 14201 bcm_vlan_match_info_t match_info; 14202 vlan_mac_entry_t *vmtab = NULL; 14203 vlan_mac_entry_t *vment = NULL; 14204 14205 if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) { 14206 return BCM_E_UNAVAIL; 14207 } 14208 14209 /* Parameter checks */ 14210 if ((size < 0) || (count == NULL)) { 14211 return BCM_E_PARAM; 14212 } 14213 if ((size > 0) && ((match_info_array == NULL) || 14214 (action_set == NULL))) { 14215 return BCM_E_PARAM; 14216 } 14217 14218 imin = soc_mem_index_min(unit, VLAN_MACm); 14219 imax = soc_mem_index_max(unit, VLAN_MACm); 14220 nent = soc_mem_index_count(unit, VLAN_MACm); 14221 vmbytes = soc_mem_entry_words(unit, VLAN_MACm); 14222 vmbytes = WORDS2BYTES(vmbytes); 14223 14224 vmtab = soc_cm_salloc(unit, nent * vmbytes, "vlan_mac"); 14225 14226 if (vmtab == NULL) { 14227 return BCM_E_MEMORY; 14228 } 14229 14230 soc_mem_lock(unit, VLAN_MACm); 14231 rv = soc_mem_read_range(unit, VLAN_MACm, MEM_BLOCK_ANY, 14232 imin, imax, vmtab); 14233 soc_mem_unlock(unit, VLAN_MACm); 14234 14235 if (rv < 0) { 14236 soc_cm_sfree(unit, vmtab); 14237 return rv; 14238 } 14239 14240 soc_mem_lock(unit, VLAN_MACm); 14241 for(i = 0, ctr = 0; i < nent; i++) { 14242 if ((size != 0) && (size <= ctr)) { 14243 break; 14244 } 14245 14246 vment = soc_mem_table_idx_to_pointer(unit, VLAN_MACm, 14247 vlan_mac_entry_t *, vmtab, i); 14248 14249 if (!soc_VLAN_MACm_field32_get(unit, vment, VALIDf)) { 14250 continue; 14251 } 14252 14253 /* Read KeyType */ 14254 key_type_value = soc_VLAN_MACm_field32_get(unit, vment, KEY_TYPEf); 14255 (void) _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value, 14256 &key_type); 14257 switch(key_type) { 14258 case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT: 14259 /* Read Key Fields */ 14260 bcm_vlan_match_info_t_init(&match_info); 14261 (void) _bcm_trx_vlan_mac_port_key_fields_get(unit, 14262 vment, &match_info); 14263 if (match_info.match == BCM_VLAN_MATCH_INVALID) { 14264 matched = FALSE; 14265 break; 14266 } 14267 14268 /* Evaluate SVP */ 14269 matched = FALSE; 14270 svp_valid = soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SVP_VALIDf); 14271 if ((port != BCM_GPORT_INVALID) && (svp_valid == TRUE)) { 14272 vp = soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SVPf); 14273 matched = _bcm_esw_port_vp_gport_check(port, vp); 14274 } else if ((port == BCM_GPORT_INVALID) && (svp_valid == FALSE)) { 14275 matched = TRUE; 14276 } else { 14277 /* (((port != BCM_GPORT_INVALID) && (svp_valid == FALSE)) || 14278 ((port == BCM_GPORT_INVALID) && (svp_valid == TRUE))) */ 14279 matched = FALSE; 14280 } 14281 /* Evaluate match criteria */ 14282 if ((match != BCM_VLAN_MATCH_INVALID) && 14283 (match != match_info.match)) { 14284 matched = FALSE; 14285 } 14286 break; 14287 default: 14288 matched = FALSE; 14289 break; 14290 } 14291 14292 if (matched == FALSE) { 14293 continue; 14294 } 14295 14296 ctr++; 14297 if (size >= ctr) { 14298 /* Copy Key Fields */ 14299 sal_memcpy(match_info_array, &match_info, 14300 sizeof(bcm_vlan_match_info_t)); 14301 14302 /* Read Data Fields */ 14303 action_set->new_outer_vlan = 14304 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__OVIDf); 14305 action_set->new_inner_vlan = 14306 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__IVIDf); 14307 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 14308 action_set->priority = 14309 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__OPRIf); 14310 action_set->new_outer_cfi = 14311 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__OCFIf); 14312 action_set->new_inner_pkt_prio = 14313 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__IPRIf); 14314 action_set->new_inner_cfi = 14315 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__ICFIf); 14316 } else { 14317 action_set->priority = 14318 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__PRIf); 14319 } 14320 14321 profile_idx = soc_VLAN_MACm_field32_get(unit, vment, 14322 MAC_PORT__TAG_ACTION_PROFILE_PTRf); 14323 14324 _bcm_trx_vlan_action_profile_entry_get(unit, action_set, profile_idx); 14325 14326 action_set++; 14327 match_info_array++; 14328 } 14329 } 14330 *count = ctr; 14331 14332 soc_mem_unlock(unit, VLAN_MACm); 14333 soc_cm_sfree(unit, vmtab); 14334 14335 return rv; 14336 } 14337 14338 /* 14339 * Function: 14340 * _bcm_trx_vlan_match_action_delete_all 14341 * Purpose: 14342 * Remove all actions for vlan match 14343 * Parameters: 14344 * unit (IN) Device Number 14345 * match (IN) vlan match 14346 * port (IN) port number 14347 * Returns: 14348 * BCM_E_XXX 14349 */ 14350 int 14351 _bcm_trx_vlan_match_action_delete_all(int unit, 14352 bcm_vlan_match_t match, bcm_gport_t port) 14353 { 14354 int vp, svp_valid; 14355 int rv, i, matched; 14356 int imin, imax, nent, vmbytes; 14357 uint32 profile_idx; 14358 vlan_mac_entry_t *vmtab = NULL; 14359 vlan_mac_entry_t *vment = NULL; 14360 int key_type_value, key_type; 14361 bcm_vlan_match_info_t match_info; 14362 14363 if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) { 14364 return BCM_E_UNAVAIL; 14365 } 14366 14367 imin = soc_mem_index_min(unit, VLAN_MACm); 14368 imax = soc_mem_index_max(unit, VLAN_MACm); 14369 nent = soc_mem_index_count(unit, VLAN_MACm); 14370 vmbytes = soc_mem_entry_words(unit, VLAN_MACm); 14371 vmbytes = WORDS2BYTES(vmbytes); 14372 14373 vmtab = soc_cm_salloc(unit, nent * vmbytes, "vlan_mac"); 14374 14375 if (vmtab == NULL) { 14376 return BCM_E_MEMORY; 14377 } 14378 14379 soc_mem_lock(unit, VLAN_MACm); 14380 rv = soc_mem_read_range(unit, VLAN_MACm, MEM_BLOCK_ANY, 14381 imin, imax, vmtab); 14382 soc_mem_unlock(unit, VLAN_MACm); 14383 14384 if (rv < 0) { 14385 soc_cm_sfree(unit, vmtab); 14386 return rv; 14387 } 14388 14389 soc_mem_lock(unit, VLAN_MACm); 14390 for(i = 0; i < nent; i++) { 14391 14392 vment = soc_mem_table_idx_to_pointer(unit, VLAN_MACm, 14393 vlan_mac_entry_t *, vmtab, i); 14394 14395 if (!soc_VLAN_MACm_field32_get(unit, vment, VALIDf)) { 14396 continue; 14397 } 14398 14399 /* Read KeyType */ 14400 key_type_value = soc_VLAN_MACm_field32_get(unit, vment, KEY_TYPEf); 14401 (void) _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value, 14402 &key_type); 14403 switch(key_type) { 14404 case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT: 14405 matched = TRUE; 14406 /* Read Key Fields */ 14407 bcm_vlan_match_info_t_init(&match_info); 14408 (void) _bcm_trx_vlan_mac_port_key_fields_get(unit, 14409 vment, &match_info); 14410 if (match_info.match == BCM_VLAN_MATCH_INVALID) { 14411 matched = FALSE; 14412 break; 14413 } 14414 14415 /* Evaluate SVP */ 14416 matched = FALSE; 14417 svp_valid = soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SVP_VALIDf); 14418 if ((port != BCM_GPORT_INVALID) && (svp_valid == TRUE)) { 14419 vp = soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SVPf); 14420 matched = _bcm_esw_port_vp_gport_check(port, vp); 14421 } else if ((port == BCM_GPORT_INVALID) && (svp_valid == FALSE)) { 14422 matched = TRUE; 14423 } else { 14424 /* (((port != BCM_GPORT_INVALID) && (svp_valid == FALSE)) || 14425 ((port == BCM_GPORT_INVALID) && (svp_valid == TRUE))) */ 14426 matched = FALSE; 14427 } 14428 /* Evaluate match criteria */ 14429 if ((match != BCM_VLAN_MATCH_INVALID) && 14430 (match != match_info.match)) { 14431 matched = FALSE; 14432 } 14433 break; 14434 default: 14435 matched = FALSE; 14436 break; 14437 } 14438 14439 if (matched == FALSE) { 14440 continue; 14441 } 14442 14443 if (soc_VLAN_MACm_field32_get(unit, &vment, 14444 MAC_PORT__VLAN_ACTION_VALIDf)) { 14445 /* Read action profile data. */ 14446 profile_idx = soc_VLAN_MACm_field32_get(unit, 14447 vment, MAC_PORT__TAG_ACTION_PROFILE_PTRf); 14448 _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx); 14449 } 14450 14451 rv = soc_mem_delete_return_old(unit, VLAN_MACm, MEM_BLOCK_ALL, 14452 vment, vment); 14453 if (rv != BCM_E_NONE) { 14454 break; 14455 } 14456 } 14457 14458 soc_mem_unlock(unit, VLAN_MACm); 14459 soc_cm_sfree(unit, vmtab); 14460 14461 return rv; 14462 } 14463 14464 #else /* BCM_TRX_SUPPORT */ 14465 int _triumph_vlan_not_empty; 14466 #endif /* BCM_TRX_SUPPORT */ 14467