failover.c (9917B)
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 failover API 8 */ 9 10 #include <shared/bsl.h> 11 12 #include <soc/defs.h> 13 #include <sal/core/libc.h> 14 15 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3) 16 17 #include <soc/drv.h> 18 #include <soc/mem.h> 19 #include <soc/util.h> 20 #include <soc/debug.h> 21 #include <bcm/types.h> 22 #include <bcm/error.h> 23 #include <bcm/failover.h> 24 #include <bcm_int/esw_dispatch.h> 25 #include <bcm_int/esw/katana2.h> 26 #include <bcm_int/esw/katana.h> 27 #include <bcm_int/common/multicast.h> 28 #include <bcm_int/esw/failover.h> 29 #include <bcm_int/esw/mpls.h> 30 #include <bcm_int/esw/triumph.h> 31 #include <bcm_int/esw/triumph2.h> 32 33 34 STATIC int 35 _bcm_kt2_failover_nhi_get(int unit, bcm_gport_t port, int *nh_index) 36 { 37 int vp=0xFFFF; 38 ing_dvp_table_entry_t dvp; 39 40 if (!BCM_GPORT_IS_MPLS_PORT(port) && 41 !BCM_GPORT_IS_MIM_PORT(port) ) { 42 return BCM_E_PARAM; 43 } 44 45 if ( BCM_GPORT_IS_MPLS_PORT(port)) { 46 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 47 } else if ( BCM_GPORT_IS_MIM_PORT(port)) { 48 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 49 } 50 51 if (vp >= soc_mem_index_count(unit, SOURCE_VPm)) { 52 return BCM_E_PARAM; 53 } 54 BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp)); 55 56 /* Next-hop index is used for multicast replication */ 57 *nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, NEXT_HOP_INDEXf); 58 return BCM_E_NONE; 59 } 60 /* 61 * Function: 62 * bcm_kt2_failover_status_set 63 * Purpose: 64 * Set the parameters for a failover object 65 * Parameters: 66 * IN : unit 67 * IN : failover_id 68 * IN : value 69 * Returns: 70 * BCM_E_XXX 71 */ 72 73 int 74 bcm_kt2_failover_status_set(int unit, 75 bcm_failover_element_t *failover, 76 int value) 77 { 78 int rv = BCM_E_UNAVAIL; 79 int nh_index; 80 uint32 label_action = -1; 81 bcm_l3_egress_t egr; 82 initial_prot_group_table_entry_t prot_group_entry; 83 rx_prot_group_table_entry_t rx_prot_group_entry; 84 initial_prot_nhi_table_1_entry_t prot_nhi_1_entry; 85 86 if ((value < 0) || (value > 1)) { 87 return BCM_E_PARAM; 88 } 89 90 if (failover->failover_id != BCM_FAILOVER_INVALID) { 91 /* Group protection for Port and Tunnel: Egress and Ingress */ 92 BCM_IF_ERROR_RETURN( 93 bcm_tr2_failover_id_validate ( unit, failover->failover_id )); 94 95 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_GROUP_TABLEm, 96 MEM_BLOCK_ANY, failover->failover_id, &prot_group_entry)); 97 98 soc_mem_field32_set(unit, INITIAL_PROT_GROUP_TABLEm, 99 &prot_group_entry, REPLACE_ENABLEf, value); 100 101 BCM_IF_ERROR_RETURN( 102 soc_mem_write(unit, INITIAL_PROT_GROUP_TABLEm, 103 MEM_BLOCK_ALL, failover->failover_id, &prot_group_entry)); 104 105 BCM_IF_ERROR_RETURN (soc_mem_read(unit, RX_PROT_GROUP_TABLEm, 106 MEM_BLOCK_ANY, failover->failover_id, &rx_prot_group_entry)); 107 108 soc_mem_field32_set(unit, RX_PROT_GROUP_TABLEm, 109 &rx_prot_group_entry, DROP_DATA_ENABLEf, value); 110 111 rv = soc_mem_write(unit, RX_PROT_GROUP_TABLEm, 112 MEM_BLOCK_ALL, failover->failover_id, &rx_prot_group_entry); 113 114 }else if (failover->intf != BCM_IF_INVALID) { 115 /* Only Egress is applicable */ 116 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, failover->intf)) { 117 nh_index = failover->intf - BCM_XGS3_EGRESS_IDX_MIN(unit); 118 } else { 119 nh_index = failover->intf - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 120 } 121 122 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLE_1m, 123 MEM_BLOCK_ANY, nh_index, &prot_nhi_1_entry)); 124 125 soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLE_1m, 126 &prot_nhi_1_entry, REPLACE_ENABLEf, value); 127 128 rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLE_1m, 129 MEM_BLOCK_ALL, nh_index, &prot_nhi_1_entry); 130 if (rv < 0) { 131 return rv; 132 } 133 134 /* handle 1+1 protection on MSP (multiplex section protection) */ 135 if (soc_feature(unit, soc_feature_mpls)) { 136 bcm_l3_egress_t_init(&egr); 137 BCM_IF_ERROR_RETURN(bcm_xgs3_l3_egress_get(unit, 138 failover->intf, &egr)); 139 if (BCM_SUCCESS(_bcm_esw_failover_egr_check (unit, &egr))) { 140 if (_BCM_MULTICAST_IS_SET(egr.failover_mc_group)) { 141 142 if (BCM_XGS3_L3_MPLS_LBL_VALID(egr.mpls_label)) { 143 BCM_IF_ERROR_RETURN( 144 bcm_tr_mpls_get_label_action(unit, nh_index, 145 &label_action)); 146 switch (label_action) { 147 case _BCM_MPLS_ACTION_SWAP: 148 LOG_CLI((BSL_META_U(unit, 149 "swap\n"))); 150 rv = _bcm_kt_egress_object_p2mp_set(unit, 151 egr.failover_mc_group, 152 BCM_MPLS_SWITCH_ACTION_SWAP, value); 153 break; 154 default: 155 break; 156 } 157 } 158 } 159 } 160 } 161 } else if (failover->port != BCM_GPORT_INVALID) { 162 /* Individual protection for Pseudo-wire: Egress and Ingress */ 163 BCM_IF_ERROR_RETURN ( 164 _bcm_kt2_failover_nhi_get(unit, failover->port , &nh_index)); 165 166 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLE_1m, 167 MEM_BLOCK_ANY, nh_index, &prot_nhi_1_entry)); 168 169 soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLE_1m, 170 &prot_nhi_1_entry, REPLACE_ENABLEf, value); 171 172 rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLE_1m, 173 MEM_BLOCK_ALL, nh_index, &prot_nhi_1_entry); 174 175 } 176 return rv; 177 } 178 179 180 /* 181 * Function: 182 * bcm_kt2_failover_status_get 183 * Purpose: 184 * Get the parameters for a failover object 185 * Parameters: 186 * IN : unit 187 * IN : failover_id 188 * OUT : value 189 * Returns: 190 * BCM_E_XXX 191 */ 192 193 int 194 bcm_kt2_failover_status_get(int unit, 195 bcm_failover_element_t *failover, 196 int *value) 197 { 198 initial_prot_group_table_entry_t prot_group_entry; 199 rx_prot_group_table_entry_t rx_prot_group_entry; 200 initial_prot_nhi_table_1_entry_t prot_nhi_1_entry; 201 int nh_index; 202 203 204 if (failover->failover_id != BCM_FAILOVER_INVALID) { 205 206 BCM_IF_ERROR_RETURN( 207 bcm_tr2_failover_id_validate ( unit, failover->failover_id )); 208 209 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_GROUP_TABLEm, 210 MEM_BLOCK_ANY, failover->failover_id, &prot_group_entry)); 211 212 *value = soc_mem_field32_get(unit, INITIAL_PROT_GROUP_TABLEm, 213 &prot_group_entry, REPLACE_ENABLEf); 214 215 BCM_IF_ERROR_RETURN (soc_mem_read(unit, RX_PROT_GROUP_TABLEm, 216 MEM_BLOCK_ANY, failover->failover_id, &rx_prot_group_entry)); 217 218 *value &= soc_mem_field32_get(unit, RX_PROT_GROUP_TABLEm, 219 &rx_prot_group_entry, DROP_DATA_ENABLEf); 220 221 } else if (failover->intf != BCM_IF_INVALID) { 222 223 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, failover->intf)) { 224 nh_index = failover->intf - BCM_XGS3_EGRESS_IDX_MIN(unit); 225 } else { 226 nh_index = failover->intf - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 227 } 228 229 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLE_1m, 230 MEM_BLOCK_ANY, nh_index, &prot_nhi_1_entry)); 231 232 *value = soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLE_1m, 233 &prot_nhi_1_entry, REPLACE_ENABLEf); 234 235 } else if (failover->port != BCM_GPORT_INVALID) { 236 237 BCM_IF_ERROR_RETURN ( 238 _bcm_kt2_failover_nhi_get(unit, failover->port , &nh_index)); 239 240 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLE_1m, 241 MEM_BLOCK_ANY, nh_index, &prot_nhi_1_entry)); 242 243 *value = soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLE_1m, 244 &prot_nhi_1_entry, REPLACE_ENABLEf); 245 246 } 247 return BCM_E_NONE; 248 } 249 250 /* 251 * Function: 252 * bcm_kt2_failover_prot_nhi_cleanup 253 * Purpose: 254 * Cleanup the entry for PROT_NHI 255 * Parameters: 256 * IN : unit 257 * IN : Primary Next Hop Index 258 * Returns: 259 * BCM_E_XXX 260 */ 261 262 int 263 bcm_kt2_failover_prot_nhi_cleanup (int unit, int nh_index) 264 { 265 initial_prot_nhi_table_entry_t prot_nhi_entry; 266 initial_prot_nhi_table_1_entry_t prot_nhi_1_entry; 267 int rv; 268 269 rv = soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 270 MEM_BLOCK_ANY, nh_index, &prot_nhi_entry); 271 272 if (rv < 0){ 273 return BCM_E_NOT_FOUND; 274 } 275 276 sal_memset(&prot_nhi_entry, 0, sizeof(initial_prot_nhi_table_entry_t)); 277 278 rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLEm, 279 MEM_BLOCK_ALL, nh_index, &prot_nhi_entry); 280 281 if (rv < 0){ 282 return rv; 283 } 284 285 rv = soc_mem_read(unit, INITIAL_PROT_NHI_TABLE_1m, 286 MEM_BLOCK_ANY, nh_index, &prot_nhi_1_entry); 287 288 if (rv < 0){ 289 return BCM_E_NOT_FOUND; 290 } 291 292 sal_memset(&prot_nhi_1_entry, 0, sizeof(initial_prot_nhi_table_1_entry_t)); 293 294 rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLE_1m, 295 MEM_BLOCK_ALL, nh_index, &prot_nhi_1_entry); 296 297 return rv; 298 299 } 300 301 #endif /* defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3) */