vlan.c (52092B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: vlan.c 8 * Purpose: Handle trident2 specific vlan features: 9 * Manages VP VLAN membership tables. 10 */ 11 12 #include <soc/defs.h> 13 #include <sal/core/libc.h> 14 15 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 16 17 #include <soc/mem.h> 18 #include <soc/hash.h> 19 #include <soc/ptable.h> 20 #include <soc/mcm/memacc.h> 21 #include <bcm/error.h> 22 23 #include <bcm_int/esw_dispatch.h> 24 #include <bcm_int/api_xlate_port.h> 25 26 #include <bcm_int/common/multicast.h> 27 #include <bcm_int/esw/multicast.h> 28 #include <bcm_int/esw/virtual.h> 29 #include <bcm_int/esw/vlan.h> 30 #include <bcm_int/esw/firebolt.h> 31 #include <bcm_int/esw/trx.h> 32 #include <bcm_int/esw/triumph2.h> 33 #include <bcm_int/esw/trident.h> 34 #include <bcm_int/esw/stack.h> 35 #include <bcm_int/esw/trunk.h> 36 #include <bcm_int/esw/ipmc.h> 37 #include <bcm_int/esw/stg.h> 38 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 39 #include <bcm_int/esw/vpn.h> 40 #endif 41 /* 42 * Function: 43 * _bcm_td2_flag_to_stp_state 44 * Purpose: 45 * Translate API flags to hardware stp state 46 * 47 * Parameters: 48 * unit - (IN) BCM device number 49 * flags - (IN) API flags 50 * egress - (IN) TRUE for egress, FALSE for ingress 51 * Returns: 52 * STP state 53 */ 54 int 55 _bcm_td2_flags_to_stp_state(int unit, uint32 flags, int egress) 56 { 57 uint32 mask; 58 int stp_state; 59 60 mask = egress ? BCM_VLAN_GPORT_ADD_EGRESS_STP_MASK : BCM_VLAN_GPORT_ADD_STP_MASK; 61 62 switch (flags & mask) { 63 case BCM_VLAN_GPORT_ADD_STP_BLOCK: 64 case BCM_VLAN_GPORT_ADD_EGRESS_STP_BLOCK: 65 stp_state = 1; 66 break; 67 case BCM_VLAN_GPORT_ADD_STP_LEARN: 68 case BCM_VLAN_GPORT_ADD_EGRESS_STP_LEARN: 69 stp_state = 2; 70 break; 71 case BCM_VLAN_GPORT_ADD_STP_FORWARD: 72 case BCM_VLAN_GPORT_ADD_EGRESS_STP_FORWARD: 73 stp_state = 3; 74 break; 75 default: 76 stp_state = 0; 77 break; 78 } 79 80 return stp_state; 81 } 82 83 /* 84 * Function: 85 * _bcm_td2_stp_state_to_flags 86 * Purpose: 87 * Translate hardware stp state to API flags 88 * 89 * Parameters: 90 * unit - (IN) BCM device number 91 * stp_state - (IN) STP state 92 * egress - (IN) TRUE for egress, FALSE for ingress 93 * flags - (OUT) API flags 94 * Returns: 95 * corresponding flag value 96 */ 97 int 98 _bcm_td2_stp_state_to_flags(int unit, int stp_state, int egress) 99 { 100 int flags; 101 102 switch (stp_state) { 103 case 1: 104 if (egress) { 105 flags = BCM_VLAN_GPORT_ADD_EGRESS_STP_BLOCK; 106 } else { 107 flags = BCM_VLAN_GPORT_ADD_STP_BLOCK; 108 } 109 break; 110 case 2: 111 if (egress) { 112 flags = BCM_VLAN_GPORT_ADD_EGRESS_STP_LEARN; 113 } else { 114 flags = BCM_VLAN_GPORT_ADD_STP_LEARN; 115 } 116 break; 117 case 3: 118 if (egress) { 119 flags = BCM_VLAN_GPORT_ADD_EGRESS_STP_FORWARD; 120 } else { 121 flags = BCM_VLAN_GPORT_ADD_STP_FORWARD; 122 } 123 break; 124 default: 125 if (egress) { 126 flags = BCM_VLAN_GPORT_ADD_EGRESS_STP_DISABLE; 127 } else { 128 flags = BCM_VLAN_GPORT_ADD_STP_DISABLE; 129 } 130 break; 131 } 132 133 return flags; 134 } 135 136 /* 137 * Function: 138 * bcm_td2_ing_vp_vlan_membership_add 139 * Purpose: 140 * create a ING_VP_VLAN_MEMBERSHIP entry 141 * 142 * Parameters: 143 * unit - (IN) BCM device number 144 * vp - (IN) VP number 145 * vlan - (IN) VLAN 146 * Returns: 147 * BCM_E_XXX 148 */ 149 int 150 bcm_td2_ing_vp_vlan_membership_add(int unit, int vp, bcm_vlan_t vlan_vfi, 151 uint32 flags, 152 _bcm_vp_vlan_mbrship_key_type_e key_type) 153 { 154 int rv = BCM_E_NONE; 155 ing_vp_vlan_membership_entry_t ivvm_ent; 156 ing_vp_vlan_membership_entry_t ivvm_ent_result; 157 int index; 158 159 if (!SOC_MEM_IS_VALID(unit, ING_VP_VLAN_MEMBERSHIPm)) { 160 return BCM_E_UNAVAIL; 161 } 162 163 sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent)); 164 165 /* Setup the appropriate fields based on key_type */ 166 if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) { 167 /* Set key_type if is valid field, it is so TD2+ onwards. The below 168 sections do not need this check since those key_types are not 169 valid for earlier devices */ 170 if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) { 171 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 172 _bcm_vp_vlan_mbrship_vp_vlan_type); 173 } 174 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp); 175 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi); 176 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){ 177 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 178 _bcm_vp_vlan_mbrship_glp_vlan_type); 179 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp); 180 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi); 181 } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) { 182 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 183 _bcm_vp_vlan_mbrship_vp_vfi_type); 184 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp); 185 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi); 186 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) { 187 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 188 _bcm_vp_vlan_mbrship_glp_vfi_type); 189 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp); 190 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi); 191 } 192 193 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SP_TREEf, 194 _bcm_td2_flags_to_stp_state(unit, flags, FALSE)); 195 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, 196 soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1); 197 198 rv = soc_mem_search(unit, ING_VP_VLAN_MEMBERSHIPm, MEM_BLOCK_ANY, 199 &index, &ivvm_ent, &ivvm_ent_result, 0); 200 201 if (rv == SOC_E_NONE) { 202 /* found the entry, update the data field and write back */ 203 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent_result, 204 SP_TREEf, _bcm_td2_flags_to_stp_state(unit, flags, FALSE)); 205 rv = soc_mem_write(unit, ING_VP_VLAN_MEMBERSHIPm, 206 MEM_BLOCK_ALL, index, &ivvm_ent_result); 207 208 } else if (rv != SOC_E_NOT_FOUND) { 209 return rv; /* error return */ 210 } else { 211 /* not found, add to the table */ 212 rv = soc_mem_insert(unit, ING_VP_VLAN_MEMBERSHIPm, 213 MEM_BLOCK_ALL, &ivvm_ent); 214 } 215 return rv; 216 } 217 218 /* 219 * Function: 220 * bcm_td2_egr_vp_vlan_membership_add 221 * Purpose: 222 * create a EGR_VP_VLAN_MEMBERSHIP entry 223 * 224 * Parameters: 225 * unit - (IN) BCM device number 226 * vp - (IN) VP number 227 * vlan - (IN) VLAN 228 * key_type - (IN) Key type to identify specific entry 229 * Returns: 230 * BCM_E_XXX 231 */ 232 int 233 bcm_td2_egr_vp_vlan_membership_add(int unit, int vp, bcm_vlan_t vlan_vfi, uint32 flags, 234 _bcm_vp_vlan_mbrship_key_type_e key_type) 235 { 236 int rv = BCM_E_NONE; 237 egr_vp_vlan_membership_entry_t evvm_ent; 238 egr_vp_vlan_membership_entry_t evvm_ent_result; 239 int index; 240 241 if (!SOC_MEM_IS_VALID(unit, EGR_VP_VLAN_MEMBERSHIPm)) { 242 return BCM_E_UNAVAIL; 243 } 244 245 sal_memset(&evvm_ent, 0, sizeof(evvm_ent)); 246 247 /* Setup the appropriate fields based on key_type */ 248 if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) { 249 250 /* Set key_type if is valid field, it is so TD2+ onwards. The below 251 sections do not need this check since those key_types are not 252 valid for earlier devices */ 253 if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) { 254 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 255 _bcm_vp_vlan_mbrship_vp_vlan_type); 256 } 257 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp); 258 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi); 259 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){ 260 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 261 _bcm_vp_vlan_mbrship_glp_vlan_type); 262 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp); 263 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi); 264 } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) { 265 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 266 _bcm_vp_vlan_mbrship_vp_vfi_type); 267 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp); 268 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi); 269 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) { 270 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 271 _bcm_vp_vlan_mbrship_glp_vfi_type); 272 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp); 273 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi); 274 } 275 276 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, 277 soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1); 278 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, SP_TREEf, 279 _bcm_td2_flags_to_stp_state(unit, flags, FALSE)); 280 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, UNTAGf, 281 (flags & BCM_VLAN_PORT_UNTAGGED)? 1:0); 282 283 rv = soc_mem_search(unit, EGR_VP_VLAN_MEMBERSHIPm, MEM_BLOCK_ANY, 284 &index, &evvm_ent, &evvm_ent_result, 0); 285 286 if (rv == SOC_E_NONE) { 287 /* found the entry, update */ 288 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent_result, 289 SP_TREEf, _bcm_td2_flags_to_stp_state(unit, flags, FALSE)); 290 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, 291 &evvm_ent_result, UNTAGf, 292 (flags & BCM_VLAN_PORT_UNTAGGED)? 1:0); 293 rv = soc_mem_write(unit, EGR_VP_VLAN_MEMBERSHIPm, 294 MEM_BLOCK_ALL, index, &evvm_ent_result); 295 } else if (rv != SOC_E_NOT_FOUND) { 296 return rv; /* error return */ 297 } else { 298 /* not found, add to the table */ 299 rv = soc_mem_insert(unit, EGR_VP_VLAN_MEMBERSHIPm, 300 MEM_BLOCK_ALL, &evvm_ent); 301 } 302 return rv; 303 } 304 305 /* 306 * Function: 307 * bcm_td2_ing_vp_vlan_membership_delete 308 * Purpose: 309 * delete a ING_VP_VLAN_MEMBERSHIP entry 310 * 311 * Parameters: 312 * unit - (IN) BCM device number 313 * vp - (IN) VP number 314 * vlan - (IN) VLAN 315 * key_type - (IN) Key type to identify specific entry 316 * Returns: 317 * BCM_E_XXX 318 */ 319 int 320 bcm_td2_ing_vp_vlan_membership_delete(int unit, int vp, bcm_vlan_t vlan_vfi, 321 _bcm_vp_vlan_mbrship_key_type_e key_type) 322 { 323 int rv = BCM_E_NONE; 324 ing_vp_vlan_membership_entry_t ivvm_ent; 325 326 sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent)); 327 328 /* Setup the appropriate fields based on key_type */ 329 if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) { 330 /* Set key_type if is valid field, it is so TD2+ onwards. The below 331 sections do not need this check since those key_types are not 332 valid for earlier devices */ 333 if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) { 334 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 335 _bcm_vp_vlan_mbrship_vp_vlan_type); 336 } 337 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp); 338 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi); 339 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){ 340 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 341 _bcm_vp_vlan_mbrship_glp_vlan_type); 342 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp); 343 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi); 344 } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) { 345 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 346 _bcm_vp_vlan_mbrship_vp_vfi_type); 347 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp); 348 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi); 349 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) { 350 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 351 _bcm_vp_vlan_mbrship_glp_vfi_type); 352 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp); 353 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi); 354 } 355 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, 356 soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1); 357 358 rv = soc_mem_delete_return_old(unit, ING_VP_VLAN_MEMBERSHIPm, 359 MEM_BLOCK_ALL, &ivvm_ent, &ivvm_ent); 360 361 return rv; 362 } 363 364 /* 365 * Function: 366 * bcm_td2_egr_vp_vlan_membership_delete 367 * Purpose: 368 * delete a EGR_VP_VLAN_MEMBERSHIP entry 369 * 370 * Parameters: 371 * unit - (IN) BCM device number 372 * vp - (IN) VP number 373 * vlan - (IN) VLAN 374 * Returns: 375 * BCM_E_XXX 376 */ 377 int 378 bcm_td2_egr_vp_vlan_membership_delete(int unit, int vp, bcm_vlan_t vlan_vfi, 379 _bcm_vp_vlan_mbrship_key_type_e key_type) 380 { 381 int rv = BCM_E_NONE; 382 egr_vp_vlan_membership_entry_t evvm_ent; 383 384 sal_memset(&evvm_ent, 0, sizeof(evvm_ent)); 385 386 /* Setup the appropriate fields based on key_type */ 387 if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) { 388 /* Set key_type if is valid field, it is so TD2+ onwards. The below 389 sections do not need this check since those key_types are not 390 valid for earlier devices */ 391 if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) { 392 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 393 _bcm_vp_vlan_mbrship_vp_vlan_type); 394 } 395 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp); 396 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi); 397 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){ 398 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 399 _bcm_vp_vlan_mbrship_glp_vlan_type); 400 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp); 401 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi); 402 } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) { 403 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 404 _bcm_vp_vlan_mbrship_vp_vfi_type); 405 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp); 406 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi); 407 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) { 408 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 409 _bcm_vp_vlan_mbrship_glp_vfi_type); 410 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp); 411 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi); 412 } 413 414 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, 415 soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1); 416 417 rv = soc_mem_delete_return_old(unit, EGR_VP_VLAN_MEMBERSHIPm, 418 MEM_BLOCK_ALL, &evvm_ent, &evvm_ent); 419 420 return rv; 421 } 422 423 424 /* 425 * Function: 426 * bcm_td2_ing_vp_vlan_membership_get 427 * Purpose: 428 * get the STP state of this ING_VP_VLAN_MEMBERSHIP entry 429 * 430 * Parameters: 431 * unit - (IN) BCM device number 432 * vp - (IN) VP number 433 * vlan - (IN) VLAN 434 * key_type - (IN) Key type to identify specific entry 435 * Returns: 436 * BCM_E_XXX 437 */ 438 int 439 bcm_td2_ing_vp_vlan_membership_get(int unit, int vp, bcm_vlan_t vlan_vfi, uint32 *flags, 440 _bcm_vp_vlan_mbrship_key_type_e key_type) 441 { 442 ing_vp_vlan_membership_entry_t ivvm_ent; 443 ing_vp_vlan_membership_entry_t ivvm_ent_result; 444 int idx; 445 int sp_state; 446 447 *flags = 0; 448 sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent)); 449 450 /* Setup the appropriate fields based on key_type */ 451 if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) { 452 /* Set key_type if is valid field, it is so TD2+ onwards. The below 453 sections do not need this check since those key_types are not 454 valid for earlier devices */ 455 if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) { 456 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 457 _bcm_vp_vlan_mbrship_vp_vlan_type); 458 } 459 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp); 460 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi); 461 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){ 462 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 463 _bcm_vp_vlan_mbrship_glp_vlan_type); 464 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp); 465 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi); 466 } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) { 467 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 468 _bcm_vp_vlan_mbrship_vp_vfi_type); 469 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp); 470 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi); 471 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) { 472 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 473 _bcm_vp_vlan_mbrship_glp_vfi_type); 474 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp); 475 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi); 476 } 477 478 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, 479 soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1); 480 481 BCM_IF_ERROR_RETURN(soc_mem_search(unit, ING_VP_VLAN_MEMBERSHIPm, 482 MEM_BLOCK_ALL, &idx, 483 &ivvm_ent, &ivvm_ent_result, 0)); 484 485 sp_state = soc_ING_VP_VLAN_MEMBERSHIPm_field32_get(unit, &ivvm_ent_result, 486 SP_TREEf); 487 if (sp_state == PVP_STP_DISABLED) { 488 *flags = BCM_VLAN_GPORT_ADD_STP_DISABLE; 489 } else if (sp_state == PVP_STP_LEARNING) { 490 *flags = BCM_VLAN_GPORT_ADD_STP_LEARN; 491 } else if (sp_state == PVP_STP_BLOCKING) { 492 *flags = BCM_VLAN_GPORT_ADD_STP_BLOCK; 493 } else { 494 *flags = BCM_VLAN_GPORT_ADD_STP_FORWARD; 495 } 496 497 return BCM_E_NONE; 498 } 499 500 /* 501 * Function: 502 * bcm_td2_egr_vp_vlan_membership_get 503 * Purpose: 504 * get the STP state of this EGR_VP_VLAN_MEMBERSHIP entry 505 * 506 * Parameters: 507 * unit - (IN) BCM device number 508 * vp - (IN) VP number 509 * vlan - (IN) VLAN 510 * key_type - (IN) Key type to identify specific entry 511 * Returns: 512 * BCM_E_XXX 513 */ 514 int 515 bcm_td2_egr_vp_vlan_membership_get(int unit, int vp, bcm_vlan_t vlan_vfi, uint32 *flags, 516 _bcm_vp_vlan_mbrship_key_type_e key_type) 517 { 518 egr_vp_vlan_membership_entry_t evvm_ent; 519 egr_vp_vlan_membership_entry_t evvm_ent_result; 520 int idx; 521 int sp_state; 522 int untag; 523 524 *flags = 0; 525 sal_memset(&evvm_ent, 0, sizeof(evvm_ent)); 526 527 /* Setup the appropriate fields based on key_type */ 528 if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) { 529 530 /* Set key_type if is valid field, it is so TD2+ onwards. The below 531 sections do not need this check since those key_types are not 532 valid for earlier devices */ 533 if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) { 534 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 535 _bcm_vp_vlan_mbrship_vp_vlan_type); 536 } 537 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp); 538 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi); 539 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){ 540 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 541 _bcm_vp_vlan_mbrship_glp_vlan_type); 542 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp); 543 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi); 544 } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) { 545 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 546 _bcm_vp_vlan_mbrship_vp_vfi_type); 547 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp); 548 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi); 549 } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) { 550 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 551 _bcm_vp_vlan_mbrship_glp_vfi_type); 552 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp); 553 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi); 554 } 555 556 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, 557 soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1); 558 BCM_IF_ERROR_RETURN(soc_mem_search(unit, EGR_VP_VLAN_MEMBERSHIPm, 559 MEM_BLOCK_ALL, &idx, 560 &evvm_ent, &evvm_ent_result, 0)); 561 562 sp_state = soc_EGR_VP_VLAN_MEMBERSHIPm_field32_get(unit, &evvm_ent_result, 563 SP_TREEf); 564 if (sp_state == PVP_STP_DISABLED) { 565 *flags = BCM_VLAN_GPORT_ADD_STP_DISABLE; 566 } else if (sp_state == PVP_STP_LEARNING) { 567 *flags = BCM_VLAN_GPORT_ADD_STP_LEARN; 568 } else if (sp_state == PVP_STP_BLOCKING) { 569 *flags = BCM_VLAN_GPORT_ADD_STP_BLOCK; 570 } else { 571 *flags = BCM_VLAN_GPORT_ADD_STP_FORWARD; 572 } 573 untag = soc_EGR_VP_VLAN_MEMBERSHIPm_field32_get(unit, &evvm_ent_result, 574 UNTAGf); 575 *flags |= untag? BCM_VLAN_PORT_UNTAGGED:0; 576 return BCM_E_NONE; 577 } 578 579 /* 580 * Function: 581 * bcm_td2_ing_vp_vlan_membership_get_all 582 * Purpose: 583 * For the given vlan, get all the virtual ports and flags from 584 * ING_VP_VLAN_MEMBERSHIP table. 585 * Parameters: 586 * unit - (IN) SOC unit number. 587 * vlan - (IN) VLAN. 588 * vp_bitmap - (OUT) Bitmap of virtual ports. 589 * arr_size - (IN) Number of elements in flags_arr. 590 * flags_arr - (OUT) Array of flags. 591 * Returns: 592 * BCM_E_XXX 593 */ 594 int 595 bcm_td2_ing_vp_vlan_membership_get_all(int unit, bcm_vlan_t vlan, 596 SHR_BITDCL *vp_bitmap, int arr_size, int *flags_arr) 597 { 598 int rv = BCM_E_NONE; 599 soc_mem_t mem; 600 int chunk_size, num_chunks, chunk_index; 601 int alloc_size; 602 uint8 *buf = NULL; 603 int i, entry_index_min, entry_index_max; 604 uint32 *buf_entry; 605 int vp; 606 int sp_state; 607 soc_field_t vld_fld = VALIDf; 608 609 if (NULL == vp_bitmap) { 610 return BCM_E_PARAM; 611 } 612 if (arr_size != soc_mem_index_count(unit, SOURCE_VPm)) { 613 return BCM_E_PARAM; 614 } 615 if (NULL == flags_arr) { 616 return BCM_E_PARAM; 617 } 618 619 mem = ING_VP_VLAN_MEMBERSHIPm; 620 if (soc_feature(unit, soc_feature_base_valid)) { 621 vld_fld = BASE_VALIDf; 622 } 623 624 chunk_size = 1024; 625 num_chunks = soc_mem_index_count(unit, mem) / chunk_size; 626 if (soc_mem_index_count(unit, mem) % chunk_size) { 627 num_chunks++; 628 } 629 630 alloc_size = sizeof(ing_vp_vlan_membership_entry_t) * chunk_size; 631 buf = soc_cm_salloc(unit, alloc_size, "ING_VP_VLAN_MEMBERSHIP buffer"); 632 if (NULL == buf) { 633 rv = BCM_E_MEMORY; 634 goto cleanup; 635 } 636 637 for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) { 638 639 /* Get a chunk of entries */ 640 entry_index_min = chunk_index * chunk_size; 641 entry_index_max = entry_index_min + chunk_size - 1; 642 if (entry_index_max > soc_mem_index_max(unit, mem)) { 643 entry_index_max = soc_mem_index_max(unit, mem); 644 } 645 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 646 entry_index_min, entry_index_max, buf); 647 if (SOC_FAILURE(rv)) { 648 goto cleanup; 649 } 650 651 /* Read each entry of the chunk to extract VP and flags */ 652 for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) { 653 buf_entry = soc_mem_table_idx_to_pointer(unit, 654 mem, uint32 *, buf, i); 655 656 if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) { 657 continue; 658 } 659 if (soc_mem_field32_get(unit, mem, buf_entry, VLANf) != vlan) { 660 continue; 661 } 662 663 vp = soc_mem_field32_get(unit, mem, buf_entry, VPf); 664 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan) && 665 !_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv) && 666 !_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender) && 667 !_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 668 continue; 669 } 670 SHR_BITSET(vp_bitmap, vp); 671 672 sp_state = soc_mem_field32_get(unit, mem, buf_entry, SP_TREEf); 673 if (sp_state == PVP_STP_DISABLED) { 674 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_DISABLE; 675 } else if (sp_state == PVP_STP_LEARNING) { 676 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_LEARN; 677 } else if (sp_state == PVP_STP_BLOCKING) { 678 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_BLOCK; 679 } else { 680 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_FORWARD; 681 } 682 } 683 } 684 685 cleanup: 686 if (buf) { 687 soc_cm_sfree(unit, buf); 688 } 689 690 return rv; 691 } 692 693 /* 694 * Function: 695 * bcm_td2_egr_vp_vlan_membership_get_all 696 * Purpose: 697 * For the given vlan, get all the virtual ports and flags from 698 * EGR_VP_VLAN_MEMBERSHIP table. 699 * Parameters: 700 * unit - (IN) SOC unit number. 701 * vlan - (IN) VLAN. 702 * vp_bitmap - (OUT) Bitmap of virtual ports. 703 * arr_size - (IN) Number of elements in flags_arr. 704 * flags_arr - (OUT) Array of flags. 705 * Returns: 706 * BCM_E_XXX 707 */ 708 int 709 bcm_td2_egr_vp_vlan_membership_get_all(int unit, bcm_vlan_t vlan, 710 SHR_BITDCL *vp_bitmap, int arr_size, int *flags_arr) 711 { 712 int rv = BCM_E_NONE; 713 soc_mem_t mem; 714 int chunk_size, num_chunks, chunk_index; 715 int alloc_size; 716 uint8 *buf = NULL; 717 int i, entry_index_min, entry_index_max; 718 uint32 *buf_entry; 719 int vp; 720 int sp_state; 721 int untag; 722 soc_field_t vld_fld = VALIDf; 723 724 if (NULL == vp_bitmap) { 725 return BCM_E_PARAM; 726 } 727 if (arr_size != soc_mem_index_count(unit, SOURCE_VPm)) { 728 return BCM_E_PARAM; 729 } 730 if (NULL == flags_arr) { 731 return BCM_E_PARAM; 732 } 733 734 mem = EGR_VP_VLAN_MEMBERSHIPm; 735 if (soc_feature(unit, soc_feature_base_valid)) { 736 vld_fld = BASE_VALIDf; 737 } 738 739 chunk_size = 1024; 740 num_chunks = soc_mem_index_count(unit, mem) / chunk_size; 741 if (soc_mem_index_count(unit, mem) % chunk_size) { 742 num_chunks++; 743 } 744 745 alloc_size = sizeof(egr_vp_vlan_membership_entry_t) * chunk_size; 746 buf = soc_cm_salloc(unit, alloc_size, "EGR_VP_VLAN_MEMBERSHIP buffer"); 747 if (NULL == buf) { 748 rv = BCM_E_MEMORY; 749 goto cleanup; 750 } 751 752 for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) { 753 754 /* Get a chunk of entries */ 755 entry_index_min = chunk_index * chunk_size; 756 entry_index_max = entry_index_min + chunk_size - 1; 757 if (entry_index_max > soc_mem_index_max(unit, mem)) { 758 entry_index_max = soc_mem_index_max(unit, mem); 759 } 760 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 761 entry_index_min, entry_index_max, buf); 762 if (SOC_FAILURE(rv)) { 763 goto cleanup; 764 } 765 766 /* Read each entry of the chunk to extract VP and flags */ 767 for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) { 768 buf_entry = soc_mem_table_idx_to_pointer(unit, 769 mem, uint32 *, buf, i); 770 771 if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) { 772 continue; 773 } 774 if (soc_mem_field32_get(unit, mem, buf_entry, VLANf) != vlan) { 775 continue; 776 } 777 778 vp = soc_mem_field32_get(unit, mem, buf_entry, VPf); 779 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan) && 780 !_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv) && 781 !_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender) && 782 !_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 783 continue; 784 } 785 SHR_BITSET(vp_bitmap, vp); 786 787 sp_state = soc_mem_field32_get(unit, mem, buf_entry, SP_TREEf); 788 if (sp_state == PVP_STP_DISABLED) { 789 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_DISABLE; 790 } else if (sp_state == PVP_STP_LEARNING) { 791 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_LEARN; 792 } else if (sp_state == PVP_STP_BLOCKING) { 793 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_BLOCK; 794 } else { 795 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_FORWARD; 796 } 797 798 untag = soc_mem_field32_get(unit, mem, buf_entry, UNTAGf); 799 if (untag) { 800 flags_arr[vp] |= BCM_VLAN_PORT_UNTAGGED; 801 } 802 } 803 } 804 805 cleanup: 806 if (buf) { 807 soc_cm_sfree(unit, buf); 808 } 809 810 return rv; 811 } 812 813 /* 814 * Function: 815 * bcm_td2_ing_vp_vlan_membership_delete_all 816 * Purpose: 817 * For the given vlan, delete all the virtual ports from 818 * ING_VP_VLAN_MEMBERSHIP table. 819 * Parameters: 820 * unit - (IN) SOC unit number. 821 * vlan - (IN) VLAN. 822 * Returns: 823 * BCM_E_XXX 824 */ 825 int 826 bcm_td2_ing_vp_vlan_membership_delete_all(int unit, bcm_vlan_t vlan_vpn) 827 { 828 int rv = BCM_E_NONE; 829 soc_mem_t mem; 830 int chunk_size, num_chunks, chunk_index; 831 int alloc_size; 832 uint8 *buf = NULL; 833 int i, entry_index_min, entry_index_max; 834 uint32 *buf_entry; 835 int vp, key_type, glp_vlan_vfi = 0; 836 int vlan_vfi; 837 soc_field_t vlan_vfi_field; 838 soc_field_t vld_fld = VALIDf; 839 840 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 841 if (_BCM_VPN_VFI_IS_SET(vlan_vpn)) { 842 vlan_vfi_field = VFIf; 843 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan_vpn); 844 } else 845 #endif 846 { 847 vlan_vfi = vlan_vpn; 848 vlan_vfi_field = VLANf; 849 } 850 851 mem = ING_VP_VLAN_MEMBERSHIPm; 852 if (soc_feature(unit, soc_feature_base_valid)) { 853 vld_fld = BASE_VALIDf; 854 } 855 856 /* Set default key_type to vp_vlan_type */ 857 key_type = _bcm_vp_vlan_mbrship_vp_vlan_type; 858 859 chunk_size = 1024; 860 num_chunks = soc_mem_index_count(unit, mem) / chunk_size; 861 if (soc_mem_index_count(unit, mem) % chunk_size) { 862 num_chunks++; 863 } 864 865 alloc_size = sizeof(ing_vp_vlan_membership_entry_t) * chunk_size; 866 buf = soc_cm_salloc(unit, alloc_size, "ING_VP_VLAN_MEMBERSHIP buffer"); 867 if (NULL == buf) { 868 rv = BCM_E_MEMORY; 869 goto cleanup; 870 } 871 872 for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) { 873 874 /* Get a chunk of entries */ 875 entry_index_min = chunk_index * chunk_size; 876 entry_index_max = entry_index_min + chunk_size - 1; 877 if (entry_index_max > soc_mem_index_max(unit, mem)) { 878 entry_index_max = soc_mem_index_max(unit, mem); 879 } 880 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 881 entry_index_min, entry_index_max, buf); 882 if (SOC_FAILURE(rv)) { 883 goto cleanup; 884 } 885 886 /* Read each entry of the chunk */ 887 for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) { 888 buf_entry = soc_mem_table_idx_to_pointer(unit, 889 mem, uint32 *, buf, i); 890 891 if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) { 892 continue; 893 } 894 if (soc_mem_field32_get(unit, mem, buf_entry, vlan_vfi_field) != vlan_vfi) { 895 continue; 896 } 897 898 glp_vlan_vfi = 0; 899 /* Get the VP */ 900 vp = soc_mem_field32_get(unit, mem, buf_entry, VPf); 901 902 /* Set key_type if is valid field, it is so TD2+ onwards. The below 903 sections do not need this check since those key_types are not 904 valid for earlier devices */ 905 if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) { 906 /* Get the key_type */ 907 key_type = soc_mem_field32_get(unit, mem, buf_entry, KEY_TYPEf); 908 /* If the key_type is GLP_VLAN, set the flag */ 909 if ((key_type == _bcm_vp_vlan_mbrship_glp_vlan_type) || 910 (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type)) { 911 glp_vlan_vfi = 1; 912 vp = soc_mem_field32_get(unit, mem, buf_entry, SGLPf); 913 } 914 } 915 916 if (!glp_vlan_vfi && !_bcm_vp_used_get(unit, vp, _bcmVpTypeAny)) { 917 continue; 918 } 919 rv = bcm_td2_ing_vp_vlan_membership_delete(unit, vp, vlan_vfi, key_type); 920 if (BCM_FAILURE(rv)) { 921 goto cleanup; 922 } 923 } 924 } 925 926 cleanup: 927 if (buf) { 928 soc_cm_sfree(unit, buf); 929 } 930 931 return rv; 932 } 933 934 /* 935 * Function: 936 * bcm_td2_egr_vp_vlan_membership_delete_all 937 * Purpose: 938 * For the given vlan, delete all the virtual ports from 939 * EGR_VP_VLAN_MEMBERSHIP table. 940 * Parameters: 941 * unit - (IN) SOC unit number. 942 * vlan - (IN) VLAN. 943 * Returns: 944 * BCM_E_XXX 945 */ 946 int 947 bcm_td2_egr_vp_vlan_membership_delete_all(int unit, bcm_vlan_t vlan_vpn) 948 { 949 int rv = BCM_E_NONE; 950 soc_mem_t mem; 951 int chunk_size, num_chunks, chunk_index; 952 int alloc_size; 953 uint8 *buf = NULL; 954 int i, entry_index_min, entry_index_max; 955 uint32 *buf_entry; 956 int vp, key_type, glp_vlan_vfi = 0; 957 int vlan_vfi; 958 soc_field_t vlan_vfi_field; 959 soc_field_t vld_fld = VALIDf; 960 961 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 962 if (_BCM_VPN_VFI_IS_SET(vlan_vpn)) { 963 vlan_vfi_field = VFIf; 964 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan_vpn); 965 } else 966 #endif 967 { 968 vlan_vfi = vlan_vpn; 969 vlan_vfi_field = VLANf; 970 } 971 972 mem = EGR_VP_VLAN_MEMBERSHIPm; 973 if (soc_feature(unit, soc_feature_base_valid)) { 974 vld_fld = BASE_VALIDf; 975 } 976 977 /* Set default key_type to vp_vlan_type */ 978 key_type = _bcm_vp_vlan_mbrship_vp_vlan_type; 979 980 chunk_size = 1024; 981 num_chunks = soc_mem_index_count(unit, mem) / chunk_size; 982 if (soc_mem_index_count(unit, mem) % chunk_size) { 983 num_chunks++; 984 } 985 986 alloc_size = sizeof(egr_vp_vlan_membership_entry_t) * chunk_size; 987 buf = soc_cm_salloc(unit, alloc_size, "EGR_VP_VLAN_MEMBERSHIP buffer"); 988 if (NULL == buf) { 989 rv = BCM_E_MEMORY; 990 goto cleanup; 991 } 992 993 for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) { 994 995 /* Get a chunk of entries */ 996 entry_index_min = chunk_index * chunk_size; 997 entry_index_max = entry_index_min + chunk_size - 1; 998 if (entry_index_max > soc_mem_index_max(unit, mem)) { 999 entry_index_max = soc_mem_index_max(unit, mem); 1000 } 1001 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 1002 entry_index_min, entry_index_max, buf); 1003 if (SOC_FAILURE(rv)) { 1004 goto cleanup; 1005 } 1006 1007 /* Read each entry of the chunk */ 1008 for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) { 1009 buf_entry = soc_mem_table_idx_to_pointer(unit, 1010 mem, uint32 *, buf, i); 1011 1012 if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) { 1013 continue; 1014 } 1015 if (soc_mem_field32_get(unit, mem, buf_entry, vlan_vfi_field) != vlan_vfi) { 1016 continue; 1017 } 1018 1019 glp_vlan_vfi = 0; 1020 /* Get the VP */ 1021 vp = soc_mem_field32_get(unit, mem, buf_entry, VPf); 1022 1023 /* Set key_type if is valid field, it is so TD2+ onwards. The below 1024 sections do not need this check since those key_types are not 1025 valid for earlier devices */ 1026 if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) { 1027 /* Get the key_type */ 1028 key_type = soc_mem_field32_get(unit, mem, buf_entry, KEY_TYPEf); 1029 /* If the key_type is GLP_VLAN, set the flag */ 1030 if ((key_type == _bcm_vp_vlan_mbrship_glp_vlan_type) || 1031 (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type)) { 1032 glp_vlan_vfi = 1; 1033 vp = soc_mem_field32_get(unit, mem, buf_entry, DGLPf); 1034 } 1035 } 1036 1037 if (!glp_vlan_vfi && !_bcm_vp_used_get(unit, vp, _bcmVpTypeAny)) { 1038 continue; 1039 } 1040 rv = bcm_td2_egr_vp_vlan_membership_delete(unit, vp, vlan_vfi, key_type); 1041 if (BCM_FAILURE(rv)) { 1042 goto cleanup; 1043 } 1044 } 1045 } 1046 1047 cleanup: 1048 if (buf) { 1049 soc_cm_sfree(unit, buf); 1050 } 1051 1052 return rv; 1053 } 1054 1055 /* 1056 * Function: 1057 * bcm_td2_vp_vlan_stp_set 1058 * Purpose: 1059 * Set the spanning tree state for a virtual port 1060 * Parameters: 1061 * unit - (IN) BCM device number 1062 * vp - (IN) VP number 1063 * vlan - (IN) VLAN 1064 * stp_state - (IN) State to set 1065 * Returns: 1066 * BCM_E_XXX 1067 */ 1068 int 1069 bcm_td2_vp_vlan_stp_set(int unit, int vp, bcm_vlan_t vlan, int stp_state) 1070 { 1071 int rv = BCM_E_NONE; 1072 int idx; 1073 int hw_stp_state; 1074 ing_vp_vlan_membership_entry_t ivvm_ent; 1075 ing_vp_vlan_membership_entry_t ivvm_ent_result; 1076 egr_vp_vlan_membership_entry_t evvm_ent; 1077 egr_vp_vlan_membership_entry_t evvm_ent_result; 1078 1079 /* Translate API space port state to hw stp port state. */ 1080 BCM_IF_ERROR_RETURN(_bcm_stg_stp_translate(unit, stp_state, &hw_stp_state)); 1081 1082 /* Ingress direction */ 1083 sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent)); 1084 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp); 1085 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan); 1086 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, 1087 soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1); 1088 1089 BCM_IF_ERROR_RETURN(soc_mem_search(unit, ING_VP_VLAN_MEMBERSHIPm, 1090 MEM_BLOCK_ALL, &idx, 1091 &ivvm_ent, &ivvm_ent_result, 0)); 1092 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent_result, SP_TREEf, 1093 hw_stp_state); 1094 BCM_IF_ERROR_RETURN(soc_mem_write(unit, ING_VP_VLAN_MEMBERSHIPm, 1095 MEM_BLOCK_ALL, idx, &ivvm_ent_result)); 1096 1097 /* Egress direction */ 1098 sal_memset(&evvm_ent, 0, sizeof(evvm_ent)); 1099 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp); 1100 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan); 1101 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, 1102 soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1); 1103 1104 BCM_IF_ERROR_RETURN(soc_mem_search(unit, EGR_VP_VLAN_MEMBERSHIPm, 1105 MEM_BLOCK_ALL, &idx, 1106 &evvm_ent, &evvm_ent_result, 0)); 1107 soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent_result, SP_TREEf, 1108 hw_stp_state); 1109 BCM_IF_ERROR_RETURN(soc_mem_write(unit, EGR_VP_VLAN_MEMBERSHIPm, 1110 MEM_BLOCK_ALL, idx, &evvm_ent_result)); 1111 1112 return rv; 1113 } 1114 1115 /* 1116 * Function: 1117 * bcm_td2_vp_vlan_stp_get 1118 * Purpose: 1119 * Get the spanning tree state for a virtual port 1120 * Parameters: 1121 * unit - (IN) BCM device number 1122 * vp - (IN) VP number 1123 * vlan - (IN) VLAN 1124 * stp_state - (OUT) State to set 1125 * Returns: 1126 * BCM_E_XXX 1127 */ 1128 int 1129 bcm_td2_vp_vlan_stp_get(int unit, int vp, bcm_vlan_t vlan, int *stp_state) 1130 { 1131 int rv = BCM_E_NONE; 1132 int idx; 1133 int hw_stp_state; 1134 ing_vp_vlan_membership_entry_t ivvm_ent; 1135 ing_vp_vlan_membership_entry_t ivvm_ent_result; 1136 1137 sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent)); 1138 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp); 1139 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan); 1140 soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, 1141 soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1); 1142 1143 BCM_IF_ERROR_RETURN(soc_mem_search(unit, ING_VP_VLAN_MEMBERSHIPm, 1144 MEM_BLOCK_ALL, &idx, 1145 &ivvm_ent, &ivvm_ent_result, 0)); 1146 hw_stp_state = soc_ING_VP_VLAN_MEMBERSHIPm_field32_get(unit, &ivvm_ent_result, 1147 SP_TREEf); 1148 1149 /* Translate hw stp port state to API format. */ 1150 BCM_IF_ERROR_RETURN(_bcm_stg_pvp_translate(unit, hw_stp_state, stp_state)); 1151 1152 return rv; 1153 } 1154 1155 /* 1156 * Function: 1157 * bcm_td2_vp_vlan_membership_add 1158 * Purpose: 1159 * create a VP_VLAN_MEMBERSHIP entry 1160 * 1161 * Parameters: 1162 * unit - (IN) BCM device number 1163 * vp - (IN) VP number 1164 * vlan - (IN) VLAN 1165 * Returns: 1166 * BCM_E_XXX 1167 */ 1168 int 1169 bcm_td2_vp_vlan_membership_add(int unit, int vp, bcm_vlan_t vlan, int flags) 1170 { 1171 int rv = BCM_E_NONE; 1172 int vlan_vfi = 0; 1173 _bcm_vp_vlan_mbrship_key_type_e key_type; 1174 1175 if ((flags & BCM_VLAN_GPORT_ADD_INGRESS_ONLY) && 1176 (flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY)) { 1177 return BCM_E_PARAM; 1178 } 1179 1180 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1181 if (_BCM_VPN_VFI_IS_SET(vlan)) { 1182 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan); 1183 key_type = _bcm_vp_vlan_mbrship_glp_vfi_type; 1184 } else 1185 #endif 1186 { 1187 vlan_vfi = vlan; 1188 key_type = _bcm_vp_vlan_mbrship_glp_vlan_type; 1189 } 1190 1191 if (!(flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY)) { 1192 BCM_IF_ERROR_RETURN(bcm_td2_ing_vp_vlan_membership_add(unit, 1193 vp, vlan_vfi, flags, key_type)); 1194 } 1195 1196 if (!(flags & BCM_VLAN_GPORT_ADD_INGRESS_ONLY)) { 1197 BCM_IF_ERROR_RETURN(bcm_td2_egr_vp_vlan_membership_add(unit, 1198 vp, vlan_vfi, flags, key_type)); 1199 } 1200 1201 return rv; 1202 } 1203 1204 /* 1205 * Function: 1206 * bcm_td2_vp_vlan_membership_delete 1207 * Purpose: 1208 * delete VP_VLAN_MEMBERSHIP entry 1209 * 1210 * Parameters: 1211 * unit - (IN) BCM device number 1212 * vp - (IN) VP number 1213 * vlan - (IN) VLAN 1214 * Returns: 1215 * BCM_E_XXX 1216 */ 1217 int 1218 bcm_td2_vp_vlan_membership_delete(int unit, int vp, bcm_vlan_t vlan) 1219 { 1220 int rv = BCM_E_NONE; 1221 int vlan_vfi = 0; 1222 int ing_vp_vlan_membership_found = 0; 1223 int egr_vp_vlan_membership_found = 0; 1224 _bcm_vp_vlan_mbrship_key_type_e key_type; 1225 1226 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1227 if (_BCM_VPN_VFI_IS_SET(vlan)) { 1228 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan); 1229 key_type = _bcm_vp_vlan_mbrship_glp_vfi_type; 1230 } else 1231 #endif 1232 { 1233 vlan_vfi = vlan; 1234 key_type = _bcm_vp_vlan_mbrship_glp_vlan_type; 1235 } 1236 1237 rv = bcm_td2_ing_vp_vlan_membership_delete(unit, vp, vlan_vfi, key_type); 1238 if (BCM_SUCCESS(rv)) { 1239 ing_vp_vlan_membership_found = TRUE; 1240 } else if (rv == BCM_E_NOT_FOUND) { 1241 ing_vp_vlan_membership_found = FALSE; 1242 rv = BCM_E_NONE; 1243 } else { 1244 return rv; 1245 } 1246 1247 rv = bcm_td2_egr_vp_vlan_membership_delete(unit, vp, vlan_vfi, key_type); 1248 if (BCM_SUCCESS(rv)) { 1249 egr_vp_vlan_membership_found = TRUE; 1250 } else if (rv == BCM_E_NOT_FOUND) { 1251 egr_vp_vlan_membership_found = FALSE; 1252 rv = BCM_E_NONE; 1253 } else { 1254 return rv; 1255 } 1256 1257 if (!ing_vp_vlan_membership_found && !egr_vp_vlan_membership_found) { 1258 return BCM_E_NOT_FOUND; 1259 } 1260 1261 return rv; 1262 } 1263 1264 /* 1265 * Function: 1266 * bcm_td2_vp_vlan_membership_get 1267 * Purpose: 1268 * get the STP state of VP_VLAN_MEMBERSHIP entry 1269 * 1270 * Parameters: 1271 * unit - (IN) BCM device number 1272 * vp - (IN) VP number 1273 * vlan - (IN) VLAN 1274 * flags - (OUT) STP state 1275 * Returns: 1276 * BCM_E_XXX 1277 */ 1278 int 1279 bcm_td2_vp_vlan_membership_get(int unit, int vp, bcm_vlan_t vlan, int *flags) 1280 { 1281 int rv = BCM_E_NONE; 1282 int vlan_vfi = 0; 1283 uint32 ing_flags = 0; 1284 uint32 egr_flags = 0; 1285 int ing_vp_vlan_membership_found = 0; 1286 int egr_vp_vlan_membership_found = 0; 1287 _bcm_vp_vlan_mbrship_key_type_e key_type; 1288 1289 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1290 if (_BCM_VPN_VFI_IS_SET(vlan)) { 1291 _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan); 1292 key_type = _bcm_vp_vlan_mbrship_glp_vfi_type; 1293 } else 1294 #endif 1295 { 1296 vlan_vfi = vlan; 1297 key_type = _bcm_vp_vlan_mbrship_glp_vlan_type; 1298 } 1299 1300 rv = bcm_td2_ing_vp_vlan_membership_get(unit, 1301 vp, vlan_vfi, &ing_flags, key_type); 1302 if (BCM_SUCCESS(rv)) { 1303 ing_vp_vlan_membership_found = TRUE; 1304 *flags |= ing_flags; 1305 *flags |= BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP; 1306 } else if (rv == BCM_E_NOT_FOUND) { 1307 ing_vp_vlan_membership_found = FALSE; 1308 rv = BCM_E_NONE; 1309 } else { 1310 return rv; 1311 } 1312 1313 rv = bcm_td2_egr_vp_vlan_membership_get(unit, 1314 vp, vlan_vfi, &egr_flags, key_type); 1315 if (BCM_SUCCESS(rv)) { 1316 egr_vp_vlan_membership_found = TRUE; 1317 *flags |= egr_flags; 1318 *flags |= BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP; 1319 } else if (rv == BCM_E_NOT_FOUND) { 1320 egr_vp_vlan_membership_found = FALSE; 1321 rv = BCM_E_NONE; 1322 } else { 1323 return rv; 1324 } 1325 1326 if (!ing_vp_vlan_membership_found && !egr_vp_vlan_membership_found) { 1327 return BCM_E_NOT_FOUND; 1328 } 1329 1330 if (ing_vp_vlan_membership_found && !egr_vp_vlan_membership_found) { 1331 *flags |= BCM_VLAN_GPORT_ADD_INGRESS_ONLY; 1332 } else if (!ing_vp_vlan_membership_found && egr_vp_vlan_membership_found) { 1333 *flags |= BCM_VLAN_GPORT_ADD_EGRESS_ONLY; 1334 } 1335 1336 return rv; 1337 } 1338 1339 int 1340 bcm_td2_vp_vlan_membership_get_all(int unit, bcm_vlan_t vlan, int array_max, 1341 bcm_gport_t *gport_array, int *flags_array, 1342 int *array_size) 1343 { 1344 int i = 0; 1345 int rv = 0; 1346 int num_vp = 0; 1347 SHR_BITDCL *ing_vp_bitmap = NULL; 1348 int *ing_flags_arr = NULL; 1349 SHR_BITDCL *egr_vp_bitmap = NULL; 1350 int *egr_flags_arr = NULL; 1351 bcm_gport_t local_gport; 1352 int index = 0; 1353 int gport_found = 0; 1354 int flags = 0; 1355 1356 if ((*array_size == array_max) && (gport_array || flags_array)) { 1357 return BCM_E_NONE; 1358 } 1359 1360 num_vp = soc_mem_index_count(unit, SOURCE_VPm); 1361 1362 ing_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "ing_vp_bitmap"); 1363 if (NULL == ing_vp_bitmap) { 1364 rv = BCM_E_MEMORY; 1365 goto cleanup; 1366 } 1367 sal_memset(ing_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 1368 1369 ing_flags_arr = sal_alloc(num_vp * sizeof(int), "ing_flags_arr"); 1370 if (NULL == ing_flags_arr) { 1371 rv = BCM_E_MEMORY; 1372 goto cleanup; 1373 } 1374 sal_memset(ing_flags_arr, 0, num_vp * sizeof(int)); 1375 1376 if (soc_feature(unit, soc_feature_ing_vp_vlan_membership)) { 1377 rv = bcm_td2_ing_vp_vlan_membership_get_all(unit, vlan, ing_vp_bitmap, 1378 num_vp, ing_flags_arr); 1379 if (BCM_FAILURE(rv)) { 1380 goto cleanup; 1381 } 1382 } 1383 1384 egr_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "egr_vp_bitmap"); 1385 if (NULL == egr_vp_bitmap) { 1386 rv = BCM_E_MEMORY; 1387 goto cleanup; 1388 } 1389 sal_memset(egr_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp)); 1390 1391 egr_flags_arr = sal_alloc(num_vp * sizeof(int), "egr_flags_arr"); 1392 if (NULL == egr_flags_arr) { 1393 rv = BCM_E_MEMORY; 1394 goto cleanup; 1395 } 1396 sal_memset(egr_flags_arr, 0, num_vp * sizeof(int)); 1397 1398 if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) { 1399 rv = bcm_td2_egr_vp_vlan_membership_get_all(unit, vlan, egr_vp_bitmap, 1400 num_vp, egr_flags_arr); 1401 if (BCM_FAILURE(rv)) { 1402 goto cleanup; 1403 } 1404 } 1405 1406 for (i = 0; i < num_vp; i++) { 1407 if (!SHR_BITGET(ing_vp_bitmap, i) && 1408 !SHR_BITGET(egr_vp_bitmap, i)) { 1409 continue; 1410 } 1411 1412 if ((*array_size == array_max) && (gport_array || flags_array)) { 1413 break; 1414 } 1415 1416 if (_bcm_vp_used_get(unit, i, _bcmVpTypeVlan)) { 1417 BCM_GPORT_VLAN_PORT_ID_SET(local_gport, i); 1418 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeNiv)) { 1419 BCM_GPORT_NIV_PORT_ID_SET(local_gport, i ); 1420 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeExtender)) { 1421 BCM_GPORT_EXTENDER_PORT_ID_SET(local_gport, i); 1422 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeVxlan)) { 1423 BCM_GPORT_VXLAN_PORT_ID_SET(local_gport, i); 1424 } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeMpls)) { 1425 BCM_GPORT_MPLS_PORT_ID_SET(local_gport, i); 1426 } else { 1427 rv = BCM_E_INTERNAL; 1428 goto cleanup; 1429 } 1430 1431 if (NULL != gport_array) { 1432 gport_found = 0; 1433 for (index = 0; index < *array_size; index++) { 1434 if (gport_array[index] == local_gport) { 1435 gport_found = 1; 1436 break; 1437 } 1438 } 1439 if (gport_found == 1) { 1440 continue; 1441 } 1442 gport_array[*array_size] = local_gport; 1443 } 1444 1445 if (NULL != flags_array) { 1446 flags_array[*array_size] = ing_flags_arr[i] | 1447 egr_flags_arr[i] | 1448 BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP; 1449 1450 if (SHR_BITGET(ing_vp_bitmap, i) && !SHR_BITGET(egr_vp_bitmap, i)) { 1451 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_INGRESS_ONLY; 1452 } 1453 1454 if (!SHR_BITGET(ing_vp_bitmap, i) && SHR_BITGET(egr_vp_bitmap, i)) { 1455 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_EGRESS_ONLY; 1456 } 1457 1458 rv = bcm_tr2_vlan_gport_get(unit, vlan, local_gport, &flags); 1459 if (BCM_FAILURE(rv)) { 1460 goto cleanup; 1461 } 1462 flags_array[*array_size] |= flags; 1463 } 1464 1465 (*array_size)++; 1466 } 1467 1468 cleanup: 1469 if (NULL != ing_vp_bitmap) { 1470 sal_free(ing_vp_bitmap); 1471 } 1472 if (NULL != ing_flags_arr) { 1473 sal_free(ing_flags_arr); 1474 } 1475 if (NULL != egr_vp_bitmap) { 1476 sal_free(egr_vp_bitmap); 1477 } 1478 if (NULL != egr_flags_arr) { 1479 sal_free(egr_flags_arr); 1480 } 1481 1482 return rv; 1483 1484 } 1485 1486 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */