stg.c (9616B)
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 * STG support 8 * 9 * These functions set or get port related fields in the Spanning tree 10 * table. 11 */ 12 13 #include <shared/bsl.h> 14 15 #include <soc/drv.h> 16 #include <soc/mem.h> 17 #include <soc/ptable.h> /* PVP_* defines */ 18 19 #include <bcm/types.h> 20 #include <bcm/error.h> 21 #include <bcm/stg.h> 22 23 #include <bcm_int/esw/stg.h> 24 25 #ifdef BCM_TRIDENT2PLUS_SUPPORT 26 #include <bcm_int/esw/trident2plus.h> 27 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 28 29 #define STG_BITS_PER_PORT 2 30 #define STG_PORT_MASK ((1 << STG_BITS_PER_PORT)-1) 31 #define STG_PORTS_PER_WORD (32 / STG_BITS_PER_PORT) 32 #define STG_WORD(port) ((port) / STG_PORTS_PER_WORD) 33 #define STG_BITS_SHIFT(port) \ 34 (STG_BITS_PER_PORT * ((port) % STG_PORTS_PER_WORD)) 35 #define STG_BITS_MASK(port) (STG_PORT_MASK << (STG_BITS_SHIFT(port))) 36 37 /* 38 * Function: 39 * _bcm_xgs3_stg_stp_init 40 * Purpose: 41 * Initialize spanning tree group on a single device. 42 * Parameters: 43 * unit - (IN)SOC unit number. 44 * stg - (IN)Spanning tree group id. 45 * mem - (IN)Spanning tree group table memory. 46 * Returns: 47 * BCM_E_XXX 48 */ 49 STATIC int 50 _bcm_xgs3_stg_stp_init(int unit, bcm_stg_t stg, soc_mem_t mem) 51 { 52 uint32 entry[SOC_MAX_MEM_WORDS]; /* Spanning tree port state map. */ 53 int stp_state; /* STP port state. */ 54 bcm_pbmp_t stacked; /* Bitmap of stacked ports. */ 55 bcm_port_t port; /* Port iterator. */ 56 57 #ifdef BCM_SHADOW_SUPPORT 58 /* EGR_VLAN_STGm not supported in shadow */ 59 if (SOC_IS_SHADOW(unit) && (mem == EGR_VLAN_STGm)) { 60 return SOC_E_NONE; 61 } 62 #endif 63 64 /* Set all ports to PVP_STP_DISABLED */ 65 sal_memset(entry, 0, sizeof(entry)); 66 67 /* Get all stacking ports and set them into forwarding */ 68 BCM_PBMP_ASSIGN(stacked, PBMP_ST_ALL(unit)); 69 BCM_PBMP_OR(stacked, SOC_PBMP_STACK_CURRENT(unit)); 70 stp_state = PVP_STP_FORWARDING; 71 72 #ifdef BCM_RCPU_SUPPORT 73 if (SOC_IS_RCPU_ONLY(unit)) { 74 if (BCM_STG_DEFAULT == stg) { 75 PBMP_ALL_ITER(unit, port) { 76 entry[STG_WORD(port)] |= stp_state << STG_BITS_SHIFT(port); 77 } 78 } 79 } 80 #endif /* BCM_RCPU_SUPPORT */ 81 82 if (!SOC_IS_TOMAHAWK3(unit)) { 83 /* Get all stacking ports and set them into forwarding */ 84 BCM_PBMP_ASSIGN(stacked, PBMP_ST_ALL(unit)); 85 BCM_PBMP_OR(stacked, SOC_PBMP_STACK_CURRENT(unit)); 86 87 /* Iterate over stacking ports & set stp state. */ 88 PBMP_ITER(stacked, port) { 89 entry[STG_WORD(port)] |= stp_state << STG_BITS_SHIFT(port); 90 } 91 } 92 93 #ifdef BCM_FLOWTRACKER_SUPPORT 94 /* Add FT internal ports to stp forwarding state. */ 95 PBMP_FAE_ITER(unit, port) { 96 entry[STG_WORD(port)] |= stp_state << STG_BITS_SHIFT(port); 97 } 98 #endif /* BCM_FLOWTRACKER_SUPPORT */ 99 100 /* Write spanning tree group port states to hw. */ 101 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, stg, entry)); 102 103 104 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 105 if ((BCM_STG_DEFAULT == stg) && 106 soc_feature(unit, soc_feature_vlan_vfi_membership)) { 107 108 /* Initialize the STP state for 'PVP_STP_FORWARDING' for all 109 groups on default STG */ 110 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_init( 111 unit, stg, (mem == EGR_VLAN_STGm), stp_state)); 112 } 113 #endif 114 115 return (BCM_E_NONE); 116 } 117 118 /* 119 * Function: 120 * _bcm_xgs3_stg_stp_set 121 * Purpose: 122 * Set the spanning tree state for a port in specified STG. 123 * Parameters: 124 * unit - (IN)SOC unit number. 125 * stg - (IN)Spanning tree group id. 126 * port - (IN)StrataSwitch port number. 127 * stp_state - (IN)STP state to place port in. 128 * mem - (IN)Spanning tree group table memory. 129 * Returns: 130 * BCM_E_XXX 131 */ 132 STATIC int 133 _bcm_xgs3_stg_stp_set(int unit, bcm_stg_t stg, bcm_port_t port, 134 int stp_state, soc_mem_t mem) 135 { 136 uint32 entry[SOC_MAX_MEM_WORDS]; /* STP group ports state map. */ 137 int hw_stp_state; /* STP port state in hw format. */ 138 int rv; /* Operation return status. */ 139 140 /* Input parameters verification. */ 141 if (!SOC_PORT_VALID(unit, port)) { 142 return BCM_E_PORT; 143 } 144 145 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA_SUPPORT) 146 if ((SOC_IS_ENDURO(unit) || SOC_IS_KATANAX(unit)) 147 && IS_LB_PORT(unit, port)) { 148 } else 149 #endif 150 if (!IS_PORT(unit, port)) { 151 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 152 if (!SOC_IS_TRIDENT2PLUS(unit) || !IS_CPU_PORT(unit, port)) 153 #endif 154 return BCM_E_PORT; 155 } 156 157 /* Translate API space port state to hw stp port state. */ 158 BCM_IF_ERROR_RETURN(_bcm_stg_stp_translate(unit, stp_state, &hw_stp_state)); 159 160 soc_mem_lock(unit, mem); 161 /* Read ports states for the stp group. */ 162 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stg, entry); 163 if (BCM_FAILURE(rv)) { 164 LOG_ERROR(BSL_LS_BCM_STG, 165 (BSL_META_U(unit, 166 "Error: (%d) reading port states for stg(%d)\n"), rv, stg)); 167 soc_mem_unlock(unit, mem); 168 return rv; 169 } 170 171 /* Reset port current state bit. */ 172 entry[STG_WORD(port)] &= ~(STG_BITS_MASK(port)); 173 174 /* Set new port state. */ 175 entry[STG_WORD(port)] |= (hw_stp_state << STG_BITS_SHIFT(port)); 176 177 /* Write spanning tree group port states to hw. */ 178 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, stg, entry); 179 soc_mem_unlock(unit, mem); 180 181 return rv; 182 } 183 184 /* 185 * Function: 186 * _bcm_xgs3_stg_stp_get 187 * Purpose: 188 * Retrieve the spanning tree state for a port in specified STG. 189 * Parameters: 190 * unit - (IN)SOC unit number. 191 * stg - (IN)Spanning tree group id. 192 * port - (IN)StrataSwitch port number. 193 * stp_state - (IN/OUT)Port STP state. 194 * mem - (IN)Spanning tree group table memory. 195 * Returns: 196 * BCM_E_XXX 197 */ 198 STATIC int 199 _bcm_xgs3_stg_stp_get(int unit, bcm_stg_t stg, bcm_port_t port, 200 int *stp_state, soc_mem_t mem) 201 { 202 uint32 entry[SOC_MAX_MEM_WORDS]; /* STP group ports state map. */ 203 int hw_stp_state; /* STP port state in hw format. */ 204 int rv; /* Operation return status. */ 205 206 /* Input parameters check. */ 207 if (!SOC_PORT_VALID(unit, port)) { 208 return BCM_E_PORT; 209 } 210 211 if (!IS_PORT(unit, port)) { 212 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 213 if (!SOC_IS_TRIDENT2PLUS(unit) || !IS_CPU_PORT(unit, port)) 214 #endif 215 return BCM_E_PORT; 216 } 217 218 soc_mem_lock(unit, mem); 219 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stg, entry); 220 soc_mem_unlock(unit, mem); 221 if (BCM_FAILURE(rv)) { 222 return rv; 223 } 224 /* Get specific port state from the entry. */ 225 hw_stp_state = entry[STG_WORD(port)] >> STG_BITS_SHIFT(port); 226 hw_stp_state &= STG_PORT_MASK; 227 228 /* Translate hw stp port state to API format. */ 229 BCM_IF_ERROR_RETURN(_bcm_stg_pvp_translate(unit, hw_stp_state, stp_state)); 230 231 return (BCM_E_NONE); 232 } 233 234 /* 235 * Function: 236 * _bcm_xgs3_stg_stp_init 237 * Purpose: 238 * Initialize spanning tree group on a single device. 239 * Parameters: 240 * unit - (IN)SOC unit number. 241 * stg - (IN)Spanning tree group id. 242 * Returns: 243 * BCM_E_XXX 244 */ 245 int 246 bcm_xgs3_stg_stp_init(int unit, bcm_stg_t stg) 247 { 248 BCM_IF_ERROR_RETURN(_bcm_xgs3_stg_stp_init(unit, stg, STG_TABm)); 249 #if defined(BCM_TOMAHAWK3_SUPPORT) 250 if (SOC_IS_TOMAHAWK3(unit)) { 251 BCM_IF_ERROR_RETURN(_bcm_xgs3_stg_stp_init(unit, stg, STG_TAB_2m)); 252 } 253 #endif /* BCM_TOMAHAWK3_SUPPORT */ 254 if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLAN_STGm)) { 255 BCM_IF_ERROR_RETURN(_bcm_xgs3_stg_stp_init(unit, stg, EGR_VLAN_STGm)); 256 } 257 return (BCM_E_NONE); 258 } 259 260 /* 261 * Function: 262 * bcm_xgs3_stg_stp_set 263 * Purpose: 264 * Set the spanning tree state for a port in specified STG. 265 * Parameters: 266 * unit - (IN)SOC unit number. 267 * stg - (IN)Spanning tree group id. 268 * port - (IN)StrataSwitch port number. 269 * stp_state - (IN)STP state to place port in. 270 * Returns: 271 * BCM_E_XXX 272 */ 273 int 274 bcm_xgs3_stg_stp_set(int unit, bcm_stg_t stg, bcm_port_t port, int stp_state) 275 { 276 BCM_IF_ERROR_RETURN 277 (_bcm_xgs3_stg_stp_set(unit, stg, port, stp_state, STG_TABm)); 278 #if defined(BCM_TOMAHAWK3_SUPPORT) 279 if (SOC_IS_TOMAHAWK3(unit)) { 280 BCM_IF_ERROR_RETURN( 281 _bcm_xgs3_stg_stp_set(unit, stg, port, stp_state, STG_TAB_2m)); 282 } 283 #endif /* BCM_TOMAHAWK3_SUPPORT */ 284 if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLAN_STGm)) { 285 BCM_IF_ERROR_RETURN 286 (_bcm_xgs3_stg_stp_set(unit, stg, port, stp_state, EGR_VLAN_STGm)); 287 } 288 return (BCM_E_NONE); 289 } 290 291 /* 292 * Function: 293 * bcm_xgs3_stg_stp_get 294 * Purpose: 295 * Retrieve the spanning tree state for a port in specified STG. 296 * Parameters: 297 * unit - (IN)SOC unit number. 298 * stg - (IN)Spanning tree group id. 299 * port - (IN)StrataSwitch port number. 300 * stp_state - (IN/OUT)Port STP state int the group. 301 * Returns: 302 * BCM_E_XXX 303 */ 304 int 305 bcm_xgs3_stg_stp_get(int unit, bcm_stg_t stg, bcm_port_t port, int *stp_state) 306 { 307 /* Input parameters check. */ 308 if (!stp_state) { 309 return (BCM_E_PARAM); 310 } 311 312 /* Get port state in specified group. */ 313 return _bcm_xgs3_stg_stp_get(unit, stg, port, stp_state, STG_TABm); 314 }