field.c (11714B)
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 * SOC Routines related to Field module. 8 */ 9 10 #include <soc/debug.h> 11 #include <soc/tomahawk.h> 12 #include <bcm_int/esw/tomahawk.h> 13 #include <bcm_int/esw/xgs4.h> 14 #if defined(BCM_TOMAHAWK_SUPPORT) 15 16 /* 17 * Function: 18 * soc_th_field_mem_mode_get 19 * Purpose: 20 * Retrieve Field Processor Group operational mode 21 * for the given field memory. 22 * Parameters: 23 * unit - (IN) BCM Device number. 24 * mem - (IN) Field TCAM Memory. 25 * mode - (OUT) Reference to SER memory mode. 26 * 27 * Returns: 28 * SOC_E_NONE - Operation successful. 29 * SOC_E_PARAM - Invalid parameter. 30 * SOC_E_INIT - BCM unit not initialized. 31 * 32 * Notes: 33 * Valid "mem" input parameter values supported by 34 * this routine: 35 * "VFP_TCAMm, EFP_TCAMm, IFP_TCAMm," 36 * "IFP_TCAM_WIDEm, IFP_LOGICAL_TABLE_TCAMm" 37 * "EXACT_MATCH_LOGICAL_TABLE_SELECTm." 38 */ 39 int 40 soc_th_field_mem_mode_get(int unit, soc_mem_t mem, int *mode) 41 { 42 bcm_field_qualify_t stage; /* Field Stage Qualifier Id */ 43 bcm_field_group_oper_mode_t oper_mode; /* Field Operation Mode */ 44 int rv; /* Return Value */ 45 46 /* Validate input parameters */ 47 if (mode == NULL) { 48 return SOC_E_PARAM; 49 } 50 51 switch (mem) { 52 /* Field lookup TCAMs and SRAMs */ 53 case VFP_TCAMm: 54 case VFP_POLICY_TABLEm: 55 stage = bcmFieldQualifyStageLookup; 56 break; 57 58 /* Field Egress TCAMs and SRAMs */ 59 case EFP_TCAMm: 60 case EFP_POLICY_TABLEm: 61 case EFP_COUNTER_TABLEm: 62 case EFP_METER_TABLEm: 63 stage = bcmFieldQualifyStageEgress; 64 break; 65 66 /* Field Ingress TCAMs */ 67 case IFP_LOGICAL_TABLE_SELECTm: 68 case IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm: 69 case IFP_TCAMm: 70 /* Field Ingress SRAMs */ 71 case IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm: 72 case IFP_LOGICAL_TABLE_ACTION_PRIORITYm: 73 case IFP_KEY_GEN_PROGRAM_PROFILEm: 74 case IFP_KEY_GEN_PROGRAM_PROFILE2m: 75 case IFP_POLICY_TABLEm: 76 case IFP_METER_TABLEm: 77 stage = bcmFieldQualifyStageIngress; 78 break; 79 80 /* Exact Match TCAMs */ 81 case EXACT_MATCH_LOGICAL_TABLE_SELECTm: 82 case EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm: 83 /* Exact Match SRAMs */ 84 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm: 85 case EXACT_MATCH_KEY_GEN_PROGRAM_PROFILEm: 86 case EXACT_MATCH_ACTION_PROFILEm: 87 case EXACT_MATCH_QOS_ACTIONS_PROFILEm: 88 case EXACT_MATCH_DEFAULT_POLICYm: 89 case EXACT_MATCH_KEY_GEN_MASKm: 90 case EXACT_MATCH_2m: 91 case EXACT_MATCH_4m: 92 case EXACT_MATCH_2_ENTRY_ONLYm: 93 case EXACT_MATCH_4_ENTRY_ONLYm: 94 stage = bcmFieldQualifyStageIngressExactMatch; 95 break; 96 97 /* Field Ingress Compression TCAMs and SRAMs */ 98 case SRC_COMPRESSIONm: 99 case SRC_COMPRESSION_TCAM_ONLYm: 100 case SRC_COMPRESSION_DATA_ONLYm: 101 case DST_COMPRESSIONm: 102 case DST_COMPRESSION_TCAM_ONLYm: 103 case DST_COMPRESSION_DATA_ONLYm: 104 stage = bcmFieldQualifyStageClass; 105 break; 106 case TTL_FNm: 107 case TOS_FNm: 108 case TCP_FNm: 109 case IP_PROTO_MAPm: 110 stage = bcmFieldQualifyStageClassExactMatch; 111 break; 112 case FP_UDF_TCAMm: 113 case FP_UDF_OFFSETm: 114 /* 115 * When udf support is not available or the memory is not being used 116 * by either UDF or FIELD module, return BCM_E_UNAVAIL 117 */ 118 if (soc_feature(unit, soc_feature_udf_support) && UDF_CTRL(unit)) { 119 if (UDF_CTRL(unit)->udf_used_by_module == UDF_USED_BY_UDF_MODULE) { 120 bcm_udf_oper_mode_t udf_oper_mode = 0; 121 rv = bcmi_xgs4_udf_oper_mode_get(unit, &udf_oper_mode); 122 if (BCM_SUCCESS(rv)) { 123 *mode = (udf_oper_mode == bcmUdfOperModeGlobal) ? 124 _SOC_SER_MEM_MODE_GLOBAL : _SOC_SER_MEM_MODE_PIPE_UNIQUE; 125 } 126 } else if(UDF_CTRL(unit)->udf_used_by_module == 127 UDF_USED_BY_FIELD_MODULE) { 128 /* 129 * Currently Field Module is not supporting per-pipe mode 130 * for this memory. Hence, returning it as Global mode. 131 */ 132 *mode = _SOC_SER_MEM_MODE_GLOBAL; 133 rv = BCM_E_NONE; 134 } else { 135 /* Not used by any of the module. */ 136 rv = BCM_E_UNAVAIL; 137 } 138 } else { 139 /* Feature doesn't support */ 140 rv = BCM_E_UNAVAIL; 141 } 142 143 if (BCM_FAILURE(rv)) { 144 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 145 "Failed to get Operation Mode[%d] for UDF Memory[%d].\n"), 146 rv, mem)); 147 } 148 return rv; 149 case IFP_TCAM_WIDEm: 150 if (soc_property_get(unit, spn_FIELD_ATOMIC_UPDATE, FALSE) == TRUE) { 151 stage = bcmFieldQualifyStageIngress; 152 } else { 153 /* 154 * Inorder to support bcmFieldQualifyInPorts in Global mode, 155 * IP_TCAM_WIDE should always be in pipe local mode. 156 */ 157 *mode = _SOC_SER_MEM_MODE_PIPE_UNIQUE; 158 return BCM_E_NONE; 159 } 160 break; 161 162 default: 163 return SOC_E_UNAVAIL; 164 break; 165 } 166 167 rv = _bcm_field_th_group_oper_mode_get(unit, stage, &oper_mode); 168 if (SOC_FAILURE(rv)) { 169 LOG_ERROR(BSL_LS_BCM_FP, 170 (BSL_META_U(unit, 171 "Failed to get Group Operation Mode[%d] for " 172 "Stage Qualifier[%d]/TCAM Memory[%d].\n"), 173 rv, stage, mem)); 174 return rv; 175 } 176 177 *mode = (oper_mode == bcmFieldGroupOperModeGlobal) ? 178 _SOC_SER_MEM_MODE_GLOBAL:_SOC_SER_MEM_MODE_PIPE_UNIQUE; 179 180 return SOC_E_NONE; 181 } 182 183 /* 184 * Function: 185 * soc_mem_field_nw_tcam_prio_order_index_get 186 * 187 * Purpose: 188 * To retrieve the right priority index for the given index for the groups 189 * operated in narrow wide (80-bit) TCAMs. 190 * 191 * Parameters: 192 * unit - (IN) BCM device number. 193 * mem - (IN) Memory 194 * tcam_idx - (IN) Reference to TCAM index. 195 * 196 * Returns: 197 * SOC_E_NONE - Success 198 */ 199 int soc_mem_field_nw_tcam_prio_order_index_get(int unit, 200 soc_mem_t mem, 201 int *tcam_idx) 202 { 203 int slice_num; 204 soc_reg_t reg = INVALIDr; 205 206 if (soc_feature(unit, soc_feature_fp_nw_tcam_prio_order_war) && 207 ((mem == IFP_TCAMm) || (mem == IFP_TCAM_PIPE0m) || 208 (mem == IFP_TCAM_PIPE1m) || (mem == IFP_TCAM_PIPE2m) || 209 (mem == IFP_TCAM_PIPE3m) || (mem == IFP_POLICY_TABLEm) || 210 (mem == IFP_POLICY_TABLE_PIPE0m) || (mem == IFP_POLICY_TABLE_PIPE1m) || 211 (mem == IFP_POLICY_TABLE_PIPE2m) || (mem == IFP_POLICY_TABLE_PIPE3m))) { 212 213 if (tcam_idx == NULL) { 214 return SOC_E_PARAM; 215 } 216 217 /* 218 * As IFP_POLICY_TABLE is common among multiple IFP_TCAM modes, 219 * retrieve the field mode in-case of Policy Table. 220 */ 221 if (mem == IFP_POLICY_TABLEm) { 222 reg = IFP_CONFIGr; 223 } else if (mem == IFP_POLICY_TABLE_PIPE0m) { 224 reg = IFP_CONFIG_PIPE0r; 225 } else if (mem == IFP_POLICY_TABLE_PIPE1m) { 226 reg = IFP_CONFIG_PIPE1r; 227 } else if (mem == IFP_POLICY_TABLE_PIPE2m) { 228 reg = IFP_CONFIG_PIPE2r; 229 } else if (mem == IFP_POLICY_TABLE_PIPE3m) { 230 reg = IFP_CONFIG_PIPE3r; 231 } 232 233 /* Calculate slice number of the given tcam_idx. */ 234 slice_num = (*tcam_idx)/512; 235 236 if (reg != INVALIDr) { 237 uint32 regval = 0; 238 uint32 mode; 239 240 SOC_IF_ERROR_RETURN 241 (soc_reg32_get(unit, reg, REG_PORT_ANY, slice_num, ®val)); 242 243 if (soc_feature(unit, soc_feature_ifp_no_narrow_mode_support)) { 244 mode = 1; 245 } else { 246 mode = soc_reg_field_get(unit, reg, regval, IFP_SLICE_MODEf); 247 } 248 249 /* Return if the TCAM mode is WIDE. */ 250 if (mode == 1) { 251 return SOC_E_NONE; 252 } 253 } 254 255 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 256 "Changed TCAM_ID: %d -"), *tcam_idx)); 257 258 if (*tcam_idx % 2) { 259 *tcam_idx = 256 + (slice_num * 256) + ((*tcam_idx)/2); 260 } else { 261 *tcam_idx = (slice_num * 256) + ((*tcam_idx)/2); 262 } 263 264 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 265 " %d for slice:%d\n\r"), *tcam_idx, slice_num)); 266 } 267 268 return SOC_E_NONE; 269 } 270 271 /* 272 * Function: 273 * soc_th_ifp_mem_write 274 * Purpose: 275 * Write a memory internal to the SOC for TH IFP. 276 * Notes: 277 * GBP/CBP memory should only accessed when MMU is in DEBUG mode. 278 */ 279 int 280 soc_th_ifp_mem_write(int unit, soc_mem_t mem, int copyno, int index, 281 void *entry_data) 282 { 283 int rv; 284 285 if (soc_feature(unit, soc_feature_fp_nw_tcam_prio_order_war) && 286 ((mem == IFP_TCAMm) || (mem == IFP_TCAM_PIPE0m) || 287 (mem == IFP_TCAM_PIPE1m) || (mem == IFP_TCAM_PIPE2m) || 288 (mem == IFP_TCAM_PIPE3m) || (mem == IFP_POLICY_TABLEm) || 289 (mem == IFP_POLICY_TABLE_PIPE0m) || (mem == IFP_POLICY_TABLE_PIPE1m) || 290 (mem == IFP_POLICY_TABLE_PIPE2m) || (mem == IFP_POLICY_TABLE_PIPE3m))) { 291 292 rv = soc_mem_field_nw_tcam_prio_order_index_get(unit, mem, &index); 293 SOC_IF_ERROR_RETURN(rv); 294 295 } 296 297 return soc_mem_write(unit, mem, copyno, index, entry_data); 298 } 299 300 /* 301 * Function: 302 * soc_th_ifp_mem_read 303 * Purpose: 304 * Read a memory internal to the SOC for TH IFP. 305 * Notes: 306 * GBP/CBP memory should only accessed when MMU is in DEBUG mode. 307 */ 308 int 309 soc_th_ifp_mem_read(int unit, soc_mem_t mem, int copyno, int index, 310 void *entry_data) 311 { 312 int rv; 313 314 if (soc_feature(unit, soc_feature_fp_nw_tcam_prio_order_war) && 315 ((mem == IFP_TCAMm) || (mem == IFP_TCAM_PIPE0m) || 316 (mem == IFP_TCAM_PIPE1m) || (mem == IFP_TCAM_PIPE2m) || 317 (mem == IFP_TCAM_PIPE3m) || (mem == IFP_POLICY_TABLEm) || 318 (mem == IFP_POLICY_TABLE_PIPE0m) || (mem == IFP_POLICY_TABLE_PIPE1m) || 319 (mem == IFP_POLICY_TABLE_PIPE2m) || (mem == IFP_POLICY_TABLE_PIPE3m))) { 320 321 rv = soc_mem_field_nw_tcam_prio_order_index_get(unit, mem, &index); 322 SOC_IF_ERROR_RETURN(rv); 323 324 } 325 326 return soc_mem_read(unit, mem, copyno, index, entry_data); 327 } 328 329 /* 330 * Function: 331 * soc_th_ifp_slice_mode_get 332 * Purpose: 333 * Retrieve the IFP TCAM slice mode and enable status. 334 * Parameters: 335 * unit - (IN) BCM Device number. 336 * pipe - (IN) Pipe Instance. (pipe < 0 indicates Global.) 337 * slice_num - (IN) IFP TCAM Slice number. 338 * slice_mode - (OUT) IFP TCAM mode. 339 * slice_enabled - (OUT) Whether the slice is enabled. 340 * 341 * Returns: 342 * SOC_E_NONE - Operation successful. 343 * SOC_E_PARAM - Invalid parameter. 344 * SOC_E_INIT - Field Module is not initialized. 345 */ 346 int 347 soc_th_ifp_slice_mode_get(int unit, int pipe, int slice_num, int *slice_mode, 348 int *slice_enabled) 349 { 350 int rv; /* Return Value */ 351 352 /* Validate input parameters */ 353 if (slice_mode == NULL || slice_enabled == NULL) { 354 return SOC_E_PARAM; 355 } 356 357 rv = _bcm_field_th_ifp_slice_mode_get(unit, pipe, slice_num, 358 slice_mode, slice_enabled); 359 return rv; 360 } 361 362 #endif /* BCM_TOMAHAWK_SUPPORT */