stg.c (8343B)
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 * Katana2 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 #define STG_BITS_PER_PORT 2 26 #define STG_PORT_MASK ((1 << STG_BITS_PER_PORT)-1) 27 #define STG_PORTS_PER_WORD (32 / STG_BITS_PER_PORT) 28 #define STG_WORD(port) ((port) / STG_PORTS_PER_WORD) 29 #define STG_BITS_SHIFT(port) \ 30 (STG_BITS_PER_PORT * ((port) % STG_PORTS_PER_WORD)) 31 #define STG_BITS_MASK(port) (STG_PORT_MASK << (STG_BITS_SHIFT(port))) 32 33 /* 34 * Function: 35 * _bcm_kt2_stg_stp_init 36 * Purpose: 37 * Initialize spanning tree group on a single device. 38 * Parameters: 39 * unit - (IN)SOC unit number. 40 * stg - (IN)Spanning tree group id. 41 * mem - (IN)Spanning tree group table memory. 42 * Returns: 43 * BCM_E_XXX 44 */ 45 STATIC int 46 _bcm_kt2_stg_stp_init(int unit, bcm_stg_t stg, soc_mem_t mem) 47 { 48 uint32 entry[SOC_MAX_MEM_WORDS]; /* Spanning tree port state map. */ 49 int stp_state; /* STP port state. */ 50 bcm_pbmp_t stacked; /* Bitmap of stacked ports. */ 51 bcm_port_t port; /* Port iterator. */ 52 53 /* Set all ports to PVP_STP_DISABLED */ 54 sal_memset(entry, 0, sizeof(entry)); 55 56 /* Get all stacking ports and set them into forwarding */ 57 BCM_PBMP_ASSIGN(stacked, PBMP_ST_ALL(unit)); 58 BCM_PBMP_OR(stacked, SOC_PBMP_STACK_CURRENT(unit)); 59 60 stp_state = PVP_STP_FORWARDING; 61 62 #ifdef BCM_RCPU_SUPPORT 63 if (SOC_IS_RCPU_ONLY(unit)) { 64 if (BCM_STG_DEFAULT == stg) { 65 PBMP_ALL_ITER(unit, port) { 66 entry[STG_WORD(port)] |= stp_state << STG_BITS_SHIFT(port); 67 } 68 } 69 } 70 #endif /* BCM_RCPU_SUPPORT */ 71 72 /* Iterate over stacking ports & set stp state. */ 73 PBMP_ITER(stacked, port) { 74 entry[STG_WORD(port)] |= stp_state << STG_BITS_SHIFT(port); 75 } 76 77 /* Write spanning tree group port states to hw. */ 78 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, stg, entry)); 79 80 return (BCM_E_NONE); 81 } 82 83 /* 84 * Function: 85 * _bcm_kt2_stg_stp_set 86 * Purpose: 87 * Set the spanning tree state for a port in specified STG. 88 * Parameters: 89 * unit - (IN)SOC unit number. 90 * stg - (IN)Spanning tree group id. 91 * port - (IN)StrataSwitch port number. 92 * stp_state - (IN)STP state to place port in. 93 * mem - (IN)Spanning tree group table memory. 94 * Returns: 95 * BCM_E_XXX 96 */ 97 STATIC int 98 _bcm_kt2_stg_stp_set(int unit, bcm_stg_t stg, bcm_port_t port, 99 int stp_state, soc_mem_t mem) 100 { 101 uint32 entry[SOC_MAX_MEM_WORDS]; /* STP group ports state map. */ 102 int hw_stp_state; /* STP port state in hw format. */ 103 int rv; /* Operation return status. */ 104 105 /* Input parameters verification. */ 106 if (!IS_LB_PORT(unit, port)) { 107 if (BCM_PBMP_MEMBER(SOC_INFO(unit).linkphy_pp_port_pbm, port) || 108 BCM_PBMP_MEMBER(SOC_INFO(unit).subtag_pp_port_pbm, port) || 109 BCM_PBMP_MEMBER(SOC_INFO(unit).general_pp_port_pbm, port)) { 110 if (!SOC_PP_PORT_VALID(unit, port)) { 111 return BCM_E_PORT; 112 } 113 } else { 114 if (!SOC_PORT_VALID(unit, port) || !IS_PORT(unit, port)) { 115 return (BCM_E_PORT); 116 } 117 } 118 } 119 120 /* Translate API space port state to hw stp port state. */ 121 BCM_IF_ERROR_RETURN(_bcm_stg_stp_translate(unit, stp_state, &hw_stp_state)); 122 123 soc_mem_lock(unit, mem); 124 /* Read ports states for the stp group. */ 125 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stg, entry); 126 if (BCM_FAILURE(rv)) { 127 LOG_ERROR(BSL_LS_BCM_L2, 128 (BSL_META_U(unit, 129 "Error: (%d) reading port states for stg(%d)\n"), rv, stg)); 130 soc_mem_unlock(unit, mem); 131 return rv; 132 } 133 134 /* Reset port current state bit. */ 135 entry[STG_WORD(port)] &= ~(STG_BITS_MASK(port)); 136 137 /* Set new port state. */ 138 entry[STG_WORD(port)] |= (hw_stp_state << STG_BITS_SHIFT(port)); 139 140 /* Write spanning tree group port states to hw. */ 141 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, stg, entry); 142 soc_mem_unlock(unit, mem); 143 144 return rv; 145 } 146 147 /* 148 * Function: 149 * _bcm_kt2_stg_stp_get 150 * Purpose: 151 * Retrieve the spanning tree state for a port in specified STG. 152 * Parameters: 153 * unit - (IN)SOC unit number. 154 * stg - (IN)Spanning tree group id. 155 * port - (IN)StrataSwitch port number. 156 * stp_state - (IN/OUT)Port STP state. 157 * mem - (IN)Spanning tree group table memory. 158 * Returns: 159 * BCM_E_XXX 160 */ 161 STATIC int 162 _bcm_kt2_stg_stp_get(int unit, bcm_stg_t stg, bcm_port_t port, 163 int *stp_state, soc_mem_t mem) 164 { 165 uint32 entry[SOC_MAX_MEM_WORDS]; /* STP group ports state map. */ 166 int hw_stp_state; /* STP port state in hw format. */ 167 int rv; /* Operation return status. */ 168 169 /* Input parameters check. */ 170 if (!IS_LB_PORT(unit, port)) { 171 if (BCM_PBMP_MEMBER(SOC_INFO(unit).linkphy_pp_port_pbm, port) || 172 BCM_PBMP_MEMBER(SOC_INFO(unit).subtag_pp_port_pbm, port) || 173 BCM_PBMP_MEMBER(SOC_INFO(unit).general_pp_port_pbm, port)) { 174 if (!SOC_PP_PORT_VALID(unit, port)) { 175 return BCM_E_PORT; 176 } 177 } else { 178 if (!SOC_PORT_VALID(unit, port) || !IS_PORT(unit, port)) { 179 return (BCM_E_PORT); 180 } 181 } 182 } 183 184 soc_mem_lock(unit, mem); 185 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stg, entry); 186 soc_mem_unlock(unit, mem); 187 if (BCM_FAILURE(rv)) { 188 return rv; 189 } 190 /* Get specific port state from the entry. */ 191 hw_stp_state = entry[STG_WORD(port)] >> STG_BITS_SHIFT(port); 192 hw_stp_state &= STG_PORT_MASK; 193 194 /* Translate hw stp port state to API format. */ 195 BCM_IF_ERROR_RETURN(_bcm_stg_pvp_translate(unit, hw_stp_state, stp_state)); 196 197 return (BCM_E_NONE); 198 } 199 200 /* 201 * Function: 202 * _bcm_kt2_stg_stp_init 203 * Purpose: 204 * Initialize spanning tree group on a single device. 205 * Parameters: 206 * unit - (IN)SOC unit number. 207 * stg - (IN)Spanning tree group id. 208 * Returns: 209 * BCM_E_XXX 210 */ 211 int 212 bcm_kt2_stg_stp_init(int unit, bcm_stg_t stg) 213 { 214 BCM_IF_ERROR_RETURN(_bcm_kt2_stg_stp_init(unit, stg, STG_TABm)); 215 if (SOC_IS_FBX(unit)) { 216 BCM_IF_ERROR_RETURN(_bcm_kt2_stg_stp_init(unit, stg, EGR_VLAN_STGm)); 217 } 218 return (BCM_E_NONE); 219 } 220 221 /* 222 * Function: 223 * bcm_kt2_stg_stp_set 224 * Purpose: 225 * Set the spanning tree state for a port in specified STG. 226 * Parameters: 227 * unit - (IN)SOC unit number. 228 * stg - (IN)Spanning tree group id. 229 * port - (IN)StrataSwitch port number. 230 * stp_state - (IN)STP state to place port in. 231 * Returns: 232 * BCM_E_XXX 233 */ 234 int 235 bcm_kt2_stg_stp_set(int unit, bcm_stg_t stg, 236 bcm_port_t port, int stp_state) 237 { 238 BCM_IF_ERROR_RETURN 239 (_bcm_kt2_stg_stp_set(unit, stg, port, stp_state, STG_TABm)); 240 BCM_IF_ERROR_RETURN 241 (_bcm_kt2_stg_stp_set(unit, stg, port, stp_state, EGR_VLAN_STGm)); 242 return (BCM_E_NONE); 243 } 244 245 /* 246 * Function: 247 * bcm_kt2_stg_stp_get 248 * Purpose: 249 * Retrieve the spanning tree state for a port in specified STG. 250 * Parameters: 251 * unit - (IN)SOC unit number. 252 * stg - (IN)Spanning tree group id. 253 * port - (IN)StrataSwitch port number. 254 * stp_state - (IN/OUT)Port STP state int the group. 255 * Returns: 256 * BCM_E_XXX 257 */ 258 int 259 bcm_kt2_stg_stp_get(int unit, bcm_stg_t stg, 260 bcm_port_t port, int *stp_state) 261 { 262 /* Input parameters check. */ 263 if (!stp_state) { 264 return (BCM_E_PARAM); 265 } 266 267 /* Get port state in specified group. */ 268 return _bcm_kt2_stg_stp_get(unit, stg, port, stp_state, STG_TABm); 269 } 270