vlan.c (706884B)
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 * Module: VLAN management 8 * 9 * Purpose: 10 * These routines manage the VTABLE entries as well as VLAN-related 11 * fields in the PTABLE. 12 * 13 * The bcm layer keeps the VTABLE and PTABLE coherent in terms of 14 * what ports belong to what VLANs and which ports are untagged. 15 */ 16 17 #include <shared/bsl.h> 18 19 #include <soc/drv.h> 20 #include <soc/scache.h> 21 #include <soc/hash.h> 22 23 #include <sal/core/boot.h> 24 #include <bcm/error.h> 25 #include <bcm/vlan.h> 26 27 #include <bcm_int/common/lock.h> 28 #include <bcm_int/control.h> 29 #include <bcm_int/esw/vlan.h> 30 #include <bcm_int/esw/mbcm.h> 31 #include <bcm_int/esw/stg.h> 32 #include <bcm_int/esw/firebolt.h> 33 #if defined(BCM_TRX_SUPPORT) 34 #include <bcm_int/esw/triumph.h> 35 #include <bcm_int/esw/mpls.h> 36 #include <bcm_int/esw/trx.h> 37 #endif /* BCM_TRX_SUPPORT */ 38 #if defined(BCM_TRIUMPH2_SUPPORT) 39 #include <bcm_int/esw/triumph2.h> 40 #include <bcm_int/common/multicast.h> 41 #endif /* BCM_TRIUMPH2_SUPPORT */ 42 #if defined(BCM_TRIDENT_SUPPORT) 43 #include <bcm_int/esw/trident.h> 44 #endif /* BCM_TRIDENT_SUPPORT */ 45 #if defined(BCM_TRIDENT2_SUPPORT) 46 #include <soc/trident2.h> 47 #include <bcm_int/esw/trident2.h> 48 #endif /* BCM_TRIDENT2_SUPPORT */ 49 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 50 #include <soc/td2_td2p.h> 51 #include <bcm_int/esw/trident2plus.h> 52 #include <bcm_int/esw/vpn.h> 53 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 54 #if defined(BCM_TRIDENT3_SUPPORT) 55 #include <soc/trident3.h> 56 #include <soc/esw/cancun.h> 57 #include <bcm_int/esw/trident3.h> 58 #include <bcm_int/esw/flow.h> 59 #endif /* BCM_TRIDENT3_SUPPORT */ 60 #if defined(BCM_HGPROXY_COE_SUPPORT) 61 #include <bcm_int/esw/xgs5.h> 62 #endif /* BCM_HGPROXY_COE_SUPPORT */ 63 #if defined(BCM_ENDURO_SUPPORT) 64 #include <bcm_int/esw/enduro.h> 65 #endif /* BCM_ENDURO_SUPPORT */ 66 #include <bcm_int/esw/virtual.h> 67 #include <bcm_int/esw/mim.h> 68 #include <bcm_int/esw/port.h> 69 #include <bcm_int/esw/multicast.h> 70 #ifdef BCM_WARM_BOOT_SUPPORT 71 #include <bcm_int/esw/switch.h> 72 #endif /* BCM_WARM_BOOT_SUPPORT */ 73 #include <bcm_int/esw/stack.h> 74 #include <bcm_int/esw/ipmc.h> 75 76 #ifdef BCM_TRIUMPH3_SUPPORT 77 #include <bcm_int/esw/triumph3.h> 78 #endif /* BCM_TRIUMPH3_SUPPORT */ 79 #if defined(BCM_KATANA2_SUPPORT) 80 #include <soc/katana2.h> 81 #include <bcm_int/esw/katana2.h> 82 #include <bcm_int/esw/subport.h> 83 #endif /* BCM_KATANA2_SUPPORT */ 84 #ifdef BCM_HURRICANE3_SUPPORT 85 #include <bcm_int/esw/hurricane3.h> 86 #include <soc/hurricane3.h> 87 #endif /* BCM_HURRICANE3_SUPPORT */ 88 #ifdef BCM_GREYHOUND2_SUPPORT 89 #include <bcm_int/esw/greyhound2.h> 90 #include <soc/greyhound2.h> 91 #endif /* BCM_GREYHOUND2_SUPPORT */ 92 #ifdef BCM_TOMAHAWK3_SUPPORT 93 #include <bcm_int/esw/tomahawk3.h> 94 #include <bcm_int/tomahawk3_dispatch.h> 95 #endif /* BCM_TOMAHAWK3_SUPPORT */ 96 #ifdef BCM_HURRICANE2_SUPPORT 97 #include <soc/hurricane2.h> 98 #endif /* BCM_HURRICANE2_SUPPORT */ 99 100 #include <bcm_int/esw_dispatch.h> 101 #include <bcm_int/api_xlate_port.h> 102 #include <bcm_int/esw/flex_ctr.h> 103 #include <bcm_int/esw/policer.h> 104 105 106 bcm_vlan_info_t vlan_info[BCM_MAX_NUM_UNITS]; 107 108 #ifndef BCM_VLAN_VID_MAX 109 #define BCM_VLAN_VID_MAX 4095 110 #endif 111 112 #define CHECK_INIT(unit) \ 113 if (!vlan_info[unit].init) \ 114 return BCM_E_INIT 115 116 STATIC int _bcm_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, 117 pbmp_t ubmp, pbmp_t ing_pbmp, int flags); 118 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 119 STATIC 120 bcm_error_t _bcm_esw_vlan_stat_get_table_info( 121 int unit, 122 bcm_vlan_t vlan, 123 uint32 *num_of_tables, 124 bcm_stat_flex_table_info_t *table_info); 125 static 126 bcm_error_t _bcm_esw_vlan_translate_stat_get_table_info( 127 int unit, 128 bcm_gport_t port, 129 bcm_vlan_translate_key_t key_type, 130 bcm_vlan_t outer_vlan, 131 bcm_vlan_t inner_vlan, 132 uint32 *num_of_tables, 133 bcm_stat_flex_table_info_t *table_info); 134 static 135 bcm_error_t _bcm_esw_vlan_translate_egress_stat_get_table_info( 136 int unit, 137 int port_class, 138 bcm_vlan_t outer_vlan, 139 bcm_vlan_t inner_vlan, 140 uint32 *num_of_tables, 141 bcm_stat_flex_table_info_t *table_info); 142 #endif 143 144 #ifdef BCM_WARM_BOOT_SUPPORT 145 STATIC int _bcm_vlan_reinit(int unit); 146 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 147 #define BCM_WB_VERSION_1_1 SOC_SCACHE_VERSION(1,1) 148 #define BCM_WB_VERSION_1_2 SOC_SCACHE_VERSION(1,2) 149 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_2 150 #else 151 #define _bcm_vlan_reinit(unit) (BCM_E_NONE) 152 #endif /* BCM_WARM_BOOT_SUPPORT */ 153 154 /* 155 * For BCM internal use to set vlan create default flood mode. 156 * Follow the same locking convention as other members in the structure 157 */ 158 /* 159 * Set the default PFM to be used by vlan_create 160 * Called from bcm_switch_control_set 161 */ 162 int 163 _bcm_esw_vlan_flood_default_set(int unit, bcm_vlan_mcast_flood_t mode) 164 { 165 bcm_vlan_info_t *vi = &vlan_info[unit]; 166 167 vi->flood_mode = mode; 168 169 return BCM_E_NONE; 170 } 171 172 /* 173 * Get the default PFM used by vlan_create 174 * Called from bcm_switch_control_get, bcm_vlan_create 175 */ 176 int 177 _bcm_esw_vlan_flood_default_get(int unit, bcm_vlan_mcast_flood_t *mode) 178 { 179 bcm_vlan_info_t *vi = &vlan_info[unit]; 180 181 *mode = vi->flood_mode; 182 183 return BCM_E_NONE; 184 } 185 186 /* 187 * Set the PFM to be used in the Module Header for L2 packets when 188 * EGR_CONFIG.STATIC_MH_PFM == 1. When STATIC_MH_PFM==0, the PFM in 189 * the MH comes from the Vlan table. 190 */ 191 int 192 _bcm_esw_higig_flood_l2_set(int unit, bcm_vlan_mcast_flood_t mode) 193 { 194 #ifdef BCM_XGS3_SWITCH_SUPPORT 195 uint32 rval; 196 197 if (soc_feature(unit, soc_feature_static_pfm)) { 198 if (mode >= BCM_VLAN_MCAST_FLOOD_COUNT) { 199 return BCM_E_PARAM; 200 } 201 SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval)); 202 soc_reg_field_set(unit, EGR_CONFIG_1r, &rval, MH_PFMf, mode); 203 SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIG_1r(unit, rval)); 204 return BCM_E_NONE; 205 } 206 #endif 207 return BCM_E_UNAVAIL; 208 } 209 210 /* 211 * Get the PFM to be used in the Module Header for L2 packets when 212 * EGR_CONFIG.STATIC_MH_PFM == 1. 213 */ 214 int 215 _bcm_esw_higig_flood_l2_get(int unit, bcm_vlan_mcast_flood_t *mode) 216 { 217 #ifdef BCM_XGS3_SWITCH_SUPPORT 218 uint32 rval; 219 220 if (soc_feature(unit, soc_feature_static_pfm)) { 221 SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval)); 222 *mode = soc_reg_field_get(unit, EGR_CONFIG_1r, rval, MH_PFMf); 223 return BCM_E_NONE; 224 } 225 #endif 226 return BCM_E_UNAVAIL; 227 } 228 229 /* 230 * Function: 231 * _bcm_esw_vlan_xlate_key_type_value_get 232 * Purpose: 233 * get the hardware specific vlan translation key type value from 234 * the common vlan translation key type for VLAN_XLATE table 235 * 236 * Parameters: 237 * key_type - input, common key type 238 * key_type_value - output, hardware specific key type value 239 */ 240 int 241 _bcm_esw_vlan_xlate_key_type_value_get(int unit, 242 int key_type, int *key_type_value) 243 { 244 #if defined(BCM_TRIDENT2_SUPPORT) 245 if (SOC_IS_TD2_TT2(unit)) { 246 switch (key_type) { 247 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 248 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_IVID_OVID; 249 break; 250 case VLXLT_HASH_KEY_TYPE_OTAG: 251 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_OTAG; 252 break; 253 case VLXLT_HASH_KEY_TYPE_ITAG: 254 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_ITAG; 255 break; 256 case VLXLT_HASH_KEY_TYPE_VLAN_MAC: 257 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VLAN_MAC; 258 break; 259 case VLXLT_HASH_KEY_TYPE_OVID: 260 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_OVID; 261 break; 262 case VLXLT_HASH_KEY_TYPE_IVID: 263 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_IVID; 264 break; 265 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 266 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_PRI_CFI; 267 break; 268 case VLXLT_HASH_KEY_TYPE_HPAE: 269 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_HPAE; 270 break; 271 case VLXLT_HASH_KEY_TYPE_VIF: 272 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF; 273 break; 274 case VLXLT_HASH_KEY_TYPE_VIF_VLAN: 275 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF_VLAN; 276 break; 277 case VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 278 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF_CVLAN; 279 break; 280 case VLXLT_HASH_KEY_TYPE_VIF_OTAG: 281 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF_OTAG; 282 break; 283 case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 284 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF_ITAG; 285 break; 286 case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT: 287 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT; 288 break; 289 case VLXLT_HASH_KEY_TYPE_L2GRE_DIP: 290 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_L2GRE_DIP; 291 break; 292 case VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN: 293 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN; 294 break; 295 case VLXLT_HASH_KEY_TYPE_IVID_VSAN: 296 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_IVID_VSAN; 297 break; 298 case VLXLT_HASH_KEY_TYPE_OVID_VSAN: 299 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_OVID_VSAN; 300 break; 301 case VLXLT_HASH_KEY_TYPE_VXLAN_DIP: 302 *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VXLAN_DIP; 303 break; 304 default: 305 *key_type_value = 0; 306 return BCM_E_UNAVAIL; 307 } 308 } else 309 #endif /* BCM_TRIDENT2_SUPPORT */ 310 #if defined(BCM_TRIUMPH3_SUPPORT) 311 if (SOC_IS_TRIUMPH3(unit)) { 312 switch (key_type) { 313 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 314 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_IVID_OVID; 315 break; 316 case VLXLT_HASH_KEY_TYPE_OTAG: 317 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_OTAG; 318 break; 319 case VLXLT_HASH_KEY_TYPE_ITAG: 320 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_ITAG; 321 break; 322 case VLXLT_HASH_KEY_TYPE_VLAN_MAC: 323 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC; 324 break; 325 case VLXLT_HASH_KEY_TYPE_OVID: 326 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_OVID; 327 break; 328 case VLXLT_HASH_KEY_TYPE_IVID: 329 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_IVID; 330 break; 331 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 332 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_PRI_CFI; 333 break; 334 case VLXLT_HASH_KEY_TYPE_HPAE: 335 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_HPAE; 336 break; 337 case VLXLT_HASH_KEY_TYPE_VIF: 338 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF; 339 break; 340 case VLXLT_HASH_KEY_TYPE_VIF_VLAN: 341 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF_VLAN; 342 break; 343 case VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 344 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF_CVLAN; 345 break; 346 case VLXLT_HASH_KEY_TYPE_VIF_OTAG: 347 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF_OTAG; 348 break; 349 case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 350 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF_ITAG; 351 break; 352 case VLXLT_HASH_KEY_TYPE_L2GRE_DIP: 353 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_L2GRE_DIP; 354 break; 355 default: 356 *key_type_value = 0; 357 return BCM_E_UNAVAIL; 358 } 359 } else 360 #endif 361 #if defined(BCM_KATANA2_SUPPORT) 362 if (SOC_IS_KATANA2(unit)) { 363 switch (key_type) { 364 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 365 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_IVID_OVID; 366 break; 367 case VLXLT_HASH_KEY_TYPE_OTAG: 368 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_OTAG; 369 break; 370 case VLXLT_HASH_KEY_TYPE_ITAG: 371 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_ITAG; 372 break; 373 case VLXLT_HASH_KEY_TYPE_VLAN_MAC: 374 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VLAN_MAC; 375 break; 376 case VLXLT_HASH_KEY_TYPE_OVID: 377 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_OVID; 378 break; 379 case VLXLT_HASH_KEY_TYPE_IVID: 380 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_IVID; 381 break; 382 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 383 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_PRI_CFI; 384 break; 385 case VLXLT_HASH_KEY_TYPE_HPAE: 386 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_HPAE; 387 break; 388 case VLXLT_HASH_KEY_TYPE_VIF: 389 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF; 390 break; 391 case VLXLT_HASH_KEY_TYPE_VIF_VLAN: 392 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF_VLAN; 393 break; 394 case VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 395 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF_CVLAN; 396 break; 397 case VLXLT_HASH_KEY_TYPE_VIF_OTAG: 398 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF_OTAG; 399 break; 400 case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 401 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF_ITAG; 402 break; 403 case VLXLT_HASH_KEY_TYPE_LLVID: 404 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_LLTAG_VID; 405 break; 406 case VLXLT_HASH_KEY_TYPE_LLVID_OVID: 407 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_LLVID_OVID; 408 break; 409 case VLXLT_HASK_KEY_TYPE_LLVID_IVID: 410 *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_LLVID_IVID; 411 break; 412 default: 413 *key_type_value = 0; 414 return BCM_E_UNAVAIL; 415 } 416 } else 417 #endif /* BCM_KATANA2_SUPPORT */ 418 #if defined(BCM_HURRICANE2_SUPPORT) 419 if (SOC_IS_HURRICANE2(unit)) { 420 switch (key_type) { 421 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 422 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_IVID_OVID; 423 break; 424 case VLXLT_HASH_KEY_TYPE_OTAG: 425 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_OTAG; 426 break; 427 case VLXLT_HASH_KEY_TYPE_ITAG: 428 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_ITAG; 429 break; 430 case VLXLT_HASH_KEY_TYPE_VLAN_MAC: 431 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_VLAN_MAC; 432 break; 433 case VLXLT_HASH_KEY_TYPE_OVID: 434 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_OVID; 435 break; 436 case VLXLT_HASH_KEY_TYPE_IVID: 437 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_IVID; 438 break; 439 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 440 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PRI_CFI; 441 break; 442 case VLXLT_HASH_KEY_TYPE_HPAE: 443 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_HPAE; 444 break; 445 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID: 446 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID; 447 break; 448 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG: 449 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG; 450 break; 451 case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG: 452 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG; 453 break; 454 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID: 455 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID; 456 break; 457 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID: 458 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID; 459 break; 460 default: 461 *key_type_value = 0; 462 return BCM_E_UNAVAIL; 463 } 464 } else 465 #endif /* BCM_HURRICANE2_SUPPORT */ 466 467 #if defined(BCM_HURRICANE3_SUPPORT) 468 if (SOC_IS_HURRICANE3(unit)) { 469 switch (key_type){ 470 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 471 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_IVID_OVID; 472 break; 473 case VLXLT_HASH_KEY_TYPE_OTAG: 474 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_OTAG; 475 break; 476 case VLXLT_HASH_KEY_TYPE_ITAG: 477 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_ITAG; 478 break; 479 case VLXLT_HASH_KEY_TYPE_VLAN_MAC: 480 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC; 481 break; 482 case VLXLT_HASH_KEY_TYPE_OVID: 483 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_OVID; 484 break; 485 case VLXLT_HASH_KEY_TYPE_IVID: 486 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_IVID; 487 break; 488 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 489 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PRI_CFI; 490 break; 491 case VLXLT_HASH_KEY_TYPE_HPAE: 492 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_HPAE; 493 break; 494 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID: 495 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID; 496 break; 497 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG: 498 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG; 499 break; 500 case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG: 501 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG; 502 break; 503 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID: 504 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID; 505 break; 506 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID: 507 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID; 508 break; 509 default: 510 *key_type_value = 0; 511 return BCM_E_UNAVAIL; 512 } 513 } else 514 #endif /* BCM_HURRICANE3_SUPPORT */ 515 #if defined(BCM_GREYHOUND2_SUPPORT) 516 if (SOC_IS_GREYHOUND2(unit)) { 517 switch (key_type){ 518 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 519 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_IVID_OVID; 520 break; 521 case VLXLT_HASH_KEY_TYPE_OTAG: 522 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_OTAG; 523 break; 524 case VLXLT_HASH_KEY_TYPE_ITAG: 525 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_ITAG; 526 break; 527 case VLXLT_HASH_KEY_TYPE_VLAN_MAC: 528 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_VLAN_MAC; 529 break; 530 case VLXLT_HASH_KEY_TYPE_OVID: 531 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_OVID; 532 break; 533 case VLXLT_HASH_KEY_TYPE_IVID: 534 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_IVID; 535 break; 536 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 537 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PRI_CFI; 538 break; 539 case VLXLT_HASH_KEY_TYPE_HPAE: 540 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_HPAE; 541 break; 542 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID: 543 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID; 544 break; 545 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG: 546 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG; 547 break; 548 case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG: 549 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG; 550 break; 551 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID: 552 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID; 553 break; 554 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID: 555 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID; 556 break; 557 case VLXLT_HASH_KEY_TYPE_VNID: 558 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_VNID; 559 break; 560 default: 561 *key_type_value = 0; 562 return BCM_E_UNAVAIL; 563 } 564 } else 565 #endif /* BCM_GREYHOUND2_SUPPORT */ 566 { 567 switch (key_type) { 568 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 569 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_IVID_OVID; 570 break; 571 case VLXLT_HASH_KEY_TYPE_OTAG: 572 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_OTAG; 573 break; 574 case VLXLT_HASH_KEY_TYPE_ITAG: 575 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_ITAG; 576 break; 577 case VLXLT_HASH_KEY_TYPE_VLAN_MAC: 578 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC; 579 break; 580 case VLXLT_HASH_KEY_TYPE_OVID: 581 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_OVID; 582 break; 583 case VLXLT_HASH_KEY_TYPE_IVID: 584 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_IVID; 585 break; 586 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 587 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_PRI_CFI; 588 break; 589 case VLXLT_HASH_KEY_TYPE_HPAE: 590 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_HPAE; 591 break; 592 case VLXLT_HASH_KEY_TYPE_VIF: 593 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_VIF; 594 break; 595 case VLXLT_HASH_KEY_TYPE_VIF_VLAN: 596 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_VIF_VLAN; 597 break; 598 case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT: 599 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT; 600 break; 601 default: 602 *key_type_value = 0; 603 return BCM_E_UNAVAIL; 604 } 605 } 606 return BCM_E_NONE; 607 } 608 609 /* 610 * Function: 611 * _bcm_esw_vlan_xlate_key_type_get 612 * Purpose: 613 * get the common vlan translation key type from hardware specific 614 * vlan translation key type value for VLAN_XLATE table 615 * 616 * Parameters: 617 * key_type_value - input, hardware specific key type value 618 * key_type - output, common key type 619 */ 620 int 621 _bcm_esw_vlan_xlate_key_type_get(int unit, 622 int key_type_value, int *key_type) 623 { 624 #if defined(BCM_TRIDENT2_SUPPORT) 625 if (SOC_IS_TD2_TT2(unit)) { 626 switch (key_type_value) { 627 case TD2_VLXLT_HASH_KEY_TYPE_IVID_OVID: 628 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 629 break; 630 case TD2_VLXLT_HASH_KEY_TYPE_OTAG: 631 *key_type = VLXLT_HASH_KEY_TYPE_OTAG; 632 break; 633 case TD2_VLXLT_HASH_KEY_TYPE_ITAG: 634 *key_type = VLXLT_HASH_KEY_TYPE_ITAG; 635 break; 636 case TD2_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 637 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC; 638 break; 639 case TD2_VLXLT_HASH_KEY_TYPE_OVID: 640 *key_type = VLXLT_HASH_KEY_TYPE_OVID; 641 break; 642 case TD2_VLXLT_HASH_KEY_TYPE_IVID: 643 *key_type = VLXLT_HASH_KEY_TYPE_IVID; 644 break; 645 case TD2_VLXLT_HASH_KEY_TYPE_PRI_CFI: 646 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 647 break; 648 case TD2_VLXLT_HASH_KEY_TYPE_HPAE: 649 *key_type = VLXLT_HASH_KEY_TYPE_HPAE; 650 break; 651 case TD2_VLXLT_HASH_KEY_TYPE_VIF: 652 *key_type = VLXLT_HASH_KEY_TYPE_VIF; 653 break; 654 case TD2_VLXLT_HASH_KEY_TYPE_VIF_VLAN: 655 *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN; 656 break; 657 case TD2_VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 658 *key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN; 659 break; 660 case TD2_VLXLT_HASH_KEY_TYPE_VIF_OTAG: 661 *key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG; 662 break; 663 case TD2_VLXLT_HASH_KEY_TYPE_VIF_ITAG: 664 *key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG; 665 break; 666 case TD2_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT: 667 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT; 668 break; 669 case TD2_VLXLT_HASH_KEY_TYPE_L2GRE_DIP: 670 *key_type = VLXLT_HASH_KEY_TYPE_L2GRE_DIP; 671 break; 672 case TD2_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN: 673 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN; 674 break; 675 case TD2_VLXLT_HASH_KEY_TYPE_IVID_VSAN: 676 *key_type = VLXLT_HASH_KEY_TYPE_IVID_VSAN; 677 break; 678 case TD2_VLXLT_HASH_KEY_TYPE_OVID_VSAN: 679 *key_type = VLXLT_HASH_KEY_TYPE_OVID_VSAN; 680 break; 681 case TD2_VLXLT_HASH_KEY_TYPE_VXLAN_DIP: 682 *key_type = VLXLT_HASH_KEY_TYPE_VXLAN_DIP; 683 break; 684 default: 685 *key_type = 0; 686 return BCM_E_UNAVAIL; 687 } 688 } else 689 #endif /* BCM_TRIDENT2_SUPPORT */ 690 #if defined(BCM_TRIUMPH3_SUPPORT) 691 if (SOC_IS_TRIUMPH3(unit)) { 692 switch (key_type_value) { 693 case TR3_VLXLT_HASH_KEY_TYPE_IVID_OVID: 694 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 695 break; 696 case TR3_VLXLT_HASH_KEY_TYPE_OTAG: 697 *key_type = VLXLT_HASH_KEY_TYPE_OTAG; 698 break; 699 case TR3_VLXLT_HASH_KEY_TYPE_ITAG: 700 *key_type = VLXLT_HASH_KEY_TYPE_ITAG; 701 break; 702 case TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 703 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC; 704 break; 705 case TR3_VLXLT_HASH_KEY_TYPE_OVID: 706 *key_type = VLXLT_HASH_KEY_TYPE_OVID; 707 break; 708 case TR3_VLXLT_HASH_KEY_TYPE_IVID: 709 *key_type = VLXLT_HASH_KEY_TYPE_IVID; 710 break; 711 case TR3_VLXLT_HASH_KEY_TYPE_PRI_CFI: 712 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 713 break; 714 case TR3_VLXLT_HASH_KEY_TYPE_HPAE: 715 *key_type = VLXLT_HASH_KEY_TYPE_HPAE; 716 break; 717 case TR3_VLXLT_HASH_KEY_TYPE_VIF: 718 *key_type = VLXLT_HASH_KEY_TYPE_VIF; 719 break; 720 case TR3_VLXLT_HASH_KEY_TYPE_VIF_VLAN: 721 *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN; 722 break; 723 case TR3_VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 724 *key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN; 725 break; 726 case TR3_VLXLT_HASH_KEY_TYPE_VIF_OTAG: 727 *key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG; 728 break; 729 case TR3_VLXLT_HASH_KEY_TYPE_VIF_ITAG: 730 *key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG; 731 break; 732 case TR3_VLXLT_HASH_KEY_TYPE_L2GRE_DIP: 733 *key_type = TR3_VLXLT_HASH_KEY_TYPE_L2GRE_DIP; 734 break; 735 default: 736 *key_type = 0; 737 return BCM_E_UNAVAIL; 738 } 739 } else 740 #endif 741 #if defined(BCM_KATANA2_SUPPORT) 742 if (SOC_IS_KATANA2(unit)) { 743 switch (key_type_value) { 744 case KT2_VLXLT_HASH_KEY_TYPE_IVID_OVID: 745 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 746 break; 747 case KT2_VLXLT_HASH_KEY_TYPE_OTAG: 748 *key_type = VLXLT_HASH_KEY_TYPE_OTAG; 749 break; 750 case KT2_VLXLT_HASH_KEY_TYPE_ITAG: 751 *key_type = VLXLT_HASH_KEY_TYPE_ITAG; 752 break; 753 case KT2_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 754 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC; 755 break; 756 case KT2_VLXLT_HASH_KEY_TYPE_OVID: 757 *key_type = VLXLT_HASH_KEY_TYPE_OVID; 758 break; 759 case KT2_VLXLT_HASH_KEY_TYPE_IVID: 760 *key_type = VLXLT_HASH_KEY_TYPE_IVID; 761 break; 762 case KT2_VLXLT_HASH_KEY_TYPE_PRI_CFI: 763 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 764 break; 765 case KT2_VLXLT_HASH_KEY_TYPE_HPAE: 766 *key_type = VLXLT_HASH_KEY_TYPE_HPAE; 767 break; 768 case KT2_VLXLT_HASH_KEY_TYPE_VIF: 769 *key_type = VLXLT_HASH_KEY_TYPE_VIF; 770 break; 771 case KT2_VLXLT_HASH_KEY_TYPE_VIF_VLAN: 772 *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN; 773 break; 774 case KT2_VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 775 *key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN; 776 break; 777 case KT2_VLXLT_HASH_KEY_TYPE_VIF_OTAG: 778 *key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG; 779 break; 780 case KT2_VLXLT_HASH_KEY_TYPE_VIF_ITAG: 781 *key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG; 782 break; 783 case KT2_VLXLT_HASH_KEY_TYPE_LLTAG_VID: 784 *key_type = VLXLT_HASH_KEY_TYPE_LLVID; 785 break; 786 case KT2_VLXLT_HASH_KEY_TYPE_LLVID_IVID: 787 *key_type = VLXLT_HASK_KEY_TYPE_LLVID_IVID; 788 break; 789 case KT2_VLXLT_HASH_KEY_TYPE_LLVID_OVID: 790 *key_type = VLXLT_HASH_KEY_TYPE_LLVID_OVID; 791 break; 792 default: 793 *key_type = 0; 794 return BCM_E_UNAVAIL; 795 } 796 } else 797 #endif /* BCM_KATANA2_SUPPORT */ 798 #if defined(BCM_HURRICANE2_SUPPORT) 799 if (SOC_IS_HURRICANE2(unit)) { 800 switch (key_type_value) { 801 case HR2_VLXLT_HASH_KEY_TYPE_IVID_OVID: 802 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 803 break; 804 case HR2_VLXLT_HASH_KEY_TYPE_OTAG: 805 *key_type = VLXLT_HASH_KEY_TYPE_OTAG; 806 break; 807 case HR2_VLXLT_HASH_KEY_TYPE_ITAG: 808 *key_type = VLXLT_HASH_KEY_TYPE_ITAG; 809 break; 810 case HR2_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 811 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC; 812 break; 813 case HR2_VLXLT_HASH_KEY_TYPE_OVID: 814 *key_type = VLXLT_HASH_KEY_TYPE_OVID; 815 break; 816 case HR2_VLXLT_HASH_KEY_TYPE_IVID: 817 *key_type = VLXLT_HASH_KEY_TYPE_IVID; 818 break; 819 case HR2_VLXLT_HASH_KEY_TYPE_PRI_CFI: 820 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 821 break; 822 case HR2_VLXLT_HASH_KEY_TYPE_HPAE: 823 *key_type = VLXLT_HASH_KEY_TYPE_HPAE; 824 break; 825 case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID: 826 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID; 827 break; 828 case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG: 829 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG; 830 break; 831 case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG: 832 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG; 833 break; 834 case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID: 835 *key_type= VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID; 836 break; 837 case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID: 838 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID; 839 break; 840 default: 841 *key_type = 0; 842 return BCM_E_UNAVAIL; 843 } 844 } else 845 #endif /* BCM_HURRICANE2_SUPPORT */ 846 #if defined(BCM_HURRICANE3_SUPPORT) 847 if (SOC_IS_HURRICANE3(unit)) { 848 switch (key_type_value){ 849 case HR3_VLXLT_HASH_KEY_TYPE_IVID_OVID: 850 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 851 break; 852 case HR3_VLXLT_HASH_KEY_TYPE_OTAG: 853 *key_type = VLXLT_HASH_KEY_TYPE_OTAG; 854 break; 855 case HR3_VLXLT_HASH_KEY_TYPE_ITAG: 856 *key_type = VLXLT_HASH_KEY_TYPE_ITAG; 857 break; 858 case HR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 859 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC; 860 break; 861 case HR3_VLXLT_HASH_KEY_TYPE_OVID: 862 *key_type = VLXLT_HASH_KEY_TYPE_OVID; 863 break; 864 case HR3_VLXLT_HASH_KEY_TYPE_IVID: 865 *key_type = VLXLT_HASH_KEY_TYPE_IVID; 866 break; 867 case HR3_VLXLT_HASH_KEY_TYPE_PRI_CFI: 868 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 869 break; 870 case HR3_VLXLT_HASH_KEY_TYPE_HPAE: 871 *key_type = VLXLT_HASH_KEY_TYPE_HPAE; 872 break; 873 case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID: 874 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID; 875 break; 876 case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG: 877 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG; 878 break; 879 case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG: 880 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG; 881 break; 882 case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID: 883 *key_type= VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID; 884 break; 885 case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID: 886 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID; 887 break; 888 default: 889 *key_type = 0; 890 return BCM_E_UNAVAIL; 891 } 892 } else 893 #endif /* BCM_HURRICANE3_SUPPORT */ 894 #if defined(BCM_GREYHOUND2_SUPPORT) 895 if (SOC_IS_GREYHOUND2(unit)) { 896 switch (key_type_value){ 897 case GH2_VLXLT_HASH_KEY_TYPE_IVID_OVID: 898 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 899 break; 900 case GH2_VLXLT_HASH_KEY_TYPE_OTAG: 901 *key_type = VLXLT_HASH_KEY_TYPE_OTAG; 902 break; 903 case GH2_VLXLT_HASH_KEY_TYPE_ITAG: 904 *key_type = VLXLT_HASH_KEY_TYPE_ITAG; 905 break; 906 case GH2_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 907 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC; 908 break; 909 case GH2_VLXLT_HASH_KEY_TYPE_OVID: 910 *key_type = VLXLT_HASH_KEY_TYPE_OVID; 911 break; 912 case GH2_VLXLT_HASH_KEY_TYPE_IVID: 913 *key_type = VLXLT_HASH_KEY_TYPE_IVID; 914 break; 915 case GH2_VLXLT_HASH_KEY_TYPE_PRI_CFI: 916 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 917 break; 918 case GH2_VLXLT_HASH_KEY_TYPE_HPAE: 919 *key_type = VLXLT_HASH_KEY_TYPE_HPAE; 920 break; 921 case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID: 922 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID; 923 break; 924 case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG: 925 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG; 926 break; 927 case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG: 928 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG; 929 break; 930 case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID: 931 *key_type= VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID; 932 break; 933 case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID: 934 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID; 935 break; 936 case GH2_VLXLT_HASH_KEY_TYPE_VNID: 937 *key_type = VLXLT_HASH_KEY_TYPE_VNID; 938 break; 939 default: 940 *key_type = 0; 941 return BCM_E_UNAVAIL; 942 } 943 } else 944 #endif /* BCM_GREYHOUND2_SUPPORT */ 945 { 946 switch (key_type_value) { 947 case TR_VLXLT_HASH_KEY_TYPE_IVID_OVID: 948 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 949 break; 950 case TR_VLXLT_HASH_KEY_TYPE_OTAG: 951 *key_type = VLXLT_HASH_KEY_TYPE_OTAG; 952 break; 953 case TR_VLXLT_HASH_KEY_TYPE_ITAG: 954 *key_type = VLXLT_HASH_KEY_TYPE_ITAG; 955 break; 956 case TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 957 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC; 958 break; 959 case TR_VLXLT_HASH_KEY_TYPE_OVID: 960 *key_type = VLXLT_HASH_KEY_TYPE_OVID; 961 break; 962 case TR_VLXLT_HASH_KEY_TYPE_IVID: 963 *key_type = VLXLT_HASH_KEY_TYPE_IVID; 964 break; 965 case TR_VLXLT_HASH_KEY_TYPE_PRI_CFI: 966 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 967 break; 968 case TR_VLXLT_HASH_KEY_TYPE_HPAE: 969 *key_type = VLXLT_HASH_KEY_TYPE_HPAE; 970 break; 971 case TR_VLXLT_HASH_KEY_TYPE_VIF: 972 *key_type = VLXLT_HASH_KEY_TYPE_VIF; 973 break; 974 case TR_VLXLT_HASH_KEY_TYPE_VIF_VLAN: 975 *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN; 976 break; 977 case TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT: 978 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT; 979 break; 980 default: 981 *key_type = 0; 982 return BCM_E_UNAVAIL; 983 } 984 } 985 return BCM_E_NONE; 986 } 987 988 /* 989 * Function: 990 * _bcm_esw_pt_vtkey_type_value_get 991 * Purpose: 992 * get the hardware specific port table vlan translation key type value 993 * from the common vlan translation key type for PORT_TABLE VT_KEY_TYPE 994 * field. In Triumph3, key type value in VLAN_XLATE differs from 995 * PORT_TABLE's VT_KEY_TYPE(_2) field 996 * 997 * Parameters: 998 * key_type - input, common key type 999 * key_type_value - output, hardware specific PORT_TABLE key type value 1000 */ 1001 int 1002 _bcm_esw_pt_vtkey_type_value_get(int unit, 1003 int key_type, int *key_type_value) 1004 { 1005 #if defined(BCM_TRIUMPH3_SUPPORT) 1006 if (SOC_IS_TRIUMPH3(unit)) { 1007 switch (key_type) { 1008 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 1009 *key_type_value = TR3_PT_XLT_KEY_TYPE_IVID_OVID; 1010 break; 1011 case VLXLT_HASH_KEY_TYPE_OTAG: 1012 *key_type_value = TR3_PT_XLT_KEY_TYPE_OTAG; 1013 break; 1014 case VLXLT_HASH_KEY_TYPE_ITAG: 1015 *key_type_value = TR3_PT_XLT_KEY_TYPE_ITAG; 1016 break; 1017 case VLXLT_HASH_KEY_TYPE_VLAN_MAC: 1018 *key_type_value = TR3_PT_XLT_KEY_TYPE_VLAN_MAC; 1019 break; 1020 case VLXLT_HASH_KEY_TYPE_OVID: 1021 *key_type_value = TR3_PT_XLT_KEY_TYPE_OVID; 1022 break; 1023 case VLXLT_HASH_KEY_TYPE_IVID: 1024 *key_type_value = TR3_PT_XLT_KEY_TYPE_IVID; 1025 break; 1026 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 1027 *key_type_value = TR3_PT_XLT_KEY_TYPE_PRI_CFI; 1028 break; 1029 case VLXLT_HASH_KEY_TYPE_HPAE: 1030 *key_type_value = TR3_PT_XLT_KEY_TYPE_HPAE; 1031 break; 1032 case VLXLT_HASH_KEY_TYPE_VIF: 1033 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF; 1034 break; 1035 case VLXLT_HASH_KEY_TYPE_VIF_VLAN: 1036 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF_VLAN; 1037 break; 1038 case VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 1039 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF_CVLAN; 1040 break; 1041 case VLXLT_HASH_KEY_TYPE_VIF_OTAG: 1042 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF_OTAG; 1043 break; 1044 case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 1045 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF_ITAG; 1046 break; 1047 default: 1048 *key_type_value = 0; 1049 return BCM_E_UNAVAIL; 1050 } 1051 } else 1052 #endif 1053 { 1054 /* for other switches, PORT_TABLE key type value is same as the 1055 * VLAN_XLATE key type value. 1056 */ 1057 return _bcm_esw_vlan_xlate_key_type_value_get(unit, key_type, 1058 key_type_value); 1059 } 1060 return BCM_E_NONE; 1061 } 1062 1063 /* 1064 * Function: 1065 * _bcm_esw_pt_vtkey_type_get 1066 * Purpose: 1067 * get the common vlan translation key type from hardware specific 1068 * PORT_TABLE vlan translation key type value 1069 * 1070 * Parameters: 1071 * key_type_value - input, common key type 1072 * key_type - output, hardware specific PORT_TABLE key type value 1073 */ 1074 int 1075 _bcm_esw_pt_vtkey_type_get(int unit, 1076 int key_type_value, int *key_type) 1077 { 1078 #if defined(BCM_TRIUMPH3_SUPPORT) 1079 if (SOC_IS_TRIUMPH3(unit)) { 1080 switch (key_type_value) { 1081 case TR3_PT_XLT_KEY_TYPE_IVID_OVID: 1082 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 1083 break; 1084 case TR3_PT_XLT_KEY_TYPE_OTAG: 1085 *key_type = VLXLT_HASH_KEY_TYPE_OTAG; 1086 break; 1087 case TR3_PT_XLT_KEY_TYPE_ITAG: 1088 *key_type = VLXLT_HASH_KEY_TYPE_ITAG; 1089 break; 1090 case TR3_PT_XLT_KEY_TYPE_VLAN_MAC: 1091 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC; 1092 break; 1093 case TR3_PT_XLT_KEY_TYPE_OVID: 1094 *key_type = VLXLT_HASH_KEY_TYPE_OVID; 1095 break; 1096 case TR3_PT_XLT_KEY_TYPE_IVID: 1097 *key_type = VLXLT_HASH_KEY_TYPE_IVID; 1098 break; 1099 case TR3_PT_XLT_KEY_TYPE_PRI_CFI: 1100 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 1101 break; 1102 case TR3_PT_XLT_KEY_TYPE_HPAE: 1103 *key_type = VLXLT_HASH_KEY_TYPE_HPAE; 1104 break; 1105 case TR3_PT_XLT_KEY_TYPE_VIF: 1106 *key_type = VLXLT_HASH_KEY_TYPE_VIF; 1107 break; 1108 case TR3_PT_XLT_KEY_TYPE_VIF_VLAN: 1109 *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN; 1110 break; 1111 case TR3_PT_XLT_KEY_TYPE_VIF_CVLAN: 1112 *key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN; 1113 break; 1114 case TR3_PT_XLT_KEY_TYPE_VIF_OTAG: 1115 *key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG; 1116 break; 1117 case TR3_PT_XLT_KEY_TYPE_VIF_ITAG: 1118 *key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG; 1119 break; 1120 default: 1121 *key_type = 0; 1122 return BCM_E_UNAVAIL; 1123 } 1124 } else 1125 #endif 1126 { 1127 /* For other devices, key type in VLAN_XLATE is same as in PORT_TABLE*/ 1128 return _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value, 1129 key_type); 1130 } 1131 return BCM_E_NONE; 1132 } 1133 1134 /* 1135 * Function: 1136 * _bcm_esw_egr_vtkey_type_value_get 1137 * Purpose: 1138 * get the hardware specific EGR_VLAN_CONTROL_1 egress vlan 1139 * translation key type value from the common key type 1140 * 1141 * Parameters: 1142 * key_type - input, common key type 1143 * key_type_value - output, hardware specific 1144 * EGR_VLAN_CONTROL_1 table VT_ENABLE/VT2_ENABLE fields 1145 */ 1146 int 1147 _bcm_esw_egr_vtkey_type_value_get(int unit, 1148 int key_type, int *key_type_value) 1149 { 1150 switch (key_type) { 1151 case bcmVlanTranslateEgressKeyPortGroupDouble: 1152 /* For devices where feature 'egr_vlan_xlate_second_lookup' is enabled, 1153 * VT_ENABLEf is a 2-bit field and explicit second lookup is allowed. 1154 * This key_type is an alias of the existing key_type 1155 * bcmVlanTranslateEgressKeyVlanPort in term of functionality, 1156 * on these devices.*/ 1157 if (!(SOC_IS_APACHE(unit) && 1158 soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup))) { 1159 return BCM_E_UNAVAIL; 1160 } 1161 /* passthru */ 1162 /* coverity[fallthrough: FALSE] */ 1163 case bcmVlanTranslateEgressKeyVlanPort: 1164 /* Note: This is the default key type for first lookup */ 1165 *key_type_value = EVXLT_KEY_TYPE_PORT_GROUP_VLAN_DOUBLE; 1166 break; 1167 case bcmVlanTranslateEgressKeyPortDouble: 1168 if (soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) { 1169 *key_type_value = EVXLT_KEY_TYPE_PORT_VLAN_DOUBLE; 1170 } else { 1171 return BCM_E_UNAVAIL; 1172 } 1173 break; 1174 case bcmVlanTranslateEgressKeyInvalid: 1175 *key_type_value = EVXLT_KEY_TYPE_NOOP; 1176 break; 1177 default: 1178 *key_type_value = 0; 1179 return BCM_E_UNAVAIL; 1180 } 1181 return BCM_E_NONE; 1182 } 1183 1184 /* 1185 * Function: 1186 * _bcm_esw_dvp_vtkey_type_value_get 1187 * Purpose: 1188 * get the hardware specific EGR_DVP_ATTRIBUTE egress vlan 1189 * translation key type value from the common key type 1190 * 1191 * Parameters: 1192 * key_type - input, common key type 1193 * key_type_value - output, hardware specific EGR_DVP_ATTRIBUTE key type value 1194 */ 1195 int 1196 _bcm_esw_dvp_vtkey_type_value_get(int unit, 1197 int key_type, int *key_type_value) 1198 { 1199 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1200 if (soc_feature(unit, soc_feature_egr_vlan_xlate_key_on_dvp)) { 1201 if (key_type_value == NULL) { 1202 return BCM_E_PARAM; 1203 } 1204 switch (key_type) { 1205 case bcmVlanTranslateEgressKeyVpn: 1206 *key_type_value = TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_VFI; 1207 break; 1208 case bcmVlanTranslateEgressKeyVpnGport: 1209 *key_type_value = TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_DVP_VFI; 1210 break; 1211 case bcmVlanTranslateEgressKeyVpnGportGroup: 1212 *key_type_value = TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_GID_VFI; 1213 break; 1214 case bcmVlanTranslateEgressKeyVlanPort: 1215 /* not supported now*/ 1216 *key_type_value = 0; 1217 return BCM_E_UNAVAIL; 1218 case bcmVlanTranslateEgressKeyInvalid: 1219 *key_type_value = TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_NOOP; 1220 break; 1221 default: 1222 *key_type_value = 0; 1223 return BCM_E_PARAM; 1224 } 1225 return BCM_E_NONE; 1226 } else 1227 #endif 1228 { 1229 return BCM_E_UNAVAIL; 1230 } 1231 } 1232 1233 /* 1234 * Function: 1235 * _bcm_esw_egr_vtkey_type_get 1236 * Purpose: 1237 * Get the common vlan translation key type from the hardware specific 1238 * EGR_VLAN_CONTROL_1 vlan translation key type value VT_ENABLE/VT2_ENABLE 1239 * 1240 * Parameters: 1241 * key_type_value - input, common key type 1242 * key_type - output, hardware specific EGR_VLAN_CONTROL_1 key type value 1243 */ 1244 int 1245 _bcm_esw_egr_vtkey_type_get(int unit, 1246 int key_type_value, int *key_type) 1247 { 1248 if (key_type == NULL) { 1249 return BCM_E_PARAM; 1250 } 1251 switch (key_type_value) { 1252 case EVXLT_KEY_TYPE_PORT_GROUP_VLAN_DOUBLE: 1253 /* For devices where feature 'egr_vlan_xlate_second_lookup' is 1254 * enabled, VT_ENABLEf is a 2-bit field and explicit second 1255 * lookup is allowed. This key_type_value maps to both key_types. 1256 * Returning bcmVlanTranslateEgressKeyPortGroupDouble for those 1257 * devices where soc feature is enabled as it clears the 1258 * ambiguity in the naming of existing enums. Otherwise, 1259 * bcmVlanTranslateEgressKeyVlanPort is returned as before */ 1260 if (SOC_IS_APACHE(unit) && 1261 soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) { 1262 *key_type = bcmVlanTranslateEgressKeyPortGroupDouble; 1263 } else { 1264 *key_type = bcmVlanTranslateEgressKeyVlanPort; 1265 } 1266 break; 1267 case EVXLT_KEY_TYPE_PORT_VLAN_DOUBLE: 1268 *key_type = bcmVlanTranslateEgressKeyPortDouble; 1269 break; 1270 case EVXLT_KEY_TYPE_NOOP: 1271 *key_type = bcmVlanTranslateEgressKeyInvalid; 1272 break; 1273 default: 1274 *key_type = 0; 1275 return BCM_E_PARAM; 1276 } 1277 return BCM_E_NONE; 1278 } 1279 1280 /* 1281 * Function: 1282 * _bcm_esw_dvp_vtkey_type_get 1283 * Purpose: 1284 * get the common vlan translation key type from the hardware specific 1285 * EGR_DVP_ATTRIBUTE vlan translation key type value 1286 * 1287 * Parameters: 1288 * key_type_value - input, common key type 1289 * key_type - output, hardware specific EGR_DVP_ATTRIBUTE key type value 1290 */ 1291 int 1292 _bcm_esw_dvp_vtkey_type_get(int unit, 1293 int key_type_value, int *key_type) 1294 { 1295 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1296 if (soc_feature(unit, soc_feature_egr_vlan_xlate_key_on_dvp)) { 1297 if (key_type == NULL) { 1298 return BCM_E_PARAM; 1299 } 1300 switch (key_type_value) { 1301 case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_VFI: 1302 *key_type = bcmVlanTranslateEgressKeyVpn; 1303 break; 1304 case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_DVP_VFI: 1305 *key_type = bcmVlanTranslateEgressKeyVpnGport; 1306 break; 1307 case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_GID_VFI: 1308 *key_type = bcmVlanTranslateEgressKeyVpnGportGroup; 1309 break; 1310 case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_NOOP: 1311 *key_type = bcmVlanTranslateEgressKeyInvalid; 1312 break; 1313 case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_DVP_OL_VLAN: 1314 case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_PORT_UL_VLAN: 1315 *key_type = 0; 1316 return BCM_E_UNAVAIL; 1317 default: 1318 *key_type = 0; 1319 return BCM_E_PARAM; 1320 } 1321 return BCM_E_NONE; 1322 } else 1323 #endif 1324 { 1325 return BCM_E_UNAVAIL; 1326 } 1327 } 1328 1329 /* 1330 * MACRO: 1331 * _BCM_VBMP_INSERT 1332 * Purpose: 1333 * Add a VLAN ID to a vbmap 1334 */ 1335 #define _BCM_VBMP_INSERT(_bmp_, _vid_) SHR_BITSET(((_bmp_).w), (_vid_)) 1336 1337 /* 1338 * Macro: 1339 * _BCM_VBMP_REMOVE 1340 * Purpose: 1341 * Delete a VLAN ID from a vbmp 1342 */ 1343 #define _BCM_VBMP_REMOVE(_bmp_, _vid_) SHR_BITCLR(((_bmp_).w), (_vid_)) 1344 1345 /* 1346 * Macro : 1347 * _BCM_VBMP_LOOKUP 1348 * Purpose: 1349 * Return TRUE if a VLAN ID exists in a vbmp, FALSE otherwise 1350 */ 1351 #define _BCM_VBMP_LOOKUP(_bmp_, _vid_) SHR_BITGET(((_bmp_).w), (_vid_)) 1352 1353 /* 1354 * Function: 1355 * _bcm_vbmp_destroy 1356 * Purpose: 1357 * Free all memory used by a active VLANs bitmap 1358 */ 1359 1360 int 1361 _bcm_vbmp_destroy(vbmp_t *bmp) 1362 { 1363 if (bmp->w != NULL) { 1364 sal_free(bmp->w); 1365 bmp->w = NULL; 1366 } 1367 return BCM_E_NONE; 1368 } 1369 1370 /* 1371 * Function: 1372 * _bcm_vbmp_init 1373 * Purpose: 1374 * Create new valid vlans bitmap. 1375 */ 1376 1377 int 1378 _bcm_vbmp_init(vbmp_t *bmp) 1379 { 1380 int alloc_size; 1381 1382 /* Deinit previously allocated bitmap. */ 1383 _bcm_vbmp_destroy(bmp); 1384 1385 alloc_size = SHR_BITALLOCSIZE(BCM_VLAN_COUNT); 1386 bmp->w = sal_alloc(alloc_size, "Active vlans bitmap"); 1387 if (NULL == bmp->w) { 1388 return (BCM_E_MEMORY); 1389 } 1390 sal_memset(bmp->w, 0, alloc_size); 1391 1392 return BCM_E_NONE; 1393 } 1394 1395 /* 1396 * Check for valid VLAN. If easy reload, check software state; 1397 * otherwise, check hardware entry 1398 */ 1399 int _bcm_vlan_valid_check(int unit, int table, vlan_tab_entry_t *vt, 1400 bcm_vlan_t vid) 1401 { 1402 #if defined(BCM_EASY_RELOAD_SUPPORT) 1403 if (SOC_IS_RELOADING(unit)) { 1404 vbmp_t vbmp; 1405 1406 if (! ((table == EGR_VLANm) || (table == VLAN_TABm || table == VLAN_2_TABm))) { 1407 return BCM_E_PARAM; 1408 } 1409 vbmp = (table == EGR_VLANm) ? vlan_info[unit].egr_vlan_bmp : 1410 vlan_info[unit].vlan_tab_bmp; 1411 if (! _BCM_VBMP_LOOKUP(vbmp, vid)) { 1412 return BCM_E_NOT_FOUND; 1413 } 1414 } else 1415 #endif 1416 { 1417 if (!soc_mem_field32_get(unit, table, vt, VALIDf)) { 1418 return BCM_E_NOT_FOUND; 1419 } 1420 } 1421 return BCM_E_NONE; 1422 } 1423 1424 #if defined(BCM_EASY_RELOAD_SUPPORT) 1425 /* 1426 * Set valid VLAN as software state for easy reload 1427 */ 1428 int _bcm_vlan_valid_set(int unit, int table, bcm_vlan_t vid, int val) 1429 { 1430 vbmp_t vbmp; 1431 if (! ((table == EGR_VLANm) || (table == VLAN_TABm || table == VLAN_2_TABm))) { 1432 return BCM_E_PARAM; 1433 } 1434 vbmp = (table == EGR_VLANm) ? vlan_info[unit].egr_vlan_bmp : 1435 vlan_info[unit].vlan_tab_bmp; 1436 1437 if (val) { 1438 _BCM_VBMP_INSERT(vbmp, vid); 1439 } else { 1440 _BCM_VBMP_REMOVE(vbmp, vid); 1441 } 1442 return BCM_E_NONE; 1443 } 1444 #endif 1445 1446 /* 1447 * Function: 1448 * _bcm_vlan_control_trust_gport 1449 * Purpose: 1450 * Validate if a given VLAN control is capable of parsing GPORT internaly 1451 * Parameters: 1452 * type - VLAN control to be checked 1453 * Returns: 1454 * BCM_E_NONE - control is capable of parsing GPORT. 1455 * BCM_E_INTERNAL - GPORT for the control should be parsed by the API 1456 */ 1457 STATIC int 1458 _bcm_vlan_control_trust_gport(bcm_vlan_control_port_t type) 1459 { 1460 int itter; 1461 bcm_vlan_control_port_t types_arr[] = { 1462 bcmVlanPortUseInnerPri, 1463 bcmVlanPortUseOuterPri, 1464 bcmVlanPortTranslateKeyFirst, 1465 bcmVlanPortTranslateEgressKey 1466 }; 1467 1468 for (itter = 0; itter < COUNTOF(types_arr); itter ++) { 1469 if (types_arr[itter] == type) { 1470 return BCM_E_NONE; 1471 } 1472 } 1473 1474 return BCM_E_INTERNAL; 1475 } 1476 1477 1478 /* 1479 * Function: 1480 * _bcm_vlan_1st (internal) 1481 * Purpose: 1482 * Return the first defined VLAN ID that is not the default VLAN. 1483 */ 1484 1485 STATIC INLINE bcm_vlan_t 1486 _bcm_vlan_1st(int unit) 1487 { 1488 int idx; 1489 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT) 1490 bcm_vlan_t olp_vlan = BCM_VLAN_INVALID; 1491 uint8 feature_xflow_macsec_olp = 0; 1492 if (soc_feature(unit, soc_feature_xflow_macsec_olp)) { 1493 olp_vlan = soc_property_get(unit, spn_XFLOW_MACSEC_OLP_VLAN, BCM_VLAN_INVALID); 1494 feature_xflow_macsec_olp = 1; 1495 } 1496 #endif 1497 for (idx = BCM_VLAN_MIN; idx < BCM_VLAN_COUNT; idx++) { 1498 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT) 1499 if ((idx == olp_vlan) && (feature_xflow_macsec_olp)) { 1500 continue; 1501 } 1502 #endif 1503 if ((idx != vlan_info[unit].defl) && 1504 (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, idx))) { 1505 return (idx); 1506 } 1507 } 1508 return BCM_VLAN_INVALID; 1509 } 1510 1511 /* 1512 * Function: 1513 * bcm_vlan_init 1514 * Purpose: 1515 * Initialize the VLAN module. 1516 * Parameters: 1517 * unit - StrataSwitch PCI device unit number (driver internal). 1518 * Returns: 1519 * BCM_E_NONE - Success. 1520 * BCM_E_INTERNAL - Chip access failure. 1521 */ 1522 1523 int 1524 bcm_esw_vlan_init(int unit) 1525 { 1526 bcm_vlan_info_t *vi = &vlan_info[unit]; 1527 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_WARM_BOOT_SUPPORT) 1528 int qm_size = 0; 1529 #endif 1530 int rv = BCM_E_NONE; 1531 #ifdef BCM_WARM_BOOT_SUPPORT 1532 soc_scache_handle_t scache_handle; 1533 uint8 *vlan_scache_ptr; 1534 uint32 vlan_scache_size; 1535 #else 1536 #endif /* BCM_WARM_BOOT_SUPPORT */ 1537 1538 #ifdef BCM_KATANA_SUPPORT 1539 vlan_subnet_entry_t *vstab=NULL; 1540 vlan_subnet_entry_t *vsnull=NULL; 1541 vlan_subnet_entry_t *vstabp=NULL; 1542 int index=0; 1543 int vsbytes=0; 1544 #endif 1545 int vlan_auto_stack_soc; 1546 1547 #ifdef BCM_TOMAHAWK3_SUPPORT 1548 if (SOC_IS_TOMAHAWK3(unit)) { 1549 return bcm_tomahawk3_vlan_init(unit); 1550 } 1551 #endif 1552 1553 vlan_auto_stack_soc = soc_property_get(unit, spn_VLAN_AUTO_STACK, 0); 1554 if (vlan_auto_stack_soc == 1) { 1555 vi->vlan_auto_stack = 1; 1556 } else if (vlan_auto_stack_soc == 2) { 1557 vi->vlan_auto_stack = 0; 1558 } else { 1559 #ifdef BCM_VLAN_NO_AUTO_STACK 1560 vi->vlan_auto_stack = 0; 1561 #else 1562 vi->vlan_auto_stack = 1; 1563 #endif /* BCM_VLAN_NO_AUTO_STACK */ 1564 } 1565 1566 if (SOC_WARM_BOOT(unit)) { 1567 return(_bcm_vlan_reinit(unit)); 1568 } else { 1569 1570 bcm_vlan_data_t vd; 1571 bcm_pbmp_t temp_pbmp; 1572 1573 /* 1574 * Initialize hardware tables 1575 */ 1576 1577 BCM_PBMP_CLEAR(temp_pbmp); 1578 BCM_PBMP_ASSIGN(temp_pbmp, PBMP_ALL(unit)); 1579 #ifdef BCM_KATANA2_SUPPORT 1580 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 1581 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &temp_pbmp)); 1582 } 1583 #endif 1584 vd.vlan_tag = BCM_VLAN_DEFAULT; 1585 BCM_PBMP_ASSIGN(vd.port_bitmap, temp_pbmp); 1586 BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_LB(unit)); 1587 BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_RDB_ALL(unit)); 1588 BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_FAE_ALL(unit)); 1589 BCM_PBMP_ASSIGN(vd.ut_port_bitmap, temp_pbmp); 1590 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_CMIC(unit)); 1591 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_LB(unit)); 1592 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_RDB_ALL(unit)); 1593 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_FAE_ALL(unit)); 1594 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_MACSEC_ALL(unit)); 1595 1596 /* 1597 * A compile-time application policy may prefer to not add 1598 * Ethernet or CPU ports to the default VLAN. 1599 */ 1600 1601 #ifdef BCM_VLAN_NO_DEFAULT_ETHER 1602 BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_E_ALL(unit)); 1603 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_E_ALL(unit)); 1604 #endif /* BCM_VLAN_NO_DEFAULT_ETHER */ 1605 #ifdef BCM_VLAN_NO_DEFAULT_CPU 1606 BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_CMIC(unit)); 1607 #endif /* BCM_VLAN_NO_DEFAULT_CPU */ 1608 1609 if (!vi->vlan_auto_stack) { 1610 BCM_PBMP_REMOVE(vd.port_bitmap, SOC_PBMP_STACK_CURRENT(unit)); 1611 BCM_PBMP_REMOVE(vd.ut_port_bitmap, SOC_PBMP_STACK_CURRENT(unit)); 1612 } 1613 1614 #if defined(BCM_RCPU_SUPPORT) 1615 if (SOC_IS_RCPU_ONLY(unit) && vlan_info[unit].init) { 1616 bcm_vlan_t idx; 1617 soc_rcpu_cfg_t cfg; 1618 1619 if (SOC_E_NONE != soc_cm_get_rcpu_cfg(unit, &cfg)) { 1620 cfg.vlan = BCM_VLAN_INVALID; 1621 } 1622 1623 /* Destroy previous VLANs */ 1624 for (idx = BCM_VLAN_MIN; idx < BCM_VLAN_COUNT; idx++) { 1625 if ((idx != vlan_info[unit].defl) && 1626 (idx != cfg.vlan) && 1627 (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, idx))) { 1628 BCM_IF_ERROR_RETURN 1629 (mbcm_driver[unit]->mbcm_vlan_destroy(unit, idx)); 1630 } 1631 } 1632 } 1633 #endif /* BCM_RCPU_SUPPORT */ 1634 1635 #ifdef BCM_MCAST_FLOOD_DEFAULT 1636 BCM_IF_ERROR_RETURN 1637 (_bcm_esw_vlan_flood_default_set(unit, BCM_MCAST_FLOOD_DEFAULT)); 1638 #else 1639 BCM_IF_ERROR_RETURN 1640 (_bcm_esw_vlan_flood_default_set(unit, 1641 BCM_VLAN_MCAST_FLOOD_UNKNOWN)); 1642 #endif 1643 1644 #if defined (BCM_EASY_RELOAD_SUPPORT) 1645 BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->egr_vlan_bmp)); 1646 BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->vlan_tab_bmp)); 1647 #endif 1648 1649 BCM_IF_ERROR_RETURN 1650 (mbcm_driver[unit]->mbcm_vlan_init(unit, &vd)); 1651 1652 1653 #ifdef BCM_TRIUMPH2_SUPPORT 1654 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 1655 if (vi->qm_bmp != NULL) { 1656 sal_free(vi->qm_bmp); 1657 } 1658 if (vi->qm_it_bmp != NULL) { 1659 sal_free(vi->qm_it_bmp); 1660 } 1661 1662 qm_size = SHR_BITALLOCSIZE 1663 (1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm, 1664 PHB2_DOT1P_MAPPING_PTRf)); 1665 vi->qm_bmp = sal_alloc(qm_size, "VLAN queue mapping bitmap"); 1666 if (vi->qm_bmp == NULL) { 1667 return BCM_E_MEMORY; 1668 } 1669 sal_memset(vi->qm_bmp, 0, qm_size); 1670 vi->qm_it_bmp = sal_alloc(qm_size, "VLAN queue mapping bitmap"); 1671 if (vi->qm_it_bmp == NULL) { 1672 return BCM_E_MEMORY; 1673 } 1674 } 1675 #endif 1676 1677 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 1678 if (soc_feature(unit, soc_feature_vlan_vp)) { 1679 #ifdef BCM_ENDURO_SUPPORT 1680 if (SOC_IS_ENDURO(unit)) { 1681 BCM_IF_ERROR_RETURN(bcm_enduro_vlan_virtual_init(unit)); 1682 } else 1683 #endif /* BCM_ENDURO_SUPPORT */ 1684 { 1685 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_virtual_init(unit)); 1686 } 1687 } 1688 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 1689 1690 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 1691 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1692 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 1693 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_init(unit)); 1694 } else 1695 #endif 1696 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) || 1697 soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 1698 BCM_IF_ERROR_RETURN(bcm_td_vp_group_init(unit)); 1699 } 1700 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 1701 1702 #ifdef BCM_KATANA_SUPPORT 1703 1704 /* ###################################################################### */ 1705 /* Temporary Work around for katata chip to initialize vlan_subnet table */ 1706 /* with zero entries */ 1707 /* ###################################################################### */ 1708 1709 if (SOC_IS_KATANA(unit)) { 1710 vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm); 1711 vsbytes = soc_mem_entry_words(unit, VLAN_SUBNETm); 1712 vsbytes = WORDS2BYTES(vsbytes); 1713 vstab = soc_cm_salloc(unit, 1714 soc_mem_index_count(unit, VLAN_SUBNETm) * 1715 sizeof(*vstab), "vlan_subnet"); 1716 if (vstab == NULL) { 1717 return BCM_E_MEMORY; 1718 } 1719 rv = soc_mem_read_range(unit, VLAN_SUBNETm, MEM_BLOCK_ANY, 1720 soc_mem_index_min(unit, VLAN_SUBNETm), 1721 soc_mem_index_max(unit, VLAN_SUBNETm), vstab); 1722 if (BCM_FAILURE(rv)) { 1723 soc_cm_sfree(unit, vstab); 1724 return rv; 1725 } 1726 for(index = soc_mem_index_min(unit, VLAN_SUBNETm); 1727 index < soc_mem_index_count(unit, VLAN_SUBNETm); 1728 index++) { 1729 vstabp = soc_mem_table_idx_to_pointer(unit, 1730 VLAN_SUBNETm, vlan_subnet_entry_t *, 1731 vstab, index); 1732 sal_memcpy(vstabp,vsnull,vsbytes); 1733 } 1734 rv = soc_mem_write_range(unit, VLAN_SUBNETm, MEM_BLOCK_ALL, 1735 soc_mem_index_min(unit, VLAN_SUBNETm), 1736 soc_mem_index_max(unit, VLAN_SUBNETm), vstab); 1737 soc_cm_sfree(unit, vstab); 1738 if (BCM_FAILURE(rv)) { 1739 return rv; 1740 } 1741 } 1742 #endif 1743 1744 /* 1745 * Initialize software structures 1746 */ 1747 vi->defl = BCM_VLAN_DEFAULT; 1748 1749 #ifdef BCM_WARM_BOOT_SUPPORT 1750 /* Warm boot level 2 cache size */ 1751 /* Type for 'flood_mode' is an enum, which values fit in uint8 */ 1752 vlan_scache_size = sizeof(vi->defl);/* Default VLAN */ 1753 vlan_scache_size += sizeof(vi->old_egr_xlate_cnt); /* VLAN XLATE old_cnt */ 1754 vlan_scache_size += sizeof(uint8); /* Flood mode */ 1755 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 1756 vlan_scache_size += (qm_size * 2); /* (qm_bmp, qm_it_bmp) */ 1757 } 1758 1759 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) || 1760 soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 1761 vlan_scache_size += sizeof(uint8) * 2; /* vp group unmanaged flags */ 1762 } 1763 1764 if (BCM_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_1) { 1765 /* VLAN info: VP Multicast control mode */ 1766 vlan_scache_size += sizeof(vi->vp_mode); 1767 } 1768 1769 #ifdef BCM_TRIDENT3_SUPPORT 1770 if (soc_feature(unit, soc_feature_pvlan_on_vfi)) { 1771 if (BCM_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_2) { 1772 vlan_scache_size += sizeof(vi->shared_vlan_enable); 1773 } 1774 } 1775 #endif 1776 1777 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VLAN, 0); 1778 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 1779 vlan_scache_size, 1780 &vlan_scache_ptr, 1781 BCM_WB_DEFAULT_VERSION, NULL); 1782 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 1783 return rv; 1784 } 1785 rv = BCM_E_NONE; 1786 #endif /* BCM_WARM_BOOT_SUPPORT */ 1787 1788 1789 /* In case bcm_vlan_init is called more than once */ 1790 BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->bmp)); 1791 _BCM_VBMP_INSERT(vi->bmp, vd.vlan_tag); 1792 1793 BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->pre_cfg_bmp)); 1794 1795 #if defined (BCM_EASY_RELOAD_SUPPORT) 1796 _BCM_VBMP_INSERT(vi->egr_vlan_bmp, vd.vlan_tag); 1797 _BCM_VBMP_INSERT(vi->vlan_tab_bmp, vd.vlan_tag); 1798 #endif 1799 1800 /* Free vlan translation arrays if any. */ 1801 if (NULL != vi->egr_trans) { 1802 sal_free(vi->egr_trans); 1803 vi->egr_trans = NULL; 1804 } 1805 if (NULL != vi->ing_trans) { 1806 sal_free(vi->ing_trans); 1807 vi->ing_trans = NULL; 1808 } 1809 1810 vi->count = 1; 1811 1812 } 1813 1814 vi->init = TRUE; 1815 1816 #if defined(BCM_RCPU_SUPPORT) 1817 if (SOC_IS_RCPU_ONLY(unit)) { 1818 soc_rcpu_cfg_t cfg; 1819 if (SOC_E_NONE == soc_cm_get_rcpu_cfg(unit, &cfg) && 1820 BCM_VLAN_DEFAULT != cfg.vlan) { 1821 /* 1822 * RCPU vlan should have been created in remote device, sync 1823 * software status. 1824 */ 1825 _BCM_VBMP_INSERT(vlan_info[unit].bmp, cfg.vlan); 1826 vlan_info[unit].count++; 1827 } 1828 } 1829 #endif /* BCM_RCPU_SUPPORT */ 1830 1831 return rv; 1832 } 1833 1834 /* 1835 * Function: 1836 * bcm_esw_vlan_detach 1837 * Purpose: 1838 * De-initialize the VLAN module. 1839 * Parameters: 1840 * unit - (IN) BCM device number. 1841 * Returns: 1842 * BCM_E_XXX 1843 */ 1844 1845 int 1846 bcm_esw_vlan_detach(int unit) 1847 { 1848 bcm_vlan_info_t *vi = &vlan_info[unit]; 1849 int rv = BCM_E_NONE; 1850 1851 #ifdef BCM_TOMAHAWK3_SUPPORT 1852 if (SOC_IS_TOMAHAWK3(unit)) { 1853 return bcm_tomahawk3_vlan_detach(unit); 1854 } 1855 #endif 1856 1857 BCM_LOCK(unit); 1858 1859 _bcm_vbmp_destroy(&vi->bmp); 1860 rv = _bcm_vbmp_destroy(&vi->pre_cfg_bmp); 1861 if (BCM_FAILURE(rv)) { 1862 BCM_UNLOCK(unit); 1863 return (rv); 1864 } 1865 #if defined (BCM_EASY_RELOAD_SUPPORT) 1866 rv = _bcm_vbmp_destroy(&vi->egr_vlan_bmp); 1867 if (BCM_FAILURE(rv)) { 1868 BCM_UNLOCK(unit); 1869 return (rv); 1870 } 1871 rv = _bcm_vbmp_destroy(&vi->vlan_tab_bmp); 1872 if (BCM_FAILURE(rv)) { 1873 BCM_UNLOCK(unit); 1874 return (rv); 1875 } 1876 #endif 1877 1878 if (vi->egr_trans != NULL) { 1879 sal_free(vi->egr_trans); 1880 vi->egr_trans = NULL; 1881 } 1882 if (vi->ing_trans != NULL) { 1883 sal_free(vi->ing_trans); 1884 vi->ing_trans = NULL; 1885 } 1886 1887 vi->init = 0; 1888 1889 #ifdef BCM_TRIUMPH2_SUPPORT 1890 if (soc_feature(unit, soc_feature_gport_service_counters)) { 1891 rv = _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeService); 1892 } 1893 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 1894 sal_free(vi->qm_bmp); 1895 vi->qm_bmp = NULL; 1896 sal_free(vi->qm_it_bmp); 1897 vi->qm_it_bmp = NULL; 1898 } 1899 #endif /* BCM_TRIUMPH2_SUPPORT */ 1900 1901 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 1902 || defined(BCM_RAVEN_SUPPORT) 1903 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 1904 rv = _bcm_xgs3_vlan_profile_detach(unit); 1905 } 1906 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || \ 1907 BCM_RAVEN_SUPPORT */ 1908 1909 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 1910 if (soc_feature(unit, soc_feature_vlan_vp)) { 1911 #ifdef BCM_ENDURO_SUPPORT 1912 if (SOC_IS_ENDURO(unit)) { 1913 rv = bcm_enduro_vlan_virtual_detach(unit); 1914 if (BCM_FAILURE(rv)) { 1915 BCM_UNLOCK(unit); 1916 return (rv); 1917 } 1918 } else 1919 #endif /* BCM_ENDURO_SUPPORT */ 1920 { 1921 rv = bcm_tr2_vlan_virtual_detach(unit); 1922 if (BCM_FAILURE(rv)) { 1923 BCM_UNLOCK(unit); 1924 return (rv); 1925 } 1926 } 1927 } 1928 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 1929 1930 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 1931 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1932 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 1933 rv = bcm_td2p_vp_group_detach(unit); 1934 if (BCM_FAILURE(rv)) { 1935 BCM_UNLOCK(unit); 1936 return (rv); 1937 } 1938 } else 1939 #endif 1940 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) || 1941 soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 1942 rv = bcm_td_vp_group_detach(unit); 1943 if (BCM_FAILURE(rv)) { 1944 BCM_UNLOCK(unit); 1945 return (rv); 1946 } 1947 } 1948 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 1949 1950 BCM_UNLOCK(unit); 1951 return rv; 1952 } 1953 1954 /* 1955 * Function: 1956 * _bcm_vlan_create 1957 * Purpose: 1958 * Main body of bcm_vlan_create; assumes locking already done; 1959 */ 1960 1961 STATIC int 1962 _bcm_vlan_create(int unit, bcm_vlan_t vid) 1963 { 1964 bcm_stg_t stg_defl; 1965 int rv; 1966 rv = bcm_esw_stg_default_get(unit, &stg_defl); 1967 if (rv == BCM_E_UNAVAIL) { 1968 stg_defl = -1; 1969 } else if (rv < 0) { 1970 return rv; 1971 } 1972 1973 #ifdef BCM_SHADOW_SUPPORT 1974 if (SOC_IS_SHADOW(unit)) { 1975 return BCM_E_NONE; 1976 } 1977 #endif /* BCM_SHADOW_SUPPORT */ 1978 1979 if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) { 1980 return BCM_E_EXISTS; 1981 } 1982 1983 BCM_IF_ERROR_RETURN 1984 (mbcm_driver[unit]->mbcm_vlan_create(unit, vid)); 1985 1986 _BCM_VBMP_INSERT(vlan_info[unit].bmp, vid); 1987 SHR_BITCLR(vlan_info[unit].pre_cfg_bmp.w,vid); 1988 vlan_info[unit].count++; 1989 1990 if (stg_defl >= 0) { 1991 /* Must be after v bitmap insert */ 1992 BCM_IF_ERROR_RETURN 1993 (bcm_esw_stg_vlan_add(unit, stg_defl, vid)); 1994 } 1995 1996 return BCM_E_NONE; 1997 } 1998 1999 /* 2000 * Function: 2001 * bcm_vlan_create 2002 * Purpose: 2003 * Allocate and configure a VLAN on StrataSwitch. 2004 * Parameters: 2005 * unit - StrataSwitch PCI device unit number (driver internal). 2006 * vid - VLAN ID to create. 2007 * Returns: 2008 * BCM_E_NONE - Success. 2009 * BCM_E_INTERNAL - Chip access failure. 2010 * BCM_E_EXISTS - VLAN ID already in use. 2011 * Notes: 2012 * VLAN is placed in the default STG and can be reassigned later. 2013 */ 2014 2015 int 2016 bcm_esw_vlan_create(int unit, bcm_vlan_t vid) 2017 { 2018 int rv; 2019 2020 LOG_VERBOSE(BSL_LS_BCM_VLAN, 2021 (BSL_META_U(unit, 2022 "VLAN %d: create vid %d\n"), 2023 unit, vid)); 2024 2025 CHECK_INIT(unit); 2026 VLAN_CHK_ID(unit, vid); 2027 2028 /* Check if valid vlan id */ 2029 if (vid == BCM_VLAN_NONE) { 2030 return BCM_E_PARAM; 2031 } 2032 2033 BCM_LOCK(unit); 2034 rv = _bcm_vlan_create(unit, vid); 2035 2036 if (vlan_info[unit].vlan_auto_stack) { 2037 if (rv == BCM_E_NONE) { 2038 soc_pbmp_t stacked, empty_pbmp; 2039 2040 SOC_PBMP_ASSIGN(stacked, SOC_PBMP_STACK_CURRENT(unit)); 2041 SOC_PBMP_CLEAR(empty_pbmp); 2042 2043 rv = _bcm_vlan_port_add(unit, vid, stacked, empty_pbmp, stacked, 0); 2044 } 2045 } 2046 BCM_UNLOCK(unit); 2047 2048 return rv; 2049 } 2050 2051 /* 2052 * Function: 2053 * _bcm_vlan_destroy 2054 * Purpose: 2055 * Main body of bcm_vlan_destroy; assumes locking done. 2056 */ 2057 2058 STATIC int 2059 _bcm_vlan_destroy(int unit, bcm_vlan_t vid) 2060 { 2061 bcm_stg_t stg; 2062 int rv; 2063 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 2064 bcm_multicast_t mc_group; 2065 vlan_tab_entry_t vtab; 2066 int bc_index, umc_index, uuc_index; 2067 #endif 2068 2069 /* Cannot destroy default VLAN */ 2070 if (vid == vlan_info[unit].defl) { 2071 return BCM_E_BADID; 2072 } 2073 2074 if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) { 2075 return BCM_E_NOT_FOUND; 2076 } 2077 2078 #if defined(BCM_RCPU_SUPPORT) 2079 if (SOC_IS_RCPU_ONLY(unit)) { 2080 soc_rcpu_cfg_t cfg; 2081 if ((SOC_E_NONE == soc_cm_get_rcpu_cfg(unit, &cfg)) && 2082 (vid == cfg.vlan)) { 2083 return BCM_E_BADID; 2084 } 2085 } 2086 #endif /* BCM_RCPU_SUPPORT */ 2087 2088 /* Remove VLAN from its spanning tree group */ 2089 BCM_IF_ERROR_RETURN 2090 (bcm_esw_vlan_stg_get(unit, vid, &stg)); 2091 2092 rv = _bcm_stg_vlan_destroy(unit, stg, vid); 2093 if (rv < 0 && rv != BCM_E_UNAVAIL) { 2094 return rv; 2095 } 2096 2097 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 2098 /* If virtual port switching is enabled, destroy the 2099 * BC, UMC, and UUC multicast groups. 2100 */ 2101 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 2102 BCM_IF_ERROR_RETURN 2103 (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vtab)); 2104 2105 if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 2106 bc_index = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 2107 if (BCM_SUCCESS( 2108 _bcm_tr_multicast_ipmc_group_type_get(unit, bc_index, 2109 &mc_group))) { 2110 BCM_IF_ERROR_RETURN(bcm_esw_multicast_destroy(unit, mc_group)); 2111 } 2112 2113 umc_index = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 2114 if (umc_index != bc_index) { 2115 if (BCM_SUCCESS( 2116 _bcm_tr_multicast_ipmc_group_type_get(unit, umc_index, 2117 &mc_group))) { 2118 BCM_IF_ERROR_RETURN(bcm_esw_multicast_destroy(unit, mc_group)); 2119 } 2120 } 2121 2122 uuc_index = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 2123 if ((uuc_index != bc_index) && (uuc_index != umc_index)) { 2124 if (BCM_SUCCESS( 2125 _bcm_tr_multicast_ipmc_group_type_get(unit, uuc_index, 2126 &mc_group))) { 2127 BCM_IF_ERROR_RETURN(bcm_esw_multicast_destroy(unit, mc_group)); 2128 } 2129 } 2130 } 2131 } 2132 #endif 2133 2134 BCM_IF_ERROR_RETURN 2135 (mbcm_driver[unit]->mbcm_vlan_destroy(unit, vid)); 2136 2137 _BCM_VBMP_REMOVE(vlan_info[unit].bmp, vid); 2138 2139 vlan_info[unit].count--; 2140 2141 return BCM_E_NONE; 2142 } 2143 2144 /* 2145 * Function: 2146 * bcm_vlan_destroy 2147 * Purpose: 2148 * Deallocate VLAN from StrataSwitch. 2149 * Parameters: 2150 * unit - StrataSwitch PCI device unit number (driver internal). 2151 * vid - VLAN ID to affect. 2152 * Returns: 2153 * BCM_E_NONE Success. 2154 * BCM_E_INTERNAL Chip access failure. 2155 * BCM_E_BADID Cannot remove default VLAN 2156 * BCM_E_NOT_FOUND VLAN ID not in use. 2157 * Notes: 2158 * None. 2159 */ 2160 2161 int 2162 bcm_esw_vlan_destroy(int unit, bcm_vlan_t vid) 2163 { 2164 int rv; 2165 2166 LOG_VERBOSE(BSL_LS_BCM_VLAN, 2167 (BSL_META_U(unit, 2168 "VLAN %d: destroy vid %d\n"), 2169 unit, vid)); 2170 2171 CHECK_INIT(unit); 2172 VLAN_CHK_ID(unit, vid); 2173 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT) 2174 if (soc_feature(unit, soc_feature_xflow_macsec_olp)) { 2175 if (vid == soc_property_get(unit, spn_XFLOW_MACSEC_OLP_VLAN, BCM_VLAN_INVALID)) { 2176 return BCM_E_PARAM; 2177 } 2178 } 2179 #endif 2180 BCM_LOCK(unit); 2181 rv = _bcm_vlan_destroy(unit, vid); 2182 BCM_UNLOCK(unit); 2183 2184 return rv; 2185 } 2186 2187 /* 2188 * Function: 2189 * bcm_vlan_destroy_all 2190 * Purpose: 2191 * Destroy all VLANs except the default VLAN 2192 * Parameters: 2193 * unit - StrataSwitch PCI device unit number (driver internal). 2194 * Returns: 2195 * BCM_E_NONE - Success. 2196 * BCM_E_INTERNAL - Chip access failure. 2197 * Notes: 2198 * None. 2199 */ 2200 2201 int 2202 bcm_esw_vlan_destroy_all(int unit) 2203 { 2204 int rv = BCM_E_NONE; 2205 bcm_vlan_t vid; 2206 2207 LOG_VERBOSE(BSL_LS_BCM_VLAN, 2208 (BSL_META_U(unit, 2209 "VLAN %d: destroy all VLANs\n"), 2210 unit)); 2211 2212 CHECK_INIT(unit); 2213 2214 BCM_LOCK(unit); 2215 2216 while ((vid = _bcm_vlan_1st(unit)) != BCM_VLAN_INVALID) { 2217 if ((rv = bcm_esw_vlan_destroy(unit, vid)) < 0) { 2218 break; 2219 } 2220 } 2221 2222 #ifdef BCM_KATANA2_SUPPORT 2223 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 2224 /* Clear parity status on L2 bulk operation */ 2225 if (BCM_FAILURE(rv)) { 2226 BCM_UNLOCK(unit); 2227 return (rv); 2228 } 2229 rv = soc_reg_field32_modify(unit, L2_BULK_CONTROLr, 2230 REG_PORT_ANY, STARTf, 0); 2231 if (BCM_FAILURE(rv)) { 2232 BCM_UNLOCK(unit); 2233 return (rv); 2234 } 2235 rv = soc_reg_field32_modify(unit, L2_BULK_CONTROLr, 2236 REG_PORT_ANY, COMPLETEf, 0); 2237 } 2238 #endif 2239 BCM_UNLOCK(unit); 2240 2241 return rv; 2242 } 2243 2244 /* 2245 * Function: 2246 * _bcm_vlan_port_add 2247 * Purpose: 2248 * Main part of bcm_vlan_port_add; assumes locking already done. 2249 */ 2250 2251 STATIC int 2252 _bcm_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp, 2253 pbmp_t ing_pbmp, int flags) 2254 { 2255 pbmp_t vlan_pbmp, vlan_ubmp, vlan_ing_pbmp, orig_pbmp; 2256 pbmp_t stacked; 2257 2258 /* No such thing as untagged CPU */ 2259 SOC_PBMP_REMOVE(ubmp, PBMP_CMIC(unit)); 2260 2261 /* Remove internal loopback port from vlan port bitmaps. 2262 * Hardware does not perform ingress and egress VLAN membership checks 2263 * on internal loopback port. Also, on Triumph2, the port bitmaps in 2264 * VLAN and EGR_VLAN tables do not include the internal loopback port. 2265 */ 2266 SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 2267 SOC_PBMP_REMOVE(ubmp, PBMP_LB(unit)); 2268 SOC_PBMP_REMOVE(ing_pbmp, PBMP_LB(unit)); 2269 2270 /* 2271 * Illegal to have untagged stack ports; remove inactive ports from bitmap 2272 */ 2273 SOC_PBMP_STACK_ACTIVE_GET(unit, stacked); 2274 SOC_PBMP_REMOVE(ubmp, stacked); 2275 SOC_PBMP_REMOVE(pbmp, SOC_PBMP_STACK_INACTIVE(unit)); 2276 SOC_PBMP_REMOVE(ubmp, SOC_PBMP_STACK_INACTIVE(unit)); 2277 SOC_PBMP_REMOVE(ing_pbmp, SOC_PBMP_STACK_INACTIVE(unit)); 2278 2279 /* Don't add ports that are already there */ 2280 BCM_IF_ERROR_RETURN 2281 (mbcm_driver[unit]->mbcm_vlan_port_get(unit, vid, &vlan_pbmp, 2282 &vlan_ubmp, &vlan_ing_pbmp)); 2283 SOC_PBMP_ASSIGN(orig_pbmp, pbmp); 2284 COMPILER_REFERENCE(orig_pbmp); 2285 /* But do allow for making the port tagged/untagged if its already added to the vlan */ 2286 SOC_PBMP_XOR(vlan_ubmp, ubmp); 2287 SOC_PBMP_REMOVE(vlan_pbmp, vlan_ubmp); 2288 SOC_PBMP_REMOVE(pbmp, vlan_pbmp); 2289 SOC_PBMP_REMOVE(ubmp, vlan_pbmp); 2290 SOC_PBMP_REMOVE(ing_pbmp, vlan_ing_pbmp); 2291 2292 if (SOC_PBMP_NOT_NULL(pbmp) || SOC_PBMP_NOT_NULL(ubmp) || 2293 SOC_PBMP_NOT_NULL(ing_pbmp)) { 2294 BCM_IF_ERROR_RETURN 2295 (mbcm_driver[unit]->mbcm_vlan_port_add 2296 (unit, vid, pbmp, ubmp, ing_pbmp)); 2297 } 2298 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 2299 if (soc_feature(unit, soc_feature_vlan_egress_membership_l3_only) && 2300 (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 2301 if (SOC_PBMP_NOT_NULL(pbmp)) { 2302 SOC_PBMP_CLEAR(ing_pbmp); 2303 SOC_PBMP_CLEAR(ubmp); 2304 BCM_IF_ERROR_RETURN 2305 (_bcm_xgs3_vlan_table_port_remove(unit, vid, pbmp, ubmp, 2306 ing_pbmp, VLAN_TABLE(unit))); 2307 } 2308 } 2309 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_HURRICANE3_SUPPORT */ 2310 2311 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 2312 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf) && 2313 BCM_VLAN_VALID(vid)) { 2314 2315 vlan_tab_entry_t vtab; 2316 int ipmc_group[3] = {0, 0, 0}; 2317 int do_not_add[3] = {0, 0, 0}; 2318 int i; 2319 int rv; 2320 bcm_multicast_t mc_group; 2321 pbmp_t l2_pbmp, l3_pbmp; 2322 2323 BCM_IF_ERROR_RETURN 2324 (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vtab)); 2325 2326 if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 2327 /* If virtual port switching is enabled, update the 2328 * L2_BITMAP in the corresponding MC group 2329 */ 2330 2331 ipmc_group[0] = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 2332 ipmc_group[1] = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 2333 ipmc_group[2] = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 2334 2335 if (flags & BCM_VLAN_GPORT_ADD_BCAST_DO_NOT_ADD) { 2336 do_not_add[0] = 1; 2337 } 2338 if (flags & BCM_VLAN_GPORT_ADD_UNKNOWN_MCAST_DO_NOT_ADD) { 2339 do_not_add[1] = 1; 2340 } 2341 if (flags & BCM_VLAN_GPORT_ADD_UNKNOWN_UCAST_DO_NOT_ADD) { 2342 do_not_add[2] = 1; 2343 } 2344 2345 if ((ipmc_group[0] == ipmc_group[1]) && (do_not_add[0] != do_not_add[1])) { 2346 return BCM_E_PARAM; 2347 } 2348 if ((ipmc_group[0] == ipmc_group[2]) && (do_not_add[0] != do_not_add[2])) { 2349 return BCM_E_PARAM; 2350 } 2351 if ((ipmc_group[1] == ipmc_group[2]) && (do_not_add[1] != do_not_add[2])) { 2352 return BCM_E_PARAM; 2353 } 2354 2355 for (i = 0; i < 3; i++) { 2356 if (do_not_add[i]) { 2357 continue; 2358 } 2359 /* index:0 is reserved, check if multicast group is used */ 2360 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, ipmc_group[i], &mc_group); 2361 if (rv < 0) { 2362 /* if index is used, ensure error code is checked */ 2363 if (ipmc_group[i] != 0) { 2364 return rv; 2365 } 2366 continue; 2367 } 2368 2369 BCM_IF_ERROR_RETURN(_bcm_esw_multicast_ipmc_read(unit, ipmc_group[i], 2370 &l2_pbmp, 2371 &l3_pbmp)); 2372 SOC_PBMP_OR(l2_pbmp, orig_pbmp); 2373 BCM_IF_ERROR_RETURN(_bcm_esw_multicast_ipmc_write(unit, 2374 ipmc_group[i], l2_pbmp, l3_pbmp, TRUE)); 2375 } 2376 } 2377 } 2378 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 2379 2380 return BCM_E_NONE; 2381 } 2382 2383 /* 2384 * Function: 2385 * bcm_vlan_port_add 2386 * Purpose: 2387 * Add ports to the specified vlan. 2388 * Parameters: 2389 * unit - StrataSwitch PCI device unit number (driver internal). 2390 * vid - VLAN ID to add port to as a member. 2391 * pbmp - port bitmap for members of VLAN 2392 * ubmp - untagged members of VLAN 2393 * Returns: 2394 * BCM_E_NONE - Success. 2395 * BCM_E_INTERNAL - Chip access failure. 2396 * BCM_E_NOT_FOUND - VLAN ID not in use. 2397 */ 2398 2399 int 2400 bcm_esw_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp) 2401 { 2402 int rv = BCM_E_NONE; 2403 bcm_pbmp_t pbm, ubm; 2404 2405 #ifdef BCM_TOMAHAWK3_SUPPORT 2406 if (SOC_IS_TOMAHAWK3(unit)) { 2407 return bcm_tomahawk3_vlan_port_add(unit, vid, pbmp, ubmp); 2408 } 2409 #endif 2410 2411 CHECK_INIT(unit); 2412 VLAN_CHK_ID(unit, vid); 2413 2414 BCM_PBMP_CLEAR(pbm); 2415 BCM_PBMP_CLEAR(ubm); 2416 2417 /* we need to check if pbmp and ubmp are valid as well */ 2418 BCM_PBMP_ASSIGN(pbm,PBMP_ALL(unit)); 2419 BCM_PBMP_ASSIGN(ubm,PBMP_ALL(unit)); 2420 2421 #ifdef BCM_KATANA2_SUPPORT 2422 if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_linkphy_coe) || 2423 soc_feature(unit, soc_feature_subtag_coe))) { 2424 _bcm_kt2_subport_pbmp_update(unit, &pbm); 2425 _bcm_kt2_subport_pbmp_update(unit, &ubm); 2426 } 2427 #endif 2428 2429 BCM_PBMP_AND(pbm,pbmp); 2430 BCM_PBMP_AND(ubm,ubmp); 2431 2432 if(!(BCM_PBMP_EQ(pbm, pbmp) && BCM_PBMP_EQ(ubm, ubmp))) { 2433 return BCM_E_PARAM; 2434 } 2435 2436 LOG_VERBOSE(BSL_LS_BCM_VLAN, 2437 (BSL_META_U(unit, 2438 "VLAN %d: port add: vid %d. pbm 0x%x. utpbm 0x%x.\n"), 2439 unit, vid, SOC_PBMP_WORD_GET(pbmp, 0), 2440 SOC_PBMP_WORD_GET(ubmp, 0))); 2441 2442 BCM_LOCK(unit); 2443 rv = _bcm_vlan_port_add(unit, vid, pbmp, ubmp, pbmp, 0); 2444 BCM_UNLOCK(unit); 2445 2446 return rv; 2447 } 2448 2449 /* 2450 * Function: 2451 * _bcm_vlan_port_remove 2452 * Purpose: 2453 * Main part of bcm_vlan_port_remove; assumes locking already done. 2454 */ 2455 2456 STATIC int 2457 _bcm_vlan_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp, 2458 pbmp_t ing_pbmp, soc_field_t *dlf_type) 2459 { 2460 pbmp_t vlan_pbmp, vlan_ubmp, vlan_ing_pbmp, orig_pbmp; 2461 int rv = BCM_E_NONE; 2462 2463 /* Don't remove ports that are not there */ 2464 2465 BCM_LOCK(unit); 2466 2467 rv = (mbcm_driver[unit]->mbcm_vlan_port_get 2468 (unit, vid, &vlan_pbmp, &vlan_ubmp, &vlan_ing_pbmp)); 2469 if (rv < 0) { 2470 BCM_UNLOCK(unit); 2471 return rv; 2472 } 2473 2474 SOC_PBMP_ASSIGN(orig_pbmp, pbmp); 2475 if (!soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf) && 2476 !(soc_feature(unit, soc_feature_vlan_vfi_membership))) { 2477 SOC_PBMP_OR(vlan_pbmp, vlan_ing_pbmp); 2478 SOC_PBMP_AND(pbmp, vlan_pbmp); 2479 } 2480 COMPILER_REFERENCE(orig_pbmp); 2481 2482 rv = (mbcm_driver[unit]->mbcm_vlan_port_remove(unit, vid, pbmp, ubmp, 2483 ing_pbmp)); 2484 if (rv < 0) { 2485 BCM_UNLOCK(unit); 2486 return rv; 2487 } 2488 2489 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 2490 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf) && 2491 BCM_VLAN_VALID(vid)) { 2492 2493 vlan_tab_entry_t vtab; 2494 soc_field_t grp_type[3] = {BC_IDXf, UMC_IDXf, UUC_IDXf}; 2495 int i; 2496 int mc_index; 2497 bcm_multicast_t mc_group; 2498 pbmp_t l2_pbmp, l3_pbmp; 2499 soc_field_t * group_type; 2500 2501 if (dlf_type == NULL) { 2502 group_type = grp_type; 2503 } else { 2504 group_type = dlf_type; 2505 } 2506 2507 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vtab); 2508 if (BCM_FAILURE(rv)) { 2509 BCM_UNLOCK(unit); 2510 return (rv); 2511 } 2512 2513 if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 2514 /* If virtual port switching is enabled, update the 2515 * L2_BITMAP in the corresponding MC group 2516 */ 2517 2518 for (i = 0; i < 3; i++) { 2519 if (group_type[i] == 0) { 2520 continue; 2521 } 2522 mc_index = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, 2523 group_type[i]); 2524 2525 /* index:0 is reserved, check if multicast group is used */ 2526 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, mc_index, 2527 &mc_group); 2528 if (rv < 0) { 2529 if (mc_index != 0) { 2530 BCM_UNLOCK(unit); 2531 return rv; 2532 } 2533 continue; 2534 } 2535 2536 rv = _bcm_esw_multicast_ipmc_read(unit, mc_index, 2537 &l2_pbmp, &l3_pbmp); 2538 if (rv < 0) { 2539 BCM_UNLOCK(unit); 2540 return rv; 2541 } 2542 2543 BCM_PBMP_REMOVE(l2_pbmp, orig_pbmp); 2544 2545 rv = _bcm_esw_multicast_ipmc_write(unit, mc_index, 2546 l2_pbmp, l3_pbmp, TRUE); 2547 if (rv < 0) { 2548 BCM_UNLOCK(unit); 2549 return rv; 2550 } 2551 } 2552 } 2553 } 2554 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 2555 2556 BCM_UNLOCK(unit); 2557 2558 return BCM_E_NONE; 2559 } 2560 2561 /* 2562 * Function: 2563 * bcm_vlan_port_remove 2564 * Purpose: 2565 * Remove ports from a specified vlan. 2566 * Parameters: 2567 * unit - StrataSwitch PCI device unit number (driver internal). 2568 * vid - VLAN ID to remove port(s) from. 2569 * pbmp - port bitmap for ports to remove. 2570 * Returns: 2571 * BCM_E_NONE - Success. 2572 * BCM_E_INTERNAL - Chip access failure. 2573 * BCM_E_NOT_FOUND - VLAN ID not in use. 2574 * Notes: 2575 * None. 2576 */ 2577 2578 int 2579 bcm_esw_vlan_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp) 2580 { 2581 int rv = BCM_E_NONE; 2582 2583 #ifdef BCM_TOMAHAWK3_SUPPORT 2584 if (SOC_IS_TOMAHAWK3(unit)) { 2585 return bcm_tomahawk3_vlan_port_remove(unit, vid, pbmp); 2586 } 2587 #endif 2588 2589 LOG_VERBOSE(BSL_LS_BCM_VLAN, 2590 (BSL_META_U(unit, 2591 "VLAN %d: port remove: vid %d. pbm 0x%x.\n"), 2592 unit, vid, SOC_PBMP_WORD_GET(pbmp, 0))); 2593 2594 CHECK_INIT(unit); 2595 VLAN_CHK_ID(unit, vid); 2596 /* As we are passing only one pbmp parameter to API bcm_vlan_port_remove, 2597 * the expected result is to remove same pbmp from PORT_BITMAPf, UT_BITMAPf 2598 * and ING_PORT_BITMAPf. Hence, same pbmp is passed as argument for ubmp 2599 * and ing_pbmp to _bcm_vlan_port_remove*/ 2600 rv = _bcm_vlan_port_remove(unit, vid, pbmp, pbmp, pbmp, NULL); 2601 2602 return rv; 2603 } 2604 2605 /* 2606 * Function: 2607 * _bcm_vlan_port_get 2608 * Purpose: 2609 * Retrieves a list of the member ports of an existing VLAN. 2610 */ 2611 STATIC int 2612 _bcm_vlan_port_get(int unit, bcm_vlan_t vid, pbmp_t *pbmp, pbmp_t *ubmp, 2613 pbmp_t *ing_pbmp) 2614 { 2615 int rv; 2616 2617 BCM_LOCK(unit); 2618 rv = mbcm_driver[unit]->mbcm_vlan_port_get 2619 (unit, vid, pbmp, ubmp, ing_pbmp); 2620 2621 LOG_VERBOSE(BSL_LS_BCM_VLAN, 2622 (BSL_META_U(unit, 2623 "VLAN %d: bcm_vlan_port_get: vid %d. pbm 0x%x upbm 0x%x.\n"), 2624 unit, vid, SOC_PBMP_WORD_GET(*ing_pbmp, 0), 2625 SOC_PBMP_WORD_GET(*ubmp, 0))); 2626 2627 BCM_UNLOCK(unit); 2628 2629 return rv; 2630 } 2631 2632 /* 2633 * Function: 2634 * bcm_vlan_port_get 2635 * Purpose: 2636 * Retrieves a list of the member ports of an existing VLAN. 2637 * Parameters: 2638 * unit - StrataSwitch PCI device unit number (driver internal). 2639 * vid - VLAN ID to lookup. 2640 * tag_pbmp - (output) member port bitmap (ignored if NULL) 2641 * untag_pbmp - (output) untagged port bitmap (ignored if NULL) 2642 * Returns: 2643 * BCM_E_NONE - Success (port bitmaps filled in). 2644 * BCM_E_INTERNAL - Chip access failure. 2645 * BCM_E_NOT_FOUND - No such VLAN defined. 2646 */ 2647 2648 int 2649 bcm_esw_vlan_port_get(int unit, bcm_vlan_t vid, pbmp_t *pbmp, pbmp_t *ubmp) 2650 { 2651 pbmp_t ing_pbmp; 2652 2653 CHECK_INIT(unit); 2654 VLAN_CHK_ID(unit, vid); 2655 2656 if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) { 2657 return BCM_E_NOT_FOUND; 2658 } 2659 2660 BCM_IF_ERROR_RETURN 2661 (_bcm_vlan_port_get(unit, vid, pbmp, ubmp, &ing_pbmp)); 2662 2663 SOC_PBMP_OR(*pbmp, ing_pbmp); 2664 2665 return BCM_E_NONE; 2666 2667 } 2668 2669 /* 2670 * Function: 2671 * _bcm_vlan_list 2672 * Purpose: 2673 * Main body of bcm_vlan_list() and bcm_vlan_list_by_pbmp(). 2674 * Assumes locking already done. 2675 * Parameters: 2676 * list_all - if TRUE, lists all ports and ignores list_pbmp. 2677 * list_pbmp - if list_all is FALSE, lists only VLANs containing 2678 * any of the ports in list_pbmp. 2679 */ 2680 2681 STATIC int 2682 _bcm_vlan_list(int unit, bcm_vlan_data_t **listp, int *countp, 2683 int list_all, pbmp_t list_pbmp) 2684 { 2685 bcm_vlan_data_t *list; 2686 int count, i, rv; 2687 int idx; 2688 int valid_count; 2689 pbmp_t pbmp, ubmp, tbmp; 2690 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT) 2691 bcm_vlan_t olp_vlan = BCM_VLAN_INVALID; 2692 #endif 2693 2694 *countp = 0; 2695 *listp = NULL; 2696 2697 if (!list_all && SOC_PBMP_IS_NULL(list_pbmp)) { /* Empty list */ 2698 return BCM_E_NONE; 2699 } 2700 2701 count = vlan_info[unit].count; 2702 2703 if (count == 0) { 2704 return BCM_E_NONE; /* Empty list */ 2705 } 2706 2707 if ((list = sal_alloc(count * sizeof (list[0]), "vlan_list")) == NULL) { 2708 return BCM_E_MEMORY; 2709 } 2710 2711 i = 0; 2712 valid_count = 0; 2713 2714 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT) 2715 if (soc_feature(unit, soc_feature_xflow_macsec_olp)) { 2716 olp_vlan = soc_property_get(unit, spn_XFLOW_MACSEC_OLP_VLAN, BCM_VLAN_INVALID); 2717 } 2718 #endif 2719 2720 for (idx = BCM_VLAN_MIN; idx < BCM_VLAN_COUNT; idx++) { 2721 if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, idx)) { 2722 continue; 2723 } 2724 2725 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT) 2726 if (olp_vlan == idx) { 2727 count -= 1; 2728 continue; 2729 } 2730 #endif 2731 rv = bcm_esw_vlan_port_get(unit, idx, &pbmp, &ubmp); 2732 if (BCM_FAILURE(rv)) { 2733 sal_free(list); 2734 return rv; 2735 } 2736 valid_count++; 2737 2738 SOC_PBMP_ASSIGN(tbmp, list_pbmp); 2739 SOC_PBMP_AND(tbmp, pbmp); 2740 if (list_all || SOC_PBMP_NOT_NULL(tbmp)) { 2741 list[i].vlan_tag = idx; 2742 BCM_PBMP_ASSIGN(list[i].port_bitmap, pbmp); 2743 BCM_PBMP_ASSIGN(list[i].ut_port_bitmap, ubmp); 2744 i++; 2745 2746 } 2747 if (valid_count == count) { 2748 break; 2749 } 2750 } 2751 assert(!list_all || i == count); /* If list_all, make sure all listed */ 2752 2753 *countp = i; 2754 *listp = list; 2755 return BCM_E_NONE; 2756 } 2757 2758 /* 2759 * Function: 2760 * bcm_vlan_list 2761 * Purpose: 2762 * Returns an array of all defined VLANs and their port bitmaps. 2763 * Parameters: 2764 * unit - StrataSwitch PCI device unit number 2765 * listp - Place where pointer to return array will be stored, 2766 * which will be NULL if there are zero VLANs defined. 2767 * countp - Place where number of entries in array will be stored, 2768 * which will be 0 if there are zero VLANs defined. 2769 * Returns: 2770 * BCM_E_NONE - Success. 2771 * BCM_E_INTERNAL - Chip access failure. 2772 * BCM_E_MEMORY - Out of system memory. 2773 * Notes: 2774 * The caller is responsible for freeing the memory that is 2775 * returned, using bcm_vlan_list_destroy. 2776 */ 2777 2778 int 2779 bcm_esw_vlan_list(int unit, bcm_vlan_data_t **listp, int *countp) 2780 { 2781 int rv; 2782 pbmp_t empty_pbm; 2783 2784 CHECK_INIT(unit); 2785 2786 SOC_PBMP_CLEAR(empty_pbm); 2787 BCM_LOCK(unit); 2788 rv = _bcm_vlan_list(unit, listp, countp, TRUE, empty_pbm); 2789 BCM_UNLOCK(unit); 2790 2791 return rv; 2792 } 2793 2794 /* 2795 * Function: 2796 * bcm_esw_vlan_list_by_pbmp 2797 * Purpose: 2798 * Returns an array of defined VLANs and port bitmaps. 2799 * Only VLANs that containing any of the specified ports are listed. 2800 * Parameters: 2801 * unit - StrataSwitch PCI device unit number 2802 * pbmp - Bitmap of ports 2803 * listp - Place where pointer to return array will be stored, 2804 * which will be NULL if there are zero VLANs defined. 2805 * countp - Place where number of entries in array will be stored, 2806 * which will be 0 if there are zero VLANs defined. 2807 * Returns: 2808 * BCM_E_NONE Success. 2809 * BCM_E_INTERNAL Chip access failure. 2810 * BCM_E_MEMORY Out of system memory. 2811 * Notes: 2812 * The caller is responsible for freeing the memory that is 2813 * returned, using bcm_vlan_list_destroy. 2814 */ 2815 2816 int 2817 bcm_esw_vlan_list_by_pbmp(int unit, pbmp_t pbmp, 2818 bcm_vlan_data_t **listp, int *countp) 2819 { 2820 int rv; 2821 2822 CHECK_INIT(unit); 2823 2824 BCM_LOCK(unit); 2825 rv = _bcm_vlan_list(unit, listp, countp, FALSE, pbmp); 2826 BCM_UNLOCK(unit); 2827 2828 return rv; 2829 } 2830 2831 /* 2832 * Function: 2833 * bcm_vlan_list_destroy 2834 * Purpose: 2835 * Destroy a list returned by bcm_vlan_list. 2836 * Also works for the zero-VLAN case (NULL list). 2837 * Parameters: 2838 * unit - StrataSwitch PCI device unit number 2839 * list - List returned by bcm_vlan_list 2840 * count - Count returned by bcm_vlan_list 2841 * Returns: 2842 * BCM_E_NONE Success. 2843 * Notes: 2844 * None. 2845 */ 2846 2847 int 2848 bcm_esw_vlan_list_destroy(int unit, bcm_vlan_data_t *list, int count) 2849 { 2850 COMPILER_REFERENCE(unit); 2851 COMPILER_REFERENCE(count); 2852 2853 if (list != NULL) { 2854 sal_free(list); 2855 } 2856 2857 return BCM_E_NONE; 2858 } 2859 2860 /* 2861 * Function: 2862 * bcm_vlan_default_get 2863 * Purpose: 2864 * Get the default VLAN ID 2865 * Parameters: 2866 * unit - StrataSwitch PCI device unit number (driver internal). 2867 * vid_ptr - (OUT) Target to receive the VLAN ID. 2868 * Returns: 2869 * BCM_E_NONE - Success. 2870 */ 2871 int 2872 bcm_esw_vlan_default_get(int unit, bcm_vlan_t *vid_ptr) 2873 { 2874 *vid_ptr = vlan_info[unit].defl; 2875 2876 return BCM_E_NONE; 2877 } 2878 2879 /* 2880 * Function: 2881 * _bcm_vlan_default_set 2882 * Purpose: 2883 * Main part of bcm_vlan_default_set; assumes locking already done. 2884 */ 2885 2886 STATIC int 2887 _bcm_vlan_default_set(int unit, bcm_vlan_t vid) 2888 { 2889 if (!BCM_VLAN_VALID(vid)) { 2890 return BCM_E_PARAM; 2891 } 2892 2893 if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) { 2894 return BCM_E_NOT_FOUND; 2895 } 2896 2897 vlan_info[unit].defl = vid; 2898 return BCM_E_NONE; 2899 } 2900 2901 /* 2902 * Function: 2903 * bcm_vlan_default_set 2904 * Purpose: 2905 * Set the default VLAN ID 2906 * Parameters: 2907 * unit - StrataSwitch PCI device unit number (driver internal). 2908 * vid - The new default VLAN 2909 * Returns: 2910 * BCM_E_NONE - Success. 2911 * Notes: 2912 * The new default VLAN must already exist. 2913 */ 2914 2915 int 2916 bcm_esw_vlan_default_set(int unit, bcm_vlan_t vid) 2917 { 2918 int rv; 2919 2920 LOG_VERBOSE(BSL_LS_BCM_VLAN, 2921 (BSL_META_U(unit, 2922 "VLAN %d: dflt vid set: %d\n"), 2923 unit, vid)); 2924 2925 CHECK_INIT(unit); 2926 2927 BCM_LOCK(unit); 2928 rv = _bcm_vlan_default_set(unit, vid); 2929 2930 #ifdef BCM_WARM_BOOT_SUPPORT 2931 SOC_CONTROL_LOCK(unit); 2932 SOC_CONTROL(unit)->scache_dirty = 1; 2933 SOC_CONTROL_UNLOCK(unit); 2934 #endif 2935 2936 BCM_UNLOCK(unit); 2937 2938 return rv; 2939 } 2940 2941 /* 2942 * Function: 2943 * bcm_vlan_stg_get 2944 * Purpose: 2945 * Retrieve the VTABLE STG for the specified vlan 2946 * Parameters: 2947 * unit - StrataSwitch PCI device unit number. 2948 * vid - VLAN ID. 2949 * stg_ptr - (OUT) Pointer to store stgid for return. 2950 * Returns: 2951 * BCM_E_XXX 2952 */ 2953 2954 int 2955 bcm_esw_vlan_stg_get(int unit, bcm_vlan_t vid, bcm_stg_t *stg_ptr) 2956 { 2957 int rv; 2958 2959 CHECK_INIT(unit); 2960 2961 BCM_LOCK(unit); 2962 rv = mbcm_driver[unit]->mbcm_vlan_stg_get(unit, vid, stg_ptr); 2963 BCM_UNLOCK(unit); 2964 2965 return rv; 2966 } 2967 2968 /* 2969 * Function: 2970 * bcm_vlan_stg_set 2971 * Purpose: 2972 * Update the VTABLE STG for the specified vlan 2973 * Parameters: 2974 * unit - StrataSwitch PCI device unit number 2975 * vid - VLAN ID 2976 * stg - New spanning tree group number for VLAN 2977 * Returns: 2978 * BCM_E_XXX 2979 */ 2980 2981 int 2982 bcm_esw_vlan_stg_set(int unit, bcm_vlan_t vid, bcm_stg_t stg) 2983 { 2984 int rv; 2985 2986 CHECK_INIT(unit); 2987 2988 BCM_LOCK(unit); 2989 rv = bcm_esw_stg_vlan_add(unit, stg, vid); 2990 BCM_UNLOCK(unit); 2991 2992 return rv; 2993 } 2994 2995 /* 2996 * Function: 2997 * _bcm_vlan_stp_set 2998 * Purpose: 2999 * Main part of bcm_vlan_stp_set; assumes locking already done. 3000 */ 3001 3002 STATIC int 3003 _bcm_vlan_stp_set(int unit, bcm_vlan_t vid, bcm_port_t port, int stp_state) 3004 { 3005 bcm_stg_t stgid; 3006 3007 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stg_get(unit, vid, &stgid)); 3008 BCM_IF_ERROR_RETURN(bcm_esw_stg_stp_set(unit, stgid, port, stp_state)); 3009 3010 return BCM_E_NONE; 3011 } 3012 3013 /* 3014 * Function: 3015 * bcm_vlan_stp_set 3016 * Purpose: 3017 * Set the spanning tree state for a port in the whole spanning 3018 * tree group that contains the specified VLAN. 3019 * Parameters: 3020 * unit - StrataSwitch PCI device unit number 3021 * vid - VLAN ID 3022 * port - Port 3023 * stp_state - State to set 3024 * Returns: 3025 * BCM_E_XXX 3026 */ 3027 3028 int 3029 bcm_esw_vlan_stp_set(int unit, bcm_vlan_t vid, 3030 bcm_port_t port, int stp_state) 3031 { 3032 int rv; 3033 3034 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 3035 int vp = -1; 3036 /* Extender */ 3037 if (soc_feature(unit, soc_feature_port_extension) && 3038 BCM_GPORT_IS_EXTENDER_PORT(port)) { 3039 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port); 3040 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) { 3041 return BCM_E_NOT_FOUND; 3042 } 3043 } 3044 3045 if (vp != -1) { 3046 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership) && 3047 soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 3048 return bcm_td2_vp_vlan_stp_set(unit, vp, vid, stp_state); 3049 } 3050 return BCM_E_UNAVAIL; 3051 } 3052 #endif 3053 3054 BCM_LOCK(unit); 3055 rv = _bcm_vlan_stp_set(unit, vid, port, stp_state); 3056 BCM_UNLOCK(unit); 3057 3058 return rv; 3059 } 3060 3061 /* 3062 * Function: 3063 * _bcm_vlan_stp_get 3064 * Purpose: 3065 * Main part of bcm_vlan_stp_get; assumes locking already done. 3066 */ 3067 3068 STATIC int 3069 _bcm_vlan_stp_get(int unit, bcm_vlan_t vid, 3070 bcm_port_t port, int *stp_state) 3071 { 3072 bcm_stg_t stgid; 3073 3074 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stg_get(unit, vid, &stgid)); 3075 BCM_IF_ERROR_RETURN(bcm_esw_stg_stp_get(unit, stgid, port, stp_state)); 3076 3077 return BCM_E_NONE; 3078 } 3079 3080 /* 3081 * Function: 3082 * bcm_vlan_stp_get 3083 * Purpose: 3084 * Get the spanning tree state for a port in the whole spanning 3085 * tree group that contains the specified VLAN. 3086 * Parameters: 3087 * unit - StrataSwitch PCI device unit number. 3088 * vid - VLAN ID. 3089 * port - Port 3090 * stp_state - (OUT) State to return. 3091 * Returns: 3092 * BCM_E_XXX 3093 */ 3094 3095 int 3096 bcm_esw_vlan_stp_get(int unit, bcm_vlan_t vid, 3097 bcm_port_t port, int *stp_state) 3098 { 3099 int rv; 3100 3101 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 3102 int vp = -1; 3103 /* Extender */ 3104 if (soc_feature(unit, soc_feature_port_extension) && 3105 BCM_GPORT_IS_EXTENDER_PORT(port)) { 3106 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port); 3107 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) { 3108 return BCM_E_NOT_FOUND; 3109 } 3110 } 3111 3112 if (vp != -1) { 3113 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership) && 3114 soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 3115 return bcm_td2_vp_vlan_stp_get(unit, vp, vid, stp_state); 3116 } 3117 return BCM_E_UNAVAIL; 3118 } 3119 #endif 3120 3121 BCM_LOCK(unit); 3122 rv = _bcm_vlan_stp_get(unit, vid, port, stp_state); 3123 BCM_UNLOCK(unit); 3124 3125 return rv; 3126 } 3127 3128 /* 3129 * Function: 3130 * bcm_esw_vlan_policer_get 3131 * Purpose: 3132 * Retrieve the Policer ID accociated for the specified physical port. 3133 * Parameters: 3134 * Unit - (IN) unit number 3135 * vlan - (IN) VLAN 3136 * policer - (OUT) policer Id 3137 * Returns: 3138 * BCM_E_XXX 3139 */ 3140 int bcm_esw_vlan_policer_get( 3141 int unit, 3142 bcm_vlan_t vlan, 3143 bcm_policer_t *policer) 3144 { 3145 int rv = BCM_E_NONE; 3146 vlan_tab_entry_t vt; 3147 3148 #ifdef BCM_TOMAHAWK3_SUPPORT 3149 if (SOC_IS_TOMAHAWK3(unit)) { 3150 return BCM_E_UNAVAIL; 3151 } 3152 #endif 3153 3154 VLAN_CHK_ID(unit, vlan); 3155 BCM_IF_ERROR_RETURN(_check_global_meter_init(unit)); 3156 *policer = 0; 3157 rv = _bcm_esw_get_policer_from_table(unit, VLAN_TABm, vlan, &vt, 3158 policer, 0); 3159 if (BCM_FAILURE(rv)) { 3160 LOG_ERROR(BSL_LS_BCM_VLAN, 3161 (BSL_META_U(unit, 3162 "Unable to read vlan table entry\n"))); 3163 return (rv); 3164 } 3165 return rv; 3166 3167 } 3168 3169 /* 3170 * Function: 3171 * bcm_esw_vlan_policer_set 3172 * Purpose: 3173 * Set the Policer ID accociated for the specified physical port. 3174 * Parameters: 3175 * Unit - (IN) unit number 3176 * vlan - (IN) VLAN 3177 * policer - (IN) policer Id 3178 * Returns: 3179 * BCM_E_XXX 3180 */ 3181 int bcm_esw_vlan_policer_set( 3182 int unit, 3183 bcm_vlan_t vlan, 3184 bcm_policer_t policer) 3185 { 3186 int rv = BCM_E_NONE; 3187 vlan_tab_entry_t vt; 3188 3189 #ifdef BCM_TOMAHAWK3_SUPPORT 3190 if (SOC_IS_TOMAHAWK3(unit)) { 3191 return BCM_E_UNAVAIL; 3192 } 3193 #endif 3194 3195 VLAN_CHK_ID(unit, vlan); 3196 if (!soc_feature(unit, soc_feature_global_meter)) { 3197 return BCM_E_UNAVAIL; 3198 } 3199 BCM_IF_ERROR_RETURN(_check_global_meter_init(unit)); 3200 rv = _bcm_esw_policer_validate(unit, &policer); 3201 if (BCM_FAILURE(rv)) { 3202 LOG_VERBOSE(BSL_LS_BCM_VLAN, 3203 (BSL_META_U(unit, 3204 "Invalid policer id passed: %x \n"), 3205 policer)); 3206 return (rv); 3207 } 3208 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_APACHE_SUPPORT) 3209 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_APACHE(unit)) { 3210 int offset_mode = 0; 3211 offset_mode = (((policer) & BCM_POLICER_GLOBAL_METER_MODE_MASK) >> 3212 BCM_POLICER_GLOBAL_METER_MODE_SHIFT); 3213 3214 if ((offset_mode == 0) && (policer != 0)) { 3215 /* 3216 * Not a Global meter policer, 3217 * policer zero is used to detach already configured policer 3218 */ 3219 return (BCM_E_PARAM); 3220 } 3221 } 3222 #endif 3223 soc_mem_lock(unit, VLAN_TABm); 3224 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vlan, &vt); 3225 if (BCM_FAILURE(rv)) { 3226 LOG_ERROR(BSL_LS_BCM_VLAN, 3227 (BSL_META_U(unit, 3228 "Unable to read vlan table entry\n"))); 3229 soc_mem_unlock(unit, VLAN_TABm); 3230 return (rv); 3231 } 3232 3233 rv = _bcm_esw_add_policer_to_table(unit, policer, 3234 VLAN_TABm, vlan, (void *)(&vt)); 3235 if (BCM_FAILURE(rv)) { 3236 LOG_ERROR(BSL_LS_BCM_VLAN, 3237 (BSL_META_U(unit, 3238 "Unable to add policer to vlan table entry\n"))); 3239 soc_mem_unlock(unit, VLAN_TABm); 3240 return (rv); 3241 } 3242 rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ANY, vlan, &vt); 3243 if (BCM_FAILURE(rv)) { 3244 LOG_ERROR(BSL_LS_BCM_VLAN, 3245 (BSL_META_U(unit, 3246 "Unable to add policer to vlan table entry\n"))); 3247 soc_mem_unlock(unit, VLAN_TABm); 3248 return (rv); 3249 } 3250 soc_mem_unlock(unit, VLAN_TABm); 3251 return rv; 3252 } 3253 /* 3254 * Port-based VLAN actions 3255 */ 3256 /* 3257 * Function: 3258 * bcm_vlan_port_default_action_set 3259 * Purpose: 3260 * Set the port's default vlan tag actions 3261 * Parameters: 3262 * unit - (IN) BCM unit. 3263 * port - (IN) Port number. 3264 * action - (IN) Vlan tag actions 3265 * Returns: 3266 * BCM_E_XXX 3267 */ 3268 int 3269 bcm_esw_vlan_port_default_action_set(int unit, bcm_port_t port, 3270 bcm_vlan_action_set_t *action) 3271 { 3272 int rv = BCM_E_UNAVAIL; 3273 3274 #ifdef BCM_TOMAHAWK3_SUPPORT 3275 if (SOC_IS_TOMAHAWK3(unit)) { 3276 rv = bcm_tomahawk3_vlan_port_default_action_set(unit, port, action); 3277 } else 3278 #endif 3279 #ifdef BCM_TRX_SUPPORT 3280 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 3281 bcm_port_t local_port; 3282 3283 #ifdef BCM_HGPROXY_COE_SUPPORT 3284 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 3285 BCM_GPORT_IS_SET(port) && 3286 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 3287 local_port = port; 3288 } else 3289 #endif 3290 { 3291 BCM_IF_ERROR_RETURN( 3292 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3293 } 3294 3295 PORT_LOCK(unit); 3296 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 3297 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 3298 rv = _bcm_trx_vlan_port_default_action_profile_set(unit, 3299 local_port, action); 3300 } else 3301 #endif 3302 { 3303 rv = _bcm_trx_vlan_port_default_action_set(unit, 3304 local_port, action); 3305 } 3306 PORT_UNLOCK(unit); 3307 } 3308 #endif /* BCM_TRX_SUPPORT */ 3309 3310 return rv; 3311 } 3312 3313 /* 3314 * Function: 3315 * bcm_vlan_port_default_action_get 3316 * Purpose: 3317 * Get the port's default vlan tag actions 3318 * Parameters: 3319 * unit - (IN) BCM unit. 3320 * port - (IN) Port number. 3321 * action - (OUT) Vlan tag actions 3322 * Returns: 3323 * BCM_E_XXX 3324 */ 3325 int 3326 bcm_esw_vlan_port_default_action_get(int unit, bcm_port_t port, 3327 bcm_vlan_action_set_t *action) 3328 { 3329 int rv = BCM_E_UNAVAIL; 3330 3331 #ifdef BCM_TOMAHAWK3_SUPPORT 3332 if (SOC_IS_TOMAHAWK3(unit)) { 3333 rv = bcm_tomahawk3_vlan_port_default_action_get(unit, port, action); 3334 } else 3335 #endif 3336 #ifdef BCM_TRX_SUPPORT 3337 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 3338 bcm_port_t local_port; 3339 3340 #ifdef BCM_HGPROXY_COE_SUPPORT 3341 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 3342 BCM_GPORT_IS_SET(port) && 3343 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 3344 local_port = port; 3345 } else 3346 #endif 3347 { 3348 BCM_IF_ERROR_RETURN( 3349 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3350 } 3351 3352 bcm_vlan_action_set_t_init(action); 3353 PORT_LOCK(unit); 3354 rv = _bcm_trx_vlan_port_default_action_get(unit, local_port, action); 3355 PORT_UNLOCK(unit); 3356 } 3357 #endif /* BCM_TRIUMPH_SUPPORT */ 3358 3359 return rv; 3360 } 3361 3362 3363 /* 3364 * Function: 3365 * bcm_vlan_port_default_action_delete 3366 * Purpose: 3367 * Delete the port's default vlan tag actions 3368 * Parameters: 3369 * unit - (IN) BCM unit. 3370 * port - (IN) Port number. 3371 * Returns: 3372 * BCM_E_XXX 3373 */ 3374 int 3375 bcm_esw_vlan_port_default_action_delete(int unit, bcm_port_t port) 3376 { 3377 int rv = BCM_E_UNAVAIL; 3378 3379 #ifdef BCM_TOMAHAWK3_SUPPORT 3380 if (SOC_IS_TOMAHAWK3(unit)) { 3381 rv = bcm_tomahawk3_vlan_port_default_action_delete(unit, port); 3382 } else 3383 #endif 3384 #ifdef BCM_TRX_SUPPORT 3385 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 3386 bcm_port_t local_port; 3387 3388 BCM_IF_ERROR_RETURN( 3389 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3390 3391 PORT_LOCK(unit); 3392 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 3393 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 3394 /* Increase ref count of default profile */ 3395 BCM_IF_ERROR_RETURN 3396 (_bcm_port_vlan_protocol_data_entry_reference(unit, 0, 16)); 3397 rv = _bcm_trx_vlan_port_default_action_profile_delete(unit, local_port); 3398 } else 3399 #endif 3400 { 3401 rv = _bcm_trx_vlan_port_default_action_delete(unit, local_port); 3402 } 3403 PORT_UNLOCK(unit); 3404 } 3405 #endif /* BCM_TRX_SUPPORT */ 3406 3407 return rv; 3408 } 3409 3410 /* 3411 * Function: 3412 * bcm_vlan_port_egress_default_action_set 3413 * Purpose: 3414 * Set the egress port's default vlan tag actions 3415 * Parameters: 3416 * unit - (IN) BCM unit. 3417 * port - (IN) Port number. 3418 * action - (IN) Vlan tag actions 3419 * Returns: 3420 * BCM_E_XXX 3421 */ 3422 int 3423 bcm_esw_vlan_port_egress_default_action_set(int unit, 3424 bcm_port_t port, 3425 bcm_vlan_action_set_t *action) 3426 { 3427 int rv = BCM_E_UNAVAIL; 3428 3429 #ifdef BCM_TOMAHAWK3_SUPPORT 3430 if (SOC_IS_TOMAHAWK3(unit)) { 3431 rv = 3432 bcm_tomahawk3_vlan_port_egress_default_action_set(unit, port, action); 3433 } else 3434 #endif 3435 #ifdef BCM_TRX_SUPPORT 3436 if (SOC_IS_TRX(unit) && ((soc_feature(unit, soc_feature_vlan_action)) || 3437 (soc_feature(unit, soc_feature_fast_egr_vlan_action)) || 3438 (soc_feature(unit, soc_feature_egr_vlan_action)))) { 3439 bcm_port_t local_port; 3440 3441 BCM_IF_ERROR_RETURN( 3442 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3443 3444 rv = _bcm_trx_vlan_port_egress_default_action_set(unit, 3445 local_port, action); 3446 } 3447 #endif /* BCM_TRX_SUPPORT */ 3448 3449 return rv; 3450 } 3451 3452 /* 3453 * Function: 3454 * bcm_vlan_port_egress_default_action_get 3455 * Purpose: 3456 * Get the egress port's default vlan tag actions 3457 * Parameters: 3458 * unit - (IN) BCM unit. 3459 * port - (IN) Port number. 3460 * action - (OUT) Vlan tag actions 3461 * Returns: 3462 * BCM_E_XXX 3463 */ 3464 int 3465 bcm_esw_vlan_port_egress_default_action_get(int unit, 3466 bcm_port_t port, 3467 bcm_vlan_action_set_t *action) 3468 { 3469 int rv = BCM_E_UNAVAIL; 3470 3471 #ifdef BCM_TOMAHAWK3_SUPPORT 3472 if (SOC_IS_TOMAHAWK3(unit)) { 3473 rv = 3474 bcm_tomahawk3_vlan_port_egress_default_action_get(unit, port, action); 3475 } else 3476 #endif 3477 #ifdef BCM_TRX_SUPPORT 3478 if (SOC_IS_TRX(unit) && ((soc_feature(unit, soc_feature_vlan_action)) || 3479 (soc_feature(unit, soc_feature_fast_egr_vlan_action)) || 3480 (soc_feature(unit, soc_feature_egr_vlan_action)))) { 3481 bcm_port_t local_port; 3482 3483 BCM_IF_ERROR_RETURN( 3484 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3485 3486 bcm_vlan_action_set_t_init(action); 3487 rv = _bcm_trx_vlan_port_egress_default_action_get(unit, local_port, 3488 action); 3489 } 3490 #endif /* BCM_TRX_SUPPORT */ 3491 3492 return rv; 3493 } 3494 3495 /* 3496 * Function: 3497 * bcm_vlan_port_egress_default_action_delete 3498 * Purpose: 3499 * delete the egress port's default vlan tag actions 3500 * Parameters: 3501 * unit - (IN) BCM unit. 3502 * port - (IN) Port number. 3503 * Returns: 3504 * BCM_E_XXX 3505 */ 3506 int 3507 bcm_esw_vlan_port_egress_default_action_delete(int unit, bcm_port_t port) 3508 { 3509 int rv = BCM_E_UNAVAIL; 3510 3511 #ifdef BCM_TOMAHAWK3_SUPPORT 3512 if (SOC_IS_TOMAHAWK3(unit)) { 3513 rv = bcm_tomahawk3_vlan_port_egress_default_action_delete(unit, port); 3514 } else 3515 #endif 3516 #ifdef BCM_TRX_SUPPORT 3517 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 3518 bcm_port_t local_port; 3519 3520 BCM_IF_ERROR_RETURN( 3521 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3522 3523 rv = _bcm_trx_vlan_port_egress_default_action_delete(unit, local_port); 3524 3525 /* The port is using the default profile */ 3526 _bcm_trx_egr_vlan_action_profile_entry_increment 3527 (unit, BCM_TRX_EGR_VLAN_ACTION_PROFILE_DEFAULT); 3528 } 3529 #endif /* BCM_TRX_SUPPORT */ 3530 3531 return rv; 3532 } 3533 3534 /* 3535 * Protocol-based VLAN actions 3536 */ 3537 3538 /* 3539 * Function : 3540 * bcm_vlan_port_protocol_action_add 3541 * Description : 3542 * Add protocol based VLAN with specified action. 3543 * If the entry already exists, update the action. 3544 * Parameters : 3545 * unit (IN) BCM unit number 3546 * port (IN) Port number 3547 * frame (IN) Frame type 3548 * ether (IN) 16 bit ether type 3549 * action (IN) Action for outer tag and inner tag 3550 * Note: 3551 * Program VLAN_PROTOCOL_DATAm and VLAN_PROTOCOLm. 3552 */ 3553 int 3554 bcm_esw_vlan_port_protocol_action_add(int unit, 3555 bcm_port_t port, 3556 bcm_port_frametype_t frame, 3557 bcm_port_ethertype_t ether, 3558 bcm_vlan_action_set_t *action) 3559 { 3560 int rv = BCM_E_UNAVAIL; 3561 3562 #ifdef BCM_TOMAHAWK3_SUPPORT 3563 if (!SOC_IS_TOMAHAWK3(unit)) 3564 #endif 3565 #ifdef BCM_TRX_SUPPORT 3566 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 3567 bcm_port_t local_port; 3568 3569 BCM_IF_ERROR_RETURN( 3570 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3571 3572 if (IS_HG_PORT(unit, local_port)){ 3573 return SOC_E_PORT; 3574 } 3575 3576 PORT_LOCK(unit); 3577 rv = _bcm_trx_vlan_port_protocol_action_add(unit, local_port, frame, 3578 ether, action); 3579 PORT_UNLOCK(unit); 3580 } 3581 #endif /* BCM_TRX_SUPPORT */ 3582 return (rv); 3583 } 3584 /* 3585 * Function : 3586 * bcm_vlan_port_protocol_action_get 3587 * Description : 3588 * Get protocol based VLAN with specified action. 3589 * Parameters : 3590 * unit (IN) BCM unit number 3591 * port (IN) Port number 3592 * frame (IN) Frame type 3593 * ether (IN) 16 bit ether type 3594 * action (OUT) Action for outer and inner tag 3595 * Note: 3596 */ 3597 int 3598 bcm_esw_vlan_port_protocol_action_get(int unit, 3599 bcm_port_t port, 3600 bcm_port_frametype_t frame, 3601 bcm_port_ethertype_t ether, 3602 bcm_vlan_action_set_t *action) 3603 { 3604 int rv = BCM_E_UNAVAIL; 3605 #ifdef BCM_TOMAHAWK3_SUPPORT 3606 if (!SOC_IS_TOMAHAWK3(unit)) 3607 #endif 3608 #ifdef BCM_TRX_SUPPORT 3609 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 3610 bcm_port_t local_port; 3611 3612 BCM_IF_ERROR_RETURN( 3613 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3614 3615 bcm_vlan_action_set_t_init(action); 3616 PORT_LOCK(unit); 3617 rv = _bcm_trx_vlan_port_protocol_action_get(unit, local_port, frame, 3618 ether, action); 3619 PORT_UNLOCK(unit); 3620 return rv; 3621 } 3622 #endif /* BCM_TRX_SUPPORT */ 3623 3624 return (rv); 3625 } 3626 3627 3628 /* 3629 * Function : 3630 * bcm_vlan_port_protocol_action_delete 3631 * Description : 3632 * Delete protocol based VLAN action. 3633 * Parameters : 3634 * unit (IN) BCM unit number 3635 * port (IN) Port number 3636 * frame (IN) Frame type 3637 * ether (IN) 16 bit ether type 3638 * Note: 3639 * Program VLAN_PROTOCOL_DATAm and VLAN_PROTOCOLm. 3640 */ 3641 int 3642 bcm_esw_vlan_port_protocol_action_delete(int unit,bcm_port_t port, 3643 bcm_port_frametype_t frame, 3644 bcm_port_ethertype_t ether) 3645 { 3646 int rv = BCM_E_UNAVAIL; 3647 #ifdef BCM_TOMAHAWK3_SUPPORT 3648 if (!SOC_IS_TOMAHAWK3(unit)) 3649 #endif 3650 #ifdef BCM_TRX_SUPPORT 3651 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 3652 bcm_port_t local_port; 3653 3654 BCM_IF_ERROR_RETURN( 3655 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3656 3657 3658 PORT_LOCK(unit); 3659 rv = _bcm_trx_vlan_port_protocol_delete(unit, local_port, frame, ether); 3660 PORT_UNLOCK(unit); 3661 return rv; 3662 } 3663 #endif /* BCM_TRX_SUPPORT */ 3664 return (rv); 3665 } 3666 3667 3668 /* 3669 * Function : 3670 * bcm_vlan_port_protocol_action_delete_all 3671 * Description : 3672 * Delete all protocol based VLAN actiona. 3673 * Parameters : 3674 * unit (IN) BCM unit number 3675 * port (IN) Port number 3676 * Note: 3677 * Program VLAN_PROTOCOL_DATAm and VLAN_PROTOCOLm. 3678 */ 3679 int 3680 bcm_esw_vlan_port_protocol_action_delete_all(int unit,bcm_port_t port) 3681 { 3682 int rv = BCM_E_UNAVAIL; 3683 3684 #ifdef BCM_TOMAHAWK3_SUPPORT 3685 if (!SOC_IS_TOMAHAWK3(unit)) 3686 #endif 3687 #ifdef BCM_TRX_SUPPORT 3688 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 3689 bcm_port_t local_port; 3690 3691 BCM_IF_ERROR_RETURN( 3692 _bcm_esw_port_gport_validate(unit, port, &local_port)); 3693 3694 PORT_LOCK(unit); 3695 rv = _bcm_trx_vlan_port_protocol_delete_all(unit, local_port); 3696 PORT_UNLOCK(unit); 3697 } 3698 #endif /* BCM_TRX_SUPPORT */ 3699 return (rv); 3700 } 3701 3702 /* 3703 * Function : 3704 * bcm_esw_vlan_port_protocol_action_traverse 3705 * Description : 3706 * Traverse over vlan port protocol actions. 3707 * Parameters : 3708 * unit (IN) BCM unit number 3709 * cb (IN) User provided call back function 3710 * user_data (IN) User provided data 3711 * Note: 3712 * Program VLAN_PROTOCOL_DATAm and VLAN_PROTOCOLm. 3713 */ 3714 int 3715 bcm_esw_vlan_port_protocol_action_traverse(int unit, 3716 bcm_vlan_port_protocol_action_traverse_cb cb, 3717 void *user_data) 3718 { 3719 int rv = BCM_E_UNAVAIL; 3720 #ifdef BCM_TOMAHAWK3_SUPPORT 3721 if (!SOC_IS_TOMAHAWK3(unit)) 3722 #endif 3723 #ifdef BCM_TRX_SUPPORT 3724 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 3725 PORT_LOCK(unit); 3726 rv = _bcm_trx_vlan_port_protocol_action_traverse(unit, cb, user_data); 3727 PORT_UNLOCK(unit); 3728 } 3729 #endif /* BCM_TRX_SUPPORT */ 3730 return (rv); 3731 } 3732 3733 3734 /* 3735 * Mac based vlans 3736 */ 3737 int 3738 bcm_esw_vlan_mac_add(int unit, bcm_mac_t mac, bcm_vlan_t vid, int prio) 3739 { 3740 3741 VLAN_CHK_ID(unit, vid); 3742 if (prio < BCM_PRIO_MIN || prio > BCM_PRIO_MAX) { 3743 return BCM_E_PARAM; 3744 } 3745 3746 #ifdef BCM_TRX_SUPPORT 3747 if (SOC_IS_TRX(unit)) { 3748 bcm_vlan_action_set_t action; 3749 3750 if (!soc_feature(unit, soc_feature_vlan_action) 3751 || !soc_feature(unit, soc_feature_mac_based_vlan)) { 3752 return BCM_E_UNAVAIL; 3753 } 3754 prio &= ~BCM_PRIO_DROP_FIRST; 3755 3756 if ((prio & ~BCM_VLAN_XLATE_PRIO_MASK) != 0) { 3757 return BCM_E_PARAM; 3758 } 3759 3760 bcm_vlan_action_set_t_init(&action); 3761 action.new_outer_vlan = vid; 3762 action.new_inner_vlan = 0; 3763 action.priority = prio; 3764 action.dt_outer_prio = bcmVlanActionReplace; 3765 action.ot_outer_prio = bcmVlanActionReplace; 3766 action.it_outer = bcmVlanActionAdd; 3767 action.it_inner_prio = bcmVlanActionNone; 3768 action.ut_outer = bcmVlanActionAdd; 3769 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 3770 action.ut_outer_pkt_prio = bcmVlanActionAdd; 3771 } 3772 3773 #if defined(BCM_TRIDENT3_SUPPORT) 3774 if (SOC_IS_TRIDENT3X(unit)) { 3775 return _bcm_td3_vlan_mac_action_add(unit, mac, &action); 3776 } else 3777 #endif 3778 { 3779 return _bcm_trx_vlan_mac_action_add(unit, mac, &action); 3780 } 3781 } 3782 #endif /* BCM_TRX_SUPPORT */ 3783 #if defined(BCM_TRIUMPH3_SUPPORT) 3784 if (SOC_IS_TRIUMPH3(unit)) { 3785 vlan_xlate_entry_t vxent; 3786 prio &= ~BCM_PRIO_DROP_FIRST; 3787 3788 if ((prio & ~BCM_VLAN_XLATE_PRIO_MASK) != 0) { 3789 return BCM_E_PARAM; 3790 } 3791 3792 sal_memset(&vxent, 0, sizeof(vxent)); 3793 soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent), 3794 VLAN_MAC__MAC_ADDRf, mac); 3795 soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OVIDf, vid); 3796 soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OPRIf, prio); 3797 soc_VLAN_XLATEm_field32_set(unit, &vxent, VALIDf, 1); 3798 3799 return soc_mem_insert(unit, VLAN_XLATEm, MEM_BLOCK_ALL, &vxent); 3800 } else 3801 #endif /* BCM_TRIUMPH3_SUPPORT */ 3802 { 3803 #ifdef BCM_XGS3_SWITCH_SUPPORT 3804 if (SOC_IS_XGS3_SWITCH(unit)) { 3805 vlan_mac_entry_t vment; 3806 prio &= ~BCM_PRIO_DROP_FIRST; 3807 3808 if ((prio & ~BCM_VLAN_XLATE_PRIO_MASK) != 0) { 3809 return BCM_E_PARAM; 3810 } 3811 3812 sal_memset(&vment, 0, sizeof(vment)); 3813 soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac); 3814 soc_VLAN_MACm_field32_set(unit, &vment, VLAN_IDf, vid); 3815 soc_VLAN_MACm_field32_set(unit, &vment, PRIf, prio); 3816 soc_VLAN_MACm_field32_set(unit, &vment, VALIDf, 1); 3817 3818 return soc_mem_insert(unit, VLAN_MACm, MEM_BLOCK_ALL, &vment); 3819 } 3820 #endif 3821 } 3822 return BCM_E_UNAVAIL; 3823 } 3824 3825 int 3826 bcm_esw_vlan_mac_delete(int unit, bcm_mac_t mac) 3827 { 3828 #ifdef BCM_TRX_SUPPORT 3829 if (SOC_IS_TRX(unit)) { 3830 if (!soc_feature(unit, soc_feature_vlan_action) 3831 || !soc_feature(unit, soc_feature_mac_based_vlan)) { 3832 return BCM_E_UNAVAIL; 3833 } 3834 #if defined(BCM_TRIDENT3_SUPPORT) 3835 if (SOC_IS_TRIDENT3X(unit)) { 3836 return _bcm_td3_vlan_mac_delete(unit, mac); 3837 } else 3838 #endif 3839 { 3840 return _bcm_trx_vlan_mac_delete(unit, mac); 3841 } 3842 } 3843 #endif /* BCM_TRX_SUPPORT */ 3844 #if defined(BCM_TRIUMPH3_SUPPORT) 3845 if (SOC_IS_TRIUMPH3(unit)) { 3846 vlan_xlate_entry_t vxent; 3847 int rv; 3848 3849 sal_memset(&vxent, 0, sizeof(vxent)); 3850 soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent), 3851 VLAN_MAC__MAC_ADDRf, mac); 3852 rv = soc_mem_delete(unit, VLAN_XLATEm, MEM_BLOCK_ALL, &vxent); 3853 if (rv == SOC_E_NOT_FOUND) { 3854 rv = SOC_E_NONE; 3855 } 3856 return rv; 3857 } else 3858 #endif /* BCM_TRIUMPH3_SUPPORT */ 3859 { 3860 #ifdef BCM_XGS3_SWITCH_SUPPORT 3861 if (SOC_IS_XGS3_SWITCH(unit)) { 3862 vlan_mac_entry_t vment; 3863 int rv; 3864 3865 sal_memset(&vment, 0, sizeof(vment)); 3866 soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac); 3867 rv = soc_mem_delete(unit, VLAN_MACm, MEM_BLOCK_ALL, &vment); 3868 if (rv == SOC_E_NOT_FOUND) { 3869 rv = SOC_E_NONE; 3870 } 3871 return rv; 3872 } 3873 #endif 3874 } 3875 return BCM_E_UNAVAIL; 3876 } 3877 3878 3879 int 3880 bcm_esw_vlan_mac_delete_all(int unit) 3881 { 3882 #ifdef BCM_TRX_SUPPORT 3883 if (SOC_IS_TRX(unit)) { 3884 if (!soc_feature(unit, soc_feature_vlan_action) 3885 || !soc_feature(unit, soc_feature_mac_based_vlan)) { 3886 return BCM_E_UNAVAIL; 3887 } 3888 #if defined(BCM_TRIDENT3_SUPPORT) 3889 if (SOC_IS_TRIDENT3X(unit)) { 3890 return _bcm_td3_vlan_mac_delete_all(unit); 3891 } else 3892 #endif 3893 { 3894 return _bcm_trx_vlan_mac_delete_all(unit); 3895 } 3896 } 3897 #endif /* BCM_TRX_SUPPORT */ 3898 #if defined(BCM_TRIUMPH3_SUPPORT) 3899 if (SOC_IS_TRIUMPH3(unit)) { 3900 return soc_mem_clear(unit, VLAN_XLATEm, MEM_BLOCK_ALL, 0); 3901 } else 3902 #endif /* BCM_TRIUMPH3_SUPPORT */ 3903 { 3904 #ifdef BCM_XGS3_SWITCH_SUPPORT 3905 if (SOC_IS_XGS3_SWITCH(unit)) { 3906 return soc_mem_clear(unit, VLAN_MACm, MEM_BLOCK_ALL, 0); 3907 } 3908 #endif 3909 } 3910 return BCM_E_UNAVAIL; 3911 } 3912 3913 /* 3914 * Function: 3915 * bcm_esw_vlan_mac_action_add 3916 * Purpose: 3917 * Add an association from MAC address to VLAN actions, which are 3918 * used for VLAN tag/s assignment to untagged packets. 3919 * 3920 * Parameters: 3921 * unit - (IN) BCM device number. 3922 * mac - (IN) Mac address. 3923 * action (IN) Action for outer and inner tag 3924 * Returns: 3925 * BCM_E_XXX 3926 */ 3927 int 3928 bcm_esw_vlan_mac_action_add(int unit, bcm_mac_t mac, bcm_vlan_action_set_t *action) 3929 { 3930 #if defined(BCM_TRX_SUPPORT) 3931 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 3932 && soc_feature(unit, soc_feature_mac_based_vlan)) { 3933 #if defined(BCM_TRIDENT3_SUPPORT) 3934 if (SOC_IS_TRIDENT3X(unit)) { 3935 return _bcm_td3_vlan_mac_action_add(unit, mac, action); 3936 } else 3937 #endif 3938 { 3939 return _bcm_trx_vlan_mac_action_add(unit, mac, action); 3940 } 3941 } 3942 #endif /* BCM_TRX_SUPPORT */ 3943 return BCM_E_UNAVAIL; 3944 } 3945 3946 /* 3947 * Function: 3948 * bcm_esw_vlan_mac_action_get 3949 * Purpose: 3950 * Retrive an association from MAC address to VLAN actions, which 3951 * are used for VLAN tag assignment to untagged packets. 3952 * 3953 * Parameters: 3954 * unit - (IN) BCM device number. 3955 * mac - (IN) Mac address. 3956 * action (OUT) Action for outer and inner tag 3957 * Returns: 3958 * BCM_E_XXX 3959 */ 3960 int 3961 bcm_esw_vlan_mac_action_get(int unit, bcm_mac_t mac, bcm_vlan_action_set_t *action) 3962 { 3963 #if defined(BCM_TRX_SUPPORT) 3964 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 3965 && soc_feature(unit, soc_feature_mac_based_vlan)) { 3966 3967 bcm_vlan_action_set_t_init(action); 3968 #if defined(BCM_TRIDENT3_SUPPORT) 3969 if (SOC_IS_TRIDENT3X(unit)) { 3970 return _bcm_td3_vlan_mac_action_get(unit, mac, action); 3971 } else 3972 #endif 3973 { 3974 return _bcm_trx_vlan_mac_action_get(unit, mac, action); 3975 } 3976 } 3977 #endif /* BCM_TRX_SUPPORT */ 3978 return BCM_E_UNAVAIL; 3979 } 3980 3981 /* 3982 * Function: 3983 * bcm_esw_vlan_mac_action_delete 3984 * Purpose: 3985 * Remove an association from MAC address to VLAN actions, which 3986 * are used for VLAN tag assignment to untagged packets. 3987 * 3988 * Parameters: 3989 * unit - (IN) BCM device number. 3990 * mac - (IN) Mac address. 3991 * Returns: 3992 * BCM_E_XXX 3993 */ 3994 int 3995 bcm_esw_vlan_mac_action_delete(int unit, bcm_mac_t mac) 3996 { 3997 #ifdef BCM_TRX_SUPPORT 3998 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 3999 && soc_feature(unit, soc_feature_mac_based_vlan)) { 4000 #if defined(BCM_TRIDENT3_SUPPORT) 4001 if (SOC_IS_TRIDENT3X(unit)) { 4002 return _bcm_td3_vlan_mac_delete(unit, mac); 4003 } else 4004 #endif 4005 { 4006 return _bcm_trx_vlan_mac_delete(unit, mac); 4007 } 4008 } 4009 #endif /* BCM_TRX_SUPPORT */ 4010 return BCM_E_UNAVAIL; 4011 } 4012 4013 /* 4014 * Function: 4015 * bcm_esw_vlan_mac_action_delete_all 4016 * Purpose: 4017 * Remove all MAC addresses to VLAN actions associations. 4018 * Mac to VLAN actions are used for VLAN tag assignment to untagged packets. 4019 * 4020 * Parameters: 4021 * unit - (IN) BCM device number. 4022 * Returns: 4023 * BCM_E_XXX 4024 */ 4025 int 4026 bcm_esw_vlan_mac_action_delete_all(int unit) 4027 { 4028 #ifdef BCM_TRX_SUPPORT 4029 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 4030 && soc_feature(unit, soc_feature_mac_based_vlan)) { 4031 #if defined(BCM_TRIDENT3_SUPPORT) 4032 if (SOC_IS_TRIDENT3X(unit)) { 4033 return _bcm_td3_vlan_mac_delete_all(unit); 4034 } else 4035 #endif 4036 { 4037 return _bcm_trx_vlan_mac_delete_all(unit); 4038 } 4039 } 4040 #endif /* BCM_TRX_SUPPORT */ 4041 return BCM_E_UNAVAIL; 4042 } 4043 4044 /* 4045 * Function : 4046 * bcm_vlan_mac_action_traverse 4047 * Description : 4048 * Traverse over vlan mac actions, which are used for VLAN 4049 * tag/s assignment to untagged packets. 4050 * Parameters : 4051 * unit (IN) BCM unit number 4052 * cb (IN) Call back function 4053 * user_data (IN) User provided data to pass to a call back 4054 */ 4055 int 4056 bcm_esw_vlan_mac_action_traverse(int unit, 4057 bcm_vlan_mac_action_traverse_cb cb, 4058 void *user_data) 4059 { 4060 #ifdef BCM_TRX_SUPPORT 4061 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 4062 && soc_feature(unit, soc_feature_mac_based_vlan)) { 4063 #if defined(BCM_TRIDENT3_SUPPORT) 4064 if (SOC_IS_TRIDENT3X(unit)) { 4065 return _bcm_td3_vlan_mac_action_traverse(unit, cb, user_data); 4066 } else 4067 #endif 4068 { 4069 return _bcm_trx_vlan_mac_action_traverse(unit, cb, user_data); 4070 } 4071 } 4072 #endif /* BCM_TRX_SUPPORT */ 4073 return BCM_E_UNAVAIL; 4074 } 4075 4076 #ifdef BCM_FIREBOLT_SUPPORT 4077 #ifdef BCM_WARM_BOOT_SUPPORT 4078 STATIC int 4079 _bcm_fb_vlan_translate_reload(int unit, int xtable) 4080 { 4081 soc_mem_t mem; 4082 int addvid, index_min, index_max, index_count, i, rv; 4083 uint32 *vtcachep, vtcache; 4084 vlan_xlate_entry_t *vtentries, *vtent; 4085 uint32 ve_valid, ve_port, ve_vid, ve_add; 4086 4087 if (!soc_feature(unit, soc_feature_vlan_translation)) { 4088 return BCM_E_NONE; 4089 } 4090 4091 switch (xtable) { 4092 case BCM_VLAN_XLATE_ING: 4093 mem = VLAN_XLATEm; 4094 addvid = 0; 4095 break; 4096 case BCM_VLAN_XLATE_EGR: 4097 mem = EGR_VLAN_XLATEm; 4098 addvid = -1; 4099 break; 4100 case BCM_VLAN_XLATE_DTAG: 4101 mem = VLAN_XLATEm; 4102 addvid = 1; 4103 break; 4104 default: 4105 return BCM_E_INTERNAL; 4106 } 4107 4108 index_min = soc_mem_index_min(unit, mem); 4109 index_max = soc_mem_index_max(unit, mem); 4110 index_count = soc_mem_index_count(unit, mem); 4111 4112 soc_mem_lock(unit, mem); 4113 4114 /* get vt cache, allocate if necessary */ 4115 if (mem == EGR_VLAN_XLATEm) { 4116 vtcachep = vlan_info[unit].egr_trans; 4117 } else { 4118 vtcachep = vlan_info[unit].ing_trans; 4119 } 4120 if (vtcachep == NULL) { 4121 vtcachep = sal_alloc(sizeof(*vtcachep) * (index_max+1), 4122 "vlan trans cache"); 4123 if (vtcachep == NULL) { 4124 soc_mem_unlock(unit, mem); 4125 return BCM_E_MEMORY; 4126 } 4127 sal_memset(vtcachep, 0, sizeof(*vtcachep) * (index_max+1)); 4128 if (mem == EGR_VLAN_XLATEm) { 4129 vlan_info[unit].egr_trans = vtcachep; 4130 } else { 4131 vlan_info[unit].ing_trans = vtcachep; 4132 } 4133 } 4134 4135 vtentries = soc_cm_salloc(unit, index_count * sizeof(*vtentries), 4136 "vlan trans dma"); 4137 if (vtentries == NULL) { 4138 soc_mem_unlock(unit, mem); 4139 return BCM_E_MEMORY; 4140 } 4141 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, index_min, index_max, 4142 vtentries); 4143 if (rv < 0) { 4144 soc_cm_sfree(unit, vtentries); 4145 sal_free(vtcachep); 4146 if (mem == EGR_VLAN_XLATEm) { 4147 vlan_info[unit].egr_trans = NULL; 4148 } else { 4149 vlan_info[unit].ing_trans = NULL; 4150 } 4151 soc_mem_unlock(unit, mem); 4152 return rv; 4153 } 4154 for (i = 0; i < index_count; i++) { 4155 vtent = soc_mem_table_idx_to_pointer(unit, mem, vlan_xlate_entry_t *, 4156 vtentries, i); 4157 vtcache = 0; 4158 ve_valid = soc_mem_field32_get(unit, mem, vtent, VALIDf); 4159 if (ve_valid) { 4160 if (soc_mem_field_valid(unit, mem, KEY_TYPEf) && 4161 (soc_mem_field32_get(unit, mem, vtent, KEY_TYPEf) != 0)) { 4162 continue; 4163 } 4164 if (soc_mem_field_valid(unit, mem, ENTRY_TYPEf) && 4165 (soc_mem_field32_get(unit, mem, vtent, ENTRY_TYPEf) != 0)) { 4166 continue; 4167 } 4168 BCM_VTCACHE_VALID_SET(vtcache, 1); 4169 if (soc_mem_field_valid(unit, mem, DST_PORTf)) { 4170 ve_port = soc_mem_field32_get(unit, mem, vtent, DST_PORTf); 4171 } else if (soc_mem_field_valid(unit, mem, PORT_NUMf)) { 4172 ve_port = soc_mem_field32_get(unit, mem, vtent, PORT_NUMf); 4173 } else { 4174 ve_port = soc_mem_field32_get(unit, mem, vtent, PORTf); 4175 } 4176 BCM_VTCACHE_PORT_SET(vtcache, ve_port); 4177 ve_vid = soc_mem_field32_get(unit, mem, vtent, OLD_VLAN_IDf); 4178 BCM_VTCACHE_VID_SET(vtcache, ve_vid); 4179 if (addvid >= 0) { 4180 if (soc_mem_field_valid(unit, mem, ADD_VIDf)) { 4181 ve_add = soc_mem_field32_get(unit, mem, vtent, ADD_VIDf); 4182 BCM_VTCACHE_ADD_SET(vtcache, ve_add); 4183 } 4184 } 4185 } 4186 vtcachep[index_min + i] = vtcache; 4187 } 4188 soc_cm_sfree(unit, vtentries); 4189 soc_mem_unlock(unit, mem); 4190 return BCM_E_NONE; 4191 } 4192 #else 4193 #define _bcm_fb_vlan_translate_reload(unit, xtable) (BCM_E_NONE) 4194 #endif /* BCM_WARM_BOOT_SUPPORT */ 4195 #endif /* BCM_FIREBOLT_SUPPORT */ 4196 4197 /* 4198 * Function: 4199 * bcm_esw_vlan_translate_get 4200 * Purpose: 4201 * Get vlan translation 4202 * Parameters: 4203 * unit - StrataSwitch PCI device unit number (driver internal). 4204 * port - port numebr 4205 * old_vid - Old VLAN ID to has translation for 4206 * new_vid - New VLAN ID that packet will get 4207 * prio - Priority 4208 * Returns: 4209 * BCM_E_NONE - Translation found, new_vid nad prio will have the values. 4210 * BCM_E_NOT_FOUND - Translation does not exist 4211 * BCM_E_XXX - Other error 4212 * Notes: 4213 * None. 4214 */ 4215 4216 int 4217 bcm_esw_vlan_translate_get (int unit, bcm_port_t port, bcm_vlan_t old_vid, 4218 bcm_vlan_t *new_vid, int *prio) 4219 { 4220 4221 bcm_module_t modid; 4222 bcm_trunk_t tgid = -1; 4223 int id = -1; 4224 4225 #ifdef BCM_TOMAHAWK3_SUPPORT 4226 if (SOC_IS_TOMAHAWK3(unit)) { 4227 return BCM_E_UNAVAIL; 4228 } 4229 #endif 4230 4231 CHECK_INIT(unit); 4232 VLAN_CHK_ID(unit, old_vid); 4233 if (NULL == new_vid) { 4234 return BCM_E_PARAM; 4235 } 4236 if (NULL == prio) { 4237 return BCM_E_PARAM; 4238 } 4239 4240 #ifdef BCM_TRX_SUPPORT 4241 if (SOC_IS_TRX(unit)) { 4242 bcm_gport_t gport; 4243 bcm_vlan_action_set_t action; 4244 4245 if (!soc_feature(unit, soc_feature_vlan_action)) { 4246 return BCM_E_UNAVAIL; 4247 } 4248 if (BCM_GPORT_IS_SET(port)) { 4249 gport = port; 4250 } else { 4251 if (!SOC_PORT_VALID(unit, port)) { 4252 return BCM_E_PORT; 4253 } 4254 BCM_IF_ERROR_RETURN( 4255 bcm_esw_port_gport_get(unit, port, &gport)); 4256 } 4257 bcm_vlan_action_set_t_init(&action); 4258 4259 BCM_IF_ERROR_RETURN 4260 (_bcm_trx_vlan_translate_action_get(unit, gport, 4261 bcmVlanTranslateKeyPortOuter, 4262 old_vid, 0, &action)); 4263 4264 if (bcmVlanActionReplace == action.ot_outer){ 4265 *new_vid = action.new_outer_vlan; 4266 *prio = action.priority; 4267 return BCM_E_NONE; 4268 } 4269 4270 BCM_IF_ERROR_RETURN 4271 (_bcm_trx_vlan_translate_action_get(unit, gport, 4272 bcmVlanTranslateKeyPortInner, 4273 0, old_vid, &action)); 4274 if (bcmVlanActionAdd == action.it_outer) { 4275 *new_vid = action.new_inner_vlan; 4276 *prio = action.priority; 4277 return BCM_E_NONE; 4278 } 4279 4280 return BCM_E_NOT_FOUND; 4281 } 4282 #endif /* BCM_TRX_SUPPORT */ 4283 4284 if (BCM_GPORT_IS_SET(port)) { 4285 BCM_IF_ERROR_RETURN( 4286 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 4287 if (-1 != tgid || -1 != id) { 4288 return BCM_E_PORT; 4289 } 4290 } else { 4291 if (!SOC_PORT_VALID(unit, port)) { 4292 return BCM_E_PORT; 4293 } 4294 BCM_IF_ERROR_RETURN( 4295 bcm_esw_stk_my_modid_get(unit, &modid)); 4296 } 4297 4298 #ifdef BCM_FIREBOLT_SUPPORT 4299 if (SOC_IS_FBX(unit)) { 4300 return _bcm_fb_vlan_translate_get(unit, port, old_vid, new_vid, prio, 4301 BCM_VLAN_XLATE_ING); 4302 } 4303 #endif /* BCM_FIREBOLT_SUPPORT */ 4304 4305 return BCM_E_UNAVAIL; 4306 } 4307 4308 4309 4310 /* 4311 * Function: 4312 * bcm_esw_vlan_translate_add 4313 * Purpose: 4314 * Add vlan translation 4315 * Parameters: 4316 * unit - StrataSwitch PCI device unit number (driver internal). 4317 * port - port numebr 4318 * old_vid - Old VLAN ID to has translation for 4319 * new_vid - New VLAN ID that packet will get 4320 * prio - Priority 4321 * Returns: 4322 * BCM_E_NONE - Translation found, new_vid nad prio will have the values. 4323 * BCM_E_NOT_FOUND - Translation does not exist 4324 * BCM_E_XXX - Other error 4325 * Notes: 4326 * None. 4327 */ 4328 int 4329 bcm_esw_vlan_translate_add(int unit, int port, bcm_vlan_t old_vid, 4330 bcm_vlan_t new_vid, int prio) 4331 { 4332 bcm_module_t modid; 4333 bcm_trunk_t tgid = -1; 4334 int id = -1; 4335 4336 #ifdef BCM_TOMAHAWK3_SUPPORT 4337 if (SOC_IS_TOMAHAWK3(unit)) { 4338 return BCM_E_UNAVAIL; 4339 } 4340 #endif 4341 4342 CHECK_INIT(unit); 4343 VLAN_CHK_ID(unit, old_vid); 4344 VLAN_CHK_ID(unit, new_vid); 4345 4346 /* XGS does not support translation of VLAN ID 0 */ 4347 if (old_vid == 0) { 4348 return BCM_E_PARAM; 4349 } 4350 4351 if ((prio != -1) && ((prio & BCM_PRIO_MASK) > BCM_PRIO_MAX)) { 4352 return BCM_E_PARAM; 4353 } 4354 4355 #ifdef BCM_TRX_SUPPORT 4356 if (SOC_IS_TRX(unit)) { 4357 bcm_vlan_action_set_t action; 4358 bcm_gport_t gport; 4359 4360 if (!soc_feature(unit, soc_feature_vlan_action)) { 4361 return BCM_E_UNAVAIL; 4362 } 4363 if (BCM_GPORT_IS_SET(port)) { 4364 gport = port; 4365 } else { 4366 if (!SOC_PORT_VALID(unit, port)) { 4367 return BCM_E_PORT; 4368 } 4369 BCM_IF_ERROR_RETURN( 4370 bcm_esw_port_gport_get(unit, port, &gport)); 4371 } 4372 4373 /* add an entry for inner-tagged packets */ 4374 bcm_vlan_action_set_t_init(&action); 4375 action.new_outer_vlan = new_vid; 4376 action.priority = prio; 4377 action.it_outer = bcmVlanActionAdd; 4378 action.it_inner = bcmVlanActionDelete; 4379 action.it_inner_prio = bcmVlanActionNone; 4380 4381 BCM_IF_ERROR_RETURN 4382 (_bcm_trx_vlan_translate_action_add(unit, gport, 4383 bcmVlanTranslateKeyPortInner, 4384 0, old_vid, &action)); 4385 4386 /* add an entry for outer-tagged packets */ 4387 bcm_vlan_action_set_t_init(&action); 4388 action.new_outer_vlan = new_vid; 4389 action.priority = prio; 4390 action.ot_outer = bcmVlanActionReplace; 4391 action.ot_outer_prio = bcmVlanActionReplace; 4392 action.dt_outer = bcmVlanActionReplace; 4393 action.dt_outer_prio = bcmVlanActionReplace; 4394 4395 BCM_IF_ERROR_RETURN 4396 (_bcm_trx_vlan_translate_action_add(unit, gport, 4397 bcmVlanTranslateKeyPortOuter, 4398 old_vid, 0, &action)); 4399 return BCM_E_NONE; 4400 } 4401 #endif /* BCM_TRX_SUPPORT */ 4402 4403 if (BCM_GPORT_IS_SET(port)) { 4404 BCM_IF_ERROR_RETURN( 4405 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 4406 if (-1 != tgid || -1 != id) { 4407 return BCM_E_PORT; 4408 } 4409 } else { 4410 if (SOC_IS_RAVEN(unit)) { 4411 if (port != -1) { 4412 if (!SOC_PORT_VALID(unit, port)) { 4413 return BCM_E_PORT; 4414 } 4415 } 4416 } else { 4417 if (!SOC_PORT_VALID(unit, port)) { 4418 return BCM_E_PORT; 4419 } 4420 } 4421 BCM_IF_ERROR_RETURN( 4422 bcm_esw_stk_my_modid_get(unit, &modid)); 4423 } 4424 4425 #ifdef BCM_FIREBOLT_SUPPORT 4426 if (SOC_IS_FBX(unit)) { 4427 return _bcm_fb_vlan_translate_add(unit, port, old_vid, new_vid, prio, 4428 BCM_VLAN_XLATE_ING); 4429 } 4430 #endif 4431 4432 return BCM_E_UNAVAIL; 4433 } 4434 4435 /* 4436 * Function: 4437 * bcm_esw_vlan_translate_delete 4438 * Purpose: 4439 * Delete vlan translation 4440 * Parameters: 4441 * unit - StrataSwitch PCI device unit number (driver internal). 4442 * port - port numebr 4443 * old_vid - Old VLAN ID to delete translation for 4444 * Returns: 4445 * BCM_E_NONE - Translation found, new_vid nad prio will have the values. 4446 * BCM_E_NOT_FOUND - Translation does not exist 4447 * BCM_E_XXX - Other error 4448 * Notes: 4449 * None. 4450 */ 4451 4452 int 4453 bcm_esw_vlan_translate_delete(int unit, int port, bcm_vlan_t old_vid) 4454 { 4455 bcm_module_t modid; 4456 bcm_trunk_t tgid = -1; 4457 int id = -1; 4458 4459 #ifdef BCM_TOMAHAWK3_SUPPORT 4460 if (SOC_IS_TOMAHAWK3(unit)) { 4461 return BCM_E_UNAVAIL; 4462 } 4463 #endif 4464 4465 CHECK_INIT(unit); 4466 VLAN_CHK_ID(unit, old_vid); 4467 4468 /* XGS does not support translation of VLAN ID 0 */ 4469 if (old_vid == 0) { 4470 return BCM_E_PARAM; 4471 } 4472 4473 #ifdef BCM_TRX_SUPPORT 4474 if (SOC_IS_TRX(unit)) { 4475 bcm_gport_t gport; 4476 int rv1, rv2; 4477 4478 rv1 = rv2 = BCM_E_NONE; 4479 if (!soc_feature(unit, soc_feature_vlan_action)) { 4480 return BCM_E_UNAVAIL; 4481 } 4482 if (BCM_GPORT_IS_SET(port)) { 4483 gport = port; 4484 } else { 4485 if (!SOC_PORT_VALID(unit, port)) { 4486 return BCM_E_PORT; 4487 } 4488 BCM_IF_ERROR_RETURN( 4489 bcm_esw_port_gport_get(unit, port, &gport)); 4490 } 4491 rv1 = _bcm_trx_vlan_translate_action_delete(unit, gport, 4492 bcmVlanTranslateKeyPortInner, 4493 0, old_vid); 4494 if (BCM_SUCCESS(rv1) || (rv1 == BCM_E_NOT_FOUND)) { 4495 rv2 = _bcm_trx_vlan_translate_action_delete(unit, gport, 4496 bcmVlanTranslateKeyPortOuter, 4497 old_vid, 0); 4498 } else { 4499 return (rv1); 4500 } 4501 4502 if (BCM_SUCCESS(rv1) && (rv2 == BCM_E_NOT_FOUND)) { 4503 return (rv1); 4504 } 4505 return (rv2); 4506 } 4507 #endif /* BCM_TRX_SUPPORT */ 4508 4509 if (BCM_GPORT_IS_SET(port)) { 4510 BCM_IF_ERROR_RETURN( 4511 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 4512 if (-1 != tgid || -1 != id) { 4513 return BCM_E_PORT; 4514 } 4515 } else { 4516 if (SOC_IS_RAVEN(unit)) { 4517 if (port != -1) { 4518 if (!SOC_PORT_VALID(unit, port)) { 4519 return BCM_E_PORT; 4520 } 4521 } 4522 } else { 4523 if (!SOC_PORT_VALID(unit, port)) { 4524 return BCM_E_PORT; 4525 } 4526 } 4527 BCM_IF_ERROR_RETURN( 4528 bcm_esw_stk_my_modid_get(unit, &modid)); 4529 } 4530 4531 #ifdef BCM_FIREBOLT_SUPPORT 4532 if (SOC_IS_FBX(unit)) { 4533 return _bcm_fb_vlan_translate_delete(unit, port, old_vid, 4534 BCM_VLAN_XLATE_ING); 4535 } 4536 #endif 4537 4538 return BCM_E_UNAVAIL; 4539 } 4540 4541 4542 int 4543 bcm_esw_vlan_translate_delete_all(int unit) 4544 { 4545 #ifdef BCM_TOMAHAWK3_SUPPORT 4546 if (SOC_IS_TOMAHAWK3(unit)) { 4547 return BCM_E_UNAVAIL; 4548 } 4549 #endif 4550 4551 CHECK_INIT(unit); 4552 4553 #ifdef BCM_TRX_SUPPORT 4554 if (SOC_IS_TRX(unit)) { 4555 if (!soc_feature(unit, soc_feature_vlan_action)) { 4556 return BCM_E_UNAVAIL; 4557 } 4558 return _bcm_trx_vlan_translate_action_delete_all(unit); 4559 } 4560 #endif /* BCM_TRX_SUPPORT */ 4561 4562 #ifdef BCM_FIREBOLT_SUPPORT 4563 if (SOC_IS_FBX(unit)) { 4564 int rv; 4565 4566 rv = _bcm_fb_vlan_translate_delete(unit, -1, BCM_VLAN_NONE, 4567 BCM_VLAN_XLATE_ING); 4568 if (BCM_SUCCESS(rv) || (rv == BCM_E_NOT_FOUND)) { 4569 return BCM_E_NONE; 4570 } 4571 4572 return rv; 4573 } 4574 #endif 4575 4576 return BCM_E_UNAVAIL; 4577 } 4578 4579 /* 4580 * Function : 4581 * bcm_vlan_translate_action_add 4582 * Description : 4583 * Add an entry to ingress VLAN translation table. 4584 * Parameters : 4585 * unit (IN) BCM unit number 4586 * port (IN) Generic port 4587 * key_type (IN) Key Type : bcmVlanTranslateKey* 4588 * outer_vlan (IN) Packet outer VLAN ID 4589 * inner_vlan (IN) Packet inner VLAN ID 4590 * action (IN) Action for outer and inner tag 4591 */ 4592 int 4593 bcm_esw_vlan_translate_action_add(int unit, 4594 bcm_gport_t port, 4595 bcm_vlan_translate_key_t key_type, 4596 bcm_vlan_t outer_vlan, 4597 bcm_vlan_t inner_vlan, 4598 bcm_vlan_action_set_t *action) 4599 { 4600 #ifdef BCM_TOMAHAWK3_SUPPORT 4601 if (SOC_IS_TOMAHAWK3(unit)) { 4602 return BCM_E_UNAVAIL; 4603 } 4604 #endif 4605 4606 CHECK_INIT(unit); 4607 4608 #ifdef BCM_TRX_SUPPORT 4609 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 4610 return _bcm_trx_vlan_translate_action_add(unit, port, 4611 key_type, outer_vlan, 4612 inner_vlan, action); 4613 } 4614 #endif /* BCM_TRX_SUPPORT */ 4615 4616 return BCM_E_UNAVAIL; 4617 } 4618 4619 /* 4620 * Function : 4621 * bcm_vlan_translate_action_get 4622 * Description : 4623 * Get an entry to ingress VLAN translation table. 4624 * Parameters : 4625 * unit (IN) BCM unit number 4626 * port (IN) Generic port 4627 * key_type (IN) Key Type : bcmVlanTranslateKey* 4628 * outer_vlan (IN) Packet outer VLAN ID 4629 * inner_vlan (IN) Packet inner VLAN ID 4630 * action (OUT) Action for outer and inner tag 4631 */ 4632 int 4633 bcm_esw_vlan_translate_action_get (int unit, bcm_gport_t port, 4634 bcm_vlan_translate_key_t key_type, 4635 bcm_vlan_t outer_vlan, 4636 bcm_vlan_t inner_vlan, 4637 bcm_vlan_action_set_t *action) 4638 { 4639 #ifdef BCM_TOMAHAWK3_SUPPORT 4640 if (SOC_IS_TOMAHAWK3(unit)) { 4641 return BCM_E_UNAVAIL; 4642 } 4643 #endif 4644 4645 CHECK_INIT(unit); 4646 4647 #ifdef BCM_TRX_SUPPORT 4648 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 4649 bcm_vlan_action_set_t_init(action); 4650 return _bcm_trx_vlan_translate_action_get(unit, port, key_type, 4651 outer_vlan, inner_vlan, 4652 action); 4653 } 4654 #endif /* BCM_TRX_SUPPORT */ 4655 4656 return BCM_E_UNAVAIL; 4657 } 4658 4659 4660 /* 4661 * Function : 4662 * _bcm_trx_vlan_translate_action_traverse_int_cb 4663 * Description : 4664 * Internal call back function to call user provided call back 4665 * entries in Triumph and call given call back. 4666 * Parameters : 4667 * unit (IN) BCM unit number 4668 * trvs_info (IN) Traverse structure that contain all relevant info 4669 */ 4670 int 4671 _bcm_esw_vlan_translate_action_traverse_int_cb(int unit, void *trv_info, 4672 int *stop) 4673 { 4674 _bcm_vlan_translate_traverse_t *trvs_str; 4675 _translate_action_traverse_cb_t *usr_cb_st; 4676 4677 if ((NULL == trv_info) || (NULL == stop)){ 4678 return BCM_E_PARAM; 4679 } 4680 trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info; 4681 usr_cb_st = (_translate_action_traverse_cb_t *)trvs_str->user_cb_st; 4682 4683 *stop = FALSE; 4684 return usr_cb_st->usr_cb(unit, trvs_str->gport, trvs_str->key_type, 4685 trvs_str->outer_vlan, trvs_str->inner_vlan, 4686 trvs_str->action, trvs_str->user_data); 4687 } 4688 4689 /* 4690 * Function : 4691 * _bcm_esw_vlan_translate_egress_action_traverse_int_cb 4692 * Description : 4693 * Internal call back function to call user provided call back 4694 * entries in Triumph and call given call back. 4695 * Parameters : 4696 * unit (IN) BCM unit number 4697 * trvs_info (IN) Traverse structure that contain all relevant info 4698 */ 4699 int 4700 _bcm_esw_vlan_translate_egress_action_traverse_int_cb(int unit, void *trv_info, 4701 int *stop) 4702 { 4703 _bcm_vlan_translate_traverse_t *trvs_str; 4704 _translate_egress_action_traverse_cb_t *usr_cb_st; 4705 4706 if ((NULL == trv_info) || (NULL == stop)){ 4707 return BCM_E_PARAM; 4708 } 4709 trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info; 4710 usr_cb_st = (_translate_egress_action_traverse_cb_t *)trvs_str->user_cb_st; 4711 4712 *stop = FALSE; 4713 4714 return usr_cb_st->usr_cb(unit, trvs_str->port_class, 4715 trvs_str->outer_vlan, 4716 trvs_str->inner_vlan, 4717 trvs_str->action, 4718 trvs_str->user_data); 4719 } 4720 4721 /* 4722 * Function : 4723 * _bcm_esw_vlan_translate_action_range_traverse_int_cb 4724 * Description : 4725 * Internal call back function to call user provided call back 4726 * entries in Triumph and call given call back. 4727 * Parameters : 4728 * unit (IN) BCM unit number 4729 * trvs_info (IN) Traverse structure that contain all relevant info 4730 */ 4731 int 4732 _bcm_esw_vlan_translate_action_range_traverse_int_cb(int unit, void *trv_info, 4733 int *stop) 4734 { 4735 _bcm_vlan_translate_traverse_t *trvs_str; 4736 _translate_action_range_traverse_cb_t *usr_cb_st; 4737 4738 if ((NULL == trv_info) || (NULL == stop)){ 4739 return BCM_E_PARAM; 4740 } 4741 trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info; 4742 usr_cb_st = (_translate_action_range_traverse_cb_t *)trvs_str->user_cb_st; 4743 4744 *stop = FALSE; 4745 return usr_cb_st->usr_cb(unit, trvs_str->gport, trvs_str->outer_vlan, 4746 trvs_str->outer_vlan_high, trvs_str->inner_vlan, 4747 trvs_str->inner_vlan_high, trvs_str->action, 4748 trvs_str->user_data); 4749 } 4750 4751 /* 4752 * Function : 4753 * _bcm_esw_vlan_translate_range_traverse_int_cb 4754 * Description : 4755 * Internal call back function to call user provided call back 4756 * entries and call given call back. 4757 * Parameters : 4758 * unit (IN) BCM unit number 4759 * trvs_info (IN) Traverse structure that contain all relevant info 4760 */ 4761 int 4762 _bcm_esw_vlan_translate_range_traverse_int_cb(int unit, void *trv_info, 4763 int *stop) 4764 { 4765 _bcm_vlan_translate_traverse_t *trvs_str; 4766 _translate_range_traverse_cb_t *usr_cb_st; 4767 4768 if ((NULL == trv_info) || (NULL == stop)){ 4769 return BCM_E_PARAM; 4770 } 4771 trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info; 4772 usr_cb_st = (_translate_range_traverse_cb_t *)trvs_str->user_cb_st; 4773 4774 *stop = FALSE; 4775 if ((trvs_str->key_type == bcmVlanTranslateKeyPortOuter) && 4776 (trvs_str->action->dt_outer == bcmVlanActionReplace) && 4777 (trvs_str->action->dt_inner == bcmVlanActionNone) && 4778 (trvs_str->action->ot_outer == bcmVlanActionReplace) && 4779 (trvs_str->action->ot_inner == bcmVlanActionNone)) { 4780 return usr_cb_st->usr_cb(unit, trvs_str->gport, trvs_str->outer_vlan, 4781 trvs_str->outer_vlan_high, 4782 trvs_str->action->new_outer_vlan, 4783 trvs_str->action->priority, trvs_str->user_data); 4784 } else { 4785 return BCM_E_NONE; 4786 } 4787 } 4788 4789 /* 4790 * Function : 4791 * _bcm_esw_vlan_translate_traverse_int_cb 4792 * Description : 4793 * Internal call back function to call user provided call back 4794 * Parameters : 4795 * unit (IN) BCM unit number 4796 * trvs_info (IN) Traverse structure that contain all relevant info 4797 */ 4798 int 4799 _bcm_esw_vlan_translate_traverse_int_cb(int unit, void *trv_info, int *stop) 4800 { 4801 _bcm_vlan_translate_traverse_t *trvs_str; 4802 _translate_traverse_cb_t *usr_cb_st; 4803 bcm_vlan_t old_vlan, new_vlan; 4804 4805 if ((NULL == trv_info) || (NULL == stop)){ 4806 return BCM_E_PARAM; 4807 } 4808 trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info; 4809 usr_cb_st = (_translate_traverse_cb_t *)trvs_str->user_cb_st; 4810 if (BCM_VLAN_INVALID != trvs_str->outer_vlan) { 4811 old_vlan = trvs_str->outer_vlan; 4812 } else { 4813 old_vlan = trvs_str->inner_vlan; 4814 } 4815 4816 if (BCM_VLAN_INVALID != trvs_str->action->new_outer_vlan) { 4817 new_vlan = trvs_str->action->new_outer_vlan; 4818 } else { 4819 new_vlan = trvs_str->action->new_inner_vlan; 4820 } 4821 4822 *stop = FALSE; 4823 return usr_cb_st->usr_cb(unit, trvs_str->gport, old_vlan, new_vlan, 4824 trvs_str->action->priority, trvs_str->user_data); 4825 } 4826 4827 4828 /* 4829 * Function : 4830 * _bcm_esw_vlan_translate_egress_traverse_int_cb 4831 * Description : 4832 * Internal call back function to call user provided call back 4833 * Parameters : 4834 * unit (IN) BCM unit number 4835 * trvs_info (IN) Traverse structure that contain all relevant info 4836 */ 4837 int 4838 _bcm_esw_vlan_translate_egress_traverse_int_cb(int unit, void *trv_info, 4839 int *stop) 4840 { 4841 _bcm_vlan_translate_traverse_t *trvs_str; 4842 _translate_egress_traverse_cb_t *usr_cb_st; 4843 bcm_vlan_t old_vlan, new_vlan; 4844 bcm_gport_t gport = 0; 4845 4846 if ((NULL == trv_info) || (NULL == stop)){ 4847 return BCM_E_PARAM; 4848 } 4849 trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info; 4850 usr_cb_st = (_translate_egress_traverse_cb_t *)trvs_str->user_cb_st; 4851 if (BCM_VLAN_INVALID != trvs_str->outer_vlan) { 4852 old_vlan = trvs_str->outer_vlan; 4853 } else { 4854 old_vlan = trvs_str->inner_vlan; 4855 } 4856 4857 if (BCM_VLAN_INVALID != trvs_str->action->new_outer_vlan) { 4858 new_vlan = trvs_str->action->new_outer_vlan; 4859 } else { 4860 new_vlan = trvs_str->action->new_inner_vlan; 4861 } 4862 4863 *stop = FALSE; 4864 if (!BCM_GPORT_IS_SET(trvs_str->port_class)) { 4865 if (bcm_esw_port_gport_get(unit, trvs_str->port_class, &gport) != 4866 BCM_E_NONE) { 4867 return BCM_E_PORT; 4868 } 4869 } 4870 4871 return usr_cb_st->usr_cb(unit, gport, old_vlan, new_vlan, 4872 trvs_str->action->priority, trvs_str->user_data); 4873 } 4874 4875 /* 4876 * Function : 4877 * _bcm_esw_vlan_dtag_traverse_int_cb 4878 * Description : 4879 * Internal call back function to call user provided call back 4880 * Parameters : 4881 * unit (IN) BCM unit number 4882 * trvs_info (IN) Traverse structure that contain all relevant info 4883 */ 4884 int 4885 _bcm_esw_vlan_dtag_traverse_int_cb(int unit, void *trv_info, int *stop) 4886 { 4887 _bcm_vlan_translate_traverse_t *trvs_str; 4888 _dtag_traverse_cb_t *usr_cb_st; 4889 bcm_vlan_t old_vlan, new_vlan; 4890 4891 if ((NULL == trv_info) || (NULL == stop)){ 4892 return BCM_E_PARAM; 4893 } 4894 trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info; 4895 usr_cb_st = (_dtag_traverse_cb_t *)trvs_str->user_cb_st; 4896 if (BCM_VLAN_INVALID != trvs_str->outer_vlan) { 4897 old_vlan = trvs_str->outer_vlan; 4898 } else { 4899 old_vlan = trvs_str->inner_vlan; 4900 } 4901 4902 if (BCM_VLAN_INVALID != trvs_str->action->new_outer_vlan) { 4903 new_vlan = trvs_str->action->new_outer_vlan; 4904 } else { 4905 new_vlan = trvs_str->action->new_inner_vlan; 4906 } 4907 4908 *stop = FALSE; 4909 return usr_cb_st->usr_cb(unit, trvs_str->gport, old_vlan, new_vlan, 4910 trvs_str->action->priority, trvs_str->user_data); 4911 } 4912 4913 /* 4914 * Function : 4915 * _bcm_esw_vlan_dtag_range_traverse_int_cb 4916 * Description : 4917 * Internal call back function to call user provided call back 4918 * entries and call given call back. 4919 * Parameters : 4920 * unit (IN) BCM unit number 4921 * trvs_info (IN) Traverse structure that contain all relevant info 4922 */ 4923 int 4924 _bcm_esw_vlan_dtag_range_traverse_int_cb(int unit, void *trv_info, 4925 int *stop) 4926 { 4927 _bcm_vlan_translate_traverse_t *trvs_str; 4928 _dtag_range_traverse_cb_t *usr_cb_st; 4929 4930 if ((NULL == trv_info) || (NULL == stop)){ 4931 return BCM_E_PARAM; 4932 } 4933 trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info; 4934 usr_cb_st = (_dtag_range_traverse_cb_t *)trvs_str->user_cb_st; 4935 4936 *stop = FALSE; 4937 if ((trvs_str->key_type == bcmVlanTranslateKeyPortInner) && 4938 (trvs_str->action->it_outer == bcmVlanActionAdd) && 4939 (trvs_str->action->it_inner == bcmVlanActionNone)) { 4940 return usr_cb_st->usr_cb(unit, trvs_str->gport, trvs_str->inner_vlan, 4941 trvs_str->inner_vlan_high, 4942 trvs_str->action->new_outer_vlan, 4943 trvs_str->action->priority, trvs_str->user_data); 4944 } else { 4945 return BCM_E_NONE; 4946 } 4947 } 4948 4949 /* 4950 * Function: 4951 * _bcm_esw_vlan_translate_entry_valid 4952 * Description: 4953 * Check if given Vlan Translate entry is Valid 4954 * Parameters: 4955 * unit device number 4956 * mem memory to operate on 4957 * vent entry read from HW 4958 * valid (OUT) Entry valid indicator 4959 * Return: 4960 * BCM_E_XXX 4961 */ 4962 4963 STATIC int 4964 _bcm_esw_vlan_translate_entry_valid(int unit, soc_mem_t mem, uint32 *vent, int *valid) 4965 { 4966 uint32 fval = 0; 4967 4968 if (INVALIDm == mem) { 4969 return BCM_E_MEMORY; 4970 } 4971 4972 if ((NULL == vent) || (NULL == valid)) { 4973 return BCM_E_PARAM; 4974 } 4975 4976 #if defined(BCM_TRX_SUPPORT) || defined (BCM_FIREBOLT_SUPPORT) 4977 if (SOC_IS_FBX(unit)) { 4978 4979 #ifdef BCM_TRIUMPH3_SUPPORT 4980 if (SOC_IS_TRIUMPH3(unit) && (mem == VLAN_XLATE_EXTDm)) { 4981 /* both VALID_0 and VALID_1 fields need to be set */ 4982 if ((!soc_mem_field32_get(unit, mem, vent, VALID_0f)) || 4983 (!soc_mem_field32_get(unit, mem, vent, VALID_1f))) { 4984 *valid = FALSE; 4985 return (BCM_E_NONE); 4986 } 4987 4988 /* qualify with key type: odd number */ 4989 fval = soc_mem_field32_get(unit, mem, vent, KEY_TYPE_0f); 4990 fval &= 0x1; 4991 } else 4992 #endif /* BCM_TRIUMPH3_SUPPORT */ 4993 #ifdef BCM_TRIDENT3_SUPPORT 4994 if (SOC_IS_TRIDENT3X(unit)) { 4995 if (mem == VLAN_XLATE_1_DOUBLEm || 4996 mem == VLAN_XLATE_2_DOUBLEm || 4997 mem == EGR_VLAN_XLATE_1_DOUBLEm || 4998 mem == EGR_VLAN_XLATE_2_DOUBLEm) { 4999 /* both VALID_0 and VALID_1 fields need to be set */ 5000 if ((!soc_mem_field32_get(unit, mem, vent, BASE_VALID_0f)) || 5001 (!soc_mem_field32_get(unit, mem, vent, BASE_VALID_1f))) { 5002 *valid = FALSE; 5003 } else { 5004 *valid = TRUE; 5005 } 5006 } else if (mem == VLAN_XLATE_1_SINGLEm || 5007 mem == VLAN_XLATE_2_SINGLEm || 5008 mem == EGR_VLAN_XLATE_1_SINGLEm || 5009 mem == EGR_VLAN_XLATE_2_SINGLEm) { 5010 fval = soc_mem_field32_get(unit, mem, vent, BASE_VALIDf); 5011 *valid = fval ? TRUE : FALSE; 5012 } else { 5013 fval = soc_mem_field32_get(unit, mem, vent, VALIDf); 5014 *valid = fval ? TRUE : FALSE; 5015 } 5016 return (BCM_E_NONE); 5017 } else 5018 #endif /* BCM_TRIDENT3_SUPPORT */ 5019 { 5020 fval = soc_mem_field32_get(unit, mem, vent, VALIDf); 5021 } 5022 } 5023 #endif /* BCM_TRX_SUPPORT || BCM_FIREBOLT_SUPPORT */ 5024 5025 *valid = fval ? TRUE : FALSE; 5026 5027 return (BCM_E_NONE); 5028 } 5029 5030 5031 /* 5032 * Function: 5033 * _bcm_esw_vlan_translate_entry_parse 5034 * Description: 5035 * Parser function to parse vlan translate entry into truverse structure 5036 * will call per chip parser 5037 * Parameters: 5038 * unit device number 5039 * mem memory to operate on 5040 * vent entry read from HW 5041 * trvs_info Structure to fill 5042 * Return: 5043 * BCM_E_XXX 5044 */ 5045 5046 STATIC int 5047 _bcm_esw_vlan_translate_entry_parse(int unit, soc_mem_t mem, uint32 *vent, 5048 _bcm_vlan_translate_traverse_t *trvs_info) 5049 { 5050 #ifdef BCM_TRX_SUPPORT 5051 5052 if (SOC_IS_TRX(unit)) { 5053 return _bcm_trx_vlan_translate_parse(unit, mem, vent, trvs_info); 5054 } 5055 #endif /* BCM_TRX_SUPPORT */ 5056 #ifdef BCM_FIREBOLT_SUPPORT 5057 if (SOC_IS_FBX(unit)) { 5058 return _bcm_fb_vlan_translate_parse(unit, mem, vent, trvs_info); 5059 } 5060 #endif /* BCM_FIREBOLT_SUPPORT */ 5061 return (BCM_E_UNAVAIL); 5062 } 5063 5064 /* 5065 * Function : 5066 * _bcm_esw_vlan_translate_traverse_mem 5067 * Description : 5068 * Traverse over all translate entries and call parse function 5069 * based on the unit 5070 * Parameters : 5071 * unit (IN) BCM unit number 5072 * cb (IN) Call back function 5073 * user_data (IN) User provided data to pass to a call back 5074 */ 5075 int 5076 _bcm_esw_vlan_translate_traverse_mem(int unit, soc_mem_t mem, 5077 _bcm_vlan_translate_traverse_t *trvs_info) 5078 { 5079 /* Indexes to iterate over memories, chunks and entries */ 5080 int chnk_idx, ent_idx, chnk_idx_max, mem_idx_max; 5081 int buf_size, chunksize, chnk_end; 5082 /* Buffer to store chunk of L2 table we currently work on */ 5083 uint32 *vt_tbl_chnk; 5084 uint32 *vent; 5085 int valid, stop, rv = BCM_E_NONE; 5086 5087 if (INVALIDm == mem) { 5088 return BCM_E_MEMORY; 5089 } 5090 if (!soc_mem_index_count(unit, mem)) { 5091 return BCM_E_NONE; 5092 } 5093 5094 chunksize = soc_property_get(unit, spn_VLANDELETE_CHUNKS, 5095 VLAN_MEM_CHUNKS_DEFAULT); 5096 5097 buf_size = 4 * SOC_MAX_MEM_FIELD_WORDS * chunksize; 5098 vt_tbl_chnk = soc_cm_salloc(unit, buf_size, "vlan translate traverse"); 5099 if (NULL == vt_tbl_chnk) { 5100 return BCM_E_MEMORY; 5101 } 5102 5103 mem_idx_max = soc_mem_index_max(unit, mem); 5104 for (chnk_idx = soc_mem_index_min(unit, mem); 5105 chnk_idx <= mem_idx_max; 5106 chnk_idx += chunksize) { 5107 sal_memset((void *)vt_tbl_chnk, 0, buf_size); 5108 5109 chnk_idx_max = 5110 ((chnk_idx + chunksize) <= mem_idx_max) ? 5111 chnk_idx + chunksize - 1: mem_idx_max; 5112 5113 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 5114 chnk_idx, chnk_idx_max, vt_tbl_chnk); 5115 if (SOC_FAILURE(rv)) { 5116 break; 5117 } 5118 chnk_end = (chnk_idx_max - chnk_idx); 5119 for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) { 5120 5121 vent = 5122 soc_mem_table_idx_to_pointer(unit, mem, uint32 *, 5123 vt_tbl_chnk, ent_idx); 5124 rv = _bcm_esw_vlan_translate_entry_valid(unit, mem, vent, &valid); 5125 if (BCM_FAILURE(rv)) { 5126 break; 5127 } 5128 if (!valid) { 5129 continue; 5130 } 5131 rv = _bcm_esw_vlan_translate_entry_parse(unit, mem, vent, trvs_info); 5132 if (rv == BCM_E_NOT_FOUND) { /* for entries not exposed to user */ 5133 continue; 5134 } else if (BCM_FAILURE(rv)) { 5135 break; 5136 } 5137 rv = trvs_info->int_cb(unit, trvs_info, &stop); 5138 if (BCM_FAILURE(rv)) { 5139 break; 5140 } 5141 /* 5142 Only get cb function that will use internal traverse should mark 5143 stop condition as true upon a match 5144 */ 5145 if (stop) { 5146 break; 5147 } 5148 } 5149 } 5150 soc_cm_sfree(unit, vt_tbl_chnk); 5151 return rv; 5152 } 5153 5154 5155 5156 /* 5157 * Function : 5158 * bcm_vlan_translate_traverse 5159 * Description : 5160 * Traverse over all translate entries and call given call back with 5161 * new vid and prio. 5162 * Parameters : 5163 * unit (IN) BCM unit number 5164 * cb (IN) Call back function 5165 * user_data (IN) User provided data to pass to a call back 5166 */ 5167 int 5168 bcm_esw_vlan_translate_traverse(int unit, bcm_vlan_translate_traverse_cb cb, 5169 void *user_data) 5170 { 5171 5172 5173 _bcm_vlan_translate_traverse_t trvs_st; 5174 bcm_vlan_action_set_t action; 5175 _translate_traverse_cb_t usr_cb_st; 5176 int rv; 5177 soc_mem_t mem = INVALIDm; 5178 5179 #ifdef BCM_TOMAHAWK3_SUPPORT 5180 if (SOC_IS_TOMAHAWK3(unit)) { 5181 return (BCM_E_UNAVAIL); 5182 } 5183 #endif 5184 5185 if (!cb) { 5186 return (BCM_E_PARAM); 5187 } 5188 5189 sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t)); 5190 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 5191 sal_memset(&usr_cb_st, 0, sizeof(_translate_traverse_cb_t)); 5192 5193 usr_cb_st.usr_cb = cb; 5194 5195 trvs_st.user_data = user_data; 5196 trvs_st.action = &action; 5197 trvs_st.user_cb_st = (void *)&usr_cb_st; 5198 trvs_st.int_cb = _bcm_esw_vlan_translate_traverse_int_cb; 5199 5200 #ifdef BCM_TRX_SUPPORT 5201 if (SOC_IS_TRX(unit)) { 5202 mem = VLAN_XLATEm; 5203 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 5204 mem = VLAN_XLATE_1_DOUBLEm; 5205 } 5206 if (!soc_feature(unit, soc_feature_vlan_action)) { 5207 return BCM_E_UNAVAIL; 5208 } 5209 } 5210 #endif /* BCM_FIREBOLT_SUPPORT */ 5211 #ifdef BCM_FIREBOLT_SUPPORT 5212 if (SOC_IS_FBX(unit)) { 5213 if (!soc_feature(unit, soc_feature_vlan_translation)) { 5214 return BCM_E_UNAVAIL; 5215 } 5216 mem = VLAN_XLATEm; 5217 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 5218 mem = VLAN_XLATE_1_DOUBLEm; 5219 } 5220 } 5221 #endif /* BCM_FIREBOLT_SUPPORT */ 5222 if (INVALIDm == mem) { 5223 return BCM_E_UNAVAIL; 5224 } 5225 rv = _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st); 5226 #ifdef BCM_TRIUMPH3_SUPPORT 5227 if (SOC_IS_TRIUMPH3(unit)) { 5228 /* for the extended table */ 5229 mem = VLAN_XLATE_EXTDm; 5230 rv = _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st); 5231 } 5232 #endif 5233 return rv; 5234 } 5235 5236 5237 /* 5238 * Function : 5239 * bcm_vlan_translate_egress_traverse 5240 * Description : 5241 * Traverse over all translate entries and call given call back with 5242 * new vid and prio. 5243 * Parameters : 5244 * unit (IN) BCM unit number 5245 * cb (IN) Call back function 5246 * user_data (IN) User provided data to pass to a call back 5247 */ 5248 int 5249 bcm_esw_vlan_translate_egress_traverse(int unit, 5250 bcm_vlan_translate_egress_traverse_cb cb, 5251 void *user_data) 5252 { 5253 5254 5255 _bcm_vlan_translate_traverse_t trvs_st; 5256 bcm_vlan_action_set_t action; 5257 _translate_egress_traverse_cb_t usr_cb_st; 5258 soc_mem_t mem = INVALIDm; 5259 5260 #ifdef BCM_TOMAHAWK3_SUPPORT 5261 if (SOC_IS_TOMAHAWK3(unit)) { 5262 return (BCM_E_UNAVAIL); 5263 } 5264 #endif 5265 5266 if (!cb) { 5267 return (BCM_E_PARAM); 5268 } 5269 5270 sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t)); 5271 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 5272 sal_memset(&usr_cb_st, 0, sizeof(_translate_egress_traverse_cb_t)); 5273 5274 usr_cb_st.usr_cb = cb; 5275 5276 trvs_st.user_data = user_data; 5277 trvs_st.action = &action; 5278 trvs_st.user_cb_st = (void *)&usr_cb_st; 5279 trvs_st.int_cb = _bcm_esw_vlan_translate_egress_traverse_int_cb; 5280 5281 5282 #ifdef BCM_TRX_SUPPORT 5283 if (SOC_IS_TRX(unit)) { 5284 soc_control_t *sc = SOC_CONTROL(unit); 5285 5286 if (!soc_feature(unit, soc_feature_vlan_action)) { 5287 return BCM_E_UNAVAIL; 5288 } 5289 5290 /* If port class is changed system should not allow */ 5291 /* To use this API since it leads to confused outcome */ 5292 if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) { 5293 return BCM_E_CONFIG; 5294 } 5295 mem = EGR_VLAN_XLATEm; 5296 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 5297 mem = EGR_VLAN_XLATE_1_DOUBLEm; 5298 } 5299 } 5300 #endif /* BCM_FIREBOLT_SUPPORT */ 5301 #ifdef BCM_FIREBOLT_SUPPORT 5302 if (SOC_IS_FBX(unit)) { 5303 if (!soc_feature(unit, soc_feature_vlan_translation)) { 5304 return BCM_E_UNAVAIL; 5305 } 5306 mem = EGR_VLAN_XLATEm; 5307 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 5308 mem = EGR_VLAN_XLATE_1_DOUBLEm; 5309 } 5310 } 5311 #endif /* BCM_FIREBOLT_SUPPORT */ 5312 5313 if (INVALIDm == mem) { 5314 return BCM_E_UNAVAIL; 5315 } 5316 return _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st); 5317 } 5318 5319 /* 5320 * Function : 5321 * bcm_vlan_translate_egress_traverse 5322 * Description : 5323 * Traverse over all translate entries and call given call back with 5324 * new vid and prio. 5325 * Parameters : 5326 * unit (IN) BCM unit number 5327 * cb (IN) Call back function 5328 * user_data (IN) User provided data to pass to a call back 5329 */ 5330 int 5331 bcm_esw_vlan_dtag_traverse(int unit, 5332 bcm_vlan_dtag_traverse_cb cb, 5333 void *user_data) 5334 { 5335 _bcm_vlan_translate_traverse_t trvs_st; 5336 bcm_vlan_action_set_t action; 5337 _dtag_traverse_cb_t usr_cb_st; 5338 soc_mem_t mem = INVALIDm; 5339 5340 #ifdef BCM_TOMAHAWK3_SUPPORT 5341 if (SOC_IS_TOMAHAWK3(unit)) { 5342 return (BCM_E_UNAVAIL); 5343 } 5344 #endif 5345 5346 if (!cb) { 5347 return (BCM_E_PARAM); 5348 } 5349 5350 sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t)); 5351 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 5352 sal_memset(&usr_cb_st, 0, sizeof(_dtag_traverse_cb_t)); 5353 5354 usr_cb_st.usr_cb = cb; 5355 5356 trvs_st.user_data = user_data; 5357 trvs_st.action = &action; 5358 trvs_st.user_cb_st = (void *)&usr_cb_st; 5359 trvs_st.int_cb = _bcm_esw_vlan_dtag_traverse_int_cb; 5360 5361 #ifdef BCM_TRX_SUPPORT 5362 if (SOC_IS_TRX(unit)) { 5363 mem = VLAN_XLATEm; 5364 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 5365 mem = VLAN_XLATE_1_DOUBLEm; 5366 } 5367 if (!soc_feature(unit, soc_feature_vlan_action)) { 5368 return BCM_E_UNAVAIL; 5369 } 5370 } 5371 #endif /* BCM_FIREBOLT_SUPPORT */ 5372 #ifdef BCM_FIREBOLT_SUPPORT 5373 if (SOC_IS_FBX(unit)) { 5374 if (!soc_feature(unit, soc_feature_vlan_translation)) { 5375 return BCM_E_UNAVAIL; 5376 } 5377 mem = VLAN_XLATEm; 5378 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 5379 mem = VLAN_XLATE_1_DOUBLEm; 5380 } 5381 } 5382 #endif /* BCM_FIREBOLT_SUPPORT */ 5383 5384 if (INVALIDm == mem) { 5385 return BCM_E_UNAVAIL; 5386 } 5387 return _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st); 5388 } 5389 5390 /* 5391 * Function : 5392 * bcm_vlan_translate_action_traverse 5393 * Description : 5394 * Traverse over all translate entries and call given callback with 5395 * action structure 5396 * Parameters : 5397 * unit (IN) BCM unit number 5398 * cb (IN) Call back function 5399 * user_data (IN) User provided data to pass to a call back 5400 */ 5401 int 5402 bcm_esw_vlan_translate_action_traverse(int unit, 5403 bcm_vlan_translate_action_traverse_cb cb, 5404 void *user_data) 5405 { 5406 _bcm_vlan_translate_traverse_t trvs_st; 5407 bcm_vlan_action_set_t action; 5408 _translate_action_traverse_cb_t usr_cb_st; 5409 int rv = BCM_E_UNAVAIL; 5410 5411 #ifdef BCM_TOMAHAWK3_SUPPORT 5412 if (SOC_IS_TOMAHAWK3(unit)) { 5413 return (BCM_E_UNAVAIL); 5414 } 5415 #endif 5416 5417 if (!cb) { 5418 return (BCM_E_PARAM); 5419 } 5420 5421 sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t)); 5422 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 5423 sal_memset(&usr_cb_st, 0, sizeof(_translate_action_traverse_cb_t)); 5424 5425 usr_cb_st.usr_cb = cb; 5426 5427 trvs_st.user_data = user_data; 5428 trvs_st.action = &action; 5429 trvs_st.user_cb_st = (void *)&usr_cb_st; 5430 5431 #ifdef BCM_TRX_SUPPORT 5432 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 5433 soc_mem_t mem = VLAN_XLATEm; 5434 if (SOC_IS_TRIDENT3X(unit)) { 5435 mem = VLAN_XLATE_1_DOUBLEm; 5436 } 5437 trvs_st.int_cb = _bcm_esw_vlan_translate_action_traverse_int_cb; 5438 rv = _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st); 5439 } 5440 #endif /* BCM_TRX_SUPPORT */ 5441 5442 #ifdef BCM_TRIUMPH3_SUPPORT 5443 if (SOC_IS_TRIUMPH3(unit) && soc_feature(unit, soc_feature_vlan_action)) { 5444 trvs_st.int_cb = _bcm_esw_vlan_translate_action_traverse_int_cb; 5445 /* for the extended table */ 5446 rv = _bcm_esw_vlan_translate_traverse_mem(unit, VLAN_XLATE_EXTDm, 5447 &trvs_st); 5448 } 5449 #endif 5450 5451 return rv; 5452 } 5453 5454 /* 5455 * Function : 5456 * bcm_vlan_translate_egress_action_traverse 5457 * Description : 5458 * Traverse over all translate entries and call given callback with 5459 * action structure 5460 * Parameters : 5461 * unit (IN) BCM unit number 5462 * cb (IN) Call back function 5463 * user_data (IN) User provided data to pass to a call back 5464 */ 5465 int 5466 bcm_esw_vlan_translate_egress_action_traverse(int unit, 5467 bcm_vlan_translate_egress_action_traverse_cb cb, 5468 void *user_data) 5469 { 5470 _bcm_vlan_translate_traverse_t trvs_st; 5471 bcm_vlan_action_set_t action; 5472 _translate_egress_action_traverse_cb_t usr_cb_st; 5473 #ifdef BCM_TRX_SUPPORT 5474 soc_mem_t mem = EGR_VLAN_XLATEm; 5475 5476 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 5477 mem = EGR_VLAN_XLATE_1_DOUBLEm; 5478 } 5479 #endif 5480 #ifdef BCM_TOMAHAWK3_SUPPORT 5481 if (SOC_IS_TOMAHAWK3(unit)) { 5482 return (BCM_E_UNAVAIL); 5483 } 5484 #endif 5485 5486 if (!cb) { 5487 return (BCM_E_PARAM); 5488 } 5489 5490 sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t)); 5491 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 5492 sal_memset(&usr_cb_st, 0, sizeof(_translate_egress_action_traverse_cb_t)); 5493 5494 usr_cb_st.usr_cb = cb; 5495 5496 trvs_st.user_data = user_data; 5497 trvs_st.action = &action; 5498 trvs_st.user_cb_st = (void *)&usr_cb_st; 5499 5500 #ifdef BCM_TRX_SUPPORT 5501 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 5502 trvs_st.int_cb = _bcm_esw_vlan_translate_egress_action_traverse_int_cb; 5503 return _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st); 5504 } 5505 #endif /* BCM_TRX_SUPPORT */ 5506 return BCM_E_UNAVAIL; 5507 } 5508 5509 5510 /* 5511 * Function: 5512 * bcm_vlan_translate_action_delete 5513 * Purpose: 5514 * Delete a vlan translate lookup entry. 5515 * Parameters: 5516 * unit (IN) BCM unit number 5517 * port (IN) Generic port 5518 * key_type (IN) Key Type : bcmVlanTranslateKey* 5519 * outer_vlan (IN) Packet outer VLAN ID 5520 * inner_vlan (IN) Packet inner VLAN ID 5521 */ 5522 int 5523 bcm_esw_vlan_translate_action_delete(int unit, 5524 bcm_gport_t port, 5525 bcm_vlan_translate_key_t key_type, 5526 bcm_vlan_t outer_vlan, 5527 bcm_vlan_t inner_vlan) 5528 { 5529 #ifdef BCM_TOMAHAWK3_SUPPORT 5530 if (SOC_IS_TOMAHAWK3(unit)) { 5531 return (BCM_E_UNAVAIL); 5532 } 5533 #endif 5534 5535 CHECK_INIT(unit); 5536 5537 #ifdef BCM_TRX_SUPPORT 5538 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 5539 return _bcm_trx_vlan_translate_action_delete(unit, port, 5540 key_type, outer_vlan, 5541 inner_vlan); 5542 } 5543 #endif /* BCM_TRX_SUPPORT */ 5544 5545 return BCM_E_UNAVAIL; 5546 } 5547 5548 int 5549 bcm_esw_vlan_translate_range_add(int unit, int port, bcm_vlan_t old_vid_low, 5550 bcm_vlan_t old_vid_high, bcm_vlan_t new_vid, 5551 int int_prio) 5552 { 5553 bcm_gport_t gport; 5554 5555 CHECK_INIT(unit); 5556 VLAN_CHK_ID(unit, old_vid_low); 5557 VLAN_CHK_ID(unit, old_vid_high); 5558 VLAN_CHK_ID(unit, new_vid); 5559 if (old_vid_high < old_vid_low) { 5560 return BCM_E_PARAM; 5561 } 5562 5563 if (BCM_GPORT_IS_SET(port)) { 5564 gport = port; 5565 } else { 5566 if (!SOC_PORT_VALID(unit, port)) { 5567 return BCM_E_PORT; 5568 } 5569 BCM_IF_ERROR_RETURN( 5570 bcm_esw_port_gport_get(unit, port, &gport)); 5571 } 5572 5573 if (soc_feature(unit, soc_feature_vlan_translation_range)) { 5574 #ifdef BCM_TRX_SUPPORT 5575 if (SOC_IS_TRX(unit)) { 5576 bcm_vlan_action_set_t action; 5577 5578 /* add vlan range and translate entry for inner-tagged packets */ 5579 bcm_vlan_action_set_t_init(&action); 5580 action.new_outer_vlan = new_vid; 5581 action.priority = int_prio; 5582 action.it_outer = bcmVlanActionAdd; 5583 action.it_inner = bcmVlanActionDelete; 5584 action.it_inner_prio = bcmVlanActionNone; 5585 5586 BCM_IF_ERROR_RETURN 5587 (_bcm_trx_vlan_translate_action_range_add(unit, gport, 5588 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 5589 old_vid_low, old_vid_high, 5590 &action)); 5591 5592 5593 5594 /* Add vlan translate entry for outer-tagged packets. 5595 * This translate entry uses the range established above 5596 * for free on devices which only support one range space 5597 * between inner and outer tagged packets. */ 5598 bcm_vlan_action_set_t_init(&action); 5599 action.new_outer_vlan = new_vid; 5600 action.priority = int_prio; 5601 action.ot_outer = bcmVlanActionReplace; 5602 action.ot_outer_prio = bcmVlanActionReplace; 5603 action.dt_outer = bcmVlanActionReplace; 5604 action.dt_outer_prio = bcmVlanActionReplace; 5605 5606 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 5607 if (soc_feature(unit, soc_feature_vlan_xlate_dtag_range)) { 5608 BCM_IF_ERROR_RETURN 5609 (_bcm_trx_vlan_translate_action_range_add(unit, gport, 5610 old_vid_low, old_vid_high, 5611 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 5612 &action)); 5613 } else 5614 #endif 5615 { 5616 BCM_IF_ERROR_RETURN 5617 (_bcm_trx_vlan_translate_action_add(unit, gport, 5618 bcmVlanTranslateKeyPortOuter, 5619 old_vid_low, BCM_VLAN_INVALID, 5620 &action)); 5621 } 5622 return BCM_E_NONE; 5623 } 5624 #endif /* BCM_TRX_SUPPORT */ 5625 } 5626 5627 return BCM_E_UNAVAIL; 5628 } 5629 5630 int bcm_esw_vlan_translate_range_get (int unit, bcm_port_t port, 5631 bcm_vlan_t old_vlan_low, 5632 bcm_vlan_t old_vlan_high, 5633 bcm_vlan_t *new_vid, int *prio) 5634 { 5635 bcm_gport_t gport; 5636 5637 CHECK_INIT(unit); 5638 VLAN_CHK_ID(unit, old_vlan_low); 5639 VLAN_CHK_ID(unit, old_vlan_high); 5640 5641 if (BCM_GPORT_IS_SET(port)) { 5642 gport = port; 5643 } else { 5644 if (!SOC_PORT_VALID(unit, port)) { 5645 return BCM_E_PORT; 5646 } 5647 BCM_IF_ERROR_RETURN( 5648 bcm_esw_port_gport_get(unit, port, &gport)); 5649 } 5650 5651 if ((NULL == new_vid) || NULL == prio ){ 5652 return BCM_E_PARAM; 5653 } 5654 if (old_vlan_high < old_vlan_low) { 5655 return BCM_E_PARAM; 5656 } 5657 5658 if (soc_feature(unit, soc_feature_vlan_translation_range)) { 5659 #ifdef BCM_TRX_SUPPORT 5660 if (SOC_IS_TRX(unit)) { 5661 bcm_vlan_action_set_t action; 5662 5663 bcm_vlan_action_set_t_init(&action); 5664 BCM_IF_ERROR_RETURN 5665 (_bcm_trx_vlan_translate_action_range_get(unit, gport, 5666 old_vlan_low, old_vlan_high, 5667 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 5668 &action)); 5669 if (BCM_VLAN_INVALID != action.new_outer_vlan) { 5670 *new_vid = action.new_outer_vlan; 5671 *prio = action.priority; 5672 return BCM_E_NONE; 5673 } 5674 5675 BCM_IF_ERROR_RETURN 5676 (_bcm_trx_vlan_translate_action_range_get(unit, gport, 5677 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 5678 old_vlan_low, old_vlan_high, 5679 &action)); 5680 5681 if (BCM_VLAN_INVALID != action.new_outer_vlan) { 5682 *new_vid = action.new_outer_vlan; 5683 *prio = action.priority; 5684 return BCM_E_NONE; 5685 } 5686 5687 return BCM_E_NOT_FOUND; 5688 } 5689 #endif /* BCM_TRX_SUPPORT */ 5690 } 5691 5692 return BCM_E_UNAVAIL; 5693 } 5694 5695 5696 int 5697 bcm_esw_vlan_translate_range_delete(int unit, int port, 5698 bcm_vlan_t old_vid_low, 5699 bcm_vlan_t old_vid_high) 5700 { 5701 bcm_gport_t gport; 5702 5703 CHECK_INIT(unit); 5704 VLAN_CHK_ID(unit, old_vid_low); 5705 VLAN_CHK_ID(unit, old_vid_high); 5706 if (old_vid_high < old_vid_low) { 5707 return BCM_E_PARAM; 5708 } 5709 5710 if (BCM_GPORT_IS_SET(port)) { 5711 gport = port; 5712 } else { 5713 if (!SOC_PORT_VALID(unit, port)) { 5714 return BCM_E_PORT; 5715 } 5716 BCM_IF_ERROR_RETURN( 5717 bcm_esw_port_gport_get(unit, port, &gport)); 5718 } 5719 5720 if (soc_feature(unit, soc_feature_vlan_translation_range)) { 5721 #ifdef BCM_TRX_SUPPORT 5722 if (SOC_IS_TRX(unit)) { 5723 int rv = BCM_E_NONE; 5724 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 5725 if (soc_feature(unit, soc_feature_vlan_xlate_dtag_range)) { 5726 /* Delete outer vlan translate entry and range */ 5727 rv = _bcm_trx_vlan_translate_action_range_delete(unit, gport, 5728 old_vid_low, old_vid_high, 5729 BCM_VLAN_INVALID, BCM_VLAN_INVALID); 5730 } else 5731 #endif 5732 { 5733 /* Delete outer vlan translate entry */ 5734 rv = _bcm_trx_vlan_translate_action_delete(unit, gport, 5735 bcmVlanTranslateKeyPortOuter, 5736 old_vid_low, BCM_VLAN_INVALID); 5737 } 5738 5739 /* Delete inner vlan translate entry and range */ 5740 if (BCM_SUCCESS(rv) || (rv == BCM_E_NOT_FOUND) ) { 5741 BCM_IF_ERROR_RETURN 5742 (_bcm_trx_vlan_translate_action_range_delete(unit, gport, 5743 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 5744 old_vid_low, old_vid_high)); 5745 } else { 5746 return (rv); 5747 } 5748 5749 return (BCM_E_NONE); 5750 } 5751 #endif /* BCM_TRX_SUPPORT */ 5752 } 5753 5754 return BCM_E_UNAVAIL; 5755 } 5756 5757 int 5758 bcm_esw_vlan_translate_range_delete_all(int unit) 5759 { 5760 if (soc_feature(unit, soc_feature_vlan_translation_range)) { 5761 #ifdef BCM_TRX_SUPPORT 5762 if (SOC_IS_TRX(unit)) { 5763 return _bcm_trx_vlan_translate_action_range_delete_all(unit); 5764 } 5765 #endif /* BCM_TRX_SUPPORT */ 5766 } 5767 5768 return BCM_E_UNAVAIL; 5769 } 5770 5771 int 5772 bcm_esw_vlan_dtag_range_add(int unit, int port, 5773 bcm_vlan_t old_vid_low, 5774 bcm_vlan_t old_vid_high, 5775 bcm_vlan_t new_vid, int int_prio) 5776 { 5777 bcm_gport_t gport; 5778 5779 CHECK_INIT(unit); 5780 VLAN_CHK_ID(unit, old_vid_low); 5781 VLAN_CHK_ID(unit, old_vid_high); 5782 VLAN_CHK_ID(unit, new_vid); 5783 if (old_vid_high < old_vid_low) { 5784 return BCM_E_PARAM; 5785 } 5786 if ((int_prio < BCM_PRIO_MIN) || (int_prio > BCM_PRIO_MAX)) { 5787 return BCM_E_PARAM; 5788 } 5789 5790 if (BCM_GPORT_IS_SET(port)) { 5791 gport = port; 5792 } else { 5793 if (!SOC_PORT_VALID(unit, port)) { 5794 return BCM_E_PORT; 5795 } 5796 BCM_IF_ERROR_RETURN( 5797 bcm_esw_port_gport_get(unit, port, &gport)); 5798 } 5799 5800 if (soc_feature(unit, soc_feature_vlan_translation_range)) { 5801 #ifdef BCM_TRX_SUPPORT 5802 if (SOC_IS_TRX(unit)) { 5803 bcm_vlan_action_set_t action; 5804 5805 bcm_vlan_action_set_t_init(&action); 5806 action.new_outer_vlan = new_vid; 5807 action.priority = int_prio; 5808 /* For inner tagged packets, set the outer tag action and outer 5809 * packet prio action to ADD. 5810 * For all other packet types, the action is initialized to NONE. 5811 */ 5812 action.it_outer = bcmVlanActionAdd; 5813 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 5814 action.it_outer_pkt_prio = bcmVlanActionAdd; 5815 } else { 5816 action.it_outer_pkt_prio = bcmVlanActionNone; 5817 } 5818 return _bcm_trx_vlan_translate_action_range_add(unit, gport, 5819 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 5820 old_vid_low, old_vid_high, 5821 &action); 5822 } 5823 #endif /* BCM_TRX_SUPPORT */ 5824 } 5825 5826 return BCM_E_UNAVAIL; 5827 } 5828 5829 5830 int 5831 bcm_esw_vlan_dtag_range_get (int unit, bcm_port_t port, 5832 bcm_vlan_t old_vid_low, 5833 bcm_vlan_t old_vid_high, 5834 bcm_vlan_t *new_vid, 5835 int *prio) 5836 { 5837 bcm_gport_t gport; 5838 5839 CHECK_INIT(unit); 5840 VLAN_CHK_ID(unit, old_vid_low); 5841 VLAN_CHK_ID(unit, old_vid_high); 5842 5843 if ((NULL == new_vid) || NULL == prio ){ 5844 return BCM_E_PARAM; 5845 } 5846 if (old_vid_high < old_vid_low) { 5847 return BCM_E_PARAM; 5848 } 5849 if (BCM_GPORT_IS_SET(port)) { 5850 gport = port; 5851 } else { 5852 if (!SOC_PORT_VALID(unit, port)) { 5853 return BCM_E_PORT; 5854 } 5855 BCM_IF_ERROR_RETURN( 5856 bcm_esw_port_gport_get(unit, port, &gport)); 5857 } 5858 5859 if (soc_feature(unit, soc_feature_vlan_translation_range)) { 5860 #ifdef BCM_TRX_SUPPORT 5861 if (SOC_IS_TRX(unit)) { 5862 bcm_vlan_action_set_t action; 5863 5864 bcm_vlan_action_set_t_init(&action); 5865 BCM_IF_ERROR_RETURN 5866 (_bcm_trx_vlan_translate_action_range_get(unit, gport, 5867 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 5868 old_vid_low, old_vid_high, 5869 &action)); 5870 if (BCM_VLAN_INVALID != action.new_outer_vlan) { 5871 *new_vid = action.new_outer_vlan; 5872 *prio = action.priority; 5873 return BCM_E_NONE; 5874 } 5875 5876 return BCM_E_NOT_FOUND; 5877 } 5878 #endif /* BCM_TRX_SUPPORT */ 5879 } 5880 5881 return BCM_E_UNAVAIL; 5882 } 5883 5884 5885 int 5886 bcm_esw_vlan_dtag_range_delete(int unit, int port, 5887 bcm_vlan_t old_vid_low, 5888 bcm_vlan_t old_vid_high) 5889 { 5890 bcm_gport_t gport; 5891 5892 CHECK_INIT(unit); 5893 VLAN_CHK_ID(unit, old_vid_low); 5894 VLAN_CHK_ID(unit, old_vid_high); 5895 if (old_vid_high < old_vid_low) { 5896 return BCM_E_PARAM; 5897 } 5898 if (BCM_GPORT_IS_SET(port)) { 5899 gport = port; 5900 } else { 5901 if (!SOC_PORT_VALID(unit, port)) { 5902 return BCM_E_PORT; 5903 } 5904 BCM_IF_ERROR_RETURN( 5905 bcm_esw_port_gport_get(unit, port, &gport)); 5906 } 5907 5908 if (soc_feature(unit, soc_feature_vlan_translation_range)) { 5909 #ifdef BCM_TRX_SUPPORT 5910 if (SOC_IS_TRX(unit)) { 5911 return _bcm_trx_vlan_translate_action_range_delete(unit, gport, 5912 BCM_VLAN_INVALID, BCM_VLAN_INVALID, 5913 old_vid_low, old_vid_high); 5914 } 5915 #endif /* BCM_TRX_SUPPORT */ 5916 } 5917 5918 return BCM_E_UNAVAIL; 5919 } 5920 5921 int 5922 bcm_esw_vlan_dtag_range_delete_all(int unit) 5923 { 5924 if (soc_feature(unit, soc_feature_vlan_translation_range)) { 5925 #ifdef BCM_TRX_SUPPORT 5926 if (SOC_IS_TRX(unit)) { 5927 return _bcm_trx_vlan_translate_action_range_delete_all(unit); 5928 } 5929 #endif /* BCM_TRX_SUPPORT */ 5930 } 5931 5932 return BCM_E_UNAVAIL; 5933 } 5934 5935 /* 5936 * Function : 5937 * bcm_vlan_translate_action_range_add 5938 * Description : 5939 * Add an entry to the VLAN Translation table, which assigns 5940 * VLAN actions for packets matching within the VLAN range(s). 5941 * Parameters : 5942 * unit (IN) BCM unit number 5943 * port (IN) Ingress gport (generic port) 5944 * outer_vlan_low (IN) Outer VLAN ID Low 5945 * outer_vlan_high (IN) Outer VLAN ID High 5946 * inner_vlan_low (IN) Inner VLAN ID Low 5947 * inner_vlan_high (IN) Inner VLAN ID High 5948 * action (IN) Action for outer and inner tag 5949 * 5950 * Notes : 5951 * For translation of double-tagged packets, specify a valid 5952 * VLAN ID value for outer_vlan_low/high and inner_vlan_low/high. 5953 * For translation of single outer-tagged packets, specify a 5954 * valid VLAN ID for outer_vlan_low/high and BCM_VLAN_INVALID 5955 * for inner_vlan_low/high. For translation of single inner-tagged 5956 * packets, specify a valid VLAN ID for inner_vlan_low/high and 5957 * BCM_VLAN_INVALID for outer_vlan_low/high. 5958 */ 5959 5960 int 5961 bcm_esw_vlan_translate_action_range_add(int unit, bcm_gport_t port, 5962 bcm_vlan_t outer_vlan_low, 5963 bcm_vlan_t outer_vlan_high, 5964 bcm_vlan_t inner_vlan_low, 5965 bcm_vlan_t inner_vlan_high, 5966 bcm_vlan_action_set_t *action) 5967 { 5968 #ifdef BCM_TOMAHAWK3_SUPPORT 5969 if (SOC_IS_TOMAHAWK3(unit)) { 5970 return BCM_E_UNAVAIL; 5971 } 5972 #endif 5973 5974 CHECK_INIT(unit); 5975 /* BCM_VLAN_INVALID is valid input for this API */ 5976 if (BCM_VLAN_INVALID != outer_vlan_low) 5977 VLAN_CHK_ID(unit, outer_vlan_low); 5978 if (BCM_VLAN_INVALID != outer_vlan_high) 5979 VLAN_CHK_ID(unit, outer_vlan_high); 5980 if (BCM_VLAN_INVALID != inner_vlan_low) 5981 VLAN_CHK_ID(unit, inner_vlan_low); 5982 if (BCM_VLAN_INVALID != inner_vlan_high) 5983 VLAN_CHK_ID(unit, inner_vlan_high); 5984 if (NULL == action) 5985 return BCM_E_PARAM; 5986 5987 if (port == BCM_GPORT_INVALID) 5988 return BCM_E_PORT; 5989 5990 #ifdef BCM_TRX_SUPPORT 5991 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 5992 return _bcm_trx_vlan_translate_action_range_add(unit, port, 5993 outer_vlan_low, outer_vlan_high, 5994 inner_vlan_low, inner_vlan_high, 5995 action); 5996 } 5997 #endif /* BCM_TRX_SUPPORT */ 5998 return BCM_E_UNAVAIL; 5999 } 6000 6001 6002 /* 6003 * Function : 6004 * bcm_esw_vlan_translate_action_range_get 6005 * Description : 6006 * Get an entry to the VLAN Translation table, which assigns 6007 * VLAN actions for packets matching within the VLAN range(s). 6008 * Parameters : 6009 * unit (IN) BCM unit number 6010 * port (IN) Ingress gport (generic port) 6011 * outer_vlan_low (IN) Outer VLAN ID Low 6012 * outer_vlan_high (IN) Outer VLAN ID High 6013 * inner_vlan_low (IN) Inner VLAN ID Low 6014 * inner_vlan_high (IN) Inner VLAN ID High 6015 * action (OUT) Action for outer and inner tag 6016 * 6017 * Notes : 6018 * For translation of double-tagged packets, specify a valid 6019 * VLAN ID value for outer_vlan_low/high and inner_vlan_low/high. 6020 * For translation of single outer-tagged packets, specify a 6021 * valid VLAN ID for outer_vlan_low/high and BCM_VLAN_INVALID 6022 * for inner_vlan_low/high. For translation of single inner-tagged 6023 * packets, specify a valid VLAN ID for inner_vlan_low/high and 6024 * BCM_VLAN_INVALID for outer_vlan_low/high. 6025 */ 6026 int 6027 bcm_esw_vlan_translate_action_range_get (int unit, bcm_gport_t port, 6028 bcm_vlan_t outer_vlan_low, 6029 bcm_vlan_t outer_vlan_high, 6030 bcm_vlan_t inner_vlan_low, 6031 bcm_vlan_t inner_vlan_high, 6032 bcm_vlan_action_set_t *action) 6033 { 6034 #ifdef BCM_TOMAHAWK3_SUPPORT 6035 if (SOC_IS_TOMAHAWK3(unit)) { 6036 return BCM_E_UNAVAIL; 6037 } 6038 #endif 6039 6040 CHECK_INIT(unit); 6041 /* BCM_VLAN_INVALID is valid input for this API */ 6042 if (BCM_VLAN_INVALID != outer_vlan_low) 6043 VLAN_CHK_ID(unit, outer_vlan_low); 6044 if (BCM_VLAN_INVALID != outer_vlan_high) 6045 VLAN_CHK_ID(unit, outer_vlan_high); 6046 if (BCM_VLAN_INVALID != inner_vlan_low) 6047 VLAN_CHK_ID(unit, inner_vlan_low); 6048 if (BCM_VLAN_INVALID != inner_vlan_high) 6049 VLAN_CHK_ID(unit, inner_vlan_high); 6050 if (NULL == action) 6051 return BCM_E_PARAM; 6052 6053 if (port == BCM_GPORT_INVALID) 6054 return BCM_E_PORT; 6055 6056 #ifdef BCM_TRX_SUPPORT 6057 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 6058 bcm_vlan_action_set_t_init(action); 6059 return _bcm_trx_vlan_translate_action_range_get(unit, port, 6060 outer_vlan_low, outer_vlan_high, 6061 inner_vlan_low, inner_vlan_high, 6062 action); 6063 } 6064 #endif /* BCM_TRX_SUPPORT */ 6065 return BCM_E_UNAVAIL; 6066 } 6067 6068 /* 6069 * Function : 6070 * bcm_vlan_translate_action_range_delete 6071 * Description : 6072 * Delete an entry from the VLAN Translation table for the 6073 * specified VLAN range(s). 6074 * Parameters : 6075 * unit (IN) BCM unit number 6076 * port (IN) Ingress gport (generic port) 6077 * outer_vlan_low (IN) Outer VLAN ID Low 6078 * outer_vlan_high (IN) Outer VLAN ID High 6079 * inner_vlan_low (IN) Inner VLAN ID Low 6080 * inner_vlan_high (IN) Inner VLAN ID High 6081 * 6082 * Notes : 6083 * For translation of double-tagged packets, specify a valid 6084 * VLAN ID value for outer_vlan_low/high and inner_vlan_low/high. 6085 * For translation of single outer-tagged packets, specify a 6086 * valid VLAN ID for outer_vlan_low/high and BCM_VLAN_INVALID 6087 * for inner_vlan_low/high. For translation of single inner-tagged 6088 * packets, specify a valid VLAN ID for inner_vlan_low/high and 6089 * BCM_VLAN_INVALID for outer_vlan_low/high. 6090 */ 6091 6092 int 6093 bcm_esw_vlan_translate_action_range_delete(int unit, bcm_gport_t port, 6094 bcm_vlan_t outer_vlan_low, 6095 bcm_vlan_t outer_vlan_high, 6096 bcm_vlan_t inner_vlan_low, 6097 bcm_vlan_t inner_vlan_high) 6098 { 6099 #ifdef BCM_TOMAHAWK3_SUPPORT 6100 if (SOC_IS_TOMAHAWK3(unit)) { 6101 return BCM_E_UNAVAIL; 6102 } 6103 #endif 6104 6105 CHECK_INIT(unit); 6106 /* BCM_VLAN_INVALID is valid input for this API */ 6107 if (BCM_VLAN_INVALID != outer_vlan_low) 6108 VLAN_CHK_ID(unit, outer_vlan_low); 6109 if (BCM_VLAN_INVALID != outer_vlan_high) 6110 VLAN_CHK_ID(unit, outer_vlan_high); 6111 if (BCM_VLAN_INVALID != inner_vlan_low) 6112 VLAN_CHK_ID(unit, inner_vlan_low); 6113 if (BCM_VLAN_INVALID != inner_vlan_high) 6114 VLAN_CHK_ID(unit, inner_vlan_high); 6115 6116 if (port == BCM_GPORT_INVALID) 6117 return BCM_E_PORT; 6118 6119 #ifdef BCM_TRX_SUPPORT 6120 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 6121 return _bcm_trx_vlan_translate_action_range_delete(unit, port, 6122 outer_vlan_low, outer_vlan_high, 6123 inner_vlan_low, inner_vlan_high); 6124 } 6125 #endif /* BCM_TRX_SUPPORT */ 6126 return BCM_E_UNAVAIL; 6127 } 6128 6129 /* 6130 * Function : 6131 * bcm_vlan_translate_action_range_delete_all 6132 * Description : 6133 * Delete all VLAN range entries from the VLAN Translation table. 6134 * Parameters : 6135 * unit (IN) BCM unit number 6136 */ 6137 6138 int 6139 bcm_esw_vlan_translate_action_range_delete_all(int unit) 6140 { 6141 #ifdef BCM_TOMAHAWK3_SUPPORT 6142 if (SOC_IS_TOMAHAWK3(unit)) { 6143 return BCM_E_UNAVAIL; 6144 } 6145 #endif 6146 6147 CHECK_INIT(unit); 6148 6149 #ifdef BCM_TRX_SUPPORT 6150 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 6151 return _bcm_trx_vlan_translate_action_range_delete_all(unit); 6152 } 6153 #endif /* BCM_TRX_SUPPORT */ 6154 return BCM_E_UNAVAIL; 6155 } 6156 6157 6158 /* 6159 * Function : 6160 * bcm_vlan_translate_action_range_traverse 6161 * Description : 6162 * Traverses over VLAN Translation table and call provided callback 6163 * with valid entries. 6164 * Parameters : 6165 * unit (IN) BCM unit number 6166 * cb (IN) User callback function 6167 * user_data (IN) Pointer to user specific data 6168 * Return: 6169 * 6170 * BCM_E_XXX 6171 */ 6172 int 6173 bcm_esw_vlan_translate_action_range_traverse(int unit, 6174 bcm_vlan_translate_action_range_traverse_cb cb, void *user_data) 6175 { 6176 _bcm_vlan_translate_traverse_t trvs_st; 6177 bcm_vlan_action_set_t action; 6178 _translate_action_range_traverse_cb_t usr_cb_st; 6179 6180 if (!soc_feature(unit, soc_feature_vlan_translation_range)) { 6181 return BCM_E_UNAVAIL; 6182 } 6183 if (!cb) { 6184 return (BCM_E_PARAM); 6185 } 6186 6187 sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t)); 6188 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 6189 sal_memset(&usr_cb_st, 0, sizeof(_translate_action_range_traverse_cb_t)); 6190 6191 usr_cb_st.usr_cb = cb; 6192 6193 trvs_st.user_data = user_data; 6194 trvs_st.action = &action; 6195 trvs_st.user_cb_st = (void *)&usr_cb_st; 6196 trvs_st.int_cb = _bcm_esw_vlan_translate_action_range_traverse_int_cb; 6197 6198 #if defined(BCM_TRX_SUPPORT) 6199 if (SOC_IS_TRX(unit)) { 6200 return _bcm_trx_vlan_translate_action_range_traverse(unit, &trvs_st); 6201 } 6202 #endif /* BCM_TRX_SUPPORT */ 6203 6204 return BCM_E_UNAVAIL; 6205 } 6206 6207 6208 /* 6209 * Function : 6210 * bcm_vlan_translate_range_traverse 6211 * Description : 6212 * Traverses over VLAN translate table and call provided callback 6213 * with valid entries. 6214 * Parameters : 6215 * unit (IN) BCM unit number 6216 * cb (IN) User callback function 6217 * user_data (IN) Pointer to user specific data 6218 * Return: 6219 * 6220 * BCM_E_XXX 6221 */ 6222 int 6223 bcm_esw_vlan_translate_range_traverse(int unit, 6224 bcm_vlan_translate_range_traverse_cb cb, 6225 void *user_data) 6226 { 6227 6228 _bcm_vlan_translate_traverse_t trvs_st; 6229 bcm_vlan_action_set_t action; 6230 _translate_range_traverse_cb_t usr_cb_st; 6231 6232 if (!soc_feature(unit, soc_feature_vlan_translation_range)) { 6233 return BCM_E_UNAVAIL; 6234 } 6235 if (!cb) { 6236 return (BCM_E_PARAM); 6237 } 6238 6239 sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t)); 6240 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 6241 sal_memset(&usr_cb_st, 0, sizeof(_translate_range_traverse_cb_t)); 6242 6243 usr_cb_st.usr_cb = cb; 6244 6245 trvs_st.user_data = user_data; 6246 trvs_st.action = &action; 6247 trvs_st.user_cb_st = (void *)&usr_cb_st; 6248 6249 6250 #if defined(BCM_TRX_SUPPORT) 6251 if (SOC_IS_TRX(unit)) { 6252 trvs_st.int_cb = _bcm_esw_vlan_translate_range_traverse_int_cb; 6253 return _bcm_trx_vlan_translate_action_range_traverse(unit, &trvs_st); 6254 } 6255 #endif /* BCM_TRX_SUPPORT */ 6256 6257 return BCM_E_UNAVAIL; 6258 } 6259 6260 /* 6261 * Function : 6262 * bcm_vlan_dtag_range_traverse 6263 * Description : 6264 * Traverses over VLAN double tagging table and call provided callback 6265 * with valid entries. 6266 * Parameters : 6267 * unit (IN) BCM unit number 6268 * cb (IN) User callback function 6269 * user_data (IN) Pointer to user specific data 6270 * Return: 6271 * 6272 * BCM_E_XXX 6273 */ 6274 int 6275 bcm_esw_vlan_dtag_range_traverse(int unit, bcm_vlan_dtag_range_traverse_cb cb, 6276 void *user_data) 6277 { 6278 6279 _bcm_vlan_translate_traverse_t trvs_st; 6280 bcm_vlan_action_set_t action; 6281 _dtag_range_traverse_cb_t usr_cb_st; 6282 6283 if (!soc_feature(unit, soc_feature_vlan_translation_range)) { 6284 return BCM_E_UNAVAIL; 6285 } 6286 if (!cb) { 6287 return (BCM_E_PARAM); 6288 } 6289 6290 sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t)); 6291 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 6292 sal_memset(&usr_cb_st, 0, sizeof(_dtag_range_traverse_cb_t)); 6293 6294 usr_cb_st.usr_cb = cb; 6295 6296 trvs_st.user_data = user_data; 6297 trvs_st.action = &action; 6298 trvs_st.user_cb_st = (void *)&usr_cb_st; 6299 6300 #if defined(BCM_TRX_SUPPORT) 6301 trvs_st.int_cb = _bcm_esw_vlan_dtag_range_traverse_int_cb; 6302 if (SOC_IS_TRX(unit)) { 6303 return _bcm_trx_vlan_translate_action_range_traverse(unit, &trvs_st); 6304 } 6305 #endif /* BCM_TRX_SUPPORT */ 6306 6307 return BCM_E_UNAVAIL; 6308 } 6309 6310 6311 int 6312 bcm_esw_vlan_translate_egress_add(int unit, int port, bcm_vlan_t old_vid, 6313 bcm_vlan_t new_vid, int prio) 6314 { 6315 6316 bcm_module_t modid = -1; 6317 bcm_trunk_t tgid = -1; 6318 int id = -1; 6319 6320 #ifdef BCM_TOMAHAWK3_SUPPORT 6321 if (SOC_IS_TOMAHAWK3(unit)) { 6322 return BCM_E_UNAVAIL; 6323 } 6324 #endif 6325 6326 CHECK_INIT(unit); 6327 VLAN_CHK_ID(unit, old_vid); 6328 VLAN_CHK_ID(unit, new_vid); 6329 6330 /* XGS does not support translation of VLAN ID 0 */ 6331 if (old_vid == 0) { 6332 return BCM_E_PARAM; 6333 } 6334 6335 if (BCM_GPORT_IS_SET(port)) { 6336 if (!BCM_GPORT_IS_TUNNEL(port)) { 6337 BCM_IF_ERROR_RETURN( 6338 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 6339 } 6340 if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port)) { 6341 return BCM_E_PORT; 6342 } 6343 } else { 6344 if (SOC_IS_RAVEN(unit)) { 6345 if (port != -1) { 6346 if (!SOC_PORT_VALID(unit, port)) { 6347 return BCM_E_PORT; 6348 } 6349 } 6350 } else { 6351 if (!SOC_PORT_VALID(unit, port)) { 6352 return BCM_E_PORT; 6353 } 6354 } 6355 BCM_IF_ERROR_RETURN( 6356 bcm_esw_stk_my_modid_get(unit, &modid)); 6357 } 6358 6359 #ifdef BCM_TRX_SUPPORT 6360 if (SOC_IS_TRX(unit)) { 6361 bcm_vlan_action_set_t action; 6362 soc_control_t *sc = SOC_CONTROL(unit); 6363 bcm_vlan_info_t *vi = &vlan_info[unit]; 6364 int rv = BCM_E_NONE; 6365 6366 if (!soc_feature(unit, soc_feature_vlan_action)) { 6367 return BCM_E_UNAVAIL; 6368 } 6369 6370 /* If port class is changed system should not allow */ 6371 /* To use this API since it leads to confused outcome */ 6372 if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) { 6373 return BCM_E_CONFIG; 6374 } 6375 6376 bcm_vlan_action_set_t_init(&action); 6377 action.new_outer_vlan = new_vid; 6378 action.new_inner_vlan = 0; 6379 action.priority = prio; 6380 action.ot_outer = bcmVlanActionReplace; 6381 action.dt_outer = bcmVlanActionReplace; 6382 6383 rv = _bcm_trx_vlan_translate_egress_action_add(unit, port, 6384 old_vid, 0, 6385 &action); 6386 /* In case of usage of this API on Triumph and newer devices */ 6387 /* port parameter is pretended to be a port_class therefore */ 6388 /* port_class will remain unchanged as long as there are entries */ 6389 /* in egress vlan translation table added using this API */ 6390 if (BCM_SUCCESS(rv)) { 6391 sc->soc_flags |= SOC_F_PORT_CLASS_BLOCKED; 6392 vi->old_egr_xlate_cnt++; 6393 #ifdef BCM_WARM_BOOT_SUPPORT 6394 SOC_CONTROL_LOCK(unit); 6395 SOC_CONTROL(unit)->scache_dirty = 1; 6396 SOC_CONTROL_UNLOCK(unit); 6397 #endif 6398 } 6399 6400 return rv; 6401 } 6402 #endif /* BCM_TRX_SUPPORT */ 6403 6404 6405 #ifdef BCM_FIREBOLT_SUPPORT 6406 if (SOC_IS_FBX(unit)) { 6407 return _bcm_fb_vlan_translate_add(unit, port, old_vid, new_vid, prio, 6408 BCM_VLAN_XLATE_EGR); 6409 } 6410 #endif 6411 6412 return BCM_E_UNAVAIL; 6413 } 6414 6415 6416 /* 6417 * Function: 6418 * bcm_vlan_translate_egress_get 6419 * Purpose: 6420 * Get vlan egress translation 6421 * Parameters: 6422 * unit - StrataSwitch PCI device unit number (driver internal). 6423 * port - port numebr 6424 * old_vid - Old VLAN ID to has translation for 6425 * new_vid - New VLAN ID that packet will get 6426 * prio - Priority 6427 * Returns: 6428 * BCM_E_NONE - Translation found, new_vid nad prio will have the values. 6429 * BCM_E_NOT_FOUND - Translation does not exist 6430 * BCM_E_XXX - Other error 6431 * Notes: 6432 * None. 6433 */ 6434 int bcm_esw_vlan_translate_egress_get (int unit, bcm_port_t port, 6435 bcm_vlan_t old_vid, 6436 bcm_vlan_t *new_vid, 6437 int *prio) 6438 { 6439 bcm_module_t modid; 6440 bcm_trunk_t tgid = -1; 6441 int id = -1; 6442 6443 #ifdef BCM_TOMAHAWK3_SUPPORT 6444 if (SOC_IS_TOMAHAWK3(unit)) { 6445 return BCM_E_UNAVAIL; 6446 } 6447 #endif 6448 6449 CHECK_INIT(unit); 6450 VLAN_CHK_ID(unit, old_vid); 6451 6452 /* XGS does not support translation of VLAN ID 0 */ 6453 if (old_vid == 0) { 6454 return BCM_E_PARAM; 6455 } 6456 6457 if ((NULL == new_vid) ||(NULL == prio)){ 6458 return BCM_E_PARAM; 6459 } 6460 6461 if (BCM_GPORT_IS_SET(port)) { 6462 if (!BCM_GPORT_IS_TUNNEL(port)) { 6463 BCM_IF_ERROR_RETURN( 6464 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 6465 } 6466 if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port)) { 6467 return BCM_E_PORT; 6468 } 6469 } else { 6470 if (!SOC_PORT_VALID(unit, port)) { 6471 return BCM_E_PORT; 6472 } 6473 BCM_IF_ERROR_RETURN( 6474 bcm_esw_stk_my_modid_get(unit, &modid)); 6475 } 6476 6477 #ifdef BCM_TRX_SUPPORT 6478 if (SOC_IS_TRX(unit)) { 6479 bcm_vlan_action_set_t action; 6480 soc_control_t *sc = SOC_CONTROL(unit); 6481 6482 if (!soc_feature(unit, soc_feature_vlan_action)) { 6483 return BCM_E_UNAVAIL; 6484 } 6485 6486 /* If port class is changed system should not allow */ 6487 /* To use this API since it leads to confused outcome */ 6488 if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) { 6489 return BCM_E_CONFIG; 6490 } 6491 6492 bcm_vlan_action_set_t_init(&action); 6493 BCM_IF_ERROR_RETURN( 6494 _bcm_trx_vlan_translate_egress_action_get(unit, port, old_vid, 6495 0, &action)); 6496 *new_vid = action.new_outer_vlan; 6497 *prio = action.priority; 6498 6499 return BCM_E_NONE; 6500 } 6501 #endif /* BCM_TRX_SUPPORT */ 6502 6503 #ifdef BCM_FIREBOLT_SUPPORT 6504 if (SOC_IS_FBX(unit)) { 6505 return _bcm_fb_vlan_translate_get(unit, port, old_vid, new_vid, 6506 prio, BCM_VLAN_XLATE_EGR); 6507 } 6508 #endif 6509 6510 return BCM_E_UNAVAIL; 6511 } 6512 6513 int 6514 bcm_esw_vlan_translate_egress_delete(int unit, int port, bcm_vlan_t old_vid) 6515 { 6516 bcm_module_t modid; 6517 bcm_trunk_t tgid = -1; 6518 int id = -1; 6519 6520 #ifdef BCM_TOMAHAWK3_SUPPORT 6521 if (SOC_IS_TOMAHAWK3(unit)) { 6522 return BCM_E_UNAVAIL; 6523 } 6524 #endif 6525 6526 CHECK_INIT(unit); 6527 VLAN_CHK_ID(unit, old_vid); 6528 6529 if (BCM_GPORT_IS_SET(port)) { 6530 if (!BCM_GPORT_IS_TUNNEL(port)) { 6531 BCM_IF_ERROR_RETURN( 6532 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 6533 } 6534 if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port)) { 6535 return BCM_E_PORT; 6536 } 6537 } else { 6538 if (SOC_IS_RAVEN(unit)) { 6539 if (port != -1) { 6540 if (!SOC_PORT_VALID(unit, port)) { 6541 return BCM_E_PORT; 6542 } 6543 } 6544 } else { 6545 if (!SOC_PORT_VALID(unit, port)) { 6546 return BCM_E_PORT; 6547 } 6548 } 6549 BCM_IF_ERROR_RETURN( 6550 bcm_esw_stk_my_modid_get(unit, &modid)); 6551 } 6552 6553 #ifdef BCM_TRX_SUPPORT 6554 if (SOC_IS_TRX(unit)) { 6555 6556 /* XGS does not support translation of VLAN ID 0 */ 6557 if (old_vid == 0) { 6558 return BCM_E_PARAM; 6559 } 6560 6561 if (!soc_feature(unit, soc_feature_vlan_action)) { 6562 return BCM_E_UNAVAIL; 6563 } else { 6564 soc_control_t *sc = SOC_CONTROL(unit); 6565 bcm_vlan_info_t *vi = &vlan_info[unit]; 6566 int rv = BCM_E_NONE; 6567 6568 /* If port class is changed system should not allow */ 6569 /* To use this API since it leads to confused outcome */ 6570 if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) { 6571 return BCM_E_CONFIG; 6572 } 6573 6574 rv = _bcm_trx_vlan_translate_egress_action_delete(unit, port, 6575 old_vid, 0); 6576 6577 /* In case of usage of this API on Triumph and newer devices */ 6578 /* port parameter is pretended to be a port_class therefore */ 6579 /* port_class operation will be permited only when last entry */ 6580 /* in egress vlan translation table removed using this API */ 6581 if (BCM_SUCCESS(rv)) { 6582 vi->old_egr_xlate_cnt--; 6583 #ifdef BCM_WARM_BOOT_SUPPORT 6584 SOC_CONTROL_LOCK(unit); 6585 SOC_CONTROL(unit)->scache_dirty = 1; 6586 SOC_CONTROL_UNLOCK(unit); 6587 #endif 6588 if (0 == vi->old_egr_xlate_cnt) { 6589 sc->soc_flags &= ~SOC_F_PORT_CLASS_BLOCKED; 6590 } 6591 } 6592 return rv; 6593 } 6594 } 6595 #endif /* BCM_TRX_SUPPORT */ 6596 6597 #ifdef BCM_FIREBOLT_SUPPORT 6598 if (SOC_IS_FBX(unit)) { 6599 return _bcm_fb_vlan_translate_delete(unit, port, old_vid, 6600 BCM_VLAN_XLATE_EGR); 6601 } 6602 #endif 6603 6604 return BCM_E_UNAVAIL; 6605 } 6606 6607 int 6608 bcm_esw_vlan_translate_egress_delete_all(int unit) 6609 { 6610 #ifdef BCM_TOMAHAWK3_SUPPORT 6611 if (SOC_IS_TOMAHAWK3(unit)) { 6612 return BCM_E_UNAVAIL; 6613 } 6614 #endif 6615 #ifdef BCM_TRX_SUPPORT 6616 if (SOC_IS_TRX(unit)) { 6617 if (!soc_feature(unit, soc_feature_vlan_action)) { 6618 return BCM_E_UNAVAIL; 6619 } else { 6620 soc_control_t *sc = SOC_CONTROL(unit); 6621 bcm_vlan_info_t *vi = &vlan_info[unit]; 6622 int rv = BCM_E_NONE; 6623 6624 /* If port class is changed system should not allow */ 6625 /* To use this API since it leads to confused outcome */ 6626 if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) { 6627 return BCM_E_CONFIG; 6628 } 6629 6630 rv = _bcm_trx_vlan_translate_egress_action_delete_all(unit); 6631 6632 /* In case of usage of this API on Triumph and newer devices */ 6633 /* port parameter is pretended to be a port_class therefore */ 6634 /* port_class operation will be permited when all entries */ 6635 /* in egress vlan translation table removed using this API */ 6636 if (BCM_SUCCESS(rv)) { 6637 sc->soc_flags &= ~SOC_F_PORT_CLASS_BLOCKED; 6638 vi->old_egr_xlate_cnt = 0; 6639 #ifdef BCM_WARM_BOOT_SUPPORT 6640 SOC_CONTROL_LOCK(unit); 6641 SOC_CONTROL(unit)->scache_dirty = 1; 6642 SOC_CONTROL_UNLOCK(unit); 6643 #endif 6644 } 6645 return rv; 6646 } 6647 } 6648 #endif /* BCM_TRX_SUPPORT */ 6649 6650 #ifdef BCM_FIREBOLT_SUPPORT 6651 if (SOC_IS_FBX(unit)) { 6652 int rv; 6653 rv = _bcm_fb_vlan_translate_delete(unit, -1, BCM_VLAN_NONE, 6654 BCM_VLAN_XLATE_EGR); 6655 if (BCM_SUCCESS(rv) || (rv == BCM_E_NOT_FOUND)) { 6656 return BCM_E_NONE; 6657 } 6658 6659 return rv; 6660 } 6661 #endif 6662 6663 return BCM_E_UNAVAIL; 6664 } 6665 6666 /* 6667 * Function : 6668 * _bcm_esw_vlan_translate_egress_action_add 6669 * Description : 6670 * Helper function to converge the two APIs 6671 * bcm_vlan_translate_egress_action_add and 6672 * bcm_vlan_translate_egress_gport_action_add 6673 * Parameters : 6674 * unit (IN) BCM unit number 6675 * port_class (IN) Group ID of ingress port 6676 * outer_vlan (IN) Packet outer VLAN ID 6677 * inner_vlan (IN) Packet inner VLAN ID 6678 * action (IN) Action for outer and inner tag 6679 */ 6680 static int 6681 _bcm_esw_vlan_translate_egress_action_add(int unit, int port_class, 6682 bcm_vlan_t outer_vlan, 6683 bcm_vlan_t inner_vlan, 6684 bcm_vlan_action_set_t *action, 6685 int handle_modport_gport) 6686 { 6687 bcm_module_t modid; 6688 bcm_trunk_t tgid = -1; 6689 int id = -1; 6690 6691 CHECK_INIT(unit); 6692 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 6693 if (soc_feature(unit, soc_feature_vp_sharing)) { 6694 int num_vfi = 0; 6695 bcm_vpn_t vpn_min = 0, vpn_max = 0; 6696 if (outer_vlan > BCM_VLAN_MAX) { 6697 num_vfi = soc_mem_index_count(unit, VFIm); 6698 _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0); 6699 vpn_max = vpn_min + num_vfi - 1; 6700 if (outer_vlan > vpn_max) { 6701 return (BCM_E_PARAM); 6702 } else if ((outer_vlan >= vpn_min) && 6703 (outer_vlan <= vpn_max)) { 6704 if (inner_vlan != BCM_VLAN_INVALID) { 6705 return BCM_E_PARAM; 6706 } 6707 } else { 6708 return BCM_E_PARAM; 6709 } 6710 } else { 6711 VLAN_CHK_ID(unit, inner_vlan); 6712 } 6713 } else 6714 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 6715 { 6716 VLAN_CHK_ID(unit, outer_vlan); 6717 VLAN_CHK_ID(unit, inner_vlan); 6718 } 6719 6720 if (NULL == action) { 6721 return BCM_E_PARAM; 6722 } 6723 6724 if (BCM_GPORT_IS_SET(port_class)) { 6725 if (!BCM_GPORT_IS_TUNNEL(port_class) && 6726 !BCM_GPORT_IS_MIM_PORT(port_class) && 6727 !BCM_GPORT_IS_NIV_PORT(port_class) && 6728 !BCM_GPORT_IS_MPLS_PORT(port_class) && 6729 !BCM_GPORT_IS_VLAN_PORT(port_class) && 6730 !BCM_GPORT_IS_VXLAN_PORT(port_class) && 6731 !BCM_GPORT_IS_EXTENDER_PORT(port_class) && 6732 !BCM_GPORT_IS_L2GRE_PORT(port_class) && 6733 !(handle_modport_gport && 6734 (BCM_GPORT_IS_MODPORT(port_class) || 6735 BCM_GPORT_IS_SUBPORT_PORT(port_class)))) 6736 { 6737 BCM_IF_ERROR_RETURN( 6738 _bcm_esw_gport_resolve(unit, port_class, &modid, &port_class, 6739 &tgid, &id)); 6740 } 6741 if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port_class) && 6742 !BCM_GPORT_IS_MIM_PORT(port_class) && 6743 !BCM_GPORT_IS_NIV_PORT(port_class) && 6744 !BCM_GPORT_IS_MPLS_PORT(port_class) && 6745 !BCM_GPORT_IS_VLAN_PORT(port_class) && 6746 !BCM_GPORT_IS_EXTENDER_PORT(port_class) && 6747 !BCM_GPORT_IS_VXLAN_PORT(port_class) && 6748 !BCM_GPORT_IS_L2GRE_PORT(port_class)) 6749 { 6750 return BCM_E_PORT; 6751 } 6752 } else 6753 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 6754 if (inner_vlan == BCM_VLAN_INVALID) { 6755 BCM_IF_ERROR_RETURN 6756 (bcm_td2p_dvp_group_validate(unit, port_class)); 6757 } else 6758 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 6759 { 6760 if (!SOC_PORT_CLASS_VALID(unit, port_class)) { 6761 return BCM_E_PORT; 6762 } 6763 } 6764 6765 #ifdef BCM_TRX_SUPPORT 6766 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 6767 return _bcm_trx_vlan_translate_egress_action_add(unit, port_class, 6768 outer_vlan, inner_vlan, 6769 action); 6770 } 6771 #endif /* BCM_TRX_SUPPORT */ 6772 6773 return BCM_E_UNAVAIL; 6774 } 6775 6776 /* 6777 * Function : 6778 * _bcm_esw_vlan_translate_egress_action_get 6779 * Description : 6780 * Helper function to converge the APIs 6781 * bcm_vlan_translate_egress_action_get and 6782 * bcm_vlan_translate_egress_gport_action_get 6783 * Parameters : 6784 * unit (IN) BCM unit number 6785 * port_class (IN) Group ID of ingress port 6786 * outer_vlan (IN) Packet outer VLAN ID 6787 * inner_vlan (IN) Packet inner VLAN ID 6788 * action (OUT) Action for outer and inner tag 6789 */ 6790 static int 6791 _bcm_esw_vlan_translate_egress_action_get (int unit, int port_class, 6792 bcm_vlan_t outer_vlan, 6793 bcm_vlan_t inner_vlan, 6794 bcm_vlan_action_set_t *action, 6795 int handle_modport_gport) 6796 { 6797 bcm_module_t modid; 6798 bcm_trunk_t tgid = -1; 6799 int id = -1; 6800 6801 CHECK_INIT(unit); 6802 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 6803 if (soc_feature(unit, soc_feature_vp_sharing)) { 6804 int num_vfi = 0; 6805 bcm_vpn_t vpn_min = 0, vpn_max = 0; 6806 if (outer_vlan > BCM_VLAN_MAX) { 6807 num_vfi = soc_mem_index_count(unit, VFIm); 6808 _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0); 6809 vpn_max = vpn_min + num_vfi - 1; 6810 if (outer_vlan > vpn_max) { 6811 return (BCM_E_PARAM); 6812 } else if ((outer_vlan >= vpn_min) && 6813 (outer_vlan <= vpn_max)) { 6814 if (inner_vlan != BCM_VLAN_INVALID) { 6815 return BCM_E_PARAM; 6816 } 6817 } else { 6818 return BCM_E_PARAM; 6819 } 6820 } else { 6821 VLAN_CHK_ID(unit, inner_vlan); 6822 } 6823 } else 6824 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 6825 { 6826 VLAN_CHK_ID(unit, outer_vlan); 6827 VLAN_CHK_ID(unit, inner_vlan); 6828 } 6829 6830 if (NULL == action) { 6831 return BCM_E_PARAM; 6832 } 6833 6834 if (BCM_GPORT_IS_SET(port_class)) { 6835 if (!BCM_GPORT_IS_TUNNEL(port_class) && 6836 !BCM_GPORT_IS_MIM_PORT(port_class) && 6837 !BCM_GPORT_IS_NIV_PORT(port_class) && 6838 !BCM_GPORT_IS_MPLS_PORT(port_class) && 6839 !BCM_GPORT_IS_VLAN_PORT(port_class) && 6840 !BCM_GPORT_IS_VXLAN_PORT(port_class) && 6841 !BCM_GPORT_IS_EXTENDER_PORT(port_class) && 6842 !BCM_GPORT_IS_L2GRE_PORT(port_class) && 6843 !(handle_modport_gport && 6844 (BCM_GPORT_IS_MODPORT(port_class) || 6845 BCM_GPORT_IS_SUBPORT_PORT(port_class)))) 6846 { 6847 BCM_IF_ERROR_RETURN( 6848 _bcm_esw_gport_resolve(unit, port_class, &modid, &port_class, 6849 &tgid, &id)); 6850 } 6851 if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port_class) && 6852 !BCM_GPORT_IS_MIM_PORT(port_class) && 6853 !BCM_GPORT_IS_NIV_PORT(port_class) && 6854 !BCM_GPORT_IS_EXTENDER_PORT(port_class) && 6855 !BCM_GPORT_IS_MPLS_PORT(port_class) && 6856 !BCM_GPORT_IS_VLAN_PORT(port_class) && 6857 !BCM_GPORT_IS_VXLAN_PORT(port_class) && 6858 !BCM_GPORT_IS_L2GRE_PORT(port_class)) 6859 { 6860 return BCM_E_PORT; 6861 } 6862 } else { 6863 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 6864 if (inner_vlan == BCM_VLAN_INVALID) { 6865 BCM_IF_ERROR_RETURN 6866 (bcm_td2p_dvp_group_validate(unit, port_class)); 6867 } else 6868 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 6869 if (!SOC_PORT_CLASS_VALID(unit, port_class)) { 6870 return BCM_E_PORT; 6871 } 6872 } 6873 6874 #ifdef BCM_TRX_SUPPORT 6875 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 6876 return _bcm_trx_vlan_translate_egress_action_get(unit, port_class, 6877 outer_vlan, inner_vlan, 6878 action); 6879 } 6880 #endif /* BCM_TRX_SUPPORT */ 6881 6882 return BCM_E_UNAVAIL; 6883 } 6884 6885 /* 6886 * Function: 6887 * _bcm_esw_vlan_translate_egress_action_delete 6888 * Purpose: 6889 * Helper function to converge the APIs 6890 * bcm_vlan_translate_egress_action_delete and 6891 * bcm_vlan_translate_egress_gport_action_delete 6892 * Parameters: 6893 * unit (IN) BCM unit number 6894 * port_class (IN) Group ID of ingress port 6895 * outer_vlan (IN) Packet outer VLAN ID 6896 * inner_vlan (IN) Packet inner VLAN ID 6897 */ 6898 int 6899 _bcm_esw_vlan_translate_egress_action_delete(int unit, int port_class, 6900 bcm_vlan_t outer_vlan, 6901 bcm_vlan_t inner_vlan, 6902 int handle_modport_gport) 6903 { 6904 bcm_module_t modid; 6905 bcm_trunk_t tgid = -1; 6906 int id = -1; 6907 6908 CHECK_INIT(unit); 6909 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 6910 if (soc_feature(unit, soc_feature_vp_sharing)) { 6911 int num_vfi = 0; 6912 bcm_vpn_t vpn_min = 0, vpn_max = 0; 6913 if (outer_vlan > BCM_VLAN_MAX) { 6914 num_vfi = soc_mem_index_count(unit, VFIm); 6915 _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0); 6916 vpn_max = vpn_min + num_vfi - 1; 6917 if (outer_vlan > vpn_max) { 6918 return (BCM_E_PARAM); 6919 } else if ((outer_vlan >= vpn_min) && 6920 (outer_vlan <= vpn_max)) { 6921 if (inner_vlan != BCM_VLAN_INVALID) { 6922 return BCM_E_PARAM; 6923 } 6924 } else { 6925 return BCM_E_PARAM; 6926 } 6927 } else { 6928 VLAN_CHK_ID(unit, inner_vlan); 6929 } 6930 } else 6931 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 6932 { 6933 VLAN_CHK_ID(unit, outer_vlan); 6934 VLAN_CHK_ID(unit, inner_vlan); 6935 } 6936 6937 if (BCM_GPORT_IS_SET(port_class)) { 6938 if (!BCM_GPORT_IS_TUNNEL(port_class) && 6939 !BCM_GPORT_IS_MIM_PORT(port_class) && 6940 !BCM_GPORT_IS_NIV_PORT(port_class) && 6941 !BCM_GPORT_IS_EXTENDER_PORT(port_class) && 6942 !BCM_GPORT_IS_MPLS_PORT(port_class) && 6943 !BCM_GPORT_IS_VLAN_PORT(port_class) && 6944 !BCM_GPORT_IS_VXLAN_PORT(port_class) && 6945 !BCM_GPORT_IS_L2GRE_PORT(port_class) && 6946 !(handle_modport_gport && 6947 (BCM_GPORT_IS_MODPORT(port_class) || 6948 BCM_GPORT_IS_SUBPORT_PORT(port_class)))) 6949 { 6950 BCM_IF_ERROR_RETURN( 6951 _bcm_esw_gport_resolve(unit, port_class, &modid, &port_class, 6952 &tgid, &id)); 6953 } 6954 if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port_class) && 6955 !BCM_GPORT_IS_MIM_PORT(port_class) && 6956 !BCM_GPORT_IS_NIV_PORT(port_class) && 6957 !BCM_GPORT_IS_EXTENDER_PORT(port_class) && 6958 !BCM_GPORT_IS_MPLS_PORT(port_class) && 6959 !BCM_GPORT_IS_VLAN_PORT(port_class) && 6960 !BCM_GPORT_IS_VXLAN_PORT(port_class) && 6961 !BCM_GPORT_IS_L2GRE_PORT(port_class)) 6962 { 6963 return BCM_E_PORT; 6964 } 6965 } else { 6966 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 6967 if (inner_vlan == BCM_VLAN_INVALID) { 6968 BCM_IF_ERROR_RETURN 6969 (bcm_td2p_dvp_group_validate(unit, port_class)); 6970 } else 6971 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 6972 if (!SOC_PORT_CLASS_VALID(unit, port_class)) { 6973 return BCM_E_PORT; 6974 } 6975 } 6976 6977 #ifdef BCM_TRX_SUPPORT 6978 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) { 6979 return _bcm_trx_vlan_translate_egress_action_delete(unit, port_class, 6980 outer_vlan, 6981 inner_vlan); 6982 } 6983 #endif /* BCM_TRX_SUPPORT */ 6984 6985 return BCM_E_UNAVAIL; 6986 } 6987 6988 /* 6989 * Function : 6990 * bcm_vlan_translate_egress_action_add 6991 * Description : 6992 * Add an entry to egress VLAN translation table. 6993 * Parameters : 6994 * unit (IN) BCM unit number 6995 * port_class (IN) Group ID of ingress port 6996 * outer_vlan (IN) Packet outer VLAN ID 6997 * inner_vlan (IN) Packet inner VLAN ID 6998 * action (IN) Action for outer and inner tag 6999 */ 7000 int 7001 bcm_esw_vlan_translate_egress_action_add(int unit, int port_class, 7002 bcm_vlan_t outer_vlan, 7003 bcm_vlan_t inner_vlan, 7004 bcm_vlan_action_set_t *action) 7005 { 7006 int handle_modport_gport = 0; 7007 #ifdef BCM_TOMAHAWK3_SUPPORT 7008 if (SOC_IS_TOMAHAWK3(unit)) { 7009 return BCM_E_UNAVAIL; 7010 } 7011 #endif 7012 return _bcm_esw_vlan_translate_egress_action_add(unit, port_class, 7013 outer_vlan, inner_vlan, action, handle_modport_gport); 7014 } 7015 7016 /* 7017 * Function : 7018 * bcm_vlan_translate_egress_action_get 7019 * Description : 7020 * Get an entry to egress VLAN translation table. 7021 * Parameters : 7022 * unit (IN) BCM unit number 7023 * port_class (IN) Group ID of ingress port 7024 * outer_vlan (IN) Packet outer VLAN ID 7025 * inner_vlan (IN) Packet inner VLAN ID 7026 * action (OUT) Action for outer and inner tag 7027 */ 7028 int 7029 bcm_esw_vlan_translate_egress_action_get (int unit, int port_class, 7030 bcm_vlan_t outer_vlan, 7031 bcm_vlan_t inner_vlan, 7032 bcm_vlan_action_set_t *action) 7033 { 7034 int handle_modport_gport = 0; 7035 #ifdef BCM_TOMAHAWK3_SUPPORT 7036 if (SOC_IS_TOMAHAWK3(unit)) { 7037 return BCM_E_UNAVAIL; 7038 } 7039 #endif 7040 7041 bcm_vlan_action_set_t_init(action); 7042 return _bcm_esw_vlan_translate_egress_action_get(unit, port_class, 7043 outer_vlan, inner_vlan, action, handle_modport_gport); 7044 7045 } 7046 7047 /* 7048 * Function: 7049 * bcm_vlan_translate_egress_action_delete 7050 * Purpose: 7051 * Delete an egress vlan translate lookup entry. 7052 * Parameters: 7053 * unit (IN) BCM unit number 7054 * port_class (IN) Group ID of ingress port 7055 * outer_vlan (IN) Packet outer VLAN ID 7056 * inner_vlan (IN) Packet inner VLAN ID 7057 */ 7058 int 7059 bcm_esw_vlan_translate_egress_action_delete(int unit, int port_class, 7060 bcm_vlan_t outer_vlan, 7061 bcm_vlan_t inner_vlan) 7062 { 7063 int handle_modport_gport = 0; 7064 #ifdef BCM_TOMAHAWK3_SUPPORT 7065 if (SOC_IS_TOMAHAWK3(unit)) { 7066 return BCM_E_UNAVAIL; 7067 } 7068 #endif 7069 return _bcm_esw_vlan_translate_egress_action_delete(unit, port_class, 7070 outer_vlan, inner_vlan, handle_modport_gport); 7071 } 7072 7073 /* 7074 * Function : 7075 * bcm_esw_vlan_translate_egress_gport_action_add 7076 * Description : 7077 * Add an entry to egress VLAN translation table based on gport 7078 * Parameters : 7079 * unit (IN) BCM unit number 7080 * port (IN) Egress gport 7081 * outer_vlan (IN) Packet outer VLAN ID 7082 * inner_vlan (IN) Packet inner VLAN ID 7083 * action (IN) Action for outer and inner tag 7084 */ 7085 int 7086 bcm_esw_vlan_translate_egress_gport_action_add (int unit, bcm_gport_t port, 7087 bcm_vlan_t outer_vlan, 7088 bcm_vlan_t inner_vlan, 7089 bcm_vlan_action_set_t *action) 7090 { 7091 int handle_modport_gport = 0; 7092 #ifdef BCM_TOMAHAWK3_SUPPORT 7093 if (SOC_IS_TOMAHAWK3(unit)) { 7094 return BCM_E_UNAVAIL; 7095 } 7096 #endif 7097 if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) { 7098 handle_modport_gport = 1; 7099 } 7100 return _bcm_esw_vlan_translate_egress_action_add(unit, port, 7101 outer_vlan, inner_vlan, action, handle_modport_gport); 7102 } 7103 7104 /* 7105 * Function : 7106 * bcm_esw_vlan_translate_egress_gport_action_get 7107 * Description : 7108 * Get a gport based entry from egress VLAN translation table. 7109 * Parameters : 7110 * unit (IN) BCM unit number 7111 * port (IN) Egress gport 7112 * outer_vlan (IN) Packet outer VLAN ID 7113 * inner_vlan (IN) Packet inner VLAN ID 7114 * action (OUT) Action for outer and inner tag 7115 */ 7116 int 7117 bcm_esw_vlan_translate_egress_gport_action_get (int unit, bcm_gport_t port, 7118 bcm_vlan_t outer_vlan, 7119 bcm_vlan_t inner_vlan, 7120 bcm_vlan_action_set_t *action) 7121 { 7122 int handle_modport_gport = 0; 7123 #ifdef BCM_TOMAHAWK3_SUPPORT 7124 if (SOC_IS_TOMAHAWK3(unit)) { 7125 return BCM_E_UNAVAIL; 7126 } 7127 #endif 7128 if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) { 7129 handle_modport_gport = 1; 7130 } 7131 7132 bcm_vlan_action_set_t_init(action); 7133 return _bcm_esw_vlan_translate_egress_action_get(unit, port, 7134 outer_vlan, inner_vlan, action, handle_modport_gport); 7135 } 7136 7137 /* 7138 * Function: 7139 * bcm_esw_vlan_translate_egress_gport_action_delete 7140 * Purpose: 7141 * Delete a gport based egress vlan translate entry. 7142 * Parameters: 7143 * unit (IN) BCM unit number 7144 * port (IN) Egress gport 7145 * outer_vlan (IN) Packet outer VLAN ID 7146 * inner_vlan (IN) Packet inner VLAN ID 7147 */ 7148 int 7149 bcm_esw_vlan_translate_egress_gport_action_delete(int unit, bcm_gport_t port, 7150 bcm_vlan_t outer_vlan, 7151 bcm_vlan_t inner_vlan) 7152 { 7153 int handle_modport_gport = 0; 7154 #ifdef BCM_TOMAHAWK3_SUPPORT 7155 if (SOC_IS_TOMAHAWK3(unit)) { 7156 return BCM_E_UNAVAIL; 7157 } 7158 #endif 7159 if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) { 7160 handle_modport_gport = 1; 7161 } 7162 return _bcm_esw_vlan_translate_egress_action_delete(unit, port, 7163 outer_vlan, inner_vlan, handle_modport_gport); 7164 } 7165 7166 int 7167 bcm_esw_vlan_dtag_add(int unit, int port, bcm_vlan_t inner_vid, 7168 bcm_vlan_t outer_vid, int prio) 7169 { 7170 bcm_module_t modid; 7171 bcm_trunk_t tgid = -1; 7172 int id = -1; 7173 7174 #ifdef BCM_TOMAHAWK3_SUPPORT 7175 if (SOC_IS_TOMAHAWK3(unit)) { 7176 return BCM_E_UNAVAIL; 7177 } 7178 #endif 7179 7180 CHECK_INIT(unit); 7181 VLAN_CHK_ID(unit, inner_vid); 7182 VLAN_CHK_ID(unit, outer_vid); 7183 7184 #ifdef BCM_TRX_SUPPORT 7185 if (SOC_IS_TRX(unit)) { 7186 bcm_vlan_action_set_t action; 7187 bcm_gport_t gport; 7188 7189 if (!soc_feature(unit, soc_feature_vlan_action)) { 7190 return BCM_E_UNAVAIL; 7191 } 7192 if (BCM_GPORT_IS_SET(port)) { 7193 gport = port; 7194 } else { 7195 if (!SOC_PORT_VALID(unit, port)) { 7196 return BCM_E_PORT; 7197 } 7198 BCM_IF_ERROR_RETURN( 7199 bcm_esw_port_gport_get(unit, port, &gport)); 7200 } 7201 7202 bcm_vlan_action_set_t_init(&action); 7203 action.new_outer_vlan = outer_vid; 7204 action.priority = prio; 7205 /* For inner tagged packets, set the outer tag action and outer pkt 7206 * priority action to ADD. 7207 * For all other packet types, the action is initialized to NONE. 7208 */ 7209 action.it_outer = bcmVlanActionAdd; 7210 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 7211 action.it_outer_pkt_prio = bcmVlanActionAdd; 7212 } else { 7213 action.it_outer_pkt_prio = bcmVlanActionNone; 7214 } 7215 return _bcm_trx_vlan_translate_action_add(unit, gport, 7216 bcmVlanTranslateKeyPortInner, 7217 0, inner_vid, &action); 7218 } 7219 #endif /* BCM_TRX_SUPPORT */ 7220 7221 if (BCM_GPORT_IS_SET(port)) { 7222 BCM_IF_ERROR_RETURN( 7223 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 7224 if (-1 != tgid || -1 != id) { 7225 return BCM_E_PORT; 7226 } 7227 } else { 7228 if (!SOC_PORT_VALID(unit, port)) { 7229 return BCM_E_PORT; 7230 } 7231 BCM_IF_ERROR_RETURN( 7232 bcm_esw_stk_my_modid_get(unit, &modid)); 7233 } 7234 7235 #ifdef BCM_FIREBOLT_SUPPORT 7236 if (SOC_IS_FBX(unit)) { 7237 return _bcm_fb_vlan_translate_add(unit, port, inner_vid, outer_vid, 7238 prio, BCM_VLAN_XLATE_DTAG); 7239 } 7240 #endif 7241 7242 return BCM_E_UNAVAIL; 7243 } 7244 7245 /* 7246 * Function: 7247 * bcm_esw_vlan_dtag_get 7248 * Purpose: 7249 * Get vlan translation for double tagging 7250 * Parameters: 7251 * unit - StrataSwitch PCI device unit number (driver internal). 7252 * port - port numebr 7253 * old_vid - Old VLAN ID to has translation for 7254 * new_vid - New VLAN ID that packet will get 7255 * prio - Priority 7256 * Returns: 7257 * BCM_E_NONE - Translation found, new_vid and prio will have the values. 7258 * BCM_E_NOT_FOUND - Translation does not exist 7259 * BCM_E_XXX - Other error 7260 * Notes: 7261 * None. 7262 */ 7263 int 7264 bcm_esw_vlan_dtag_get (int unit, bcm_port_t port, 7265 bcm_vlan_t old_vid, 7266 bcm_vlan_t *new_vid, 7267 int *prio) 7268 { 7269 bcm_module_t modid; 7270 bcm_trunk_t tgid = -1; 7271 int id = -1; 7272 7273 #ifdef BCM_TOMAHAWK3_SUPPORT 7274 if (SOC_IS_TOMAHAWK3(unit)) { 7275 return BCM_E_UNAVAIL; 7276 } 7277 #endif 7278 7279 CHECK_INIT(unit); 7280 VLAN_CHK_ID(unit, old_vid); 7281 7282 #ifdef BCM_TRX_SUPPORT 7283 if (SOC_IS_TRX(unit)) { 7284 bcm_gport_t gport; 7285 bcm_vlan_action_set_t action; 7286 7287 if (!soc_feature(unit, soc_feature_vlan_action)) { 7288 return BCM_E_UNAVAIL; 7289 } 7290 if (BCM_GPORT_IS_SET(port)) { 7291 gport = port; 7292 } else { 7293 if (!SOC_PORT_VALID(unit, port)) { 7294 return BCM_E_PORT; 7295 } 7296 BCM_IF_ERROR_RETURN( 7297 bcm_esw_port_gport_get(unit, port, &gport)); 7298 } 7299 bcm_vlan_action_set_t_init(&action); 7300 BCM_IF_ERROR_RETURN( 7301 _bcm_trx_vlan_translate_action_get(unit, gport, 7302 bcmVlanTranslateKeyPortInner, 7303 0, old_vid, &action)); 7304 if (bcmVlanActionAdd == action.it_outer) { 7305 *new_vid = action.new_outer_vlan; 7306 *prio = action.priority; 7307 7308 return BCM_E_NONE; 7309 } 7310 7311 return BCM_E_NOT_FOUND; 7312 } 7313 #endif /* BCM_TRX_SUPPORT */ 7314 7315 if (BCM_GPORT_IS_SET(port)) { 7316 BCM_IF_ERROR_RETURN( 7317 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 7318 if (-1 != tgid || -1 != id) { 7319 return BCM_E_PORT; 7320 } 7321 } else { 7322 if (!SOC_PORT_VALID(unit, port)) { 7323 return BCM_E_PORT; 7324 } 7325 BCM_IF_ERROR_RETURN( 7326 bcm_esw_stk_my_modid_get(unit, &modid)); 7327 } 7328 7329 #ifdef BCM_FIREBOLT_SUPPORT 7330 if (SOC_IS_FBX(unit)) { 7331 return _bcm_fb_vlan_translate_get(unit, port, old_vid, new_vid, 7332 prio, BCM_VLAN_XLATE_DTAG); 7333 } 7334 #endif 7335 7336 return BCM_E_UNAVAIL; 7337 } 7338 7339 7340 int 7341 bcm_esw_vlan_dtag_delete(int unit, int port, bcm_vlan_t vid) 7342 { 7343 bcm_module_t modid; 7344 bcm_trunk_t tgid = -1; 7345 int id = -1; 7346 7347 #ifdef BCM_TOMAHAWK3_SUPPORT 7348 if (SOC_IS_TOMAHAWK3(unit)) { 7349 return BCM_E_UNAVAIL; 7350 } 7351 #endif 7352 7353 CHECK_INIT(unit); 7354 VLAN_CHK_ID(unit, vid); 7355 7356 #ifdef BCM_TRX_SUPPORT 7357 if (SOC_IS_TRX(unit)) { 7358 bcm_gport_t gport; 7359 7360 if (!soc_feature(unit, soc_feature_vlan_action)) { 7361 return BCM_E_UNAVAIL; 7362 } 7363 if (BCM_GPORT_IS_SET(port)) { 7364 gport = port; 7365 } else { 7366 if (!SOC_PORT_VALID(unit, port)) { 7367 return BCM_E_PORT; 7368 } 7369 BCM_IF_ERROR_RETURN( 7370 bcm_esw_port_gport_get(unit, port, &gport)); 7371 } 7372 7373 return _bcm_trx_vlan_translate_action_delete(unit, gport, 7374 bcmVlanTranslateKeyPortInner, 7375 0, vid); 7376 } 7377 #endif /* BCM_TRX_SUPPORT */ 7378 7379 if (BCM_GPORT_IS_SET(port)) { 7380 BCM_IF_ERROR_RETURN( 7381 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 7382 if (-1 != tgid || -1 != id) { 7383 return BCM_E_PORT; 7384 } 7385 } else { 7386 if (!SOC_PORT_VALID(unit, port)) { 7387 return BCM_E_PORT; 7388 } 7389 BCM_IF_ERROR_RETURN( 7390 bcm_esw_stk_my_modid_get(unit, &modid)); 7391 } 7392 7393 #ifdef BCM_FIREBOLT_SUPPORT 7394 if (SOC_IS_FBX(unit)) { 7395 return _bcm_fb_vlan_translate_delete(unit, port, vid, 7396 BCM_VLAN_XLATE_DTAG); 7397 } 7398 #endif 7399 7400 return BCM_E_UNAVAIL; 7401 } 7402 7403 int 7404 bcm_esw_vlan_dtag_delete_all(int unit) 7405 { 7406 #ifdef BCM_TOMAHAWK3_SUPPORT 7407 if (SOC_IS_TOMAHAWK3(unit)) { 7408 return BCM_E_UNAVAIL; 7409 } 7410 #endif 7411 7412 CHECK_INIT(unit); 7413 7414 #ifdef BCM_TRX_SUPPORT 7415 if (SOC_IS_TRX(unit)) { 7416 if (!soc_feature(unit, soc_feature_vlan_action)) { 7417 return BCM_E_UNAVAIL; 7418 } 7419 return _bcm_trx_vlan_translate_action_delete_all(unit); 7420 } 7421 #endif /* BCM_TRX_SUPPORT */ 7422 7423 #ifdef BCM_FIREBOLT_SUPPORT 7424 if (SOC_IS_FBX(unit)) { 7425 int rv; 7426 7427 rv = _bcm_fb_vlan_translate_delete(unit, -1, BCM_VLAN_NONE, 7428 BCM_VLAN_XLATE_DTAG); 7429 if (BCM_SUCCESS(rv) || (BCM_E_NOT_FOUND == rv)) { 7430 return BCM_E_NONE; 7431 } 7432 7433 return rv; 7434 } 7435 #endif 7436 7437 return BCM_E_UNAVAIL; 7438 } 7439 7440 /* 7441 * IP based vlans 7442 */ 7443 7444 #ifdef BCM_XGS3_SWITCH_SUPPORT 7445 static void 7446 _ip6_prefix_to_mask(int prefix, bcm_ip6_t mask) 7447 { 7448 int i; 7449 7450 sal_memset(mask, 0, sizeof(bcm_ip6_t)); 7451 /* Construct the mask from the prefix */ 7452 for (i = 0; prefix > 8; prefix -= 8, i++) { 7453 mask[i] = 0xff; 7454 } 7455 mask[i] = 0xff << (8 - prefix); 7456 } 7457 7458 static int 7459 _ip6_mask_to_prefix(bcm_ip6_t mask) 7460 { 7461 int i; 7462 int prefix; 7463 for (i = 0, prefix = 0; mask[i] == 0xff; i++) { 7464 prefix += 8; 7465 } 7466 switch(mask[i]) { 7467 case 0x80: 7468 prefix += 1; 7469 break; 7470 case 0xc0: 7471 prefix += 2; 7472 break; 7473 case 0xe0: 7474 prefix += 3; 7475 break; 7476 case 0xf0: 7477 prefix += 4; 7478 break; 7479 case 0xf8: 7480 prefix += 5; 7481 break; 7482 case 0xfc: 7483 prefix += 6; 7484 break; 7485 case 0xfe: 7486 prefix += 7; 7487 break; 7488 case 0: 7489 break; 7490 default: 7491 return(-1); 7492 } 7493 return prefix; 7494 } 7495 7496 static void 7497 _ip4cat(uint8 * buf, bcm_ip_t ip) 7498 { 7499 int i; 7500 for (i = 3; i > -1; i--) { 7501 buf[i] = ip & 0x00ff; 7502 ip >>= 8; 7503 } 7504 } 7505 7506 /* 7507 * On XGS3, VLAN_SUBNET.IP_ADDR stores only a top half (64 bits) of 7508 * the IPV6 address. Comparing it against a full length of a parameter 7509 * will have certainly result in a mismatch. There should be a 7510 * special type for a stored part of the address; meanwhile, a 7511 * symbolic constant is used. 7512 */ 7513 7514 #define VLAN_SUBNET_IP_ADDR_LENGTH 8 7515 7516 /* Macro to copy bcm_ip6_t addr into uint32[] for soc_mem_field_set call */ 7517 #define VLAN_IP6_TO_HW_FORMAT(_ip, _reg) \ 7518 do { \ 7519 _reg[0] = (_ip[4] << 24) | (_ip[5] << 16) | (_ip[6] << 8) | _ip[7]; \ 7520 _reg[1] = (_ip[0] << 24) | (_ip[1] << 16) | (_ip[2] << 8) | _ip[3]; \ 7521 } while (0) 7522 7523 /* Macro to copy uint32[] addr values from soc_mem_field_get into bcm_ip6_t */ 7524 #define VLAN_HW_FORMAT_TO_IP6(_reg, _ip) \ 7525 do { \ 7526 _ip[3] = (_reg[1]) & 0xff; \ 7527 _ip[2] = (_reg[1] >> 8) & 0xff; \ 7528 _ip[1] = (_reg[1] >> 16) & 0xff; \ 7529 _ip[0] = (_reg[1] >> 24) & 0xff; \ 7530 _ip[7] = (_reg[0]) & 0xff; \ 7531 _ip[6] = (_reg[0] >> 8) & 0xff; \ 7532 _ip[5] = (_reg[0] >> 16) & 0xff; \ 7533 _ip[4] = (_reg[0] >> 24) & 0xff; \ 7534 } while (0) 7535 7536 static int 7537 _xgs3_vlan_ipv6_add(int unit, 7538 bcm_ip6_t ip, bcm_ip6_t mask, bcm_vlan_t vid, int prio) 7539 { 7540 int i, imin, imax, nent, vsbytes; 7541 int match = -1, empty = -1, insert = -1; 7542 int rv; 7543 vlan_subnet_entry_t * vstab, * vsnull, *vstabp; 7544 int prefix; 7545 uint32 hw_ip[2], hw_nm[2]; 7546 7547 VLAN_CHK_ID(unit, vid); 7548 VLAN_CHK_PRIO(unit, prio); 7549 7550 VLAN_IP6_TO_HW_FORMAT(ip, hw_ip); 7551 VLAN_IP6_TO_HW_FORMAT(mask, hw_nm); 7552 7553 imin = soc_mem_index_min(unit, VLAN_SUBNETm); 7554 imax = soc_mem_index_max(unit, VLAN_SUBNETm); 7555 nent = soc_mem_index_count(unit, VLAN_SUBNETm); 7556 vsbytes = soc_mem_entry_words(unit, VLAN_SUBNETm); 7557 vsbytes = WORDS2BYTES(vsbytes); 7558 7559 prefix = _ip6_mask_to_prefix(mask); 7560 if (prefix < 0) { 7561 return BCM_E_PARAM; 7562 } 7563 7564 vstab = soc_cm_salloc(unit, nent * sizeof(*vstab), "vlan_subnet"); 7565 if (vstab == NULL) { 7566 return BCM_E_MEMORY; 7567 } 7568 7569 vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm); 7570 7571 soc_mem_lock(unit, VLAN_SUBNETm); 7572 rv = soc_mem_read_range(unit, VLAN_SUBNETm, MEM_BLOCK_ANY, 7573 imin, imax, vstab); 7574 if (rv < 0) { 7575 soc_mem_unlock(unit, VLAN_SUBNETm); 7576 soc_cm_sfree(unit, vstab); 7577 return rv; 7578 } 7579 7580 for(i = 0; i < nent; i++) { 7581 uint32 enm[2], eip[2]; 7582 bcm_ip6_t temp_nm; 7583 int epx; 7584 vstabp = soc_mem_table_idx_to_pointer(unit, 7585 VLAN_SUBNETm, vlan_subnet_entry_t *, 7586 vstab, i); 7587 if (sal_memcmp(vstabp, vsnull, vsbytes) == 0) { 7588 empty = i; 7589 break; 7590 } 7591 soc_mem_field_get(unit, VLAN_SUBNETm, 7592 (uint32 *) vstabp, MASKf, (uint32 *) enm); 7593 7594 /* copy mask into bcm_ip6_t */ 7595 sal_memset(temp_nm, 0, sizeof(bcm_ip6_t)); 7596 VLAN_HW_FORMAT_TO_IP6(enm, temp_nm); 7597 7598 epx = _ip6_mask_to_prefix(temp_nm); 7599 if (epx < 0) { 7600 soc_mem_unlock(unit, VLAN_SUBNETm); 7601 soc_cm_sfree(unit, vstab); 7602 return BCM_E_PARAM; 7603 } 7604 if ((epx < prefix) && (insert < 0)) { 7605 insert = i; 7606 } 7607 if (sal_memcmp(hw_nm, enm, VLAN_SUBNET_IP_ADDR_LENGTH) != 0) { 7608 continue; 7609 } 7610 soc_mem_field_get(unit, VLAN_SUBNETm, 7611 (uint32 *) vstabp, IP_ADDRf, (uint32 *) eip); 7612 7613 if (sal_memcmp(hw_ip, eip, VLAN_SUBNET_IP_ADDR_LENGTH) == 0) { 7614 match = i; 7615 } 7616 } 7617 7618 if (match >= 0) { /* found an exact match */ 7619 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 7620 vlan_subnet_entry_t *, vstab, match); 7621 soc_VLAN_SUBNETm_field32_set(unit, vstabp, VLAN_IDf, vid); 7622 soc_VLAN_SUBNETm_field32_set(unit, vstabp, PRIf, prio); 7623 soc_VLAN_SUBNETm_field32_set(unit, vstabp, VALIDf, 1); 7624 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT) 7625 if (soc_mem_field_valid(unit, VLAN_SUBNETm, RESERVED_MASKf)) { 7626 soc_mem_field32_set(unit, VLAN_SUBNETm, vstabp, RESERVED_MASKf, 0); 7627 } 7628 if (soc_mem_field_valid(unit, VLAN_SUBNETm, RESERVED_KEYf)) { 7629 soc_mem_field32_set(unit, VLAN_SUBNETm, vstabp, RESERVED_KEYf, 0); 7630 } 7631 #endif /* BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 7632 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL, match, vstabp); 7633 } else if (empty < 0) { 7634 rv = BCM_E_FULL; 7635 } else { 7636 if (insert < 0) { 7637 insert = empty; 7638 } 7639 7640 for (i = empty; i > insert; i--) { 7641 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 7642 vlan_subnet_entry_t *, vstab, (i - 1)); 7643 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, vstabp); 7644 if (rv < 0) { 7645 break; 7646 } 7647 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i - 1, &vsnull); 7648 if (rv < 0) { 7649 break; 7650 } 7651 } 7652 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 7653 vlan_subnet_entry_t *, vstab, insert); 7654 sal_memset(vstabp, 0, vsbytes); 7655 soc_VLAN_SUBNETm_field32_set(unit, vstabp, VLAN_IDf, vid); 7656 soc_VLAN_SUBNETm_field32_set(unit, vstabp, PRIf, prio); 7657 soc_VLAN_SUBNETm_field32_set(unit, vstabp, VALIDf, 1); 7658 soc_mem_field_set(unit, VLAN_SUBNETm, 7659 (uint32 *) vstabp, IP_ADDRf, (uint32 *) hw_ip); 7660 soc_mem_field_set(unit, VLAN_SUBNETm, 7661 (uint32 *) vstabp, MASKf, (uint32 *) hw_nm); 7662 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT) 7663 if (soc_mem_field_valid(unit, VLAN_SUBNETm, RESERVED_MASKf)) { 7664 soc_mem_field32_set(unit, VLAN_SUBNETm, vstabp, RESERVED_MASKf, 0); 7665 } 7666 if (soc_mem_field_valid(unit, VLAN_SUBNETm, RESERVED_KEYf)) { 7667 soc_mem_field32_set(unit, VLAN_SUBNETm, vstabp, RESERVED_KEYf, 0); 7668 } 7669 #endif /* BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 7670 7671 if (rv >= 0) { 7672 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL, 7673 insert, vstabp); 7674 } 7675 } 7676 7677 soc_mem_unlock(unit, VLAN_SUBNETm); 7678 soc_cm_sfree(unit, vstab); 7679 return rv; 7680 } 7681 7682 static int 7683 _xgs3_vlan_ipv6_delete(int unit, bcm_ip6_t ip, bcm_ip6_t mask) 7684 { 7685 int i, imin, imax, nent, vsbytes; 7686 int match = -1, empty = -1; 7687 int rv; 7688 vlan_subnet_entry_t * vstab, * vsnull, *vstabp; 7689 uint32 hw_ip[2], hw_nm[2]; 7690 7691 VLAN_IP6_TO_HW_FORMAT(ip, hw_ip); 7692 VLAN_IP6_TO_HW_FORMAT(mask, hw_nm); 7693 #ifdef BCM_TRIDENT_SUPPORT 7694 if (SOC_IS_TD_TT(unit)) { 7695 hw_ip[0] &= hw_nm[0]; 7696 hw_ip[1] &= hw_nm[1]; 7697 } 7698 #endif /* BCM_TRIDENT_SUPPORT */ 7699 7700 imin = soc_mem_index_min(unit, VLAN_SUBNETm); 7701 imax = soc_mem_index_max(unit, VLAN_SUBNETm); 7702 nent = soc_mem_index_count(unit, VLAN_SUBNETm); 7703 vsbytes = soc_mem_entry_words(unit, VLAN_SUBNETm); 7704 vsbytes = WORDS2BYTES(vsbytes); 7705 vstab = soc_cm_salloc(unit, nent * sizeof(*vstab), "vlan_subnet"); 7706 7707 if (vstab == NULL) { 7708 return BCM_E_MEMORY; 7709 } 7710 7711 vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm); 7712 7713 soc_mem_lock(unit, VLAN_SUBNETm); 7714 rv = soc_mem_read_range(unit, VLAN_SUBNETm, MEM_BLOCK_ANY, 7715 imin, imax, vstab); 7716 if (rv < 0) { 7717 soc_mem_unlock(unit, VLAN_SUBNETm); 7718 soc_cm_sfree(unit, vstab); 7719 return rv; 7720 } 7721 7722 for(i = 0; i < nent; i++) { 7723 uint32 enm[2], eip[2]; 7724 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 7725 vlan_subnet_entry_t *, vstab, i); 7726 if (sal_memcmp(vstabp, vsnull, vsbytes) == 0) { 7727 empty = i; 7728 break; 7729 } 7730 soc_mem_field_get(unit, VLAN_SUBNETm, 7731 (uint32 *) vstabp, MASKf, (uint32 *) enm); 7732 if (sal_memcmp(hw_nm, enm, VLAN_SUBNET_IP_ADDR_LENGTH) != 0) { 7733 continue; 7734 } 7735 soc_mem_field_get(unit, VLAN_SUBNETm, 7736 (uint32 *) vstabp, IP_ADDRf, (uint32 *) eip); 7737 if (sal_memcmp(hw_ip, eip, VLAN_SUBNET_IP_ADDR_LENGTH) == 0) { 7738 match = i; 7739 } 7740 } 7741 7742 if (match < 0) { 7743 soc_mem_unlock(unit, VLAN_SUBNETm); 7744 soc_cm_sfree(unit, vstab); 7745 return BCM_E_NOT_FOUND; 7746 } 7747 7748 if (empty == -1) { 7749 empty = nent; 7750 } 7751 7752 for (i = match; (i < empty - 1) && (rv == BCM_E_NONE); i++) { 7753 vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 7754 vlan_subnet_entry_t *, vstab, (i + 1)); 7755 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, vstabp); 7756 } 7757 7758 if (rv >= 0) { 7759 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, empty - 1, vsnull); 7760 } 7761 7762 soc_mem_unlock(unit, VLAN_SUBNETm); 7763 soc_cm_sfree(unit, vstab); 7764 return rv; 7765 } 7766 7767 static int 7768 _xgs3_vlan_ipv6_delete_all(int unit) 7769 { 7770 int i, imax; 7771 int rv = BCM_E_NONE; 7772 vlan_subnet_entry_t * vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm); 7773 7774 soc_mem_lock(unit, VLAN_SUBNETm); 7775 imax = soc_mem_index_max(unit, VLAN_SUBNETm); 7776 7777 for (i = soc_mem_index_min(unit, VLAN_SUBNETm); i <= imax; i++) { 7778 rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL, i, vsnull); 7779 if (rv < 0) { 7780 break; 7781 } 7782 } 7783 7784 soc_mem_unlock(unit, VLAN_SUBNETm); 7785 return rv; 7786 } 7787 #endif 7788 7789 /* 7790 * Vlan selection based on IPv4 addresses 7791 */ 7792 7793 /* 7794 * Function: 7795 * bcm_vlan_ip4_add 7796 * Purpose: 7797 * Add an IPv4 subnet lookup to select vlan and priority for 7798 * untagged packets 7799 * Parameters: 7800 * unit - device number 7801 * ipaddr - IPv4 address 7802 * netmask - network mask of ipaddr to match 7803 * vid - VLAN number to give matching packets 7804 * prio - priority to give matching packets 7805 * Returns: 7806 * BCM_E_XXX 7807 * Notes: 7808 * This API is superseded by bcm_vlan_ip_add. 7809 */ 7810 7811 int 7812 bcm_esw_vlan_ip4_add(int unit, bcm_ip_t ipaddr, bcm_ip_t netmask, 7813 bcm_vlan_t vid, int prio) 7814 { 7815 #ifdef BCM_XGS3_SWITCH_SUPPORT 7816 if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) { 7817 bcm_ip6_t ip6addr; 7818 bcm_ip6_t ip6mask; 7819 uint8 * ptr; 7820 7821 #ifdef BCM_SCORPION_SUPPORT 7822 if (SOC_IS_SC_CQ(unit) && 7823 !soc_feature(unit, soc_feature_vlan_action)) { 7824 return BCM_E_UNAVAIL; 7825 } 7826 #endif 7827 7828 #ifdef BCM_TRIDENT_SUPPORT 7829 if (SOC_IS_TD_TT(unit) && 7830 !soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 7831 return BCM_E_UNAVAIL; 7832 } 7833 #endif 7834 7835 /* Construct ipv6 mask/address from ipv4 parameters. 7836 * Only use the upper 64-bits of ipv6 mask/address. 7837 */ 7838 ptr = ip6addr; 7839 sal_memset(ptr, 0, sizeof(ip6addr)); 7840 sal_memcpy(ptr, "\xff\xff\x00\x00", 4); 7841 _ip4cat(ptr + 4, ipaddr); 7842 7843 ptr = ip6mask; 7844 sal_memset(ptr, 0, sizeof(ip6mask)); 7845 sal_memcpy(ptr, "\xff\xff\xff\xff", 4); 7846 _ip4cat(ptr + 4, netmask); 7847 7848 return _xgs3_vlan_ipv6_add(unit, ip6addr, ip6mask, vid, prio); 7849 } 7850 #endif 7851 return BCM_E_UNAVAIL; 7852 } 7853 7854 /* 7855 * Function: 7856 * bcm_vlan_ip4_delete 7857 * Purpose: 7858 * Delete an IPv4 subnet lookup entry. 7859 * Parameters: 7860 * unit - device number 7861 * ipaddr - IPv4 address 7862 * netmask - network mask of ipaddr to match 7863 * Returns: 7864 * BCM_E_XXX 7865 * Notes: 7866 * This API is superseded by bcm_vlan_ip_delete. 7867 */ 7868 7869 int 7870 bcm_esw_vlan_ip4_delete(int unit, bcm_ip_t ipaddr, bcm_ip_t netmask) 7871 { 7872 #ifdef BCM_XGS3_SWITCH_SUPPORT 7873 if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) { 7874 bcm_ip6_t ip6addr; 7875 bcm_ip6_t ip6mask; 7876 uint8 * ptr; 7877 7878 #ifdef BCM_SCORPION_SUPPORT 7879 if (SOC_IS_SC_CQ(unit) && 7880 !soc_feature(unit, soc_feature_vlan_action)) { 7881 return BCM_E_UNAVAIL; 7882 } 7883 #endif 7884 7885 #ifdef BCM_TRIDENT_SUPPORT 7886 if (SOC_IS_TD_TT(unit) && 7887 !soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 7888 return BCM_E_UNAVAIL; 7889 } 7890 #endif 7891 7892 /* Construct ipv6 mask/address from ipv4 parameters */ 7893 ptr = ip6addr; 7894 sal_memset(ptr, 0, sizeof(ip6addr)); 7895 sal_memcpy(ptr, "\xff\xff\x00\x00", 4); 7896 _ip4cat(ptr + 4, ipaddr); 7897 7898 ptr = ip6mask; 7899 sal_memset(ptr, 0, sizeof(ip6mask)); 7900 sal_memcpy(ptr, "\xff\xff\xff\xff", 4); 7901 _ip4cat(ptr + 4, netmask); 7902 7903 return _xgs3_vlan_ipv6_delete(unit, ip6addr, ip6mask); 7904 } 7905 #endif 7906 return BCM_E_UNAVAIL; 7907 } 7908 7909 /* 7910 * Function: 7911 * bcm_vlan_ip4_delete_all 7912 * Purpose: 7913 * Delete all IPv4 subnet lookup entries. 7914 * Parameters: 7915 * unit - device number 7916 * Returns: 7917 * BCM_E_XXX 7918 * Notes: 7919 * This API is superseded by bcm_vlan_ip_delete_all. 7920 */ 7921 7922 int 7923 bcm_esw_vlan_ip4_delete_all(int unit) 7924 { 7925 #ifdef BCM_XGS3_SWITCH_SUPPORT 7926 if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) { 7927 #ifdef BCM_SCORPION_SUPPORT 7928 if (SOC_IS_SC_CQ(unit) && 7929 !soc_feature(unit, soc_feature_vlan_action)) { 7930 return BCM_E_UNAVAIL; 7931 } 7932 #endif 7933 7934 #ifdef BCM_TRIDENT_SUPPORT 7935 if (SOC_IS_TD_TT(unit) && 7936 !soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 7937 return BCM_E_UNAVAIL; 7938 } 7939 #endif 7940 7941 return _xgs3_vlan_ipv6_delete_all(unit); 7942 } 7943 #endif 7944 return BCM_E_UNAVAIL; 7945 } 7946 7947 /* 7948 * Vlan selection based on IPv6 addresses 7949 */ 7950 7951 /* 7952 * Function: 7953 * _bcm_vlan_ip6_add (internal) 7954 * Purpose: 7955 * Add an IPv6 subnet lookup to select vlan and priority for 7956 * untagged packets 7957 * Parameters: 7958 * unit - device number 7959 * ipaddr - IPv6 address 7960 * prefix - network prefix of ipaddr to match 7961 * vlan - VLAN number to give matching packets 7962 * prio - priority to give matching packets 7963 * Returns: 7964 * BCM_E_XXX 7965 * Notes: 7966 * Valid prefix lengths may be limited to no more than 64 7967 */ 7968 7969 STATIC int 7970 _bcm_vlan_ip6_add(int unit, 7971 bcm_ip6_t ipaddr, 7972 int prefix, 7973 bcm_vlan_t vlan, 7974 int prio) 7975 { 7976 #ifdef BCM_XGS3_SWITCH_SUPPORT 7977 if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) { 7978 bcm_ip6_t mask; 7979 7980 if (prefix > 64) { 7981 return BCM_E_PARAM; 7982 } 7983 7984 _ip6_prefix_to_mask(prefix, mask); 7985 return _xgs3_vlan_ipv6_add(unit, ipaddr, mask, vlan, prio); 7986 } 7987 #endif 7988 7989 return BCM_E_UNAVAIL; 7990 } 7991 7992 /* 7993 * Function: 7994 * _bcm_vlan_ip6_delete (internal) 7995 * Purpose: 7996 * Delete an IPv6 subnet lookup entry 7997 * Parameters: 7998 * unit - device number 7999 * ipaddr - IPv6 address 8000 * prefix - network prefix of ipaddr to match 8001 * Returns: 8002 * BCM_E_XXX 8003 */ 8004 8005 STATIC int 8006 _bcm_vlan_ip6_delete(int unit, 8007 bcm_ip6_t ipaddr, 8008 int prefix) 8009 { 8010 #ifdef BCM_XGS3_SWITCH_SUPPORT 8011 if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) { 8012 bcm_ip6_t mask; 8013 8014 if (prefix > 64) { 8015 return BCM_E_PARAM; 8016 } 8017 8018 _ip6_prefix_to_mask(prefix, mask); 8019 return _xgs3_vlan_ipv6_delete(unit, ipaddr, mask); 8020 } 8021 #endif 8022 8023 return BCM_E_UNAVAIL; 8024 } 8025 8026 /* 8027 * Function: 8028 * _bcm_vlan_ip6_delete_all (internal) 8029 * Purpose: 8030 * Delete all IPv6 subnet lookup entries 8031 * Parameters: 8032 * unit - device number 8033 * Returns: 8034 * BCM_E_XXX 8035 */ 8036 8037 STATIC int 8038 _bcm_vlan_ip6_delete_all(int unit) 8039 { 8040 #ifdef BCM_XGS3_SWITCH_SUPPORT 8041 if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) { 8042 return _xgs3_vlan_ipv6_delete_all(unit); 8043 } 8044 #endif 8045 8046 return BCM_E_UNAVAIL; 8047 } 8048 8049 /* 8050 * Vlan selection based on unified IPv4/IPv6 information structure. 8051 */ 8052 8053 /* 8054 * Function: 8055 * bcm_vlan_ip_add 8056 * Purpose: 8057 * Add a subnet lookup to select vlan and priority for 8058 * untagged packets 8059 * Parameters: 8060 * unit - device number 8061 * vlan_ip - structure specifying IP address and other info 8062 * Returns: 8063 * BCM_E_XXX 8064 */ 8065 8066 int 8067 bcm_esw_vlan_ip_add(int unit, bcm_vlan_ip_t *vlan_ip) 8068 { 8069 #ifdef BCM_TRX_SUPPORT 8070 if (SOC_IS_TRX(unit)) { 8071 int rv; 8072 8073 if (soc_feature(unit, soc_feature_vlan_action) 8074 && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 8075 bcm_vlan_action_set_t action; 8076 8077 bcm_vlan_action_set_t_init(&action); 8078 action.new_outer_vlan = vlan_ip->vid; 8079 action.new_inner_vlan = 0; 8080 action.priority = vlan_ip->prio; 8081 action.dt_outer_prio = bcmVlanActionReplace; 8082 action.ot_outer_prio = bcmVlanActionReplace; 8083 action.it_outer = bcmVlanActionAdd; 8084 action.it_inner_prio = bcmVlanActionNone; 8085 action.ut_outer = bcmVlanActionAdd; 8086 8087 soc_mem_lock(unit, VLAN_SUBNETm); 8088 rv = _bcm_trx_vlan_ip_action_add(unit, vlan_ip, &action); 8089 soc_mem_unlock(unit, VLAN_SUBNETm); 8090 8091 return rv; 8092 } else { 8093 return BCM_E_UNAVAIL; /* Latency bypass */ 8094 } 8095 } 8096 #endif /* BCM_TRX_SUPPORT */ 8097 8098 return (vlan_ip->flags & BCM_VLAN_SUBNET_IP6) 8099 ? _bcm_vlan_ip6_add(unit, vlan_ip->ip6, vlan_ip->prefix, 8100 vlan_ip->vid, vlan_ip->prio) 8101 : bcm_esw_vlan_ip4_add(unit, vlan_ip->ip4, vlan_ip->mask, 8102 vlan_ip->vid, vlan_ip->prio); 8103 } 8104 8105 /* 8106 * Function: 8107 * bcm_vlan_ip_delete 8108 * Purpose: 8109 * Delete a subnet lookup entry. 8110 * Parameters: 8111 * unit - device number 8112 * vlan_ip - structure specifying IP address and other info 8113 * Returns: 8114 * BCM_E_XXX 8115 */ 8116 8117 int 8118 bcm_esw_vlan_ip_delete(int unit, bcm_vlan_ip_t *vlan_ip) 8119 { 8120 #ifdef BCM_TRX_SUPPORT 8121 if (SOC_IS_TRX(unit)) { 8122 int rv; 8123 8124 if (soc_feature(unit, soc_feature_vlan_action) 8125 && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 8126 soc_mem_lock(unit, VLAN_SUBNETm); 8127 rv = _bcm_trx_vlan_ip_delete(unit, vlan_ip); 8128 soc_mem_unlock(unit, VLAN_SUBNETm); 8129 8130 return rv; 8131 } else { 8132 return BCM_E_UNAVAIL; /* Latency bypass */ 8133 } 8134 } 8135 #endif /* BCM_TRX_SUPPORT */ 8136 8137 return (vlan_ip->flags & BCM_VLAN_SUBNET_IP6) 8138 ? _bcm_vlan_ip6_delete(unit, vlan_ip->ip6, vlan_ip->prefix) 8139 : bcm_esw_vlan_ip4_delete(unit, vlan_ip->ip4, vlan_ip->mask); 8140 } 8141 8142 /* 8143 * Function: 8144 * bcm_vlan_ip_delete_all 8145 * Purpose: 8146 * Delete all subnet lookup entries. 8147 * Parameters: 8148 * unit - device number 8149 * Returns: 8150 * BCM_E_XXX 8151 */ 8152 8153 int 8154 bcm_esw_vlan_ip_delete_all(int unit) 8155 { 8156 int rv; 8157 8158 #ifdef BCM_TRX_SUPPORT 8159 if (SOC_IS_TRX(unit)) { 8160 if (soc_feature(unit, soc_feature_vlan_action) 8161 && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 8162 soc_mem_lock(unit, VLAN_SUBNETm); 8163 rv = _bcm_trx_vlan_ip_delete_all(unit); 8164 soc_mem_unlock(unit, VLAN_SUBNETm); 8165 8166 return rv; 8167 } else { 8168 return BCM_E_UNAVAIL; /* Latency bypass */ 8169 } 8170 } 8171 #endif /* BCM_TRX_SUPPORT */ 8172 8173 if ((rv = _bcm_vlan_ip6_delete_all(unit)) == BCM_E_UNAVAIL) { 8174 rv = BCM_E_NONE; 8175 } 8176 if (rv == BCM_E_NONE) { 8177 rv = bcm_esw_vlan_ip4_delete_all(unit); 8178 } 8179 8180 return rv; 8181 } 8182 8183 /* 8184 * Function: 8185 * bcm_vlan_ip_action_add 8186 * Purpose: 8187 * Add a subnet lookup to select vlan action for untagged packets 8188 * Parameters: 8189 * unit - device number 8190 * vlan_ip - structure specifying IP address and other info 8191 * action - structure VLAN tag actions 8192 * Returns: 8193 * BCM_E_XXX 8194 */ 8195 8196 int 8197 bcm_esw_vlan_ip_action_add(int unit, bcm_vlan_ip_t *vlan_ip, 8198 bcm_vlan_action_set_t *action) 8199 { 8200 #ifdef BCM_TRX_SUPPORT 8201 int rv; 8202 8203 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 8204 && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 8205 soc_mem_lock(unit, VLAN_SUBNETm); 8206 rv = _bcm_trx_vlan_ip_action_add(unit, vlan_ip, action); 8207 soc_mem_unlock(unit, VLAN_SUBNETm); 8208 8209 return rv; 8210 } 8211 #endif /* BCM_TRX_SUPPORT */ 8212 8213 return BCM_E_UNAVAIL; 8214 } 8215 8216 /* 8217 * Function: 8218 * bcm_vlan_ip_action_get 8219 * Purpose: 8220 * Get an action for subnet 8221 * Parameters: 8222 * unit - (IN) device number 8223 * vlan_ip - (IN) structure specifying IP address and other info 8224 * action - (OUT) structure VLAN tag actions 8225 * Returns: 8226 * BCM_E_XXX 8227 */ 8228 8229 int 8230 bcm_esw_vlan_ip_action_get(int unit, bcm_vlan_ip_t *vlan_ip, 8231 bcm_vlan_action_set_t *action) 8232 { 8233 #ifdef BCM_TRX_SUPPORT 8234 int rv; 8235 8236 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 8237 && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 8238 8239 bcm_vlan_action_set_t_init(action); 8240 soc_mem_lock(unit, VLAN_SUBNETm); 8241 rv = _bcm_trx_vlan_ip_action_get(unit, vlan_ip, action); 8242 soc_mem_unlock(unit, VLAN_SUBNETm); 8243 8244 return rv; 8245 } 8246 #endif /* BCM_TRX_SUPPORT */ 8247 8248 return BCM_E_UNAVAIL; 8249 } 8250 8251 /* 8252 * Function: 8253 * bcm_esw_vlan_ip_action_delete 8254 * Purpose: 8255 * Delete an action for subnet 8256 * Parameters: 8257 * unit - (IN) device number 8258 * vlan_ip - (IN) structure specifying IP address and other info 8259 * Returns: 8260 * BCM_E_XXX 8261 */ 8262 8263 int 8264 bcm_esw_vlan_ip_action_delete(int unit, bcm_vlan_ip_t *vlan_ip) 8265 { 8266 #ifdef BCM_TRX_SUPPORT 8267 int rv; 8268 8269 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 8270 && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 8271 soc_mem_lock(unit, VLAN_SUBNETm); 8272 rv = _bcm_trx_vlan_ip_delete(unit, vlan_ip); 8273 soc_mem_unlock(unit, VLAN_SUBNETm); 8274 8275 return rv; 8276 } 8277 #endif /* BCM_TRX_SUPPORT */ 8278 8279 return BCM_E_UNAVAIL; 8280 } 8281 8282 /* 8283 * Function: 8284 * bcm_esw_vlan_ip_action_delete_all 8285 * Purpose: 8286 * Delete all actions for all subnets 8287 * Parameters: 8288 * unit - (IN) device number 8289 * Returns: 8290 * BCM_E_XXX 8291 */ 8292 8293 int 8294 bcm_esw_vlan_ip_action_delete_all(int unit) 8295 { 8296 #ifdef BCM_TRX_SUPPORT 8297 int rv; 8298 8299 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 8300 && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 8301 soc_mem_lock(unit, VLAN_SUBNETm); 8302 rv = _bcm_trx_vlan_ip_delete_all(unit); 8303 soc_mem_unlock(unit, VLAN_SUBNETm); 8304 8305 return rv; 8306 } 8307 #endif /* BCM_TRX_SUPPORT */ 8308 8309 return BCM_E_UNAVAIL; 8310 } 8311 /* 8312 * Function: 8313 * bcm_esw_vlan_ip_action_traverse 8314 * Purpose: 8315 * Delete all actions for all subnets 8316 * Parameters: 8317 * unit - (IN) device number 8318 * cb - (IN) call back function 8319 * user_data - (IN) a pointer to user data 8320 * Returns: 8321 * BCM_E_XXX 8322 */ 8323 int 8324 bcm_esw_vlan_ip_action_traverse(int unit, bcm_vlan_ip_action_traverse_cb cb, 8325 void *user_data) 8326 { 8327 #ifdef BCM_TRX_SUPPORT 8328 int rv; 8329 8330 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action) 8331 && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) { 8332 soc_mem_lock(unit, VLAN_SUBNETm); 8333 rv = _bcm_trx_vlan_ip_action_traverse(unit, cb, user_data); 8334 soc_mem_unlock(unit, VLAN_SUBNETm); 8335 8336 return rv; 8337 } 8338 #endif /* BCM_TRX_SUPPORT */ 8339 8340 return BCM_E_UNAVAIL; 8341 } 8342 8343 /* 8344 * IMPLEMENTATION NOTES 8345 * 8346 * bcm_vlan_ip4_* should be implemented in FB/ER as adding 8347 * entries to the VLAN_SUBNET tables with: 8348 * VLAN_SUBNET.IP_ADDR = 0xFFFF0000 <ip4_addr> 8349 * VLAN_SUBNET.MASK = 0xFFFFFFFF <ip4_netmask> 8350 * VLAN_SUBNET.VALID = 1 8351 * The VLAN_SUBNET entries must be sorted in order from 8352 * longest prefix match to shortest prefix match. 8353 */ 8354 8355 /* 8356 * Function: 8357 * bcm_vlan_control_set 8358 * 8359 * Purpose: 8360 * Set miscellaneous VLAN-specific chip options 8361 * 8362 * Parameters: 8363 * unit - StrataSwitch PCI device unit number (driver internal). 8364 * type - A value from bcm_vlan_control_t enumeration list 8365 * arg - state whose meaning is dependent on 'type' 8366 * 8367 * Returns: 8368 * BCM_E_NONE - Success 8369 * BCM_E_INTERNAL - Chip access failure. 8370 * BCM_E_UNAVAIL - type not supported on unit 8371 */ 8372 8373 int 8374 bcm_esw_vlan_control_set(int unit, bcm_vlan_control_t type, int arg) 8375 { 8376 bcm_pbmp_t e_pbmp; 8377 8378 #if defined(BCM_HGPROXY_COE_SUPPORT) 8379 int i; 8380 bcm_gport_t gport; 8381 #endif /* BCM_HGPROXY_COE_SUPPORT */ 8382 8383 #ifdef BCM_TOMAHAWK3_SUPPORT 8384 if (SOC_IS_TOMAHAWK3(unit)) { 8385 return bcm_tomahawk3_vlan_control_set(unit, type, arg); 8386 } 8387 #endif 8388 8389 LOG_VERBOSE(BSL_LS_BCM_VLAN, 8390 (BSL_META_U(unit, 8391 "VLAN %d: control set: type %d, arg %d\n"), 8392 unit, type, arg)); 8393 8394 BCM_PBMP_CLEAR(e_pbmp); 8395 BCM_PBMP_ASSIGN(e_pbmp, PBMP_E_ALL(unit)); 8396 #ifdef BCM_KATANA2_SUPPORT 8397 if (soc_feature(unit, soc_feature_linkphy_coe) || 8398 soc_feature(unit, soc_feature_subtag_coe)) { 8399 _bcm_kt2_subport_pbmp_update (unit, &e_pbmp); 8400 } 8401 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 8402 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &e_pbmp)); 8403 } 8404 #endif 8405 8406 #ifdef BCM_XGS3_SWITCH_SUPPORT 8407 if (SOC_IS_XGS3_SWITCH(unit) && (!SOC_IS_XGS3_FABRIC(unit) || 8408 SOC_IS_TOMAHAWK2(unit))) { 8409 bcm_port_t port; 8410 uint32 vlan_ctrl; 8411 uint32 data; 8412 int oval; 8413 8414 PBMP_E_ITER(unit, port) { 8415 break; 8416 } 8417 8418 switch (type) { 8419 case bcmVlanDropUnknown: 8420 return bcm_esw_switch_control_set(unit, 8421 bcmSwitchUnknownVlanToCpu, 8422 arg ? 0 : 1); 8423 8424 case bcmVlanShared: 8425 if (!SOC_REG_FIELD_VALID(unit, EGR_CONFIGr, USE_LEARN_VIDf) || 8426 !SOC_REG_FIELD_VALID(unit, VLAN_CTRLr, USE_LEARN_VIDf)) { 8427 return BCM_E_UNAVAIL; 8428 } 8429 arg = (arg ? 1 : 0); 8430 SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl)); 8431 data = vlan_ctrl; 8432 soc_reg_field_set(unit, VLAN_CTRLr, &vlan_ctrl, 8433 USE_LEARN_VIDf, arg); 8434 if (data != vlan_ctrl) { 8435 SOC_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, vlan_ctrl)); 8436 if (SOC_IS_FBX(unit)) { 8437 SOC_IF_ERROR_RETURN 8438 (soc_reg_field32_modify(unit, EGR_CONFIGr, port, 8439 USE_LEARN_VIDf, arg)); 8440 } 8441 } 8442 return BCM_E_NONE; 8443 case bcmVlanSharedID: 8444 if (!SOC_REG_FIELD_VALID(unit, EGR_CONFIGr, LEARN_VIDf) || 8445 !SOC_REG_FIELD_VALID(unit, VLAN_CTRLr, LEARN_VIDf)) { 8446 return BCM_E_UNAVAIL; 8447 } 8448 SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl)); 8449 data = vlan_ctrl; 8450 soc_reg_field_set(unit, VLAN_CTRLr, &vlan_ctrl, 8451 LEARN_VIDf, arg); 8452 if (data != vlan_ctrl) { 8453 SOC_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, vlan_ctrl)); 8454 if (SOC_IS_FBX(unit)) { 8455 SOC_IF_ERROR_RETURN 8456 (soc_reg_field32_modify(unit, EGR_CONFIGr, port, 8457 LEARN_VIDf, arg)); 8458 } 8459 } 8460 return BCM_E_NONE; 8461 case bcmVlanPreferIP4: 8462 arg = (arg ? 1 : 0); 8463 SOC_IF_ERROR_RETURN 8464 (_bcm_esw_port_config_get(unit, port, 8465 _bcmPortVlanPrecedence, &oval)); 8466 if (arg != oval) { 8467 PBMP_ITER(e_pbmp, port) { 8468 SOC_IF_ERROR_RETURN 8469 (_bcm_esw_port_config_set(unit, port, 8470 _bcmPortVlanPrecedence, arg)); 8471 } 8472 #if defined(BCM_HGPROXY_COE_SUPPORT) 8473 BCM_HGPROXY_SUBTAG_COE_PORT_ITER(i, gport) { 8474 SOC_IF_ERROR_RETURN 8475 (_bcm_esw_port_config_set(unit, gport, 8476 _bcmPortVlanPrecedence, arg)); 8477 } 8478 #endif /* BCM_HGPROXY_COE_SUPPORT */ 8479 } 8480 return BCM_E_NONE; 8481 8482 case bcmVlanPreferMAC: 8483 if (soc_feature(unit, soc_feature_mac_based_vlan)) { 8484 arg = (arg ? 0 : 1); 8485 SOC_IF_ERROR_RETURN 8486 (_bcm_esw_port_config_get(unit, port, 8487 _bcmPortVlanPrecedence, &oval)); 8488 if (arg != oval) { 8489 PBMP_ITER(e_pbmp, port) { 8490 SOC_IF_ERROR_RETURN 8491 (_bcm_esw_port_config_set(unit, port, 8492 _bcmPortVlanPrecedence, arg)); 8493 } 8494 #if defined(BCM_HGPROXY_COE_SUPPORT) 8495 BCM_HGPROXY_SUBTAG_COE_PORT_ITER(i, gport) { 8496 SOC_IF_ERROR_RETURN 8497 (_bcm_esw_port_config_set(unit, gport, 8498 _bcmPortVlanPrecedence, 8499 arg)); 8500 } 8501 #endif /* BCM_HGPROXY_COE_SUPPORT */ 8502 8503 } 8504 return BCM_E_NONE; 8505 } 8506 return BCM_E_UNAVAIL; 8507 8508 case bcmVlanTranslate: 8509 if (soc_feature(unit, soc_feature_vlan_translation)) { 8510 arg = (arg ? 1 : 0); 8511 SOC_IF_ERROR_RETURN 8512 (_bcm_esw_port_config_get(unit, port, 8513 _bcmPortVlanTranslate, &oval)); 8514 if (arg != oval) { 8515 PBMP_ITER(e_pbmp, port) { 8516 #ifdef BCM_TRIDENT2PLUS_SUPPORT 8517 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 8518 if (soc_feature(unit, soc_feature_egr_all_profile)) { 8519 BCM_IF_ERROR_RETURN 8520 (bcm_esw_port_egr_lport_field_set(unit, port, 8521 EGR_VLAN_CONTROL_1m, VT_ENABLEf, arg)); 8522 } else { 8523 egr_vlan_control_1_entry_t entry; 8524 SOC_IF_ERROR_RETURN( 8525 READ_EGR_VLAN_CONTROL_1m(unit, 8526 MEM_BLOCK_ANY, port, &entry)); 8527 soc_EGR_VLAN_CONTROL_1m_field32_set(unit, 8528 &entry, VT_ENABLEf, arg); 8529 SOC_IF_ERROR_RETURN( 8530 WRITE_EGR_VLAN_CONTROL_1m(unit, 8531 MEM_BLOCK_ANY, port, &entry)); 8532 } 8533 } else 8534 #endif 8535 { 8536 SOC_IF_ERROR_RETURN 8537 (soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, 8538 port, VT_ENABLEf, arg)); 8539 } 8540 SOC_IF_ERROR_RETURN 8541 (_bcm_esw_port_config_set(unit, port, 8542 _bcmPortVlanTranslate, arg)); 8543 } 8544 #if defined(BCM_HGPROXY_COE_SUPPORT) 8545 BCM_HGPROXY_SUBTAG_COE_PORT_ITER(i, gport) { 8546 SOC_IF_ERROR_RETURN 8547 (_bcm_esw_port_config_set(unit, gport, 8548 _bcmPortVlanTranslate, 8549 arg)); 8550 } 8551 #endif /* BCM_HGPROXY_COE_SUPPORT */ 8552 } 8553 return BCM_E_NONE; 8554 } 8555 return BCM_E_UNAVAIL; 8556 8557 case bcmVlanPreferEgressTranslate: 8558 arg = (arg ? 1 : 0); 8559 #ifdef BCM_TRX_SUPPORT 8560 if (SOC_IS_TRX(unit)) { 8561 SOC_IF_ERROR_RETURN 8562 (soc_reg_field32_modify(unit, 8563 SOC_IS_TRIDENT3X(unit) ? EGR_CONFIG_1_64r : EGR_CONFIG_1r, 8564 port, DISABLE_VT_IF_IFP_CHANGE_VLANf, arg)); 8565 return BCM_E_NONE; 8566 } 8567 #endif 8568 return BCM_E_UNAVAIL; 8569 default: 8570 return BCM_E_UNAVAIL; 8571 } 8572 } 8573 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 8574 8575 #ifdef BCM_XGS12_SWITCH_SUPPORT 8576 if (SOC_IS_XGS12_SWITCH(unit)) { 8577 bcm_port_t port; 8578 uint64 r64, o64; 8579 switch (type) { 8580 case bcmVlanDropUnknown: 8581 PBMP_E_ITER(unit, port) { 8582 SOC_IF_ERROR_RETURN(READ_CPU_CONTROLr(unit, port, &r64)); 8583 o64 = r64; 8584 soc_reg64_field32_set(unit, CPU_CONTROLr, &r64, 8585 UVLAN_TOCPUf, arg ? 0 : 1); 8586 if (COMPILER_64_NE(r64, o64)) { 8587 SOC_IF_ERROR_RETURN(WRITE_CPU_CONTROLr(unit, port, r64)); 8588 } 8589 } 8590 return BCM_E_NONE; 8591 case bcmVlanShared: 8592 PBMP_E_ITER(unit, port) { 8593 SOC_IF_ERROR_RETURN(READ_VLAN_CONTROLr(unit, port, &r64)); 8594 o64 = r64; 8595 soc_reg64_field32_set(unit, VLAN_CONTROLr, &r64, 8596 USE_LEARN_VIDf, arg ? 1 : 0); 8597 if (COMPILER_64_NE(r64, o64)) { 8598 SOC_IF_ERROR_RETURN(WRITE_VLAN_CONTROLr(unit, port, r64)); 8599 } 8600 } 8601 return BCM_E_NONE; 8602 case bcmVlanSharedID: 8603 PBMP_E_ITER(unit, port) { 8604 SOC_IF_ERROR_RETURN(READ_VLAN_CONTROLr(unit, port, &r64)); 8605 o64 = r64; 8606 soc_reg64_field32_set(unit, VLAN_CONTROLr, &r64, 8607 LEARN_VIDf, arg & 0xfff); 8608 if (COMPILER_64_NE(r64, o64)) { 8609 SOC_IF_ERROR_RETURN(WRITE_VLAN_CONTROLr(unit, port, r64)); 8610 } 8611 } 8612 return BCM_E_NONE; 8613 default: 8614 break; 8615 } 8616 } 8617 #endif /* BCM_XGS12_SWITCH_SUPPORT */ 8618 return BCM_E_UNAVAIL; 8619 } 8620 8621 /* 8622 * Function: 8623 * bcm_vlan_control_get 8624 * 8625 * Purpose: 8626 * Get miscellaneous VLAN-specific chip options 8627 * 8628 * Parameters: 8629 * unit - StrataSwitch PCI device unit number (driver internal). 8630 * type - A value from bcm_vlan_control_t enumeration list 8631 * arg - (OUT) state whose meaning is dependent on 'type' 8632 * 8633 * Returns: 8634 * BCM_E_NONE - Success 8635 * BCM_E_PARAM - arg points to NULL 8636 * BCM_E_INTERNAL - Chip access failure. 8637 * BCM_E_UNAVAIL - type not supported on unit 8638 */ 8639 8640 int 8641 bcm_esw_vlan_control_get(int unit, bcm_vlan_control_t type, int *arg) 8642 { 8643 #ifdef BCM_TOMAHAWK3_SUPPORT 8644 if (SOC_IS_TOMAHAWK3(unit)) { 8645 return bcm_tomahawk3_vlan_control_get(unit, type, arg); 8646 } 8647 #endif 8648 8649 if (arg == 0) { 8650 return BCM_E_PARAM; 8651 } 8652 8653 #ifdef BCM_XGS3_SWITCH_SUPPORT 8654 if (SOC_IS_XGS3_SWITCH(unit) && (!SOC_IS_XGS3_FABRIC(unit) || 8655 SOC_IS_TOMAHAWK2(unit))) { 8656 int port; 8657 uint32 vlan_ctrl; 8658 8659 PBMP_E_ITER(unit, port) { 8660 break; 8661 } 8662 switch (type) { 8663 8664 case bcmVlanDropUnknown: 8665 { 8666 int ret_val; 8667 ret_val = bcm_esw_switch_control_get(unit, 8668 bcmSwitchUnknownVlanToCpu, 8669 arg); 8670 if (ret_val == BCM_E_NONE) { 8671 *arg = (*arg) ? 0 : 1; 8672 } 8673 return ret_val; 8674 } 8675 case bcmVlanShared: 8676 if (!SOC_REG_FIELD_VALID(unit, EGR_CONFIGr, USE_LEARN_VIDf) || 8677 !SOC_REG_FIELD_VALID(unit, VLAN_CTRLr, USE_LEARN_VIDf)) { 8678 return BCM_E_UNAVAIL; 8679 } 8680 SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl)); 8681 *arg = soc_reg_field_get(unit, VLAN_CTRLr, 8682 vlan_ctrl, USE_LEARN_VIDf); 8683 return BCM_E_NONE; 8684 8685 case bcmVlanSharedID: 8686 if (!SOC_REG_FIELD_VALID(unit, EGR_CONFIGr, LEARN_VIDf) || 8687 !SOC_REG_FIELD_VALID(unit, VLAN_CTRLr, LEARN_VIDf)) { 8688 return BCM_E_UNAVAIL; 8689 } 8690 SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl)); 8691 *arg = soc_reg_field_get(unit, VLAN_CTRLr, 8692 vlan_ctrl, LEARN_VIDf); 8693 return BCM_E_NONE; 8694 8695 case bcmVlanPreferIP4: 8696 return (_bcm_esw_port_config_get(unit, port, 8697 _bcmPortVlanPrecedence, arg)); 8698 case bcmVlanPreferMAC: 8699 SOC_IF_ERROR_RETURN 8700 (_bcm_esw_port_config_get(unit, port, 8701 _bcmPortVlanPrecedence, arg)); 8702 *arg = !*arg; 8703 return BCM_E_NONE; 8704 case bcmVlanTranslate: 8705 if (soc_feature(unit, soc_feature_vlan_translation)) { 8706 return (_bcm_esw_port_config_get(unit, port, 8707 _bcmPortVlanTranslate, arg)); 8708 } else { 8709 return BCM_E_UNAVAIL; 8710 } 8711 case bcmVlanPreferEgressTranslate: 8712 #ifdef BCM_TRX_SUPPORT 8713 if (SOC_IS_TRIDENT3X(unit)) { 8714 uint64 rval64; 8715 COMPILER_64_ZERO(rval64); 8716 SOC_IF_ERROR_RETURN(soc_reg_get(unit, EGR_CONFIG_1_64r, 8717 REG_PORT_ANY, 0, &rval64)); 8718 *arg = soc_reg64_field32_get(unit, EGR_CONFIG_1_64r, rval64, 8719 DISABLE_VT_IF_IFP_CHANGE_VLANf); 8720 return BCM_E_NONE; 8721 } else if (SOC_IS_TRX(unit)) { 8722 uint32 egr_cfg; 8723 SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &egr_cfg)); 8724 *arg = soc_reg_field_get(unit, EGR_CONFIG_1r, egr_cfg, 8725 DISABLE_VT_IF_IFP_CHANGE_VLANf); 8726 return BCM_E_NONE; 8727 } 8728 #endif 8729 return BCM_E_UNAVAIL; 8730 default: 8731 return BCM_E_UNAVAIL; 8732 } 8733 } 8734 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 8735 8736 #ifdef BCM_XGS12_SWITCH_SUPPORT 8737 if (SOC_IS_XGS12_SWITCH(unit)) { 8738 int port; 8739 uint64 r64; 8740 switch (type) { 8741 case bcmVlanDropUnknown: 8742 COMPILER_64_ZERO(r64); 8743 PBMP_E_ITER(unit, port) { 8744 SOC_IF_ERROR_RETURN(READ_CPU_CONTROLr(unit, port, &r64)); 8745 break; 8746 } 8747 *arg = !soc_reg64_field32_get(unit, CPU_CONTROLr, r64, 8748 UVLAN_TOCPUf); 8749 return BCM_E_NONE; 8750 case bcmVlanShared: 8751 COMPILER_64_ZERO(r64); 8752 PBMP_E_ITER(unit, port) { 8753 SOC_IF_ERROR_RETURN(READ_VLAN_CONTROLr(unit, port, &r64)); 8754 break; 8755 } 8756 *arg = soc_reg64_field32_get(unit, VLAN_CONTROLr, r64, 8757 USE_LEARN_VIDf); 8758 return BCM_E_NONE; 8759 case bcmVlanSharedID: 8760 COMPILER_64_ZERO(r64); 8761 PBMP_E_ITER(unit, port) { 8762 SOC_IF_ERROR_RETURN(READ_VLAN_CONTROLr(unit, port, &r64)); 8763 break; 8764 } 8765 *arg = soc_reg64_field32_get(unit, VLAN_CONTROLr, r64, 8766 LEARN_VIDf); 8767 return BCM_E_NONE; 8768 default: 8769 return BCM_E_UNAVAIL; 8770 } 8771 } 8772 #endif /* BCM_XGS12_SWITCH_SUPPORT */ 8773 8774 return BCM_E_UNAVAIL; 8775 } 8776 8777 /* 8778 * Function: 8779 * bcm_esw_vlan_control_port_proxy_validate 8780 * Description: 8781 * Checks that vlan port control is valid for a PROXY GPORT. 8782 * Resolves port to expected port value for the given port control type. 8783 * Parameters: 8784 * unit - (IN) Device number 8785 * port - (IN) Port to resolve 8786 * type - (IN) Vlan control type 8787 * port_out - (OUT) Returns port (gport or BCM format) that 8788 * is expected for corresponding vlan control type. 8789 * Return Value: 8790 * BCM_E_XXX 8791 */ 8792 STATIC int 8793 bcm_esw_vlan_control_port_proxy_validate(int unit, bcm_port_t port, 8794 bcm_vlan_control_port_t type, 8795 bcm_port_t *port_out) 8796 { 8797 int rv = BCM_E_PORT; 8798 int support = FALSE; 8799 8800 if (!soc_feature(unit, soc_feature_proxy_port_property)) { 8801 return BCM_E_PORT; 8802 } 8803 8804 switch(type) { 8805 case bcmVlanTranslateIngressEnable: 8806 case bcmVlanPortTranslateKeyFirst: 8807 case bcmVlanPortTranslateKeySecond: 8808 support = TRUE; 8809 break; 8810 default: 8811 support = FALSE; 8812 break; 8813 } 8814 8815 if (support) { 8816 *port_out = port; 8817 rv = BCM_E_NONE; 8818 } 8819 8820 return rv; 8821 } 8822 8823 /* 8824 * Function: 8825 * bcm_esw_vlan_control_port_niv_validate 8826 * Description: 8827 * Checks that vlan port control is valid for a NIV GPORT. 8828 * Resolves port to expected port value for the given port control type. 8829 * Parameters: 8830 * unit - (IN) Device number 8831 * port - (IN) Port to resolve 8832 * type - (IN) Vlan control type 8833 * port_out - (OUT) Returns port (gport or BCM format) that 8834 * is expected for corresponding vlan control type. 8835 * Return Value: 8836 * BCM_E_XXX 8837 */ 8838 STATIC int 8839 bcm_esw_vlan_control_port_niv_validate(int unit, bcm_port_t port, 8840 bcm_vlan_control_port_t type, 8841 bcm_port_t *port_out) 8842 { 8843 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 8844 int rv = BCM_E_PORT; 8845 int support = FALSE; 8846 8847 if (!soc_feature(unit, soc_feature_niv)) { 8848 return BCM_E_PORT; 8849 } 8850 8851 switch(type) { 8852 case bcmVlanPortTranslateKeyFirst: 8853 support = TRUE; 8854 break; 8855 default: 8856 support = FALSE; 8857 break; 8858 } 8859 8860 if (support) { 8861 *port_out = port; 8862 rv = BCM_E_NONE; 8863 } 8864 8865 return rv; 8866 #else 8867 return BCM_E_PORT; 8868 #endif 8869 } 8870 8871 /* 8872 * Function: 8873 * bcm_esw_vlan_control_port_flow_validate 8874 * Description: 8875 * Checks that vlan port control is valid for a FLOW GPORT. 8876 * Resolves port to expected port value for the given port control type. 8877 * Parameters: 8878 * unit - (IN) Device number 8879 * port - (IN) Port to resolve 8880 * type - (IN) Vlan control type 8881 * port_out - (OUT) Returns port (gport or BCM format) that 8882 * is expected for corresponding vlan control type. 8883 * Return Value: 8884 * BCM_E_XXX 8885 */ 8886 STATIC int 8887 bcm_esw_vlan_control_port_flow_validate(int unit, bcm_port_t port, 8888 bcm_vlan_control_port_t type, 8889 bcm_port_t *port_out) 8890 { 8891 #if defined(BCM_TRIDENT3_SUPPORT) && defined(INCLUDE_L3) 8892 int rv = BCM_E_PORT; 8893 int support = FALSE; 8894 8895 if (!soc_feature(unit, soc_feature_flex_flow)) { 8896 return BCM_E_PORT; 8897 } 8898 8899 switch(type) { 8900 case bcmVlanPortTranslateEgressKey: 8901 case bcmVlanPortUseInnerPri: 8902 support = TRUE; 8903 break; 8904 default: 8905 support = FALSE; 8906 break; 8907 } 8908 8909 if (support) { 8910 *port_out = port; 8911 rv = BCM_E_NONE; 8912 } 8913 8914 return rv; 8915 #else 8916 return BCM_E_PORT; 8917 #endif 8918 } 8919 8920 #if defined(BCM_TRX_SUPPORT) 8921 /* 8922 * Function: 8923 * bcm_esw_vlan_control_port_niv_resolve 8924 * Description: 8925 * Resolve NIV GPORT to a BCM local physical port. 8926 * Parameters: 8927 * unit - (IN) Device number 8928 * port - (IN) Port to resolve 8929 * port_out - (OUT) Returns BCM local physical port 8930 * Return Value: 8931 * BCM_E_XXX 8932 */ 8933 STATIC int 8934 bcm_esw_vlan_control_port_niv_resolve(int unit, bcm_port_t port, 8935 bcm_port_t *port_out) 8936 { 8937 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 8938 bcm_niv_port_t niv_port; 8939 bcm_module_t modid; 8940 bcm_port_t local_port; 8941 bcm_trunk_t trunk_id; 8942 int gport_id; 8943 int is_local; 8944 bcm_niv_egress_t niv_egress; 8945 int rv = BCM_E_NONE; 8946 bcm_gport_t gport; 8947 int count; 8948 8949 bcm_niv_port_t_init(&niv_port); 8950 niv_port.niv_port_id = port; 8951 8952 BCM_IF_ERROR_RETURN(bcm_esw_niv_port_get(unit, &niv_port)); 8953 if (niv_port.flags & BCM_NIV_PORT_MATCH_NONE) { 8954 bcm_niv_egress_t_init(&niv_egress); 8955 rv = bcm_trident_niv_egress_get(unit, niv_port.niv_port_id, 8956 1, &niv_egress, &count); 8957 if (BCM_FAILURE(rv)) { 8958 return BCM_E_PARAM; 8959 } 8960 8961 if (niv_egress.flags & BCM_NIV_EGRESS_MULTICAST) { 8962 return BCM_E_PARAM; 8963 } else { 8964 gport = niv_egress.port; 8965 } 8966 } else { 8967 gport = niv_port.port; 8968 } 8969 8970 BCM_IF_ERROR_RETURN 8971 (_bcm_esw_gport_resolve(unit, gport, 8972 &modid, &local_port, 8973 &trunk_id, &gport_id)); 8974 8975 BCM_IF_ERROR_RETURN(_bcm_esw_modid_is_local(unit, modid, &is_local)); 8976 if (!is_local) { 8977 return BCM_E_PORT; 8978 8979 } 8980 8981 *port_out = local_port; 8982 8983 return BCM_E_NONE; 8984 #else 8985 return BCM_E_PORT; 8986 #endif 8987 } 8988 #endif /*BCM_TRX_SUPPORT*/ 8989 /* 8990 * Function: 8991 * bcm_esw_vlan_control_port_validate 8992 * Description: 8993 * Checks that port is valid and that control is supported 8994 * for the given port type. Resolves port to expected 8995 * port value for the given vlan control type. 8996 * Parameters: 8997 * unit - (IN) Device number 8998 * port - (IN) Port to resolve 8999 * type - (IN) Vlan control type 9000 * port_out - (OUT) Returns port (gport or BCM format) that 9001 * is expected for corresponding vlan control type. 9002 * Return Value: 9003 * BCM_E_XXX 9004 */ 9005 STATIC int 9006 bcm_esw_vlan_control_port_validate(int unit, bcm_port_t port, 9007 bcm_vlan_control_port_t type, 9008 bcm_port_t *port_out) 9009 { 9010 bcm_module_t modid; 9011 bcm_port_t port_id; 9012 bcm_trunk_t tgid; 9013 int id; 9014 #if defined(BCM_KATANA2_SUPPORT) 9015 int my_modid = 0, pp_port; 9016 int min_subport = SOC_INFO(unit).pp_port_index_min; 9017 int max_subport = SOC_INFO(unit).pp_port_index_max; 9018 #endif 9019 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HGPROXY_COE_SUPPORT) 9020 int is_local_subport = FALSE; 9021 #endif 9022 9023 if (BCM_GPORT_IS_SET(port)) { 9024 if (BCM_GPORT_IS_PROXY(port)) { 9025 BCM_IF_ERROR_RETURN 9026 (bcm_esw_vlan_control_port_proxy_validate(unit, port, 9027 type, port_out)); 9028 } else if (BCM_GPORT_IS_NIV_PORT(port)) { 9029 BCM_IF_ERROR_RETURN 9030 (bcm_esw_vlan_control_port_niv_validate(unit, port, 9031 type, port_out)); 9032 } else if (BCM_GPORT_IS_FLOW_PORT(port)) { 9033 BCM_IF_ERROR_RETURN 9034 (bcm_esw_vlan_control_port_flow_validate(unit, port, 9035 type, port_out)); 9036 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 9037 9038 #if defined(BCM_HGPROXY_COE_SUPPORT) 9039 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9040 BCM_GPORT_IS_SET(port) && 9041 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 9042 9043 if(_bcm_xgs5_subport_coe_gport_local(unit, port)) { 9044 is_local_subport = TRUE; 9045 } 9046 9047 if (is_local_subport == FALSE) { 9048 return BCM_E_PORT; 9049 } 9050 9051 /*For HGPROXY_COE, subport is needed for configuring 9052 *port and lport tables. 9053 */ 9054 *port_out = port; 9055 9056 } else 9057 #endif 9058 #if defined(BCM_KATANA2_SUPPORT) 9059 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) { 9060 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 9061 &modid, &port_id, &tgid, &id)); 9062 pp_port = BCM_GPORT_SUBPORT_PORT_GET(port); 9063 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 9064 if ((_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE) || 9065 (soc_feature(unit, soc_feature_general_cascade) && 9066 SOC_PBMP_MEMBER(SOC_INFO(unit).general_pp_port_pbm, pp_port))) { 9067 #if defined BCM_METROLITE_SUPPORT 9068 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 9069 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 9070 is_local_subport = 1; 9071 *port_out = pp_port; 9072 } 9073 } else 9074 #endif 9075 { 9076 if ((pp_port >= min_subport) && 9077 (pp_port <= max_subport)) { 9078 is_local_subport = 1; 9079 *port_out = pp_port; 9080 } 9081 } 9082 } 9083 if (is_local_subport == 0) { 9084 return BCM_E_PORT; 9085 } 9086 } else 9087 #endif 9088 { 9089 return BCM_E_PORT; 9090 } 9091 } else { 9092 /* Other GPORT types */ 9093 if (BCM_SUCCESS(_bcm_vlan_control_trust_gport(type))) { 9094 *port_out = port; 9095 } else { 9096 BCM_IF_ERROR_RETURN 9097 (_bcm_esw_gport_resolve(unit, port, &modid, &port_id, 9098 &tgid, &id)); 9099 if ((id != -1) || (tgid != -1)) { 9100 return BCM_E_PORT; 9101 } 9102 *port_out = port_id; 9103 } 9104 } 9105 9106 } else { 9107 9108 #ifdef BCM_KATANA2_SUPPORT 9109 if ((soc_feature(unit, soc_feature_linkphy_coe) && 9110 BCM_PBMP_MEMBER(SOC_INFO(unit).linkphy_pp_port_pbm, port)) || 9111 (soc_feature(unit, soc_feature_subtag_coe) && 9112 BCM_PBMP_MEMBER(SOC_INFO(unit).subtag_pp_port_pbm, port))) { 9113 } else 9114 #endif 9115 if (!SOC_PORT_VALID(unit, port)) { 9116 return BCM_E_PORT; 9117 } 9118 *port_out = port; 9119 } 9120 9121 return BCM_E_NONE; 9122 } 9123 9124 STATIC int 9125 _bcm_vlan_control_port_set(int unit, int port, 9126 bcm_vlan_control_port_t type, int arg) 9127 { 9128 #if defined(BCM_FIREBOLT_SUPPORT) 9129 if (SOC_IS_FBX(unit)) { 9130 uint32 data; 9131 uint32 evc; 9132 soc_reg_t egr_register; 9133 int key_type_value; 9134 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9135 soc_field_t field = VT_ENABLEf; 9136 soc_mem_t egr_mem; 9137 egr_mem = EGR_VLAN_CONTROL_1m; 9138 #endif 9139 egr_register = EGR_VLAN_CONTROL_1r; 9140 9141 switch (type) { 9142 case bcmVlanPortPreferIP4: 9143 arg = (arg ? 1 : 0); 9144 return (_bcm_esw_port_config_set(unit, port, 9145 _bcmPortVlanPrecedence, arg)); 9146 9147 case bcmVlanPortPreferMAC: 9148 arg = (arg ? 0 : 1); 9149 return (_bcm_esw_port_config_set(unit, port, 9150 _bcmPortVlanPrecedence, arg)); 9151 9152 case bcmVlanTranslateIngressEnable: 9153 if (soc_feature(unit, soc_feature_vlan_translation)) { 9154 arg = (arg ? 1 : 0); 9155 return (_bcm_esw_port_config_set(unit, port, 9156 _bcmPortVlanTranslate, arg)); 9157 } 9158 return BCM_E_UNAVAIL; 9159 9160 case bcmVlanTranslateIngressMissDrop: 9161 if (soc_feature(unit, soc_feature_vlan_translation)) { 9162 arg = (arg ? 1 : 0); 9163 return (_bcm_esw_port_config_set(unit, port, 9164 _bcmPortVTMissDrop, arg)); 9165 } 9166 return BCM_E_UNAVAIL; 9167 9168 case bcmVlanTranslateEgressEnable: 9169 if (soc_feature(unit, soc_feature_vlan_translation)) { 9170 arg = (arg ? 1 : 0); 9171 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9172 if (SOC_MEM_IS_VALID(unit, egr_mem)) { 9173 egr_vlan_control_1_entry_t entry; 9174 if (soc_feature(unit, soc_feature_egr_all_profile) 9175 #if defined(BCM_HGPROXY_COE_SUPPORT) 9176 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9177 BCM_GPORT_IS_SET(port) && 9178 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9179 #endif 9180 ) { 9181 SOC_IF_ERROR_RETURN( 9182 bcm_esw_port_egr_lport_field_set(unit, port, 9183 EGR_VLAN_CONTROL_1m, VT_ENABLEf, arg)); 9184 return BCM_E_NONE; 9185 } 9186 SOC_IF_ERROR_RETURN 9187 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9188 data = soc_mem_field32_get(unit, egr_mem, &entry, VT_ENABLEf); 9189 if (data != arg) { 9190 soc_mem_field32_set(unit, egr_mem, &entry, VT_ENABLEf, arg); 9191 return (soc_mem_write(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9192 } 9193 } else 9194 #endif 9195 { 9196 SOC_IF_ERROR_RETURN 9197 (soc_reg32_get(unit, egr_register, port, 0, &evc)); 9198 data = evc; 9199 soc_reg_field_set(unit, egr_register, &evc, VT_ENABLEf, arg); 9200 if (evc != data) { 9201 return (soc_reg32_set(unit, egr_register, port, 0, evc)); 9202 } 9203 } 9204 return BCM_E_NONE; 9205 } 9206 return BCM_E_UNAVAIL; 9207 9208 case bcmVlanTranslateEgressMissDrop: 9209 if (soc_feature(unit, soc_feature_vlan_translation)) { 9210 arg = (arg ? 1 : 0); 9211 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9212 if (SOC_MEM_IS_VALID(unit, egr_mem)) { 9213 egr_vlan_control_1_entry_t entry; 9214 if (soc_feature(unit, soc_feature_egr_all_profile) 9215 #if defined(BCM_HGPROXY_COE_SUPPORT) 9216 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9217 BCM_GPORT_IS_SET(port) && 9218 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9219 #endif 9220 ) { 9221 SOC_IF_ERROR_RETURN( 9222 bcm_esw_port_egr_lport_field_set(unit, port, 9223 EGR_VLAN_CONTROL_1m, VT_MISS_DROPf, arg)); 9224 return BCM_E_NONE; 9225 } 9226 SOC_IF_ERROR_RETURN 9227 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9228 data = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_DROPf); 9229 if (data != arg) { 9230 soc_mem_field32_set(unit, egr_mem, &entry, VT_MISS_DROPf, arg); 9231 return (soc_mem_write(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9232 } 9233 } else 9234 #endif 9235 { 9236 SOC_IF_ERROR_RETURN 9237 (soc_reg32_get(unit, egr_register, port, 0, &evc)); 9238 data = evc; 9239 soc_reg_field_set(unit, egr_register, &evc, VT_MISS_DROPf, arg); 9240 if (evc != data) { 9241 return (soc_reg32_set(unit, egr_register, port, 0, evc)); 9242 } 9243 } 9244 return BCM_E_NONE; 9245 } 9246 return BCM_E_UNAVAIL; 9247 9248 case bcmVlanTranslateEgressMissUntaggedDrop: 9249 if ((soc_feature(unit, soc_feature_untagged_vt_miss)) && 9250 (soc_feature(unit,soc_feature_vlan_translation))) { 9251 arg = (arg ? 1 : 0); 9252 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9253 if (SOC_MEM_IS_VALID(unit, egr_mem)) { 9254 egr_vlan_control_1_entry_t entry; 9255 if (soc_feature(unit, soc_feature_egr_all_profile) 9256 #if defined(BCM_HGPROXY_COE_SUPPORT) 9257 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9258 BCM_GPORT_IS_SET(port) && 9259 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9260 #endif 9261 ) { 9262 SOC_IF_ERROR_RETURN( 9263 bcm_esw_port_egr_lport_field_set(unit, port, 9264 EGR_VLAN_CONTROL_1m, VT_MISS_UT_DROPf, arg)); 9265 return BCM_E_NONE; 9266 } 9267 SOC_IF_ERROR_RETURN 9268 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9269 data = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_UT_DROPf); 9270 if (data != arg) { 9271 soc_mem_field32_set(unit, egr_mem, &entry, VT_MISS_UT_DROPf, arg); 9272 SOC_IF_ERROR_RETURN 9273 (soc_mem_write(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9274 } 9275 } else 9276 #endif 9277 { 9278 SOC_IF_ERROR_RETURN 9279 (soc_reg32_get(unit, egr_register, port, 0, &evc)); 9280 data = evc; 9281 soc_reg_field_set(unit, egr_register, &evc, VT_MISS_UT_DROPf, 9282 arg); 9283 if (evc != data) { 9284 SOC_IF_ERROR_RETURN 9285 (soc_reg32_set(unit, egr_register, port, 0, evc)); 9286 } 9287 } 9288 return BCM_E_NONE; 9289 } 9290 return BCM_E_UNAVAIL; 9291 9292 case bcmVlanTranslateEgressMissUntag: 9293 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || \ 9294 defined(BCM_RAVEN_SUPPORT) 9295 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9296 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 9297 egr_vlan_control_1_entry_t entry; 9298 if (SOC_MEM_FIELD_VALID(unit, egr_mem, VT_MISS_UNTAGf)) { 9299 arg = (arg ? 1 : 0); 9300 if (soc_feature(unit, soc_feature_egr_all_profile) 9301 #if defined(BCM_HGPROXY_COE_SUPPORT) 9302 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9303 BCM_GPORT_IS_SET(port) && 9304 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9305 #endif 9306 ) { 9307 SOC_IF_ERROR_RETURN( 9308 bcm_esw_port_egr_lport_field_set(unit, port, 9309 EGR_VLAN_CONTROL_1m, VT_MISS_UNTAGf, arg)); 9310 if (SOC_IS_TRIDENT3X(unit)) { 9311 SOC_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, 9312 port,VXLT_CTRL_IDf, arg)); 9313 } 9314 return BCM_E_NONE; 9315 } 9316 SOC_IF_ERROR_RETURN(soc_mem_read(unit, egr_mem, 9317 MEM_BLOCK_ANY, port, &entry)); 9318 soc_mem_field32_set(unit, egr_mem, &entry, 9319 VT_MISS_UNTAGf, arg); 9320 return soc_mem_write(unit, EGR_VLAN_CONTROL_1m, 9321 MEM_BLOCK_ANY, port, &entry); 9322 } 9323 } else 9324 #endif 9325 { 9326 if (SOC_REG_FIELD_VALID(unit, egr_register, VT_MISS_UNTAGf)) { 9327 arg = (arg ? 1 : 0); 9328 return soc_reg_field32_modify(unit, egr_register, port, 9329 VT_MISS_UNTAGf, arg); 9330 } 9331 } 9332 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRIUMPH_SUPPORT || BCM_RAPTOR_SUPPORT */ 9333 return BCM_E_UNAVAIL; 9334 9335 case bcmVlanLookupMACEnable: 9336 arg = (arg ? 1 : 0); 9337 return (_bcm_esw_port_config_set(unit, port, 9338 _bcmPortLookupMACEnable, arg)); 9339 9340 case bcmVlanLookupIPEnable: 9341 arg = (arg ? 1 : 0); 9342 return (_bcm_esw_port_config_set(unit, port, 9343 _bcmPortLookupIPEnable, arg)); 9344 9345 case bcmVlanPortUseInnerPri: 9346 arg = (arg ? 1 : 0); 9347 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 9348 if (BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port) || 9349 BCM_GPORT_IS_VXLAN_PORT(port)) { 9350 return (_bcm_tr2_svp_field_set(unit, port, 9351 USE_INNER_PRIf, arg)); 9352 } 9353 #endif 9354 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 9355 || defined(BCM_RAVEN_SUPPORT) 9356 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_TRX(unit) || 9357 SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 9358 if (BCM_GPORT_IS_SET(port)) { 9359 BCM_IF_ERROR_RETURN( 9360 bcm_esw_port_local_get(unit, port, &port)); 9361 } 9362 return (_bcm_esw_port_config_set(unit, port, 9363 _bcmPortUseInnerPri, arg)); 9364 } 9365 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 9366 return BCM_E_UNAVAIL; 9367 9368 case bcmVlanPortUseOuterPri: 9369 arg = (arg ? 1 : 0); 9370 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 9371 if (BCM_GPORT_IS_MPLS_PORT(port) || BCM_GPORT_IS_MIM_PORT(port)) { 9372 int rv = BCM_E_NONE; 9373 rv = _bcm_tr2_svp_field_set(unit, port, 9374 TRUST_OUTER_DOT1Pf, arg); 9375 if (rv == BCM_E_UNAVAIL) { 9376 return BCM_E_PORT; 9377 } else { 9378 return rv; 9379 } 9380 } 9381 #endif 9382 #if defined(BCM_TRX_SUPPORT) 9383 if (SOC_IS_TRX(unit)) { 9384 if (BCM_GPORT_IS_SET(port)) { 9385 BCM_IF_ERROR_RETURN( 9386 bcm_esw_port_local_get(unit, port, &port)); 9387 } 9388 return (_bcm_esw_port_config_set(unit, port, 9389 _bcmPortUseOuterPri, arg)); 9390 } 9391 #endif /* BCM_TRX_SUPPORT */ 9392 return BCM_E_UNAVAIL; 9393 9394 case bcmVlanPortVerifyOuterTpid: 9395 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAPTOR_SUPPORT) \ 9396 || defined(BCM_TRX_SUPPORT) 9397 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 9398 SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) { 9399 arg = (arg ? 1 : 0); 9400 return (_bcm_esw_port_config_set(unit, port, 9401 _bcmPortVerifyOuterTpid, arg)); 9402 } 9403 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAPTOR_SUPPORT || BCM_TRX_SUPPORT */ 9404 return BCM_E_UNAVAIL; 9405 9406 case bcmVlanPortOuterTpidSelect: 9407 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 9408 || defined(BCM_TRX_SUPPORT) 9409 if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 9410 SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) && 9411 !SOC_IS_SHADOW(unit)) { 9412 if (arg != BCM_PORT_OUTER_TPID && 9413 arg != BCM_VLAN_OUTER_TPID) { 9414 return BCM_E_PARAM; 9415 } 9416 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9417 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 9418 egr_vlan_control_1_entry_t entry; 9419 soc_field_t tpid_sel_f = OUTER_TPID_VALIDf; 9420 if (SOC_MEM_FIELD_VALID(unit, EGR_VLAN_CONTROL_1m, 9421 OUTER_TPID_SELf)) { 9422 tpid_sel_f = OUTER_TPID_SELf; 9423 } 9424 if (soc_feature(unit, soc_feature_egr_all_profile) 9425 #if defined(BCM_HGPROXY_COE_SUPPORT) 9426 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9427 BCM_GPORT_IS_SET(port) && 9428 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9429 #endif 9430 ) { 9431 SOC_IF_ERROR_RETURN( 9432 bcm_esw_port_egr_lport_field_set(unit, port, 9433 EGR_VLAN_CONTROL_1m, tpid_sel_f, arg)); 9434 return BCM_E_NONE; 9435 } 9436 SOC_IF_ERROR_RETURN( 9437 READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, 9438 &entry)); 9439 data = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry, 9440 tpid_sel_f); 9441 if (arg != data) { 9442 soc_EGR_VLAN_CONTROL_1m_field32_set(unit, &entry, 9443 tpid_sel_f, arg); 9444 SOC_IF_ERROR_RETURN( 9445 WRITE_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, 9446 port, &entry)); 9447 } 9448 } else 9449 #endif 9450 { 9451 SOC_IF_ERROR_RETURN 9452 (READ_EGR_VLAN_CONTROL_1r(unit, port, &evc)); 9453 data = evc; 9454 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &evc, 9455 OUTER_TPID_SELf, arg); 9456 if (evc != data) { 9457 SOC_IF_ERROR_RETURN 9458 (WRITE_EGR_VLAN_CONTROL_1r(unit, port, evc)); 9459 } 9460 } 9461 return BCM_E_NONE; 9462 } 9463 9464 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 9465 return BCM_E_UNAVAIL; 9466 9467 case bcmVlanPortTranslateKeyFirst: 9468 case bcmVlanPortTranslateKeySecond: 9469 #if defined(BCM_TRX_SUPPORT) 9470 if (SOC_IS_TRX(unit)) { 9471 _bcm_port_config_t vt_key_type; 9472 _bcm_port_config_t vt_key_port; 9473 int rv, key_type = 0, use_port = 0; 9474 switch (arg) { 9475 case bcmVlanTranslateKeyPortDouble: 9476 use_port = 1; 9477 /* fall through */ 9478 case bcmVlanTranslateKeyDouble: 9479 key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 9480 break; 9481 case bcmVlanTranslateKeyPortOuterTag: 9482 use_port = 1; 9483 /* fall through */ 9484 case bcmVlanTranslateKeyOuterTag: 9485 key_type = VLXLT_HASH_KEY_TYPE_OTAG; 9486 break; 9487 case bcmVlanTranslateKeyPortInnerTag: 9488 use_port = 1; 9489 /* fall through */ 9490 case bcmVlanTranslateKeyInnerTag: 9491 key_type = VLXLT_HASH_KEY_TYPE_ITAG; 9492 break; 9493 case bcmVlanTranslateKeyPortOuter: 9494 use_port = 1; 9495 /* fall through */ 9496 case bcmVlanTranslateKeyOuter: 9497 key_type = VLXLT_HASH_KEY_TYPE_OVID; 9498 break; 9499 case bcmVlanTranslateKeyPortInner: 9500 use_port = 1; 9501 /* fall through */ 9502 case bcmVlanTranslateKeyInner: 9503 key_type = VLXLT_HASH_KEY_TYPE_IVID; 9504 break; 9505 case bcmVlanTranslateKeyPortOuterPri: 9506 use_port = 1; 9507 /* fall through */ 9508 case bcmVlanTranslateKeyOuterPri: 9509 key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 9510 break; 9511 case bcmVlanTranslateKeyPortPonTunnel: 9512 use_port = 1; 9513 key_type = VLXLT_HASH_KEY_TYPE_LLVID; 9514 break; 9515 case bcmVlanTranslateKeyPortPonTunnelOuter: 9516 use_port = 1; 9517 key_type = VLXLT_HASH_KEY_TYPE_LLVID_OVID; 9518 break; 9519 case bcmVlanTranslateKeyPortPonTunnelInner: 9520 key_type = VLXLT_HASK_KEY_TYPE_LLVID_IVID; 9521 use_port = 1; 9522 break; 9523 case bcmVlanTranslateKeyPortCapwapPayloadDouble: 9524 use_port = 1; 9525 /* fall through */ 9526 case bcmVlanTranslateKeyCapwapPayloadDouble: 9527 key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID; 9528 break; 9529 case bcmVlanTranslateKeyPortCapwapPayloadOuter: 9530 use_port = 1; 9531 /* fall through */ 9532 case bcmVlanTranslateKeyCapwapPayloadOuter: 9533 key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID; 9534 break; 9535 case bcmVlanTranslateKeyPortCapwapPayloadInner: 9536 use_port = 1; 9537 /* fall through */ 9538 case bcmVlanTranslateKeyCapwapPayloadInner: 9539 key_type =VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID; 9540 break; 9541 case bcmVlanTranslateKeyPortCapwapPayloadOuterTag: 9542 use_port = 1; 9543 /* fall through */ 9544 case bcmVlanTranslateKeyCapwapPayloadOuterTag: 9545 key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG; 9546 break; 9547 case bcmVlanTranslateKeyPortCapwapPayloadInnerTag: 9548 use_port = 1; 9549 /* fall through */ 9550 case bcmVlanTranslateKeyCapwapPayloadInnerTag: 9551 key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG; 9552 break; 9553 case bcmVlanTranslateKeyPortVxlanVnid: 9554 use_port = 1; 9555 /* fall through */ 9556 case bcmVlanTranslateKeyVxlanVnid: 9557 key_type = VLXLT_HASH_KEY_TYPE_VNID; 9558 break; 9559 #if defined(BCM_TRIDENT2_SUPPORT) 9560 case bcmVlanTranslateKeyPortGroupDouble: 9561 use_port = 3; /* port_group */ 9562 key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 9563 break; 9564 case bcmVlanTranslateKeyPortGroupOuterTag: 9565 use_port = 3; /* port_group */ 9566 key_type = VLXLT_HASH_KEY_TYPE_OTAG; 9567 break; 9568 case bcmVlanTranslateKeyPortGroupInnerTag: 9569 use_port = 3; /* port_group */ 9570 key_type = VLXLT_HASH_KEY_TYPE_ITAG; 9571 break; 9572 case bcmVlanTranslateKeyPortGroupOuter: 9573 use_port = 3; /* port_group */ 9574 key_type = VLXLT_HASH_KEY_TYPE_OVID; 9575 break; 9576 case bcmVlanTranslateKeyPortGroupInner: 9577 use_port = 3; /* port_group */ 9578 key_type = VLXLT_HASH_KEY_TYPE_IVID; 9579 break; 9580 case bcmVlanTranslateKeyPortGroupOuterPri: 9581 use_port = 3; /* port_group */ 9582 key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 9583 break; 9584 #endif /* BCM_TRIDENT2_SUPPORT */ 9585 case bcmVlanTranslateKeyMacPort: 9586 use_port = 1; /* Port */ 9587 key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT; 9588 break; 9589 case bcmVlanTranslateKeyMacVirtualPort: 9590 use_port = 2; /* Virtual Port */ 9591 key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT; 9592 break; 9593 case bcmVlanTranslateKeyMacPortGroup: 9594 use_port = 3; /* Port Group */ 9595 key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT; 9596 break; 9597 default: 9598 return BCM_E_PARAM; 9599 } 9600 9601 if (BCM_GPORT_IS_NIV_PORT(port)) { 9602 switch (arg) { 9603 case bcmVlanTranslateKeyPortOuterTag: 9604 key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG; 9605 break; 9606 9607 case bcmVlanTranslateKeyPortInnerTag: 9608 key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG; 9609 break; 9610 9611 case bcmVlanTranslateKeyPortOuter: 9612 key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN; 9613 break; 9614 9615 case bcmVlanTranslateKeyPortInner: 9616 key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN; 9617 break; 9618 9619 default: 9620 return BCM_E_PARAM; 9621 } 9622 9623 BCM_IF_ERROR_RETURN 9624 (bcm_esw_vlan_control_port_niv_resolve(unit, 9625 port, &port)); 9626 use_port = 1; 9627 } 9628 9629 if ((use_port == 3) && 9630 !(soc_feature(unit, soc_feature_port_group_for_ivxlt))) { 9631 return BCM_E_UNAVAIL; 9632 } 9633 9634 if (type == bcmVlanPortTranslateKeyFirst) { 9635 vt_key_type = _bcmPortVTKeyTypeFirst; 9636 vt_key_port = _bcmPortVTKeyPortFirst; 9637 } else { 9638 vt_key_type = _bcmPortVTKeyTypeSecond; 9639 vt_key_port = _bcmPortVTKeyPortSecond; 9640 } 9641 BCM_IF_ERROR_RETURN 9642 (_bcm_esw_pt_vtkey_type_value_get(unit, 9643 key_type,&key_type_value)); 9644 9645 rv = _bcm_esw_port_config_set(unit, port, 9646 vt_key_type, 9647 key_type_value); 9648 if (rv < 0) { 9649 return rv; 9650 } 9651 return (_bcm_esw_port_config_set(unit, port, 9652 vt_key_port, 9653 use_port)); 9654 } 9655 #endif /* BCM_TRX_SUPPORT */ 9656 return BCM_E_UNAVAIL; 9657 9658 #if defined(BCM_KATANA2_SUPPORT) 9659 case bcmVlanPortOamUseXlatedInnerVlan: 9660 if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_oam))) { 9661 arg = (arg ? 1 : 0); 9662 return (_bcm_esw_port_config_set(unit, port, 9663 _bcmPortOamUseXlatedInnerVlan, arg)); 9664 } 9665 return BCM_E_UNAVAIL; 9666 break; 9667 #endif /* BCM_KATANA2_SUPPORT */ 9668 9669 case bcmVlanPortTranslateEgressKey: 9670 case bcmVlanPortTranslateEgressKeyFirst: 9671 case bcmVlanPortTranslateEgressKeySecond: 9672 if ((arg < bcmVlanTranslateEgressKeyInvalid) || 9673 (arg >= bcmVlanTranslateEgressKeyCount)) { 9674 return BCM_E_PARAM; 9675 } 9676 9677 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 9678 if (bcmVlanPortTranslateEgressKeySecond == type) { 9679 if (soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) { 9680 field = VT2_ENABLEf; 9681 } else { 9682 return BCM_E_UNAVAIL; 9683 } 9684 } 9685 9686 if (soc_feature(unit, soc_feature_egr_vlan_xlate_key_on_dvp)) { 9687 if (BCM_GPORT_IS_VXLAN_PORT(port) || BCM_GPORT_IS_MIM_PORT(port) 9688 || BCM_GPORT_IS_MPLS_PORT(port) || BCM_GPORT_IS_L2GRE_PORT(port)) { 9689 if (bcmVlanPortTranslateEgressKeySecond == type) { 9690 /* Second EVxlate lookup is not supported with VPs */ 9691 return BCM_E_UNAVAIL; 9692 } 9693 9694 BCM_IF_ERROR_RETURN 9695 (_bcm_esw_dvp_vtkey_type_value_get(unit, arg, 9696 &key_type_value)); 9697 return (bcm_td2p_dvp_vlan_xlate_key_set(unit, port, 9698 key_type_value)); 9699 } else if (BCM_GPORT_IS_FLOW_PORT(port)) { 9700 int rv = BCM_E_UNAVAIL; 9701 #ifdef BCM_TRIDENT3_SUPPORT 9702 if (soc_feature(unit,soc_feature_flex_flow)) { 9703 rv = bcmi_esw_flow_dvp_vlan_xlate_key_set(unit, 9704 port, arg); 9705 } 9706 #endif 9707 return rv; 9708 } 9709 } 9710 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 9711 9712 BCM_IF_ERROR_RETURN 9713 (_bcm_esw_egr_vtkey_type_value_get(unit, arg, 9714 &key_type_value)); 9715 9716 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9717 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 9718 egr_vlan_control_1_entry_t entry; 9719 if (soc_feature(unit, soc_feature_egr_all_profile) 9720 #if defined(BCM_HGPROXY_COE_SUPPORT) 9721 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9722 BCM_GPORT_IS_SET(port) && 9723 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9724 #endif 9725 ) { 9726 SOC_IF_ERROR_RETURN( 9727 bcm_esw_port_egr_lport_field_set(unit, port, 9728 EGR_VLAN_CONTROL_1m, field, key_type_value)); 9729 return BCM_E_NONE; 9730 } 9731 if (BCM_GPORT_IS_LOCAL(port)) { 9732 port = BCM_GPORT_LOCAL_GET(port); 9733 } 9734 if (!SOC_PORT_VALID(unit, port)) { 9735 return BCM_E_PORT; 9736 } 9737 9738 SOC_IF_ERROR_RETURN 9739 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9740 data = soc_mem_field32_get(unit, egr_mem, &entry, field); 9741 9742 if (data != key_type_value) { 9743 soc_mem_field32_set(unit, egr_mem, &entry, field, key_type_value); 9744 return (soc_mem_write(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9745 } 9746 return BCM_E_NONE; 9747 } else 9748 #endif 9749 { 9750 /* 9751 * We reach here for devices where EGR_VLAN_CONTROL_1 is a register; 9752 * There's nothing to set for them as VT_ENABLEf in the register 9753 * would have been programmed through bcmVlanTranslateEgressEnable 9754 */ 9755 return BCM_E_NONE; 9756 } 9757 default: 9758 return BCM_E_UNAVAIL; 9759 } 9760 } 9761 #endif /* BCM_FIREBOLT_SUPPORT */ 9762 return BCM_E_UNAVAIL; 9763 } 9764 9765 int 9766 bcm_esw_vlan_control_port_set(int unit, bcm_port_t port, 9767 bcm_vlan_control_port_t type, int arg) 9768 { 9769 bcm_pbmp_t temp_pbmp; 9770 #if defined(BCM_HGPROXY_COE_SUPPORT) 9771 int i; 9772 bcm_gport_t gport; 9773 #endif /* BCM_HGPROXY_COE_SUPPORT */ 9774 9775 #ifdef BCM_TOMAHAWK3_SUPPORT 9776 if (SOC_IS_TOMAHAWK3(unit)) { 9777 return bcm_tomahawk3_vlan_control_port_set(unit, port, type, arg); 9778 } 9779 #endif 9780 9781 if (port == -1) { 9782 BCM_PBMP_CLEAR(temp_pbmp); 9783 BCM_PBMP_ASSIGN(temp_pbmp, PBMP_E_ALL(unit)); 9784 9785 #ifdef BCM_KATANA2_SUPPORT 9786 if (soc_feature(unit, soc_feature_linkphy_coe) || 9787 soc_feature(unit, soc_feature_subtag_coe)) { 9788 _bcm_kt2_subport_pbmp_update (unit, &temp_pbmp); 9789 } 9790 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 9791 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &temp_pbmp)); 9792 } 9793 #endif 9794 9795 PBMP_ITER(temp_pbmp, port) { 9796 BCM_IF_ERROR_RETURN 9797 (_bcm_vlan_control_port_set(unit, port, type, arg)); 9798 } 9799 9800 #if defined(BCM_HGPROXY_COE_SUPPORT) 9801 BCM_HGPROXY_SUBTAG_COE_PORT_ITER(i, gport) { 9802 BCM_IF_ERROR_RETURN 9803 (_bcm_vlan_control_port_set(unit, gport, type, arg)); 9804 } 9805 #endif /* BCM_HGPROXY_COE_SUPPORT */ 9806 } else { 9807 BCM_IF_ERROR_RETURN 9808 (bcm_esw_vlan_control_port_validate(unit, port, type, &port)); 9809 return _bcm_vlan_control_port_set(unit, port, type, arg); 9810 } 9811 9812 return BCM_E_NONE; 9813 } 9814 9815 int 9816 bcm_esw_vlan_control_port_get(int unit, bcm_port_t port, 9817 bcm_vlan_control_port_t type, int * arg) 9818 { 9819 #ifdef BCM_TOMAHAWK3_SUPPORT 9820 if (SOC_IS_TOMAHAWK3(unit)) { 9821 return bcm_tomahawk3_vlan_control_port_get(unit, port, type, arg); 9822 } 9823 #endif 9824 9825 if (arg == 0) { 9826 return BCM_E_PARAM; 9827 } 9828 9829 BCM_IF_ERROR_RETURN 9830 (bcm_esw_vlan_control_port_validate(unit, port, type, &port)); 9831 9832 #if defined(BCM_FIREBOLT_SUPPORT) 9833 if (SOC_IS_FBX(unit)) { 9834 uint32 evc; 9835 soc_reg_t egr_register; 9836 int key_type_value; 9837 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9838 soc_field_t field = VT_ENABLEf; 9839 soc_mem_t egr_mem; 9840 egr_mem = EGR_VLAN_CONTROL_1m; 9841 #endif 9842 egr_register = EGR_VLAN_CONTROL_1r; 9843 9844 switch (type) { 9845 case bcmVlanPortPreferIP4: 9846 return _bcm_esw_port_config_get(unit, port, _bcmPortVlanPrecedence, 9847 arg); 9848 9849 case bcmVlanPortPreferMAC: 9850 SOC_IF_ERROR_RETURN 9851 (_bcm_esw_port_config_get(unit, port, _bcmPortVlanPrecedence, 9852 arg)); 9853 *arg = !*arg; 9854 return BCM_E_NONE; 9855 9856 case bcmVlanTranslateIngressEnable: 9857 if (soc_feature(unit, soc_feature_vlan_translation)) { 9858 return (_bcm_esw_port_config_get(unit, port, 9859 _bcmPortVlanTranslate, arg)); 9860 } 9861 return BCM_E_UNAVAIL; 9862 9863 case bcmVlanTranslateIngressMissDrop: 9864 if (soc_feature(unit, soc_feature_vlan_translation)) { 9865 return (_bcm_esw_port_config_get(unit, port, 9866 _bcmPortVTMissDrop, arg)); 9867 } 9868 return BCM_E_UNAVAIL; 9869 9870 case bcmVlanTranslateEgressEnable: 9871 if (soc_feature(unit, soc_feature_vlan_translation)) { 9872 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9873 if (SOC_MEM_IS_VALID(unit, egr_mem)) { 9874 egr_vlan_control_1_entry_t entry; 9875 if (soc_feature(unit, soc_feature_egr_all_profile) 9876 #if defined(BCM_HGPROXY_COE_SUPPORT) 9877 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9878 BCM_GPORT_IS_SET(port) && 9879 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9880 #endif 9881 ) { 9882 SOC_IF_ERROR_RETURN( 9883 bcm_esw_port_egr_lport_field_get(unit, port, 9884 EGR_VLAN_CONTROL_1m, VT_ENABLEf, (uint32 *)arg)); 9885 return BCM_E_NONE; 9886 } 9887 SOC_IF_ERROR_RETURN 9888 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9889 *arg = soc_mem_field32_get(unit, egr_mem, &entry, VT_ENABLEf); 9890 } else 9891 #endif 9892 { 9893 SOC_IF_ERROR_RETURN 9894 (soc_reg32_get(unit, egr_register, port, 0, &evc)); 9895 *arg = soc_reg_field_get(unit, egr_register, evc, VT_ENABLEf); 9896 } 9897 return BCM_E_NONE; 9898 } 9899 return BCM_E_UNAVAIL; 9900 9901 case bcmVlanTranslateEgressMissDrop: 9902 if (soc_feature(unit, soc_feature_vlan_translation)) { 9903 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9904 if (SOC_MEM_IS_VALID(unit, egr_mem)) { 9905 egr_vlan_control_1_entry_t entry; 9906 if (soc_feature(unit, soc_feature_egr_all_profile) 9907 #if defined(BCM_HGPROXY_COE_SUPPORT) 9908 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9909 BCM_GPORT_IS_SET(port) && 9910 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9911 #endif 9912 ) { 9913 SOC_IF_ERROR_RETURN( 9914 bcm_esw_port_egr_lport_field_get(unit, port, 9915 EGR_VLAN_CONTROL_1m, VT_MISS_DROPf, (uint32 *)arg)); 9916 return BCM_E_NONE; 9917 } 9918 SOC_IF_ERROR_RETURN 9919 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9920 *arg = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_DROPf); 9921 } else 9922 #endif 9923 { 9924 SOC_IF_ERROR_RETURN 9925 (soc_reg32_get(unit, egr_register, port, 0, &evc)); 9926 *arg = soc_reg_field_get(unit, egr_register, evc, 9927 VT_MISS_DROPf); 9928 } 9929 return BCM_E_NONE; 9930 } 9931 return BCM_E_UNAVAIL; 9932 9933 case bcmVlanTranslateEgressMissUntaggedDrop: 9934 if ((soc_feature(unit, soc_feature_untagged_vt_miss)) && 9935 (soc_feature(unit,soc_feature_vlan_translation))) { 9936 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9937 if (SOC_MEM_IS_VALID(unit, egr_mem)) { 9938 egr_vlan_control_1_entry_t entry; 9939 if (soc_feature(unit, soc_feature_egr_all_profile) 9940 #if defined(BCM_HGPROXY_COE_SUPPORT) 9941 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9942 BCM_GPORT_IS_SET(port) && 9943 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9944 #endif 9945 ) { 9946 SOC_IF_ERROR_RETURN( 9947 bcm_esw_port_egr_lport_field_get(unit, port, 9948 EGR_VLAN_CONTROL_1m, 9949 VT_MISS_UT_DROPf, (uint32 *)arg)); 9950 return BCM_E_NONE; 9951 } 9952 SOC_IF_ERROR_RETURN 9953 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9954 *arg = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_UT_DROPf); 9955 } else 9956 #endif 9957 { 9958 SOC_IF_ERROR_RETURN 9959 (soc_reg32_get(unit, egr_register, port, 0, &evc)); 9960 *arg = soc_reg_field_get(unit, egr_register, evc, VT_MISS_UT_DROPf); 9961 } 9962 return BCM_E_NONE; 9963 } 9964 return BCM_E_UNAVAIL; 9965 9966 case bcmVlanTranslateEgressMissUntag: 9967 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || \ 9968 defined(BCM_RAVEN_SUPPORT) 9969 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9970 if (SOC_MEM_IS_VALID(unit, egr_mem)) { 9971 egr_vlan_control_1_entry_t entry; 9972 if (SOC_MEM_FIELD_VALID(unit, egr_mem, VT_MISS_UNTAGf)) { 9973 if (soc_feature(unit, soc_feature_egr_all_profile) 9974 #if defined(BCM_HGPROXY_COE_SUPPORT) 9975 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 9976 BCM_GPORT_IS_SET(port) && 9977 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 9978 #endif 9979 ) { 9980 SOC_IF_ERROR_RETURN( 9981 bcm_esw_port_egr_lport_field_get(unit, port, 9982 EGR_VLAN_CONTROL_1m, 9983 VT_MISS_UNTAGf, (uint32 *)arg)); 9984 return BCM_E_NONE; 9985 } 9986 SOC_IF_ERROR_RETURN 9987 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 9988 *arg = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_UNTAGf); 9989 return BCM_E_NONE; 9990 } 9991 } else 9992 #endif 9993 { 9994 if (SOC_REG_FIELD_VALID(unit, egr_register, VT_MISS_UNTAGf)) { 9995 SOC_IF_ERROR_RETURN 9996 (soc_reg32_get(unit, egr_register, port, 0, &evc)); 9997 *arg = soc_reg_field_get(unit, egr_register, evc, 9998 VT_MISS_UNTAGf); 9999 return BCM_E_NONE; 10000 } 10001 } 10002 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 10003 return BCM_E_UNAVAIL; 10004 10005 case bcmVlanLookupMACEnable: 10006 return _bcm_esw_port_config_get(unit, port, 10007 _bcmPortLookupMACEnable, arg); 10008 case bcmVlanLookupIPEnable: 10009 return _bcm_esw_port_config_get(unit, port, 10010 _bcmPortLookupIPEnable, arg); 10011 case bcmVlanPortUseInnerPri: 10012 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 10013 if (BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port) || 10014 BCM_GPORT_IS_VXLAN_PORT(port)) { 10015 return (_bcm_tr2_svp_field_get(unit, port, 10016 USE_INNER_PRIf, arg)); 10017 } 10018 #endif 10019 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 10020 || defined(BCM_RAVEN_SUPPORT) 10021 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_TRX(unit) || 10022 SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit) || 10023 SOC_IS_HURRICANEX(unit)) { 10024 if (BCM_GPORT_IS_SET(port)) { 10025 BCM_IF_ERROR_RETURN( 10026 bcm_esw_port_local_get(unit, port, &port)); 10027 } 10028 return (_bcm_esw_port_config_get(unit, port, 10029 _bcmPortUseInnerPri, arg)); 10030 } 10031 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 10032 return BCM_E_UNAVAIL; 10033 case bcmVlanPortUseOuterPri: 10034 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 10035 if (BCM_GPORT_IS_MPLS_PORT(port) || BCM_GPORT_IS_MIM_PORT(port)) { 10036 return (_bcm_tr2_svp_field_get(unit, port, 10037 TRUST_OUTER_DOT1Pf, arg)); 10038 } 10039 #endif 10040 #if defined(BCM_TRX_SUPPORT) 10041 if (SOC_IS_TRX(unit)) { 10042 if (BCM_GPORT_IS_SET(port)) { 10043 BCM_IF_ERROR_RETURN( 10044 bcm_esw_port_local_get(unit, port, &port)); 10045 } 10046 return (_bcm_esw_port_config_get(unit, port, 10047 _bcmPortUseOuterPri, arg)); 10048 } 10049 #endif /* BCM_TRX_SUPPORT */ 10050 return BCM_E_UNAVAIL; 10051 case bcmVlanPortVerifyOuterTpid: 10052 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAPTOR_SUPPORT) \ 10053 || defined(BCM_TRX_SUPPORT) 10054 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 10055 SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit) || 10056 SOC_IS_HURRICANEX(unit)) { 10057 return (_bcm_esw_port_config_get(unit, port, 10058 _bcmPortVerifyOuterTpid, arg)); 10059 } 10060 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAPTOR_SUPPORT || BCM_TRX_SUPPORT */ 10061 return BCM_E_UNAVAIL; 10062 case bcmVlanPortOuterTpidSelect: 10063 10064 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 10065 || defined(BCM_TRX_SUPPORT) 10066 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 10067 SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit) || 10068 SOC_IS_HURRICANEX(unit)) { 10069 #ifdef BCM_TRIDENT2PLUS_SUPPORT 10070 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 10071 egr_vlan_control_1_entry_t entry; 10072 soc_field_t tpid_sel_f = OUTER_TPID_VALIDf; 10073 if (SOC_MEM_FIELD_VALID(unit, EGR_VLAN_CONTROL_1m, 10074 OUTER_TPID_SELf)) { 10075 tpid_sel_f = OUTER_TPID_SELf; 10076 } 10077 if (soc_feature(unit, soc_feature_egr_all_profile) 10078 #if defined(BCM_HGPROXY_COE_SUPPORT) 10079 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 10080 BCM_GPORT_IS_SET(port) && 10081 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 10082 #endif 10083 ) { 10084 SOC_IF_ERROR_RETURN( 10085 bcm_esw_port_egr_lport_field_get(unit, port, 10086 EGR_VLAN_CONTROL_1m, 10087 tpid_sel_f, (uint32 *)arg)); 10088 return BCM_E_NONE; 10089 } 10090 SOC_IF_ERROR_RETURN( 10091 READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry)); 10092 *arg = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry, 10093 tpid_sel_f); 10094 } else 10095 #endif 10096 { 10097 SOC_IF_ERROR_RETURN 10098 (READ_EGR_VLAN_CONTROL_1r(unit, port, &evc)); 10099 *arg = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, 10100 evc, OUTER_TPID_SELf); 10101 } 10102 return BCM_E_NONE; 10103 } 10104 10105 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 10106 return BCM_E_UNAVAIL; 10107 case bcmVlanPortTranslateKeyFirst: 10108 case bcmVlanPortTranslateKeySecond: 10109 #if defined(BCM_TRX_SUPPORT) 10110 if (SOC_IS_TRX(unit)) { 10111 _bcm_port_config_t vt_key_type; 10112 _bcm_port_config_t vt_key_port; 10113 int key_type = 0, use_port = 0; 10114 int key_type_value; 10115 10116 if (type == bcmVlanPortTranslateKeyFirst) { 10117 vt_key_type = _bcmPortVTKeyTypeFirst; 10118 vt_key_port = _bcmPortVTKeyPortFirst; 10119 } else { 10120 vt_key_type = _bcmPortVTKeyTypeSecond; 10121 vt_key_port = _bcmPortVTKeyPortSecond; 10122 } 10123 10124 if (BCM_GPORT_IS_NIV_PORT(port)) { 10125 BCM_IF_ERROR_RETURN 10126 (bcm_esw_vlan_control_port_niv_resolve(unit, port, 10127 &port)); 10128 } 10129 10130 BCM_IF_ERROR_RETURN 10131 (_bcm_esw_port_config_get(unit, port, 10132 vt_key_type, 10133 &key_type_value)); 10134 10135 BCM_IF_ERROR_RETURN 10136 (_bcm_esw_pt_vtkey_type_get(unit, 10137 key_type_value,&key_type)); 10138 10139 BCM_IF_ERROR_RETURN 10140 (_bcm_esw_port_config_get(unit, port, 10141 vt_key_port, 10142 &use_port)); 10143 switch (key_type) { 10144 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 10145 if (use_port == 3) { 10146 *arg = bcmVlanTranslateKeyPortGroupDouble; 10147 } else { 10148 *arg = (use_port) ? bcmVlanTranslateKeyPortDouble : 10149 bcmVlanTranslateKeyDouble; 10150 } 10151 break; 10152 case VLXLT_HASH_KEY_TYPE_OTAG: 10153 if (use_port == 3) { 10154 *arg = bcmVlanTranslateKeyPortGroupOuterTag; 10155 } else { 10156 *arg = (use_port) ? bcmVlanTranslateKeyPortOuterTag : 10157 bcmVlanTranslateKeyOuterTag; 10158 } 10159 break; 10160 case VLXLT_HASH_KEY_TYPE_ITAG: 10161 if (use_port == 3) { 10162 *arg = bcmVlanTranslateKeyPortGroupInnerTag; 10163 } else { 10164 *arg = (use_port) ? bcmVlanTranslateKeyPortInnerTag : 10165 bcmVlanTranslateKeyInnerTag; 10166 } 10167 break; 10168 case VLXLT_HASH_KEY_TYPE_OVID: 10169 if (use_port == 3) { 10170 *arg = bcmVlanTranslateKeyPortGroupOuter; 10171 } else { 10172 *arg = (use_port) ? bcmVlanTranslateKeyPortOuter : 10173 bcmVlanTranslateKeyOuter; 10174 } 10175 break; 10176 case VLXLT_HASH_KEY_TYPE_IVID: 10177 if (use_port == 3) { 10178 *arg = bcmVlanTranslateKeyPortGroupInner; 10179 } else { 10180 *arg = (use_port) ? bcmVlanTranslateKeyPortInner : 10181 bcmVlanTranslateKeyInner; 10182 } 10183 break; 10184 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 10185 if (use_port == 3) { 10186 *arg = bcmVlanTranslateKeyPortGroupOuterPri; 10187 } else { 10188 *arg = (use_port) ? bcmVlanTranslateKeyPortOuterPri : 10189 bcmVlanTranslateKeyOuterPri; 10190 } 10191 break; 10192 case VLXLT_HASH_KEY_TYPE_VIF_OTAG: 10193 *arg = (use_port) ? bcmVlanTranslateKeyPortOuterTag : 10194 bcmVlanTranslateKeyOuterTag; 10195 break; 10196 case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 10197 *arg = (use_port) ? bcmVlanTranslateKeyPortInnerTag : 10198 bcmVlanTranslateKeyInnerTag; 10199 break; 10200 case VLXLT_HASH_KEY_TYPE_VIF_VLAN: 10201 *arg = (use_port) ? bcmVlanTranslateKeyPortOuter: 10202 bcmVlanTranslateKeyOuter; 10203 break; 10204 case VLXLT_HASH_KEY_TYPE_VIF_CVLAN: 10205 *arg = (use_port) ? bcmVlanTranslateKeyPortInner: 10206 bcmVlanTranslateKeyInner; 10207 break; 10208 case VLXLT_HASH_KEY_TYPE_LLVID: 10209 *arg = (use_port) ? bcmVlanTranslateKeyPortPonTunnel: 10210 bcmVlanTranslateKeyInvalid; 10211 break; 10212 case VLXLT_HASH_KEY_TYPE_LLVID_OVID: 10213 *arg = (use_port) ? bcmVlanTranslateKeyPortPonTunnelOuter: 10214 bcmVlanTranslateKeyInvalid; 10215 break; 10216 case VLXLT_HASK_KEY_TYPE_LLVID_IVID: 10217 *arg = (use_port) ? bcmVlanTranslateKeyPortPonTunnelOuter: 10218 bcmVlanTranslateKeyPortPonTunnelInner; 10219 break; 10220 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID: 10221 *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadDouble: 10222 bcmVlanTranslateKeyCapwapPayloadDouble; 10223 break; 10224 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG: 10225 *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadOuterTag: 10226 bcmVlanTranslateKeyCapwapPayloadOuterTag; 10227 break; 10228 case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG: 10229 *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadInnerTag: 10230 bcmVlanTranslateKeyCapwapPayloadInnerTag; 10231 break; 10232 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID: 10233 *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadOuter: 10234 bcmVlanTranslateKeyCapwapPayloadOuter; 10235 break; 10236 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID: 10237 *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadInner: 10238 bcmVlanTranslateKeyCapwapPayloadInner; 10239 break; 10240 case VLXLT_HASH_KEY_TYPE_VNID: 10241 *arg = (use_port) ? bcmVlanTranslateKeyPortVxlanVnid: 10242 bcmVlanTranslateKeyVxlanVnid; 10243 break; 10244 case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT: 10245 if (use_port == 1) { 10246 *arg = bcmVlanTranslateKeyMacPort; 10247 } else if (use_port == 2) { 10248 *arg = bcmVlanTranslateKeyMacVirtualPort; 10249 } else if (use_port == 3) { 10250 *arg = bcmVlanTranslateKeyMacPortGroup; 10251 } 10252 break; 10253 default: 10254 *arg = bcmVlanTranslateKeyInvalid; 10255 break; 10256 } 10257 return BCM_E_NONE; 10258 } 10259 #endif /* BCM_TRX_SUPPORT */ 10260 return BCM_E_UNAVAIL; 10261 #if defined(BCM_KATANA2_SUPPORT) 10262 case bcmVlanPortOamUseXlatedInnerVlan: 10263 if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_oam))) { 10264 return (_bcm_esw_port_config_get(unit, port, 10265 _bcmPortOamUseXlatedInnerVlan, arg)); 10266 } 10267 return BCM_E_UNAVAIL; 10268 break; 10269 #endif /* BCM_KATANA2_SUPPORT */ 10270 case bcmVlanPortTranslateEgressKey: 10271 case bcmVlanPortTranslateEgressKeyFirst: 10272 case bcmVlanPortTranslateEgressKeySecond: 10273 10274 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 10275 if (bcmVlanPortTranslateEgressKeySecond == type) { 10276 if (soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) { 10277 field = VT2_ENABLEf; 10278 } else { 10279 return BCM_E_UNAVAIL; 10280 } 10281 } 10282 10283 if (soc_feature(unit, soc_feature_egr_vlan_xlate_key_on_dvp)) { 10284 int key_type_value; 10285 10286 if (BCM_GPORT_IS_VXLAN_PORT(port) || BCM_GPORT_IS_MIM_PORT(port) 10287 || BCM_GPORT_IS_MPLS_PORT(port) || BCM_GPORT_IS_L2GRE_PORT(port)) { 10288 if (bcmVlanPortTranslateEgressKeySecond == type) { 10289 /* Second EVxlate lookup is not supported with VPs */ 10290 return BCM_E_UNAVAIL; 10291 } 10292 BCM_IF_ERROR_RETURN 10293 (bcm_td2p_dvp_vlan_xlate_key_get(unit, port, 10294 &key_type_value)); 10295 return (_bcm_esw_dvp_vtkey_type_get(unit, 10296 key_type_value, arg)); 10297 } else if (BCM_GPORT_IS_FLOW_PORT(port)) { 10298 int rv = BCM_E_UNAVAIL; 10299 #ifdef BCM_TRIDENT3_SUPPORT 10300 if (soc_feature(unit,soc_feature_flex_flow)) { 10301 rv = bcmi_esw_flow_dvp_vlan_xlate_key_get(unit, 10302 port, arg); 10303 } 10304 #endif 10305 return rv; 10306 } 10307 } 10308 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 10309 10310 if (soc_feature(unit, soc_feature_vlan_translation)) { 10311 #ifdef BCM_TRIDENT2PLUS_SUPPORT 10312 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 10313 egr_vlan_control_1_entry_t entry; 10314 if (soc_feature(unit, soc_feature_egr_all_profile) 10315 #if defined(BCM_HGPROXY_COE_SUPPORT) 10316 || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 10317 BCM_GPORT_IS_SET(port) && 10318 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) 10319 #endif 10320 ) { 10321 SOC_IF_ERROR_RETURN( 10322 bcm_esw_port_egr_lport_field_get(unit, port, 10323 EGR_VLAN_CONTROL_1m, 10324 field, (uint32 *)(&key_type_value))); 10325 } else { 10326 if (BCM_GPORT_IS_LOCAL(port)) { 10327 port = BCM_GPORT_LOCAL_GET(port); 10328 } 10329 if (!SOC_PORT_VALID(unit, port)) { 10330 return BCM_E_PORT; 10331 } 10332 10333 SOC_IF_ERROR_RETURN 10334 (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry)); 10335 key_type_value = soc_mem_field32_get(unit, egr_mem, &entry, field); 10336 } 10337 } else 10338 #endif 10339 { 10340 if (BCM_GPORT_IS_LOCAL(port)) { 10341 port = BCM_GPORT_LOCAL_GET(port); 10342 } 10343 if (!SOC_PORT_VALID(unit, port)) { 10344 return BCM_E_PORT; 10345 } 10346 10347 SOC_IF_ERROR_RETURN 10348 (soc_reg32_get(unit, egr_register, port, 0, &evc)); 10349 key_type_value = soc_reg_field_get(unit, egr_register, evc, VT_ENABLEf); 10350 } 10351 return (_bcm_esw_egr_vtkey_type_get(unit, key_type_value, arg)); 10352 } 10353 return BCM_E_UNAVAIL; 10354 10355 default: 10356 return BCM_E_UNAVAIL; 10357 } 10358 } 10359 #endif /* BCM_FIREBOLT_SUPPORT */ 10360 return BCM_E_UNAVAIL; 10361 } 10362 10363 #if defined(BCM_XGS_SWITCH_SUPPORT) 10364 /**************************************************************** 10365 * 10366 * Stack port updating of VLAN tables 10367 */ 10368 10369 /* Boolean: returns TRUE if bitmap changed. */ 10370 STATIC int 10371 _stk_vlan_bitmap_update(int unit, bcm_pbmp_t remove_ports, 10372 bcm_pbmp_t old_ports, bcm_pbmp_t *new_ports) 10373 { 10374 SOC_PBMP_ASSIGN(*new_ports, old_ports); 10375 SOC_PBMP_OR(*new_ports, SOC_PBMP_STACK_CURRENT(unit)); 10376 SOC_PBMP_REMOVE(*new_ports, remove_ports); 10377 10378 return SOC_PBMP_NEQ(*new_ports, old_ports); 10379 } 10380 10381 STATIC void 10382 _xgs_vlan_bitmap_get(int unit, vlan_tab_entry_t *vt, bcm_pbmp_t *ports) 10383 { 10384 SOC_PBMP_CLEAR(*ports); 10385 10386 #if defined(BCM_XGS3_SWITCH_SUPPORT) 10387 if (SOC_IS_XGS3_SWITCH(unit)) { 10388 soc_mem_pbmp_field_get(unit, VLAN_TABLE(unit), vt, PORT_BITMAPf, ports); 10389 } 10390 #endif 10391 } 10392 10393 STATIC void 10394 _xgs_vlan_bitmap_set(int unit, vlan_tab_entry_t *vt, bcm_pbmp_t ports) 10395 { 10396 #if defined(BCM_XGS3_SWITCH_SUPPORT) 10397 if (SOC_IS_XGS3_SWITCH(unit)) { 10398 soc_mem_pbmp_field_set(unit, VLAN_TABLE(unit), vt, PORT_BITMAPf, &ports); 10399 } 10400 #endif 10401 } 10402 #ifdef BCM_TRIUMPH3_SUPPORT 10403 STATIC void 10404 _xgs_vlan_ing_bitmap_get(int unit, vlan_tab_entry_t *vt, bcm_pbmp_t *ports) 10405 { 10406 SOC_PBMP_CLEAR(*ports); 10407 10408 #if defined(BCM_XGS3_SWITCH_SUPPORT) 10409 if (SOC_IS_XGS3_SWITCH(unit)) { 10410 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf)) { 10411 soc_mem_pbmp_field_get(unit, VLAN_TABLE(unit), vt, ING_PORT_BITMAPf, 10412 ports); 10413 } 10414 } 10415 #endif 10416 } 10417 10418 STATIC void 10419 _xgs_vlan_ing_bitmap_set(int unit, vlan_tab_entry_t *vt, bcm_pbmp_t ports) 10420 { 10421 #if defined(BCM_XGS3_SWITCH_SUPPORT) 10422 if (SOC_IS_XGS3_SWITCH(unit)) { 10423 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf)) { 10424 soc_mem_pbmp_field_set(unit, VLAN_TABLE(unit), vt, ING_PORT_BITMAPf, 10425 &ports); 10426 } 10427 } 10428 #endif 10429 } 10430 #endif /*BCM_TRIUMPH3_SUPPORT*/ 10431 #endif /* BCM_XGS_SWITCH_SUPPORT */ 10432 10433 STATIC int 10434 _xgs_vlan_stk_update(int unit, int vid, bcm_pbmp_t add_ports, 10435 bcm_pbmp_t remove_ports) 10436 { 10437 #if defined(BCM_XGS_SWITCH_SUPPORT) 10438 10439 vlan_tab_entry_t vt; 10440 bcm_pbmp_t old_ports, new_ports; 10441 int pbmp_update=0; 10442 #ifdef BCM_TRIUMPH3_SUPPORT 10443 int ing_pbmp_update=0; 10444 bcm_pbmp_t old_ing_ports, new_ing_ports; 10445 #endif /* BCM_TRIUMPH3_SUPPORT*/ 10446 10447 /* Read in table entry. Assume valid as given VID */ 10448 SOC_IF_ERROR_RETURN(soc_mem_read(unit, VLAN_TABLE(unit), MEM_BLOCK_ANY, vid, &vt)); 10449 10450 _xgs_vlan_bitmap_get(unit, &vt, &old_ports); 10451 10452 /* See if changed */ 10453 pbmp_update = 10454 _stk_vlan_bitmap_update(unit, remove_ports, old_ports, &new_ports); 10455 if (pbmp_update) { 10456 _xgs_vlan_bitmap_set(unit, &vt, new_ports); 10457 } 10458 10459 #ifdef BCM_TRIUMPH3_SUPPORT 10460 if (SOC_IS_TRIUMPH3(unit)) { 10461 _xgs_vlan_ing_bitmap_get(unit, &vt, &old_ing_ports); 10462 ing_pbmp_update = _stk_vlan_bitmap_update(unit, remove_ports, old_ing_ports, &new_ing_ports); 10463 if (ing_pbmp_update) { 10464 _xgs_vlan_ing_bitmap_set(unit, &vt, new_ing_ports); 10465 } 10466 } 10467 10468 if (pbmp_update || ing_pbmp_update) 10469 #else 10470 if (pbmp_update) 10471 #endif 10472 { 10473 SOC_IF_ERROR_RETURN(soc_mem_write(unit, VLAN_TABLE(unit), MEM_BLOCK_ANY, vid, &vt)); 10474 } 10475 10476 /* FIREBOLT has an EGR VLAN table; 10477 in general, this should match VLAN_TAB */ 10478 if (SOC_IS_FBX(unit) && soc_feature(unit, soc_feature_egr_vlan_check) ) { 10479 #if defined(BCM_FIREBOLT_SUPPORT) 10480 egr_vlan_entry_t evt; 10481 bcm_pbmp_t old_ports, new_ports; 10482 10483 /* Read in EGR_VLAN table entry. */ 10484 SOC_IF_ERROR_RETURN(READ_EGR_VLANm(unit, MEM_BLOCK_ANY, vid, &evt)); 10485 10486 if (_bcm_vlan_valid_check(unit, EGR_VLANm, (void *) &evt, 10487 vid) == BCM_E_NONE) { 10488 soc_mem_pbmp_field_get(unit, EGR_VLANm, &evt, PORT_BITMAPf, 10489 &old_ports); 10490 10491 /* See if changed */ 10492 if (_stk_vlan_bitmap_update(unit, remove_ports, 10493 old_ports, &new_ports)) { 10494 soc_mem_pbmp_field_set(unit, EGR_VLANm, &evt, PORT_BITMAPf, 10495 &new_ports); 10496 SOC_IF_ERROR_RETURN(WRITE_EGR_VLANm(unit, MEM_BLOCK_ANY, 10497 vid, &evt)); 10498 } 10499 } 10500 #endif /* BCM_FIREBOLT_SUPPORT */ 10501 } 10502 10503 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 10504 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 10505 BCM_IF_ERROR_RETURN( 10506 bcm_td2p_vlan_vfi_mbrship_port_set(unit, vid, TRUE, 10507 TRUE, add_ports)); 10508 BCM_IF_ERROR_RETURN( 10509 bcm_td2p_vlan_vfi_mbrship_port_set(unit, vid, TRUE, 10510 FALSE, remove_ports)); 10511 if (pbmp_update) { 10512 BCM_IF_ERROR_RETURN( 10513 bcm_td2p_vlan_vfi_mbrship_port_set(unit, vid, FALSE, 10514 TRUE, add_ports)); 10515 BCM_IF_ERROR_RETURN( 10516 bcm_td2p_vlan_vfi_mbrship_port_set(unit, vid, FALSE, 10517 FALSE, remove_ports)); 10518 } 10519 } 10520 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 10521 10522 #endif /* BCM_XGS_SWITCH_SUPPORT */ 10523 10524 return BCM_E_NONE; 10525 } 10526 10527 STATIC int 10528 _esw_vlan_stk_update(int unit, int vid, bcm_pbmp_t add_ports, 10529 bcm_pbmp_t remove_ports) 10530 { 10531 LOG_VERBOSE(BSL_LS_BCM_VLAN, 10532 (BSL_META_U(unit, 10533 "VLAN %d: stk update internal: vid %d, add 0x%x, " 10534 "rmv 0x%x\n"), unit, vid, 10535 SOC_PBMP_WORD_GET(add_ports, 0), 10536 SOC_PBMP_WORD_GET(remove_ports, 0))); 10537 10538 if (SOC_IS_XGS_SWITCH(unit)) { 10539 return _xgs_vlan_stk_update(unit, vid, add_ports, remove_ports); 10540 } 10541 10542 return BCM_E_NONE; /* Ignore where not supported. */ 10543 } 10544 10545 STATIC void 10546 _vlan_mem_lock(int unit) 10547 { 10548 #ifdef BCM_XGS12_SWITCH_SUPPORT 10549 if (SOC_IS_XGS12_SWITCH(unit)) { 10550 soc_mem_lock(unit, VLAN_TABm); 10551 } 10552 #endif 10553 10554 #ifdef BCM_XGS3_SWITCH_SUPPORT 10555 if (SOC_IS_XGS3_SWITCH(unit)) { 10556 soc_mem_lock(unit, VLAN_TABm); 10557 soc_mem_lock(unit, EGR_VLANm); 10558 } 10559 #endif 10560 } 10561 10562 STATIC void 10563 _vlan_mem_unlock(int unit) 10564 { 10565 #ifdef BCM_XGS12_SWITCH_SUPPORT 10566 if (SOC_IS_XGS12_SWITCH(unit)) { 10567 soc_mem_unlock(unit, VLAN_TABm); 10568 } 10569 #endif 10570 10571 #ifdef BCM_XGS3_SWITCH_SUPPORT 10572 if (SOC_IS_XGS3_SWITCH(unit)) { 10573 soc_mem_unlock(unit, EGR_VLANm); 10574 soc_mem_unlock(unit, VLAN_TABm); 10575 } 10576 #endif 10577 } 10578 10579 10580 10581 int 10582 _bcm_esw_vlan_untag_update(int unit, bcm_port_t port, int untag) 10583 { 10584 int rv = BCM_E_NONE; 10585 bcm_pbmp_t port_pbmp, port_ubmp, vlan_pbmp, vlan_ubmp, vlan_ing_pbmp; 10586 int vid; 10587 10588 if (!soc_feature(unit, soc_feature_xport_convertible) && !SOC_IS_RAVEN(unit)) { 10589 return BCM_E_NONE; 10590 } 10591 10592 SOC_PBMP_CLEAR(port_pbmp); 10593 SOC_PBMP_CLEAR(port_ubmp); 10594 10595 SOC_PBMP_PORT_SET(port_pbmp, port); 10596 if (!untag) { 10597 SOC_PBMP_PORT_SET(port_ubmp, port); 10598 } 10599 10600 _vlan_mem_lock(unit); 10601 vid = vlan_info[unit].defl; 10602 rv = mbcm_driver[unit]->mbcm_vlan_port_get 10603 (unit, vid, &vlan_pbmp, &vlan_ubmp, &vlan_ing_pbmp); 10604 10605 if (rv >= 0) { 10606 if (untag || SOC_PBMP_MEMBER(vlan_pbmp, port)) { 10607 /* port_pbmp is a mask for the other two arguments */ 10608 BCM_PBMP_AND(vlan_ing_pbmp, port_pbmp); 10609 rv = mbcm_driver[unit]->mbcm_vlan_port_add 10610 (unit, vid, port_pbmp, port_ubmp, vlan_ing_pbmp); 10611 } 10612 } 10613 _vlan_mem_unlock(unit); 10614 10615 return rv; 10616 } 10617 10618 10619 10620 int 10621 _bcm_esw_vlan_stk_update(int unit, uint32 flags) 10622 { 10623 int rv = BCM_E_NONE; 10624 10625 if (vlan_info[unit].vlan_auto_stack) { 10626 bcm_pbmp_t add_ports, remove_ports; 10627 int vid; 10628 int vlan_count = 0; 10629 10630 LOG_VERBOSE(BSL_LS_BCM_VLAN, 10631 (BSL_META_U(unit, 10632 "VLAN %d: stk_update: flags 0x%x\n"), 10633 unit, flags)); 10634 10635 /* 10636 * Force all stack ports in all VLANs and assume BLOCK registers 10637 * take care of DLFs and BCast; remove ports no longer stacking. 10638 */ 10639 SOC_PBMP_ASSIGN(add_ports, SOC_PBMP_STACK_CURRENT(unit)); 10640 10641 SOC_PBMP_ASSIGN(remove_ports, SOC_PBMP_STACK_PREVIOUS(unit)); 10642 SOC_PBMP_REMOVE(remove_ports, SOC_PBMP_STACK_CURRENT(unit)); 10643 10644 _vlan_mem_lock(unit); 10645 10646 for (vid = BCM_VLAN_MIN;vid < BCM_VLAN_COUNT; vid++) { 10647 if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) { 10648 continue; 10649 } 10650 vlan_count++; 10651 rv = _esw_vlan_stk_update(unit, vid, add_ports, remove_ports); 10652 if (BCM_FAILURE(rv)) { 10653 break; 10654 } 10655 if (vlan_info[unit].count == vlan_count) { 10656 break; 10657 } 10658 } 10659 _vlan_mem_unlock(unit); 10660 } 10661 return rv; 10662 } 10663 10664 10665 /* 10666 * Function: 10667 * bcm_vlan_mcast_flood_set 10668 * Purpose: 10669 * Set the VLAN Multicast flood mode (aka PFM - port filter mode) 10670 * Parameters: 10671 * unit - StrataSwitch PCI device unit number (driver internal). 10672 * vid - VLAN to change the flood setting on. 10673 * mode - Multicast flood mode 10674 * Returns: 10675 * BCM_E_NONE - Success. 10676 * BCM_E_XXX 10677 * Notes: 10678 * Available on XGS3 only. 10679 */ 10680 int 10681 bcm_esw_vlan_mcast_flood_set(int unit, 10682 bcm_vlan_t vlan, 10683 bcm_vlan_mcast_flood_t mode) 10684 { 10685 int rv = BCM_E_UNAVAIL; 10686 10687 #ifdef BCM_XGS3_SWITCH_SUPPORT 10688 if (soc_feature(unit, soc_feature_vlan_mc_flood_ctrl)) { 10689 CHECK_INIT(unit); 10690 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \ 10691 defined(INCLUDE_L3) 10692 if (_BCM_MPLS_VPN_IS_VPLS(vlan)) { 10693 if (soc_feature(unit, soc_feature_vfi_mc_flood_ctrl)) { 10694 return bcm_tr_mpls_mcast_flood_set(unit, vlan, mode); 10695 } else { 10696 return rv; 10697 } 10698 } 10699 #endif 10700 VLAN_CHK_ID(unit, vlan); 10701 10702 if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) { 10703 rv = _bcm_xgs3_vlan_mcast_flood_set(unit, vlan, mode); 10704 } else { 10705 rv = BCM_E_PARAM; 10706 } 10707 } 10708 #endif 10709 return rv; 10710 } 10711 10712 /* 10713 * Function: 10714 * bcm_vlan_mcast_flood_get 10715 * Purpose: 10716 * Get the VLAN Multicast flood mode (aka PFM - port filter mode) 10717 * Parameters: 10718 * unit - StrataSwitch PCI device unit number (driver internal). 10719 * vid - VLAN to get the flood setting for. 10720 * mode - Multicast flood mode 10721 * Returns: 10722 * BCM_E_NONE - Success. 10723 * BCM_E_XXX 10724 * Notes: 10725 * Available on XGS3 only. 10726 */ 10727 int 10728 bcm_esw_vlan_mcast_flood_get(int unit, 10729 bcm_vlan_t vlan, 10730 bcm_vlan_mcast_flood_t *mode) 10731 { 10732 int rv = BCM_E_UNAVAIL; 10733 #ifdef BCM_XGS3_SWITCH_SUPPORT 10734 if (soc_feature(unit, soc_feature_vlan_mc_flood_ctrl)) { 10735 CHECK_INIT(unit); 10736 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \ 10737 defined(INCLUDE_L3) 10738 if (_BCM_MPLS_VPN_IS_VPLS(vlan)) { 10739 if (soc_feature(unit, soc_feature_vfi_mc_flood_ctrl)) { 10740 return bcm_tr_mpls_mcast_flood_get(unit, vlan, mode); 10741 } else { 10742 return rv; 10743 } 10744 } 10745 #endif 10746 VLAN_CHK_ID(unit, vlan); 10747 if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) { 10748 rv = _bcm_xgs3_vlan_mcast_flood_get(unit, vlan, mode); 10749 } else { 10750 rv = BCM_E_PARAM; 10751 } 10752 } 10753 #endif 10754 return rv; 10755 } 10756 10757 10758 /* 10759 * Function: 10760 * bcm_esw_vlan_block_set 10761 * Purpose: 10762 * Set per VLAN configuration. 10763 * Parameters: 10764 * unit - (IN) BCM device number. 10765 * vid - (IN) VLAN to get the flood setting for. 10766 * block - (IN) VLAN block structure 10767 * Returns: 10768 * BCM_E_NONE - Success. 10769 * BCM_E_XXX 10770 * Notes: 10771 */ 10772 int 10773 bcm_esw_vlan_block_set(int unit, bcm_vlan_t vid, bcm_vlan_block_t *block) 10774 { 10775 int rv = BCM_E_UNAVAIL; 10776 10777 #ifdef BCM_TRX_SUPPORT 10778 CHECK_INIT(unit); 10779 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 10780 if (soc_feature(unit, soc_feature_vfi_combo_profile) && 10781 _BCM_VPN_VFI_IS_SET(vid)) { 10782 int vfi = 0; 10783 bcm_vpn_t vpn_min = 0; 10784 int num_vfi = soc_mem_index_count(unit, VFIm); 10785 10786 _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0); 10787 if ((vid > (vpn_min+num_vfi-1)) || (vid < vpn_min)) { 10788 return (BCM_E_PARAM); 10789 } 10790 10791 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid); 10792 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) { 10793 return BCM_E_NOT_FOUND; 10794 } 10795 10796 rv = bcmi_td2p_vlan_block_set(unit, vid, block); 10797 } else 10798 #endif 10799 { 10800 VLAN_CHK_ID(unit, vid); 10801 10802 if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m)) { 10803 if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) { 10804 BCM_LOCK(unit); 10805 rv = _bcm_trx_vlan_block_set(unit, vid, block); 10806 BCM_UNLOCK(unit); 10807 } else { 10808 rv = BCM_E_PARAM; 10809 } 10810 } 10811 } 10812 #endif /* BCM_TRX_SUPPORT */ 10813 return rv; 10814 } 10815 10816 /* 10817 * Function: 10818 * bcm_esw_vlan_block_get 10819 * Purpose: 10820 * Get per VLAN block configuration. 10821 * Parameters: 10822 * unit - (IN) BCM device number. 10823 * vid - (IN) VLAN to get the flood setting for. 10824 * control - (OUT) VLAN control structure 10825 * Returns: 10826 * BCM_E_NONE - Success. 10827 * BCM_E_XXX 10828 * Notes: 10829 */ 10830 int 10831 bcm_esw_vlan_block_get(int unit, bcm_vlan_t vid, bcm_vlan_block_t *block) 10832 { 10833 int rv = BCM_E_UNAVAIL; 10834 10835 if (NULL == block) { 10836 return (BCM_E_PARAM); 10837 } 10838 10839 #ifdef BCM_TRX_SUPPORT 10840 CHECK_INIT(unit); 10841 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 10842 if (soc_feature(unit, soc_feature_vfi_combo_profile) && 10843 _BCM_VPN_VFI_IS_SET(vid)) { 10844 int vfi = 0; 10845 bcm_vpn_t vpn_min = 0; 10846 int num_vfi = soc_mem_index_count(unit, VFIm); 10847 10848 _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0); 10849 if ((vid > (vpn_min+num_vfi-1)) || (vid < vpn_min)) { 10850 return (BCM_E_PARAM); 10851 } 10852 10853 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid); 10854 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) { 10855 return BCM_E_NOT_FOUND; 10856 } 10857 10858 rv = bcmi_td2p_vlan_block_get(unit, vid, block); 10859 } else 10860 #endif 10861 { 10862 VLAN_CHK_ID(unit, vid); 10863 if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m)) { 10864 if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) { 10865 BCM_LOCK(unit); 10866 rv = _bcm_trx_vlan_block_get(unit, vid, block); 10867 BCM_UNLOCK(unit); 10868 } else { 10869 rv = BCM_E_PARAM; 10870 } 10871 } 10872 } 10873 #endif /* BCM_TRX_SUPPORT */ 10874 return rv; 10875 } 10876 10877 /* 10878 * Function: 10879 * bcm_esw_vlan_control_vlan_selective_set 10880 * Purpose: 10881 * Set per VLAN configuration. 10882 * Parameters: 10883 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 10884 * vid - (IN) VLAN to get the flood setting for. 10885 * valid_fields - (IN) Valid fields for VLAN control structure, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 10886 * control - (IN) VLAN control structure 10887 * Returns: 10888 * BCM_E_NONE - Success. 10889 * BCM_E_XXX 10890 * Notes: 10891 */ 10892 int 10893 bcm_esw_vlan_control_vlan_selective_set(int unit, bcm_vlan_t vlan, 10894 uint32 valid_fields, bcm_vlan_control_vlan_t *control) 10895 { 10896 int rv = BCM_E_UNAVAIL; 10897 10898 #ifdef BCM_TOMAHAWK3_SUPPORT 10899 if (SOC_IS_TOMAHAWK3(unit)) { 10900 return bcm_tomahawk3_vlan_control_vlan_selective_set(unit, 10901 vlan, 10902 valid_fields, 10903 control); 10904 } 10905 #endif 10906 10907 if (NULL == control) { 10908 return (BCM_E_PARAM); 10909 } 10910 10911 #ifdef BCM_XGS3_SWITCH_SUPPORT 10912 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 10913 defined(BCM_GREYHOUND2_SUPPORT)) && defined(INCLUDE_L3) 10914 if (_BCM_VPN_VFI_IS_SET(vlan)) { 10915 int vfi = 0; 10916 bcm_vpn_t vpn_min = 0; 10917 int max_vfi = soc_mem_index_max(unit, VFIm); 10918 10919 _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0); 10920 if ((vlan > (vpn_min + max_vfi)) || (vlan < vpn_min)) { 10921 return (BCM_E_PARAM); 10922 } 10923 10924 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan); 10925 #ifdef BCM_GREYHOUND2_SUPPORT 10926 if (soc_feature(unit, soc_feature_vxlan_lite_riot)) { 10927 if (!bcmi_gh2_vxlan_vfi_used_get(unit, vfi)) { 10928 return BCM_E_NOT_FOUND; 10929 } 10930 } else 10931 #endif /* BCM_GREYHOUND2_SUPPORT */ 10932 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) { 10933 return BCM_E_NOT_FOUND; 10934 } 10935 } else 10936 #endif /* TRIDENT2PLUS || TOMAHAWK || GREYHOUND2 */ 10937 { 10938 VLAN_CHK_ID(unit, vlan); 10939 } 10940 10941 if ((control->vrf > SOC_VRF_MAX(unit))) { 10942 return (BCM_E_PARAM); 10943 } 10944 10945 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 10946 BCM_LOCK(unit); 10947 rv = _bcm_xgs3_vlan_control_vlan_set(unit, vlan, valid_fields, control); 10948 BCM_UNLOCK(unit); 10949 } 10950 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 10951 10952 return rv; 10953 } 10954 10955 /* 10956 * Function: 10957 * bcm_esw_vlan_control_vlan_selective_get 10958 * Purpose: 10959 * Get per VLAN configuration. 10960 * Parameters: 10961 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 10962 * vid - (IN) VLAN to get the flood setting for. 10963 * valid_fields - (IN) Valid fields for VLAN control structure, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 10964 * control - (OUT) VLAN control structure 10965 * Returns: 10966 * BCM_E_NONE - Success. 10967 * BCM_E_XXX 10968 * Notes: 10969 */ 10970 int 10971 bcm_esw_vlan_control_vlan_selective_get(int unit, bcm_vlan_t vlan, 10972 uint32 valid_fields, bcm_vlan_control_vlan_t *control) 10973 { 10974 int rv = BCM_E_UNAVAIL; 10975 10976 #ifdef BCM_TOMAHAWK3_SUPPORT 10977 if (SOC_IS_TOMAHAWK3(unit)) { 10978 return bcm_tomahawk3_vlan_control_vlan_selective_get(unit, 10979 vlan, 10980 valid_fields, 10981 control); 10982 } 10983 #endif 10984 10985 if (NULL == control) { 10986 return (BCM_E_PARAM); 10987 } 10988 10989 #ifdef BCM_XGS3_SWITCH_SUPPORT 10990 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \ 10991 defined(BCM_GREYHOUND2_SUPPORT)) && defined(INCLUDE_L3) 10992 if (_BCM_VPN_VFI_IS_SET(vlan)) { 10993 int vfi = 0; 10994 bcm_vpn_t vpn_min = 0; 10995 int max_vfi = soc_mem_index_max(unit, VFIm); 10996 10997 _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0); 10998 if ((vlan > (vpn_min + max_vfi)) || (vlan < vpn_min)) { 10999 return (BCM_E_PARAM); 11000 } 11001 11002 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan); 11003 #ifdef BCM_GREYHOUND2_SUPPORT 11004 if (soc_feature(unit, soc_feature_vxlan_lite_riot)) { 11005 if (!bcmi_gh2_vxlan_vfi_used_get(unit, vfi)) { 11006 return BCM_E_NOT_FOUND; 11007 } 11008 } else 11009 #endif /* BCM_GREYHOUND2_SUPPORT */ 11010 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) { 11011 return BCM_E_NOT_FOUND; 11012 } 11013 } else 11014 #endif /* TRIDENT2PLUS || TOMAHAWK || GREYHOUND2 */ 11015 { 11016 VLAN_CHK_ID(unit, vlan); 11017 } 11018 11019 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 11020 BCM_LOCK(unit); 11021 rv = _bcm_xgs3_vlan_control_vlan_get(unit, vlan, valid_fields, control); 11022 BCM_UNLOCK(unit); 11023 } 11024 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 11025 11026 return rv; 11027 } 11028 11029 /* 11030 * Function: 11031 * bcm_esw_vlan_control_vlan_set 11032 * Purpose: 11033 * Set per VLAN configuration. 11034 * Parameters: 11035 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 11036 * vid - (IN) VLAN to get the flood setting for. 11037 * control - (IN) VLAN control structure 11038 * Returns: 11039 * BCM_E_NONE - Success. 11040 * BCM_E_XXX 11041 * Notes: 11042 */ 11043 int 11044 bcm_esw_vlan_control_vlan_set(int unit, bcm_vlan_t vid, 11045 /* coverity[pass_by_value] */ 11046 bcm_vlan_control_vlan_t control) 11047 { 11048 int rv = BCM_E_UNAVAIL; 11049 11050 #ifdef BCM_XGS3_SWITCH_SUPPORT 11051 #ifdef BCM_TOMAHAWK3_SUPPORT 11052 if (SOC_IS_TOMAHAWK3(unit)) { 11053 return bcm_tomahawk3_vlan_control_vlan_set(unit, vid, control); 11054 } 11055 #endif 11056 CHECK_INIT(unit); 11057 11058 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 11059 uint32 valid_fields = BCM_VLAN_CONTROL_VLAN_ALL_MASK; 11060 11061 /* API semantic validation */ 11062 if (!_BCM_VPN_VFI_IS_SET(vid)) { 11063 VLAN_CHK_ID(unit, vid); 11064 } 11065 if (control.vrf > SOC_VRF_MAX(unit)) { 11066 return (BCM_E_PARAM); 11067 } 11068 11069 /* 11070 * On some devices not all fields are supported 11071 * Raven does not support Forwarding database support. 11072 */ 11073 if (soc_feature(unit, soc_feature_forwarding_db_no_support)) { 11074 if (control.forwarding_vlan) { 11075 return BCM_E_UNAVAIL; 11076 } 11077 valid_fields &= ~BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK; 11078 } 11079 /* 11080 * some device can't support VLAN based VRF due to L3_IIFm can't 11081 * be indexed by VID. 11082 */ 11083 if (soc_feature(unit, soc_feature_no_vlan_vrf)) { 11084 if (control.vrf != 0) { 11085 return BCM_E_UNAVAIL; 11086 } 11087 valid_fields &= ~BCM_VLAN_CONTROL_VLAN_VRF_MASK; 11088 } 11089 rv = bcm_esw_vlan_control_vlan_selective_set( 11090 unit, vid, valid_fields, &control); 11091 } 11092 11093 #if defined(BCM_BRADLEY_SUPPORT) 11094 else if (SOC_IS_HB_GW(unit)) { 11095 bcm_vlan_control_vlan_t vctrl; 11096 vlan_tab_entry_t vt; 11097 11098 /* Check for unsupported parameters */ 11099 sal_memset(&vctrl, 0, sizeof(vctrl)); 11100 if (control.forwarding_vlan > BCM_VLAN_MAX) { 11101 return BCM_E_PARAM; 11102 } 11103 vctrl.forwarding_vlan = control.forwarding_vlan; 11104 if (sal_memcmp(&vctrl, &control, sizeof(vctrl)) != 0) { 11105 return BCM_E_PARAM; 11106 } 11107 11108 soc_mem_lock(unit, VLAN_TABm); 11109 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vid, &vt); 11110 if (BCM_SUCCESS(rv)) { 11111 soc_mem_field32_set(unit, VLAN_TABm, &vt, FID_IDf, 11112 control.forwarding_vlan); 11113 rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ANY, vid, &vt); 11114 } 11115 soc_mem_unlock(unit, VLAN_TABm); 11116 } 11117 #endif /* BCM_BRADLEY_SUPPORT */ 11118 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 11119 return rv; 11120 } 11121 11122 /* 11123 * Function: 11124 * bcm_esw_vlan_control_vlan_get 11125 * Purpose: 11126 * Get per VLAN configuration. 11127 * Parameters: 11128 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 11129 * vid - (IN) VLAN to get the flood setting for. 11130 * control - (OUT) VLAN control structure 11131 * Returns: 11132 * BCM_E_NONE - Success. 11133 * BCM_E_XXX 11134 * Notes: 11135 */ 11136 int 11137 bcm_esw_vlan_control_vlan_get(int unit, bcm_vlan_t vid, 11138 bcm_vlan_control_vlan_t *control) 11139 { 11140 int rv = BCM_E_UNAVAIL; 11141 11142 #ifdef BCM_TOMAHAWK3_SUPPORT 11143 if (SOC_IS_TOMAHAWK3(unit)) { 11144 return bcm_tomahawk3_vlan_control_vlan_get(unit, vid, control); 11145 } 11146 #endif 11147 11148 if (NULL == control) { 11149 return (BCM_E_PARAM); 11150 } 11151 11152 #ifdef BCM_XGS3_SWITCH_SUPPORT 11153 CHECK_INIT(unit); 11154 11155 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 11156 uint32 valid_fields = BCM_VLAN_CONTROL_VLAN_ALL_MASK; 11157 11158 /* 11159 * some device can't support VLAN based VRF due to L3_IIFm can't 11160 * be indexed by VID 11161 */ 11162 if (soc_feature(unit, soc_feature_no_vlan_vrf)) { 11163 valid_fields &= ~BCM_VLAN_CONTROL_VLAN_VRF_MASK; 11164 } 11165 rv = bcm_esw_vlan_control_vlan_selective_get(unit, vid, valid_fields, 11166 control); 11167 } 11168 #if defined(BCM_BRADLEY_SUPPORT) 11169 else if (SOC_IS_HB_GW(unit)) { 11170 vlan_tab_entry_t vt; 11171 11172 soc_mem_lock(unit, VLAN_TABm); 11173 rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vid, &vt); 11174 if (BCM_SUCCESS(rv)) { 11175 control->forwarding_vlan = soc_mem_field32_get(unit, VLAN_TABm, 11176 &vt, FID_IDf); 11177 if (!SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VRF_IDf)) { 11178 control->vrf = 0; 11179 } 11180 } 11181 soc_mem_unlock(unit, VLAN_TABm); 11182 } 11183 #endif /* BCM_TRX_SUPPORT || BCM_BRADLEY_SUPPORT */ 11184 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 11185 return rv; 11186 } 11187 11188 /* 11189 * Function 11190 * bcm_esw_vlan_vector_flags_set 11191 * Purpose 11192 * Set a one or more VLAN control vlan flags on a vlan_vector on this unit 11193 * Parameters 11194 * (in) int unit = unit number 11195 * (in) bcm_vlan_vector_t vlan_vector = Vlan vector for values to be set 11196 * (in) uint32 flags_mask 11197 * (in) uint32 flags_value 11198 * Returns 11199 * bcm_error_t = BCM_E_NONE if successful 11200 * BCM_E_* appropriately if not 11201 * Notes 11202 */ 11203 int 11204 bcm_esw_vlan_vector_flags_set(int unit, 11205 bcm_vlan_vector_t vlan_vector, 11206 uint32 flags_mask, 11207 uint32 flags_value) 11208 { 11209 int rv; 11210 11211 bcm_vlan_t vid; 11212 bcm_vlan_control_vlan_t control; 11213 11214 #ifdef BCM_TOMAHAWK3_SUPPORT 11215 if (SOC_IS_TOMAHAWK3(unit)) { 11216 return bcm_tomahawk3_vlan_vector_flags_set(unit, vlan_vector, 11217 flags_mask, flags_value); 11218 } 11219 #endif 11220 11221 /* non-supported vector flags */ 11222 if (flags_mask & (BCM_VLAN_USE_FABRIC_DISTRIBUTION | BCM_VLAN_COSQ_ENABLE)) { 11223 return BCM_E_PARAM; 11224 } 11225 11226 /* Optimistically assume success from here */ 11227 rv = BCM_E_NONE; 11228 11229 for (vid = BCM_VLAN_MIN + 1; vid < BCM_VLAN_MAX; vid++) { 11230 11231 if (BCM_VLAN_VEC_GET(vlan_vector, vid)) { 11232 11233 rv = bcm_esw_vlan_control_vlan_get(unit, vid, &control); 11234 11235 control.flags = (~flags_mask & control.flags) | (flags_mask & flags_value); 11236 11237 if (BCM_SUCCESS(rv)) { 11238 rv = bcm_esw_vlan_control_vlan_set(unit, vid, control); 11239 } 11240 } 11241 } 11242 return rv; 11243 } 11244 11245 /* 11246 * Function: 11247 * bcm_vlan_cross_connect_add 11248 * Purpose: 11249 * Add a VLAN cross connect entry 11250 * Parameters: 11251 * unit - Device unit number 11252 * outer_vlan - Outer vlan ID 11253 * inner_vlan - Inner vlan ID 11254 * port_1 - First port in the cross-connect 11255 * port_2 - Second port in the cross-connect 11256 * Returns: 11257 * BCM_E_NONE - Success. 11258 * BCM_E_XXX 11259 */ 11260 int 11261 bcm_esw_vlan_cross_connect_add(int unit, 11262 bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan, 11263 bcm_gport_t port_1, bcm_gport_t port_2) 11264 { 11265 #ifdef BCM_TOMAHAWK3_SUPPORT 11266 if (SOC_IS_TOMAHAWK3(unit)) { 11267 return bcm_tomahawk3_vlan_cross_connect_add( 11268 unit, outer_vlan, inner_vlan, port_1, port_2); 11269 } 11270 #endif 11271 #ifdef BCM_TRX_SUPPORT 11272 11273 if ((port_1 == BCM_GPORT_INVALID) || (port_2 == BCM_GPORT_INVALID)) { 11274 return BCM_E_PORT; 11275 } 11276 #ifdef BCM_TRIUMPH3_SUPPORT 11277 if (SOC_IS_TRIUMPH3(unit)) { 11278 return bcm_tr3_l2_cross_connect_add(unit, outer_vlan, inner_vlan, 11279 port_1, port_2); 11280 } 11281 #endif 11282 if (SOC_IS_TRX(unit)) { 11283 return bcm_tr_l2_cross_connect_add(unit, outer_vlan, inner_vlan, 11284 port_1, port_2); 11285 } 11286 #endif 11287 return BCM_E_UNAVAIL; 11288 } 11289 11290 /* 11291 * Function: 11292 * bcm_vlan_cross_connect_delete 11293 * Purpose: 11294 * Delete a VLAN cross connect entry 11295 * Parameters: 11296 * unit - Device unit number 11297 * outer_vlan - Outer vlan ID 11298 * inner_vlan - Inner vlan ID 11299 * Returns: 11300 * BCM_E_NONE - Success. 11301 * BCM_E_XXX 11302 */ 11303 int 11304 bcm_esw_vlan_cross_connect_delete(int unit, 11305 bcm_vlan_t outer_vlan, 11306 bcm_vlan_t inner_vlan) 11307 { 11308 #ifdef BCM_TOMAHAWK3_SUPPORT 11309 if (SOC_IS_TOMAHAWK3(unit)) { 11310 return bcm_tomahawk3_vlan_cross_connect_delete( 11311 unit, outer_vlan, inner_vlan); 11312 } 11313 #endif 11314 #ifdef BCM_TRX_SUPPORT 11315 #ifdef BCM_TRIUMPH3_SUPPORT 11316 if (SOC_IS_TRIUMPH3(unit)) { 11317 return bcm_tr3_l2_cross_connect_delete(unit, outer_vlan, inner_vlan); 11318 } 11319 #endif 11320 if (SOC_IS_TRX(unit)) { 11321 return bcm_tr_l2_cross_connect_delete(unit, outer_vlan, inner_vlan); 11322 } 11323 #endif 11324 return BCM_E_UNAVAIL; 11325 } 11326 11327 /* 11328 * Function: 11329 * bcm_vlan_cross_connect_delete_all 11330 * Purpose: 11331 * Delete all VLAN cross connect entries 11332 * Parameters: 11333 * unit - Device unit number 11334 * Returns: 11335 * BCM_E_NONE - Success. 11336 * BCM_E_XXX 11337 */ 11338 int 11339 bcm_esw_vlan_cross_connect_delete_all(int unit) 11340 { 11341 #ifdef BCM_TOMAHAWK3_SUPPORT 11342 if (SOC_IS_TOMAHAWK3(unit)) { 11343 return bcm_tomahawk3_vlan_cross_connect_delete_all(unit); 11344 } 11345 #endif 11346 #ifdef BCM_TRIUMPH3_SUPPORT 11347 if (SOC_IS_TRIUMPH3(unit)) { 11348 return bcm_tr3_l2_cross_connect_delete_all(unit); 11349 } 11350 #endif 11351 #ifdef BCM_TRX_SUPPORT 11352 if (SOC_IS_TRX(unit)) { 11353 return bcm_tr_l2_cross_connect_delete_all(unit); 11354 } 11355 #endif 11356 return BCM_E_UNAVAIL; 11357 } 11358 11359 /* 11360 * Function: 11361 * bcm_vlan_cross_connect_traverse 11362 * Purpose: 11363 * Walks through the valid cross connect entries and calls 11364 * the user supplied callback function for each entry. 11365 * Parameters: 11366 * unit - (IN) bcm device. 11367 * trav_fn - (IN) Callback function. 11368 * user_data - (IN) User data to be passed to callback function. 11369 * Returns: 11370 * BCM_E_NONE - Success. 11371 * BCM_E_XXX 11372 */ 11373 int 11374 bcm_esw_vlan_cross_connect_traverse(int unit, 11375 bcm_vlan_cross_connect_traverse_cb cb, 11376 void *user_data) 11377 { 11378 #ifdef BCM_TOMAHAWK3_SUPPORT 11379 if (SOC_IS_TOMAHAWK3(unit)) { 11380 return bcm_tomahawk3_vlan_cross_connect_traverse(unit, cb, user_data); 11381 } 11382 #endif 11383 #ifdef BCM_TRX_SUPPORT 11384 #ifdef BCM_TRIUMPH3_SUPPORT 11385 if (SOC_IS_TRIUMPH3(unit)) { 11386 return bcm_tr3_l2_cross_connect_traverse(unit, cb, user_data); 11387 } 11388 #endif 11389 if (SOC_IS_TRX(unit)) { 11390 return bcm_tr_l2_cross_connect_traverse(unit, cb, user_data); 11391 } 11392 #endif 11393 return BCM_E_UNAVAIL; 11394 } 11395 11396 #if defined(BCM_TRIUMPH2_SUPPORT) 11397 STATIC int 11398 _bcm_xgs3_vlan_table_hw_fs_set(int unit, bcm_vlan_t vid, 11399 int fs_idx, int table) 11400 { 11401 vlan_tab_entry_t vt; 11402 int rv; 11403 11404 /* Upper layer already checks that vid is valid */ 11405 soc_mem_lock(unit, table); 11406 11407 rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt); 11408 11409 if (BCM_SUCCESS(rv) && !soc_mem_field32_get(unit, table, &vt, VALIDf)) { 11410 rv = BCM_E_NOT_FOUND; 11411 } 11412 11413 if (BCM_SUCCESS(rv)) { 11414 soc_mem_field32_set(unit, table, &vt, SERVICE_CTR_IDXf, fs_idx); 11415 11416 rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt); 11417 } 11418 11419 soc_mem_unlock(unit, table); 11420 11421 return rv; 11422 } 11423 11424 int 11425 _bcm_esw_vlan_flex_stat_index_set(int unit, bcm_vlan_t vlan, int fs_idx, 11426 uint32 flags) 11427 { 11428 int rv = BCM_E_NONE; 11429 int rv1= BCM_E_NONE; 11430 11431 BCM_LOCK(unit); /* To access the VLAN existence bitmap */ 11432 if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) { 11433 if (flags & _BCM_FLEX_STAT_HW_INGRESS) { 11434 rv = _bcm_xgs3_vlan_table_hw_fs_set(unit, vlan, fs_idx, VLAN_TABm); 11435 } 11436 if (flags & _BCM_FLEX_STAT_HW_EGRESS) { 11437 rv1 = _bcm_xgs3_vlan_table_hw_fs_set(unit, vlan, 11438 fs_idx, EGR_VLANm); 11439 } 11440 } else { 11441 rv = BCM_E_NOT_FOUND; 11442 } 11443 BCM_UNLOCK(unit); 11444 if (BCM_SUCCESS(rv1)) { 11445 return rv; 11446 } else { 11447 return rv1; 11448 } 11449 } 11450 11451 STATIC int 11452 _bcm_esw_vlan_stat_param_verify(int unit, bcm_vlan_t vlan, bcm_cos_t cos) 11453 { 11454 #if defined(INCLUDE_L3) 11455 int vfi; 11456 int rv = BCM_E_NOT_FOUND; 11457 #endif /* INCLUDE_L3 */ 11458 11459 #if defined(INCLUDE_L3) 11460 /* 11461 * Is it a VPN? Both VPLS and VPN have the same VLAN encoding hence looping 11462 * in booth the MIM and VPLS tables 11463 */ 11464 if (_BCM_VPN_IS_VPLS(vlan)) { 11465 #if defined(BCM_TOMAHAWK3_SUPPORT) 11466 if (SOC_IS_TOMAHAWK3(unit)) { 11467 rv = BCM_E_UNAVAIL; 11468 } else 11469 #endif 11470 if (soc_feature(unit, soc_feature_mpls)) { 11471 _BCM_MPLS_VPN_GET(vfi, _BCM_MPLS_VPN_TYPE_VPLS, vlan); 11472 if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMpls)) { 11473 rv = BCM_E_NONE; 11474 } 11475 } else { 11476 rv = BCM_E_UNAVAIL; 11477 } 11478 BCM_IF_ERROR_RETURN (rv); 11479 } else if ((_BCM_VPN_IS_MIM(vlan))) { 11480 if ((rv != BCM_E_NONE) && (soc_feature(unit, soc_feature_mim))) { 11481 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vlan); 11482 if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) { 11483 rv = BCM_E_NONE; 11484 } 11485 } else { 11486 rv = BCM_E_UNAVAIL; 11487 } 11488 BCM_IF_ERROR_RETURN (rv); 11489 11490 } else 11491 #endif /* INCLUDE_L3 */ 11492 { 11493 VLAN_CHK_ID(unit, vlan); 11494 } 11495 if (cos != BCM_COS_INVALID) { 11496 return BCM_E_PARAM; 11497 } 11498 return BCM_E_NONE; 11499 } 11500 11501 STATIC int 11502 _bcm_esw_vlan_stat_param_valid(int unit, bcm_vlan_t vlan, bcm_cos_t cos) 11503 { 11504 CHECK_INIT(unit); 11505 if (!soc_feature(unit, soc_feature_gport_service_counters)) { 11506 return BCM_E_UNAVAIL; 11507 } 11508 return _bcm_esw_vlan_stat_param_verify(unit,vlan,cos); 11509 } 11510 11511 typedef _bcm_flex_stat_t (*_bcm_vlan_stat_to_flex_stat_f)(bcm_vlan_stat_t 11512 stat); 11513 11514 STATIC _bcm_flex_stat_t 11515 _bcm_esw_vlan_stat_to_flex_stat(bcm_vlan_stat_t stat) 11516 { 11517 _bcm_flex_stat_t flex_stat; 11518 11519 switch (stat) { 11520 case bcmVlanStatIngressPackets: 11521 flex_stat = _bcmFlexStatIngressPackets; 11522 break; 11523 case bcmVlanStatIngressBytes: 11524 flex_stat = _bcmFlexStatIngressBytes; 11525 break; 11526 case bcmVlanStatEgressPackets: 11527 flex_stat = _bcmFlexStatEgressPackets; 11528 break; 11529 case bcmVlanStatEgressBytes: 11530 flex_stat = _bcmFlexStatEgressBytes; 11531 break; 11532 default: 11533 flex_stat = _bcmFlexStatNum; 11534 } 11535 11536 return flex_stat; 11537 } 11538 11539 /* Requires "idx" variable */ 11540 #define BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr) \ 11541 for (idx = 0; idx < nstat; idx++) { \ 11542 if (NULL == value_arr + idx) { \ 11543 return (BCM_E_PARAM); \ 11544 } \ 11545 } 11546 11547 STATIC int 11548 _bcm_vlan_stat_array_convert(int unit, int nstat, bcm_vlan_stat_t *stat_arr, 11549 _bcm_flex_stat_t *fs_arr, 11550 _bcm_vlan_stat_to_flex_stat_f vs2fs_f) 11551 { 11552 int idx; 11553 11554 if ((nstat <= 0) || (nstat > _bcmFlexStatNum)) { 11555 return BCM_E_PARAM; 11556 } 11557 11558 if (NULL == stat_arr) { 11559 return (BCM_E_PARAM); 11560 } 11561 11562 for (idx = 0; idx < nstat; idx++) { 11563 fs_arr[idx] = (*vs2fs_f)(stat_arr[idx]); 11564 } 11565 return BCM_E_NONE; 11566 } 11567 11568 #endif /* BCM_TRIUMPH2_SUPPORT */ 11569 11570 /* 11571 * Function: 11572 * bcm_esw_vlan_stat_enable_set 11573 * Purpose: 11574 * Enable/disable collection of statistics on the indicated VLAN. 11575 * Parameters: 11576 * unit - (IN) Unit number. 11577 * vlan - (IN) VLAN Id. 11578 * enable - (IN) Non-zero to enable counter collection, zero to disable. 11579 * Returns: 11580 * BCM_E_XXX 11581 * Notes: 11582 */ 11583 int 11584 bcm_esw_vlan_stat_enable_set(int unit, bcm_vlan_t vlan, int enable) 11585 { 11586 #if defined(BCM_TRIUMPH2_SUPPORT) 11587 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 11588 uint32 num_of_tables=0; 11589 uint32 num_stat_counter_ids=0; 11590 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 11591 bcm_stat_object_t object=bcmStatObjectIngPort; 11592 uint32 stat_counter_id[ 11593 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0}; 11594 uint32 num_entries=0; 11595 int index=0; 11596 11597 #endif 11598 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 11599 BCM_IF_ERROR_RETURN 11600 (_bcm_esw_vlan_stat_param_valid(unit, vlan, BCM_COS_INVALID)); 11601 return _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeService, 11602 _bcm_esw_vlan_flex_stat_hw_index_set, 11603 NULL, vlan, enable,0); 11604 } 11605 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 11606 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info( 11607 unit,vlan,&num_of_tables,&table_info[0])); 11608 if (enable ) { 11609 for(index=0;index < num_of_tables ;index++) { 11610 if(table_info[index].direction == bcmStatFlexDirectionIngress) { 11611 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object( 11612 unit,table_info[index].table, 11613 table_info[index].index,NULL,&object)); 11614 } else { 11615 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object( 11616 unit,table_info[index].table, 11617 table_info[index].index,NULL,&object)); 11618 } 11619 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create( 11620 unit,object,bcmStatGroupModeSingle, 11621 &stat_counter_id[table_info[index].direction], 11622 &num_entries)); 11623 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_attach( 11624 unit,vlan, 11625 stat_counter_id[table_info[index].direction])); 11626 } 11627 return BCM_E_NONE; 11628 } else { 11629 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id( 11630 unit, num_of_tables,&table_info[0], 11631 &num_stat_counter_ids,&stat_counter_id[0])); 11632 if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) && 11633 (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) { 11634 return BCM_E_PARAM; 11635 } 11636 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_detach(unit,vlan)); 11637 if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) { 11638 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 11639 unit, 11640 stat_counter_id[bcmStatFlexDirectionIngress])); 11641 } 11642 if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) { 11643 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 11644 unit, 11645 stat_counter_id[bcmStatFlexDirectionEgress])); 11646 } 11647 return BCM_E_NONE; 11648 } 11649 #else 11650 return BCM_E_UNAVAIL; 11651 #endif 11652 #else 11653 return BCM_E_UNAVAIL; 11654 #endif 11655 } 11656 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 11657 /* 11658 * Function: 11659 * _bcm_esw_vlan_stat_get_table_info 11660 * Description: 11661 * Provides relevant flex table information(table-name,index with 11662 * direction) for given vlan. 11663 * 11664 * Parameters: 11665 * unit - (IN) unit number 11666 * vlan - (IN) VLAN Id. 11667 * num_of_tables - (OUT) Number of flex counter tables 11668 * table_info - (OUT) Flex counter tables information 11669 * 11670 * Return Value: 11671 * BCM_E_XXX 11672 * Notes: 11673 */ 11674 STATIC 11675 bcm_error_t _bcm_esw_vlan_stat_get_table_info( 11676 int unit, 11677 bcm_vlan_t vlan, 11678 uint32 *num_of_tables, 11679 bcm_stat_flex_table_info_t *table_info) 11680 { 11681 #if defined(INCLUDE_L3) 11682 uint32 vfi=0; 11683 bcm_error_t rv = BCM_E_NOT_FOUND; 11684 #endif 11685 (*num_of_tables) = 0; 11686 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 11687 return BCM_E_UNAVAIL; 11688 } 11689 11690 BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify( 11691 unit, vlan, BCM_COS_INVALID)); 11692 if ((_BCM_MPLS_VPN_IS_SET(vlan)) || (_BCM_MIM_VPN_IS_SET(vlan))) { 11693 #if defined(INCLUDE_L3) 11694 #if defined(BCM_TOMAHAWK3_SUPPORT) 11695 if (SOC_IS_TOMAHAWK3(unit)) { 11696 return BCM_E_UNAVAIL; 11697 } 11698 #endif 11699 /* since the VLAN encoding is same for MIM and MPLS looping in both */ 11700 if (soc_feature(unit, soc_feature_mpls)) { 11701 _BCM_MPLS_VPN_GET(vfi, _BCM_MPLS_VPN_TYPE_VPLS, vlan); 11702 if ((_bcm_vfi_used_get(unit,vfi,_bcmVfiTypeMpls))) { 11703 table_info[*num_of_tables].table=VFIm; 11704 table_info[*num_of_tables].index=vfi; 11705 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 11706 (*num_of_tables)++; 11707 table_info[*num_of_tables].table=EGR_VFIm; 11708 table_info[*num_of_tables].index=vfi; 11709 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 11710 (*num_of_tables)++; 11711 rv = BCM_E_NONE; 11712 } 11713 } 11714 if ((rv == BCM_E_NOT_FOUND) && (soc_feature(unit, soc_feature_mim))) { 11715 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vlan); 11716 if ((_bcm_vfi_used_get(unit,vfi,_bcmVfiTypeMim))) { 11717 table_info[*num_of_tables].table=VFIm; 11718 table_info[*num_of_tables].index=vfi; 11719 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 11720 (*num_of_tables)++; 11721 table_info[*num_of_tables].table=EGR_VFIm; 11722 table_info[*num_of_tables].index=vfi; 11723 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 11724 (*num_of_tables)++; 11725 rv = BCM_E_NONE; 11726 } 11727 } 11728 return rv; 11729 #else 11730 return BCM_E_UNAVAIL; 11731 #endif 11732 } else { 11733 if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) { 11734 table_info[*num_of_tables].table=VLAN_TABm; 11735 table_info[*num_of_tables].index=vlan; 11736 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 11737 (*num_of_tables)++; 11738 #if defined(BCM_TOMAHAWK_SUPPORT) 11739 if (SOC_MEM_IS_VALID(unit, EGR_VLANm)) 11740 #endif 11741 { 11742 table_info[*num_of_tables].table=EGR_VLANm; 11743 table_info[*num_of_tables].index=vlan; 11744 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 11745 (*num_of_tables)++; 11746 } 11747 return BCM_E_NONE; 11748 } 11749 return BCM_E_NOT_FOUND; 11750 } 11751 /* Must not hit */ 11752 return BCM_E_NOT_FOUND; 11753 } 11754 #endif 11755 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 11756 /* 11757 * Function: 11758 * _bcm_esw_vlan_stat_attach 11759 * Description: 11760 * Attach counter entries to the given vlan 11761 * 11762 * Parameters: 11763 * unit - (IN) unit number 11764 * vlan - (IN) VLAN Id. 11765 * stat_counter_id - (IN) Stat Counter ID. 11766 * 11767 * Return Value: 11768 * BCM_E_XXX 11769 * Notes: 11770 */ 11771 STATIC bcm_error_t _bcm_esw_vlan_stat_attach( 11772 int unit, 11773 bcm_vlan_t vlan, 11774 uint32 stat_counter_id) 11775 { 11776 soc_mem_t table=0; 11777 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 11778 uint32 pool_number=0; 11779 uint32 base_index=0; 11780 bcm_stat_flex_mode_t offset_mode=0; 11781 bcm_stat_object_t object=bcmStatObjectIngPort; 11782 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 11783 uint32 count=0; 11784 uint32 actual_num_tables=0; 11785 uint32 num_of_tables=0; 11786 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 11787 11788 _bcm_esw_stat_get_counter_id_info( 11789 unit, stat_counter_id, 11790 &group_mode,&object,&offset_mode,&pool_number,&base_index); 11791 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction)); 11792 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode)); 11793 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 11794 unit,object,1,&actual_num_tables,&table,&direction)); 11795 11796 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info( 11797 unit, vlan,&num_of_tables,&table_info[0])); 11798 for (count=0; count < num_of_tables ; count++) { 11799 if ((table_info[count].direction == direction) && 11800 (table_info[count].table == table)) { 11801 if (direction == bcmStatFlexDirectionIngress) { 11802 return _bcm_esw_stat_flex_attach_ingress_table_counters( 11803 unit,table_info[count].table,table_info[count].index, 11804 offset_mode, base_index, pool_number); 11805 } else { 11806 return _bcm_esw_stat_flex_attach_egress_table_counters( 11807 unit,table_info[count].table,table_info[count].index, 11808 0, offset_mode,base_index,pool_number); 11809 } 11810 } 11811 } 11812 return BCM_E_NOT_FOUND; 11813 } 11814 #endif 11815 11816 /* 11817 * Function: 11818 * bcm_esw_vlan_stat_attach 11819 * Description: 11820 * Attach counter entries to the given vlan 11821 * 11822 * Parameters: 11823 * unit - (IN) unit number 11824 * vlan - (IN) VLAN Id. 11825 * stat_counter_id - (IN) Stat Counter ID. 11826 * 11827 * Return Value: 11828 * BCM_E_XXX 11829 * Notes: 11830 */ 11831 int bcm_esw_vlan_stat_attach( 11832 int unit, 11833 bcm_vlan_t vlan, 11834 uint32 stat_counter_id) 11835 { 11836 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 11837 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 11838 return _bcm_esw_vlan_stat_attach(unit,vlan,stat_counter_id); 11839 } else 11840 #endif 11841 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 11842 if (soc_feature(unit,soc_feature_gport_service_counters)) { 11843 _bcm_flex_stat_type_t fs_type; 11844 uint32 fs_inx; 11845 uint32 flag; 11846 11847 fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id); 11848 fs_inx = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id); 11849 11850 if (!((fs_type == _bcmFlexStatTypeService || 11851 fs_type == _bcmFlexStatTypeEgressService) && fs_inx)) { 11852 return BCM_E_PARAM; 11853 } 11854 BCM_IF_ERROR_RETURN 11855 (_bcm_esw_vlan_stat_param_valid(unit, vlan, BCM_COS_INVALID)); 11856 11857 flag = fs_type==_bcmFlexStatTypeService? _BCM_FLEX_STAT_HW_INGRESS: 11858 _BCM_FLEX_STAT_HW_EGRESS; 11859 return _bcm_esw_flex_stat_enable_set(unit, fs_type, 11860 _bcm_esw_vlan_flex_stat_hw_index_set, 11861 INT_TO_PTR(flag), 11862 vlan, TRUE,fs_inx); 11863 } else 11864 #endif 11865 { 11866 return BCM_E_UNAVAIL; 11867 } 11868 } 11869 11870 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 11871 /* 11872 * Function: 11873 * _bcm_esw_vlan_stat_detach 11874 * Description: 11875 * Detach counter entries to the given GPORT 11876 * 11877 * Parameters: 11878 * unit - (IN) unit number 11879 * vlan - (IN) VLAN Id. 11880 * 11881 * Return Value: 11882 * BCM_E_XXX 11883 * Notes: 11884 */ 11885 STATIC bcm_error_t _bcm_esw_vlan_stat_detach( 11886 int unit, 11887 bcm_vlan_t vlan) 11888 { 11889 uint32 count=0; 11890 uint32 num_of_tables=0; 11891 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 11892 bcm_error_t rv = BCM_E_NONE; 11893 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 11894 11895 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info( 11896 unit, vlan,&num_of_tables,&table_info[0])); 11897 11898 for (count=0; count < num_of_tables ; count++) { 11899 if (table_info[count].direction == bcmStatFlexDirectionIngress) { 11900 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 11901 unit, table_info[count].table, table_info[count].index); 11902 if (BCM_E_NONE != rv && 11903 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 11904 err_code[bcmStatFlexDirectionIngress] = rv; 11905 } 11906 } else { 11907 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 11908 unit, 0, table_info[count].table, table_info[count].index); 11909 11910 if (BCM_E_NONE != rv && 11911 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 11912 err_code[bcmStatFlexDirectionEgress] = rv; 11913 } 11914 } 11915 } 11916 11917 BCM_STAT_FLEX_DETACH_RETURN(err_code) 11918 } 11919 11920 /* 11921 * Function: 11922 * _bcm_esw_vlan_stat_detach_with_id 11923 * Description: 11924 * Detach counter entries to the given vlan with a given stat counter id 11925 * 11926 * Parameters: 11927 * unit - (IN) unit number 11928 * vlan - (IN) VLAN Id 11929 * stat_counter_id - (IN) Stat Counter ID. 11930 * 11931 * Return Value: 11932 * BCM_E_XXX 11933 * Notes: 11934 */ 11935 STATIC bcm_error_t _bcm_esw_vlan_stat_detach_with_id( 11936 int unit, 11937 bcm_vlan_t vlan, 11938 uint32 stat_counter_id) 11939 { 11940 uint32 count=0; 11941 uint32 num_of_tables=0; 11942 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 11943 bcm_error_t rv = BCM_E_NONE; 11944 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 11945 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 11946 uint32 pool_number=0; 11947 uint32 base_index=0; 11948 bcm_stat_flex_mode_t offset_mode=0; 11949 bcm_stat_object_t object=bcmStatObjectIngPort; 11950 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 11951 uint32 actual_num_tables=0; 11952 soc_mem_t table=0; 11953 11954 11955 _bcm_esw_stat_get_counter_id_info( 11956 unit, stat_counter_id, 11957 &group_mode,&object,&offset_mode,&pool_number,&base_index); 11958 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction)); 11959 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode)); 11960 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 11961 unit,object,1,&actual_num_tables,&table,&direction)); 11962 11963 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info( 11964 unit, vlan,&num_of_tables,&table_info[0])); 11965 11966 for (count=0; count < num_of_tables ; count++) { 11967 if((table_info[count].direction == direction) && 11968 (table_info[count].table == table)) { 11969 if(direction == bcmStatFlexDirectionIngress) { 11970 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 11971 unit, table_info[count].table, table_info[count].index); 11972 if (BCM_E_NONE != rv && 11973 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 11974 err_code[bcmStatFlexDirectionIngress] = rv; 11975 } 11976 } else { 11977 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 11978 unit, 0, table_info[count].table, table_info[count].index); 11979 if (BCM_E_NONE != rv && 11980 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 11981 err_code[bcmStatFlexDirectionEgress] = rv; 11982 } 11983 } 11984 } 11985 } 11986 11987 BCM_STAT_FLEX_DETACH_RETURN(err_code) 11988 } 11989 #endif 11990 11991 /* 11992 * Function: 11993 * bcm_esw_vlan_stat_detach 11994 * Description: 11995 * Detach counter entries to the given GPORT 11996 * 11997 * Parameters: 11998 * unit - (IN) unit number 11999 * vlan - (IN) VLAN Id. 12000 * 12001 * Return Value: 12002 * BCM_E_XXX 12003 * Notes: 12004 */ 12005 int bcm_esw_vlan_stat_detach( 12006 int unit, 12007 bcm_vlan_t vlan) 12008 { 12009 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12010 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 12011 return _bcm_esw_vlan_stat_detach(unit,vlan); 12012 } else 12013 #endif 12014 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 12015 if (soc_feature(unit,soc_feature_gport_service_counters)) { 12016 uint32 flag; 12017 int rv; 12018 12019 BCM_IF_ERROR_RETURN 12020 (_bcm_esw_vlan_stat_param_valid(unit, vlan, BCM_COS_INVALID)); 12021 12022 flag = _BCM_FLEX_STAT_HW_INGRESS; 12023 rv = _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeService, 12024 _bcm_esw_vlan_flex_stat_hw_index_set, 12025 INT_TO_PTR(flag), 12026 vlan, FALSE, 1); 12027 flag = _BCM_FLEX_STAT_HW_EGRESS; 12028 rv = _bcm_esw_flex_stat_enable_set(unit,_bcmFlexStatTypeEgressService, 12029 _bcm_esw_vlan_flex_stat_hw_index_set, 12030 INT_TO_PTR(flag), 12031 vlan, FALSE, 1); 12032 return rv; 12033 } else 12034 #endif 12035 { 12036 return BCM_E_UNAVAIL; 12037 } 12038 } 12039 12040 /* 12041 * Function: 12042 * bcm_esw_vlan_stat_detach_with_id 12043 * Description: 12044 * Detach counter entries to the given vlan with a given stat counter id 12045 * 12046 * Parameters: 12047 * unit - (IN) unit number 12048 * vlan - (IN) VLAN Id 12049 * stat_counter_id - (IN) Stat Counter ID. 12050 * 12051 * Return Value: 12052 * BCM_E_XXX 12053 * Notes: 12054 */ 12055 bcm_error_t bcm_esw_vlan_stat_detach_with_id( 12056 int unit, 12057 bcm_vlan_t vlan, 12058 uint32 stat_counter_id) 12059 { 12060 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12061 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 12062 return _bcm_esw_vlan_stat_detach_with_id(unit, vlan, stat_counter_id); 12063 } else 12064 #endif 12065 { 12066 return BCM_E_UNAVAIL; 12067 } 12068 } 12069 12070 12071 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12072 /* 12073 * Function: 12074 * _bcm_esw_vlan_stat_counter_get 12075 * Description: 12076 * retrieve set of counter statistic values for the given vlan 12077 * if sync_mode is set, sync the sw accumulated count 12078 * with hw count value first, else return sw count. 12079 * 12080 * Parameters: 12081 * unit - (IN) unit number 12082 * sync_mode - (IN) hwcount is to be synced to sw count 12083 * vlan - (IN) VLAN ID 12084 * stat - (IN) Type of the counter to retrieve 12085 * I.e. ingress/egress byte/packet) 12086 * num_entries - (IN) Number of counter Entries 12087 * counter_indexes - (IN) Pointer to Counter indexes entries 12088 * counter_values - (OUT) Pointer to counter values 12089 * 12090 * Return Value: 12091 * BCM_E_XXX 12092 * Notes: 12093 */ 12094 STATIC bcm_error_t _bcm_esw_vlan_stat_counter_get( 12095 int unit, 12096 int sync_mode, 12097 bcm_vlan_t vlan, 12098 bcm_vlan_stat_t stat, 12099 uint32 num_entries, 12100 uint32 *counter_indexes, 12101 bcm_stat_value_t *counter_values) 12102 { 12103 uint32 table_count=0; 12104 uint32 index_count=0; 12105 uint32 num_of_tables=0; 12106 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 12107 uint32 byte_flag=0; 12108 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 12109 12110 if ((NULL == counter_indexes) || (NULL == counter_values)) { 12111 return BCM_E_PARAM; 12112 } 12113 12114 switch(stat) { 12115 case bcmVlanStatIngressPackets: 12116 case bcmVlanStatEgressPackets: 12117 byte_flag=0; 12118 break; 12119 case bcmVlanStatIngressBytes: 12120 case bcmVlanStatEgressBytes: 12121 byte_flag=1; 12122 break; 12123 default: 12124 return BCM_E_PARAM; 12125 } 12126 if ((stat == bcmVlanStatIngressPackets) || 12127 (stat == bcmVlanStatIngressBytes)) { 12128 direction = bcmStatFlexDirectionIngress; 12129 } else { 12130 direction = bcmStatFlexDirectionEgress; 12131 } 12132 12133 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info( 12134 unit, vlan,&num_of_tables,&table_info[0])); 12135 12136 for (table_count=0; table_count < num_of_tables ; table_count++) { 12137 if (table_info[table_count].direction == direction) { 12138 for (index_count=0; index_count < num_entries ; index_count++) { 12139 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get( 12140 unit, sync_mode, 12141 table_info[table_count].index, 12142 table_info[table_count].table, 12143 0, 12144 byte_flag, 12145 counter_indexes[index_count], 12146 &counter_values[index_count])); 12147 } 12148 } 12149 } 12150 return BCM_E_NONE; 12151 } 12152 #endif 12153 12154 /* 12155 * Function: 12156 * _bcm_esw_vlan_flex_stat_counter_get 12157 * Description: 12158 * retrieve set of counter statistic values for the given vlan 12159 * if sync_mode is set, sync the sw accumulated count 12160 * with hw count value first, else return sw count. 12161 * 12162 * Parameters: 12163 * unit - (IN) unit number 12164 * sync_mode - (IN) hwcount is to be synced to sw count 12165 * vlan - (IN) VLAN ID 12166 * stat - (IN) Type of the counter to retrieve 12167 * I.e. ingress/egress byte/packet) 12168 * num_entries - (IN) Number of counter Entries 12169 * counter_indexes - (IN) Pointer to Counter indexes entries 12170 * counter_values - (OUT) Pointer to counter values 12171 * 12172 * Return Value: 12173 * BCM_E_XXX 12174 * Notes: 12175 */ 12176 int 12177 _bcm_esw_vlan_flex_stat_counter_get(int unit, 12178 int sync_mode, 12179 bcm_vlan_t vlan, 12180 bcm_vlan_stat_t stat, 12181 uint32 num_entries, 12182 uint32 *counter_indexes, 12183 bcm_stat_value_t *counter_values) 12184 { 12185 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12186 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 12187 return _bcm_esw_vlan_stat_counter_get(unit, sync_mode, vlan, stat, 12188 num_entries, counter_indexes, counter_values); 12189 } else 12190 #endif 12191 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 12192 if (soc_feature(unit,soc_feature_gport_service_counters)) { 12193 uint64 val; 12194 int rv = BCM_E_NONE; 12195 12196 rv = _bcm_esw_flex_stat_get(unit, 0, 12197 ((stat == bcmVlanStatIngressPackets) || 12198 (stat == bcmVlanStatIngressBytes)) ? 12199 _bcmFlexStatTypeService:_bcmFlexStatTypeEgressService, 12200 vlan, 12201 _bcm_esw_vlan_stat_to_flex_stat(stat), &val); 12202 12203 if ((stat == bcmVlanStatIngressPackets) || 12204 (stat == bcmVlanStatEgressPackets)) { 12205 counter_values->packets = COMPILER_64_LO(val); 12206 } else { 12207 COMPILER_64_SET(counter_values->bytes, 12208 COMPILER_64_HI(val), 12209 COMPILER_64_LO(val)); 12210 } 12211 return rv; 12212 12213 } else 12214 #endif 12215 { 12216 return BCM_E_UNAVAIL; 12217 } 12218 } 12219 /* 12220 * Function: 12221 * bcm_esw_vlan_stat_counter_get 12222 * Description: 12223 * retrieve set of counter statistic values for the given vlan 12224 * 12225 * Parameters: 12226 * unit - (IN) unit number 12227 * vlan - (IN) VLAN ID 12228 * stat - (IN) Type of the counter to retrieve 12229 * I.e. ingress/egress byte/packet) 12230 * num_entries - (IN) Number of counter Entries 12231 * counter_indexes - (IN) Pointer to Counter indexes entries 12232 * counter_values - (OUT) Pointer to counter values 12233 * 12234 * Return Value: 12235 * BCM_E_XXX 12236 * Notes: 12237 */ 12238 int 12239 bcm_esw_vlan_stat_counter_get(int unit, 12240 bcm_vlan_t vlan, 12241 bcm_vlan_stat_t stat, 12242 uint32 num_entries, 12243 uint32 *counter_indexes, 12244 bcm_stat_value_t *counter_values) 12245 { 12246 return _bcm_esw_vlan_flex_stat_counter_get(unit, 0, vlan, stat, num_entries, 12247 counter_indexes, counter_values); 12248 } 12249 12250 12251 /* 12252 * Function: 12253 * bcm_esw_vlan_stat_counter_sync_get 12254 * Description: 12255 * retrieve set of counter statistic values for the given vlan 12256 * sw accumulated counters synced with hw count. 12257 * 12258 * Parameters: 12259 * unit - (IN) unit number 12260 * vlan - (IN) VLAN ID 12261 * stat - (IN) Type of the counter to retrieve 12262 * I.e. ingress/egress byte/packet) 12263 * num_entries - (IN) Number of counter Entries 12264 * counter_indexes - (IN) Pointer to Counter indexes entries 12265 * counter_values - (OUT) Pointer to counter values 12266 * 12267 * Return Value: 12268 * BCM_E_XXX 12269 * Notes: 12270 */ 12271 int 12272 bcm_esw_vlan_stat_counter_sync_get(int unit, 12273 bcm_vlan_t vlan, 12274 bcm_vlan_stat_t stat, 12275 uint32 num_entries, 12276 uint32 *counter_indexes, 12277 bcm_stat_value_t *counter_values) 12278 { 12279 return _bcm_esw_vlan_flex_stat_counter_get(unit, 1, vlan, stat, num_entries, 12280 counter_indexes, counter_values); 12281 } 12282 12283 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12284 /* 12285 * Function: 12286 * _bcm_esw_vlan_stat_counter_set 12287 * Description: 12288 * set counter statistic values for the given VLAN 12289 * 12290 * Parameters: 12291 * unit - (IN) unit number 12292 * port - (IN) VLAN ID 12293 * stat - (IN) Type of the counter to retrieve 12294 * I.e. ingress/egress byte/packet) 12295 * num_entries - (IN) Number of counter Entries 12296 * counter_indexes - (IN) Pointer to Counter indexes entries 12297 * counter_values - (IN) Pointer to counter values 12298 * 12299 * Return Value: 12300 * BCM_E_XXX 12301 * Notes: 12302 */ 12303 STATIC bcm_error_t _bcm_esw_vlan_stat_counter_set( 12304 int unit, 12305 bcm_vlan_t vlan, 12306 bcm_vlan_stat_t stat, 12307 uint32 num_entries, 12308 uint32 *counter_indexes, 12309 bcm_stat_value_t *counter_values) 12310 { 12311 uint32 table_count=0; 12312 uint32 index_count=0; 12313 uint32 num_of_tables=0; 12314 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 12315 uint32 byte_flag=0; 12316 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 12317 12318 if ((NULL == counter_indexes) || (NULL == counter_values)) { 12319 return BCM_E_PARAM; 12320 } 12321 12322 switch(stat) { 12323 case bcmVlanStatIngressPackets: 12324 case bcmVlanStatEgressPackets: 12325 byte_flag=0; 12326 break; 12327 case bcmVlanStatIngressBytes: 12328 case bcmVlanStatEgressBytes: 12329 byte_flag=1; 12330 break; 12331 default: 12332 return BCM_E_PARAM; 12333 } 12334 if ((stat == bcmVlanStatIngressPackets) || 12335 (stat == bcmVlanStatIngressBytes)) { 12336 direction = bcmStatFlexDirectionIngress; 12337 } else { 12338 direction = bcmStatFlexDirectionEgress; 12339 } 12340 12341 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info( 12342 unit, vlan,&num_of_tables,&table_info[0])); 12343 12344 for (table_count=0; table_count < num_of_tables ; table_count++) { 12345 if (table_info[table_count].direction == direction) { 12346 for (index_count=0; index_count < num_entries ; index_count++) { 12347 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set( 12348 unit, 12349 table_info[table_count].index, 12350 table_info[table_count].table, 12351 0, 12352 byte_flag, 12353 counter_indexes[index_count], 12354 &counter_values[index_count])); 12355 } 12356 } 12357 } 12358 return BCM_E_NONE; 12359 } 12360 #endif 12361 12362 /* 12363 * Function: 12364 * bcm_esw_vlan_stat_counter_set 12365 * Description: 12366 * set counter statistic values for the given VLAN 12367 * 12368 * Parameters: 12369 * unit - (IN) unit number 12370 * port - (IN) VLAN ID 12371 * stat - (IN) Type of the counter to retrieve 12372 * I.e. ingress/egress byte/packet) 12373 * num_entries - (IN) Number of counter Entries 12374 * counter_indexes - (IN) Pointer to Counter indexes entries 12375 * counter_values - (IN) Pointer to counter values 12376 * 12377 * Return Value: 12378 * BCM_E_XXX 12379 * Notes: 12380 */ 12381 int bcm_esw_vlan_stat_counter_set( 12382 int unit, 12383 bcm_vlan_t vlan, 12384 bcm_vlan_stat_t stat, 12385 uint32 num_entries, 12386 uint32 *counter_indexes, 12387 bcm_stat_value_t *counter_values) 12388 { 12389 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12390 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 12391 return _bcm_esw_vlan_stat_counter_set(unit,vlan,stat, 12392 num_entries,counter_indexes,counter_values); 12393 } else 12394 #endif 12395 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 12396 if (soc_feature(unit,soc_feature_gport_service_counters)) { 12397 uint64 val; 12398 int rv = BCM_E_NONE; 12399 12400 if ((stat == bcmVlanStatIngressPackets) || 12401 (stat == bcmVlanStatEgressPackets)) { 12402 COMPILER_64_SET(val,0,counter_values->packets); 12403 } else { 12404 COMPILER_64_SET(val, 12405 COMPILER_64_HI(counter_values->bytes), 12406 COMPILER_64_LO(counter_values->bytes)); 12407 } 12408 rv = _bcm_esw_flex_stat_set(unit, 12409 ((stat == bcmVlanStatIngressPackets) || 12410 (stat == bcmVlanStatIngressBytes)) ? 12411 _bcmFlexStatTypeService:_bcmFlexStatTypeEgressService, 12412 vlan, 12413 _bcm_esw_vlan_stat_to_flex_stat(stat), val); 12414 12415 return rv; 12416 12417 } else 12418 #endif 12419 { 12420 return BCM_E_UNAVAIL; 12421 } 12422 } 12423 12424 /* 12425 * Function: 12426 * bcm_esw_vlan_stat_id_get 12427 * Description: 12428 * Get stat counter id associated with given vlan 12429 * 12430 * Parameters: 12431 * unit - (IN) unit number 12432 * vlan - (IN) VLAN ID 12433 * stat - (IN) Type of the counter to retrieve 12434 * I.e. ingress/egress byte/packet) 12435 * Stat_counter_id - (OUT) Stat Counter ID 12436 * 12437 * Return Value: 12438 * BCM_E_XXX 12439 * Notes: 12440 */ 12441 int bcm_esw_vlan_stat_id_get( 12442 int unit, 12443 bcm_vlan_t vlan, 12444 bcm_vlan_stat_t stat, 12445 uint32 *stat_counter_id) 12446 { 12447 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12448 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 12449 uint32 num_of_tables=0; 12450 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 12451 uint32 index=0; 12452 uint32 num_stat_counter_ids=0; 12453 12454 if ((stat == bcmVlanStatIngressPackets) || 12455 (stat == bcmVlanStatIngressBytes)) { 12456 direction = bcmStatFlexDirectionIngress; 12457 } else { 12458 direction = bcmStatFlexDirectionEgress; 12459 } 12460 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info( 12461 unit,vlan,&num_of_tables,&table_info[0])); 12462 for (index=0; index < num_of_tables ; index++) { 12463 if (table_info[index].direction == direction) 12464 return _bcm_esw_stat_flex_get_counter_id( 12465 unit, 1, &table_info[index], 12466 &num_stat_counter_ids,stat_counter_id); 12467 } 12468 return BCM_E_NOT_FOUND; 12469 #else 12470 return BCM_E_UNAVAIL; 12471 #endif 12472 } 12473 12474 12475 12476 /* 12477 * Function: 12478 * _bcm_esw_vlan_stat_get 12479 * Purpose: 12480 * Extract per-VLAN statistics from the chip. 12481 * if sync_mode is set, sync the sw accumulated count 12482 * with hw count value first, else return sw count. 12483 * 12484 * Parameters: 12485 * unit - (IN) Unit number. 12486 * sync_mode - (IN) hwcount is to be synced to sw count 12487 * vlan - (IN) VLAN Id. 12488 * cos - (IN) COS or priority 12489 * stat - (IN) Type of the counter to retrieve. 12490 * val - (OUT) Pointer to a counter value. 12491 * Returns: 12492 * BCM_E_XXX 12493 * Notes: 12494 */ 12495 int 12496 _bcm_esw_vlan_stat_get(int unit, int sync_mode, 12497 bcm_vlan_t vlan, bcm_cos_t cos, 12498 bcm_vlan_stat_t stat, uint64 *val) 12499 { 12500 #if defined(BCM_TRIUMPH2_SUPPORT) 12501 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12502 uint32 counter_indexes=0; 12503 bcm_stat_value_t counter_values={0}; 12504 #endif 12505 12506 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 12507 BCM_IF_ERROR_RETURN 12508 (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos)); 12509 return _bcm_esw_flex_stat_get(unit, sync_mode, 12510 _bcmFlexStatTypeService, vlan, 12511 _bcm_esw_vlan_stat_to_flex_stat(stat), 12512 val); 12513 } 12514 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12515 BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify( 12516 unit, vlan, cos)); 12517 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_flex_stat_counter_get(unit, sync_mode, 12518 vlan, stat, 1, 12519 &counter_indexes, 12520 &counter_values)); 12521 if ((stat == bcmVlanStatIngressPackets) || 12522 (stat == bcmVlanStatEgressPackets)) { 12523 COMPILER_64_SET(*val, 12524 COMPILER_64_HI(counter_values.packets64), 12525 COMPILER_64_LO(counter_values.packets64)); 12526 } else { 12527 COMPILER_64_SET(*val, 12528 COMPILER_64_HI(counter_values.bytes), 12529 COMPILER_64_LO(counter_values.bytes)); 12530 } 12531 return BCM_E_NONE; 12532 #else 12533 return BCM_E_UNAVAIL; 12534 #endif 12535 #else 12536 return BCM_E_UNAVAIL; 12537 #endif 12538 } 12539 12540 12541 /* 12542 * Function: 12543 * bcm_esw_vlan_stat_get 12544 * Purpose: 12545 * Extract per-VLAN statistics from the chip. 12546 * Parameters: 12547 * unit - (IN) Unit number. 12548 * vlan - (IN) VLAN Id. 12549 * cos - (IN) COS or priority 12550 * stat - (IN) Type of the counter to retrieve. 12551 * val - (OUT) Pointer to a counter value. 12552 * Returns: 12553 * BCM_E_XXX 12554 * Notes: 12555 */ 12556 int 12557 bcm_esw_vlan_stat_get(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 12558 bcm_vlan_stat_t stat, uint64 *val) 12559 { 12560 int rv = BCM_E_NONE; 12561 12562 rv = _bcm_esw_vlan_stat_get(unit, 0, vlan, cos, stat, val); 12563 12564 return rv; 12565 } 12566 12567 12568 /* 12569 * Function: 12570 * bcm_esw_vlan_stat_sync_get 12571 * Purpose: 12572 * Extract per-VLAN statistics from the chip. 12573 * sw accumulated counters synced with hw count. 12574 * 12575 * Parameters: 12576 * unit - (IN) Unit number. 12577 * vlan - (IN) VLAN Id. 12578 * cos - (IN) COS or priority 12579 * stat - (IN) Type of the counter to retrieve. 12580 * val - (OUT) Pointer to a counter value. 12581 * Returns: 12582 * BCM_E_XXX 12583 * Notes: 12584 */ 12585 int 12586 bcm_esw_vlan_stat_sync_get(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 12587 bcm_vlan_stat_t stat, uint64 *val) 12588 { 12589 int rv = BCM_E_NONE; 12590 12591 rv = _bcm_esw_vlan_stat_get(unit, 1, vlan, cos, stat, val); 12592 12593 return rv; 12594 } 12595 12596 /* 12597 * Function: 12598 * _bcm_esw_vlan_stat_get32 12599 * Purpose: 12600 * Extract per-VLAN statistics from the chip. 12601 * if sync_mode is set, sync the sw accumulated count 12602 * with hw count value first, else return sw count. 12603 * 12604 * Parameters: 12605 * unit - (IN) Unit number. 12606 * sync_mode - (IN) hwcount is to be synced to sw count 12607 * vlan - (IN) VLAN Id. 12608 * cos - (IN) COS or priority 12609 * stat - (IN) Type of the counter to retrieve. 12610 * val - (OUT) Pointer to a counter value. 12611 * Returns: 12612 * BCM_E_XXX 12613 * Notes: 12614 */ 12615 int 12616 _bcm_esw_vlan_stat_get32(int unit, int sync_mode, 12617 bcm_vlan_t vlan, bcm_cos_t cos, 12618 bcm_vlan_stat_t stat, uint32 *val) 12619 { 12620 #if defined(BCM_TRIUMPH2_SUPPORT) 12621 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12622 uint32 counter_indexes=0; 12623 bcm_stat_value_t counter_values={0}; 12624 #endif 12625 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 12626 BCM_IF_ERROR_RETURN 12627 (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos)); 12628 return _bcm_esw_flex_stat_get32(unit, sync_mode, 12629 _bcmFlexStatTypeService, vlan, 12630 _bcm_esw_vlan_stat_to_flex_stat(stat), val); 12631 } 12632 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12633 BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify( 12634 unit, vlan, cos)); 12635 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_flex_stat_counter_get(unit, sync_mode, 12636 vlan, stat, 1, 12637 &counter_indexes, 12638 &counter_values)); 12639 if ((stat == bcmVlanStatIngressPackets) || 12640 (stat == bcmVlanStatEgressPackets)) { 12641 *val = counter_values.packets; 12642 } else { 12643 /* Ignoring Hi bytes value */ 12644 *val = COMPILER_64_LO(counter_values.bytes); 12645 } 12646 return BCM_E_NONE; 12647 #else 12648 return BCM_E_UNAVAIL; 12649 #endif 12650 #else 12651 return BCM_E_UNAVAIL; 12652 #endif 12653 } 12654 12655 /* 12656 * Function: 12657 * bcm_esw_vlan_stat_get32 12658 * Purpose: 12659 * Extract per-VLAN statistics from the chip. 12660 * Parameters: 12661 * unit - (IN) Unit number. 12662 * vlan - (IN) VLAN Id. 12663 * cos - (IN) COS or priority 12664 * stat - (IN) Type of the counter to retrieve. 12665 * val - (OUT) Pointer to a counter value. 12666 * Returns: 12667 * BCM_E_XXX 12668 * Notes: 12669 */ 12670 int 12671 bcm_esw_vlan_stat_get32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 12672 bcm_vlan_stat_t stat, uint32 *val) 12673 { 12674 int rv = BCM_E_NONE; 12675 12676 rv = _bcm_esw_vlan_stat_get32(unit, 0, vlan, cos, stat, val); 12677 12678 return rv; 12679 } 12680 12681 /* 12682 * Function: 12683 * bcm_esw_vlan_stat_sync_get32 12684 * Purpose: 12685 * Extract per-VLAN statistics from the chip. 12686 * sw accumulated counters synced with hw count. 12687 * 12688 * Parameters: 12689 * unit - (IN) Unit number. 12690 * vlan - (IN) VLAN Id. 12691 * cos - (IN) COS or priority 12692 * stat - (IN) Type of the counter to retrieve. 12693 * val - (OUT) Pointer to a counter value. 12694 * Returns: 12695 * BCM_E_XXX 12696 * Notes: 12697 */ 12698 int 12699 bcm_esw_vlan_stat_sync_get32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 12700 bcm_vlan_stat_t stat, uint32 *val) 12701 { 12702 int rv = BCM_E_NONE; 12703 12704 rv = _bcm_esw_vlan_stat_get32(unit, 1, vlan, cos, stat, val); 12705 12706 return rv; 12707 } 12708 12709 /* 12710 * Function: 12711 * bcm_esw_vlan_stat_set 12712 * Purpose: 12713 * Set the specified statistic to the indicated value for the 12714 * specified VLAN. 12715 * Parameters: 12716 * unit - (IN) Unit number. 12717 * vlan - (IN) VLAN Id. 12718 * cos - (IN) COS or priority 12719 * stat - (IN) Type of the counter to set. 12720 * val - (IN) New counter value. 12721 * Returns: 12722 * BCM_E_XXX 12723 * Notes: 12724 */ 12725 int 12726 bcm_esw_vlan_stat_set(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 12727 bcm_vlan_stat_t stat, uint64 val) 12728 { 12729 #if defined(BCM_TRIUMPH2_SUPPORT) 12730 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12731 uint32 counter_indexes=0; 12732 bcm_stat_value_t counter_values={0}; 12733 #endif 12734 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 12735 BCM_IF_ERROR_RETURN 12736 (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos)); 12737 return _bcm_esw_flex_stat_set(unit, _bcmFlexStatTypeService, vlan, 12738 _bcm_esw_vlan_stat_to_flex_stat(stat), val); 12739 } 12740 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12741 if ((stat == bcmVlanStatIngressPackets) || 12742 (stat == bcmVlanStatEgressPackets)) { 12743 counter_values.packets = COMPILER_64_LO(val); 12744 } else { 12745 COMPILER_64_SET(counter_values.bytes, 12746 COMPILER_64_HI(val), 12747 COMPILER_64_LO(val)); 12748 } 12749 BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify( 12750 unit, vlan, cos)); 12751 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_set( 12752 unit,vlan, stat, 1, &counter_indexes, &counter_values)); 12753 return BCM_E_NONE; 12754 #else 12755 return BCM_E_UNAVAIL; 12756 #endif 12757 #else 12758 return BCM_E_UNAVAIL; 12759 #endif 12760 } 12761 12762 /* 12763 * Function: 12764 * bcm_esw_vlan_stat_set32 12765 * Purpose: 12766 * Set the specified statistic to the indicated value for the 12767 * specified VLAN. 12768 * Parameters: 12769 * unit - (IN) Unit number. 12770 * vlan - (IN) VLAN Id. 12771 * cos - (IN) COS or priority 12772 * stat - (IN) Type of the counter to set. 12773 * val - (IN) New counter value. 12774 * Returns: 12775 * BCM_E_XXX 12776 * Notes: 12777 */ 12778 int 12779 bcm_esw_vlan_stat_set32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 12780 bcm_vlan_stat_t stat, uint32 val) 12781 { 12782 #if defined(BCM_TRIUMPH2_SUPPORT) 12783 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12784 uint32 counter_indexes=0; 12785 bcm_stat_value_t counter_values={0}; 12786 #endif 12787 12788 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 12789 BCM_IF_ERROR_RETURN 12790 (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos)); 12791 return _bcm_esw_flex_stat_set32(unit, _bcmFlexStatTypeService, vlan, 12792 _bcm_esw_vlan_stat_to_flex_stat(stat), val); 12793 } 12794 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12795 if ((stat == bcmVlanStatIngressPackets) || 12796 (stat == bcmVlanStatEgressPackets)) { 12797 counter_values.packets = val; 12798 } else { 12799 /* Ignoring high value */ 12800 COMPILER_64_SET(counter_values.bytes,0,val); 12801 } 12802 BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify( 12803 unit, vlan, cos)); 12804 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_set( 12805 unit,vlan, stat, 1, &counter_indexes, &counter_values)); 12806 return BCM_E_NONE; 12807 #else 12808 return BCM_E_UNAVAIL; 12809 #endif 12810 #else 12811 return BCM_E_UNAVAIL; 12812 #endif 12813 } 12814 12815 /* 12816 * Function: 12817 * bcm_esw_vlan_stat_multi_get 12818 * Purpose: 12819 * Get 64-bit counter value for multiple VLAN statistic types. 12820 * Parameters: 12821 * unit - (IN) Unit number. 12822 * vlan - (IN) VLAN Id. 12823 * cos - (IN) COS or priority 12824 * nstat - (IN) Number of elements in stat array 12825 * stat_arr - (IN) Collected statistics descriptors array 12826 * value_arr - (OUT) Collected counters values 12827 * Returns: 12828 * BCM_E_XXX 12829 * Notes: 12830 */ 12831 int 12832 bcm_esw_vlan_stat_multi_get(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 12833 int nstat, bcm_vlan_stat_t *stat_arr, 12834 uint64 *value_arr) 12835 { 12836 #if defined(BCM_TRIUMPH2_SUPPORT) 12837 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 12838 int idx; 12839 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12840 uint32 counter_indexes=0; 12841 bcm_stat_value_t counter_values={0}; 12842 #endif 12843 12844 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 12845 BCM_IF_ERROR_RETURN 12846 (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos)); 12847 BCM_IF_ERROR_RETURN 12848 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr, 12849 &_bcm_esw_vlan_stat_to_flex_stat)); 12850 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 12851 12852 return _bcm_esw_flex_stat_multi_get(unit, _bcmFlexStatTypeService, vlan, 12853 nstat, fs_arr, value_arr); 12854 } 12855 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12856 BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify( 12857 unit, vlan, cos)); 12858 for (idx=0;idx < nstat ; idx ++) { 12859 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_get( 12860 unit, vlan, stat_arr[idx], 1, 12861 &counter_indexes, &counter_values)); 12862 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 12863 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 12864 COMPILER_64_SET(value_arr[idx], 12865 COMPILER_64_HI(counter_values.packets64), 12866 COMPILER_64_LO(counter_values.packets64)); 12867 } else { 12868 COMPILER_64_SET(value_arr[idx], 12869 COMPILER_64_HI(counter_values.bytes), 12870 COMPILER_64_LO(counter_values.bytes)); 12871 } 12872 } 12873 return BCM_E_NONE; 12874 #else 12875 return BCM_E_UNAVAIL; 12876 #endif 12877 12878 #else 12879 return BCM_E_UNAVAIL; 12880 #endif 12881 } 12882 12883 /* 12884 * Function: 12885 * bcm_esw_vlan_stat_multi_get32 12886 * Purpose: 12887 * Get lower 32-bit counter value for multiple VLAN statistic 12888 * types. 12889 * Parameters: 12890 * unit - (IN) Unit number. 12891 * vlan - (IN) VLAN Id. 12892 * cos - (IN) COS or priority 12893 * nstat - (IN) Number of elements in stat array 12894 * stat_arr - (IN) Collected statistics descriptors array 12895 * value_arr - (OUT) Collected counters values 12896 * Returns: 12897 * BCM_E_XXX 12898 * Notes: 12899 */ 12900 int 12901 bcm_esw_vlan_stat_multi_get32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 12902 int nstat, bcm_vlan_stat_t *stat_arr, 12903 uint32 *value_arr) 12904 { 12905 #if defined(BCM_TRIUMPH2_SUPPORT) 12906 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 12907 int idx; 12908 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12909 uint32 counter_indexes=0; 12910 bcm_stat_value_t counter_values={0}; 12911 #endif 12912 12913 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 12914 BCM_IF_ERROR_RETURN 12915 (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos)); 12916 BCM_IF_ERROR_RETURN 12917 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr, 12918 &_bcm_esw_vlan_stat_to_flex_stat)); 12919 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 12920 12921 return _bcm_esw_flex_stat_multi_get32(unit, _bcmFlexStatTypeService, vlan, 12922 nstat, fs_arr, value_arr); 12923 } 12924 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12925 BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify( 12926 unit, vlan, cos)); 12927 for (idx=0;idx < nstat ; idx ++) { 12928 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_get( 12929 unit, vlan, stat_arr[idx], 1, 12930 &counter_indexes, &counter_values)); 12931 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 12932 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 12933 value_arr[idx] = counter_values.packets; 12934 } else { 12935 value_arr[idx] = COMPILER_64_LO(counter_values.bytes); 12936 } 12937 } 12938 return BCM_E_NONE; 12939 #else 12940 return BCM_E_UNAVAIL; 12941 #endif 12942 #else 12943 return BCM_E_UNAVAIL; 12944 #endif 12945 } 12946 12947 /* 12948 * Function: 12949 * bcm_esw_vlan_stat_multi_set 12950 * Purpose: 12951 * Set 64-bit counter value for multiple VLAN statistic types. 12952 * Parameters: 12953 * unit - (IN) Unit number. 12954 * vlan - (IN) VLAN Id. 12955 * cos - (IN) COS or priority 12956 * nstat - (IN) Number of elements in stat array 12957 * stat_arr - (IN) New statistics descriptors array 12958 * value_arr - (IN) New counters values 12959 * Returns: 12960 * BCM_E_XXX 12961 * Notes: 12962 */ 12963 int 12964 bcm_esw_vlan_stat_multi_set(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 12965 int nstat, bcm_vlan_stat_t *stat_arr, 12966 uint64 *value_arr) 12967 { 12968 #if defined(BCM_TRIUMPH2_SUPPORT) 12969 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 12970 int idx; 12971 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12972 uint32 counter_indexes=0; 12973 bcm_stat_value_t counter_values={0}; 12974 #endif 12975 12976 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 12977 BCM_IF_ERROR_RETURN 12978 (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos)); 12979 BCM_IF_ERROR_RETURN 12980 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr, 12981 &_bcm_esw_vlan_stat_to_flex_stat)); 12982 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 12983 12984 return _bcm_esw_flex_stat_multi_set(unit, _bcmFlexStatTypeService, vlan, 12985 nstat, fs_arr, value_arr); 12986 } 12987 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 12988 BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify( 12989 unit, vlan, cos)); 12990 for (idx=0;idx < nstat ; idx ++) { 12991 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 12992 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 12993 counter_values.packets = COMPILER_64_LO(value_arr[idx]); 12994 } else { 12995 COMPILER_64_SET(counter_values.bytes, 12996 COMPILER_64_HI(value_arr[idx]), 12997 COMPILER_64_LO(value_arr[idx])); 12998 } 12999 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_set( 13000 unit, vlan, stat_arr[idx], 1, 13001 &counter_indexes, &counter_values)); 13002 } 13003 return BCM_E_NONE; 13004 #else 13005 return BCM_E_UNAVAIL; 13006 #endif 13007 13008 #else 13009 return BCM_E_UNAVAIL; 13010 #endif 13011 } 13012 13013 /* 13014 * Function: 13015 * bcm_esw_vlan_stat_multi_set32 13016 * Purpose: 13017 * Set lower 32-bit counter value for multiple VLAN statistic 13018 * types. 13019 * Parameters: 13020 * unit - (IN) Unit number. 13021 * vlan - (IN) VLAN Id. 13022 * cos - (IN) COS or priority 13023 * nstat - (IN) Number of elements in stat array 13024 * stat_arr - (IN) New statistics descriptors array 13025 * value_arr - (IN) New counters values 13026 * Returns: 13027 * BCM_E_XXX 13028 * Notes: 13029 */ 13030 int 13031 bcm_esw_vlan_stat_multi_set32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 13032 int nstat, bcm_vlan_stat_t *stat_arr, 13033 uint32 *value_arr) 13034 { 13035 #if defined(BCM_TRIUMPH2_SUPPORT) 13036 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 13037 int idx; 13038 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13039 uint32 counter_indexes=0; 13040 bcm_stat_value_t counter_values={0}; 13041 #endif 13042 13043 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 13044 BCM_IF_ERROR_RETURN 13045 (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos)); 13046 BCM_IF_ERROR_RETURN 13047 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr, 13048 &_bcm_esw_vlan_stat_to_flex_stat)); 13049 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 13050 13051 return _bcm_esw_flex_stat_multi_set32(unit, _bcmFlexStatTypeService, 13052 vlan, nstat, fs_arr, value_arr); 13053 } 13054 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13055 BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify( 13056 unit, vlan, cos)); 13057 for (idx=0;idx < nstat ; idx ++) { 13058 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 13059 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 13060 counter_values.packets = value_arr[idx]; 13061 } else { 13062 COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]); 13063 } 13064 BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_set( 13065 unit, vlan, stat_arr[idx], 1, 13066 &counter_indexes, &counter_values)); 13067 } 13068 return BCM_E_NONE; 13069 #else 13070 return BCM_E_UNAVAIL; 13071 #endif 13072 13073 #else 13074 return BCM_E_UNAVAIL; 13075 #endif 13076 } 13077 13078 #if defined(BCM_TRIUMPH2_SUPPORT) 13079 STATIC int 13080 _bcm_esw_vlan_translate_flex_stat_hw_index_set(int unit, 13081 _bcm_flex_stat_handle_t handle, 13082 int fs_idx, void *cookie) 13083 { 13084 vlan_xlate_entry_t vent, res_vent; 13085 int rv, idx; 13086 soc_mem_t mem = VLAN_XLATEm; 13087 13088 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 13089 mem = VLAN_XLATE_1_DOUBLEm; 13090 } 13091 _BCM_FLEX_STAT_HANDLE_COPY(vent, handle); 13092 13093 soc_mem_lock(unit, mem); 13094 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, 13095 &vent, &res_vent, 0); 13096 if (BCM_SUCCESS(rv)) { 13097 soc_mem_field32_set(unit, mem, &res_vent, 13098 VINTF_CTR_IDXf, fs_idx); 13099 if (SOC_MEM_FIELD_VALID(unit, mem, USE_VINTF_CTR_IDXf)) { 13100 soc_mem_field32_set(unit, mem, &res_vent, 13101 USE_VINTF_CTR_IDXf, fs_idx > 0 ? 1 : 0); 13102 } 13103 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, &res_vent); 13104 if (BCM_SUCCESS(rv)) { 13105 /* We found it already, but didn't overwrite it? The mem lock 13106 * must have failed. Not good. */ 13107 return BCM_E_INTERNAL; 13108 } else if (BCM_E_EXISTS == rv) { 13109 rv = BCM_E_NONE; 13110 } /* Else retain failing rv value */ 13111 } 13112 soc_mem_unlock(unit, mem); 13113 return rv; 13114 } 13115 13116 STATIC _bcm_flex_stat_t 13117 _bcm_esw_vlan_translate_stat_to_flex_stat(bcm_vlan_stat_t stat) 13118 { 13119 _bcm_flex_stat_t flex_stat; 13120 13121 switch (stat) { 13122 case bcmVlanStatIngressPackets: 13123 flex_stat = _bcmFlexStatIngressPackets; 13124 break; 13125 case bcmVlanStatIngressBytes: 13126 flex_stat = _bcmFlexStatIngressBytes; 13127 break; 13128 /* No egress stats for ingress translations */ 13129 default: 13130 flex_stat = _bcmFlexStatNum; 13131 } 13132 13133 return flex_stat; 13134 } 13135 13136 STATIC int 13137 _bcm_esw_vlan_translate_stat_param_valid(int unit, bcm_gport_t port, 13138 bcm_vlan_translate_key_t key_type, 13139 bcm_vlan_t outer_vlan, 13140 bcm_vlan_t inner_vlan, 13141 _bcm_flex_stat_handle_t *vxlt_fsh) 13142 { 13143 vlan_xlate_entry_t vent; 13144 13145 CHECK_INIT(unit); 13146 13147 if (!soc_feature(unit, soc_feature_gport_service_counters)) { 13148 return BCM_E_UNAVAIL; 13149 } 13150 13151 sal_memset(&vent, 0, sizeof(vlan_xlate_entry_t)); 13152 BCM_IF_ERROR_RETURN 13153 (_bcm_trx_vlan_translate_entry_assemble(unit, &vent, 13154 port, key_type, 13155 inner_vlan, outer_vlan)); 13156 13157 /* Fill handle for VTS info */ 13158 _BCM_FLEX_STAT_HANDLE_CLEAR(*vxlt_fsh); 13159 /* This next step is a bit abusive, but we don't have an accessor 13160 * which captures the full key description in the VLAN_XLATE table. */ 13161 _BCM_FLEX_STAT_HANDLE_COPY(*vxlt_fsh, vent); 13162 13163 return BCM_E_NONE; 13164 } 13165 13166 #endif /* BCM_TRIUMPH2_SUPPORT */ 13167 13168 /* 13169 * Function: 13170 * bcm_esw_vlan_translate_stat_enable_set 13171 * Purpose: 13172 * Enable/disable collection of statistics on the indicated 13173 * ingress VLAN translation. 13174 * Parameters: 13175 * unit - (IN) Unit number. 13176 * port - (IN) Generic port 13177 * key_type - (IN) Key Type : bcmVlanTranslateKey* 13178 * outer_vlan - (IN) Packet outer VLAN ID 13179 * inner_vlan - (IN) Packet inner VLAN ID 13180 * enable - (IN) Non-zero to enable counter collection, zero to disable. 13181 * Returns: 13182 * BCM_E_xxx 13183 * Notes: 13184 */ 13185 int 13186 bcm_esw_vlan_translate_stat_enable_set(int unit, bcm_gport_t port, 13187 bcm_vlan_translate_key_t key_type, 13188 bcm_vlan_t outer_vlan, 13189 bcm_vlan_t inner_vlan, 13190 int enable) 13191 { 13192 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT) 13193 _bcm_flex_stat_handle_t vxlt_fsh; 13194 #endif 13195 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13196 uint32 num_of_tables=0; 13197 uint32 num_stat_counter_ids=0; 13198 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 13199 bcm_stat_object_t object=bcmStatObjectIngPort; 13200 uint32 stat_counter_id[ 13201 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0}; 13202 uint32 num_entries=0; 13203 int index=0; 13204 #endif 13205 13206 #ifdef BCM_TOMAHAWK3_SUPPORT 13207 if (SOC_IS_TOMAHAWK3(unit)) { 13208 return BCM_E_UNAVAIL; 13209 } 13210 #endif 13211 13212 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13213 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 13214 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info( 13215 unit,port,key_type, 13216 outer_vlan,inner_vlan, 13217 &num_of_tables,&table_info[0])); 13218 if (enable ) { 13219 for(index=0;index < num_of_tables ;index++) { 13220 if(table_info[index].direction == bcmStatFlexDirectionIngress) { 13221 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object( 13222 unit,table_info[index].table, 13223 table_info[index].index,NULL,&object)); 13224 } else { 13225 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object( 13226 unit,table_info[index].table, 13227 table_info[index].index,NULL,&object)); 13228 } 13229 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create( 13230 unit,object,bcmStatGroupModeSingle, 13231 &stat_counter_id[table_info[index].direction], 13232 &num_entries)); 13233 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_attach( 13234 unit,port,key_type,outer_vlan,inner_vlan, 13235 stat_counter_id[table_info[index].direction])); 13236 } 13237 return BCM_E_NONE; 13238 } else { 13239 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id( 13240 unit, num_of_tables,&table_info[0], 13241 &num_stat_counter_ids,&stat_counter_id[0])); 13242 if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) && 13243 (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) { 13244 return BCM_E_PARAM; 13245 } 13246 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_detach( 13247 unit,port,key_type,outer_vlan,inner_vlan)); 13248 if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) { 13249 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 13250 unit, 13251 stat_counter_id[bcmStatFlexDirectionIngress])); 13252 } 13253 if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) { 13254 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 13255 unit, 13256 stat_counter_id[bcmStatFlexDirectionEgress])); 13257 } 13258 return BCM_E_NONE; 13259 } 13260 } else 13261 #endif 13262 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 13263 if (soc_feature(unit,soc_feature_gport_service_counters)) { 13264 BCM_IF_ERROR_RETURN 13265 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 13266 outer_vlan, inner_vlan, 13267 &vxlt_fsh)); 13268 13269 return _bcm_esw_flex_stat_ext_enable_set(unit, _bcmFlexStatTypeVxlt, 13270 _bcm_esw_vlan_translate_flex_stat_hw_index_set, 13271 NULL, vxlt_fsh, enable,0); 13272 } else 13273 #endif 13274 #if defined(BCM_HURRICANE3_SUPPORT) 13275 if (soc_feature(unit, soc_feature_flowcnt)) { 13276 return _bcm_hr3_vlan_translate_stat_enable_set(unit, port, key_type, 13277 outer_vlan, inner_vlan, enable); 13278 13279 } else 13280 #endif 13281 { 13282 return BCM_E_UNAVAIL; 13283 } 13284 } 13285 13286 #if defined(BCM_TRIUMPH3_SUPPORT) 13287 static 13288 bcm_error_t _bcm_esw_vlan_translate_convert_common_fields( 13289 int unit, 13290 soc_mem_t from_table, 13291 soc_mem_t to_table, 13292 soc_field_t view_field, 13293 char *view_name, 13294 void *from_entry, 13295 void *to_entry) 13296 { 13297 soc_mem_info_t *memp_from; 13298 uint32 key_type=0; 13299 int f=0; 13300 #if !defined(SOC_NO_NAMES) 13301 soc_mem_info_t *memp_to; 13302 uint32 fval[SOC_MAX_MEM_FIELD_WORDS]; 13303 soc_field_info_t *fieldp_to; 13304 soc_field_info_t *fieldp_from; 13305 #endif /* !SOC_NO_NAMES */ 13306 13307 char view_name_with_colon[64]; 13308 13309 /* sal_memset(to_entry, 0, sizeof(vlan_xlate_extd_entry_t)); */ 13310 memp_from = &SOC_MEM_INFO(unit, from_table); 13311 key_type= soc_mem_field32_get(unit, from_table, 13312 (uint32 *)from_entry , view_field); 13313 if (sal_strcmp(memp_from->views[key_type],view_name) != 0) { 13314 return BCM_E_PARAM; 13315 } 13316 sal_memset(to_entry, 0, soc_mem_entry_bytes(unit,to_table)); 13317 sal_sprintf(view_name_with_colon,"%s:",view_name); 13318 for (f = memp_from->nFields - 1; f >= 0; f--) { 13319 #if !defined(SOC_NO_NAMES) 13320 memp_to = &SOC_MEM_INFO(unit, to_table); 13321 fieldp_from = &memp_from->fields[f]; 13322 /* LOG_CLI((BSL_META_U(unit, 13323 ":%d:%s: ==>"), f,soc_fieldnames[fieldp_from->field])); */ 13324 if ((strstr(soc_fieldnames[fieldp_from->field], 13325 view_name_with_colon) != NULL) || 13326 (strstr(soc_fieldnames[fieldp_from->field], ":") == NULL)) { 13327 if (soc_mem_field_valid(unit, 13328 to_table,fieldp_from->field)) { 13329 SOC_FIND_FIELD(fieldp_from->field, 13330 memp_to->fields, 13331 memp_to->nFields, 13332 fieldp_to); 13333 if (fieldp_to->len < fieldp_from->len) { 13334 LOG_CLI((BSL_META_U(unit, 13335 "Warning:%d:%s: Mismatch in length %d:%d ==>"), 13336 f,soc_fieldnames[fieldp_from->field], 13337 fieldp_from->len,fieldp_to->len)); 13338 } else if (fieldp_to->len > fieldp_from->len) { 13339 sal_memset(fval,0,((fieldp_to->len-1) >> 5)+1); 13340 LOG_CLI((BSL_META_U(unit, 13341 "Warning:%d:%s: More lengthy field %d:%d==>"), 13342 f,soc_fieldnames[fieldp_from->field], 13343 fieldp_from->len,fieldp_to->len)); 13344 } 13345 soc_mem_field_get(unit, from_table, 13346 (uint32 *)from_entry , 13347 fieldp_from->field,fval); 13348 soc_mem_field_set(unit,to_table, 13349 (uint32 *)to_entry , 13350 fieldp_from->field, fval); 13351 /* LOG_CLI((BSL_META_U(unit, 13352 "Matched \n"))); */ 13353 } else { 13354 /* LOG_CLI((BSL_META_U(unit, 13355 "Not Matched \n"))); */ 13356 } 13357 } else { 13358 /* LOG_CLI((BSL_META_U(unit, 13359 "Skipped \n"))); */ 13360 } 13361 #endif /* !SOC_NO_NAMES */ 13362 } 13363 return BCM_E_NONE; 13364 } 13365 static 13366 bcm_error_t _bcm_esw_vlan_translate_convert_to_extd_entry( 13367 int unit, 13368 vlan_xlate_entry_t *vlan_xlate_entry, 13369 vlan_xlate_extd_entry_t *vlan_xlate_extd_entry) 13370 { 13371 uint32 key_type=0; 13372 uint32 fval[SOC_MAX_MEM_FIELD_WORDS]; 13373 uint32 new_key_type=0; 13374 13375 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_convert_common_fields( 13376 unit, 13377 VLAN_XLATEm, VLAN_XLATE_EXTDm,KEY_TYPEf,"XLATE", 13378 (void *)vlan_xlate_entry, 13379 (void *)vlan_xlate_extd_entry)); 13380 13381 /* Take care about special fields */ 13382 soc_mem_field_get(unit, VLAN_XLATEm, 13383 (uint32 *)vlan_xlate_entry , VALIDf,fval); 13384 soc_mem_field_set(unit, VLAN_XLATE_EXTDm, 13385 (uint32 *)vlan_xlate_extd_entry, VALID_0f, fval); 13386 soc_mem_field_set(unit, VLAN_XLATE_EXTDm, 13387 (uint32 *)vlan_xlate_extd_entry, VALID_1f, fval); 13388 fval[0] = 0; 13389 fval[1] = 0; 13390 soc_mem_field_get(unit,VLAN_XLATEm,(uint32 *)vlan_xlate_entry,KEYf,fval); 13391 soc_mem_field_set(unit,VLAN_XLATE_EXTDm,(uint32 *)vlan_xlate_extd_entry, 13392 XLATE__KEY_0f, fval); /* Default KEY_0f */ 13393 13394 soc_mem_field_get(unit, VLAN_XLATEm, (uint32 *)vlan_xlate_entry , 13395 KEY_TYPEf,&key_type); 13396 new_key_type=key_type+1; 13397 soc_mem_field_set(unit,VLAN_XLATE_EXTDm,(uint32 *)vlan_xlate_extd_entry, 13398 KEY_TYPE_0f, &new_key_type); 13399 soc_mem_field_set(unit,VLAN_XLATE_EXTDm,(uint32 *)vlan_xlate_extd_entry, 13400 KEY_TYPE_1f, &new_key_type); 13401 13402 fval[0] = 0; 13403 fval[1] = 0; 13404 soc_mem_field_get(unit, VLAN_XLATEm,(uint32 *)vlan_xlate_entry, DATAf,fval); 13405 soc_mem_field_set(unit, VLAN_XLATE_EXTDm, 13406 (uint32 *)vlan_xlate_extd_entry, XLATE__DATA_0f, fval); 13407 return BCM_E_NONE; 13408 } 13409 static 13410 bcm_error_t _bcm_esw_vlan_translate_convert_to_regular_entry( 13411 int unit, 13412 vlan_xlate_extd_entry_t *vlan_xlate_extd_entry, 13413 vlan_xlate_entry_t *vlan_xlate_entry) 13414 { 13415 uint32 key_type=0; 13416 uint32 fval[SOC_MAX_MEM_FIELD_WORDS]; 13417 uint32 new_key_type=0; 13418 13419 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_convert_common_fields( 13420 unit, 13421 VLAN_XLATE_EXTDm, VLAN_XLATEm,KEY_TYPE_0f,"XLATE", 13422 (void *)vlan_xlate_extd_entry, 13423 (void *)vlan_xlate_entry)); 13424 /* Take care about special fields */ 13425 13426 fval[0] = 0; 13427 fval[1] = 0; 13428 soc_mem_field_get(unit, VLAN_XLATE_EXTDm, 13429 (uint32 *)vlan_xlate_extd_entry , VALID_0f,fval); 13430 soc_mem_field_set(unit, VLAN_XLATEm,(uint32 *)vlan_xlate_entry, 13431 VALIDf, fval); 13432 13433 fval[0] = 0; 13434 fval[1] = 0; 13435 soc_mem_field_get(unit, VLAN_XLATE_EXTDm, 13436 (uint32 *)vlan_xlate_extd_entry , XLATE__KEY_0f,fval); 13437 soc_mem_field_set(unit, VLAN_XLATEm,(uint32 *)vlan_xlate_entry, 13438 KEYf, fval); 13439 13440 soc_mem_field_get(unit,VLAN_XLATE_EXTDm, (uint32 *)vlan_xlate_extd_entry, 13441 KEY_TYPE_0f, &key_type); 13442 new_key_type = key_type - 1; 13443 soc_mem_field_set(unit, VLAN_XLATEm, (uint32 *)vlan_xlate_entry , 13444 KEY_TYPEf, &new_key_type); 13445 13446 fval[0] = 0; 13447 fval[1] = 0; 13448 soc_mem_field_get(unit, VLAN_XLATE_EXTDm, (uint32 *)vlan_xlate_extd_entry, 13449 XLATE__DATA_0f,fval); 13450 fval[1] &= 0x3f; 13451 soc_mem_field_set(unit, VLAN_XLATEm, (uint32 *)vlan_xlate_entry, DATAf,fval); 13452 13453 return BCM_E_NONE; 13454 } 13455 #endif 13456 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13457 /* 13458 * Function: 13459 * _bcm_esw_vlan_translate_stat_get_table_info 13460 * Description: 13461 * Provides relevant flex table information(table-name,index with 13462 * direction) for given ingress vlan translation 13463 * 13464 * Parameters: 13465 * unit - (IN) unit number 13466 * port - (IN) Generic port 13467 * key_type - (IN) Key Type : bcmVlanTranslateKey* 13468 * outer_vlan - (IN) Packet outer VLAN ID 13469 * inner_vlan - (IN) Packet inner VLAN ID 13470 * num_of_tables - (OUT) Number of flex counter tables 13471 * table_info - (OUT) Flex counter tables information 13472 * 13473 * Return Value: 13474 * BCM_E_XXX 13475 * Notes: 13476 */ 13477 static bcm_error_t _bcm_esw_vlan_translate_stat_get_table_info( 13478 int unit, 13479 bcm_gport_t port, 13480 bcm_vlan_translate_key_t key_type, 13481 bcm_vlan_t outer_vlan, 13482 bcm_vlan_t inner_vlan, 13483 uint32 *num_of_tables, 13484 bcm_stat_flex_table_info_t *table_info) 13485 { 13486 bcm_error_t rv=BCM_E_NONE; 13487 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 13488 uint32 vlan_xlate_entry[SOC_MAX_MEM_FIELD_WORDS]; 13489 13490 int index=0; 13491 #if defined(BCM_TRIUMPH3_SUPPORT) 13492 vlan_xlate_extd_entry_t vlan_xlate_extd_entry={{0}}; 13493 #endif 13494 soc_mem_t mem = VLAN_XLATEm; 13495 13496 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 13497 mem = VLAN_XLATE_1_DOUBLEm; 13498 } 13499 13500 (*num_of_tables) = 0; 13501 13502 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 13503 return BCM_E_UNAVAIL; 13504 } 13505 sal_memset(vent, 0, sizeof(vent)); 13506 sal_memset(vlan_xlate_entry, 0, sizeof(vlan_xlate_entry)); 13507 BCM_IF_ERROR_RETURN (_bcm_trx_vlan_translate_entry_assemble( 13508 unit, vent, port, key_type, inner_vlan,outer_vlan)); 13509 soc_mem_lock(unit, mem); 13510 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL,&index,vent, 13511 vlan_xlate_entry,0); 13512 soc_mem_unlock(unit, mem); 13513 if (SOC_IS_KATANAX(unit)) { 13514 if (BCM_SUCCESS(rv)) { 13515 table_info[*num_of_tables].table=mem; 13516 table_info[*num_of_tables].index=index; 13517 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 13518 (*num_of_tables)++; 13519 } 13520 #if defined(BCM_TRIUMPH3_SUPPORT) 13521 } else if SOC_IS_TD2_TT2(unit) { 13522 if (BCM_SUCCESS(rv)) { 13523 table_info[*num_of_tables].table=mem; 13524 table_info[*num_of_tables].index=index; 13525 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 13526 (*num_of_tables)++; 13527 } 13528 } else if SOC_IS_TRIUMPH3(unit) { 13529 if (BCM_SUCCESS(rv)) { 13530 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_convert_to_extd_entry( 13531 unit, (void *)vlan_xlate_entry, 13532 &vlan_xlate_extd_entry)); 13533 BCM_IF_ERROR_RETURN(soc_mem_delete( 13534 unit, VLAN_XLATEm, MEM_BLOCK_ANY, 13535 (void *)vlan_xlate_entry)); 13536 BCM_IF_ERROR_RETURN(soc_mem_insert( 13537 unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 13538 (void *)&vlan_xlate_extd_entry)); 13539 } else { 13540 /* Possibly entry has already been moved to VLAN_XLATE_EXTD table */ 13541 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_convert_to_extd_entry( 13542 unit, (void *)vent, &vlan_xlate_extd_entry)); 13543 } 13544 BCM_IF_ERROR_RETURN(soc_mem_search(unit, VLAN_XLATE_EXTDm, 13545 MEM_BLOCK_ALL,&index, 13546 (void *)&vlan_xlate_extd_entry, 13547 (void *)&vlan_xlate_extd_entry,0)); 13548 table_info[*num_of_tables].table=VLAN_XLATE_EXTDm; 13549 table_info[*num_of_tables].index=index; 13550 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 13551 (*num_of_tables)++; 13552 return BCM_E_NONE; 13553 #endif 13554 } 13555 return rv; 13556 } 13557 #endif 13558 13559 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13560 /* 13561 * Function: 13562 * _bcm_esw_vlan_translate_stat_attach 13563 * Description: 13564 * attach counters entries for the given ingress vlan translation table. 13565 * 13566 * Parameters: 13567 * unit - (IN) unit number 13568 * Port - (IN) GPORT (global port) identifier 13569 * key_type - (IN) VLAN translation key type 13570 * outer_vlan - (IN) Outer VLAN ID or tag 13571 * inner_vlan - (IN) Inner VLAN ID or tag 13572 * Stat_counter_id - (IN) Stat Counter ID. 13573 * 13574 * Return Value: 13575 * BCM_E_XXX 13576 * Notes: 13577 */ 13578 STATIC bcm_error_t _bcm_esw_vlan_translate_stat_attach( 13579 int unit, 13580 bcm_gport_t port, 13581 bcm_vlan_translate_key_t key_type, 13582 bcm_vlan_t outer_vlan, 13583 bcm_vlan_t inner_vlan, 13584 uint32 stat_counter_id) 13585 { 13586 soc_mem_t table=0; 13587 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 13588 uint32 pool_number=0; 13589 uint32 base_index=0; 13590 bcm_stat_flex_mode_t offset_mode=0; 13591 bcm_stat_object_t object=bcmStatObjectIngPort; 13592 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 13593 uint32 count=0; 13594 uint32 actual_num_tables=0; 13595 uint32 num_of_tables=0; 13596 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 13597 13598 _bcm_esw_stat_get_counter_id_info( 13599 unit, stat_counter_id, 13600 &group_mode,&object,&offset_mode,&pool_number,&base_index); 13601 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction)); 13602 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode)); 13603 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 13604 unit,object,1,&actual_num_tables,&table,&direction)); 13605 /* When key_type is bcmVlanTranslateKeyPortOuter, 13606 outer_vlan should be old vlan_id.Inner Vlan value is discarded */ 13607 /* When key_type is bcmVlanTranslateKeyPortInn, 13608 inner_vlan should be old vlan_id.Outer vlan value is discarded */ 13609 /* 13610 if (key_type == bcmVlanTranslateKeyPortOuter) { 13611 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info( 13612 unit, port,key_type,inner_vlan,0, 13613 &num_of_tables,&table_info[0])); 13614 } else if(key_type == bcmVlanTranslateKeyPortInner) { 13615 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info( 13616 unit, port,key_type,0,inner_vlan, 13617 &num_of_tables,&table_info[0])); 13618 } else { 13619 return BCM_E_PARAM; 13620 } 13621 */ 13622 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info( 13623 unit, port,key_type,outer_vlan,inner_vlan, 13624 &num_of_tables,&table_info[0])); 13625 for (count=0; count < num_of_tables ; count++) { 13626 if ((table_info[count].direction == direction) && 13627 (table_info[count].table == table) ) { 13628 if (direction == bcmStatFlexDirectionIngress) { 13629 return _bcm_esw_stat_flex_attach_ingress_table_counters( 13630 unit, table_info[count].table, table_info[count].index, 13631 offset_mode, base_index, pool_number); 13632 } else { 13633 return _bcm_esw_stat_flex_attach_egress_table_counters( 13634 unit, table_info[count].table, table_info[count].index, 13635 0, offset_mode, base_index, pool_number); 13636 } 13637 } 13638 } 13639 return BCM_E_NOT_FOUND; 13640 } 13641 #endif 13642 13643 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 13644 /* 13645 * Function: 13646 * _tr2_vlan_translate_stat_attach 13647 * Description: 13648 * attach counters entries for the given ingress vlan translation table. 13649 * 13650 * Parameters: 13651 * unit - (IN) unit number 13652 * Port - (IN) GPORT (global port) identifier 13653 * key_type - (IN) VLAN translation key type 13654 * outer_vlan - (IN) Outer VLAN ID or tag 13655 * inner_vlan - (IN) Inner VLAN ID or tag 13656 * Stat_counter_id - (IN) Stat Counter ID. 13657 * 13658 * Return Value: 13659 * BCM_E_XXX 13660 * Notes: 13661 */ 13662 STATIC bcm_error_t _tr2_vlan_translate_stat_attach( 13663 int unit, 13664 bcm_gport_t port, 13665 bcm_vlan_translate_key_t key_type, 13666 bcm_vlan_t outer_vlan, 13667 bcm_vlan_t inner_vlan, 13668 uint32 stat_counter_id, 13669 int attached) 13670 { 13671 13672 _bcm_flex_stat_type_t fs_type; 13673 uint32 fs_inx; 13674 _bcm_flex_stat_handle_t vxlt_fsh; 13675 13676 fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id); 13677 fs_inx = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id); 13678 13679 if (!((fs_type == _bcmFlexStatTypeVxlt) && fs_inx)) { 13680 return BCM_E_PARAM; 13681 } 13682 BCM_IF_ERROR_RETURN 13683 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 13684 outer_vlan, inner_vlan, 13685 &vxlt_fsh)); 13686 13687 return _bcm_esw_flex_stat_ext_enable_set(unit, fs_type, 13688 _bcm_esw_vlan_translate_flex_stat_hw_index_set, 13689 INT_TO_PTR(_BCM_FLEX_STAT_HW_INGRESS), 13690 vxlt_fsh, attached, 13691 fs_inx); 13692 } 13693 #endif 13694 13695 /* 13696 * Function: 13697 * bcm_esw_vlan_translate_stat_attach 13698 * Description: 13699 * attach counters entries for the given ingress vlan translation table. 13700 * 13701 * Parameters: 13702 * unit - (IN) unit number 13703 * Port - (IN) GPORT (global port) identifier 13704 * key_type - (IN) VLAN translation key type 13705 * outer_vlan - (IN) Outer VLAN ID or tag 13706 * inner_vlan - (IN) Inner VLAN ID or tag 13707 * Stat_counter_id - (IN) Stat Counter ID. 13708 * 13709 * Return Value: 13710 * BCM_E_XXX 13711 * Notes: 13712 */ 13713 int bcm_esw_vlan_translate_stat_attach( 13714 int unit, 13715 bcm_gport_t port, 13716 bcm_vlan_translate_key_t key_type, 13717 bcm_vlan_t outer_vlan, 13718 bcm_vlan_t inner_vlan, 13719 uint32 stat_counter_id) 13720 { 13721 #ifdef BCM_TOMAHAWK3_SUPPORT 13722 if (SOC_IS_TOMAHAWK3(unit)) { 13723 return BCM_E_UNAVAIL; 13724 } 13725 #endif 13726 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13727 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 13728 return _bcm_esw_vlan_translate_stat_attach(unit,port, 13729 key_type,outer_vlan,inner_vlan,stat_counter_id); 13730 } else 13731 #endif 13732 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 13733 if (soc_feature(unit,soc_feature_gport_service_counters)) { 13734 return _tr2_vlan_translate_stat_attach(unit,port,key_type, 13735 outer_vlan,inner_vlan,stat_counter_id,TRUE); 13736 } else 13737 #endif 13738 #if defined(BCM_HURRICANE3_SUPPORT) 13739 if (soc_feature(unit, soc_feature_flowcnt)) { 13740 return _bcm_hr3_vlan_translate_stat_attach(unit,port,key_type, 13741 outer_vlan,inner_vlan,stat_counter_id); 13742 } else 13743 #endif 13744 { 13745 return BCM_E_UNAVAIL; 13746 } 13747 13748 } 13749 13750 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13751 /* 13752 * Function: 13753 * _bcm_esw_vlan_translate_stat_detach 13754 * Description: 13755 * Detach counters entries for the given ingress vlan translation table. 13756 * 13757 * Parameters: 13758 * unit - (IN) unit number 13759 * Port - (IN) GPORT (global port) identifier 13760 * key_type - (IN) VLAN translation key type 13761 * outer_vlan - (IN) Outer VLAN ID or tag 13762 * inner_vlan - (IN) Inner VLAN ID or tag 13763 * 13764 * Return Value: 13765 * BCM_E_XXX 13766 * Notes: 13767 */ 13768 STATIC bcm_error_t _bcm_esw_vlan_translate_stat_detach( 13769 int unit, 13770 bcm_gport_t port, 13771 bcm_vlan_translate_key_t key_type, 13772 bcm_vlan_t outer_vlan, 13773 bcm_vlan_t inner_vlan) 13774 { 13775 uint32 count=0; 13776 uint32 num_of_tables=0; 13777 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 13778 bcm_error_t rv = BCM_E_NONE; 13779 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 13780 #if defined(BCM_TRIUMPH3_SUPPORT) 13781 vlan_xlate_entry_t vlan_xlate_entry={{0}}; 13782 vlan_xlate_extd_entry_t vlan_xlate_extd_entry={{0}}; 13783 #endif 13784 13785 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info( 13786 unit, port,key_type,outer_vlan,inner_vlan, 13787 &num_of_tables,&table_info[0])); 13788 13789 for (count=0; count < num_of_tables ; count++) { 13790 if (table_info[count].direction == bcmStatFlexDirectionIngress) { 13791 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 13792 unit, table_info[count].table,table_info[count].index); 13793 #if defined(BCM_TRIUMPH3_SUPPORT) 13794 if (SOC_IS_TRIUMPH3(unit)) { 13795 BCM_IF_ERROR_RETURN(soc_mem_read( 13796 unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ANY, 13797 table_info[count].index, 13798 (void *)&vlan_xlate_extd_entry)); 13799 if (soc_mem_field32_get(unit,VLAN_XLATE_EXTDm, 13800 (uint32 *)&vlan_xlate_extd_entry, 13801 XLATE__SVC_METER_INDEXf) == 0) { 13802 BCM_IF_ERROR_RETURN( 13803 _bcm_esw_vlan_translate_convert_to_regular_entry( 13804 unit,&vlan_xlate_extd_entry,&vlan_xlate_entry)); 13805 BCM_IF_ERROR_RETURN(soc_mem_delete( 13806 unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ANY, 13807 (void *)&vlan_xlate_extd_entry)); 13808 BCM_IF_ERROR_RETURN(soc_mem_insert( 13809 unit, VLAN_XLATEm, MEM_BLOCK_ALL, 13810 (void *)&vlan_xlate_entry)); 13811 } 13812 } 13813 #endif 13814 if (BCM_E_NONE != rv && 13815 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 13816 err_code[bcmStatFlexDirectionIngress] = rv; 13817 } 13818 } else { 13819 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 13820 unit, 0, table_info[count].table,table_info[count].index); 13821 if (BCM_E_NONE != rv && 13822 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 13823 err_code[bcmStatFlexDirectionEgress] = rv; 13824 } 13825 } 13826 } 13827 13828 BCM_STAT_FLEX_DETACH_RETURN(err_code) 13829 } 13830 #endif 13831 13832 /* 13833 * Function: 13834 * bcm_esw_vlan_translate_stat_detach 13835 * Description: 13836 * Detach counters entries for the given ingress vlan translation table. 13837 * 13838 * Parameters: 13839 * unit - (IN) unit number 13840 * Port - (IN) GPORT (global port) identifier 13841 * key_type - (IN) VLAN translation key type 13842 * outer_vlan - (IN) Outer VLAN ID or tag 13843 * inner_vlan - (IN) Inner VLAN ID or tag 13844 * 13845 * Return Value: 13846 * BCM_E_XXX 13847 * Notes: 13848 */ 13849 int bcm_esw_vlan_translate_stat_detach( 13850 int unit, 13851 bcm_gport_t port, 13852 bcm_vlan_translate_key_t key_type, 13853 bcm_vlan_t outer_vlan, 13854 bcm_vlan_t inner_vlan) 13855 { 13856 #ifdef BCM_TOMAHAWK3_SUPPORT 13857 if (SOC_IS_TOMAHAWK3(unit)) { 13858 return BCM_E_UNAVAIL; 13859 } 13860 #endif 13861 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13862 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 13863 return _bcm_esw_vlan_translate_stat_detach(unit,port, 13864 key_type,outer_vlan,inner_vlan); 13865 } else 13866 #endif 13867 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 13868 if (soc_feature(unit,soc_feature_gport_service_counters)) { 13869 return _tr2_vlan_translate_stat_attach(unit,port,key_type, 13870 outer_vlan,inner_vlan, 13871 _BCM_FLEX_STAT_COUNT_ID(_bcmFlexStatTypeVxlt,1),FALSE); 13872 } else 13873 #endif 13874 #if defined(BCM_HURRICANE3_SUPPORT) 13875 if (soc_feature(unit, soc_feature_flowcnt)) { 13876 return _bcm_hr3_vlan_translate_stat_detach(unit,port,key_type, 13877 outer_vlan,inner_vlan); 13878 } else 13879 #endif 13880 { 13881 return BCM_E_UNAVAIL; 13882 } 13883 } 13884 13885 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13886 /* 13887 * Function: 13888 * _bcm_esw_vlan_translate_stat_counter_get 13889 * Description: 13890 * Get counter values from ingress vlan translation table 13891 * if sync_mode is set, sync the sw accumulated count 13892 * with hw count value first, else return sw count. 13893 * 13894 * Parameters: 13895 * unit - (IN) unit number 13896 * sync_mode - (IN) hwcount is to be synced to sw count 13897 * Port - (IN) GPORT (global port) identifier 13898 * key_type - (IN) VLAN translation key type 13899 * outer_vlan - (IN) Outer VLAN ID or tag 13900 * inner_vlan - (IN) Inner VLAN ID or tag 13901 * stat - (IN) Type of the counter to retrieve 13902 * I.e. ingress/egress byte/packet) 13903 * num_entries - (IN) Number of counter Entries 13904 * counter_indexes - (IN) Pointer to Counter indexes entries 13905 * counter_values - (OUT) Pointer to counter values 13906 * 13907 * Return Value: 13908 * BCM_E_XXX 13909 * Notes: 13910 */ 13911 STATIC bcm_error_t _bcm_esw_vlan_translate_stat_counter_get( 13912 int unit, 13913 int sync_mode, 13914 bcm_gport_t port, 13915 bcm_vlan_translate_key_t key_type, 13916 bcm_vlan_t outer_vlan, 13917 bcm_vlan_t inner_vlan, 13918 bcm_vlan_stat_t stat, 13919 uint32 num_entries, 13920 uint32 *counter_indexes, 13921 bcm_stat_value_t *counter_values) 13922 { 13923 uint32 table_count=0; 13924 uint32 index_count=0; 13925 uint32 num_of_tables=0; 13926 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 13927 uint32 byte_flag=0; 13928 bcm_stat_flex_table_info_t table_info[ 13929 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 13930 13931 if ((stat == bcmVlanStatIngressPackets) || 13932 (stat == bcmVlanStatIngressBytes)) { 13933 direction = bcmStatFlexDirectionIngress; 13934 } else { 13935 direction = bcmStatFlexDirectionEgress; 13936 } 13937 if ((stat == bcmVlanStatIngressPackets) || 13938 (stat == bcmVlanStatEgressPackets)) { 13939 byte_flag=0; 13940 } else { 13941 byte_flag=1; 13942 } 13943 13944 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info( 13945 unit, port,key_type,outer_vlan,inner_vlan, 13946 &num_of_tables,&table_info[0])); 13947 13948 for (table_count=0; table_count < num_of_tables ; table_count++) { 13949 if (table_info[table_count].direction == direction) { 13950 for (index_count=0; index_count < num_entries ; index_count++) { 13951 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get( 13952 unit, sync_mode, 13953 table_info[table_count].index, 13954 table_info[table_count].table, 0, 13955 byte_flag, 13956 counter_indexes[index_count], 13957 &counter_values[index_count])); 13958 } 13959 } 13960 } 13961 return BCM_E_NONE; 13962 } 13963 #endif 13964 13965 /* 13966 * Function: 13967 * _bcm_esw_vlan_xslate_stat_counter_get 13968 * Description: 13969 * Get counter values from ingress vlan translation table 13970 * if sync_mode is set, sync the sw accumulated count 13971 * with hw count value first, else return sw count. 13972 * 13973 * Parameters: 13974 * unit - (IN) unit number 13975 * sync_mode - (IN) hwcount is to be synced to sw count 13976 * Port - (IN) GPORT (global port) identifier 13977 * key_type - (IN) VLAN translation key type 13978 * outer_vlan - (IN) Outer VLAN ID or tag 13979 * inner_vlan - (IN) Inner VLAN ID or tag 13980 * stat - (IN) Type of the counter to retrieve 13981 * I.e. ingress/egress byte/packet) 13982 * num_entries - (IN) Number of counter Entries 13983 * counter_indexes - (IN) Pointer to Counter indexes entries 13984 * counter_values - (OUT) Pointer to counter values 13985 * 13986 * Return Value: 13987 * BCM_E_XXX 13988 * Notes: 13989 */ 13990 int 13991 bcm_esw_vlan_xslate_stat_counter_get(int unit, 13992 int sync_mode, 13993 bcm_gport_t port, 13994 bcm_vlan_translate_key_t key_type, 13995 bcm_vlan_t outer_vlan, 13996 bcm_vlan_t inner_vlan, 13997 bcm_vlan_stat_t stat, 13998 uint32 num_entries, 13999 uint32 *counter_indexes, 14000 bcm_stat_value_t *counter_values) 14001 { 14002 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 14003 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 14004 return _bcm_esw_vlan_translate_stat_counter_get(unit, sync_mode, 14005 port, key_type, 14006 outer_vlan, inner_vlan, 14007 stat,num_entries, 14008 counter_indexes, 14009 counter_values); 14010 } else 14011 #endif 14012 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14013 if (soc_feature(unit,soc_feature_gport_service_counters)) { 14014 uint64 val; 14015 _bcm_flex_stat_handle_t vxlt_fsh; 14016 int rv = BCM_E_NONE; 14017 14018 BCM_IF_ERROR_RETURN 14019 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 14020 outer_vlan, inner_vlan, 14021 &vxlt_fsh)); 14022 rv = _bcm_esw_flex_stat_ext_get(unit, 0, _bcmFlexStatTypeVxlt, 14023 vxlt_fsh, _bcm_esw_vlan_translate_stat_to_flex_stat(stat), 14024 &val); 14025 14026 if (stat == bcmVlanStatIngressPackets) { 14027 counter_values->packets = COMPILER_64_LO(val); 14028 } else { 14029 COMPILER_64_SET(counter_values->bytes, 14030 COMPILER_64_HI(val), 14031 COMPILER_64_LO(val)); 14032 } 14033 return rv; 14034 14035 } else 14036 #endif 14037 #if defined(BCM_HURRICANE3_SUPPORT) 14038 if (soc_feature(unit, soc_feature_flowcnt)) { 14039 return _bcm_hr3_vlan_translate_stat_counter_get(unit, sync_mode, 14040 port, key_type, 14041 outer_vlan, inner_vlan, 14042 stat,num_entries, 14043 counter_indexes, 14044 counter_values); 14045 } else 14046 #endif 14047 { 14048 return BCM_E_UNAVAIL; 14049 } 14050 } 14051 14052 14053 /* 14054 * Function: 14055 * bcm_esw_vlan_translate_stat_counter_get 14056 * Description: 14057 * Get counter values from ingress vlan translation table 14058 * 14059 * Parameters: 14060 * unit - (IN) unit number 14061 * Port - (IN) GPORT (global port) identifier 14062 * key_type - (IN) VLAN translation key type 14063 * outer_vlan - (IN) Outer VLAN ID or tag 14064 * inner_vlan - (IN) Inner VLAN ID or tag 14065 * stat - (IN) Type of the counter to retrieve 14066 * I.e. ingress/egress byte/packet) 14067 * num_entries - (IN) Number of counter Entries 14068 * counter_indexes - (IN) Pointer to Counter indexes entries 14069 * counter_values - (OUT) Pointer to counter values 14070 * 14071 * Return Value: 14072 * BCM_E_XXX 14073 * Notes: 14074 */ 14075 int bcm_esw_vlan_translate_stat_counter_get( 14076 int unit, 14077 bcm_gport_t port, 14078 bcm_vlan_translate_key_t key_type, 14079 bcm_vlan_t outer_vlan, 14080 bcm_vlan_t inner_vlan, 14081 bcm_vlan_stat_t stat, 14082 uint32 num_entries, 14083 uint32 *counter_indexes, 14084 bcm_stat_value_t *counter_values) 14085 { 14086 #ifdef BCM_TOMAHAWK3_SUPPORT 14087 if (SOC_IS_TOMAHAWK3(unit)) { 14088 return BCM_E_UNAVAIL; 14089 } 14090 #endif 14091 return bcm_esw_vlan_xslate_stat_counter_get(unit, 0, port, key_type, 14092 outer_vlan, inner_vlan, 14093 stat, num_entries, 14094 counter_indexes, 14095 counter_values); 14096 } 14097 14098 14099 /* 14100 * Function: 14101 * bcm_esw_vlan_translate_stat_counter_sync_get 14102 * Description: 14103 * Get counter values from ingress vlan translation table 14104 * sw accumulated counters synced with hw count. 14105 * 14106 * Parameters: 14107 * unit - (IN) unit number 14108 * Port - (IN) GPORT (global port) identifier 14109 * key_type - (IN) VLAN translation key type 14110 * outer_vlan - (IN) Outer VLAN ID or tag 14111 * inner_vlan - (IN) Inner VLAN ID or tag 14112 * stat - (IN) Type of the counter to retrieve 14113 * I.e. ingress/egress byte/packet) 14114 * num_entries - (IN) Number of counter Entries 14115 * counter_indexes - (IN) Pointer to Counter indexes entries 14116 * counter_values - (OUT) Pointer to counter values 14117 * 14118 * Return Value: 14119 * BCM_E_XXX 14120 * Notes: 14121 */ 14122 int bcm_esw_vlan_translate_stat_counter_sync_get( 14123 int unit, 14124 bcm_gport_t port, 14125 bcm_vlan_translate_key_t key_type, 14126 bcm_vlan_t outer_vlan, 14127 bcm_vlan_t inner_vlan, 14128 bcm_vlan_stat_t stat, 14129 uint32 num_entries, 14130 uint32 *counter_indexes, 14131 bcm_stat_value_t *counter_values) 14132 { 14133 #ifdef BCM_TOMAHAWK3_SUPPORT 14134 if (SOC_IS_TOMAHAWK3(unit)) { 14135 return BCM_E_UNAVAIL; 14136 } 14137 #endif 14138 return bcm_esw_vlan_xslate_stat_counter_get(unit, 1, port, key_type, 14139 outer_vlan, inner_vlan, 14140 stat, num_entries, 14141 counter_indexes, 14142 counter_values); 14143 } 14144 14145 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 14146 /* Function: 14147 * _bcm_esw_vlan_translate_stat_counter_set 14148 * Description: 14149 * Set counter values into a ingress vlan translation table 14150 * 14151 * Parameters: 14152 * unit - (IN) unit number 14153 * Port - (IN) GPORT (global port) identifier 14154 * key_type - (IN) VLAN translation key type 14155 * outer_vlan - (IN) Outer VLAN ID or tag 14156 * inner_vlan - (IN) Inner VLAN ID or tag 14157 * stat - (IN) Type of the counter to retrieve 14158 * I.e. ingress/egress byte/packet) 14159 * num_entries - (IN) Number of counter Entries 14160 * counter_indexes - (IN) Pointer to Counter indexes entries 14161 * counter_values - (IN) Pointer to counter values 14162 * 14163 * Return Value: 14164 * BCM_E_XXX 14165 * Notes: 14166 */ 14167 STATIC bcm_error_t _bcm_esw_vlan_translate_stat_counter_set( 14168 int unit, 14169 bcm_gport_t port, 14170 bcm_vlan_translate_key_t key_type, 14171 bcm_vlan_t outer_vlan, 14172 bcm_vlan_t inner_vlan, 14173 bcm_vlan_stat_t stat, 14174 uint32 num_entries, 14175 uint32 *counter_indexes, 14176 bcm_stat_value_t *counter_values) 14177 { 14178 uint32 table_count=0; 14179 uint32 index_count=0; 14180 uint32 num_of_tables=0; 14181 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 14182 uint32 byte_flag=0; 14183 bcm_stat_flex_table_info_t table_info[ 14184 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 14185 14186 if ((stat == bcmVlanStatIngressPackets) || 14187 (stat == bcmVlanStatIngressBytes)) { 14188 direction = bcmStatFlexDirectionIngress; 14189 } else { 14190 direction = bcmStatFlexDirectionEgress; 14191 } 14192 if ((stat == bcmVlanStatIngressPackets) || 14193 (stat == bcmVlanStatEgressPackets)) { 14194 byte_flag=0; 14195 } else { 14196 byte_flag=1; 14197 } 14198 14199 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info( 14200 unit, port,key_type,outer_vlan,inner_vlan, 14201 &num_of_tables,&table_info[0])); 14202 14203 for (table_count=0; table_count < num_of_tables ; table_count++) { 14204 if (table_info[table_count].direction == direction) { 14205 for (index_count=0; index_count < num_entries ; index_count++) { 14206 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set( 14207 unit, table_info[table_count].index, 14208 table_info[table_count].table, 0, 14209 byte_flag, 14210 counter_indexes[index_count], 14211 &counter_values[index_count])); 14212 } 14213 } 14214 } 14215 return BCM_E_NONE; 14216 } 14217 #endif 14218 14219 /* Function: 14220 * bcm_esw_vlan_translate_stat_counter_set 14221 * Description: 14222 * Set counter values into a ingress vlan translation table 14223 * 14224 * Parameters: 14225 * unit - (IN) unit number 14226 * Port - (IN) GPORT (global port) identifier 14227 * key_type - (IN) VLAN translation key type 14228 * outer_vlan - (IN) Outer VLAN ID or tag 14229 * inner_vlan - (IN) Inner VLAN ID or tag 14230 * stat - (IN) Type of the counter to retrieve 14231 * I.e. ingress/egress byte/packet) 14232 * num_entries - (IN) Number of counter Entries 14233 * counter_indexes - (IN) Pointer to Counter indexes entries 14234 * counter_values - (IN) Pointer to counter values 14235 * 14236 * Return Value: 14237 * BCM_E_XXX 14238 * Notes: 14239 */ 14240 int bcm_esw_vlan_translate_stat_counter_set( 14241 int unit, 14242 bcm_gport_t port, 14243 bcm_vlan_translate_key_t key_type, 14244 bcm_vlan_t outer_vlan, 14245 bcm_vlan_t inner_vlan, 14246 bcm_vlan_stat_t stat, 14247 uint32 num_entries, 14248 uint32 *counter_indexes, 14249 bcm_stat_value_t *counter_values) 14250 { 14251 #ifdef BCM_TOMAHAWK3_SUPPORT 14252 if (SOC_IS_TOMAHAWK3(unit)) { 14253 return BCM_E_UNAVAIL; 14254 } 14255 #endif 14256 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 14257 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 14258 return _bcm_esw_vlan_translate_stat_counter_set(unit,port,key_type, 14259 outer_vlan,inner_vlan,stat,num_entries, 14260 counter_indexes,counter_values); 14261 } else 14262 #endif 14263 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14264 if (soc_feature(unit,soc_feature_gport_service_counters)) { 14265 uint64 val; 14266 _bcm_flex_stat_handle_t vxlt_fsh; 14267 int rv = BCM_E_NONE; 14268 14269 if (stat == bcmVlanStatIngressPackets) { 14270 COMPILER_64_SET(val,0,counter_values->packets); 14271 } else { 14272 COMPILER_64_SET(val, 14273 COMPILER_64_HI(counter_values->bytes), 14274 COMPILER_64_LO(counter_values->bytes)); 14275 } 14276 BCM_IF_ERROR_RETURN 14277 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 14278 outer_vlan, inner_vlan, 14279 &vxlt_fsh)); 14280 rv = _bcm_esw_flex_stat_ext_set(unit, _bcmFlexStatTypeVxlt, 14281 vxlt_fsh, _bcm_esw_vlan_translate_stat_to_flex_stat(stat),val); 14282 return rv; 14283 14284 } else 14285 #endif 14286 #if defined(BCM_HURRICANE3_SUPPORT) 14287 if (soc_feature(unit, soc_feature_flowcnt)) { 14288 return _bcm_hr3_vlan_translate_stat_counter_set(unit,port,key_type, 14289 outer_vlan,inner_vlan,stat,num_entries, 14290 counter_indexes,counter_values); 14291 } else 14292 #endif 14293 { 14294 return BCM_E_UNAVAIL; 14295 } 14296 14297 } 14298 14299 /* 14300 * Function: 14301 * bcm_esw_vlan_translate_stat_id_get 14302 * Description: 14303 * Get stat counter id associated with given ingress vlan 14304 * 14305 * Parameters: 14306 * unit - (IN) unit number 14307 * Port - (IN) GPORT (global port) identifier 14308 * key_type - (IN) VLAN translation key type 14309 * outer_vlan - (IN) Outer VLAN ID or tag 14310 * inner_vlan - (IN) Inner VLAN ID or tag 14311 * stat - (IN) Type of the counter to retrieve 14312 * I.e. ingress/egress byte/packet) 14313 * Stat_counter_id - (OUT) Stat Counter ID 14314 * Return Value: 14315 * BCM_E_XXX 14316 * Notes: 14317 */ 14318 int bcm_esw_vlan_translate_stat_id_get( 14319 int unit, 14320 bcm_gport_t port, 14321 bcm_vlan_translate_key_t key_type, 14322 bcm_vlan_t outer_vlan, 14323 bcm_vlan_t inner_vlan, 14324 bcm_vlan_stat_t stat, 14325 uint32 *stat_counter_id) 14326 { 14327 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 14328 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 14329 uint32 num_of_tables=0; 14330 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 14331 uint32 index=0; 14332 uint32 num_stat_counter_ids=0; 14333 #endif 14334 14335 #ifdef BCM_TOMAHAWK3_SUPPORT 14336 if (SOC_IS_TOMAHAWK3(unit)) { 14337 return BCM_E_UNAVAIL; 14338 } 14339 #endif 14340 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 14341 if (soc_feature(unit, soc_feature_advanced_flex_counter)) { 14342 if ((stat == bcmVlanStatIngressPackets) || 14343 (stat == bcmVlanStatIngressBytes)) { 14344 direction = bcmStatFlexDirectionIngress; 14345 } else { 14346 direction = bcmStatFlexDirectionEgress; 14347 } 14348 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info( 14349 unit, port,key_type,outer_vlan,inner_vlan, 14350 &num_of_tables,&table_info[0])); 14351 for (index=0; index < num_of_tables ; index++) { 14352 if (table_info[index].direction == direction) 14353 return _bcm_esw_stat_flex_get_counter_id( 14354 unit, 1, &table_info[index], 14355 &num_stat_counter_ids,stat_counter_id); 14356 } 14357 return BCM_E_NOT_FOUND; 14358 } else 14359 #endif 14360 #if defined(BCM_HURRICANE3_SUPPORT) 14361 if (soc_feature(unit, soc_feature_flowcnt)) { 14362 return _bcm_hr3_vlan_translate_stat_id_get(unit, port, key_type, 14363 outer_vlan, inner_vlan, stat, stat_counter_id); 14364 } else 14365 #endif 14366 { 14367 return BCM_E_UNAVAIL; 14368 } 14369 } 14370 14371 /* 14372 * Function: 14373 * _bcm_esw_vlan_translate_stat_get 14374 * Purpose: 14375 * Extract ingress VLAN translation statistics from the chip. 14376 * if sync_mode is set, sync the sw accumulated count 14377 * with hw count value first, else return sw count. 14378 * 14379 * Parameters: 14380 * unit - (IN) Unit number. 14381 * sync_mode - (IN) Unit number. 14382 * port - (IN) Generic port 14383 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14384 * outer_vlan - (IN) Packet outer VLAN ID 14385 * inner_vlan - (IN) Packet inner VLAN ID 14386 * stat - (IN) Type of the counter to retrieve. 14387 * val - (OUT) Pointer to a counter value. 14388 * Returns: 14389 * BCM_E_xxx 14390 * Notes: 14391 */ 14392 int 14393 _bcm_esw_vlan_translate_stat_get(int unit, int sync_mode, bcm_gport_t port, 14394 bcm_vlan_translate_key_t key_type, 14395 bcm_vlan_t outer_vlan, 14396 bcm_vlan_t inner_vlan, 14397 bcm_vlan_stat_t stat, 14398 uint64 *val) 14399 { 14400 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT) 14401 _bcm_flex_stat_handle_t vxlt_fsh; 14402 #endif 14403 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14404 defined(BCM_HURRICANE3_SUPPORT) 14405 uint32 counter_indexes=0; 14406 bcm_stat_value_t counter_values={0}; 14407 #endif 14408 14409 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14410 if (soc_feature(unit, soc_feature_gport_service_counters)) { 14411 14412 BCM_IF_ERROR_RETURN 14413 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 14414 outer_vlan, inner_vlan, 14415 &vxlt_fsh)); 14416 return _bcm_esw_flex_stat_ext_get(unit, sync_mode, _bcmFlexStatTypeVxlt, 14417 vxlt_fsh, 14418 _bcm_esw_vlan_translate_stat_to_flex_stat(stat), 14419 val); 14420 } else 14421 #endif 14422 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14423 defined(BCM_HURRICANE3_SUPPORT) 14424 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 14425 soc_feature(unit, soc_feature_flowcnt)) { 14426 BCM_IF_ERROR_RETURN( 14427 bcm_esw_vlan_xslate_stat_counter_get(unit, sync_mode, 14428 port, key_type, 14429 outer_vlan, 14430 inner_vlan, 14431 stat, 1, 14432 &counter_indexes, 14433 &counter_values)); 14434 14435 if ((stat == bcmVlanStatIngressPackets) || 14436 (stat == bcmVlanStatEgressPackets)) { 14437 COMPILER_64_SET(*val, 14438 COMPILER_64_HI(counter_values.packets64), 14439 COMPILER_64_LO(counter_values.packets64)); 14440 } else { 14441 COMPILER_64_SET(*val, 14442 COMPILER_64_HI(counter_values.bytes), 14443 COMPILER_64_LO(counter_values.bytes)); 14444 } 14445 return BCM_E_NONE; 14446 } else 14447 #endif 14448 { 14449 return BCM_E_UNAVAIL; 14450 } 14451 } 14452 14453 /* 14454 * Function: 14455 * bcm_esw_vlan_translate_stat_get 14456 * Purpose: 14457 * Extract ingress VLAN translation statistics from the chip. 14458 * Parameters: 14459 * unit - (IN) Unit number. 14460 * port - (IN) Generic port 14461 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14462 * outer_vlan - (IN) Packet outer VLAN ID 14463 * inner_vlan - (IN) Packet inner VLAN ID 14464 * stat - (IN) Type of the counter to retrieve. 14465 * val - (OUT) Pointer to a counter value. 14466 * Returns: 14467 * BCM_E_xxx 14468 * Notes: 14469 */ 14470 int 14471 bcm_esw_vlan_translate_stat_get(int unit, bcm_gport_t port, 14472 bcm_vlan_translate_key_t key_type, 14473 bcm_vlan_t outer_vlan, 14474 bcm_vlan_t inner_vlan, 14475 bcm_vlan_stat_t stat, 14476 uint64 *val) 14477 { 14478 int rv = BCM_E_NONE; 14479 14480 #ifdef BCM_TOMAHAWK3_SUPPORT 14481 if (SOC_IS_TOMAHAWK3(unit)) { 14482 return BCM_E_UNAVAIL; 14483 } 14484 #endif 14485 14486 rv = _bcm_esw_vlan_translate_stat_get(unit, 0, port, key_type, outer_vlan, 14487 inner_vlan, stat, val); 14488 14489 return rv; 14490 } 14491 14492 /* 14493 * Function: 14494 * bcm_esw_vlan_translate_stat_sync_get 14495 * Purpose: 14496 * Extract ingress VLAN translation statistics from the chip. 14497 * sw accumulated counters synced with hw count. 14498 * 14499 * Parameters: 14500 * unit - (IN) Unit number. 14501 * port - (IN) Generic port 14502 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14503 * outer_vlan - (IN) Packet outer VLAN ID 14504 * inner_vlan - (IN) Packet inner VLAN ID 14505 * stat - (IN) Type of the counter to retrieve. 14506 * val - (OUT) Pointer to a counter value. 14507 * Returns: 14508 * BCM_E_xxx 14509 * Notes: 14510 */ 14511 int 14512 bcm_esw_vlan_translate_stat_sync_get(int unit, bcm_gport_t port, 14513 bcm_vlan_translate_key_t key_type, 14514 bcm_vlan_t outer_vlan, 14515 bcm_vlan_t inner_vlan, 14516 bcm_vlan_stat_t stat, 14517 uint64 *val) 14518 { 14519 int rv = BCM_E_NONE; 14520 14521 #ifdef BCM_TOMAHAWK3_SUPPORT 14522 if (SOC_IS_TOMAHAWK3(unit)) { 14523 return BCM_E_UNAVAIL; 14524 } 14525 #endif 14526 14527 rv = _bcm_esw_vlan_translate_stat_get(unit, 1, port, key_type, outer_vlan, 14528 inner_vlan, stat, val); 14529 14530 return rv; 14531 } 14532 14533 /* 14534 * Function: 14535 * _bcm_esw_vlan_translate_stat_get32 14536 * Purpose: 14537 * Extract ingress VLAN translation statistics from the chip. 14538 * if sync_mode is set, sync the sw accumulated count 14539 * with hw count value first, else return sw count. 14540 * 14541 * Parameters: 14542 * unit - (IN) Unit number. 14543 * sync_mode - (IN) hwcount is to be synced to sw count 14544 * port - (IN) Generic port 14545 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14546 * outer_vlan - (IN) Packet outer VLAN ID 14547 * inner_vlan - (IN) Packet inner VLAN ID 14548 * stat - (IN) Type of the counter to retrieve. 14549 * val - (OUT) Pointer to a counter value. 14550 * Returns: 14551 * BCM_E_xxx 14552 * Notes: 14553 */ 14554 int 14555 _bcm_esw_vlan_translate_stat_get32(int unit, int sync_mode, bcm_gport_t port, 14556 bcm_vlan_translate_key_t key_type, 14557 bcm_vlan_t outer_vlan, 14558 bcm_vlan_t inner_vlan, 14559 bcm_vlan_stat_t stat, 14560 uint32 *val) 14561 { 14562 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT) 14563 _bcm_flex_stat_handle_t vxlt_fsh; 14564 #endif 14565 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14566 defined(BCM_HURRICANE3_SUPPORT) 14567 uint32 counter_indexes=0; 14568 bcm_stat_value_t counter_values={0}; 14569 #endif 14570 14571 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14572 if (soc_feature(unit, soc_feature_gport_service_counters)) { 14573 BCM_IF_ERROR_RETURN 14574 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 14575 outer_vlan, inner_vlan, 14576 &vxlt_fsh)); 14577 return _bcm_esw_flex_stat_ext_get32(unit, sync_mode, _bcmFlexStatTypeVxlt, 14578 vxlt_fsh, 14579 _bcm_esw_vlan_translate_stat_to_flex_stat(stat), 14580 val); 14581 } else 14582 #endif 14583 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14584 defined(BCM_HURRICANE3_SUPPORT) 14585 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 14586 soc_feature(unit, soc_feature_flowcnt)) { 14587 BCM_IF_ERROR_RETURN(bcm_esw_vlan_xslate_stat_counter_get(unit, sync_mode, 14588 port, key_type, 14589 outer_vlan, 14590 inner_vlan, stat, 14591 1, 14592 &counter_indexes, 14593 &counter_values)); 14594 if ((stat == bcmVlanStatIngressPackets) || 14595 (stat == bcmVlanStatEgressPackets)) { 14596 *val = counter_values.packets; 14597 } else { 14598 /* Ignoring Hi bytes value */ 14599 *val = COMPILER_64_LO(counter_values.bytes); 14600 } 14601 return BCM_E_NONE; 14602 } else 14603 #endif 14604 { 14605 return BCM_E_UNAVAIL; 14606 } 14607 } 14608 14609 /* 14610 * Function: 14611 * bcm_esw_vlan_translate_stat_get32 14612 * Purpose: 14613 * Extract ingress VLAN translation statistics from the chip. 14614 * Parameters: 14615 * unit - (IN) Unit number. 14616 * port - (IN) Generic port 14617 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14618 * outer_vlan - (IN) Packet outer VLAN ID 14619 * inner_vlan - (IN) Packet inner VLAN ID 14620 * stat - (IN) Type of the counter to retrieve. 14621 * val - (OUT) Pointer to a counter value. 14622 * Returns: 14623 * BCM_E_xxx 14624 * Notes: 14625 */ 14626 int 14627 bcm_esw_vlan_translate_stat_get32(int unit, bcm_gport_t port, 14628 bcm_vlan_translate_key_t key_type, 14629 bcm_vlan_t outer_vlan, 14630 bcm_vlan_t inner_vlan, 14631 bcm_vlan_stat_t stat, 14632 uint32 *val) 14633 { 14634 int rv = BCM_E_NONE; 14635 14636 #ifdef BCM_TOMAHAWK3_SUPPORT 14637 if (SOC_IS_TOMAHAWK3(unit)) { 14638 return BCM_E_UNAVAIL; 14639 } 14640 #endif 14641 14642 rv = _bcm_esw_vlan_translate_stat_get32(unit, 0, port, key_type, outer_vlan, 14643 inner_vlan, stat, val); 14644 return rv; 14645 } 14646 14647 /* 14648 * Function: 14649 * bcm_esw_vlan_translate_stat_sync_get32 14650 * Purpose: 14651 * Extract ingress VLAN translation statistics from the chip. 14652 * sw accumulated counters synced with hw count. 14653 * 14654 * Parameters: 14655 * unit - (IN) Unit number. 14656 * port - (IN) Generic port 14657 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14658 * outer_vlan - (IN) Packet outer VLAN ID 14659 * inner_vlan - (IN) Packet inner VLAN ID 14660 * stat - (IN) Type of the counter to retrieve. 14661 * val - (OUT) Pointer to a counter value. 14662 * Returns: 14663 * BCM_E_xxx 14664 * Notes: 14665 */ 14666 int 14667 bcm_esw_vlan_translate_stat_sync_get32(int unit, bcm_gport_t port, 14668 bcm_vlan_translate_key_t key_type, 14669 bcm_vlan_t outer_vlan, 14670 bcm_vlan_t inner_vlan, 14671 bcm_vlan_stat_t stat, 14672 uint32 *val) 14673 { 14674 int rv = BCM_E_NONE; 14675 14676 #ifdef BCM_TOMAHAWK3_SUPPORT 14677 if (SOC_IS_TOMAHAWK3(unit)) { 14678 return BCM_E_UNAVAIL; 14679 } 14680 #endif 14681 14682 rv = _bcm_esw_vlan_translate_stat_get32(unit, 1, port, key_type, outer_vlan, 14683 inner_vlan, stat, val); 14684 return rv; 14685 } 14686 14687 /* 14688 * Function: 14689 * bcm_esw_vlan_translate_stat_set 14690 * Purpose: 14691 * Set the specified statistic to the indicated value for the 14692 * specified ingress VLAN translation. 14693 * Parameters: 14694 * unit - (IN) Unit number. 14695 * port - (IN) Generic port 14696 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14697 * outer_vlan - (IN) Packet outer VLAN ID 14698 * inner_vlan - (IN) Packet inner VLAN ID 14699 * stat - (IN) Type of the counter to set. 14700 * val - (IN) New counter value. 14701 * Returns: 14702 * BCM_E_xxx 14703 * Notes: 14704 */ 14705 int 14706 bcm_esw_vlan_translate_stat_set(int unit, bcm_gport_t port, 14707 bcm_vlan_translate_key_t key_type, 14708 bcm_vlan_t outer_vlan, 14709 bcm_vlan_t inner_vlan, 14710 bcm_vlan_stat_t stat, 14711 uint64 val) 14712 { 14713 #if defined(BCM_TRIUMPH2_SUPPORT) 14714 _bcm_flex_stat_handle_t vxlt_fsh; 14715 #endif 14716 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14717 defined(BCM_HURRICANE3_SUPPORT) 14718 uint32 counter_indexes=0; 14719 bcm_stat_value_t counter_values={0}; 14720 #endif 14721 14722 #ifdef BCM_TOMAHAWK3_SUPPORT 14723 if (SOC_IS_TOMAHAWK3(unit)) { 14724 return BCM_E_UNAVAIL; 14725 } 14726 #endif 14727 14728 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14729 if (soc_feature(unit, soc_feature_gport_service_counters)) { 14730 BCM_IF_ERROR_RETURN 14731 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 14732 outer_vlan, inner_vlan, 14733 &vxlt_fsh)); 14734 return _bcm_esw_flex_stat_ext_set(unit, _bcmFlexStatTypeVxlt, 14735 vxlt_fsh, 14736 _bcm_esw_vlan_translate_stat_to_flex_stat(stat), val); 14737 } else 14738 #endif 14739 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14740 defined(BCM_HURRICANE3_SUPPORT) 14741 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 14742 soc_feature(unit, soc_feature_flowcnt)) { 14743 if ((stat == bcmVlanStatIngressPackets) || 14744 (stat == bcmVlanStatEgressPackets)) { 14745 counter_values.packets = COMPILER_64_LO(val); 14746 } else { 14747 COMPILER_64_SET(counter_values.bytes, 14748 COMPILER_64_HI(val), 14749 COMPILER_64_LO(val)); 14750 } 14751 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_set( 14752 unit,port,key_type,outer_vlan,inner_vlan, 14753 stat, 1, &counter_indexes, &counter_values)); 14754 return BCM_E_NONE; 14755 } else 14756 #endif 14757 { 14758 return BCM_E_UNAVAIL; 14759 } 14760 } 14761 14762 /* 14763 * Function: 14764 * bcm_esw_vlan_translate_stat_set32 14765 * Purpose: 14766 * Set the specified statistic to the indicated value for the 14767 * specified ingress VLAN translation. 14768 * Parameters: 14769 * unit - (IN) Unit number. 14770 * port - (IN) Generic port 14771 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14772 * outer_vlan - (IN) Packet outer VLAN ID 14773 * inner_vlan - (IN) Packet inner VLAN ID 14774 * stat - (IN) Type of the counter to set. 14775 * val - (IN) New counter value. 14776 * Returns: 14777 * BCM_E_xxx 14778 * Notes: 14779 */ 14780 int 14781 bcm_esw_vlan_translate_stat_set32(int unit, bcm_gport_t port, 14782 bcm_vlan_translate_key_t key_type, 14783 bcm_vlan_t outer_vlan, 14784 bcm_vlan_t inner_vlan, 14785 bcm_vlan_stat_t stat, 14786 uint32 val) 14787 { 14788 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT) 14789 _bcm_flex_stat_handle_t vxlt_fsh; 14790 #endif 14791 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14792 defined(BCM_HURRICANE3_SUPPORT) 14793 uint32 counter_indexes=0; 14794 bcm_stat_value_t counter_values={0}; 14795 #endif 14796 14797 #ifdef BCM_TOMAHAWK3_SUPPORT 14798 if (SOC_IS_TOMAHAWK3(unit)) { 14799 return BCM_E_UNAVAIL; 14800 } 14801 #endif 14802 14803 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14804 if (soc_feature(unit, soc_feature_gport_service_counters)) { 14805 14806 BCM_IF_ERROR_RETURN 14807 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 14808 outer_vlan, inner_vlan, 14809 &vxlt_fsh)); 14810 return _bcm_esw_flex_stat_ext_set32(unit, _bcmFlexStatTypeVxlt, 14811 vxlt_fsh, 14812 _bcm_esw_vlan_translate_stat_to_flex_stat(stat), val); 14813 } else 14814 #endif 14815 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14816 defined(BCM_HURRICANE3_SUPPORT) 14817 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 14818 soc_feature(unit, soc_feature_flowcnt)) { 14819 if ((stat == bcmVlanStatIngressPackets) || 14820 (stat == bcmVlanStatEgressPackets)) { 14821 counter_values.packets = val; 14822 } else { 14823 /* Ignoring high value */ 14824 COMPILER_64_SET(counter_values.bytes,0,val); 14825 } 14826 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_set( 14827 unit,port,key_type,outer_vlan,inner_vlan, 14828 stat, 1, &counter_indexes, &counter_values)); 14829 return BCM_E_NONE; 14830 } else 14831 #endif 14832 { 14833 return BCM_E_UNAVAIL; 14834 } 14835 } 14836 14837 /* 14838 * Function: 14839 * bcm_esw_vlan_translate_stat_multi_get 14840 * Purpose: 14841 * Get 64-bit counter value for multiple ingress VLAN translation 14842 * statistic types. 14843 * Parameters: 14844 * unit - (IN) Unit number. 14845 * port - (IN) Generic port 14846 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14847 * outer_vlan - (IN) Packet outer VLAN ID 14848 * inner_vlan - (IN) Packet inner VLAN ID 14849 * nstat - (IN) Number of elements in stat array 14850 * stat_arr - (IN) Collected statistics descriptors array 14851 * value_arr - (OUT) Collected counters values 14852 * Returns: 14853 * BCM_E_xxx 14854 * Notes: 14855 */ 14856 int 14857 bcm_esw_vlan_translate_stat_multi_get(int unit, bcm_gport_t port, 14858 bcm_vlan_translate_key_t key_type, 14859 bcm_vlan_t outer_vlan, 14860 bcm_vlan_t inner_vlan, 14861 int nstat, 14862 bcm_vlan_stat_t *stat_arr, 14863 uint64 *value_arr) 14864 { 14865 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14866 _bcm_flex_stat_handle_t vxlt_fsh; 14867 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 14868 int idx; 14869 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14870 defined(BCM_HURRICANE3_SUPPORT) 14871 uint32 counter_indexes=0; 14872 bcm_stat_value_t counter_values={0}; 14873 #endif 14874 14875 #ifdef BCM_TOMAHAWK3_SUPPORT 14876 if (SOC_IS_TOMAHAWK3(unit)) { 14877 return BCM_E_UNAVAIL; 14878 } 14879 #endif 14880 14881 if (soc_feature(unit, soc_feature_gport_service_counters)) { 14882 BCM_IF_ERROR_RETURN 14883 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 14884 outer_vlan, inner_vlan, 14885 &vxlt_fsh)); 14886 BCM_IF_ERROR_RETURN 14887 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, 14888 fs_arr, &_bcm_esw_vlan_translate_stat_to_flex_stat)); 14889 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 14890 14891 return _bcm_esw_flex_stat_ext_multi_get(unit, _bcmFlexStatTypeVxlt, 14892 vxlt_fsh, 14893 nstat, fs_arr, value_arr); 14894 } else 14895 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14896 defined(BCM_HURRICANE3_SUPPORT) 14897 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 14898 soc_feature(unit, soc_feature_flowcnt)) { 14899 for (idx=0;idx < nstat ; idx ++) { 14900 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_get( 14901 unit,port,key_type,outer_vlan,inner_vlan, 14902 stat_arr[idx],1,&counter_indexes,&counter_values)); 14903 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 14904 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 14905 COMPILER_64_SET(value_arr[idx], 14906 COMPILER_64_HI(counter_values.packets64), 14907 COMPILER_64_LO(counter_values.packets64)); 14908 } else { 14909 COMPILER_64_SET(value_arr[idx], 14910 COMPILER_64_HI(counter_values.bytes), 14911 COMPILER_64_LO(counter_values.bytes)); 14912 } 14913 } 14914 return BCM_E_NONE; 14915 } else 14916 #endif 14917 #endif 14918 { 14919 return BCM_E_UNAVAIL; 14920 } 14921 } 14922 14923 /* 14924 * Function: 14925 * bcm_esw_vlan_translate_stat_multi_get32 14926 * Purpose: 14927 * Get lower 32-bit counter value for multiple ingress VLAN 14928 * translation statistic types. 14929 * Parameters: 14930 * unit - (IN) Unit number. 14931 * port - (IN) Generic port 14932 * key_type - (IN) Key Type : bcmVlanTranslateKey* 14933 * outer_vlan - (IN) Packet outer VLAN ID 14934 * inner_vlan - (IN) Packet inner VLAN ID 14935 * nstat - (IN) Number of elements in stat array 14936 * stat_arr - (IN) Collected statistics descriptors array 14937 * value_arr - (OUT) Collected counters values 14938 * Returns: 14939 * BCM_E_xxx 14940 * Notes: 14941 */ 14942 int 14943 bcm_esw_vlan_translate_stat_multi_get32(int unit, bcm_gport_t port, 14944 bcm_vlan_translate_key_t key_type, 14945 bcm_vlan_t outer_vlan, 14946 bcm_vlan_t inner_vlan, 14947 int nstat, 14948 bcm_vlan_stat_t *stat_arr, 14949 uint32 *value_arr) 14950 { 14951 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14952 _bcm_flex_stat_handle_t vxlt_fsh; 14953 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 14954 int idx; 14955 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14956 defined(BCM_HURRICANE3_SUPPORT) 14957 uint32 counter_indexes=0; 14958 bcm_stat_value_t counter_values={0}; 14959 #endif 14960 14961 #ifdef BCM_TOMAHAWK3_SUPPORT 14962 if (SOC_IS_TOMAHAWK3(unit)) { 14963 return BCM_E_UNAVAIL; 14964 } 14965 #endif 14966 14967 if (soc_feature(unit, soc_feature_gport_service_counters)) { 14968 BCM_IF_ERROR_RETURN 14969 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 14970 outer_vlan, inner_vlan, 14971 &vxlt_fsh)); 14972 BCM_IF_ERROR_RETURN 14973 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, 14974 fs_arr, &_bcm_esw_vlan_translate_stat_to_flex_stat)); 14975 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 14976 14977 return _bcm_esw_flex_stat_ext_multi_get32(unit, _bcmFlexStatTypeVxlt, 14978 vxlt_fsh, 14979 nstat, fs_arr, value_arr); 14980 } else 14981 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 14982 defined(BCM_HURRICANE3_SUPPORT) 14983 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 14984 soc_feature(unit, soc_feature_flowcnt)) { 14985 for (idx=0;idx < nstat ; idx ++) { 14986 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_get( 14987 unit,port,key_type,outer_vlan,inner_vlan, 14988 stat_arr[idx],1,&counter_indexes,&counter_values)); 14989 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 14990 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 14991 value_arr[idx] = counter_values.packets; 14992 } else { 14993 value_arr[idx] = COMPILER_64_LO(counter_values.bytes); 14994 } 14995 } 14996 return BCM_E_NONE; 14997 } 14998 #endif 14999 #endif 15000 { 15001 return BCM_E_UNAVAIL; 15002 } 15003 } 15004 15005 /* 15006 * Function: 15007 * bcm_esw_vlan_translate_stat_multi_set 15008 * Purpose: 15009 * Set 64-bit counter value for multiple ingress VLAN translation 15010 * statistic types. 15011 * Parameters: 15012 * unit - (IN) Unit number. 15013 * port - (IN) Generic port 15014 * key_type - (IN) Key Type : bcmVlanTranslateKey* 15015 * outer_vlan - (IN) Packet outer VLAN ID 15016 * inner_vlan - (IN) Packet inner VLAN ID 15017 * nstat - (IN) Number of elements in stat array 15018 * stat_arr - (IN) New statistics descriptors array 15019 * value_arr - (IN) New counters values 15020 * Returns: 15021 * BCM_E_xxx 15022 * Notes: 15023 */ 15024 int 15025 bcm_esw_vlan_translate_stat_multi_set(int unit, bcm_gport_t port, 15026 bcm_vlan_translate_key_t key_type, 15027 bcm_vlan_t outer_vlan, 15028 bcm_vlan_t inner_vlan, 15029 int nstat, 15030 bcm_vlan_stat_t *stat_arr, 15031 uint64 *value_arr) 15032 { 15033 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 15034 _bcm_flex_stat_handle_t vxlt_fsh; 15035 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 15036 int idx; 15037 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 15038 defined(BCM_HURRICANE3_SUPPORT) 15039 uint32 counter_indexes=0; 15040 bcm_stat_value_t counter_values={0}; 15041 #endif 15042 15043 #ifdef BCM_TOMAHAWK3_SUPPORT 15044 if (SOC_IS_TOMAHAWK3(unit)) { 15045 return BCM_E_UNAVAIL; 15046 } 15047 #endif 15048 15049 if (soc_feature(unit, soc_feature_gport_service_counters)) { 15050 BCM_IF_ERROR_RETURN 15051 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 15052 outer_vlan, inner_vlan, 15053 &vxlt_fsh)); 15054 BCM_IF_ERROR_RETURN 15055 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, 15056 fs_arr, &_bcm_esw_vlan_translate_stat_to_flex_stat)); 15057 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 15058 15059 return _bcm_esw_flex_stat_ext_multi_set(unit, _bcmFlexStatTypeVxlt, 15060 vxlt_fsh, 15061 nstat, fs_arr, value_arr); 15062 } else 15063 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 15064 defined(BCM_HURRICANE3_SUPPORT) 15065 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 15066 soc_feature(unit, soc_feature_flowcnt)) { 15067 for (idx=0;idx < nstat ; idx ++) { 15068 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 15069 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 15070 counter_values.packets = COMPILER_64_LO(value_arr[idx]); 15071 } else { 15072 COMPILER_64_SET(counter_values.bytes, 15073 COMPILER_64_HI(value_arr[idx]), 15074 COMPILER_64_LO(value_arr[idx])); 15075 } 15076 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_set( 15077 unit,port,key_type,outer_vlan,inner_vlan, 15078 stat_arr[idx],1,&counter_indexes,&counter_values)); 15079 } 15080 return BCM_E_NONE; 15081 } else 15082 #endif 15083 #endif 15084 { 15085 return BCM_E_UNAVAIL; 15086 } 15087 } 15088 15089 /* 15090 * Function: 15091 * bcm_esw_vlan_translate_stat_multi_set32 15092 * Purpose: 15093 * Set lower 32-bit counter value for multiple ingress VLAN 15094 * translation statistic types. 15095 * Parameters: 15096 * unit - (IN) Unit number. 15097 * port - (IN) Generic port 15098 * key_type - (IN) Key Type : bcmVlanTranslateKey* 15099 * outer_vlan - (IN) Packet outer VLAN ID 15100 * inner_vlan - (IN) Packet inner VLAN ID 15101 * nstat - (IN) Number of elements in stat array 15102 * stat_arr - (IN) New statistics descriptors array 15103 * value_arr - (IN) New counters values 15104 * Returns: 15105 * BCM_E_xxx 15106 * Notes: 15107 */ 15108 int 15109 bcm_esw_vlan_translate_stat_multi_set32(int unit, bcm_gport_t port, 15110 bcm_vlan_translate_key_t key_type, 15111 bcm_vlan_t outer_vlan, 15112 bcm_vlan_t inner_vlan, 15113 int nstat, 15114 bcm_vlan_stat_t *stat_arr, 15115 uint32 *value_arr) 15116 { 15117 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 15118 _bcm_flex_stat_handle_t vxlt_fsh; 15119 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 15120 int idx; 15121 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 15122 defined(BCM_HURRICANE3_SUPPORT) 15123 uint32 counter_indexes=0; 15124 bcm_stat_value_t counter_values={0}; 15125 #endif 15126 15127 #ifdef BCM_TOMAHAWK3_SUPPORT 15128 if (SOC_IS_TOMAHAWK3(unit)) { 15129 return BCM_E_UNAVAIL; 15130 } 15131 #endif 15132 15133 if (soc_feature(unit, soc_feature_gport_service_counters)) { 15134 BCM_IF_ERROR_RETURN 15135 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type, 15136 outer_vlan, inner_vlan, 15137 &vxlt_fsh)); 15138 BCM_IF_ERROR_RETURN 15139 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, 15140 fs_arr, &_bcm_esw_vlan_translate_stat_to_flex_stat)); 15141 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 15142 15143 return _bcm_esw_flex_stat_ext_multi_set32(unit, _bcmFlexStatTypeVxlt, 15144 vxlt_fsh, 15145 nstat, fs_arr, value_arr); 15146 } else 15147 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 15148 defined(BCM_HURRICANE3_SUPPORT) 15149 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 15150 soc_feature(unit, soc_feature_flowcnt)) { 15151 for (idx=0;idx < nstat ; idx ++) { 15152 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 15153 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 15154 counter_values.packets = value_arr[idx]; 15155 } else { 15156 COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]); 15157 } 15158 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_set( 15159 unit,port,key_type,outer_vlan,inner_vlan, 15160 stat_arr[idx],1,&counter_indexes,&counter_values)); 15161 } 15162 return BCM_E_NONE; 15163 } else 15164 #endif 15165 #endif 15166 { 15167 return BCM_E_UNAVAIL; 15168 } 15169 } 15170 15171 #if defined(BCM_TRIUMPH2_SUPPORT) 15172 STATIC int 15173 _bcm_esw_vlan_translate_egress_flex_stat_hw_index_set(int unit, 15174 _bcm_flex_stat_handle_t handle, 15175 int fs_idx, void *cookie) 15176 { 15177 egr_vlan_xlate_entry_t vent, res_vent; 15178 int rv, idx; 15179 15180 _BCM_FLEX_STAT_HANDLE_COPY(vent, handle); 15181 15182 soc_mem_lock(unit, EGR_VLAN_XLATEm); 15183 rv = soc_mem_search(unit, EGR_VLAN_XLATEm, MEM_BLOCK_ALL, &idx, 15184 &vent, &res_vent, 0); 15185 if (BCM_SUCCESS(rv)) { 15186 soc_mem_field32_set(unit, EGR_VLAN_XLATEm, &res_vent, 15187 VINTF_CTR_IDXf, fs_idx); 15188 if (SOC_MEM_FIELD_VALID(unit, EGR_VLAN_XLATEm, USE_VINTF_CTR_IDXf)) { 15189 soc_mem_field32_set(unit, EGR_VLAN_XLATEm, &res_vent, 15190 USE_VINTF_CTR_IDXf, fs_idx > 0 ? 1 : 0); 15191 } 15192 rv = soc_mem_insert(unit, EGR_VLAN_XLATEm, MEM_BLOCK_ALL, &res_vent); 15193 if (BCM_SUCCESS(rv)) { 15194 /* We found it already, but didn't overwrite it? The mem lock 15195 * must have failed. Not good. */ 15196 return BCM_E_INTERNAL; 15197 } else if (BCM_E_EXISTS == rv) { 15198 rv = BCM_E_NONE; 15199 } /* Else retain failing rv value */ 15200 } 15201 soc_mem_unlock(unit, EGR_VLAN_XLATEm); 15202 return rv; 15203 } 15204 15205 STATIC _bcm_flex_stat_t 15206 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(bcm_vlan_stat_t stat) 15207 { 15208 _bcm_flex_stat_t flex_stat; 15209 15210 /* No ingress stats for egress translations */ 15211 switch (stat) { 15212 case bcmVlanStatEgressPackets: 15213 flex_stat = _bcmFlexStatEgressPackets; 15214 break; 15215 case bcmVlanStatEgressBytes: 15216 flex_stat = _bcmFlexStatEgressBytes; 15217 break; 15218 default: 15219 flex_stat = _bcmFlexStatNum; 15220 } 15221 15222 return flex_stat; 15223 } 15224 15225 STATIC int 15226 _bcm_esw_vlan_translate_egress_stat_param_valid(int unit, int port_class, 15227 bcm_vlan_t outer_vlan, 15228 bcm_vlan_t inner_vlan, 15229 _bcm_flex_stat_handle_t *vxlt_fsh) 15230 { 15231 egr_vlan_xlate_entry_t vent; 15232 bcm_module_t modid; 15233 bcm_trunk_t tgid = -1; 15234 int id = -1; 15235 15236 CHECK_INIT(unit); 15237 15238 if (!soc_feature(unit, soc_feature_gport_service_counters)) { 15239 return BCM_E_UNAVAIL; 15240 } 15241 15242 if (BCM_GPORT_IS_SET(port_class)) { 15243 if (!BCM_GPORT_IS_TUNNEL(port_class)) { 15244 BCM_IF_ERROR_RETURN( 15245 _bcm_esw_gport_resolve(unit, port_class, &modid, &port_class, 15246 &tgid, &id)); 15247 } 15248 if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port_class)) { 15249 return BCM_E_PORT; 15250 } 15251 } else { 15252 if (!SOC_PORT_CLASS_VALID(unit, port_class)) { 15253 return BCM_E_PORT; 15254 } 15255 } 15256 15257 BCM_IF_ERROR_RETURN 15258 (_bcm_trx_vlan_translate_egress_entry_assemble(unit, &vent, 15259 port_class, 15260 outer_vlan, 15261 inner_vlan)); 15262 15263 /* Fill handle for VTS info */ 15264 _BCM_FLEX_STAT_HANDLE_CLEAR(*vxlt_fsh); 15265 /* This next step is a bit abusive, but we don't have an accessor 15266 * which captures the full key description in the VLAN_XLATE table. */ 15267 _BCM_FLEX_STAT_HANDLE_COPY(*vxlt_fsh, vent); 15268 15269 return BCM_E_NONE; 15270 } 15271 15272 #endif /* BCM_TRIUMPH2_SUPPORT */ 15273 15274 /* 15275 * Function: 15276 * bcm_esw_vlan_translate_egress_stat_enable_set 15277 * Purpose: 15278 * Enable/disable collection of statistics on the indicated 15279 * egress VLAN translation. 15280 * Parameters: 15281 * unit - (IN) Unit number. 15282 * port_class - (IN) Group ID of ingress port 15283 * outer_vlan - (IN) Packet outer VLAN ID 15284 * inner_vlan - (IN) Packet inner VLAN ID 15285 * enable - (IN) Non-zero to enable counter collection, zero to disable. 15286 * Returns: 15287 * BCM_E_xxx 15288 * Notes: 15289 */ 15290 int 15291 bcm_esw_vlan_translate_egress_stat_enable_set(int unit, int port_class, 15292 bcm_vlan_t outer_vlan, 15293 bcm_vlan_t inner_vlan, 15294 int enable) 15295 { 15296 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT) 15297 _bcm_flex_stat_handle_t vxlt_fsh; 15298 #endif 15299 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15300 uint32 num_of_tables=0; 15301 uint32 num_stat_counter_ids=0; 15302 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 15303 bcm_stat_object_t object=bcmStatObjectIngPort; 15304 uint32 stat_counter_id[ 15305 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0}; 15306 uint32 num_entries=0; 15307 int index=0; 15308 #endif 15309 15310 #ifdef BCM_TOMAHAWK3_SUPPORT 15311 if (SOC_IS_TOMAHAWK3(unit)) { 15312 return BCM_E_UNAVAIL; 15313 } 15314 #endif 15315 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 15316 if (soc_feature(unit,soc_feature_gport_service_counters)) { 15317 BCM_IF_ERROR_RETURN 15318 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 15319 outer_vlan, inner_vlan, 15320 &vxlt_fsh)); 15321 return _bcm_esw_flex_stat_ext_enable_set(unit, _bcmFlexStatTypeVxlt, 15322 _bcm_esw_vlan_translate_egress_flex_stat_hw_index_set, 15323 NULL, vxlt_fsh, enable,0); 15324 } else 15325 #endif 15326 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15327 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 15328 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info( 15329 unit,port_class, 15330 outer_vlan,inner_vlan, 15331 &num_of_tables,&table_info[0])); 15332 if (enable) { 15333 for(index=0;index < num_of_tables ;index++) { 15334 if(table_info[index].direction == bcmStatFlexDirectionIngress) { 15335 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object( 15336 unit,table_info[index].table, 15337 table_info[index].index,NULL,&object)); 15338 } else { 15339 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object( 15340 unit,table_info[index].table, 15341 table_info[index].index,NULL,&object)); 15342 } 15343 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create( 15344 unit,object,bcmStatGroupModeSingle, 15345 &stat_counter_id[table_info[index].direction], 15346 &num_entries)); 15347 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_attach( 15348 unit,port_class,outer_vlan,inner_vlan, 15349 stat_counter_id[table_info[index].direction])); 15350 } 15351 return BCM_E_NONE; 15352 } else { 15353 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id( 15354 unit, num_of_tables,&table_info[0], 15355 &num_stat_counter_ids,&stat_counter_id[0])); 15356 if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) && 15357 (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) { 15358 return BCM_E_PARAM; 15359 } 15360 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_detach( 15361 unit,port_class,outer_vlan,inner_vlan)); 15362 if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) { 15363 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 15364 unit, 15365 stat_counter_id[bcmStatFlexDirectionIngress])); 15366 } 15367 if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) { 15368 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 15369 unit, 15370 stat_counter_id[bcmStatFlexDirectionEgress])); 15371 } 15372 return BCM_E_NONE; 15373 } 15374 } else 15375 #endif 15376 #if defined(BCM_HURRICANE3_SUPPORT) 15377 if (soc_feature(unit, soc_feature_flowcnt)) { 15378 return _bcm_hr3_vlan_translate_egress_stat_enable_set(unit, port_class, 15379 outer_vlan, inner_vlan, enable); 15380 15381 } else 15382 #endif 15383 { 15384 return BCM_E_UNAVAIL; 15385 }} 15386 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15387 /* 15388 * Function: 15389 * _bcm_esw_vlan_translate_egress_stat_get_table_info 15390 * Description: 15391 * Provides relevant flex table information(table-name,index with 15392 * direction) for given egress vlan translation 15393 * 15394 * Parameters: 15395 * unit - (IN) unit number 15396 * port_class - (IN) Port class 15397 * outer_vlan - (IN) Outer VLAN ID 15398 * inner_vlan - (IN) Inner VLAN ID 15399 * num_of_tables - (OUT) Number of flex counter tables 15400 * table_info - (OUT) Flex counter tables information 15401 * 15402 * Return Value: 15403 * BCM_E_XXX 15404 * Notes: 15405 */ 15406 static 15407 bcm_error_t _bcm_esw_vlan_translate_egress_stat_get_table_info( 15408 int unit, 15409 int port_class, 15410 bcm_vlan_t outer_vlan, 15411 bcm_vlan_t inner_vlan, 15412 uint32 *num_of_tables, 15413 bcm_stat_flex_table_info_t *table_info) 15414 { 15415 soc_mem_t mem = EGR_VLAN_XLATEm; 15416 bcm_error_t rv=BCM_E_NONE; 15417 uint32 vent[SOC_MAX_MEM_FIELD_WORDS]; 15418 uint32 return_vent[SOC_MAX_MEM_FIELD_WORDS]; 15419 int index=0; 15420 bcm_module_t modid=0; 15421 bcm_trunk_t tgid = -1; 15422 int id = -1; 15423 int handle_modport_gport = 0; 15424 15425 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) { 15426 mem = EGR_VLAN_XLATE_1_DOUBLEm; 15427 } 15428 if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) { 15429 handle_modport_gport = 1; 15430 } 15431 15432 (*num_of_tables) = 0; 15433 15434 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 15435 return BCM_E_UNAVAIL; 15436 } 15437 if (BCM_GPORT_IS_SET(port_class)) { 15438 if (!BCM_GPORT_IS_TUNNEL(port_class) && 15439 !BCM_GPORT_IS_VLAN_PORT(port_class) && 15440 !BCM_GPORT_IS_MIM_PORT(port_class) && 15441 !BCM_GPORT_IS_NIV_PORT(port_class) && 15442 !BCM_GPORT_IS_MPLS_PORT(port_class) && 15443 !BCM_GPORT_IS_VXLAN_PORT(port_class) && 15444 !BCM_GPORT_IS_EXTENDER_PORT(port_class) && 15445 !BCM_GPORT_IS_L2GRE_PORT(port_class) && 15446 !(handle_modport_gport && 15447 (BCM_GPORT_IS_MODPORT(port_class) || 15448 BCM_GPORT_IS_SUBPORT_PORT(port_class)))) { 15449 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve( 15450 unit, port_class, &modid, 15451 &port_class,&tgid, &id)); 15452 } 15453 if ((-1 != tgid || -1 != id) && 15454 !BCM_GPORT_IS_TUNNEL(port_class) && 15455 !BCM_GPORT_IS_VLAN_PORT(port_class) && 15456 !BCM_GPORT_IS_MIM_PORT(port_class) && 15457 !BCM_GPORT_IS_NIV_PORT(port_class) && 15458 !BCM_GPORT_IS_MPLS_PORT(port_class) && 15459 !BCM_GPORT_IS_VXLAN_PORT(port_class) && 15460 !BCM_GPORT_IS_EXTENDER_PORT(port_class) && 15461 !BCM_GPORT_IS_L2GRE_PORT(port_class) ) { 15462 return BCM_E_PORT; 15463 } 15464 } else { 15465 if (!SOC_PORT_CLASS_VALID(unit, port_class)) { 15466 return BCM_E_PORT; 15467 } 15468 } 15469 sal_memset(vent, 0, sizeof(vent)); 15470 sal_memset(return_vent, 0, sizeof(return_vent)); 15471 BCM_IF_ERROR_RETURN (_bcm_trx_vlan_translate_egress_entry_assemble( 15472 unit, vent, port_class, outer_vlan, inner_vlan)); 15473 soc_mem_lock(unit, mem); 15474 rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &index, vent, return_vent, 0); 15475 if (BCM_SUCCESS(rv)) { 15476 table_info[*num_of_tables].table=mem; 15477 table_info[*num_of_tables].index=index; 15478 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 15479 (*num_of_tables)++; 15480 } 15481 soc_mem_unlock(unit, mem); 15482 return rv; 15483 } 15484 #endif 15485 15486 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15487 /* 15488 * Function: 15489 * _bcm_esw_vlan_translate_egress_stat_attach 15490 * Description: 15491 * Attach counters for the given egress vlan translation table 15492 * 15493 * Parameters: 15494 * unit - (IN) unit number 15495 * port_class - (IN) Port class 15496 * outer_vlan - (IN) Outer VLAN ID 15497 * inner_vlan - (IN) Inner VLAN ID 15498 * Stat_counter_id - (IN) Stat Counter ID. 15499 * 15500 * Return Value: 15501 * BCM_E_XXX 15502 * Notes: 15503 */ 15504 STATIC bcm_error_t _bcm_esw_vlan_translate_egress_stat_attach( 15505 int unit, 15506 int port_class, 15507 bcm_vlan_t outer_vlan, 15508 bcm_vlan_t inner_vlan, 15509 uint32 stat_counter_id) 15510 { 15511 soc_mem_t table=0; 15512 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 15513 uint32 pool_number=0; 15514 uint32 base_index=0; 15515 bcm_stat_flex_mode_t offset_mode=0; 15516 bcm_stat_object_t object=bcmStatObjectIngPort; 15517 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 15518 uint32 count=0; 15519 uint32 actual_num_tables=0; 15520 uint32 num_of_tables=0; 15521 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 15522 15523 _bcm_esw_stat_get_counter_id_info( 15524 unit, stat_counter_id, 15525 &group_mode,&object,&offset_mode,&pool_number,&base_index); 15526 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction)); 15527 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode)); 15528 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 15529 unit,object,1,&actual_num_tables,&table,&direction)); 15530 15531 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info( 15532 unit, port_class,outer_vlan,inner_vlan, 15533 &num_of_tables,&table_info[0])); 15534 for (count=0; count < num_of_tables ; count++) { 15535 if ((table_info[count].direction == direction) && 15536 (table_info[count].table == table) ) { 15537 if (direction == bcmStatFlexDirectionIngress) { 15538 return _bcm_esw_stat_flex_attach_ingress_table_counters( 15539 unit, table_info[count].table, table_info[count].index, 15540 offset_mode, base_index, pool_number); 15541 } else { 15542 return _bcm_esw_stat_flex_attach_egress_table_counters( 15543 unit, table_info[count].table, table_info[count].index, 15544 0, offset_mode, base_index, pool_number); 15545 } 15546 } 15547 } 15548 return BCM_E_NOT_FOUND; 15549 } 15550 #endif 15551 15552 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 15553 STATIC bcm_error_t _tr2_vlan_translate_egress_stat_attach( 15554 int unit, 15555 int port_class, 15556 bcm_vlan_t outer_vlan, 15557 bcm_vlan_t inner_vlan, 15558 uint32 stat_counter_id, 15559 int attached) 15560 { 15561 _bcm_flex_stat_type_t fs_type; 15562 _bcm_flex_stat_handle_t vxlt_fsh; 15563 uint32 fs_inx; 15564 15565 fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id); 15566 fs_inx = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id); 15567 15568 if (!((fs_type == _bcmFlexStatTypeEgrVxlt) && fs_inx)) { 15569 return BCM_E_PARAM; 15570 } 15571 BCM_IF_ERROR_RETURN 15572 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 15573 outer_vlan, inner_vlan, 15574 &vxlt_fsh)); 15575 return _bcm_esw_flex_stat_ext_enable_set(unit, _bcmFlexStatTypeEgrVxlt, 15576 _bcm_esw_vlan_translate_egress_flex_stat_hw_index_set, 15577 INT_TO_PTR(_BCM_FLEX_STAT_HW_EGRESS), 15578 vxlt_fsh, attached,fs_inx); 15579 } 15580 #endif 15581 15582 /* 15583 * Function: 15584 * bcm_esw_vlan_translate_egress_stat_attach 15585 * Description: 15586 * Attach counters for the given egress vlan translation table 15587 * 15588 * Parameters: 15589 * unit - (IN) unit number 15590 * port_class - (IN) Port class 15591 * outer_vlan - (IN) Outer VLAN ID 15592 * inner_vlan - (IN) Inner VLAN ID 15593 * Stat_counter_id - (IN) Stat Counter ID. 15594 * 15595 * Return Value: 15596 * BCM_E_XXX 15597 * Notes: 15598 */ 15599 int bcm_esw_vlan_translate_egress_stat_attach( 15600 int unit, 15601 int port_class, 15602 bcm_vlan_t outer_vlan, 15603 bcm_vlan_t inner_vlan, 15604 uint32 stat_counter_id) 15605 { 15606 #ifdef BCM_TOMAHAWK3_SUPPORT 15607 if (SOC_IS_TOMAHAWK3(unit)) { 15608 return BCM_E_UNAVAIL; 15609 } 15610 #endif 15611 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15612 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 15613 return _bcm_esw_vlan_translate_egress_stat_attach(unit, 15614 port_class,outer_vlan,inner_vlan,stat_counter_id); 15615 } else 15616 #endif 15617 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 15618 if (soc_feature(unit,soc_feature_gport_service_counters)) { 15619 return _tr2_vlan_translate_egress_stat_attach(unit, 15620 port_class,outer_vlan,inner_vlan,stat_counter_id,TRUE); 15621 } else 15622 #endif 15623 #if defined(BCM_HURRICANE3_SUPPORT) 15624 if (soc_feature(unit, soc_feature_flowcnt)) { 15625 return _bcm_hr3_vlan_translate_egress_stat_attach(unit, 15626 port_class,outer_vlan,inner_vlan,stat_counter_id); 15627 } else 15628 #endif 15629 { 15630 return BCM_E_UNAVAIL; 15631 } 15632 } 15633 15634 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15635 /* 15636 * Function: 15637 * _bcm_esw_vlan_translate_egress_stat_detach 15638 * Description: 15639 * Detach counters for the given egress vlan translation table 15640 * 15641 * Parameters: 15642 * unit - (IN) unit number 15643 * port_class - (IN) Port class 15644 * outer_vlan - (IN) Outer VLAN ID 15645 * inner_vlan - (IN) Inner VLAN ID 15646 * 15647 * Return Value: 15648 * BCM_E_XXX 15649 * Notes: 15650 */ 15651 STATIC bcm_error_t _bcm_esw_vlan_translate_egress_stat_detach( 15652 int unit, 15653 int port_class, 15654 bcm_vlan_t outer_vlan, 15655 bcm_vlan_t inner_vlan) 15656 { 15657 uint32 count=0; 15658 uint32 num_of_tables=0; 15659 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 15660 bcm_error_t rv = BCM_E_NONE; 15661 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 15662 15663 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info( 15664 unit, port_class,outer_vlan,inner_vlan, 15665 &num_of_tables,&table_info[0])); 15666 15667 for (count=0; count < num_of_tables ; count++) { 15668 if (table_info[count].direction == bcmStatFlexDirectionIngress) { 15669 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 15670 unit, table_info[count].table, table_info[count].index); 15671 if (BCM_E_NONE != rv && 15672 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 15673 err_code[bcmStatFlexDirectionIngress] = rv; 15674 } 15675 } else { 15676 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 15677 unit, 0, table_info[count].table, table_info[count].index); 15678 if (BCM_E_NONE != rv && 15679 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 15680 err_code[bcmStatFlexDirectionEgress] = rv; 15681 } 15682 } 15683 } 15684 15685 BCM_STAT_FLEX_DETACH_RETURN(err_code) 15686 } 15687 #endif 15688 15689 /* 15690 * Function: 15691 * bcm_esw_vlan_translate_egress_stat_detach 15692 * Description: 15693 * Detach counters for the given egress vlan translation table 15694 * 15695 * Parameters: 15696 * unit - (IN) unit number 15697 * port_class - (IN) Port class 15698 * outer_vlan - (IN) Outer VLAN ID 15699 * inner_vlan - (IN) Inner VLAN ID 15700 * 15701 * Return Value: 15702 * BCM_E_XXX 15703 * Notes: 15704 */ 15705 int bcm_esw_vlan_translate_egress_stat_detach( 15706 int unit, 15707 int port_class, 15708 bcm_vlan_t outer_vlan, 15709 bcm_vlan_t inner_vlan) 15710 { 15711 #ifdef BCM_TOMAHAWK3_SUPPORT 15712 if (SOC_IS_TOMAHAWK3(unit)) { 15713 return BCM_E_UNAVAIL; 15714 } 15715 #endif 15716 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15717 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 15718 return _bcm_esw_vlan_translate_egress_stat_detach(unit, 15719 port_class,outer_vlan,inner_vlan); 15720 } else 15721 #endif 15722 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 15723 if (soc_feature(unit,soc_feature_gport_service_counters)) { 15724 return _tr2_vlan_translate_egress_stat_attach(unit, 15725 port_class,outer_vlan,inner_vlan, 15726 _BCM_FLEX_STAT_COUNT_ID(_bcmFlexStatTypeEgrVxlt,1),FALSE); 15727 } else 15728 #endif 15729 #if defined(BCM_HURRICANE3_SUPPORT) 15730 if (soc_feature(unit, soc_feature_flowcnt)) { 15731 return _bcm_hr3_vlan_translate_egress_stat_detach(unit, 15732 port_class,outer_vlan,inner_vlan); 15733 } else 15734 #endif 15735 { 15736 return BCM_E_UNAVAIL; 15737 } 15738 15739 } 15740 15741 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15742 /* 15743 * Function: 15744 * _bcm_esw_vlan_translate_egress_stat_counter_get 15745 * Description: 15746 * Get counter values from egress vlan translation table 15747 * if sync_mode is set, sync the sw accumulated count 15748 * with hw count value first, else return sw count. 15749 * 15750 * Parameters: 15751 * unit - (IN) unit number 15752 * sync_mode - (IN) hwcount is to be synced to sw count 15753 * port_class - (IN) Port class 15754 * outer_vlan - (IN) Outer VLAN ID 15755 * inner_vlan - (IN) Inner VLAN ID 15756 * stat - (IN) Type of the counter to retrieve 15757 * I.e. ingress/egress byte/packet) 15758 * num_entries - (IN) Number of counter Entries 15759 * counter_indexes - (IN) Pointer to Counter indexes entries 15760 * counter_values - (OUT) Pointer to counter values 15761 * 15762 * Return Value: 15763 * BCM_E_XXX 15764 * Notes: 15765 */ 15766 STATIC bcm_error_t _bcm_esw_vlan_translate_egress_stat_counter_get( 15767 int unit, 15768 int sync_mode, 15769 int port_class, 15770 bcm_vlan_t outer_vlan, 15771 bcm_vlan_t inner_vlan, 15772 bcm_vlan_stat_t stat, 15773 uint32 num_entries, 15774 uint32 *counter_indexes, 15775 bcm_stat_value_t *counter_values) 15776 { 15777 uint32 table_count=0; 15778 uint32 index_count=0; 15779 uint32 num_of_tables=0; 15780 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 15781 uint32 byte_flag=0; 15782 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 15783 15784 if ((stat == bcmVlanStatIngressPackets) || 15785 (stat == bcmVlanStatIngressBytes)) { 15786 direction = bcmStatFlexDirectionIngress; 15787 } else { 15788 direction = bcmStatFlexDirectionEgress; 15789 } 15790 if ((stat == bcmVlanStatIngressPackets) || 15791 (stat == bcmVlanStatEgressPackets)) { 15792 byte_flag=0; 15793 } else { 15794 byte_flag=1; 15795 } 15796 15797 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info( 15798 unit, port_class,outer_vlan,inner_vlan, 15799 &num_of_tables,&table_info[0])); 15800 15801 for (table_count=0; table_count < num_of_tables ; table_count++) { 15802 if (table_info[table_count].direction == direction) { 15803 for (index_count=0; index_count < num_entries ; index_count++) { 15804 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get( 15805 unit, sync_mode, 15806 table_info[table_count].index, 15807 table_info[table_count].table, 0, 15808 byte_flag, 15809 counter_indexes[index_count], 15810 &counter_values[index_count])); 15811 } 15812 } 15813 } 15814 return BCM_E_NONE; 15815 } 15816 #endif 15817 15818 /* 15819 * Function: 15820 * _bcm_esw_vlan_xslate_egress_stat_counter_get 15821 * Description: 15822 * Get counter values from egress vlan translation table 15823 * if sync_mode is set, sync the sw accumulated count 15824 * with hw count value first, else return sw count. 15825 * 15826 * Parameters: 15827 * unit - (IN) unit number 15828 * sync_mode - (IN) hwcount is to be synced to sw count 15829 * port_cLass - (IN) Port class 15830 * outer_vlan - (IN) Outer VLAN ID 15831 * inner_vlan - (IN) Inner VLAN ID 15832 * stat - (IN) Type of the counter to retrieve 15833 * I.e. ingress/egress byte/packet) 15834 * num_entries - (IN) Number of counter Entries 15835 * counter_indexes - (IN) Pointer to Counter indexes entries 15836 * counter_values - (OUT) Pointer to counter values 15837 * 15838 * Return Value: 15839 * BCM_E_XXX 15840 * Notes: 15841 */ 15842 int 15843 _bcm_esw_vlan_xslate_egress_stat_counter_get( 15844 int unit, 15845 int sync_mode, 15846 int port_class, 15847 bcm_vlan_t outer_vlan, 15848 bcm_vlan_t inner_vlan, 15849 bcm_vlan_stat_t stat, 15850 uint32 num_entries, 15851 uint32 *counter_indexes, 15852 bcm_stat_value_t *counter_values) 15853 { 15854 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15855 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 15856 return _bcm_esw_vlan_translate_egress_stat_counter_get(unit, sync_mode, 15857 port_class,outer_vlan,inner_vlan,stat, 15858 num_entries,counter_indexes,counter_values); 15859 } else 15860 #endif 15861 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 15862 if (soc_feature(unit,soc_feature_gport_service_counters)) { 15863 uint64 val; 15864 _bcm_flex_stat_handle_t vxlt_fsh; 15865 int rv = BCM_E_NONE; 15866 15867 BCM_IF_ERROR_RETURN 15868 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 15869 outer_vlan, inner_vlan, &vxlt_fsh)); 15870 15871 rv = _bcm_esw_flex_stat_ext_get(unit, 0, _bcmFlexStatTypeEgrVxlt, 15872 vxlt_fsh, 15873 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat), &val); 15874 15875 if (stat == bcmVlanStatEgressPackets) { 15876 counter_values->packets = COMPILER_64_LO(val); 15877 } else { 15878 COMPILER_64_SET(counter_values->bytes, 15879 COMPILER_64_HI(val), 15880 COMPILER_64_LO(val)); 15881 } 15882 return rv; 15883 15884 } else 15885 #endif 15886 #if defined(BCM_HURRICANE3_SUPPORT) 15887 if (soc_feature(unit, soc_feature_flowcnt)) { 15888 return _bcm_hr3_vlan_translate_egress_stat_counter_get(unit, sync_mode, 15889 port_class, outer_vlan, inner_vlan, stat, num_entries, 15890 counter_indexes, counter_values); 15891 } else 15892 #endif 15893 { 15894 return BCM_E_UNAVAIL; 15895 } 15896 } 15897 15898 15899 /* 15900 * Function: 15901 * bcm_esw_vlan_translate_egress_stat_counter_get 15902 * Description: 15903 * Get counter values from egress vlan translation table 15904 * 15905 * Parameters: 15906 * unit - (IN) unit number 15907 * port_class - (IN) Port class 15908 * outer_vlan - (IN) Outer VLAN ID 15909 * inner_vlan - (IN) Inner VLAN ID 15910 * stat - (IN) Type of the counter to retrieve 15911 * I.e. ingress/egress byte/packet) 15912 * num_entries - (IN) Number of counter Entries 15913 * counter_indexes - (IN) Pointer to Counter indexes entries 15914 * counter_values - (OUT) Pointer to counter values 15915 * 15916 * Return Value: 15917 * BCM_E_XXX 15918 * Notes: 15919 */ 15920 int 15921 bcm_esw_vlan_translate_egress_stat_counter_get( 15922 int unit, 15923 int port_class, 15924 bcm_vlan_t outer_vlan, 15925 bcm_vlan_t inner_vlan, 15926 bcm_vlan_stat_t stat, 15927 uint32 num_entries, 15928 uint32 *counter_indexes, 15929 bcm_stat_value_t *counter_values) 15930 { 15931 #ifdef BCM_TOMAHAWK3_SUPPORT 15932 if (SOC_IS_TOMAHAWK3(unit)) { 15933 return BCM_E_UNAVAIL; 15934 } 15935 #endif 15936 return _bcm_esw_vlan_xslate_egress_stat_counter_get(unit, 0, port_class, 15937 outer_vlan, inner_vlan, 15938 stat, num_entries, 15939 counter_indexes, 15940 counter_values); 15941 } 15942 15943 15944 /* 15945 * Function: 15946 * bcm_esw_vlan_translate_egress_stat_counter_sync_get 15947 * Description: 15948 * Get counter values from egress vlan translation table 15949 * sw accumulated counters synced with hw count. 15950 * 15951 * Parameters: 15952 * unit - (IN) unit number 15953 * port_class - (IN) Port class 15954 * outer_vlan - (IN) Outer VLAN ID 15955 * inner_vlan - (IN) Inner VLAN ID 15956 * stat - (IN) Type of the counter to retrieve 15957 * I.e. ingress/egress byte/packet) 15958 * num_entries - (IN) Number of counter Entries 15959 * counter_indexes - (IN) Pointer to Counter indexes entries 15960 * counter_values - (OUT) Pointer to counter values 15961 * 15962 * Return Value: 15963 * BCM_E_XXX 15964 * Notes: 15965 */ 15966 int 15967 bcm_esw_vlan_translate_egress_stat_counter_sync_get( 15968 int unit, 15969 int port_class, 15970 bcm_vlan_t outer_vlan, 15971 bcm_vlan_t inner_vlan, 15972 bcm_vlan_stat_t stat, 15973 uint32 num_entries, 15974 uint32 *counter_indexes, 15975 bcm_stat_value_t *counter_values) 15976 { 15977 #ifdef BCM_TOMAHAWK3_SUPPORT 15978 if (SOC_IS_TOMAHAWK3(unit)) { 15979 return BCM_E_UNAVAIL; 15980 } 15981 #endif 15982 return _bcm_esw_vlan_xslate_egress_stat_counter_get(unit, 1, port_class, 15983 outer_vlan, inner_vlan, 15984 stat, num_entries, 15985 counter_indexes, 15986 counter_values); 15987 } 15988 15989 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15990 /* 15991 * Function: 15992 * _bcm_esw_vlan_translate_egress_stat_counter_set 15993 * Description: 15994 * Set counter values from egress vlan translation table . 15995 * 15996 * Parameters: 15997 * unit - (IN) unit number 15998 * port_class - (IN) Port class 15999 * outer_vlan - (IN) Outer VLAN ID 16000 * inner_vlan - (IN) Inner VLAN ID 16001 * stat - (IN) Type of the counter to retrieve 16002 * I.e. ingress/egress byte/packet) 16003 * num_entries - (IN) Number of counter Entries 16004 * counter_indexes - (IN) Pointer to Counter indexes entries 16005 * counter_values - (IN) Pointer to counter values 16006 * 16007 * Return Value: 16008 * BCM_E_XXX 16009 * Notes: 16010 */ 16011 STATIC bcm_error_t _bcm_esw_vlan_translate_egress_stat_counter_set( 16012 int unit, 16013 int port_class, 16014 bcm_vlan_t outer_vlan, 16015 bcm_vlan_t inner_vlan, 16016 bcm_vlan_stat_t stat, 16017 uint32 num_entries, 16018 uint32 *counter_indexes, 16019 bcm_stat_value_t *counter_values) 16020 { 16021 uint32 table_count=0; 16022 uint32 index_count=0; 16023 uint32 num_of_tables=0; 16024 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 16025 uint32 byte_flag=0; 16026 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 16027 16028 if ((stat == bcmVlanStatIngressPackets) || 16029 (stat == bcmVlanStatIngressBytes)) { 16030 direction = bcmStatFlexDirectionIngress; 16031 } else { 16032 direction = bcmStatFlexDirectionEgress; 16033 } 16034 if ((stat == bcmVlanStatIngressPackets) || 16035 (stat == bcmVlanStatEgressPackets)) { 16036 byte_flag=0; 16037 } else { 16038 byte_flag=1; 16039 } 16040 16041 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info( 16042 unit, port_class,outer_vlan,inner_vlan, 16043 &num_of_tables,&table_info[0])); 16044 16045 for (table_count=0; table_count < num_of_tables ; table_count++) { 16046 if (table_info[table_count].direction == direction) { 16047 for (index_count=0; index_count < num_entries ; index_count++) { 16048 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set( 16049 unit, table_info[table_count].index, 16050 table_info[table_count].table, 0, 16051 byte_flag, 16052 counter_indexes[index_count], 16053 &counter_values[index_count])); 16054 } 16055 } 16056 } 16057 return BCM_E_NONE; 16058 } 16059 #endif 16060 16061 /* 16062 * Function: 16063 * bcm_esw_vlan_translate_egress_stat_counter_set 16064 * Description: 16065 * Set counter values from egress vlan translation table . 16066 * 16067 * Parameters: 16068 * unit - (IN) unit number 16069 * port_class - (IN) Port class 16070 * outer_vlan - (IN) Outer VLAN ID 16071 * inner_vlan - (IN) Inner VLAN ID 16072 * stat - (IN) Type of the counter to retrieve 16073 * I.e. ingress/egress byte/packet) 16074 * num_entries - (IN) Number of counter Entries 16075 * counter_indexes - (IN) Pointer to Counter indexes entries 16076 * counter_values - (IN) Pointer to counter values 16077 * 16078 * Return Value: 16079 * BCM_E_XXX 16080 * Notes: 16081 */ 16082 int bcm_esw_vlan_translate_egress_stat_counter_set( 16083 int unit, 16084 int port_class, 16085 bcm_vlan_t outer_vlan, 16086 bcm_vlan_t inner_vlan, 16087 bcm_vlan_stat_t stat, 16088 uint32 num_entries, 16089 uint32 *counter_indexes, 16090 bcm_stat_value_t *counter_values) 16091 { 16092 #ifdef BCM_TOMAHAWK3_SUPPORT 16093 if (SOC_IS_TOMAHAWK3(unit)) { 16094 return BCM_E_UNAVAIL; 16095 } 16096 #endif 16097 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 16098 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 16099 return _bcm_esw_vlan_translate_egress_stat_counter_set(unit, 16100 port_class,outer_vlan,inner_vlan,stat, 16101 num_entries,counter_indexes,counter_values); 16102 } else 16103 #endif 16104 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16105 if (soc_feature(unit,soc_feature_gport_service_counters)) { 16106 uint64 val; 16107 _bcm_flex_stat_handle_t vxlt_fsh; 16108 int rv = BCM_E_NONE; 16109 16110 BCM_IF_ERROR_RETURN 16111 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 16112 outer_vlan, inner_vlan, &vxlt_fsh)); 16113 if (stat == bcmVlanStatEgressPackets) { 16114 COMPILER_64_SET(val,0,counter_values->packets); 16115 } else { 16116 COMPILER_64_SET(val, 16117 COMPILER_64_HI(counter_values->bytes), 16118 COMPILER_64_LO(counter_values->bytes)); 16119 } 16120 16121 rv = _bcm_esw_flex_stat_ext_set(unit,_bcmFlexStatTypeEgrVxlt, 16122 vxlt_fsh, 16123 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat), val); 16124 16125 return rv; 16126 16127 } else 16128 #endif 16129 #if defined(BCM_HURRICANE3_SUPPORT) 16130 if (soc_feature(unit, soc_feature_flowcnt)) { 16131 return _bcm_hr3_vlan_translate_egress_stat_counter_set(unit, 16132 port_class,outer_vlan,inner_vlan,stat, 16133 num_entries,counter_indexes,counter_values); 16134 } else 16135 #endif 16136 { 16137 return BCM_E_UNAVAIL; 16138 } 16139 } 16140 16141 /* 16142 * Function: 16143 * bcm_esw_vlan_translate_egress_stat_id_get 16144 * Description: 16145 * Get stat counter id associated with given egress vlan 16146 * 16147 * Parameters: 16148 * unit - (IN) unit number 16149 * port_class - (IN) Port class 16150 * outer_vlan - (IN) Outer VLAN ID 16151 * inner_vlan - (IN) Inner VLAN ID 16152 * stat - (IN) Type of the counter to retrieve 16153 * I.e. ingress/egress byte/packet) 16154 * Stat_counter_id - (OUT) Stat Counter ID 16155 * 16156 * Return Value: 16157 * BCM_E_XXX 16158 * Notes: 16159 */ 16160 int bcm_esw_vlan_translate_egress_stat_id_get( 16161 int unit, 16162 int port_class, 16163 bcm_vlan_t outer_vlan, 16164 bcm_vlan_t inner_vlan, 16165 bcm_vlan_stat_t stat, 16166 uint32 *stat_counter_id) 16167 { 16168 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 16169 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 16170 uint32 num_of_tables=0; 16171 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 16172 uint32 index=0; 16173 uint32 num_stat_counter_ids=0; 16174 #endif 16175 16176 #ifdef BCM_TOMAHAWK3_SUPPORT 16177 if (SOC_IS_TOMAHAWK3(unit)) { 16178 return BCM_E_UNAVAIL; 16179 } 16180 #endif 16181 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 16182 if (soc_feature(unit, soc_feature_advanced_flex_counter)) { 16183 if ((stat == bcmVlanStatIngressPackets) || 16184 (stat == bcmVlanStatIngressBytes)) { 16185 direction = bcmStatFlexDirectionIngress; 16186 } else { 16187 direction = bcmStatFlexDirectionEgress; 16188 } 16189 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info( 16190 unit, port_class,outer_vlan,inner_vlan, 16191 &num_of_tables,&table_info[0])); 16192 16193 for (index=0; index < num_of_tables ; index++) { 16194 if (table_info[index].direction == direction) 16195 return _bcm_esw_stat_flex_get_counter_id( 16196 unit, 1, &table_info[index], 16197 &num_stat_counter_ids,stat_counter_id); 16198 } 16199 return BCM_E_NOT_FOUND; 16200 } else 16201 #endif 16202 #if defined(BCM_HURRICANE3_SUPPORT) 16203 if (soc_feature(unit, soc_feature_flowcnt)) { 16204 return _bcm_hr3_vlan_translate_egress_stat_id_get(unit, port_class, 16205 outer_vlan, inner_vlan, stat, stat_counter_id); 16206 } else 16207 #endif 16208 { 16209 return BCM_E_UNAVAIL; 16210 } 16211 } 16212 16213 /* 16214 * Function: 16215 * _bcm_esw_vlan_translate_egress_stat_get 16216 * Purpose: 16217 * Extract egress VLAN translation statistics from the chip. 16218 * if sync_mode is set, sync the sw accumulated count 16219 * with hw count value first, else return sw count. 16220 * 16221 * Parameters: 16222 * unit - (IN) Unit number. 16223 * sync_mode - (IN) hwcount is to be synced to sw count 16224 * port_class - (IN) Group ID of ingress port 16225 * outer_vlan - (IN) Packet outer VLAN ID 16226 * inner_vlan - (IN) Packet inner VLAN ID 16227 * stat - (IN) Type of the counter to retrieve. 16228 * val - (OUT) Pointer to a counter value. 16229 * Returns: 16230 * BCM_E_xxx 16231 * Notes: 16232 */ 16233 int 16234 _bcm_esw_vlan_translate_egress_stat_get(int unit, int sync_mode, 16235 int port_class, 16236 bcm_vlan_t outer_vlan, 16237 bcm_vlan_t inner_vlan, 16238 bcm_vlan_stat_t stat, 16239 uint64 *val) 16240 { 16241 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT) 16242 _bcm_flex_stat_handle_t vxlt_fsh; 16243 #endif 16244 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) ||\ 16245 defined(BCM_HURRICANE3_SUPPORT) 16246 uint32 counter_indexes=0; 16247 bcm_stat_value_t counter_values={0}; 16248 #endif 16249 16250 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16251 if (soc_feature(unit, soc_feature_gport_service_counters)) { 16252 BCM_IF_ERROR_RETURN 16253 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 16254 outer_vlan, inner_vlan, 16255 &vxlt_fsh)); 16256 return _bcm_esw_flex_stat_ext_get(unit, sync_mode, _bcmFlexStatTypeVxlt, 16257 vxlt_fsh, 16258 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat), 16259 val); 16260 } else 16261 #endif 16262 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16263 defined(BCM_HURRICANE3_SUPPORT) 16264 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 16265 soc_feature(unit, soc_feature_flowcnt)) { 16266 BCM_IF_ERROR_RETURN( 16267 _bcm_esw_vlan_xslate_egress_stat_counter_get( 16268 unit, sync_mode, port_class, outer_vlan, inner_vlan, 16269 stat, 1, &counter_indexes, &counter_values)); 16270 if ((stat == bcmVlanStatIngressPackets) || 16271 (stat == bcmVlanStatEgressPackets)) { 16272 COMPILER_64_SET(*val,0,counter_values.packets); 16273 } else { 16274 COMPILER_64_SET(*val, 16275 COMPILER_64_HI(counter_values.bytes), 16276 COMPILER_64_LO(counter_values.bytes)); 16277 } 16278 return BCM_E_NONE; 16279 } else 16280 #endif 16281 { 16282 return BCM_E_UNAVAIL; 16283 } 16284 } 16285 16286 /* 16287 * Function: 16288 * bcm_esw_vlan_translate_egress_stat_get 16289 * Purpose: 16290 * Extract egress VLAN translation statistics from the chip. 16291 * Parameters: 16292 * unit - (IN) Unit number. 16293 * port_class - (IN) Group ID of ingress port 16294 * outer_vlan - (IN) Packet outer VLAN ID 16295 * inner_vlan - (IN) Packet inner VLAN ID 16296 * stat - (IN) Type of the counter to retrieve. 16297 * val - (OUT) Pointer to a counter value. 16298 * Returns: 16299 * BCM_E_xxx 16300 * Notes: 16301 */ 16302 int 16303 bcm_esw_vlan_translate_egress_stat_get(int unit, int port_class, 16304 bcm_vlan_t outer_vlan, 16305 bcm_vlan_t inner_vlan, 16306 bcm_vlan_stat_t stat, 16307 uint64 *val) 16308 { 16309 int rv = BCM_E_NONE; 16310 16311 #ifdef BCM_TOMAHAWK3_SUPPORT 16312 if (SOC_IS_TOMAHAWK3(unit)) { 16313 return BCM_E_UNAVAIL; 16314 } 16315 #endif 16316 rv = _bcm_esw_vlan_translate_egress_stat_get(unit, 0, port_class, 16317 outer_vlan, inner_vlan, 16318 stat, val); 16319 return rv; 16320 } 16321 16322 /* 16323 * Function: 16324 * bcm_esw_vlan_translate_egress_stat_sync_get 16325 * Purpose: 16326 * Extract egress VLAN translation statistics from the chip. 16327 * sw accumulated counters synced with hw count. 16328 * 16329 * Parameters: 16330 * unit - (IN) Unit number. 16331 * port_class - (IN) Group ID of ingress port 16332 * outer_vlan - (IN) Packet outer VLAN ID 16333 * inner_vlan - (IN) Packet inner VLAN ID 16334 * stat - (IN) Type of the counter to retrieve. 16335 * val - (OUT) Pointer to a counter value. 16336 * Returns: 16337 * BCM_E_xxx 16338 * Notes: 16339 */ 16340 int 16341 bcm_esw_vlan_translate_egress_stat_sync_get(int unit, int port_class, 16342 bcm_vlan_t outer_vlan, 16343 bcm_vlan_t inner_vlan, 16344 bcm_vlan_stat_t stat, 16345 uint64 *val) 16346 { 16347 int rv = BCM_E_NONE; 16348 16349 #ifdef BCM_TOMAHAWK3_SUPPORT 16350 if (SOC_IS_TOMAHAWK3(unit)) { 16351 return BCM_E_UNAVAIL; 16352 } 16353 #endif 16354 rv = _bcm_esw_vlan_translate_egress_stat_get(unit, 1, port_class, 16355 outer_vlan, inner_vlan, 16356 stat, val); 16357 return rv; 16358 } 16359 16360 /* 16361 * Function: 16362 * _bcm_esw_vlan_translate_egress_stat_get32 16363 * Purpose: 16364 * Extract egress VLAN translation statistics from the chip. 16365 * if sync_mode is set, sync the sw accumulated count 16366 * with hw count value first, else return sw count. 16367 * 16368 * Parameters: 16369 * unit - (IN) Unit number. 16370 * sync_mode - (IN) hwcount is to be synced to sw count 16371 * port_class - (IN) Group ID of ingress port 16372 * outer_vlan - (IN) Packet outer VLAN ID 16373 * inner_vlan - (IN) Packet inner VLAN ID 16374 * stat - (IN) Type of the counter to retrieve. 16375 * val - (OUT) Pointer to a counter value. 16376 * Returns: 16377 * BCM_E_xxx 16378 * Notes: 16379 */ 16380 int 16381 _bcm_esw_vlan_translate_egress_stat_get32(int unit, int sync_mode, 16382 int port_class, 16383 bcm_vlan_t outer_vlan, 16384 bcm_vlan_t inner_vlan, 16385 bcm_vlan_stat_t stat, 16386 uint32 *val) 16387 { 16388 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT) 16389 _bcm_flex_stat_handle_t vxlt_fsh; 16390 #endif 16391 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16392 defined(BCM_HURRICANE3_SUPPORT) 16393 uint32 counter_indexes=0; 16394 bcm_stat_value_t counter_values={0}; 16395 #endif 16396 16397 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16398 if (soc_feature(unit, soc_feature_gport_service_counters)) { 16399 BCM_IF_ERROR_RETURN 16400 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 16401 outer_vlan, inner_vlan, 16402 &vxlt_fsh)); 16403 return _bcm_esw_flex_stat_ext_get32(unit, sync_mode, 16404 _bcmFlexStatTypeVxlt, vxlt_fsh, 16405 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat), 16406 val); 16407 } else 16408 #endif 16409 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16410 defined(BCM_HURRICANE3_SUPPORT) 16411 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 16412 soc_feature(unit, soc_feature_flowcnt)) { 16413 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_xslate_egress_stat_counter_get( 16414 unit, sync_mode, port_class, outer_vlan, inner_vlan, 16415 stat, 1, &counter_indexes, &counter_values)); 16416 if ((stat == bcmVlanStatIngressPackets) || 16417 (stat == bcmVlanStatEgressPackets)) { 16418 *val = counter_values.packets; 16419 } else { 16420 /* Ignoring Hi bytes value */ 16421 *val = COMPILER_64_LO(counter_values.bytes); 16422 } 16423 return BCM_E_NONE; 16424 } else 16425 #endif 16426 { 16427 return BCM_E_UNAVAIL; 16428 } 16429 } 16430 16431 16432 /* 16433 * Function: 16434 * bcm_esw_vlan_translate_egress_stat_get32 16435 * Purpose: 16436 * Extract egress VLAN translation statistics from the chip. 16437 * Parameters: 16438 * unit - (IN) Unit number. 16439 * port_class - (IN) Group ID of ingress port 16440 * outer_vlan - (IN) Packet outer VLAN ID 16441 * inner_vlan - (IN) Packet inner VLAN ID 16442 * stat - (IN) Type of the counter to retrieve. 16443 * val - (OUT) Pointer to a counter value. 16444 * Returns: 16445 * BCM_E_xxx 16446 * Notes: 16447 */ 16448 int 16449 bcm_esw_vlan_translate_egress_stat_get32(int unit, int port_class, 16450 bcm_vlan_t outer_vlan, 16451 bcm_vlan_t inner_vlan, 16452 bcm_vlan_stat_t stat, 16453 uint32 *val) 16454 { 16455 int rv = BCM_E_NONE; 16456 16457 #ifdef BCM_TOMAHAWK3_SUPPORT 16458 if (SOC_IS_TOMAHAWK3(unit)) { 16459 return BCM_E_UNAVAIL; 16460 } 16461 #endif 16462 rv = _bcm_esw_vlan_translate_egress_stat_get32(unit, 0, port_class, 16463 outer_vlan, inner_vlan, 16464 stat, val); 16465 return rv; 16466 } 16467 16468 /* 16469 * Function: 16470 * bcm_esw_vlan_translate_egress_stat_sync_get32 16471 * Purpose: 16472 * Extract egress VLAN translation statistics from the chip. 16473 * sw accumulated counters synced with hw count. 16474 * 16475 * Parameters: 16476 * unit - (IN) Unit number. 16477 * port_class - (IN) Group ID of ingress port 16478 * outer_vlan - (IN) Packet outer VLAN ID 16479 * inner_vlan - (IN) Packet inner VLAN ID 16480 * stat - (IN) Type of the counter to retrieve. 16481 * val - (OUT) Pointer to a counter value. 16482 * Returns: 16483 * BCM_E_xxx 16484 * Notes: 16485 */ 16486 int 16487 bcm_esw_vlan_translate_egress_stat_sync_get32(int unit, int port_class, 16488 bcm_vlan_t outer_vlan, 16489 bcm_vlan_t inner_vlan, 16490 bcm_vlan_stat_t stat, 16491 uint32 *val) 16492 { 16493 int rv = BCM_E_NONE; 16494 16495 #ifdef BCM_TOMAHAWK3_SUPPORT 16496 if (SOC_IS_TOMAHAWK3(unit)) { 16497 return BCM_E_UNAVAIL; 16498 } 16499 #endif 16500 rv = _bcm_esw_vlan_translate_egress_stat_get32(unit, 1, port_class, 16501 outer_vlan, inner_vlan, 16502 stat, val); 16503 return rv; 16504 } 16505 16506 /* 16507 * Function: 16508 * bcm_esw_vlan_translate_egress_stat_set 16509 * Purpose: 16510 * Set the specified statistic to the indicated value for the 16511 * specified egress VLAN translation. 16512 * Parameters: 16513 * unit - (IN) Unit number. 16514 * port_class - (IN) Group ID of ingress port 16515 * outer_vlan - (IN) Packet outer VLAN ID 16516 * inner_vlan - (IN) Packet inner VLAN ID 16517 * stat - (IN) Type of the counter to set. 16518 * val - (IN) New counter value. 16519 * Returns: 16520 * BCM_E_xxx 16521 * Notes: 16522 */ 16523 int 16524 bcm_esw_vlan_translate_egress_stat_set(int unit, 16525 int port_class, 16526 bcm_vlan_t outer_vlan, 16527 bcm_vlan_t inner_vlan, 16528 bcm_vlan_stat_t stat, 16529 uint64 val) 16530 { 16531 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT) 16532 _bcm_flex_stat_handle_t vxlt_fsh; 16533 #endif 16534 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16535 defined(BCM_HURRICANE3_SUPPORT) 16536 uint32 counter_indexes=0; 16537 bcm_stat_value_t counter_values={0}; 16538 #endif 16539 16540 #ifdef BCM_TOMAHAWK3_SUPPORT 16541 if (SOC_IS_TOMAHAWK3(unit)) { 16542 return BCM_E_UNAVAIL; 16543 } 16544 #endif 16545 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16546 if (soc_feature(unit, soc_feature_gport_service_counters)) { 16547 BCM_IF_ERROR_RETURN 16548 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 16549 outer_vlan, inner_vlan, 16550 &vxlt_fsh)); 16551 return _bcm_esw_flex_stat_ext_set(unit, _bcmFlexStatTypeVxlt, 16552 vxlt_fsh, 16553 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat), 16554 val); 16555 } else 16556 #endif 16557 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16558 defined(BCM_HURRICANE3_SUPPORT) 16559 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 16560 soc_feature(unit, soc_feature_flowcnt)) { 16561 if ((stat == bcmVlanStatIngressPackets) || 16562 (stat == bcmVlanStatEgressPackets)) { 16563 counter_values.packets = COMPILER_64_LO(val); 16564 } else { 16565 COMPILER_64_SET(counter_values.bytes, 16566 COMPILER_64_HI(val), 16567 COMPILER_64_LO(val)); 16568 } 16569 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_set( 16570 unit,port_class,outer_vlan,inner_vlan, 16571 stat, 1, &counter_indexes, &counter_values)); 16572 return BCM_E_NONE; 16573 } else 16574 #endif 16575 { 16576 return BCM_E_UNAVAIL; 16577 } 16578 } 16579 16580 /* 16581 * Function: 16582 * bcm_esw_vlan_translate_egress_stat_set32 16583 * Purpose: 16584 * Set the specified statistic to the indicated value for the 16585 * specified egress VLAN translation. 16586 * Parameters: 16587 * unit - (IN) Unit number. 16588 * port_class - (IN) Group ID of ingress port 16589 * outer_vlan - (IN) Packet outer VLAN ID 16590 * inner_vlan - (IN) Packet inner VLAN ID 16591 * stat - (IN) Type of the counter to set. 16592 * val - (IN) New counter value. 16593 * Returns: 16594 * BCM_E_xxx 16595 * Notes: 16596 */ 16597 int 16598 bcm_esw_vlan_translate_egress_stat_set32(int unit, int port_class, 16599 bcm_vlan_t outer_vlan, 16600 bcm_vlan_t inner_vlan, 16601 bcm_vlan_stat_t stat, 16602 uint32 val) 16603 { 16604 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT) 16605 _bcm_flex_stat_handle_t vxlt_fsh; 16606 #endif 16607 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16608 defined(BCM_HURRICANE3_SUPPORT) 16609 uint32 counter_indexes=0; 16610 bcm_stat_value_t counter_values={0}; 16611 #endif 16612 16613 #ifdef BCM_TOMAHAWK3_SUPPORT 16614 if (SOC_IS_TOMAHAWK3(unit)) { 16615 return BCM_E_UNAVAIL; 16616 } 16617 #endif 16618 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16619 if (soc_feature(unit, soc_feature_gport_service_counters)) { 16620 BCM_IF_ERROR_RETURN 16621 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 16622 outer_vlan, inner_vlan, 16623 &vxlt_fsh)); 16624 return _bcm_esw_flex_stat_ext_set32(unit, _bcmFlexStatTypeVxlt, 16625 vxlt_fsh, 16626 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat), 16627 val); 16628 } else 16629 #endif 16630 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16631 defined(BCM_HURRICANE3_SUPPORT) 16632 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 16633 soc_feature(unit, soc_feature_flowcnt)) { 16634 if ((stat == bcmVlanStatIngressPackets) || 16635 (stat == bcmVlanStatEgressPackets)) { 16636 counter_values.packets = val; 16637 } else { 16638 /* Ignoring high value */ 16639 COMPILER_64_SET(counter_values.bytes,0,val); 16640 } 16641 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_set( 16642 unit,port_class,outer_vlan,inner_vlan, 16643 stat, 1, &counter_indexes, &counter_values)); 16644 return BCM_E_NONE; 16645 } else 16646 #endif 16647 { 16648 return BCM_E_UNAVAIL; 16649 } 16650 } 16651 16652 /* 16653 * Function: 16654 * bcm_esw_vlan_translate_egress_stat_multi_get 16655 * Purpose: 16656 * Get 64-bit counter value for multiple egress VLAN translation 16657 * statistic types. 16658 * Parameters: 16659 * unit - (IN) Unit number. 16660 * port_class - (IN) Group ID of ingress port 16661 * outer_vlan - (IN) Packet outer VLAN ID 16662 * inner_vlan - (IN) Packet inner VLAN ID 16663 * nstat - (IN) Number of elements in stat array 16664 * stat_arr - (IN) Collected statistics descriptors array 16665 * value_arr - (OUT) Collected counters values 16666 * Returns: 16667 * BCM_E_xxx 16668 * Notes: 16669 */ 16670 int 16671 bcm_esw_vlan_translate_egress_stat_multi_get(int unit, int port_class, 16672 bcm_vlan_t outer_vlan, 16673 bcm_vlan_t inner_vlan, 16674 int nstat, 16675 bcm_vlan_stat_t *stat_arr, 16676 uint64 *value_arr) 16677 { 16678 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16679 _bcm_flex_stat_handle_t vxlt_fsh; 16680 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 16681 int idx; 16682 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16683 defined(BCM_HURRICANE3_SUPPORT) 16684 uint32 counter_indexes=0; 16685 bcm_stat_value_t counter_values={0}; 16686 #endif 16687 16688 #ifdef BCM_TOMAHAWK3_SUPPORT 16689 if (SOC_IS_TOMAHAWK3(unit)) { 16690 return BCM_E_UNAVAIL; 16691 } 16692 #endif 16693 if (soc_feature(unit, soc_feature_gport_service_counters)) { 16694 BCM_IF_ERROR_RETURN 16695 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 16696 outer_vlan, inner_vlan, 16697 &vxlt_fsh)); 16698 BCM_IF_ERROR_RETURN 16699 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr, 16700 &_bcm_esw_vlan_translate_egress_stat_to_flex_stat)); 16701 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 16702 16703 return _bcm_esw_flex_stat_ext_multi_get(unit, _bcmFlexStatTypeVxlt, 16704 vxlt_fsh, 16705 nstat, fs_arr, value_arr); 16706 } else 16707 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16708 defined(BCM_HURRICANE3_SUPPORT) 16709 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 16710 soc_feature(unit, soc_feature_flowcnt)) { 16711 for (idx=0;idx < nstat ; idx ++) { 16712 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_get( 16713 unit,port_class,outer_vlan,inner_vlan, 16714 stat_arr[idx],1,&counter_indexes,&counter_values)); 16715 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 16716 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 16717 16718 COMPILER_64_SET(value_arr[idx], 16719 COMPILER_64_HI(counter_values.packets64), 16720 COMPILER_64_LO(counter_values.packets64)); 16721 } else { 16722 COMPILER_64_SET(value_arr[idx], 16723 COMPILER_64_HI(counter_values.bytes), 16724 COMPILER_64_LO(counter_values.bytes)); 16725 } 16726 } 16727 return BCM_E_NONE; 16728 } else 16729 #endif 16730 #endif 16731 { 16732 return BCM_E_UNAVAIL; 16733 } 16734 } 16735 16736 /* 16737 * Function: 16738 * bcm_esw_vlan_translate_egress_stat_multi_get32 16739 * Purpose: 16740 * Get lower 32-bit counter value for multiple egress VLAN 16741 * translation statistic types. 16742 * Parameters: 16743 * unit - (IN) Unit number. 16744 * port_class - (IN) Group ID of ingress port 16745 * outer_vlan - (IN) Packet outer VLAN ID 16746 * inner_vlan - (IN) Packet inner VLAN ID 16747 * nstat - (IN) Number of elements in stat array 16748 * stat_arr - (IN) Collected statistics descriptors array 16749 * value_arr - (OUT) Collected counters values 16750 * Returns: 16751 * BCM_E_xxx 16752 * Notes: 16753 */ 16754 int 16755 bcm_esw_vlan_translate_egress_stat_multi_get32(int unit, int port_class, 16756 bcm_vlan_t outer_vlan, 16757 bcm_vlan_t inner_vlan, 16758 int nstat, 16759 bcm_vlan_stat_t *stat_arr, 16760 uint32 *value_arr) 16761 { 16762 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16763 _bcm_flex_stat_handle_t vxlt_fsh; 16764 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 16765 int idx; 16766 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16767 defined(BCM_HURRICANE3_SUPPORT) 16768 uint32 counter_indexes=0; 16769 bcm_stat_value_t counter_values={0}; 16770 #endif 16771 16772 #ifdef BCM_TOMAHAWK3_SUPPORT 16773 if (SOC_IS_TOMAHAWK3(unit)) { 16774 return BCM_E_UNAVAIL; 16775 } 16776 #endif 16777 if (soc_feature(unit, soc_feature_gport_service_counters)) { 16778 16779 BCM_IF_ERROR_RETURN 16780 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 16781 outer_vlan, inner_vlan, 16782 &vxlt_fsh)); 16783 BCM_IF_ERROR_RETURN 16784 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr, 16785 &_bcm_esw_vlan_translate_egress_stat_to_flex_stat)); 16786 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 16787 16788 return _bcm_esw_flex_stat_ext_multi_get32(unit, _bcmFlexStatTypeVxlt, 16789 vxlt_fsh, 16790 nstat, fs_arr, value_arr); 16791 } else 16792 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16793 defined(BCM_HURRICANE3_SUPPORT) 16794 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 16795 soc_feature(unit, soc_feature_flowcnt)) { 16796 for (idx=0;idx < nstat ; idx ++) { 16797 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_get( 16798 unit,port_class,outer_vlan,inner_vlan, 16799 stat_arr[idx],1,&counter_indexes,&counter_values)); 16800 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 16801 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 16802 value_arr[idx] = counter_values.packets; 16803 } else { 16804 value_arr[idx] = COMPILER_64_LO(counter_values.bytes); 16805 } 16806 } 16807 return BCM_E_NONE; 16808 } 16809 #endif 16810 #endif 16811 { 16812 return BCM_E_UNAVAIL; 16813 } 16814 } 16815 16816 /* 16817 * Function: 16818 * bcm_esw_vlan_translate_egress_stat_multi_set 16819 * Purpose: 16820 * Set 64-bit counter value for multiple egress VLAN translation 16821 * statistic types. 16822 * Parameters: 16823 * unit - (IN) Unit number. 16824 * port_class - (IN) Group ID of ingress port 16825 * outer_vlan - (IN) Packet outer VLAN ID 16826 * inner_vlan - (IN) Packet inner VLAN ID 16827 * nstat - (IN) Number of elements in stat array 16828 * stat_arr - (IN) New statistics descriptors array 16829 * value_arr - (IN) New counters values 16830 * Returns: 16831 * BCM_E_xxx 16832 * Notes: 16833 */ 16834 int 16835 bcm_esw_vlan_translate_egress_stat_multi_set(int unit, int port_class, 16836 bcm_vlan_t outer_vlan, 16837 bcm_vlan_t inner_vlan, 16838 int nstat, 16839 bcm_vlan_stat_t *stat_arr, 16840 uint64 *value_arr) 16841 { 16842 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16843 _bcm_flex_stat_handle_t vxlt_fsh; 16844 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 16845 int idx; 16846 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16847 defined(BCM_HURRICANE3_SUPPORT) 16848 uint32 counter_indexes=0; 16849 bcm_stat_value_t counter_values={0}; 16850 #endif 16851 16852 #ifdef BCM_TOMAHAWK3_SUPPORT 16853 if (SOC_IS_TOMAHAWK3(unit)) { 16854 return BCM_E_UNAVAIL; 16855 } 16856 #endif 16857 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16858 if (soc_feature(unit, soc_feature_gport_service_counters)) { 16859 BCM_IF_ERROR_RETURN 16860 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 16861 outer_vlan, inner_vlan, 16862 &vxlt_fsh)); 16863 BCM_IF_ERROR_RETURN 16864 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr, 16865 &_bcm_esw_vlan_translate_egress_stat_to_flex_stat)); 16866 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 16867 16868 return _bcm_esw_flex_stat_ext_multi_set(unit, _bcmFlexStatTypeVxlt, 16869 vxlt_fsh, 16870 nstat, fs_arr, value_arr); 16871 } else 16872 #endif 16873 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16874 defined(BCM_HURRICANE3_SUPPORT) 16875 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 16876 soc_feature(unit, soc_feature_flowcnt)) { 16877 for (idx=0;idx < nstat ; idx ++) { 16878 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 16879 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 16880 counter_values.packets = COMPILER_64_LO(value_arr[idx]); 16881 } else { 16882 COMPILER_64_SET(counter_values.bytes, 16883 COMPILER_64_HI(value_arr[idx]), 16884 COMPILER_64_LO(value_arr[idx])); 16885 } 16886 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_set( 16887 unit,port_class,outer_vlan,inner_vlan, 16888 stat_arr[idx],1,&counter_indexes,&counter_values)); 16889 } 16890 return BCM_E_NONE; 16891 } else 16892 #endif 16893 #endif 16894 { 16895 return BCM_E_UNAVAIL; 16896 } 16897 } 16898 16899 /* 16900 * Function: 16901 * bcm_esw_vlan_translate_egress_stat_multi_set32 16902 * Purpose: 16903 * Set lower 32-bit counter value for multiple egress VLAN 16904 * translation statistic types. 16905 * Parameters: 16906 * unit - (IN) Unit number. 16907 * port_class - (IN) Group ID of ingress port 16908 * outer_vlan - (IN) Packet outer VLAN ID 16909 * inner_vlan - (IN) Packet inner VLAN ID 16910 * nstat - (IN) Number of elements in stat array 16911 * stat_arr - (IN) New statistics descriptors array 16912 * value_arr - (IN) New counters values 16913 * Returns: 16914 * BCM_E_xxx 16915 * Notes: 16916 */ 16917 int 16918 bcm_esw_vlan_translate_egress_stat_multi_set32(int unit, int port_class, 16919 bcm_vlan_t outer_vlan, 16920 bcm_vlan_t inner_vlan, 16921 int nstat, 16922 bcm_vlan_stat_t *stat_arr, 16923 uint32 *value_arr) 16924 { 16925 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 16926 _bcm_flex_stat_handle_t vxlt_fsh; 16927 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 16928 int idx; 16929 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16930 defined(BCM_HURRICANE3_SUPPORT) 16931 uint32 counter_indexes=0; 16932 bcm_stat_value_t counter_values={0}; 16933 #endif 16934 16935 #ifdef BCM_TOMAHAWK3_SUPPORT 16936 if (SOC_IS_TOMAHAWK3(unit)) { 16937 return BCM_E_UNAVAIL; 16938 } 16939 #endif 16940 if (soc_feature(unit, soc_feature_gport_service_counters)) { 16941 BCM_IF_ERROR_RETURN 16942 (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class, 16943 outer_vlan, inner_vlan, 16944 &vxlt_fsh)); 16945 BCM_IF_ERROR_RETURN 16946 (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr, 16947 &_bcm_esw_vlan_translate_egress_stat_to_flex_stat)); 16948 BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr); 16949 16950 return _bcm_esw_flex_stat_ext_multi_set32(unit, _bcmFlexStatTypeVxlt, 16951 vxlt_fsh, 16952 nstat, fs_arr, value_arr); 16953 } else 16954 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 16955 defined(BCM_HURRICANE3_SUPPORT) 16956 if (soc_feature(unit, soc_feature_advanced_flex_counter) || 16957 soc_feature(unit, soc_feature_flowcnt)) { 16958 for (idx=0;idx < nstat ; idx ++) { 16959 if ((stat_arr[idx] == bcmVlanStatIngressPackets) || 16960 (stat_arr[idx] == bcmVlanStatEgressPackets)) { 16961 counter_values.packets = value_arr[idx]; 16962 } else { 16963 COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]); 16964 } 16965 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_set( 16966 unit,port_class,outer_vlan,inner_vlan, 16967 stat_arr[idx],1,&counter_indexes,&counter_values)); 16968 } 16969 return BCM_E_NONE; 16970 } else 16971 #endif 16972 #endif 16973 { 16974 return BCM_E_UNAVAIL; 16975 } 16976 } 16977 16978 /* 16979 * Function: 16980 * _bcm_vlan_queue_map_id_check 16981 * Description: 16982 * To check the status of the specified qmid 16983 * Parameters: 16984 * unit device number 16985 * qmid queue mapping identifier 16986 * Return: 16987 * BCM_E_UNAVAIL queue mapping feature is not supported for this device 16988 * BCM_E_INIT vlan component is not initialized on this device 16989 * BCM_E_BADID specified qmid is not in valid range 16990 * BCM_E_NOT_FOUND spefified qmid is in valid range but not in used 16991 * BCM_E_NONE specified qmid is in used 16992 */ 16993 STATIC int 16994 _bcm_vlan_queue_map_id_check(int unit, 16995 int qmid) 16996 { 16997 int size; 16998 16999 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17000 return BCM_E_UNAVAIL; 17001 } 17002 17003 CHECK_INIT(unit); 17004 17005 size = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm, 17006 PHB2_DOT1P_MAPPING_PTRf); 17007 17008 if (qmid < 0 || qmid >= size) { 17009 return BCM_E_BADID; 17010 } 17011 17012 if (!SHR_BITGET(vlan_info[unit].qm_bmp, qmid)) { 17013 return BCM_E_NOT_FOUND; 17014 } 17015 17016 return BCM_E_NONE; 17017 } 17018 17019 /* Create a VLAN queue map entry. */ 17020 int 17021 bcm_esw_vlan_queue_map_create(int unit, 17022 uint32 flags, 17023 int *qmid) 17024 { 17025 bcm_vlan_info_t *vi; 17026 int size, bmp_size, free_qmid, i; 17027 uint32 bits, tag_flags; 17028 int rv; 17029 17030 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17031 return BCM_E_UNAVAIL; 17032 } 17033 17034 CHECK_INIT(unit); 17035 17036 vi = &vlan_info[unit]; 17037 size = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm, 17038 PHB2_DOT1P_MAPPING_PTRf); 17039 17040 if (flags & BCM_VLAN_QUEUE_MAP_REPLACE) { 17041 if (!(flags & BCM_VLAN_QUEUE_MAP_WITH_ID)) { 17042 return BCM_E_PARAM; 17043 } 17044 BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, *qmid)); 17045 } 17046 tag_flags = flags & (BCM_VLAN_QUEUE_MAP_INNER_PKT_PRI | 17047 BCM_VLAN_QUEUE_MAP_OUTER_PKT_PRI); 17048 if (tag_flags != BCM_VLAN_QUEUE_MAP_OUTER_PKT_PRI && 17049 tag_flags != BCM_VLAN_QUEUE_MAP_INNER_PKT_PRI) { 17050 return BCM_E_PARAM; 17051 } 17052 17053 if (!(flags & BCM_VLAN_QUEUE_MAP_REPLACE)) { 17054 if (flags & BCM_VLAN_QUEUE_MAP_WITH_ID) { 17055 rv = _bcm_vlan_queue_map_id_check(unit, *qmid); 17056 /* make sure the id is in the valid range and not taken */ 17057 if (rv != BCM_E_NOT_FOUND) { 17058 return BCM_E_PARAM; 17059 } 17060 SHR_BITSET(vi->qm_bmp, *qmid); 17061 } else { 17062 free_qmid = size; 17063 bmp_size = _SHR_BITDCLSIZE(size); 17064 /* find the index of first zero from qm_bmp */ 17065 for (i = 0; i < bmp_size; i++) { 17066 if (vi->qm_bmp[i] == 0xffffffff) { 17067 continue; 17068 } 17069 bits = vi->qm_bmp[i]; 17070 bits &= (bits << 1) | 0x00000001; 17071 bits &= (bits << 2) | 0x00000003; 17072 bits &= (bits << 4) | 0x0000000f; 17073 bits &= (bits << 8) | 0x000000ff; 17074 bits &= (bits << 16) | 0x0000ffff; 17075 free_qmid = (i << 5) + _shr_popcount(bits); 17076 break; 17077 } 17078 if (free_qmid >= size) { 17079 return BCM_E_RESOURCE; 17080 } 17081 SHR_BITSET(vi->qm_bmp, free_qmid); 17082 *qmid = free_qmid; 17083 } 17084 } 17085 17086 if (flags & BCM_VLAN_QUEUE_MAP_INNER_PKT_PRI) { 17087 SHR_BITSET(vi->qm_it_bmp, *qmid); 17088 } else { 17089 SHR_BITCLR(vi->qm_it_bmp, *qmid); 17090 } 17091 17092 #ifdef BCM_WARM_BOOT_SUPPORT 17093 SOC_CONTROL_LOCK(unit); 17094 SOC_CONTROL(unit)->scache_dirty = 1; 17095 SOC_CONTROL_UNLOCK(unit); 17096 #endif 17097 17098 return BCM_E_NONE; 17099 } 17100 17101 /* Delete a VLAN queue map entry. */ 17102 int 17103 bcm_esw_vlan_queue_map_destroy(int unit, 17104 int qmid) 17105 { 17106 int pkt_pri, cfi; 17107 17108 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17109 return BCM_E_UNAVAIL; 17110 } 17111 BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, qmid)); 17112 17113 for (pkt_pri = 0; pkt_pri <=7; pkt_pri++) { 17114 for (cfi = 0; cfi <= 1; cfi++) { 17115 BCM_IF_ERROR_RETURN(bcm_esw_vlan_queue_map_set(unit, 17116 qmid, pkt_pri, cfi, 0, 0)); 17117 } 17118 } 17119 17120 SHR_BITCLR(vlan_info[unit].qm_bmp, qmid); 17121 17122 #ifdef BCM_WARM_BOOT_SUPPORT 17123 SOC_CONTROL_LOCK(unit); 17124 SOC_CONTROL(unit)->scache_dirty = 1; 17125 SOC_CONTROL_UNLOCK(unit); 17126 #endif 17127 17128 return BCM_E_NONE; 17129 } 17130 17131 /* Delete all VLAN queue map entries. */ 17132 int 17133 bcm_esw_vlan_queue_map_destroy_all(int unit) 17134 { 17135 int size, qmid; 17136 17137 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17138 return BCM_E_UNAVAIL; 17139 } 17140 17141 CHECK_INIT(unit); 17142 17143 size = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm, 17144 PHB2_DOT1P_MAPPING_PTRf); 17145 17146 for (qmid = 0; qmid < size; qmid++) { 17147 if (SHR_BITGET(vlan_info[unit].qm_bmp, qmid)) { 17148 BCM_IF_ERROR_RETURN(bcm_esw_vlan_queue_map_destroy(unit, qmid)); 17149 } 17150 } 17151 17152 #ifdef BCM_WARM_BOOT_SUPPORT 17153 SOC_CONTROL_LOCK(unit); 17154 SOC_CONTROL(unit)->scache_dirty = 1; 17155 SOC_CONTROL_UNLOCK(unit); 17156 #endif 17157 17158 return BCM_E_NONE; 17159 } 17160 17161 /* Set a VLAN queue map entry. */ 17162 int 17163 bcm_esw_vlan_queue_map_set(int unit, 17164 int qmid, 17165 int pkt_pri, 17166 int cfi, 17167 int queue, 17168 int color) 17169 { 17170 phb2_cos_map_entry_t entry; 17171 int index; 17172 17173 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17174 return BCM_E_UNAVAIL; 17175 } 17176 17177 BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, qmid)); 17178 17179 if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) { 17180 return BCM_E_PARAM; 17181 } 17182 17183 if (queue < 0 || 17184 queue >= (1 << soc_mem_field_length(unit, PHB2_COS_MAPm, COSf))) { 17185 return BCM_E_PARAM; 17186 } 17187 17188 /* For Triumph2 and Enduro, the entry index is: 17189 * {PHB2_DOT1P_MAPPING_PTR(4-bit), 802.1 priority(3-bit), CFI/DE}. 17190 * From Trident onward, the index takes format of: 17191 * {802.1p_priority[2:0], 802.1p_cfi, PHB2_DOT1P_MAPPING_PTR}. 17192 */ 17193 17194 #ifdef BCM_TRIUMPH2_SUPPORT 17195 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 17196 SOC_IS_VALKYRIE2(unit)) { 17197 index = (qmid << 4) | (pkt_pri << 1) | cfi; 17198 } else 17199 #endif 17200 #ifdef BCM_ENDURO_SUPPORT 17201 if (SOC_IS_ENDURO(unit)) { 17202 index = (qmid << 4) | (pkt_pri << 1) | cfi; 17203 } else 17204 #endif 17205 #ifdef BCM_HELIX5_SUPPORT 17206 if (SOC_IS_HELIX5(unit)) { 17207 index = (pkt_pri << 6) | (cfi << 5) | (qmid << 1); /* Wired */ 17208 } else 17209 #endif 17210 { 17211 index = (pkt_pri << 5) | (cfi << 4) | qmid; 17212 } 17213 17214 sal_memset(&entry, 0, sizeof(entry)); 17215 soc_mem_field32_set(unit, PHB2_COS_MAPm, &entry, COSf, queue); 17216 17217 if (soc_feature(unit, soc_feature_vlan_multicast_queue_map)) { 17218 soc_mem_field32_set(unit, PHB2_COS_MAPm, &entry, MC_COS2f, queue); 17219 } 17220 17221 BCM_IF_ERROR_RETURN(soc_mem_write(unit, PHB2_COS_MAPm, MEM_BLOCK_ANY, 17222 index, 17223 &entry)); 17224 17225 #ifdef BCM_HELIX5_SUPPORT 17226 if (SOC_IS_HELIX5(unit)) { 17227 index = ((pkt_pri << 6) | (cfi << 5) | (qmid << 1)) + 1; /* Wireless */ 17228 BCM_IF_ERROR_RETURN(soc_mem_write(unit, PHB2_COS_MAPm, MEM_BLOCK_ANY, 17229 index, &entry)); 17230 } 17231 #endif 17232 17233 return BCM_E_NONE; 17234 } 17235 17236 /* Get a VLAN queue map entry. */ 17237 int 17238 bcm_esw_vlan_queue_map_get(int unit, 17239 int qmid, 17240 int pkt_pri, 17241 int cfi, 17242 int *queue, 17243 int *color) 17244 { 17245 phb2_cos_map_entry_t entry; 17246 int index; 17247 17248 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17249 return BCM_E_UNAVAIL; 17250 } 17251 17252 BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, qmid)); 17253 17254 if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) { 17255 return BCM_E_PARAM; 17256 } 17257 17258 if (queue == NULL || color == NULL) { 17259 return BCM_E_PARAM; 17260 } 17261 17262 #ifdef BCM_TRIUMPH2_SUPPORT 17263 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 17264 SOC_IS_VALKYRIE2(unit)) { 17265 index = (qmid << 4) | (pkt_pri << 1) | cfi; 17266 } else 17267 #endif 17268 #ifdef BCM_ENDURO_SUPPORT 17269 if (SOC_IS_ENDURO(unit)) { 17270 index = (qmid << 4) | (pkt_pri << 1) | cfi; 17271 } else 17272 #endif 17273 #ifdef BCM_HELIX5_SUPPORT 17274 if (SOC_IS_HELIX5(unit)) { 17275 index = (pkt_pri << 6) | (cfi << 5) | (qmid << 1); /* Wired */ 17276 } else 17277 #endif 17278 { 17279 index = (pkt_pri << 5) | (cfi << 4) | qmid; 17280 } 17281 17282 BCM_IF_ERROR_RETURN(soc_mem_read(unit, PHB2_COS_MAPm, MEM_BLOCK_ANY, 17283 index, 17284 &entry)); 17285 *queue = soc_mem_field32_get(unit, PHB2_COS_MAPm, &entry, COSf); 17286 *color = 0; 17287 17288 return BCM_E_NONE; 17289 } 17290 17291 /* Attach a queue map object to a VLAN or VFI. */ 17292 int 17293 bcm_esw_vlan_queue_map_attach(int unit, 17294 bcm_vlan_t vlan, 17295 int qmid) 17296 { 17297 #ifdef BCM_TRIUMPH2_SUPPORT 17298 vfi_entry_t vfi_entry; 17299 int use_inner_tag; 17300 #endif /* BCM_TRIUMHP2_SUPPORT */ 17301 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17302 return BCM_E_UNAVAIL; 17303 } 17304 17305 BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, qmid)); 17306 17307 #ifdef BCM_TRIUMPH2_SUPPORT 17308 VLAN_CHK_ID(unit, vlan); 17309 17310 use_inner_tag = SHR_BITGET(vlan_info[unit].qm_it_bmp, qmid) ? 1 : 0; 17311 BCM_IF_ERROR_RETURN 17312 (_bcm_tr2_vlan_qmid_set(unit, vlan, qmid, use_inner_tag)); 17313 17314 if (SOC_MEM_IS_VALID(unit, VFIm)) { 17315 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ANY, vlan, &vfi_entry)); 17316 soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_DOT1P_MAPPING_PTRf, qmid); 17317 soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_USE_INNER_DOT1Pf, 17318 use_inner_tag); 17319 soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_ENABLEf, 1); 17320 BCM_IF_ERROR_RETURN(WRITE_VFIm(unit, MEM_BLOCK_ANY, vlan, &vfi_entry)); 17321 } 17322 #endif /* BCM_TRIUMHP2_SUPPORT */ 17323 17324 return BCM_E_NONE; 17325 } 17326 17327 /* Get the queue map object which is attached to a VLAN or VFI. */ 17328 int 17329 bcm_esw_vlan_queue_map_attach_get(int unit, 17330 bcm_vlan_t vlan, 17331 int *qmid) 17332 { 17333 #ifdef BCM_TRIUMPH2_SUPPORT 17334 int use_inner_tag; 17335 #endif /* BCM_TRIUMHP2_SUPPORT */ 17336 17337 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17338 return BCM_E_UNAVAIL; 17339 } 17340 17341 #ifdef BCM_TRIUMPH2_SUPPORT 17342 CHECK_INIT(unit); 17343 17344 VLAN_CHK_ID(unit, vlan); 17345 17346 if (qmid == NULL) { 17347 return BCM_E_PARAM; 17348 } 17349 17350 BCM_IF_ERROR_RETURN 17351 (_bcm_tr2_vlan_qmid_get(unit, vlan, qmid, &use_inner_tag)); 17352 #endif /* BCM_TRIUMHP2_SUPPORT */ 17353 17354 return BCM_E_NONE; 17355 } 17356 17357 /* Detach a queue map object from a VLAN or VFI. */ 17358 int 17359 bcm_esw_vlan_queue_map_detach(int unit, 17360 bcm_vlan_t vlan) 17361 { 17362 #ifdef BCM_TRIUMPH2_SUPPORT 17363 vfi_entry_t vfi_entry; 17364 #endif /* BCM_TRIUMHP2_SUPPORT */ 17365 17366 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17367 return BCM_E_UNAVAIL; 17368 } 17369 17370 #ifdef BCM_TRIUMPH2_SUPPORT 17371 CHECK_INIT(unit); 17372 17373 VLAN_CHK_ID(unit, vlan); 17374 17375 BCM_IF_ERROR_RETURN(_bcm_tr2_vlan_qmid_set(unit, vlan, -1, 0)); 17376 17377 if (SOC_MEM_IS_VALID(unit, VFIm)) { 17378 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ANY, vlan, &vfi_entry)); 17379 soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_DOT1P_MAPPING_PTRf, 0); 17380 soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_USE_INNER_DOT1Pf, 0); 17381 soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_ENABLEf, 0); 17382 BCM_IF_ERROR_RETURN(WRITE_VFIm(unit, MEM_BLOCK_ANY, vlan, &vfi_entry)); 17383 } 17384 #endif /* BCM_TRIUMHP2_SUPPORT */ 17385 17386 return BCM_E_NONE; 17387 } 17388 17389 /* Detach queue map objects from all VLAN or VFI. */ 17390 int 17391 bcm_esw_vlan_queue_map_detach_all(int unit) 17392 { 17393 #ifdef BCM_TRIUMPH2_SUPPORT 17394 vfi_entry_t vfi_entry; 17395 int vlan; 17396 #endif /* BCM_TRIUMHP2_SUPPORT */ 17397 17398 if (!soc_feature(unit, soc_feature_vlan_queue_map)) { 17399 return BCM_E_UNAVAIL; 17400 } 17401 17402 #ifdef BCM_TRIUMPH2_SUPPORT 17403 CHECK_INIT(unit); 17404 17405 for (vlan = BCM_VLAN_MIN; vlan < BCM_VLAN_COUNT; vlan++) { 17406 if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) { 17407 BCM_IF_ERROR_RETURN(_bcm_tr2_vlan_qmid_set(unit, vlan, -1, 0)); 17408 17409 if (!SOC_MEM_IS_VALID(unit, VFIm)) { 17410 continue; 17411 } 17412 17413 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ANY, vlan, 17414 &vfi_entry)); 17415 soc_mem_field32_set(unit, VFIm, &vfi_entry, 17416 PHB2_DOT1P_MAPPING_PTRf, 0); 17417 soc_mem_field32_set(unit, VFIm, &vfi_entry, 17418 PHB2_USE_INNER_DOT1Pf, 0); 17419 soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_ENABLEf, 0); 17420 BCM_IF_ERROR_RETURN(WRITE_VFIm(unit, MEM_BLOCK_ANY, vlan, 17421 &vfi_entry)); 17422 } 17423 } 17424 #endif /* BCM_TRIUMHP2_SUPPORT */ 17425 17426 return BCM_E_NONE; 17427 } 17428 17429 /* 17430 * Function: 17431 * bcmi_esw_vlan_vfi_validate 17432 * Purpose: 17433 * Validate a VLAN/VFI 17434 * Parameters: 17435 * unit - StrataSwitch PCI device unit number (driver internal). 17436 * vlan_vfi - VLAN/VFI ID to validate. 17437 * Returns: 17438 * BCM_E_NONE - Success. 17439 * BCM_E_PARAM - Invalid value. 17440 */ 17441 int 17442 bcmi_esw_vlan_vfi_validate(int unit, bcm_vlan_t vlan_vfi) 17443 { 17444 17445 #if defined(INCLUDE_L3) && defined(BCM_TRX_SUPPORT) 17446 17447 /* For vlan validate range, for vfi ensure that one of the vpn 17448 types matches */ 17449 if((soc_feature(unit, soc_feature_vlan_vfi_membership)) && 17450 _BCM_VPN_VFI_IS_SET(vlan_vfi)) { 17451 17452 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan_vfi); 17453 if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeMpls)) 17454 return BCM_E_NONE; 17455 else if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeMim)) 17456 return BCM_E_NONE; 17457 else if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeL2Gre)) 17458 return BCM_E_NONE; 17459 else if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeVxlan)) 17460 return BCM_E_NONE; 17461 else if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeFlow)) 17462 return BCM_E_NONE; 17463 else { 17464 return BCM_E_PARAM; 17465 } 17466 #if defined(BCM_TRIUMPH3_SUPPORT) 17467 } else if ((soc_feature(unit, soc_feature_vlan_vfi)) && 17468 _BCM_VPN_VFI_IS_SET(vlan_vfi)) { 17469 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan_vfi); 17470 if (_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeVlan)) { 17471 return BCM_E_NONE; 17472 } else { 17473 return BCM_E_PARAM; 17474 } 17475 #endif /* BCM_TRIUMPH3_SUPPORT */ 17476 } else { 17477 VLAN_CHK_ID(unit, vlan_vfi); 17478 } 17479 17480 #else 17481 VLAN_CHK_ID(unit, vlan_vfi); 17482 #endif 17483 17484 return BCM_E_NONE; 17485 } 17486 17487 #define MOD_PORT_TO_GLP(unit, modid, port, glp) \ 17488 do { \ 17489 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { \ 17490 glp = ((0xFF & modid) << 7) | (0x7F & port); \ 17491 } else { \ 17492 glp = ((0xFF & modid) << 8) | (0xFF & port); \ 17493 } \ 17494 } while(0) 17495 17496 /* 17497 * Function: 17498 * bcm_vlan_gport_add 17499 * Purpose: 17500 * Add a Gport to the specified vlan. Adds WLAN/VLAN/NIV/Extender ports to 17501 * broadcast, multicast and unknown unicast groups. 17502 * Parameters: 17503 * unit - StrataSwitch PCI device unit number (driver internal). 17504 * vlan - VLAN ID to add port to as a member. 17505 * port - Gport ID 17506 * flags - BCM_VLAN_PORT_XXX 17507 * Returns: 17508 * BCM_E_NONE - Success. 17509 * BCM_E_INTERNAL - Chip access failure. 17510 * BCM_E_NOT_FOUND - VLAN ID not in use. 17511 */ 17512 int 17513 bcm_esw_vlan_gport_add(int unit, bcm_vlan_t vlan, bcm_gport_t port, 17514 int flags) 17515 { 17516 int rv = BCM_E_NONE; 17517 17518 #ifdef BCM_TOMAHAWK3_SUPPORT 17519 if (SOC_IS_TOMAHAWK3(unit)) { 17520 return bcm_tomahawk3_vlan_gport_add(unit, vlan, port, flags); 17521 } 17522 #endif 17523 17524 CHECK_INIT(unit); 17525 17526 /* VxLAN passes in a VFI, hence check VLAN for non-VxLan cases */ 17527 BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan)); 17528 17529 if (port == BCM_GPORT_INVALID) 17530 return BCM_E_PORT; 17531 17532 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 17533 if (soc_feature(unit, soc_feature_wlan) && BCM_GPORT_IS_WLAN_PORT(port)) { 17534 int i, vp, mc_idx, gport_id, mod_local, group = 0; 17535 vlan_tab_entry_t vtab; 17536 bcm_wlan_port_t wlan_port; 17537 bcm_module_t mod_out; 17538 bcm_port_t port_out; 17539 bcm_trunk_t trunk_id; 17540 bcm_gport_t local_gport; 17541 bcm_if_t encap_id; 17542 bcm_pbmp_t vlan_pbmp, vlan_ubmp, pbmp, l3_pbmp; 17543 soc_field_t group_type[3] = {BC_IDXf, UMC_IDXf, UUC_IDXf}; 17544 17545 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 17546 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 17547 return BCM_E_NOT_FOUND; 17548 } 17549 if (flags != 0) { 17550 return BCM_E_PARAM; 17551 } 17552 sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t)); 17553 17554 soc_mem_lock(unit, VLAN_TABm); 17555 17556 if ((rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, 17557 &vtab)) < 0) { 17558 soc_mem_unlock(unit, VLAN_TABm); 17559 return rv; 17560 } 17561 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 17562 soc_mem_unlock(unit, VLAN_TABm); 17563 return BCM_E_NOT_FOUND; 17564 } 17565 17566 /* Get the VP attributes (need physical port) and encap id */ 17567 if ((rv = bcm_esw_wlan_port_get(unit, port, &wlan_port)) < 0) { 17568 soc_mem_unlock(unit, VLAN_TABm); 17569 return rv; 17570 } 17571 17572 /* Enable VP switching on the VLAN */ 17573 if (!SHR_BITGET(vlan_info[unit].vp_mode, vlan) && 17574 SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 17575 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 17576 soc_mem_field32_set(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf, 1); 17577 if ((rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, (int)vlan, 17578 &vtab)) < 0) { 17579 soc_mem_unlock(unit, VLAN_TABm); 17580 return rv; 17581 } 17582 /* Also need to copy the physical port members to the L2_BITMAP of 17583 * the IPMC entry for each group once we've gone virtual */ 17584 rv = mbcm_driver[unit]->mbcm_vlan_port_get 17585 (unit, vlan, &vlan_pbmp, &vlan_ubmp, NULL); 17586 17587 if (rv < 0) { 17588 soc_mem_unlock(unit, VLAN_TABm); 17589 return rv; 17590 } 17591 /* Deal with each group */ 17592 for (i = 0; i < 3; i++) { 17593 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, 17594 group_type[i]); 17595 rv = _bcm_esw_multicast_ipmc_read(unit, mc_idx, &pbmp, 17596 &l3_pbmp); 17597 if (rv < 0) { 17598 soc_mem_unlock(unit, VLAN_TABm); 17599 return rv; 17600 } 17601 rv = _bcm_esw_multicast_ipmc_write(unit, mc_idx, vlan_pbmp, 17602 l3_pbmp, TRUE); 17603 if (rv < 0) { 17604 soc_mem_unlock(unit, VLAN_TABm); 17605 return rv; 17606 } 17607 } 17608 } 17609 } 17610 17611 /* Check if wlan_port.port is a local port or trunk */ 17612 if (BCM_GPORT_IS_TRUNK(wlan_port.port)) { 17613 trunk_id = BCM_GPORT_TRUNK_GET(wlan_port.port); 17614 rv = _bcm_trunk_id_validate(unit, trunk_id); 17615 if (BCM_FAILURE(rv)) { 17616 soc_mem_unlock(unit, VLAN_TABm); 17617 return (BCM_E_PORT); 17618 } 17619 local_gport = wlan_port.port; 17620 } else { 17621 rv = _bcm_esw_gport_resolve(unit, wlan_port.port, &mod_out, &port_out, 17622 &trunk_id, &gport_id); 17623 if (BCM_FAILURE(rv)) { 17624 soc_mem_unlock(unit, VLAN_TABm); 17625 return (BCM_E_PORT); 17626 } 17627 rv = _bcm_esw_modid_is_local(unit, mod_out, &mod_local); 17628 if (BCM_FAILURE(rv)) { 17629 soc_mem_unlock(unit, VLAN_TABm); 17630 return rv; 17631 } 17632 if (TRUE != mod_local) { 17633 /* Only add this to replication set if destination is local */ 17634 soc_mem_unlock(unit, VLAN_TABm); 17635 return BCM_E_PORT; 17636 } 17637 /* Convert system local_port to physical local_port */ 17638 if (soc_feature(unit, soc_feature_sysport_remap)) { 17639 BCM_XLATE_SYSPORT_S2P(unit, &port_out); 17640 } 17641 rv = bcm_esw_port_gport_get(unit, port_out, &local_gport); 17642 if (BCM_FAILURE(rv)) { 17643 soc_mem_unlock(unit, VLAN_TABm); 17644 return rv; 17645 } 17646 } 17647 rv = bcm_esw_multicast_wlan_encap_get(unit, group, local_gport, 17648 port, &encap_id); 17649 if (BCM_FAILURE(rv)) { 17650 soc_mem_unlock(unit, VLAN_TABm); 17651 return rv; 17652 } 17653 17654 /* Add the VP to the BC group */ 17655 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 17656 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx); 17657 rv = bcm_esw_multicast_egress_add(unit, group, local_gport, encap_id); 17658 if (rv < 0) { 17659 soc_mem_unlock(unit, VLAN_TABm); 17660 return rv; 17661 } 17662 17663 /* Add the VP to the UMC group */ 17664 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 17665 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx); 17666 rv = bcm_esw_multicast_egress_add(unit, group, local_gport, encap_id); 17667 if (rv < 0) { 17668 soc_mem_unlock(unit, VLAN_TABm); 17669 return rv; 17670 } 17671 17672 /* Add the VP to the UUC group */ 17673 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 17674 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx); 17675 rv = bcm_esw_multicast_egress_add(unit, group, local_gport, encap_id); 17676 17677 soc_mem_unlock(unit, VLAN_TABm); 17678 17679 } else if (soc_feature(unit, soc_feature_vlan_vp) && BCM_GPORT_IS_VLAN_PORT(port)) { 17680 #if defined(BCM_ENDURO_SUPPORT) 17681 if (SOC_IS_ENDURO(unit)) { 17682 rv = bcm_enduro_vlan_vp_add(unit, vlan, port, flags); 17683 } else 17684 #endif /* BCM_ENDURO_SUPPORT */ 17685 { 17686 /* COVERITY 17687 * up to this point, coverity indicates 7604 bytes stack usage. 17688 * After this call, it becomes 8220 bytes which exceeds the coverity 17689 * default check limit 8192 bytes. 17690 */ 17691 /* coverity[stack_use_overflow : FALSE] */ 17692 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17693 } 17694 } else if (soc_feature(unit, soc_feature_niv) && 17695 BCM_GPORT_IS_NIV_PORT(port)) { 17696 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17697 } else if (soc_feature(unit, soc_feature_port_extension) && 17698 BCM_GPORT_IS_EXTENDER_PORT(port)) { 17699 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17700 } else if (soc_feature(unit, soc_feature_vp_lag) && 17701 BCM_GPORT_IS_TRUNK(port)) { 17702 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17703 } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 17704 BCM_GPORT_IS_SUBPORT_PORT(port)) { 17705 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17706 } else if (soc_feature(unit, soc_feature_vxlan) && 17707 BCM_GPORT_IS_VXLAN_PORT(port)) { 17708 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17709 } else if (soc_feature(unit, soc_feature_flex_flow) && 17710 BCM_GPORT_IS_FLOW_PORT(port)) { 17711 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17712 } else if (soc_feature(unit, soc_feature_l2gre) && 17713 BCM_GPORT_IS_L2GRE_PORT(port)) { 17714 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17715 } else if (soc_feature(unit, soc_feature_mim) && 17716 BCM_GPORT_IS_MIM_PORT(port)) { 17717 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17718 } else if (soc_feature(unit, soc_feature_mpls) && 17719 BCM_GPORT_IS_MPLS_PORT(port)) { 17720 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17721 } else if (BCM_GPORT_IS_VP_GROUP(port)) { 17722 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 17723 int vpg = BCM_GPORT_VP_GROUP_GET(port); 17724 17725 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 17726 if (soc_feature(unit, soc_feature_vlan_vfi_membership)){ 17727 bcm_stg_t stg; 17728 17729 if ((flags & BCM_VLAN_PORT_INGRESS_ONLY)) { 17730 BCM_IF_ERROR_RETURN(bcm_td2p_ing_vp_group_unmanaged_set(unit,TRUE)); 17731 BCM_IF_ERROR_RETURN( 17732 bcm_td2p_vlan_vp_group_set(unit, vlan, FALSE, vpg, TRUE)); 17733 17734 BCM_IF_ERROR_RETURN( 17735 bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vlan, FALSE, &stg)); 17736 if (stg != BCM_STG_DEFAULT) { 17737 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_state_set(unit, stg, 17738 port, FALSE, _bcm_td2_flags_to_stp_state(unit, flags, FALSE))); 17739 } 17740 } 17741 17742 if ((flags & BCM_VLAN_PORT_EGRESS_ONLY)) { 17743 BCM_IF_ERROR_RETURN(bcm_td2p_egr_vp_group_unmanaged_set(unit,TRUE)); 17744 BCM_IF_ERROR_RETURN( 17745 bcm_td2p_vlan_vp_group_set(unit, vlan, TRUE, vpg, TRUE)); 17746 17747 BCM_IF_ERROR_RETURN( 17748 bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vlan, TRUE, &stg)); 17749 if (stg != BCM_STG_DEFAULT) { 17750 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_state_set(unit, stg, 17751 port, TRUE, _bcm_td2_flags_to_stp_state(unit, flags, TRUE))); 17752 } 17753 17754 if (!_BCM_VPN_VFI_IS_SET(vlan)) { 17755 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_ut_state_set(unit, 17756 vlan, vpg, (flags & BCM_VLAN_GPORT_ADD_UNTAGGED))); 17757 } 17758 #if defined(BCM_TRIDENT3_SUPPORT) 17759 else if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 17760 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_ut_state_set(unit, 17761 vlan, vpg, (flags & BCM_VLAN_GPORT_ADD_UNTAGGED))); 17762 } 17763 #endif 17764 } 17765 } else 17766 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 17767 { 17768 if ((flags & BCM_VLAN_PORT_INGRESS_ONLY) && 17769 soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 17770 BCM_IF_ERROR_RETURN(bcm_td_ing_vp_group_unmanaged_set(unit,TRUE)); 17771 BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_set( 17772 unit, VLAN_TABLE(unit), vlan, vpg, TRUE)); 17773 } 17774 if ((flags & BCM_VLAN_PORT_EGRESS_ONLY) && 17775 soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 17776 BCM_IF_ERROR_RETURN(bcm_td_egr_vp_group_unmanaged_set(unit,TRUE)); 17777 BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_set( 17778 unit, EGR_VLANm, vlan, vpg, TRUE)); 17779 } 17780 } 17781 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 17782 } else 17783 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 17784 { 17785 bcm_pbmp_t pbmp, ubmp, ing_pbmp; 17786 bcm_port_t local_port; 17787 17788 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 17789 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 17790 if ((flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY) && 17791 (flags & BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP) && 17792 _BCM_VPN_VFI_IS_SET(vlan)) { 17793 if(!BCM_GPORT_IS_MODPORT(port)) { 17794 return BCM_E_PARAM; 17795 } 17796 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags); 17797 return rv; 17798 } 17799 } 17800 #endif 17801 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 17802 if (soc_feature(unit, soc_feature_vlan_vfi_membership) && 17803 (flags & BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP)) { 17804 if (!BCM_GPORT_IS_MODPORT(port)) { 17805 return BCM_E_PARAM; 17806 } 17807 17808 MOD_PORT_TO_GLP(unit, BCM_GPORT_MODPORT_MODID_GET(port), 17809 BCM_GPORT_MODPORT_PORT_GET(port), port); 17810 rv = bcm_td2_vp_vlan_membership_add(unit, port, vlan, flags); 17811 return rv; 17812 } 17813 #endif 17814 17815 /* If Ingress/Egress only flags are specified and 'ING_PORT_BITMAPf' is 17816 not a valid field in 'VLAN_TABm' AND if the 17817 'soc_feature_vlan_vfi_membership' is FALSE, return error. If the 17818 feature is TRUE, the mentioned field comes from the profiled 17819 'ING_VLAN_VFI_MEMBERSHIPm' table*/ 17820 if (flags & (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) { 17821 if (!soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf) && 17822 !(soc_feature(unit, soc_feature_vlan_vfi_membership))) { 17823 return BCM_E_PARAM; 17824 } 17825 } 17826 if ((!soc_feature(unit, soc_feature_vlan_egress_membership_l3_only)) && 17827 (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 17828 return (BCM_E_UNAVAIL); 17829 } 17830 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 17831 if ((flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY) && 17832 (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 17833 return BCM_E_PARAM; 17834 } 17835 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_HURRICANE3_SUPPORT */ 17836 17837 BCM_IF_ERROR_RETURN( 17838 bcm_esw_port_local_get(unit, port, &local_port)); 17839 17840 if (flags & (BCM_VLAN_PORT_EGRESS_ONLY | BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 17841 BCM_PBMP_CLEAR(ing_pbmp); 17842 } else { 17843 BCM_PBMP_PORT_SET(ing_pbmp, local_port); 17844 } 17845 if (flags & BCM_VLAN_PORT_INGRESS_ONLY) { 17846 BCM_PBMP_CLEAR(pbmp); 17847 } else { 17848 BCM_PBMP_PORT_SET(pbmp, local_port); 17849 } 17850 if (flags & BCM_VLAN_PORT_UNTAGGED) { 17851 BCM_PBMP_PORT_SET(ubmp, local_port); 17852 } else { 17853 BCM_PBMP_CLEAR(ubmp); 17854 } 17855 if (SOC_IS_FBX(unit)) { 17856 BCM_LOCK(unit); 17857 rv = _bcm_vlan_port_add(unit, vlan, pbmp, ubmp, ing_pbmp, flags); 17858 BCM_UNLOCK(unit); 17859 } else { /* don't support virtual port*/ 17860 BCM_PBMP_OR(pbmp, ing_pbmp); 17861 rv = bcm_esw_vlan_port_add(unit, vlan, pbmp, ubmp); 17862 } 17863 } 17864 17865 return rv; 17866 } 17867 17868 /* 17869 * Function: 17870 * bcm_vlan_gport_delete 17871 * Purpose: 17872 * Delete a Gport from the specified vlan. 17873 * Parameters: 17874 * unit - StrataSwitch PCI device unit number (driver internal). 17875 * vlan - VLAN ID to add port to as a member. 17876 * port - Gport ID 17877 * Returns: 17878 * BCM_E_NONE - Success. 17879 * BCM_E_INTERNAL - Chip access failure. 17880 * BCM_E_NOT_FOUND - VLAN ID not in use. 17881 */ 17882 int 17883 bcm_esw_vlan_gport_delete(int unit, bcm_vlan_t vlan, bcm_gport_t port) 17884 { 17885 int rv = BCM_E_NONE; 17886 17887 #ifdef BCM_TOMAHAWK3_SUPPORT 17888 if (SOC_IS_TOMAHAWK3(unit)) { 17889 return bcm_tomahawk3_vlan_gport_delete(unit, vlan, port); 17890 } 17891 #endif 17892 17893 CHECK_INIT(unit); 17894 17895 /* VxLAN passes in a VFI, hence check VLAN for non-VxLan cases */ 17896 BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan)); 17897 17898 if (port == BCM_GPORT_INVALID) 17899 return BCM_E_PORT; 17900 17901 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 17902 if (soc_feature(unit, soc_feature_wlan) && BCM_GPORT_IS_WLAN_PORT(port)) { 17903 int vp, bc_idx,mc_idx,uuc_idx, gport_id, group = 0, mod_local; 17904 vlan_tab_entry_t vtab; 17905 bcm_wlan_port_t wlan_port; 17906 bcm_module_t mod_out; 17907 bcm_port_t port_out; 17908 bcm_trunk_t trunk_id; 17909 bcm_gport_t local_gport; 17910 bcm_if_t encap_id; 17911 17912 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 17913 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 17914 return BCM_E_NOT_FOUND; 17915 } 17916 sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t)); 17917 17918 soc_mem_lock(unit, VLAN_TABm); 17919 17920 if ((rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, 17921 &vtab)) < 0) { 17922 soc_mem_unlock(unit, VLAN_TABm); 17923 return rv; 17924 } 17925 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 17926 soc_mem_unlock(unit, VLAN_TABm); 17927 return BCM_E_NOT_FOUND; 17928 } 17929 17930 /* Get the VP attributes (need physical port) and encap id */ 17931 if ((rv = bcm_esw_wlan_port_get(unit, port, &wlan_port)) < 0) { 17932 soc_mem_unlock(unit, VLAN_TABm); 17933 return rv; 17934 } 17935 /* Check if wlan_port.port is a local port or trunk */ 17936 if (BCM_GPORT_IS_TRUNK(wlan_port.port)) { 17937 trunk_id = BCM_GPORT_TRUNK_GET(wlan_port.port); 17938 rv = _bcm_trunk_id_validate(unit, trunk_id); 17939 if (BCM_FAILURE(rv)) { 17940 soc_mem_unlock(unit, VLAN_TABm); 17941 return (BCM_E_PORT); 17942 } 17943 local_gport = wlan_port.port; 17944 } else { 17945 rv = _bcm_esw_gport_resolve(unit, wlan_port.port, &mod_out, &port_out, 17946 &trunk_id, &gport_id); 17947 if (BCM_FAILURE(rv)) { 17948 soc_mem_unlock(unit, VLAN_TABm); 17949 return (BCM_E_PORT); 17950 } 17951 rv = _bcm_esw_modid_is_local(unit, mod_out, &mod_local); 17952 if (BCM_FAILURE(rv)) { 17953 soc_mem_unlock(unit, VLAN_TABm); 17954 return rv; 17955 } 17956 if (TRUE != mod_local) { 17957 /* Only add this to replication set if destination is local */ 17958 soc_mem_unlock(unit, VLAN_TABm); 17959 return BCM_E_PORT; 17960 } 17961 /* Convert system local_port to physical local_port */ 17962 if (soc_feature(unit, soc_feature_sysport_remap)) { 17963 BCM_XLATE_SYSPORT_S2P(unit, &port_out); 17964 } 17965 rv = bcm_esw_port_gport_get(unit, port_out, &local_gport); 17966 if (BCM_FAILURE(rv)) { 17967 soc_mem_unlock(unit, VLAN_TABm); 17968 return rv; 17969 } 17970 } 17971 rv = bcm_esw_multicast_wlan_encap_get(unit, group, local_gport, 17972 port, &encap_id); 17973 if (BCM_FAILURE(rv)) { 17974 soc_mem_unlock(unit, VLAN_TABm); 17975 return rv; 17976 } 17977 17978 /* Remove from the WLAN MC group */ 17979 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 17980 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 17981 /* No group exists - this is an error*/ 17982 soc_mem_unlock(unit, VLAN_TABm); 17983 return BCM_E_PORT; 17984 } 17985 } 17986 17987 bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 17988 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, bc_idx); 17989 rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 17990 encap_id); 17991 17992 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 17993 if (mc_idx != bc_idx) { 17994 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx); 17995 rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 17996 encap_id); 17997 } 17998 17999 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 18000 if ((uuc_idx != bc_idx) && (uuc_idx != mc_idx)) { 18001 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, uuc_idx); 18002 rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 18003 encap_id); 18004 } 18005 18006 soc_mem_unlock(unit, VLAN_TABm); 18007 18008 } else if (soc_feature(unit, soc_feature_vlan_vp) && BCM_GPORT_IS_VLAN_PORT(port)) { 18009 #if defined(BCM_ENDURO_SUPPORT) 18010 if (SOC_IS_ENDURO(unit)) { 18011 rv = bcm_enduro_vlan_vp_delete(unit, vlan, port); 18012 } else 18013 #endif /* BCM_ENDURO_SUPPORT */ 18014 { 18015 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18016 } 18017 } else if (soc_feature(unit, soc_feature_niv) && 18018 BCM_GPORT_IS_NIV_PORT(port)) { 18019 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18020 } else if (soc_feature(unit, soc_feature_port_extension) && 18021 BCM_GPORT_IS_EXTENDER_PORT(port)) { 18022 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18023 } else if (soc_feature(unit, soc_feature_vp_lag) && 18024 BCM_GPORT_IS_TRUNK(port)) { 18025 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18026 } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 18027 BCM_GPORT_IS_SUBPORT_PORT(port)) { 18028 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18029 } else if (soc_feature(unit, soc_feature_vxlan) && 18030 BCM_GPORT_IS_VXLAN_PORT(port)) { 18031 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18032 } else if (soc_feature(unit, soc_feature_flex_flow) && 18033 BCM_GPORT_IS_FLOW_PORT(port)) { 18034 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18035 } else if (soc_feature(unit, soc_feature_l2gre) && 18036 BCM_GPORT_IS_L2GRE_PORT(port)) { 18037 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18038 } else if (soc_feature(unit, soc_feature_mim) && 18039 BCM_GPORT_IS_MIM_PORT(port)) { 18040 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18041 } else if (soc_feature(unit, soc_feature_mpls) && 18042 BCM_GPORT_IS_MPLS_PORT(port)) { 18043 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18044 } else if (BCM_GPORT_IS_VP_GROUP(port)) { 18045 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 18046 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 18047 if (soc_feature(unit, soc_feature_vlan_vfi_membership)){ 18048 rv = bcm_td2p_vlan_vp_group_set(unit, vlan, 18049 FALSE, BCM_GPORT_VP_GROUP_GET(port), FALSE); 18050 BCM_IF_ERROR_RETURN(rv); 18051 18052 rv = bcm_td2p_vlan_vp_group_set(unit, vlan, 18053 TRUE, BCM_GPORT_VP_GROUP_GET(port), FALSE); 18054 BCM_IF_ERROR_RETURN(rv); 18055 } else 18056 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 18057 { 18058 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 18059 rv = bcm_td_vlan_vp_group_set(unit,VLAN_TABLE(unit),vlan, 18060 BCM_GPORT_VP_GROUP_GET(port),FALSE); 18061 BCM_IF_ERROR_RETURN(rv); 18062 } 18063 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 18064 rv = bcm_td_vlan_vp_group_set(unit,EGR_VLANm,vlan, 18065 BCM_GPORT_VP_GROUP_GET(port), FALSE); 18066 BCM_IF_ERROR_RETURN(rv); 18067 } 18068 } 18069 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 18070 } else 18071 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 18072 { 18073 bcm_pbmp_t pbmp; 18074 bcm_port_t local_port; 18075 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 18076 uint32 filter_flags = 0; 18077 #endif 18078 18079 BCM_IF_ERROR_RETURN( 18080 bcm_esw_port_local_get(unit, port, &local_port)); 18081 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 18082 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 18083 if (_BCM_VPN_VFI_IS_SET(vlan) && BCM_GPORT_IS_MODPORT(port)) { 18084 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, local_port, &filter_flags)); 18085 if ((filter_flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 18086 (filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 18087 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18088 return rv; 18089 } 18090 } 18091 } 18092 #endif 18093 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 18094 if (soc_feature(unit, soc_feature_vlan_vfi_membership) && 18095 BCM_GPORT_IS_MODPORT(port)) { 18096 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, local_port, &filter_flags)); 18097 if (filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) { 18098 MOD_PORT_TO_GLP(unit, BCM_GPORT_MODPORT_MODID_GET(port), 18099 BCM_GPORT_MODPORT_PORT_GET(port), port); 18100 rv = bcm_td2_vp_vlan_membership_delete(unit, port, vlan); 18101 return rv; 18102 } 18103 } 18104 #endif 18105 BCM_PBMP_CLEAR(pbmp); 18106 BCM_PBMP_PORT_ADD(pbmp, local_port); 18107 rv = _bcm_vlan_port_remove(unit, vlan, pbmp, pbmp, pbmp, NULL); 18108 } 18109 return rv; 18110 } 18111 18112 /* 18113 * Function: 18114 * bcm_vlan_gport_extended_delete 18115 * Purpose: 18116 * Delete a Gport from the specified vlan. 18117 * Parameters: 18118 * unit - StrataSwitch PCI device unit number (driver internal). 18119 * vlan - VLAN ID to add port to as a member. 18120 * port - Gport ID 18121 * flags -BCM_VLAN_PORT_XXX 18122 * Returns: 18123 * BCM_E_NONE - Success. 18124 * BCM_E_INTERNAL - Chip access failure. 18125 * BCM_E_NOT_FOUND - VLAN ID not in use. 18126 */ 18127 int 18128 bcm_esw_vlan_gport_extended_delete(int unit, bcm_vlan_t vlan, 18129 bcm_gport_t port, int flags) 18130 { 18131 int rv = BCM_E_NONE; 18132 18133 #ifdef BCM_TOMAHAWK3_SUPPORT 18134 if (SOC_IS_TOMAHAWK3(unit)) { 18135 return 18136 bcm_tomahawk3_vlan_gport_extended_delete(unit, vlan, port, flags); 18137 } 18138 #endif 18139 18140 CHECK_INIT(unit); 18141 BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan)); 18142 18143 if (port == BCM_GPORT_INVALID) 18144 return BCM_E_PORT; 18145 18146 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 18147 if (soc_feature(unit, soc_feature_wlan) && BCM_GPORT_IS_WLAN_PORT(port)) { 18148 int vp, bc_idx,mc_idx,uuc_idx, gport_id, group = 0, mod_local; 18149 vlan_tab_entry_t vtab; 18150 bcm_wlan_port_t wlan_port; 18151 bcm_module_t mod_out; 18152 bcm_port_t port_out; 18153 bcm_trunk_t trunk_id; 18154 bcm_gport_t local_gport; 18155 bcm_if_t encap_id; 18156 18157 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 18158 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 18159 return BCM_E_NOT_FOUND; 18160 } 18161 sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t)); 18162 18163 soc_mem_lock(unit, VLAN_TABm); 18164 18165 if ((rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, 18166 &vtab)) < 0) { 18167 soc_mem_unlock(unit, VLAN_TABm); 18168 return rv; 18169 } 18170 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 18171 soc_mem_unlock(unit, VLAN_TABm); 18172 return BCM_E_NOT_FOUND; 18173 } 18174 18175 /* Get the VP attributes (need physical port) and encap id */ 18176 if ((rv = bcm_esw_wlan_port_get(unit, port, &wlan_port)) < 0) { 18177 soc_mem_unlock(unit, VLAN_TABm); 18178 return rv; 18179 } 18180 /* Check if wlan_port.port is a local port or trunk */ 18181 if (BCM_GPORT_IS_TRUNK(wlan_port.port)) { 18182 trunk_id = BCM_GPORT_TRUNK_GET(wlan_port.port); 18183 rv = _bcm_trunk_id_validate(unit, trunk_id); 18184 if (BCM_FAILURE(rv)) { 18185 soc_mem_unlock(unit, VLAN_TABm); 18186 return (BCM_E_PORT); 18187 } 18188 local_gport = wlan_port.port; 18189 } else { 18190 rv = _bcm_esw_gport_resolve(unit, wlan_port.port, &mod_out, &port_out, 18191 &trunk_id, &gport_id); 18192 if (BCM_FAILURE(rv)) { 18193 soc_mem_unlock(unit, VLAN_TABm); 18194 return (BCM_E_PORT); 18195 } 18196 rv = _bcm_esw_modid_is_local(unit, mod_out, &mod_local); 18197 if (BCM_FAILURE(rv)) { 18198 soc_mem_unlock(unit, VLAN_TABm); 18199 return rv; 18200 } 18201 if (TRUE != mod_local) { 18202 /* Only add this to replication set if destination is local */ 18203 soc_mem_unlock(unit, VLAN_TABm); 18204 return BCM_E_PORT; 18205 } 18206 /* Convert system local_port to physical local_port */ 18207 if (soc_feature(unit, soc_feature_sysport_remap)) { 18208 BCM_XLATE_SYSPORT_S2P(unit, &port_out); 18209 } 18210 rv = bcm_esw_port_gport_get(unit, port_out, &local_gport); 18211 if (BCM_FAILURE(rv)) { 18212 soc_mem_unlock(unit, VLAN_TABm); 18213 return rv; 18214 } 18215 } 18216 rv = bcm_esw_multicast_wlan_encap_get(unit, group, local_gport, 18217 port, &encap_id); 18218 if (BCM_FAILURE(rv)) { 18219 soc_mem_unlock(unit, VLAN_TABm); 18220 return rv; 18221 } 18222 18223 /* Remove from the WLAN MC group */ 18224 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 18225 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 18226 /* No group exists - this is an error*/ 18227 soc_mem_unlock(unit, VLAN_TABm); 18228 return BCM_E_PORT; 18229 } 18230 } 18231 18232 bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 18233 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, bc_idx); 18234 rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 18235 encap_id); 18236 18237 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 18238 if (mc_idx != bc_idx) { 18239 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx); 18240 rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 18241 encap_id); 18242 } 18243 18244 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 18245 if ((uuc_idx != bc_idx) && (uuc_idx != mc_idx)) { 18246 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, uuc_idx); 18247 rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 18248 encap_id); 18249 } 18250 18251 soc_mem_unlock(unit, VLAN_TABm); 18252 18253 } else if (soc_feature(unit, soc_feature_vlan_vp) && BCM_GPORT_IS_VLAN_PORT(port)) { 18254 #if defined(BCM_ENDURO_SUPPORT) 18255 if (SOC_IS_ENDURO(unit)) { 18256 rv = bcm_enduro_vlan_vp_delete(unit, vlan, port); 18257 } else 18258 #endif /* BCM_ENDURO_SUPPORT */ 18259 { 18260 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18261 } 18262 } else if (soc_feature(unit, soc_feature_niv) && 18263 BCM_GPORT_IS_NIV_PORT(port)) { 18264 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18265 } else if (soc_feature(unit, soc_feature_port_extension) && 18266 BCM_GPORT_IS_EXTENDER_PORT(port)) { 18267 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18268 } else if (soc_feature(unit, soc_feature_vp_lag) && 18269 BCM_GPORT_IS_TRUNK(port)) { 18270 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18271 } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 18272 BCM_GPORT_IS_SUBPORT_PORT(port)) { 18273 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18274 } else if (soc_feature(unit, soc_feature_vxlan) && 18275 BCM_GPORT_IS_VXLAN_PORT(port)) { 18276 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18277 } else if (soc_feature(unit, soc_feature_flex_flow) && 18278 BCM_GPORT_IS_FLOW_PORT(port)) { 18279 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18280 } else if (soc_feature(unit, soc_feature_l2gre) && 18281 BCM_GPORT_IS_L2GRE_PORT(port)) { 18282 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18283 } else if (soc_feature(unit, soc_feature_mim) && 18284 BCM_GPORT_IS_MIM_PORT(port)) { 18285 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18286 } else if (soc_feature(unit, soc_feature_mpls) && 18287 BCM_GPORT_IS_MPLS_PORT(port)) { 18288 rv = bcm_tr2_vlan_gport_delete(unit, vlan, port); 18289 } else if (BCM_GPORT_IS_VP_GROUP(port)) { 18290 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 18291 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 18292 if (soc_feature(unit, soc_feature_vlan_vfi_membership)){ 18293 rv = bcm_td2p_vlan_vp_group_set(unit, vlan, 18294 FALSE, BCM_GPORT_VP_GROUP_GET(port), FALSE); 18295 BCM_IF_ERROR_RETURN(rv); 18296 18297 rv = bcm_td2p_vlan_vp_group_set(unit, vlan, 18298 TRUE, BCM_GPORT_VP_GROUP_GET(port), FALSE); 18299 BCM_IF_ERROR_RETURN(rv); 18300 } else 18301 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 18302 { 18303 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 18304 rv = bcm_td_vlan_vp_group_set(unit,VLAN_TABm,vlan, 18305 BCM_GPORT_VP_GROUP_GET(port),FALSE); 18306 BCM_IF_ERROR_RETURN(rv); 18307 } 18308 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 18309 rv = bcm_td_vlan_vp_group_set(unit,EGR_VLANm,vlan, 18310 BCM_GPORT_VP_GROUP_GET(port), FALSE); 18311 BCM_IF_ERROR_RETURN(rv); 18312 } 18313 } 18314 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 18315 } else 18316 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 18317 { 18318 bcm_pbmp_t ing_pbmp, pbmp, ubmp; 18319 bcm_port_t local_port; 18320 int bc_idx, umc_idx, uuc_idx; 18321 int bc_do_not_update, umc_do_not_update, uuc_do_not_update; 18322 vlan_tab_entry_t vtab; 18323 soc_field_t group_types[3] = {0,0,0}; 18324 18325 /* If Ingress/Egress only flags are specified and 'ING_PORT_BITMAPf' is 18326 not a valid field in 'VLAN_TABm' AND if the 18327 'soc_feature_vlan_vfi_membership' is FALSE, return error. If the 18328 feature is TRUE, the mentioned field comes from the profiled 18329 'ING_VLAN_VFI_MEMBERSHIPm' table*/ 18330 if (flags & (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) { 18331 if (!soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf) && 18332 !(soc_feature(unit, soc_feature_vlan_vfi_membership))) { 18333 return BCM_E_PARAM; 18334 } 18335 } 18336 18337 if (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY) { 18338 if (!soc_feature(unit, soc_feature_vlan_egress_membership_l3_only)) { 18339 return BCM_E_PARAM; 18340 } 18341 } 18342 18343 BCM_IF_ERROR_RETURN( 18344 bcm_esw_port_local_get(unit, port, &local_port)); 18345 18346 BCM_IF_ERROR_RETURN 18347 (READ_VLAN_TABm(unit, MEM_BLOCK_ANY, vlan, &vtab)); 18348 18349 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 18350 bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 18351 umc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 18352 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 18353 18354 if (flags & BCM_VLAN_GPORT_BCAST_DO_NOT_UPDATE) { 18355 bc_do_not_update = 1; 18356 } else { 18357 bc_do_not_update = 0; 18358 } 18359 if (flags & BCM_VLAN_GPORT_UNKNOWN_MCAST_DO_NOT_UPDATE) { 18360 umc_do_not_update = 1; 18361 } else { 18362 umc_do_not_update = 0; 18363 } 18364 if (flags & BCM_VLAN_GPORT_UNKNOWN_UCAST_DO_NOT_UPDATE) { 18365 uuc_do_not_update = 1; 18366 } else { 18367 uuc_do_not_update = 0; 18368 } 18369 18370 if ((bc_idx == umc_idx) && (bc_do_not_update != umc_do_not_update)) { 18371 return BCM_E_PARAM; 18372 } 18373 if ((bc_idx == uuc_idx) && (bc_do_not_update != uuc_do_not_update)) { 18374 return BCM_E_PARAM; 18375 } 18376 if ((umc_idx == uuc_idx) && (umc_do_not_update != uuc_do_not_update)) { 18377 return BCM_E_PARAM; 18378 } 18379 18380 if (!bc_do_not_update) { 18381 group_types[0] = BC_IDXf; 18382 } 18383 if ((!umc_do_not_update) && (bc_idx != umc_idx)) { 18384 group_types[1] = UMC_IDXf; 18385 } 18386 if ((!uuc_do_not_update) && (uuc_idx != umc_idx) && (uuc_idx != bc_idx)) { 18387 group_types[2] = UUC_IDXf; 18388 } 18389 } 18390 if (flags & 18391 (BCM_VLAN_PORT_EGRESS_ONLY | BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 18392 BCM_PBMP_CLEAR(ing_pbmp); 18393 } else { 18394 BCM_PBMP_PORT_SET(ing_pbmp, local_port); 18395 } 18396 if (flags & BCM_VLAN_PORT_INGRESS_ONLY) { 18397 BCM_PBMP_CLEAR(pbmp); 18398 } else { 18399 BCM_PBMP_PORT_SET(pbmp, local_port); 18400 } 18401 if (flags & BCM_VLAN_PORT_UNTAGGED) { 18402 BCM_PBMP_PORT_SET(ubmp, local_port); 18403 } else { 18404 BCM_PBMP_CLEAR(ubmp); 18405 } 18406 rv = _bcm_vlan_port_remove(unit, vlan, pbmp, ubmp, ing_pbmp, group_types); 18407 } 18408 return rv; 18409 } 18410 18411 /* 18412 * Function: 18413 * bcm_vlan_gport_delete_all 18414 * Purpose: 18415 * Delete all Gports from the specified vlan. 18416 * Parameters: 18417 * unit - StrataSwitch PCI device unit number (driver internal). 18418 * vlan - VLAN ID to add port to as a member. 18419 * Returns: 18420 * BCM_E_NONE - Success. 18421 * BCM_E_INTERNAL - Chip access failure. 18422 * BCM_E_NOT_FOUND - VLAN ID not in use. 18423 */ 18424 int 18425 bcm_esw_vlan_gport_delete_all(int unit, bcm_vlan_t vlan) 18426 { 18427 int rv = BCM_E_NONE; 18428 bcm_pbmp_t pbmp, ubmp; 18429 18430 #ifdef BCM_TOMAHAWK3_SUPPORT 18431 if (SOC_IS_TOMAHAWK3(unit)) { 18432 return bcm_tomahawk3_vlan_gport_delete_all(unit, vlan); 18433 } 18434 #endif 18435 18436 CHECK_INIT(unit); 18437 18438 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 18439 if (soc_feature(unit, soc_feature_vlan_vfi) && 18440 _BCM_VPN_VFI_IS_SET(vlan)) { 18441 int vfi = 0; 18442 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan); 18443 if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeVlan)) { 18444 return bcm_tr2_vlan_gport_delete_all(unit, vlan); 18445 } 18446 } 18447 #endif /* BCM_TRIUMPH3_SUPPORT */ 18448 18449 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 18450 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 18451 if (_BCM_VPN_VFI_IS_SET(vlan)) { 18452 int vfi = 0; 18453 int vfi_max = soc_mem_index_max(unit, VFIm); 18454 18455 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan); 18456 if (vfi < 0 || vfi > vfi_max) { 18457 return (BCM_E_PARAM); 18458 } 18459 18460 if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) { 18461 return BCM_E_NOT_FOUND; 18462 } 18463 } else { 18464 VLAN_CHK_ID(unit, vlan); 18465 } 18466 18467 if (_BCM_VPN_VFI_IS_SET(vlan) || !SOC_IS_MONTEREY(unit)) { 18468 BCM_IF_ERROR_RETURN(bcm_td2_ing_vp_vlan_membership_delete_all(unit, vlan)); 18469 BCM_IF_ERROR_RETURN(bcm_td2_egr_vp_vlan_membership_delete_all(unit, vlan)); 18470 } 18471 if (_BCM_VPN_VFI_IS_SET(vlan)) { 18472 if (bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 18473 BCM_IF_ERROR_RETURN( 18474 bcm_td2p_vlan_vp_group_set(unit, vlan, FALSE, -1, FALSE)); 18475 } else { 18476 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_delete_all(unit, vlan, FALSE)); 18477 } 18478 if (bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 18479 BCM_IF_ERROR_RETURN( 18480 bcm_td2p_vlan_vp_group_set(unit, vlan, TRUE, -1, FALSE)); 18481 } else { 18482 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_delete_all(unit, vlan, TRUE)); 18483 } 18484 return BCM_E_NONE; 18485 } 18486 } 18487 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 18488 18489 VLAN_CHK_ID(unit, vlan); 18490 18491 soc_mem_lock(unit, VLAN_TABm); 18492 18493 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 18494 18495 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 18496 18497 int mc_idx,bc_idx,uuc_idx; 18498 bcm_multicast_t mc_group; 18499 vlan_tab_entry_t vtab; 18500 18501 sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t)); 18502 18503 if ((rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, 18504 &vtab)) < 0) { 18505 soc_mem_unlock(unit, VLAN_TABm); 18506 return rv; 18507 } 18508 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 18509 soc_mem_unlock(unit, VLAN_TABm); 18510 return BCM_E_NOT_FOUND; 18511 } 18512 18513 if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 18514 /* Remove all VP members and delete the group */ 18515 18516 bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 18517 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, bc_idx, 18518 &mc_group); 18519 if (BCM_FAILURE(rv)) { 18520 soc_mem_unlock(unit, VLAN_TABm); 18521 return rv; 18522 } 18523 if (_BCM_MULTICAST_IS_WLAN(mc_group)) { 18524 18525 rv = bcm_esw_multicast_egress_delete_all(unit, mc_group); 18526 if (BCM_FAILURE(rv)) { 18527 soc_mem_unlock(unit, VLAN_TABm); 18528 return rv; 18529 } 18530 rv = bcm_esw_multicast_destroy(unit, mc_group); 18531 if (BCM_FAILURE(rv)) { 18532 soc_mem_unlock(unit, VLAN_TABm); 18533 return rv; 18534 } 18535 18536 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf); 18537 if (mc_idx != bc_idx) { 18538 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, mc_idx, 18539 &mc_group); 18540 if (BCM_FAILURE(rv)) { 18541 soc_mem_unlock(unit, VLAN_TABm); 18542 return rv; 18543 } 18544 18545 rv = bcm_esw_multicast_egress_delete_all(unit, mc_group); 18546 if (BCM_FAILURE(rv)) { 18547 soc_mem_unlock(unit, VLAN_TABm); 18548 return rv; 18549 } 18550 18551 rv = bcm_esw_multicast_destroy(unit, mc_group); 18552 if (BCM_FAILURE(rv)) { 18553 soc_mem_unlock(unit, VLAN_TABm); 18554 return rv; 18555 } 18556 } 18557 18558 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf); 18559 if ((bc_idx != uuc_idx) && (mc_idx != uuc_idx)) { 18560 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, uuc_idx, 18561 &mc_group); 18562 if (BCM_FAILURE(rv)) { 18563 soc_mem_unlock(unit, VLAN_TABm); 18564 return rv; 18565 } 18566 18567 rv = bcm_esw_multicast_egress_delete_all(unit, mc_group); 18568 if (BCM_FAILURE(rv)) { 18569 soc_mem_unlock(unit, VLAN_TABm); 18570 return rv; 18571 } 18572 rv = bcm_esw_multicast_destroy(unit, mc_group); 18573 if (BCM_FAILURE(rv)) { 18574 soc_mem_unlock(unit, VLAN_TABm); 18575 return rv; 18576 } 18577 } 18578 18579 if (!SHR_BITGET(vlan_info[unit].vp_mode, vlan)) { 18580 soc_mem_field32_set(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf, 0); 18581 } 18582 18583 _bcm_xgs3_vlan_mcast_idx_set(unit, &vtab, BC_IDXf, 0); 18584 _bcm_xgs3_vlan_mcast_idx_set(unit, &vtab, UMC_IDXf, 0); 18585 _bcm_xgs3_vlan_mcast_idx_set(unit, &vtab, UUC_IDXf, 0); 18586 if ((rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, 18587 (int)vlan, &vtab)) < 0) { 18588 soc_mem_unlock(unit, VLAN_TABm); 18589 return rv; 18590 } 18591 } else if (_BCM_MULTICAST_IS_VLAN(mc_group)) { 18592 #if defined(BCM_ENDURO_SUPPORT) 18593 if (SOC_IS_ENDURO(unit)) { 18594 rv = bcm_enduro_vlan_vp_delete_all(unit, vlan); 18595 } else 18596 #endif /* BCM_ENDURO_SUPPORT */ 18597 { 18598 rv = bcm_tr2_vlan_gport_delete_all(unit, vlan); 18599 } 18600 if (BCM_FAILURE(rv)) { 18601 soc_mem_unlock(unit, VLAN_TABm); 18602 return rv; 18603 } 18604 } else if (_BCM_MULTICAST_IS_NIV(mc_group) || 18605 _BCM_MULTICAST_IS_EXTENDER(mc_group)) { 18606 rv = bcm_tr2_vlan_gport_delete_all(unit, vlan); 18607 if (BCM_FAILURE(rv)) { 18608 soc_mem_unlock(unit, VLAN_TABm); 18609 return rv; 18610 } 18611 } else { 18612 /* Invalid multicast group type */ 18613 soc_mem_unlock(unit, VLAN_TABm); 18614 return BCM_E_INTERNAL; 18615 } 18616 18617 /* check if it is vp group unmanaged mode */ 18618 #if defined(BCM_TRIDENT_SUPPORT) 18619 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 18620 if (soc_feature(unit, soc_feature_vlan_vfi_membership)){ 18621 if (bcm_td2p_ing_vp_group_unmanaged_get(unit)) { 18622 /* clear the vp group bitmap for this vlan */ 18623 rv = bcm_td2p_vlan_vp_group_set(unit, vlan, FALSE, -1, FALSE); 18624 if (rv != BCM_E_NONE) { 18625 soc_mem_unlock(unit, VLAN_TABm); 18626 return rv; 18627 } 18628 } 18629 if (bcm_td2p_egr_vp_group_unmanaged_get(unit)) { 18630 /* clear the vp group bitmap for this vlan */ 18631 rv = bcm_td2p_vlan_vp_group_set(unit, vlan, TRUE, -1, FALSE); 18632 if (rv != BCM_E_NONE) { 18633 soc_mem_unlock(unit, VLAN_TABm); 18634 return rv; 18635 } 18636 } 18637 } else 18638 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 18639 { 18640 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) && 18641 bcm_td_ing_vp_group_unmanaged_get(unit)) { 18642 /* clear the vp group bitmap for this vlan */ 18643 rv = bcm_td_vlan_vp_group_set(unit,VLAN_TABLE(unit),vlan, -1,FALSE); 18644 if (rv != BCM_E_NONE) { 18645 soc_mem_unlock(unit, VLAN_TABm); 18646 return rv; 18647 } 18648 } 18649 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership) && 18650 bcm_td_egr_vp_group_unmanaged_get(unit)) { 18651 /* clear the vp group bitmap for this vlan */ 18652 rv = bcm_td_vlan_vp_group_set(unit,EGR_VLANm,vlan, -1,FALSE); 18653 if (rv != BCM_E_NONE) { 18654 soc_mem_unlock(unit, VLAN_TABm); 18655 return rv; 18656 } 18657 } 18658 } 18659 #endif /* BCM_TRIDENT_SUPPORT */ 18660 } 18661 } 18662 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 18663 18664 /* Now remove all local physical ports */ 18665 BCM_PBMP_CLEAR(pbmp); 18666 BCM_PBMP_CLEAR(ubmp); 18667 rv = bcm_esw_vlan_port_get(unit, vlan, &pbmp, &ubmp); 18668 if (BCM_FAILURE(rv)) { 18669 soc_mem_unlock(unit, VLAN_TABm); 18670 return rv; 18671 } 18672 rv = bcm_esw_vlan_port_remove(unit, vlan, pbmp); 18673 soc_mem_unlock(unit, VLAN_TABm); 18674 18675 return rv; 18676 } 18677 18678 int 18679 bcm_esw_vlan_gport_get(int unit, bcm_vlan_t vlan, bcm_gport_t port, 18680 int *flags) 18681 { 18682 int rv = BCM_E_NONE; 18683 bcm_pbmp_t pbmp, ubmp, ing_pbmp; 18684 18685 #ifdef BCM_TOMAHAWK3_SUPPORT 18686 if (SOC_IS_TOMAHAWK3(unit)) { 18687 return bcm_tomahawk3_vlan_gport_get(unit, vlan, port, flags); 18688 } 18689 #endif 18690 18691 CHECK_INIT(unit); 18692 18693 /* VFI types like VxLAN passes in a VFI and not VLAN, hence check one 18694 or the other */ 18695 BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan)); 18696 18697 if (port == BCM_GPORT_INVALID) 18698 return BCM_E_PORT; 18699 18700 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 18701 if (soc_feature(unit, soc_feature_wlan) && BCM_GPORT_IS_WLAN_PORT(port)) { 18702 int idx, vp, mc_idx, gport_id, group = 0, mod_local; 18703 vlan_tab_entry_t vtab; 18704 bcm_wlan_port_t wlan_port; 18705 bcm_module_t mod_out; 18706 bcm_port_t port_out=0; 18707 bcm_trunk_t trunk_id; 18708 bcm_port_t trunk_member_port[SOC_MAX_NUM_PORTS]; 18709 bcm_gport_t local_gport; 18710 bcm_if_t encap_id; 18711 bcm_if_t *if_array = NULL; 18712 int alloc_size, if_count, if_cur, if_max, match, trunk_local_ports = 0; 18713 18714 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 18715 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 18716 return BCM_E_NOT_FOUND; 18717 } 18718 sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t)); 18719 18720 BCM_IF_ERROR_RETURN 18721 (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, &vtab)); 18722 18723 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 18724 return BCM_E_NOT_FOUND; 18725 } 18726 18727 /* Get the VP attributes (need physical port) and encap id */ 18728 BCM_IF_ERROR_RETURN(bcm_esw_wlan_port_get(unit, port, &wlan_port)); 18729 /* Check if wlan_port.port is a local port or trunk */ 18730 if (BCM_GPORT_IS_TRUNK(wlan_port.port)) { 18731 trunk_id = BCM_GPORT_TRUNK_GET(wlan_port.port); 18732 rv = _bcm_trunk_id_validate(unit, trunk_id); 18733 if (BCM_FAILURE(rv)) { 18734 return (BCM_E_PORT); 18735 } 18736 rv = _bcm_esw_trunk_local_members_get(unit, trunk_id, 18737 SOC_MAX_NUM_PORTS, trunk_member_port, &trunk_local_ports); 18738 if (BCM_FAILURE(rv)) { 18739 return (BCM_E_PORT); 18740 } 18741 local_gport = wlan_port.port; 18742 } else { 18743 rv = _bcm_esw_gport_resolve(unit, wlan_port.port, &mod_out, &port_out, 18744 &trunk_id, &gport_id); 18745 if (BCM_FAILURE(rv)) { 18746 return (BCM_E_PORT); 18747 } 18748 rv = _bcm_esw_modid_is_local(unit, mod_out, &mod_local); 18749 BCM_IF_ERROR_RETURN(rv); 18750 if (TRUE != mod_local) { 18751 /* Only add this to replication set if destination is local */ 18752 return BCM_E_PORT; 18753 } 18754 /* Convert system local_port to physical local_port */ 18755 if (soc_feature(unit, soc_feature_sysport_remap)) { 18756 BCM_XLATE_SYSPORT_S2P(unit, &port_out); 18757 } 18758 rv = bcm_esw_port_gport_get(unit, port_out, &local_gport); 18759 if (BCM_FAILURE(rv)) { 18760 return rv; 18761 } 18762 } 18763 BCM_IF_ERROR_RETURN 18764 (bcm_esw_multicast_wlan_encap_get(unit, group, local_gport, 18765 port, &encap_id)); 18766 18767 /* Search the WLAN MC group */ 18768 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) { 18769 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) { 18770 /* No group exists - so not found */ 18771 return BCM_E_NOT_FOUND; 18772 } 18773 } 18774 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 18775 _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx); 18776 18777 /* If trunk, iterate over all local ports in the trunk and search for 18778 * a match on any local port */ 18779 if_max = soc_mem_index_count(unit, EGR_L3_INTFm) + 18780 soc_mem_index_count(unit, EGR_L3_NEXT_HOPm); 18781 alloc_size = if_max * sizeof(int); 18782 if_array = sal_alloc(alloc_size, "temp IPMC repl interface array"); 18783 if (if_array == NULL) { 18784 return BCM_E_MEMORY; 18785 } 18786 match = FALSE; 18787 if (BCM_GPORT_IS_TRUNK(wlan_port.port)) { 18788 for (idx = 0; idx < trunk_local_ports; idx++) { 18789 rv = bcm_esw_ipmc_egress_intf_get(unit, mc_idx, 18790 trunk_member_port[idx], 18791 if_max, if_array, &if_count); 18792 if (BCM_SUCCESS(rv)) { 18793 for (if_cur = 0; if_cur < if_count; if_cur++) { 18794 if (if_array[if_cur] == encap_id) { 18795 match = TRUE; 18796 *flags = 0; 18797 break; 18798 } 18799 } 18800 if (match) { 18801 break; 18802 } 18803 } 18804 } 18805 } else { 18806 rv = bcm_esw_ipmc_egress_intf_get(unit, mc_idx, port_out, if_max, 18807 if_array, &if_count); 18808 if (BCM_SUCCESS(rv)) { 18809 for (if_cur = 0; if_cur < if_count; if_cur++) { 18810 if (if_array[if_cur] == encap_id) { 18811 match = TRUE; 18812 *flags = 0; 18813 break; 18814 } 18815 } 18816 } 18817 } 18818 #ifdef BCM_TRIUMPH3_SUPPORT 18819 /* Triumph3 WLAN axp port to match replication interface */ 18820 if (SOC_IS_TRIUMPH3(unit) && 18821 _BCM_MULTICAST_IS_WLAN(group)) { 18822 port_out = AXP_PORT(unit, SOC_AXP_NLF_WLAN_ENCAP); 18823 rv = bcm_esw_ipmc_egress_intf_get(unit, mc_idx, port_out, if_max, 18824 if_array, &if_count); 18825 if (BCM_SUCCESS(rv)) { 18826 match = FALSE; 18827 for (if_cur = 0; if_cur < if_count; if_cur++) { 18828 if (if_array[if_cur] == encap_id) { 18829 match = TRUE; 18830 *flags = 0; 18831 break; 18832 } 18833 } 18834 18835 } 18836 } 18837 #endif /* BCM_TRIUMPH3_SUPPORT */ 18838 18839 if (!match) { 18840 rv = BCM_E_NOT_FOUND; 18841 } 18842 sal_free(if_array); 18843 18844 } else if (soc_feature(unit, soc_feature_vlan_vp) && BCM_GPORT_IS_VLAN_PORT(port)) { 18845 #if defined(BCM_ENDURO_SUPPORT) 18846 if (SOC_IS_ENDURO(unit)) { 18847 rv = bcm_enduro_vlan_vp_get(unit, vlan, port, flags); 18848 } else 18849 #endif /* BCM_ENDURO_SUPPORT */ 18850 { 18851 /* coverity[stack_use_callee] */ 18852 /* coverity[stack_use_overflow] */ 18853 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18854 } 18855 18856 } else if (soc_feature(unit, soc_feature_niv) && 18857 BCM_GPORT_IS_NIV_PORT(port)) { 18858 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18859 } else if (soc_feature(unit, soc_feature_port_extension) && 18860 BCM_GPORT_IS_EXTENDER_PORT(port)) { 18861 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18862 } else if (soc_feature(unit, soc_feature_vp_lag) && 18863 BCM_GPORT_IS_TRUNK(port)) { 18864 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18865 } else if (soc_feature(unit, soc_feature_vxlan) && 18866 BCM_GPORT_IS_VXLAN_PORT(port)) { 18867 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18868 } else if (soc_feature(unit, soc_feature_flex_flow) && 18869 BCM_GPORT_IS_FLOW_PORT(port)) { 18870 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18871 } else if (soc_feature(unit, soc_feature_l2gre) && 18872 BCM_GPORT_IS_L2GRE_PORT(port)) { 18873 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18874 } else if (soc_feature(unit, soc_feature_mim) && 18875 BCM_GPORT_IS_MIM_PORT(port)) { 18876 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18877 } else if (soc_feature(unit, soc_feature_mpls) && 18878 BCM_GPORT_IS_MPLS_PORT(port)) { 18879 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18880 } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 18881 BCM_GPORT_IS_SUBPORT_PORT(port)) { 18882 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18883 } else if (BCM_GPORT_IS_VP_GROUP(port)) { 18884 #if defined(BCM_TRIDENT_SUPPORT) 18885 int enable; 18886 int vpg = BCM_GPORT_VP_GROUP_GET(port); 18887 18888 *flags=0; 18889 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 18890 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 18891 bcm_stg_t stg; 18892 int ut_state; 18893 int hw_stp_state; 18894 18895 BCM_IF_ERROR_RETURN( 18896 bcm_td2p_vlan_vp_group_get(unit, vlan, FALSE, vpg, &enable)); 18897 if (enable) { 18898 *flags = BCM_VLAN_PORT_INGRESS_ONLY; 18899 18900 BCM_IF_ERROR_RETURN( 18901 bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vlan, FALSE, &stg)); 18902 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_state_get( 18903 unit, stg, port, FALSE, &hw_stp_state)); 18904 *flags |= _bcm_td2_stp_state_to_flags(unit, hw_stp_state, FALSE); 18905 } 18906 18907 BCM_IF_ERROR_RETURN( 18908 bcm_td2p_vlan_vp_group_get(unit, vlan, TRUE, vpg, &enable)); 18909 if (enable) { 18910 *flags |= BCM_VLAN_PORT_EGRESS_ONLY; 18911 18912 BCM_IF_ERROR_RETURN( 18913 bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vlan, TRUE, &stg)); 18914 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_state_get( 18915 unit, stg, port, TRUE, &hw_stp_state)); 18916 *flags |= _bcm_td2_stp_state_to_flags(unit, hw_stp_state, TRUE); 18917 18918 if (!_BCM_VPN_VFI_IS_SET(vlan)) { 18919 BCM_IF_ERROR_RETURN( 18920 bcm_td2p_vp_group_ut_state_get(unit, port, vlan, &ut_state)); 18921 if (ut_state) { 18922 *flags |= BCM_VLAN_GPORT_ADD_UNTAGGED; 18923 } 18924 } 18925 #if defined(BCM_TRIDENT3_SUPPORT) 18926 else if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) { 18927 BCM_IF_ERROR_RETURN( 18928 bcm_td2p_vp_group_ut_state_get(unit, port, vlan, &ut_state)); 18929 if (ut_state) { 18930 *flags |= BCM_VLAN_GPORT_ADD_UNTAGGED; 18931 } 18932 } 18933 #endif 18934 } 18935 } else 18936 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 18937 { 18938 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) { 18939 BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_get( 18940 unit, VLAN_TABLE(unit), vlan, vpg, &enable)); 18941 if (enable) { 18942 *flags = BCM_VLAN_PORT_INGRESS_ONLY; 18943 } 18944 } 18945 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 18946 BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_get( 18947 unit, EGR_VLANm, vlan,vpg, &enable)); 18948 if (enable) { 18949 *flags |= BCM_VLAN_PORT_EGRESS_ONLY; 18950 } 18951 } 18952 } 18953 #endif /* BCM_TRIDENT_SUPPORT */ 18954 18955 } else 18956 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 18957 18958 { 18959 bcm_port_t local_port; 18960 uint32 local_flags; 18961 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 18962 uint32 filter_flags = 0; 18963 #endif 18964 18965 BCM_IF_ERROR_RETURN( 18966 bcm_esw_port_local_get(unit, port, &local_port)); 18967 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 18968 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 18969 if (_BCM_VPN_VFI_IS_SET(vlan) && BCM_GPORT_IS_MODPORT(port)) { 18970 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, local_port, &filter_flags)); 18971 if ((filter_flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 18972 (filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 18973 rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags); 18974 return rv; 18975 } 18976 } 18977 } 18978 #endif 18979 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 18980 if (soc_feature(unit, soc_feature_vlan_vfi_membership) && 18981 BCM_GPORT_IS_MODPORT(port)) { 18982 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, local_port, &filter_flags)); 18983 if (filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) { 18984 MOD_PORT_TO_GLP(unit, BCM_GPORT_MODPORT_MODID_GET(port), 18985 BCM_GPORT_MODPORT_PORT_GET(port), port); 18986 rv = bcm_td2_vp_vlan_membership_get(unit, port, vlan, flags); 18987 return rv; 18988 } 18989 } 18990 #endif 18991 /* Deal with local physical ports */ 18992 rv = _bcm_vlan_port_get(unit, vlan, &pbmp, &ubmp, &ing_pbmp); 18993 local_flags = 0; 18994 if (!BCM_PBMP_MEMBER(pbmp, local_port)) { 18995 local_flags |= BCM_VLAN_PORT_INGRESS_ONLY; 18996 } 18997 if (!BCM_PBMP_MEMBER(ing_pbmp, local_port)) { 18998 local_flags |= BCM_VLAN_PORT_EGRESS_ONLY; 18999 } 19000 if (local_flags == 19001 (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) { 19002 return BCM_E_NOT_FOUND; 19003 } 19004 if (BCM_PBMP_MEMBER(ubmp, local_port)) { 19005 local_flags |= BCM_VLAN_PORT_UNTAGGED; 19006 } 19007 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 19008 if (soc_feature(unit, soc_feature_vlan_egress_membership_l3_only) && 19009 (local_flags & BCM_VLAN_PORT_EGRESS_ONLY) && BCM_VLAN_VALID(vlan)) { 19010 bcm_pbmp_t vlan_tab_pbmp; 19011 BCM_IF_ERROR_RETURN 19012 (_bcm_xgs3_vlan_table_port_get(unit, vlan, &vlan_tab_pbmp, 19013 NULL, NULL, VLAN_TABLE(unit))); 19014 if (!BCM_PBMP_MEMBER(vlan_tab_pbmp, local_port)) { 19015 local_flags &= ~BCM_VLAN_PORT_EGRESS_ONLY; 19016 local_flags |= BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY; 19017 } 19018 } 19019 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_HURRICANE3_SUPPORT */ 19020 *flags = local_flags; 19021 } 19022 19023 return rv; 19024 } 19025 19026 int 19027 bcm_esw_vlan_gport_get_all(int unit, bcm_vlan_t vlan, int array_max, 19028 bcm_gport_t *gport_array, int *flags_array, 19029 int* array_size) 19030 { 19031 bcm_pbmp_t pbmp, ubmp, ing_pbmp, bmp; 19032 bcm_port_t port, gport; 19033 bcm_module_t modid; 19034 int port_cnt = 0, is_vfi = 0; 19035 _bcm_gport_dest_t gport_dest; 19036 vlan_tab_entry_t vtab; 19037 uint32 local_flags; 19038 19039 #ifdef BCM_TOMAHAWK3_SUPPORT 19040 if (SOC_IS_TOMAHAWK3(unit)) { 19041 return 19042 bcm_tomahawk3_vlan_gport_get_all( 19043 unit, vlan, array_max, gport_array, flags_array, array_size); 19044 } 19045 #endif 19046 19047 CHECK_INIT(unit); 19048 19049 if (NULL == array_size || array_max < 0) { 19050 return BCM_E_PARAM; 19051 } 19052 19053 if ((array_max > 0) && (NULL == gport_array)) { 19054 return BCM_E_PARAM; 19055 } 19056 19057 /* 19058 * VFI types like VxLAN passes in a VFI and not VLAN, 19059 * hence check one or the other 19060 */ 19061 BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan)); 19062 19063 if(_BCM_VPN_VFI_IS_SET(vlan)) { 19064 is_vfi = 1; 19065 } 19066 19067 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 19068 if (soc_feature(unit, soc_feature_vlan_vfi) && is_vfi) { 19069 return bcm_tr2_vlan_gport_get_all(unit, vlan, array_max, 19070 gport_array, flags_array, array_size); 19071 } 19072 #endif /* BCM_TRIUMPH3_SUPPORT */ 19073 19074 if(!is_vfi) { 19075 19076 BCM_IF_ERROR_RETURN( 19077 soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, &vtab)); 19078 if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) { 19079 return BCM_E_NOT_FOUND; 19080 } 19081 19082 port_cnt = 0; 19083 19084 BCM_IF_ERROR_RETURN 19085 (_bcm_vlan_port_get(unit, vlan, &pbmp, &ubmp, &ing_pbmp)); 19086 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid)); 19087 19088 /* Prepare a superset of bitmaps to itterate over */ 19089 BCM_PBMP_ASSIGN(bmp, pbmp); 19090 BCM_PBMP_OR(bmp, ubmp); 19091 BCM_PBMP_OR(bmp, ing_pbmp); 19092 19093 BCM_PBMP_ITER(bmp, port) { 19094 if ((port_cnt == array_max) && (gport_array)) { 19095 break; 19096 } 19097 gport_dest.port = port; 19098 gport_dest.modid = modid; 19099 gport_dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 19100 BCM_IF_ERROR_RETURN( 19101 _bcm_esw_gport_construct(unit, &gport_dest, &gport)); 19102 local_flags = 0; 19103 if (!BCM_PBMP_MEMBER(pbmp, port)) { 19104 local_flags |= BCM_VLAN_PORT_INGRESS_ONLY; 19105 } 19106 if (!BCM_PBMP_MEMBER(ing_pbmp, port)) { 19107 local_flags |= BCM_VLAN_PORT_EGRESS_ONLY; 19108 } 19109 if (local_flags == 19110 (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) { 19111 continue; 19112 } 19113 if (flags_array) { 19114 if (BCM_PBMP_MEMBER(ubmp, port)) { 19115 local_flags |= BCM_VLAN_PORT_UNTAGGED; 19116 } 19117 flags_array[port_cnt] = local_flags; 19118 } 19119 if (gport_array) { 19120 gport_array[port_cnt] = gport; 19121 } 19122 port_cnt++; 19123 } 19124 } /* !is_vfi */ 19125 19126 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 19127 /* Check existance of virtual ports */ 19128 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf) && !is_vfi) { 19129 int get_all_from_tr2 = 0; 19130 if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf) && 19131 (port_cnt < array_max)) { 19132 int mc_idx; 19133 bcm_multicast_t mc_group; 19134 19135 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf); 19136 BCM_IF_ERROR_RETURN 19137 (_bcm_tr_multicast_ipmc_group_type_get(unit, mc_idx, 19138 &mc_group)); 19139 if (_BCM_MULTICAST_IS_WLAN(mc_group)) { 19140 int i, local_size; 19141 19142 if (gport_array) { 19143 BCM_IF_ERROR_RETURN( 19144 bcm_esw_multicast_egress_get(unit, mc_group, 19145 array_max - port_cnt, (gport_array + port_cnt), 19146 NULL, &local_size)); 19147 for (i = 0; i < local_size; i++) { 19148 if ((port_cnt == array_max) && (gport_array)) { 19149 break; 19150 } 19151 if (flags_array) { 19152 flags_array[port_cnt] = BCM_VLAN_PORT_UNTAGGED; 19153 } 19154 port_cnt++; 19155 } 19156 } 19157 } else if (_BCM_MULTICAST_IS_VLAN(mc_group)) { 19158 if (gport_array) { 19159 #if defined(BCM_ENDURO_SUPPORT) 19160 if (SOC_IS_ENDURO(unit)) { 19161 int local_size; 19162 if (flags_array) { 19163 BCM_IF_ERROR_RETURN 19164 (bcm_enduro_vlan_vp_get_all 19165 (unit, vlan, array_max - port_cnt, 19166 &gport_array[port_cnt], &flags_array[port_cnt], 19167 &local_size)); 19168 } else { 19169 BCM_IF_ERROR_RETURN 19170 (bcm_enduro_vlan_vp_get_all 19171 (unit, vlan, array_max - port_cnt, 19172 &gport_array[port_cnt], NULL, &local_size)); 19173 } 19174 port_cnt += local_size; 19175 } else 19176 #endif /* BCM_ENDURO_SUPPORT */ 19177 { 19178 int local_size; 19179 if (flags_array) { 19180 BCM_IF_ERROR_RETURN 19181 (bcm_tr2_vlan_gport_get_all 19182 (unit, vlan, array_max - port_cnt, 19183 &gport_array[port_cnt], &flags_array[port_cnt], 19184 &local_size)); 19185 } else { 19186 BCM_IF_ERROR_RETURN 19187 (bcm_tr2_vlan_gport_get_all 19188 (unit, vlan, array_max - port_cnt, 19189 &gport_array[port_cnt], NULL, &local_size)); 19190 } 19191 port_cnt += local_size; 19192 } 19193 } 19194 get_all_from_tr2 = 1; 19195 } else if (_BCM_MULTICAST_IS_NIV(mc_group) || 19196 _BCM_MULTICAST_IS_EXTENDER(mc_group)) { 19197 int local_size; 19198 if (gport_array) { 19199 if (flags_array) { 19200 BCM_IF_ERROR_RETURN 19201 (bcm_tr2_vlan_gport_get_all 19202 (unit, vlan, array_max - port_cnt, 19203 &gport_array[port_cnt], &flags_array[port_cnt], 19204 &local_size)); 19205 } else { 19206 BCM_IF_ERROR_RETURN 19207 (bcm_tr2_vlan_gport_get_all 19208 (unit, vlan, array_max - port_cnt, 19209 &gport_array[port_cnt], NULL, &local_size)); 19210 } 19211 port_cnt += local_size; 19212 } 19213 get_all_from_tr2 = 1; 19214 } else { 19215 /* Unrecognized multicast type */ 19216 return BCM_E_INTERNAL; 19217 } 19218 } 19219 19220 if (!get_all_from_tr2 && 19221 (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT3X(unit) || 19222 SOC_IS_APACHE(unit))) { 19223 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 19224 BCM_IF_ERROR_RETURN( 19225 bcm_td2p_vp_vlan_membership_get_all(unit, vlan, 19226 array_max, gport_array, flags_array, &port_cnt)); 19227 #endif 19228 } 19229 } 19230 #if defined(BCM_TRIDENT_SUPPORT) 19231 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 19232 if (is_vfi) { 19233 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership) || 19234 soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 19235 BCM_IF_ERROR_RETURN(bcm_td2p_vp_vlan_membership_get_all(unit, vlan, 19236 array_max, gport_array, flags_array, &port_cnt)); 19237 } 19238 } 19239 19240 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 19241 BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vp_group_get_all(unit,vlan, 19242 array_max, gport_array,flags_array,&port_cnt)); 19243 } else 19244 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 19245 #if defined(BCM_TRIDENT2_SUPPORT) 19246 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT2(unit) || 19247 SOC_IS_APACHE(unit)) { 19248 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership) || 19249 soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 19250 BCM_IF_ERROR_RETURN(bcm_td2_vp_vlan_membership_get_all(unit, vlan, 19251 array_max, gport_array, flags_array, &port_cnt)); 19252 } 19253 } else 19254 #endif 19255 { 19256 BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_get_all(unit,vlan, 19257 array_max, gport_array,flags_array,&port_cnt)); 19258 } 19259 #endif /* BCM_TRIDENT_SUPPORT */ 19260 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 19261 19262 /* If all attempts found nothing return not found */ 19263 if (!port_cnt) { 19264 return BCM_E_NOT_FOUND; 19265 } 19266 19267 *array_size = port_cnt; 19268 return BCM_E_NONE; 19269 } 19270 19271 /* 19272 * Function: 19273 * bcm_esw_vlan_port_create 19274 * Purpose: 19275 * Create a VLAN virtual port. 19276 * Parameters: 19277 * unit - (IN) SOC unit number. 19278 * vlan_port - (IN/OUT) Pointer to a VLAN virtual port structure. 19279 * Returns: 19280 * BCM_X_XXX 19281 */ 19282 int 19283 bcm_esw_vlan_port_create(int unit, 19284 bcm_vlan_port_t *vlan_port) 19285 { 19286 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 19287 if (soc_feature(unit, soc_feature_vlan_vp)) { 19288 #if defined(BCM_ENDURO_SUPPORT) 19289 if (SOC_IS_ENDURO(unit)) { 19290 return bcm_enduro_vlan_vp_create(unit, vlan_port); 19291 } else 19292 #endif /* BCM_ENDURO_SUPPORT */ 19293 { 19294 return bcm_tr2_vlan_vp_create(unit, vlan_port); 19295 } 19296 } 19297 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 19298 19299 return BCM_E_UNAVAIL; 19300 } 19301 19302 /* 19303 * Function: 19304 * bcm_esw_vlan_port_destroy 19305 * Purpose: 19306 * Destroy a VLAN virtual port. 19307 * Parameters: 19308 * unit - (IN) SOC unit number. 19309 * gport - (IN) VLAN virtual port GPORT ID. 19310 * Returns: 19311 * BCM_X_XXX 19312 */ 19313 int 19314 bcm_esw_vlan_port_destroy(int unit, 19315 bcm_gport_t gport) 19316 { 19317 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 19318 if (soc_feature(unit, soc_feature_vlan_vp)) { 19319 #if defined(BCM_ENDURO_SUPPORT) 19320 if (SOC_IS_ENDURO(unit)) { 19321 return bcm_enduro_vlan_vp_destroy(unit, gport); 19322 } else 19323 #endif /* BCM_ENDURO_SUPPORT */ 19324 { 19325 return bcm_tr2_vlan_vp_destroy(unit, gport); 19326 } 19327 } 19328 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 19329 19330 return BCM_E_UNAVAIL; 19331 } 19332 19333 /* 19334 * Function: 19335 * bcm_esw_vlan_port_find 19336 * Purpose: 19337 * Get VLAN virtual port info. 19338 * Parameters: 19339 * unit - (IN) SOC unit number. 19340 * vlan_port - (IN/OUT) Pointer to VLAN virtual port structure. 19341 * Returns: 19342 * BCM_X_XXX 19343 */ 19344 int 19345 bcm_esw_vlan_port_find(int unit, 19346 bcm_vlan_port_t *vlan_port) 19347 { 19348 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 19349 if (soc_feature(unit, soc_feature_vlan_vp)) { 19350 #if defined(BCM_ENDURO_SUPPORT) 19351 if (SOC_IS_ENDURO(unit)) { 19352 return bcm_enduro_vlan_vp_find(unit, vlan_port); 19353 } else 19354 #endif /* BCM_ENDURO_SUPPORT */ 19355 { 19356 return bcm_tr2_vlan_vp_find(unit, vlan_port); 19357 } 19358 } 19359 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 19360 19361 return BCM_E_UNAVAIL; 19362 } 19363 19364 /* 19365 * Function: 19366 * _bcm_esw_vlan_port_source_vp_lag_set 19367 * Purpose: 19368 * Set source VP LAG for a VLAN virtual port. 19369 * Parameters: 19370 * unit - (IN) SOC unit number. 19371 * gport - (IN) VLAN virtual port GPORT ID. 19372 * vp_lag_vp - (IN) VP representing the VP LAG. 19373 * Returns: 19374 * BCM_X_XXX 19375 */ 19376 int 19377 _bcm_esw_vlan_port_source_vp_lag_set(int unit, bcm_gport_t gport, 19378 int vp_lag_vp) 19379 { 19380 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 19381 if (soc_feature(unit, soc_feature_vlan_vp) && 19382 soc_feature(unit, soc_feature_vp_lag)) { 19383 return bcm_td2_vlan_vp_source_vp_lag_set(unit, gport, vp_lag_vp); 19384 } 19385 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 19386 19387 return BCM_E_UNAVAIL; 19388 } 19389 19390 /* 19391 * Function: 19392 * _bcm_esw_vlan_port_source_vp_lag_clear 19393 * Purpose: 19394 * Clear source VP LAG for a VLAN virtual port. 19395 * Parameters: 19396 * unit - (IN) SOC unit number. 19397 * gport - (IN) VLAN virtual port GPORT ID. 19398 * vp_lag_vp - (IN) VP representing the VP LAG. 19399 * Returns: 19400 * BCM_X_XXX 19401 */ 19402 int 19403 _bcm_esw_vlan_port_source_vp_lag_clear(int unit, bcm_gport_t gport, 19404 int vp_lag_vp) 19405 { 19406 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 19407 if (soc_feature(unit, soc_feature_vlan_vp) && 19408 soc_feature(unit, soc_feature_vp_lag)) { 19409 return bcm_td2_vlan_vp_source_vp_lag_clear(unit, gport, vp_lag_vp); 19410 } 19411 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 19412 19413 return BCM_E_UNAVAIL; 19414 } 19415 19416 /* 19417 * Function: 19418 * _bcm_esw_vlan_port_source_vp_lag_get 19419 * Purpose: 19420 * Get source VP LAG for a VLAN virtual port. 19421 * Parameters: 19422 * unit - (IN) SOC unit number. 19423 * gport - (IN) VLAN virtual port GPORT ID. 19424 * vp_lag_vp - (OUT) VP representing the VP LAG. 19425 * Returns: 19426 * BCM_X_XXX 19427 */ 19428 int 19429 _bcm_esw_vlan_port_source_vp_lag_get(int unit, bcm_gport_t gport, 19430 int *vp_lag_vp) 19431 { 19432 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 19433 if (soc_feature(unit, soc_feature_vlan_vp) && 19434 soc_feature(unit, soc_feature_vp_lag)) { 19435 return bcm_td2_vlan_vp_source_vp_lag_get(unit, gport, vp_lag_vp); 19436 } 19437 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 19438 19439 return BCM_E_UNAVAIL; 19440 } 19441 19442 #define VALID_VLAN_ID(vid) \ 19443 ((((vid) >= 0) && ((vid) <= BCM_VLAN_MAX)) || (vid == BCM_VLAN_INVALID)) 19444 19445 /* 19446 * Function: 19447 * _bcm_esw_vlan_system_reserved_set 19448 * Purpose: 19449 * Set ingress or egress system reserved VLAN 19450 * Parameters: 19451 * unit - Device unit number 19452 * arg - VLAN 19453 * Returns: 19454 * BCM_E_XXX 19455 */ 19456 int 19457 _bcm_esw_vlan_system_reserved_set(int unit, int arg) 19458 { 19459 int rv = BCM_E_UNAVAIL; 19460 if (VALID_VLAN_ID(arg)) { 19461 #ifdef BCM_TRX_SUPPORT 19462 if (soc_feature(unit, soc_feature_system_reserved_vlan)) { 19463 rv = _bcm_trx_system_reserved_vlan_ing_set(unit, arg); 19464 if (SOC_SUCCESS(rv)) { 19465 rv = _bcm_trx_system_reserved_vlan_egr_set(unit, arg); 19466 } 19467 } 19468 #endif 19469 } else { 19470 rv = BCM_E_PARAM; 19471 } 19472 19473 return rv; 19474 } 19475 19476 /* 19477 * Function: 19478 * _bcm_esw_vlan_system_reserved_get 19479 * Purpose: 19480 * Get ingress or egress system reserved VLAN 19481 * Parameters: 19482 * unit - Device unit number 19483 * arg - pointer to VLAN 19484 * Returns: 19485 * BCM_E_XXX 19486 */ 19487 int 19488 _bcm_esw_vlan_system_reserved_get(int unit, int *arg) 19489 { 19490 int rv = BCM_E_UNAVAIL; 19491 19492 if (arg != NULL) { 19493 #ifdef BCM_TRX_SUPPORT 19494 if (soc_feature(unit, soc_feature_system_reserved_vlan)) { 19495 rv = _bcm_trx_system_reserved_vlan_ing_get(unit, arg); 19496 } 19497 #endif 19498 } else { 19499 rv = BCM_E_PARAM; 19500 } 19501 return rv; 19502 } 19503 19504 /* 19505 * Function: 19506 * _bcm_vlan_count_get 19507 * Purpose: 19508 * Retrieves the number of VLAN created in the system 19509 * Parameters: 19510 * unit - Device unit number 19511 * arg - Vlan Count 19512 * Returns: 19513 * BCM_E_XXX 19514 */ 19515 int 19516 _bcm_vlan_count_get(int unit, int *arg) 19517 { 19518 bcm_vlan_info_t *vi = &vlan_info[unit]; 19519 19520 if (arg == NULL) { 19521 return (BCM_E_PARAM); 19522 } 19523 19524 if (vi->init != TRUE) { 19525 return (BCM_E_INIT); 19526 } 19527 19528 *arg = vi->count; 19529 return (BCM_E_NONE); 19530 } 19531 19532 #ifdef BCM_WARM_BOOT_SUPPORT 19533 /* 19534 * _bcm_vlan_reinit 19535 * 19536 * Recover VLAN state from hardware (reload) 19537 */ 19538 STATIC int 19539 _bcm_vlan_reinit(int unit) 19540 { 19541 bcm_vlan_info_t *vi = &vlan_info[unit]; 19542 int rv; 19543 soc_scache_handle_t scache_handle; 19544 uint8 *vlan_scache_ptr; 19545 uint8 flood_mode; 19546 int qm_num = 0; 19547 int qm_bmp_size; 19548 int i; 19549 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 19550 uint8 ing_vp_group_flag = 0; 19551 uint8 egr_vp_group_flag = 0; 19552 #endif 19553 uint16 recovered_ver = BCM_WB_VERSION_1_0; 19554 int additional_scache_size = 0; 19555 19556 /* Clean up existing vlan_info */ 19557 vi->init = TRUE; 19558 BCM_IF_ERROR_RETURN 19559 (_bcm_vlan_cleanup(unit)); 19560 19561 #ifdef BCM_MCAST_FLOOD_DEFAULT 19562 BCM_IF_ERROR_RETURN 19563 (_bcm_esw_vlan_flood_default_set(unit, BCM_MCAST_FLOOD_DEFAULT)); 19564 #else 19565 BCM_IF_ERROR_RETURN 19566 (_bcm_esw_vlan_flood_default_set(unit, 19567 BCM_VLAN_MCAST_FLOOD_UNKNOWN)); 19568 #endif 19569 19570 /* VLAN Queue Map */ 19571 #ifdef BCM_TRIUMPH2_SUPPORT 19572 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 19573 int qm_size; 19574 19575 if (vi->qm_bmp != NULL) { 19576 sal_free(vi->qm_bmp); 19577 } 19578 if (vi->qm_it_bmp != NULL) { 19579 sal_free(vi->qm_it_bmp); 19580 } 19581 19582 qm_num = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm, 19583 PHB2_DOT1P_MAPPING_PTRf); 19584 19585 qm_size = SHR_BITALLOCSIZE(qm_num); 19586 vi->qm_bmp = sal_alloc(qm_size, "VLAN queue mapping bitmap"); 19587 if (vi->qm_bmp == NULL) { 19588 return BCM_E_MEMORY; 19589 } 19590 sal_memset(vi->qm_bmp, 0, qm_size); 19591 vi->qm_it_bmp = sal_alloc(qm_size, "VLAN queue mapping bitmap"); 19592 if (vi->qm_it_bmp == NULL) { 19593 return BCM_E_MEMORY; 19594 } 19595 sal_memset(vi->qm_it_bmp, 0, qm_size); 19596 } 19597 #endif 19598 19599 if (SOC_IS_SHADOW(unit)) { /* Shadow doesn't implement VLAN module */ 19600 return BCM_E_NONE; 19601 } 19602 19603 /* 19604 * Initialize software structures 19605 */ 19606 vi->defl = BCM_VLAN_DEFAULT; 19607 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VLAN, 0); 19608 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 19609 0, &vlan_scache_ptr, 19610 BCM_WB_DEFAULT_VERSION, &recovered_ver); 19611 if (rv == SOC_E_NOT_FOUND) { 19612 /* Use non-Level 2 case */ 19613 } else if (SOC_FAILURE(rv)) { 19614 return rv; 19615 } else { 19616 /* Success, recover default VLAN */ 19617 sal_memcpy(&vi->defl, vlan_scache_ptr, sizeof(vi->defl)); 19618 vlan_scache_ptr += sizeof(vi->defl); 19619 19620 /* VLAN XLATE OLD counter */ 19621 sal_memcpy(&vi->old_egr_xlate_cnt, vlan_scache_ptr, 19622 sizeof(vi->old_egr_xlate_cnt)); 19623 vlan_scache_ptr += sizeof(vi->old_egr_xlate_cnt); 19624 19625 /* Flood mode */ 19626 /* Type for 'flood_mode' is an enum, which values fit in uint8 */ 19627 sal_memcpy(&flood_mode, vlan_scache_ptr, sizeof(flood_mode)); 19628 vi->flood_mode = flood_mode; 19629 vlan_scache_ptr += sizeof(flood_mode); 19630 19631 /* VLAN Queue Map */ 19632 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 19633 qm_bmp_size = _SHR_BITDCLSIZE(qm_num); 19634 for (i = 0; i < qm_bmp_size; i++) { 19635 sal_memcpy(&vi->qm_bmp[i], vlan_scache_ptr, 19636 sizeof(SHR_BITDCL)); 19637 vlan_scache_ptr += sizeof(SHR_BITDCL); 19638 } 19639 for (i = 0; i < qm_bmp_size; i++) { 19640 sal_memcpy(&vi->qm_it_bmp[i], vlan_scache_ptr, 19641 sizeof(SHR_BITDCL)); 19642 vlan_scache_ptr += sizeof(SHR_BITDCL); 19643 } 19644 } 19645 19646 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 19647 /* recover vp group unmanaged flags */ 19648 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) || 19649 soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 19650 19651 sal_memcpy(&ing_vp_group_flag, vlan_scache_ptr, 19652 sizeof(ing_vp_group_flag)); 19653 vlan_scache_ptr += sizeof(ing_vp_group_flag); 19654 sal_memcpy(&egr_vp_group_flag, vlan_scache_ptr, 19655 sizeof(egr_vp_group_flag)); 19656 vlan_scache_ptr += sizeof(egr_vp_group_flag); 19657 } 19658 #endif 19659 19660 if (recovered_ver >= BCM_WB_VERSION_1_1) { 19661 /* recover VLAN VP Multicast control mode */ 19662 sal_memcpy(&vi->vp_mode, vlan_scache_ptr, 19663 sizeof(vi->vp_mode)); 19664 vlan_scache_ptr += sizeof(vi->vp_mode); 19665 } else { 19666 additional_scache_size += sizeof(vi->vp_mode); 19667 } 19668 19669 #ifdef BCM_TRIDENT3_SUPPORT 19670 if (soc_feature(unit, soc_feature_pvlan_on_vfi)) { 19671 if (recovered_ver >= BCM_WB_VERSION_1_2) { 19672 sal_memcpy(&vi->shared_vlan_enable, vlan_scache_ptr, 19673 sizeof(vi->shared_vlan_enable)); 19674 vlan_scache_ptr += sizeof(vi->shared_vlan_enable); 19675 } else { 19676 uint64 val64 = 0; 19677 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &val64)); 19678 vi->shared_vlan_enable = 19679 soc_reg64_field32_get(unit, ING_CONFIG_64r, val64, SVL_ENABLEf); 19680 additional_scache_size += sizeof(vi->shared_vlan_enable); 19681 } 19682 } 19683 #endif 19684 19685 if (additional_scache_size > 0) { 19686 BCM_IF_ERROR_RETURN( 19687 soc_scache_realloc(unit, scache_handle, additional_scache_size)); 19688 } 19689 } 19690 19691 vi->count = 0; 19692 vi->init = TRUE; 19693 19694 BCM_IF_ERROR_RETURN 19695 (_bcm_vbmp_init(&vi->bmp)); 19696 BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->pre_cfg_bmp)); 19697 19698 BCM_IF_ERROR_RETURN 19699 (mbcm_driver[unit]->mbcm_vlan_reload(unit, &vi->bmp, &vi->count)); 19700 19701 if (0 == _BCM_VBMP_LOOKUP(vi->bmp, vi->defl)) { 19702 LOG_WARN(BSL_LS_BCM_VLAN, 19703 (BSL_META_U(unit, 19704 "Warm Reboot: Default VLAN %4d does not exist!\n"), 19705 vi->defl)); 19706 } 19707 19708 #ifdef BCM_FIREBOLT_SUPPORT 19709 if (SOC_IS_FBX(unit) && !SOC_IS_TRX(unit)) { 19710 /* Recreate software state for vlan translation */ 19711 19712 /* 19713 * NOTE: Skipped for TRX. 19714 * VLAN translation for TRX happens in 19715 * _bcm_trx_vlan_action_profile_init(). This routine is 19716 * called by the PORT module. 19717 * 19718 * TRX uses its own data cache tables ing_action_profile[], 19719 * egr_action_profileuse[], rather than 'ing_trans', 'egr_trans' in 19720 * the common vlan_info[]. 19721 */ 19722 BCM_IF_ERROR_RETURN 19723 (_bcm_fb_vlan_translate_reload(unit, BCM_VLAN_XLATE_ING)); 19724 BCM_IF_ERROR_RETURN 19725 (_bcm_fb_vlan_translate_reload(unit, BCM_VLAN_XLATE_EGR)); 19726 } 19727 #endif 19728 19729 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 19730 if (soc_feature(unit, soc_feature_vlan_vp)) { 19731 #ifdef BCM_ENDURO_SUPPORT 19732 if (SOC_IS_ENDURO(unit)) { 19733 BCM_IF_ERROR_RETURN(bcm_enduro_vlan_virtual_init(unit)); 19734 } else 19735 #endif /* BCM_ENDURO_SUPPORT */ 19736 { 19737 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_virtual_init(unit)); 19738 } 19739 } 19740 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 19741 19742 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 19743 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 19744 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 19745 (void)bcm_td2p_ing_vp_group_unmanaged_set(unit, ing_vp_group_flag); 19746 (void)bcm_td2p_egr_vp_group_unmanaged_set(unit, egr_vp_group_flag); 19747 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_init(unit)); 19748 } else 19749 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 19750 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) || 19751 soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 19752 (void)bcm_td_ing_vp_group_unmanaged_set(unit,ing_vp_group_flag); 19753 (void)bcm_td_egr_vp_group_unmanaged_set(unit,egr_vp_group_flag); 19754 BCM_IF_ERROR_RETURN(bcm_td_vp_group_init(unit)); 19755 19756 } 19757 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 19758 19759 return BCM_E_NONE; 19760 } 19761 19762 /* 19763 * Function: 19764 * _bcm_vlan_cleanup 19765 * Purpose: 19766 * Free up resources without touching hardware 19767 * Parameters: 19768 * unit - StrataSwitch PCI device unit number (driver internal). 19769 * Returns: 19770 * BCM_E_NONE - Success. 19771 */ 19772 int 19773 _bcm_vlan_cleanup(int unit) 19774 { 19775 bcm_vlan_info_t *vi; 19776 19777 CHECK_INIT(unit); 19778 19779 BCM_LOCK(unit); 19780 vi = &vlan_info[unit]; 19781 _bcm_vbmp_destroy(&vi->bmp); 19782 if (vi->qm_bmp != NULL) { 19783 sal_free(vi->qm_bmp); 19784 } 19785 if (vi->qm_it_bmp != NULL) { 19786 sal_free(vi->qm_it_bmp); 19787 } 19788 if (vi->egr_trans != NULL) { 19789 sal_free(vi->egr_trans); 19790 } 19791 if (vi->ing_trans != NULL) { 19792 sal_free(vi->ing_trans); 19793 } 19794 sal_memset(vi, 0, sizeof(bcm_vlan_info_t)); 19795 BCM_UNLOCK(unit); 19796 19797 return BCM_E_NONE; 19798 } 19799 19800 /* 19801 * Function: 19802 * _bcm_esw_vlan_sync 19803 * Purpose: 19804 * Record VLAN module persisitent info for Level 2 Warm Boot 19805 * Parameters: 19806 * unit - StrataSwitch unit number. 19807 * Returns: 19808 * BCM_E_XXX 19809 */ 19810 19811 int 19812 _bcm_esw_vlan_sync(int unit) 19813 { 19814 bcm_vlan_info_t *vi = &vlan_info[unit]; 19815 soc_scache_handle_t scache_handle; 19816 uint8 *vlan_scache_ptr; 19817 uint8 flood_mode; 19818 int qm_bmp_size; 19819 int i; 19820 19821 #ifdef BCM_TOMAHAWK3_SUPPORT 19822 if (SOC_IS_TOMAHAWK3(unit)) { 19823 return _bcm_th3_vlan_sync(unit); 19824 } 19825 #endif 19826 19827 CHECK_INIT(unit); 19828 19829 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VLAN, 0); 19830 BCM_IF_ERROR_RETURN 19831 (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 19832 0, &vlan_scache_ptr, 19833 BCM_WB_DEFAULT_VERSION, NULL)); 19834 /* Default VLAN */ 19835 sal_memcpy(vlan_scache_ptr, &vi->defl, sizeof(vi->defl)); 19836 vlan_scache_ptr += sizeof(vi->defl); 19837 19838 /* VLAN XLATE OLD counter */ 19839 sal_memcpy(vlan_scache_ptr, &vi->old_egr_xlate_cnt, 19840 sizeof(vi->old_egr_xlate_cnt)); 19841 vlan_scache_ptr += sizeof(vi->old_egr_xlate_cnt); 19842 19843 /* Flood mode */ 19844 /* Type for 'flood_mode' is an enum, which values fit in uint8 */ 19845 flood_mode = vlan_info[unit].flood_mode; 19846 sal_memcpy(vlan_scache_ptr, &flood_mode, sizeof(flood_mode)); 19847 vlan_scache_ptr += sizeof(flood_mode); 19848 19849 /* VLAN Queue Map */ 19850 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 19851 qm_bmp_size = _SHR_BITDCLSIZE 19852 (1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm, 19853 PHB2_DOT1P_MAPPING_PTRf)); 19854 for (i = 0; i < qm_bmp_size; i++) { 19855 sal_memcpy(vlan_scache_ptr, &vi->qm_bmp[i], sizeof(SHR_BITDCL)); 19856 vlan_scache_ptr += sizeof(SHR_BITDCL); 19857 } 19858 for (i = 0; i < qm_bmp_size; i++) { 19859 sal_memcpy(vlan_scache_ptr, &vi->qm_it_bmp[i], sizeof(SHR_BITDCL)); 19860 vlan_scache_ptr += sizeof(SHR_BITDCL); 19861 } 19862 } 19863 19864 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 19865 /* vp group unmanaged flags */ 19866 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 19867 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 19868 uint8 flag = 0; 19869 19870 flag = (uint8)bcm_td2p_ing_vp_group_unmanaged_get(unit); 19871 sal_memcpy(vlan_scache_ptr, &flag, sizeof(flag)); 19872 vlan_scache_ptr += sizeof(flag); 19873 flag = (uint8)bcm_td2p_egr_vp_group_unmanaged_get(unit); 19874 sal_memcpy(vlan_scache_ptr, &flag, sizeof(flag)); 19875 vlan_scache_ptr += sizeof(flag); 19876 } else 19877 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 19878 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) || 19879 soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 19880 uint8 flag = 0; 19881 19882 flag = (uint8)bcm_td_ing_vp_group_unmanaged_get(unit); 19883 sal_memcpy(vlan_scache_ptr, &flag, sizeof(flag)); 19884 vlan_scache_ptr += sizeof(flag); 19885 flag = (uint8)bcm_td_egr_vp_group_unmanaged_get(unit); 19886 sal_memcpy(vlan_scache_ptr, &flag, sizeof(flag)); 19887 vlan_scache_ptr += sizeof(flag); 19888 } 19889 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 19890 19891 if (BCM_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_1) { 19892 /* sync VLAN info VP Multicast control mode */ 19893 sal_memcpy(vlan_scache_ptr, &vi->vp_mode, 19894 sizeof(vi->vp_mode)); 19895 vlan_scache_ptr += sizeof(vi->vp_mode); 19896 } 19897 19898 #ifdef BCM_TRIDENT3_SUPPORT 19899 if (soc_feature(unit, soc_feature_pvlan_on_vfi)) { 19900 if (BCM_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_2) { 19901 sal_memcpy(vlan_scache_ptr, &vi->shared_vlan_enable, 19902 sizeof(vi->shared_vlan_enable)); 19903 vlan_scache_ptr += sizeof(vi->shared_vlan_enable); 19904 } 19905 } 19906 #endif 19907 return BCM_E_NONE; 19908 } 19909 #endif /* BCM_WARM_BOOT_SUPPORT */ 19910 19911 19912 #ifndef BCM_SW_STATE_DUMP_DISABLE 19913 /* 19914 * Function: 19915 * _bcm_vlan_compar 19916 * Purpose: 19917 * Compares two VLAN IDs. Used by sorting utility routine 19918 * Parameters: 19919 * a - Pointer to first VLAN ID of type bcm_vlan_t to compare 19920 * b - Pointer to second VLAN ID of type bcm_vlan_t to compare 19921 * Returns: 19922 * 0 If vlan1 == vlan2 19923 * -1 If vlan1 < vlan2 19924 * 1 If vlan1 > vlan2 19925 */ 19926 int 19927 _bcm_vlan_compar(void *a, void *b) 19928 { 19929 bcm_vlan_t vlan1, vlan2; 19930 19931 vlan1 = *(bcm_vlan_t *)a; 19932 vlan2 = *(bcm_vlan_t *)b; 19933 19934 return ( (vlan1 < vlan2) ? -1 : ((vlan1 > vlan2) ? 1 : 0)); 19935 } 19936 19937 /* 19938 * Function: 19939 * _bcm_vlan_sw_dump 19940 * Purpose: 19941 * Displays VLAN software structure information. 19942 * Parameters: 19943 * unit - Device unit number 19944 * Returns: 19945 * None 19946 */ 19947 void 19948 _bcm_vlan_sw_dump(int unit) 19949 { 19950 int i; 19951 bcm_vlan_info_t *vi = &vlan_info[unit]; 19952 int vlan_count = 0; 19953 #ifdef BCM_FIREBOLT_SUPPORT 19954 int ixmem, index_min, count; 19955 soc_mem_t mem; 19956 uint32 *vtcachep, vtcache; 19957 #endif /* BCM_FIREBOLT_SUPPORT */ 19958 19959 LOG_CLI((BSL_META_U(unit, 19960 "\nSW Information VLAN\n"))); 19961 LOG_CLI((BSL_META_U(unit, 19962 " Init : %4d\n"), vi->init)); 19963 LOG_CLI((BSL_META_U(unit, 19964 " Default : %4d\n"), vi->defl)); 19965 LOG_CLI((BSL_META_U(unit, 19966 " Flood Mode : %4d\n"), vi->flood_mode)); 19967 LOG_CLI((BSL_META_U(unit, 19968 " Count : %4d\n"), vi->count)); 19969 19970 /* Print VLAN list sorted */ 19971 LOG_CLI((BSL_META_U(unit, 19972 " List :"))); 19973 for (i = BCM_VLAN_MIN; i < BCM_VLAN_COUNT; i++) { 19974 if (0 == _BCM_VBMP_LOOKUP(vi->bmp, i)){ 19975 continue; 19976 } 19977 if ((vlan_count > 0) && (!(vlan_count % 10))) { 19978 LOG_CLI((BSL_META_U(unit, 19979 "\n "))); 19980 } 19981 LOG_CLI((BSL_META_U(unit, 19982 " %4d"), i)); 19983 vlan_count++; 19984 if (vi->count == vlan_count) { 19985 break; 19986 } 19987 } 19988 LOG_CLI((BSL_META_U(unit, 19989 "\n"))); 19990 19991 #ifdef BCM_FIREBOLT_SUPPORT 19992 if (soc_feature(unit, soc_feature_vlan_translation)) { 19993 LOG_CLI((BSL_META_U(unit, 19994 "\n VLAN translation :"))); 19995 19996 for (ixmem = 0; ixmem < 2; ixmem++) { 19997 if (ixmem == 1) { 19998 mem = EGR_VLAN_XLATEm; 19999 vtcachep = vlan_info[unit].egr_trans; 20000 if (vtcachep == NULL) { 20001 continue; 20002 } 20003 LOG_CLI((BSL_META_U(unit, 20004 "\n\n Egress :"))); 20005 } else { 20006 mem = VLAN_XLATEm; 20007 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 20008 mem = VLAN_XLATE_1_DOUBLEm; 20009 } 20010 vtcachep = vlan_info[unit].ing_trans; 20011 if (vtcachep == NULL) { 20012 continue; 20013 } 20014 LOG_CLI((BSL_META_U(unit, 20015 "\n Ingress :"))); 20016 } 20017 20018 if (!SOC_MEM_IS_VALID(unit, mem)) { 20019 continue; 20020 } 20021 20022 index_min = soc_mem_index_min(unit, mem); 20023 count = soc_mem_index_count(unit, mem); 20024 for (i = 0; i < count; i++) { 20025 vtcache = vtcachep[index_min + i]; 20026 if (BCM_VTCACHE_VALID_GET(vtcache)) { 20027 LOG_CLI((BSL_META_U(unit, 20028 "\n Entry %d: Port %s, VLAN 0x%03x%s"), 20029 i, 20030 SOC_PORT_NAME(unit, BCM_VTCACHE_PORT_GET(vtcache)), 20031 BCM_VTCACHE_VID_GET(vtcache), 20032 BCM_VTCACHE_ADD_GET(vtcache) ? ", Add" : "")); 20033 } 20034 } 20035 } 20036 LOG_CLI((BSL_META_U(unit, 20037 "\n"))); 20038 } 20039 #endif /* BCM_FIREBOLT_SUPPORT */ 20040 20041 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || defined(BCM_RAPTOR_SUPPORT) 20042 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_TRX(unit) || 20043 SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 20044 _bcm_fb2_vlan_profile_sw_dump(unit); 20045 } 20046 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAPTOR_SUPPORT */ 20047 20048 #if defined(BCM_TRX_SUPPORT) 20049 #if defined(BCM_TOMAHAWK3_SUPPORT) 20050 if (SOC_IS_TOMAHAWK3(unit)) { 20051 _bcm_th3_vlan_sw_tag_action_profile_dump(unit); 20052 } else 20053 #endif 20054 if (SOC_IS_TRX(unit)) { 20055 _bcm_trx_vlan_sw_dump(unit); 20056 } 20057 #endif /* BCM_TRX_SUPPORT */ 20058 20059 /* VLAN Queue Map */ 20060 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 20061 int qm_num; 20062 int count = 0; 20063 int inner; 20064 20065 LOG_CLI((BSL_META_U(unit, 20066 "\nSW Information VLAN Queue Map\n"))); 20067 qm_num = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm, 20068 PHB2_DOT1P_MAPPING_PTRf); 20069 20070 if (vi->qm_bmp != NULL) { 20071 for (i = 0; i < qm_num; i++) { 20072 if (!SHR_BITGET(vlan_info[unit].qm_bmp, i)) { 20073 continue; 20074 } 20075 if ((count > 0) && (!(count % 10))) { 20076 LOG_CLI((BSL_META_U(unit, 20077 "\n "))); 20078 } 20079 if (!SHR_BITGET(vlan_info[unit].qm_it_bmp, i)) { 20080 inner = 0; 20081 } else { 20082 inner = 1; 20083 } 20084 LOG_CLI((BSL_META_U(unit, 20085 " %2d(%1d)"), i, inner)); 20086 count++; 20087 } 20088 LOG_CLI((BSL_META_U(unit, 20089 "\n"))); 20090 } 20091 } 20092 20093 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 20094 if (soc_feature(unit, soc_feature_vlan_vp)) { 20095 #ifdef BCM_ENDURO_SUPPORT 20096 if (SOC_IS_ENDURO(unit)) { 20097 bcm_enduro_vlan_vp_sw_dump(unit); 20098 } else 20099 #endif /* BCM_ENDURO_SUPPORT */ 20100 { 20101 bcm_tr2_vlan_vp_sw_dump(unit); 20102 } 20103 } 20104 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 20105 20106 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 20107 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 20108 if (soc_feature(unit, soc_feature_vlan_vfi_membership)){ 20109 bcm_td2p_vp_group_sw_dump(unit); 20110 } else 20111 #endif 20112 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) || 20113 soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) { 20114 bcm_td_vp_group_sw_dump(unit); 20115 } 20116 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 20117 20118 return; 20119 } 20120 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 20121 20122 #if defined(INCLUDE_L3) 20123 /* 20124 * Function: 20125 * bcm_esw_vlan_vpn_create 20126 * Purpose: 20127 * Create a VPN instance 20128 * Parameters: 20129 * unit - (IN) Device Number 20130 * info - (IN/OUT) VPN configuration info 20131 * Returns: 20132 * BCM_E_XXX 20133 */ 20134 int 20135 bcm_esw_vlan_vpn_create(int unit, bcm_vlan_vpn_config_t *info) 20136 { 20137 #if defined(BCM_TRIUMPH3_SUPPORT) 20138 int rv = BCM_E_PARAM; 20139 vfi_entry_t vfi_entry; 20140 int vfi_index = -1; 20141 int bc_group = 0, umc_group = 0, uuc_group = 0; 20142 int bc_group_type = 0, umc_group_type = 0, uuc_group_type = 0; 20143 20144 if (!soc_feature(unit, soc_feature_vlan_vfi)) { 20145 return BCM_E_UNAVAIL; 20146 } 20147 20148 if (info == NULL) { 20149 return BCM_E_PARAM; 20150 } 20151 20152 if (!(info->flags & (BCM_VLAN_VPN_ELINE | BCM_VLAN_VPN_ELAN))) { 20153 return BCM_E_PARAM; 20154 } 20155 20156 /*Allocate VFI*/ 20157 if (info->flags & BCM_VLAN_VPN_WITH_ID) { 20158 rv = _bcm_tr3_vlan_vpn_is_valid(unit, info->vpn); 20159 if (BCM_E_NONE == rv) { 20160 return BCM_E_EXISTS; 20161 } else if (BCM_E_NOT_FOUND != rv) { 20162 return rv; 20163 } 20164 20165 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, info->vpn); 20166 BCM_IF_ERROR_RETURN(_bcm_vfi_alloc_with_id(unit, VFIm, _bcmVfiTypeVlan, vfi_index)); 20167 } else { 20168 BCM_IF_ERROR_RETURN(_bcm_vfi_alloc(unit, VFIm, _bcmVfiTypeVlan, &vfi_index)); 20169 _BCM_VPN_SET(info->vpn, _BCM_VPN_TYPE_VFI, vfi_index); 20170 } 20171 20172 /*Initial and configure VFI*/ 20173 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 20174 if (info->flags & BCM_VLAN_VPN_ELINE) { 20175 soc_VFIm_field32_set(unit, &vfi_entry, PT2PT_ENf, 0x1); 20176 } else if (info->flags & BCM_VLAN_VPN_ELAN) { 20177 /* Check that the groups are valid. */ 20178 bc_group_type = _BCM_MULTICAST_TYPE_GET(info->broadcast_group); 20179 bc_group = _BCM_MULTICAST_ID_GET(info->broadcast_group); 20180 umc_group_type = _BCM_MULTICAST_TYPE_GET(info->unknown_multicast_group); 20181 umc_group = _BCM_MULTICAST_ID_GET(info->unknown_multicast_group); 20182 uuc_group_type = _BCM_MULTICAST_TYPE_GET(info->unknown_unicast_group); 20183 uuc_group = _BCM_MULTICAST_ID_GET(info->unknown_unicast_group); 20184 20185 if ((bc_group_type != _BCM_MULTICAST_TYPE_VLAN) || 20186 (umc_group_type != _BCM_MULTICAST_TYPE_VLAN) || 20187 (uuc_group_type != _BCM_MULTICAST_TYPE_VLAN) || 20188 (bc_group >= soc_mem_index_count(unit, L3_IPMCm)) || 20189 (umc_group >= soc_mem_index_count(unit, L3_IPMCm)) || 20190 (uuc_group >= soc_mem_index_count(unit, L3_IPMCm))) { 20191 (void) _bcm_vfi_free(unit, _bcmVfiTypeVlan, vfi_index); 20192 return BCM_E_PARAM; 20193 } 20194 20195 /* Commit the entry to HW */ 20196 soc_VFIm_field32_set(unit, &vfi_entry, UMC_INDEXf, umc_group); 20197 soc_VFIm_field32_set(unit, &vfi_entry, UUC_INDEXf, uuc_group); 20198 soc_VFIm_field32_set(unit, &vfi_entry, BC_INDEXf, bc_group); 20199 } 20200 20201 /*Write VFI to ASIC*/ 20202 rv = WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry); 20203 if (rv < 0) { 20204 (void) _bcm_vfi_free(unit, _bcmVfiTypeVlan, vfi_index); 20205 } 20206 20207 return BCM_E_NONE; 20208 #else 20209 return BCM_E_UNAVAIL; 20210 #endif /* BCM_TRIUMPH3_SUPPORT */ 20211 } 20212 20213 /* 20214 * Function: 20215 * bcm_esw_vlan_vpn_destroy 20216 * Purpose: 20217 * Delete a VPN instance 20218 * Parameters: 20219 * unit - Device Number 20220 * vpn - VPN instance ID 20221 * Returns: 20222 * BCM_E_XXX 20223 */ 20224 int bcm_esw_vlan_vpn_destroy(int unit, bcm_vpn_t vpn) 20225 { 20226 #if defined(BCM_TRIUMPH3_SUPPORT) 20227 int vfi = 0; 20228 20229 if (!soc_feature(unit, soc_feature_vlan_vfi)) { 20230 return BCM_E_UNAVAIL; 20231 } 20232 20233 /* Get vfi index */ 20234 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_vpn_is_valid(unit, vpn)); 20235 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn); 20236 20237 /* Delete all VLAN ports on this VPN */ 20238 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_vp_destroy_all(unit, vpn)); 20239 20240 /* Reset VFI table */ 20241 (void) _bcm_vfi_free(unit, _bcmVfiTypeVlan, vfi); 20242 20243 return BCM_E_NONE; 20244 #else 20245 return BCM_E_UNAVAIL; 20246 #endif /* BCM_TRIUMPH3_SUPPORT */ 20247 } 20248 20249 /* Function: 20250 * bcm_esw_vlan_vpn_destroy_all 20251 * Purpose: 20252 * Delete all VPN instances 20253 * Parameters: 20254 * unit - Device Number 20255 * Returns: 20256 * BCM_E_XXXX 20257 */ 20258 int bcm_esw_vlan_vpn_destroy_all(int unit) 20259 { 20260 #if defined(BCM_TRIUMPH3_SUPPORT) 20261 int num_vfi = 0, idx = 0; 20262 bcm_vpn_t vpn = 0; 20263 20264 if (!soc_feature(unit, soc_feature_vlan_vfi)) { 20265 return BCM_E_UNAVAIL; 20266 } 20267 20268 /* Destroy all VLAN VPNs */ 20269 num_vfi = soc_mem_index_count(unit, VFIm); 20270 for (idx = 0; idx < num_vfi; idx++) { 20271 if (_bcm_vfi_used_get(unit, idx, _bcmVfiTypeVlan)) { 20272 _BCM_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, idx); 20273 BCM_IF_ERROR_RETURN(bcm_esw_vlan_vpn_destroy(unit, vpn)); 20274 } 20275 } 20276 20277 return BCM_E_NONE; 20278 #else 20279 return BCM_E_UNAVAIL; 20280 #endif /* BCM_TRIUMPH3_SUPPORT */ 20281 } 20282 20283 /* Function: 20284 * bcm_esw_vlan_vpn_get 20285 * Purpose: 20286 * Get VPN information 20287 * Parameters: 20288 * unit - (IN) Device Number 20289 * vpn - (IN) VLAN VPN 20290 * info - (OUT) VLAN VPN Config 20291 * Returns: 20292 * BCM_E_XXXX 20293 */ 20294 int 20295 bcm_esw_vlan_vpn_get(int unit, bcm_vpn_t vpn, bcm_vlan_vpn_config_t *info) 20296 { 20297 #if defined(BCM_TRIUMPH3_SUPPORT) 20298 int vfi_index = -1; 20299 vfi_entry_t vfi_entry; 20300 uint8 isEline=0; 20301 20302 if (!soc_feature(unit, soc_feature_vlan_vfi)) { 20303 return BCM_E_UNAVAIL; 20304 } 20305 20306 if (info == NULL) { 20307 return BCM_E_PARAM; 20308 } 20309 20310 /*Get vfi table*/ 20311 BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_vpn_is_eline(unit, vpn, &isEline)); 20312 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn); 20313 BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry)); 20314 20315 /* Get info associated with vfi table */ 20316 if (isEline) { 20317 info->flags |= BCM_VLAN_VPN_ELINE; 20318 } else { 20319 info->flags |= BCM_VLAN_VPN_ELAN; 20320 20321 _BCM_MULTICAST_GROUP_SET(info->broadcast_group, 20322 _BCM_MULTICAST_TYPE_VLAN, 20323 soc_VFIm_field32_get(unit, &vfi_entry, BC_INDEXf)); 20324 _BCM_MULTICAST_GROUP_SET(info->unknown_unicast_group, 20325 _BCM_MULTICAST_TYPE_VLAN, 20326 soc_VFIm_field32_get(unit, &vfi_entry, UUC_INDEXf)); 20327 _BCM_MULTICAST_GROUP_SET(info->unknown_multicast_group, 20328 _BCM_MULTICAST_TYPE_VLAN, 20329 soc_VFIm_field32_get(unit, &vfi_entry, UMC_INDEXf)); 20330 } 20331 20332 _BCM_VPN_SET(info->vpn, _BCM_VPN_TYPE_VFI, vfi_index); 20333 20334 return BCM_E_NONE; 20335 #else 20336 return BCM_E_UNAVAIL; 20337 #endif /* BCM_TRIUMPH3_SUPPORT */ 20338 } 20339 20340 /* 20341 * Function: 20342 * bcm_esw_vlan_vpn_traverse 20343 * Purpose: 20344 * VPN instance Traverse 20345 * Parameters: 20346 * unit - (IN) Device Number 20347 * cb - (IN) User-provided callback 20348 * user_data - (IN/OUT) Cookie 20349 * Returns: 20350 * BCM_E_XXX 20351 */ 20352 int 20353 bcm_esw_vlan_vpn_traverse(int unit, bcm_vlan_vpn_traverse_cb cb, 20354 void *user_data) 20355 { 20356 #if defined(BCM_TRIUMPH3_SUPPORT) 20357 int idx, num_vfi; 20358 int vpn; 20359 bcm_vlan_vpn_config_t info; 20360 20361 if (!soc_feature(unit, soc_feature_vlan_vfi)) { 20362 return BCM_E_UNAVAIL; 20363 } 20364 20365 if (cb == NULL) { 20366 return BCM_E_PARAM; 20367 } 20368 20369 /* VLAN VPNs */ 20370 num_vfi = soc_mem_index_count(unit, VFIm); 20371 for (idx = 0; idx < num_vfi; idx++) { 20372 if (_bcm_vfi_used_get(unit, idx, _bcmVfiTypeVlan)) { 20373 _BCM_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, idx); 20374 bcm_vlan_vpn_config_t_init(&info); 20375 BCM_IF_ERROR_RETURN(bcm_esw_vlan_vpn_get(unit, vpn, &info)); 20376 BCM_IF_ERROR_RETURN(cb(unit, &info, user_data)); 20377 } 20378 } 20379 20380 return BCM_E_NONE; 20381 #else 20382 return BCM_E_UNAVAIL; 20383 #endif /* BCM_TRIUMPH3_SUPPORT */ 20384 } 20385 #endif 20386 20387 /* 20388 * Function: 20389 * bcm_vlan_match_action_add 20390 * Purpose: 20391 * Add action for match criteria for Vlan assignment. 20392 * Parameters: 20393 * unit - (IN) Device Number 20394 * options - (IN) Option from BCM_VLAN_MATCH_ACTION_XXX 20395 * match_info - (IN) Match criteria info 20396 * action_set - (IN) Action Set. 20397 * Returns: 20398 * BCM_E_XXX 20399 */ 20400 int 20401 bcm_esw_vlan_match_action_add(int unit, uint32 options, 20402 bcm_vlan_match_info_t *match_info, 20403 bcm_vlan_action_set_t *action_set) 20404 { 20405 #ifdef BCM_TRX_SUPPORT 20406 if (SOC_IS_TRX(unit)) { 20407 if (!soc_feature(unit, soc_feature_vlan_action) 20408 || !soc_feature(unit, soc_feature_mac_based_vlan)) { 20409 return BCM_E_UNAVAIL; 20410 } 20411 return _bcm_trx_vlan_match_action_add(unit, options, 20412 BCM_GPORT_INVALID, match_info, action_set); 20413 } 20414 #endif 20415 20416 return BCM_E_UNAVAIL; 20417 } 20418 20419 /* 20420 * Function: 20421 * bcm_esw_vlan_match_action_get 20422 * Purpose: 20423 * Get action for given match criteria. 20424 * Parameters: 20425 * unit - (IN) Device Number 20426 * match_info - (IN) Match criteria info 20427 * action_set - (IN) Action Set. 20428 * Returns: 20429 * BCM_E_XXX 20430 */ 20431 int 20432 bcm_esw_vlan_match_action_get(int unit, bcm_vlan_match_info_t *match_info, 20433 bcm_vlan_action_set_t *action_set) 20434 { 20435 #ifdef BCM_TRX_SUPPORT 20436 if (SOC_IS_TRX(unit)) { 20437 if (!soc_feature(unit, soc_feature_vlan_action) 20438 || !soc_feature(unit, soc_feature_mac_based_vlan)) { 20439 return BCM_E_UNAVAIL; 20440 } 20441 return _bcm_trx_vlan_match_action_get(unit, 20442 BCM_GPORT_INVALID, match_info, action_set); 20443 } 20444 #endif 20445 20446 return BCM_E_UNAVAIL; 20447 } 20448 20449 /* 20450 * Function: 20451 * bcm_esw_vlan_match_action_multi_get 20452 * Purpose: 20453 * Get all actions and match criteria for given vlan match. 20454 * Parameters: 20455 * unit - (IN) Device Number 20456 * match - (IN) vlan match. 20457 * size - (IN) Number of elements in match info array. 20458 * match_info_array - (OUT) Match criteria info array. 20459 * action_set_array - (OUT) Action Set array. 20460 * count - (OUT) Valid Match criteria info count. 20461 * Returns: 20462 * BCM_E_XXX 20463 */ 20464 int 20465 bcm_esw_vlan_match_action_multi_get(int unit, bcm_vlan_match_t match, 20466 int size, bcm_vlan_match_info_t *match_info_array, 20467 bcm_vlan_action_set_t *action_set, int *count) 20468 { 20469 #ifdef BCM_TRX_SUPPORT 20470 if (SOC_IS_TRX(unit)) { 20471 if (!soc_feature(unit, soc_feature_vlan_action) 20472 || !soc_feature(unit, soc_feature_mac_based_vlan)) { 20473 return BCM_E_UNAVAIL; 20474 } 20475 return _bcm_trx_vlan_match_action_multi_get(unit, match, 20476 BCM_GPORT_INVALID, size, match_info_array, 20477 action_set, count); 20478 } 20479 #endif 20480 20481 return BCM_E_UNAVAIL; 20482 } 20483 20484 /* 20485 * Function: 20486 * bcm_esw_vlan_match_action_delete 20487 * Purpose: 20488 * Remove action for a match criteria 20489 * Parameters: 20490 * unit - (IN) Device Number 20491 * match_info - (IN) Match criteria info. 20492 * Returns: 20493 * BCM_E_XXX 20494 */ 20495 int 20496 bcm_esw_vlan_match_action_delete(int unit, bcm_vlan_match_info_t *match_info) 20497 { 20498 #ifdef BCM_TRX_SUPPORT 20499 if (SOC_IS_TRX(unit)) { 20500 if (!soc_feature(unit, soc_feature_vlan_action) 20501 || !soc_feature(unit, soc_feature_mac_based_vlan)) { 20502 return BCM_E_UNAVAIL; 20503 } 20504 return _bcm_trx_vlan_match_action_delete(unit, 20505 BCM_GPORT_INVALID, match_info); 20506 } 20507 #endif 20508 20509 return BCM_E_UNAVAIL; 20510 } 20511 20512 /* 20513 * Function: 20514 * bcm_esw_vlan_match_action_delete_all 20515 * Purpose: 20516 * Remove all actions for vlan match. 20517 * Parameters: 20518 * unit - (IN) Device Number 20519 * match - (IN) Vlan Match 20520 * Returns: 20521 * BCM_E_XXX 20522 */ 20523 int 20524 bcm_esw_vlan_match_action_delete_all(int unit, bcm_vlan_match_t match) 20525 { 20526 #ifdef BCM_TRX_SUPPORT 20527 if (SOC_IS_TRX(unit)) { 20528 if (!soc_feature(unit, soc_feature_vlan_action) 20529 || !soc_feature(unit, soc_feature_mac_based_vlan)) { 20530 return BCM_E_UNAVAIL; 20531 } 20532 return _bcm_trx_vlan_match_action_delete_all(unit, 20533 match, BCM_GPORT_INVALID); 20534 } 20535 #endif 20536 20537 return BCM_E_UNAVAIL; 20538 } 20539 20540 20541 #ifdef BCM_TRX_SUPPORT 20542 /* 20543 * Function: 20544 * _bcm_vlan_match_action_multi_get 20545 * Purpose: 20546 * Get all action and match criteria for given vlan match/port. 20547 * Parameters: 20548 * unit (IN) Device Number 20549 * port (IN) gport number 20550 * size (IN) Number of elements in match_info_array 20551 * match_array (OUT) match info array 20552 * start (IN) Start index in match_array to be filled. 20553 * count (OUT) Actual number of elements in match_array 20554 * Returns: 20555 * BCM_E_XXX 20556 */ 20557 int 20558 _bcm_vlan_match_action_multi_get(int unit, bcm_gport_t port, int size, 20559 bcm_port_match_info_t *match_array, int start, int *count) 20560 { 20561 int rv, i; 20562 int ctr; 20563 int valid_count = 0; 20564 bcm_vlan_match_t match; 20565 bcm_vlan_match_info_t *vlan_match_array = NULL; 20566 bcm_vlan_action_set_t *action_set = NULL; 20567 20568 /* Proceed only if VLAN_MACx is present */ 20569 if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) { 20570 return BCM_E_NONE; 20571 } 20572 20573 if (size == 0) { 20574 match = BCM_VLAN_MATCH_INVALID; 20575 rv = _bcm_trx_vlan_match_action_multi_get(unit, match, 20576 port, size, NULL, NULL, &valid_count); 20577 BCM_IF_ERROR_RETURN(rv); 20578 20579 *count = (start + valid_count); 20580 return BCM_E_NONE; 20581 } 20582 20583 /* Allocate mem */ 20584 vlan_match_array = sal_alloc(sizeof(bcm_vlan_match_info_t) * size, 20585 "Vlan match info array"); 20586 if (vlan_match_array == NULL) { 20587 return BCM_E_MEMORY; 20588 } 20589 action_set = sal_alloc(sizeof (bcm_vlan_action_set_t) * size, 20590 "Vlan action set"); 20591 if (action_set == NULL) { 20592 sal_free(vlan_match_array); 20593 return BCM_E_MEMORY; 20594 } 20595 20596 match = BCM_VLAN_MATCH_INVALID; 20597 rv = _bcm_trx_vlan_match_action_multi_get(unit, match, 20598 port, size, vlan_match_array, action_set, &valid_count); 20599 if (rv == BCM_E_NONE) { 20600 for (i = 0, ctr = start; 20601 (size > ctr) && (i < valid_count); i++, ctr++) { 20602 switch(vlan_match_array[i].match) { 20603 case BCM_VLAN_MATCH_MAC_PORT: 20604 case BCM_VLAN_MATCH_MAC_PORT_CLASS: 20605 if (vlan_match_array[i].match == BCM_VLAN_MATCH_MAC_PORT) { 20606 match_array->match = BCM_PORT_MATCH_MAC_PORT; 20607 match_array->port = vlan_match_array[i].port; 20608 } else if (vlan_match_array[i].match == 20609 BCM_VLAN_MATCH_MAC_PORT_CLASS) { 20610 match_array->match = BCM_PORT_MATCH_MAC_PORT_CLASS; 20611 match_array->port_class = 20612 vlan_match_array[i].port_class; 20613 } 20614 sal_memcpy(match_array->src_mac, 20615 vlan_match_array[i].src_mac, sizeof (bcm_mac_t)); 20616 20617 if (match_array->action != NULL) { 20618 sal_memcpy(match_array->action, &action_set[i], 20619 sizeof(bcm_vlan_action_set_t)); 20620 } 20621 match_array++; 20622 break; 20623 default: 20624 continue; 20625 } 20626 } 20627 } 20628 20629 *count = (start + valid_count); 20630 20631 if (vlan_match_array != NULL) { 20632 sal_free(vlan_match_array); 20633 } 20634 if (action_set != NULL) { 20635 sal_free(action_set); 20636 } 20637 20638 return BCM_E_NONE; 20639 } 20640 #endif