field.c (256452B)
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: field.c 8 * Purpose: Field Processor installation functions. 9 */ 10 #include <shared/bsl.h> 11 12 #include <soc/defs.h> 13 #include <soc/scache.h> 14 15 #include <bcm/error.h> 16 #include <bcm/field.h> 17 #include <bcm/mirror.h> 18 19 #if defined(BCM_RAPTOR_SUPPORT) && defined(BCM_FIELD_SUPPORT) 20 21 #include <bcm_int/esw_dispatch.h> 22 #include <bcm_int/esw/field.h> 23 #include <bcm_int/esw/firebolt.h> 24 #include <bcm_int/esw/raptor.h> 25 #include <bcm_int/esw/mirror.h> 26 #include <bcm_int/esw/mbcm.h> 27 28 STATIC void _field_raptor_functions_init(_field_funct_t *functions); 29 STATIC int _field_raptor_detach(int unit, _field_control_t *fc); 30 STATIC int _field_raptor_hw_clear(int unit, _field_stage_t *stage_fc); 31 STATIC int _field_raptor_entry_remove(int unit, _field_entry_t *f_ent, 32 int tcam_idx); 33 STATIC int _field_raptor_tables_entry_clear(int unit, 34 _field_entry_t *f_ent, 35 _field_stage_id_t stage_id, 36 int tcam_idx); 37 STATIC int _field_raptor_group_install(int unit, _field_group_t *fg); 38 STATIC int _field_raptor_entry_install(int unit, _field_entry_t *f_ent, 39 int tcam_idx); 40 STATIC int _field_raptor_entry_reinstall(int unit, _field_entry_t *f_ent, 41 int tcam_idx); 42 STATIC int _field_raptor_selcodes_install(int unit, _field_group_t *fg, 43 uint8 slice_numb, 44 bcm_pbmp_t pbmp, int selcode_index); 45 STATIC int _field_raptor_policy_install(int unit, _field_entry_t *f_ent, 46 int tcam_idx); 47 STATIC int _field_raptor_ipbm_install(int unit, _field_entry_t *f_ent); 48 STATIC int _field_raptor_tcam_install(int unit, _field_entry_t *f_ent, 49 int tcam_idx); 50 STATIC int _field_raptor_tcam_get(int unit, _field_entry_t *f_ent, 51 fp_tcam_entry_t *t_entry); 52 STATIC int _field_raptor_action_get(int unit, _field_entry_t *f_ent, 53 int tcam_idx, _field_action_t *fa, 54 fp_policy_table_entry_t *p_entry); 55 STATIC int _field_raptor_meter_action_set(int unit, _field_entry_t *f_ent, 56 fp_policy_table_entry_t *p_entry); 57 STATIC int _field_raptor_entry_move(int unit, _field_entry_t *f_ent, 58 int parts_count, int *tcam_idx_old, 59 int *tcam_idx_new); 60 STATIC int _field_raptor_entry_rule_copy(int unit, int old_index, 61 int new_index); 62 STATIC int _field_raptor_entry_rule_del(int unit, int index); 63 STATIC int _field_raptor_entry_ipbm_copy(int unit, _field_entry_t *f_ent, 64 int part, int new_tcam_idx); 65 STATIC int _field_raptor_ipbm_entry_set(int unit, int row, 66 int col, uint32 enable); 67 STATIC int _field_raptor_ipbm_entry_get(int unit, int row, 68 int col, uint32 *enable); 69 STATIC int _field_raptor_action_params_check(int unit,_field_entry_t *f_ent, 70 _field_action_t *fa); 71 72 /* 73 * Function: 74 * _field_rp_ingress_qualifiers_init 75 * Purpose: 76 * Initialize device stage ingress qaualifiers 77 * select codes & offsets 78 * Parameters: 79 * unit - (IN) BCM device number. 80 * stage_fc - (IN) Field Processor stage control structure. 81 * 82 * Returns: 83 * BCM_E_NONE 84 */ 85 STATIC int 86 _field_rp_ingress_qualifiers_init(int unit, _field_stage_t *stage_fc) 87 { 88 soc_mem_t tcam_mem; /* TCAM memory id. */ 89 soc_mem_t policy_mem; /* Policy table memory id . */ 90 int offset; /* Tcam field offset. */ 91 int rv; /* Operation return status. */ 92 _FP_QUAL_DECL; 93 94 /* Input parameters check. */ 95 if (NULL == stage_fc) { 96 return (BCM_E_PARAM); 97 } 98 99 rv = _field_fb_tcam_policy_mem_get(unit, stage_fc->stage_id, 100 &tcam_mem, &policy_mem); 101 BCM_IF_ERROR_RETURN(rv); 102 103 _key_fld_ = F4f; 104 105 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDrop, 106 _bcmFieldSliceSelFpf4, 1, 2, 1); 107 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2Format, 108 _bcmFieldSliceSelFpf4, 1, 0, 2); 109 110 _key_fld_ = KEYf; 111 offset = 0; 112 113 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyStage, 114 _bcmFieldSliceSelDisable, 0, 0, 0); 115 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpType, 116 _bcmFieldSliceSelDisable, 0, 0, 0); 117 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInPorts, 118 _bcmFieldSliceSelDisable, 0, 0, 0); 119 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInPort, 120 _bcmFieldSliceSelDisable, 0, 0, 0); 121 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyStageIngress, 122 _bcmFieldSliceSelDisable, 0, 0, 0); 123 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIp4, 124 _bcmFieldSliceSelDisable, 0, 0, 0); 125 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIp6, 126 _bcmFieldSliceSelDisable, 0, 0, 0); 127 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyHiGig, 128 _bcmFieldSliceSelDisable, 0, 0, 0); 129 130 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2Format, 131 _bcmFieldSliceSelFpf3, 0, 0, 2); 132 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyVlanFormat, 133 _bcmFieldSliceSelFpf3, 0, 2, 2); 134 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyMHOpcode, 135 _bcmFieldSliceSelFpf3, 0, 6, 3); 136 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyPacketRes, 137 _bcmFieldSliceSelFpf3, 0, 9, 4); 138 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpInfo, 139 _bcmFieldSliceSelFpf3, 0, 13, 3); 140 141 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcPort, 142 _bcmFieldSliceSelFpf3, 1, 0, 11); 143 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcTrunk, 144 _bcmFieldSliceSelFpf3, 1, 0, 7); 145 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyMHOpcode, 146 _bcmFieldSliceSelFpf3, 1, 11, 3); 147 148 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstPort, 149 _bcmFieldSliceSelFpf3, 2, 0, 11); 150 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstTrunk, 151 _bcmFieldSliceSelFpf3, 2, 0, 7); 152 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyMHOpcode, 153 _bcmFieldSliceSelFpf3, 2, 11, 3); 154 155 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTunnelTerminated, 156 _bcmFieldSliceSelFpf3, 3, 0, 1); 157 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyVlanTranslationHit, 158 _bcmFieldSliceSelFpf3, 3, 1, 1); 159 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyForwardingVlanValid, 160 _bcmFieldSliceSelFpf3, 3, 2, 1); 161 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIngressStpState, 162 _bcmFieldSliceSelFpf3, 3, 3, 2); 163 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2SrcHit, 164 _bcmFieldSliceSelFpf3, 3, 5, 1); 165 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2SrcStatic, 166 _bcmFieldSliceSelFpf3, 3, 6, 1); 167 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2DestHit, 168 _bcmFieldSliceSelFpf3, 3, 7, 1); 169 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3Routable, 170 _bcmFieldSliceSelFpf3, 3, 8, 1); 171 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2CacheHit, 172 _bcmFieldSliceSelFpf3, 3, 9, 1); 173 #if defined (BCM_RAVEN_SUPPORT) 174 if (SOC_IS_RAVEN(unit)) { 175 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3SrcHostHit, 176 _bcmFieldSliceSelFpf3, 3, 10, 1); 177 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3DestHostHit, 178 _bcmFieldSliceSelFpf3, 3, 11, 1); 179 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpmcStarGroupHit, 180 _bcmFieldSliceSelFpf3, 3, 12, 1); 181 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3DestRouteHit, 182 _bcmFieldSliceSelFpf3, 3, 13, 1); 183 } 184 #endif /* BCM_RAVEN_SUPPORT */ 185 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2StationMove, 186 _bcmFieldSliceSelFpf3, 3, 14, 1); 187 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDosAttack, 188 _bcmFieldSliceSelFpf3, 3, 15, 1); 189 190 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTcpControl, 191 _bcmFieldSliceSelFpf3, 4, 0, 6); 192 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDSCP, 193 _bcmFieldSliceSelFpf3, 4, 6, 8); 194 195 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlan, 196 _bcmFieldSliceSelFpf3, 5, 0, 16); 197 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanId, 198 _bcmFieldSliceSelFpf3, 5, 0, 12); 199 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanCfi, 200 _bcmFieldSliceSelFpf3, 5, 12, 1); 201 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanPri, 202 _bcmFieldSliceSelFpf3, 5, 13, 3); 203 204 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDSCP, 205 _bcmFieldSliceSelFpf3, 6, 0, 8); 206 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpProtocol, 207 _bcmFieldSliceSelFpf3, 6, 8, 8); 208 209 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyRangeCheck, 210 _bcmFieldSliceSelFpf3, 7, 0, 16); 211 212 /* FPF2 */ 213 offset += _FIELD_MEM_FIELD_LENGTH(unit, tcam_mem, F3f); 214 215 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTtl, 216 _bcmFieldSliceSelFpf2, 0, offset, 8); 217 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTcpControl, 218 _bcmFieldSliceSelFpf2, 0, (offset + 8), 6); 219 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpFlags, 220 _bcmFieldSliceSelFpf2, 0, (offset + 14), 2); 221 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDSCP, 222 _bcmFieldSliceSelFpf2, 0, (offset + 16), 8); 223 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL4DstPort, 224 _bcmFieldSliceSelFpf2, 0, (offset + 24), 16); 225 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL4SrcPort, 226 _bcmFieldSliceSelFpf2, 0, (offset + 40), 16); 227 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpProtocol, 228 _bcmFieldSliceSelFpf2, 0, (offset + 56), 8); 229 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstIp, 230 _bcmFieldSliceSelFpf2, 0, (offset + 64), 32); 231 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcIp, 232 _bcmFieldSliceSelFpf2, 0, (offset + 96), 32); 233 234 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTtl, 235 _bcmFieldSliceSelFpf2, 1, offset, 8); 236 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTcpControl, 237 _bcmFieldSliceSelFpf2, 1, (offset + 8), 6); 238 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpFlags, 239 _bcmFieldSliceSelFpf2, 1, (offset + 14), 2); 240 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDSCP, 241 _bcmFieldSliceSelFpf2, 1, (offset + 16), 8); 242 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL4DstPort, 243 _bcmFieldSliceSelFpf2, 1, (offset + 24), 16); 244 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyRangeCheck, 245 _bcmFieldSliceSelFpf2, 1, (offset + 40), 16); 246 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpProtocol, 247 _bcmFieldSliceSelFpf2, 1, (offset + 56), 8); 248 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstIp, 249 _bcmFieldSliceSelFpf2, 1, (offset + 64), 32); 250 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcIp, 251 _bcmFieldSliceSelFpf2, 1, (offset + 96), 32); 252 253 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTtl, 254 _bcmFieldSliceSelFpf2, 2, offset, 8); 255 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTcpControl, 256 _bcmFieldSliceSelFpf2, 2, (offset + 8), 6); 257 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpFlags, 258 _bcmFieldSliceSelFpf2, 2, (offset + 14), 2); 259 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDSCP, 260 _bcmFieldSliceSelFpf2, 2, (offset + 16), 8); 261 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL4SrcPort, 262 _bcmFieldSliceSelFpf2, 2, (offset + 24), 16); 263 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyRangeCheck, 264 _bcmFieldSliceSelFpf2, 2, (offset + 40), 16); 265 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpProtocol, 266 _bcmFieldSliceSelFpf2, 2, (offset + 56), 8); 267 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstIp, 268 _bcmFieldSliceSelFpf2, 2, (offset + 64), 32); 269 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcIp, 270 _bcmFieldSliceSelFpf2, 2, (offset + 96), 32); 271 272 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcIp6, 273 _bcmFieldSliceSelFpf2, 3, offset, 128); 274 275 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstIp6, 276 _bcmFieldSliceSelFpf2, 4, offset, 128); 277 278 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTcpControl, 279 _bcmFieldSliceSelFpf2, 5, offset, 6); 280 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTtl, 281 _bcmFieldSliceSelFpf2, 5, (offset + 6), 8); 282 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIp6FlowLabel, 283 _bcmFieldSliceSelFpf2, 5, (offset + 14), 20); 284 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDSCP, 285 _bcmFieldSliceSelFpf2, 5, (offset + 34), 8); 286 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpProtocol, 287 _bcmFieldSliceSelFpf2, 5, (offset + 42), 8); 288 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstIp6High, 289 _bcmFieldSliceSelFpf2, 5, (offset + 50), 64); 290 291 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlan, 292 _bcmFieldSliceSelFpf2, 6, offset, 16); 293 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanId, 294 _bcmFieldSliceSelFpf2, 6, offset, 12); 295 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanCfi, 296 _bcmFieldSliceSelFpf2, 6, (offset + 12), 1); 297 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanPri, 298 _bcmFieldSliceSelFpf2, 6, (offset + 13), 3); 299 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyEtherType, 300 _bcmFieldSliceSelFpf2, 6, (offset + 16), 16); 301 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcMac, 302 _bcmFieldSliceSelFpf2, 6, (offset + 32), 48); 303 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstMac, 304 _bcmFieldSliceSelFpf2, 6, (offset + 80), 48); 305 306 307 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlan, 308 _bcmFieldSliceSelFpf2, 7, offset, 16); 309 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanId, 310 _bcmFieldSliceSelFpf2, 7, offset, 12); 311 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanCfi, 312 _bcmFieldSliceSelFpf2, 7, (offset + 12), 1); 313 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanPri, 314 _bcmFieldSliceSelFpf2, 7, (offset + 13), 3); 315 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyEtherType, 316 _bcmFieldSliceSelFpf2, 7, (offset + 16), 16); 317 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcIp, 318 _bcmFieldSliceSelFpf2, 7, (offset + 32), 32); 319 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcMac, 320 _bcmFieldSliceSelFpf2, 7, (offset + 64), 48); 321 322 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlan, 323 _bcmFieldSliceSelFpf2, 8, offset, 16); 324 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanId, 325 _bcmFieldSliceSelFpf2, 8, offset, 12); 326 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanCfi, 327 _bcmFieldSliceSelFpf2, 8, (offset + 12), 1); 328 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanPri, 329 _bcmFieldSliceSelFpf2, 8, (offset + 13), 3); 330 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyEtherType, 331 _bcmFieldSliceSelFpf2, 8, (offset + 16), 16); 332 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstIp, 333 _bcmFieldSliceSelFpf2, 8, (offset + 32), 32); 334 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstMac, 335 _bcmFieldSliceSelFpf2, 8, (offset + 64), 48); 336 337 _FP_QUAL_ADD(unit, stage_fc, _bcmFieldQualifyData0, 338 _bcmFieldSliceSelFpf2, 9, offset, 128); 339 340 _FP_QUAL_ADD(unit, stage_fc, _bcmFieldQualifyData1, 341 _bcmFieldSliceSelFpf2, 0xa, offset, 128); 342 343 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcIp6High, 344 _bcmFieldSliceSelFpf2, 0xb, offset, 64); 345 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstIp6High, 346 _bcmFieldSliceSelFpf2, 0xb, (offset + 64), 64); 347 348 349 #if defined(BCM_RAVEN_SUPPORT) 350 if (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 351 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTtl, 352 _bcmFieldSliceSelFpf2, 0xc, offset, 8); 353 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTcpControl, 354 _bcmFieldSliceSelFpf2, 0xc, (offset + 8), 6); 355 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpFrag, 356 _bcmFieldSliceSelFpf2, 0xc, (offset + 14), 2); 357 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDSCP, 358 _bcmFieldSliceSelFpf2, 0xc, (offset + 16), 8); 359 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL4DstPort, 360 _bcmFieldSliceSelFpf2, 0xc, (offset + 24), 16); 361 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL4SrcPort, 362 _bcmFieldSliceSelFpf2, 0xc, (offset + 40), 16); 363 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpProtocol, 364 _bcmFieldSliceSelFpf2, 0xc, (offset + 56), 8); 365 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstIp, 366 _bcmFieldSliceSelFpf2, 0xc, (offset + 64), 32); 367 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcIp, 368 _bcmFieldSliceSelFpf2, 0xc, (offset + 96), 32); 369 } 370 #endif /* BCM_RAVEN_SUPPORT */ 371 372 /* FPF1 */ 373 offset += _FIELD_MEM_FIELD_LENGTH(unit, tcam_mem, F2f); 374 375 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTunnelTerminated, 376 _bcmFieldSliceSelFpf1, 0, offset, 1); 377 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyVlanTranslationHit, 378 _bcmFieldSliceSelFpf1, 0, (offset + 1), 1); 379 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyForwardingVlanValid, 380 _bcmFieldSliceSelFpf1, 0, (offset + 2), 1); 381 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIngressStpState, 382 _bcmFieldSliceSelFpf1, 0, (offset + 3), 2); 383 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2SrcHit, 384 _bcmFieldSliceSelFpf1, 0, (offset + 5), 1); 385 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2SrcStatic, 386 _bcmFieldSliceSelFpf1, 0, (offset + 6), 1); 387 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2DestHit, 388 _bcmFieldSliceSelFpf1, 0, (offset + 7), 1); 389 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3Routable, 390 _bcmFieldSliceSelFpf1, 0, (offset + 8), 1); 391 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2CacheHit, 392 _bcmFieldSliceSelFpf1, 0, (offset + 9), 1); 393 #if defined (BCM_RAVEN_SUPPORT) 394 if (SOC_IS_RAVEN(unit)) { 395 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3SrcHostHit, 396 _bcmFieldSliceSelFpf1, 0, (offset + 10), 1); 397 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3DestHostHit, 398 _bcmFieldSliceSelFpf1, 0, (offset + 11), 1); 399 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpmcStarGroupHit, 400 _bcmFieldSliceSelFpf1, 0, (offset + 12), 1); 401 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3DestRouteHit, 402 _bcmFieldSliceSelFpf1, 0, (offset + 13), 1); 403 } 404 #endif /* BCM_RAVEN_SUPPORT */ 405 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2StationMove, 406 _bcmFieldSliceSelFpf1, 0, (offset + 14), 1); 407 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDosAttack, 408 _bcmFieldSliceSelFpf1, 0, (offset + 15), 1); 409 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcClassL2, 410 _bcmFieldSliceSelFpf1, 0, (offset + 16), 5); 411 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2Format, 412 _bcmFieldSliceSelFpf1, 0, (offset + 23), 2); 413 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyVlanFormat, 414 _bcmFieldSliceSelFpf1, 0, (offset + 25), 2); 415 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyPacketRes, 416 _bcmFieldSliceSelFpf1, 0, (offset + 27), 4); 417 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDrop, 418 _bcmFieldSliceSelFpf1, 0, (offset + 31), 1); 419 420 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstPort, 421 _bcmFieldSliceSelFpf1, 1, offset, 11); 422 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDstTrunk, 423 _bcmFieldSliceSelFpf1, 1, offset, 7); 424 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcPort, 425 _bcmFieldSliceSelFpf1, 1, (offset + 11), 11); 426 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifySrcTrunk, 427 _bcmFieldSliceSelFpf1, 1, (offset + 11), 7); 428 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyMHOpcode, 429 _bcmFieldSliceSelFpf1, 1, (offset + 22), 3); 430 431 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL4DstPort, 432 _bcmFieldSliceSelFpf1, 2, offset, 16); 433 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL4SrcPort, 434 _bcmFieldSliceSelFpf1, 2, (offset + 16), 16); 435 436 #if defined(BCM_RAVEN_SUPPORT) 437 if (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 438 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyInnerVlan, 439 _bcmFieldDevSelInnerVlanOverlay, 0, 440 _bcmFieldSliceSelFpf1, 3, 441 _bcmFieldSliceSelDisable, 0, 0, 442 offset, 16, 0, 0, 0, 0, 0); 443 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanId, 444 _bcmFieldDevSelInnerVlanOverlay, 0, 445 _bcmFieldSliceSelFpf1, 3, 446 _bcmFieldSliceSelDisable, 0, 0, 447 offset, 12, 0, 0, 0, 0, 0); 448 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanCfi, 449 _bcmFieldDevSelInnerVlanOverlay, 0, 450 _bcmFieldSliceSelFpf1, 3, 451 _bcmFieldSliceSelDisable, 0, 0, 452 (offset + 12), 1, 0, 0, 0, 0, 0); 453 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanPri, 454 _bcmFieldDevSelInnerVlanOverlay, 0, 455 _bcmFieldSliceSelFpf1, 3, 456 _bcmFieldSliceSelDisable, 0, 0, 457 (offset + 13), 3, 0, 0, 0, 0, 0); 458 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyVrf, 459 _bcmFieldDevSelInnerVlanOverlay, 1, 460 _bcmFieldSliceSelFpf1, 3, 461 _bcmFieldSliceSelDisable, 0, 0, 462 offset, 6, 0, 0, 0, 0, 0); 463 } else 464 #endif /* BCM_RAVEN_SUPPORT */ 465 { 466 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerVlan, 467 _bcmFieldSliceSelFpf1, 3, offset, 16); 468 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanId, 469 _bcmFieldSliceSelFpf1, 3, offset, 12); 470 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanCfi, 471 _bcmFieldSliceSelFpf1, 3, (offset + 12), 1); 472 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanPri, 473 _bcmFieldSliceSelFpf1, 3, (offset + 13), 3); 474 } 475 476 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlan, 477 _bcmFieldSliceSelFpf1, 3, (offset + 16), 16); 478 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanId, 479 _bcmFieldSliceSelFpf1, 3, (offset + 16), 12); 480 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanCfi, 481 _bcmFieldSliceSelFpf1, 3, (offset + 28), 1); 482 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanPri, 483 _bcmFieldSliceSelFpf1, 3, (offset + 29), 3); 484 485 486 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlan, 487 _bcmFieldSliceSelFpf1, 4, offset, 16); 488 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanId, 489 _bcmFieldSliceSelFpf1, 4, offset, 12); 490 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanCfi, 491 _bcmFieldSliceSelFpf1, 4, (offset + 12), 1); 492 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanPri, 493 _bcmFieldSliceSelFpf1, 4, (offset + 13), 3); 494 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyEtherType, 495 _bcmFieldSliceSelFpf1, 4, (offset + 16), 16); 496 497 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpProtocol, 498 _bcmFieldSliceSelFpf1, 5, offset, 8); 499 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyEtherType, 500 _bcmFieldSliceSelFpf1, 5, (offset + 8), 16); 501 502 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyTunnelTerminated, 503 _bcmFieldSliceSelFpf1, 6, offset, 1); 504 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyVlanTranslationHit, 505 _bcmFieldSliceSelFpf1, 6, (offset + 1), 1); 506 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyForwardingVlanValid, 507 _bcmFieldSliceSelFpf1, 6, (offset + 2), 1); 508 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIngressStpState, 509 _bcmFieldSliceSelFpf1, 6, (offset + 3), 2); 510 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2SrcHit, 511 _bcmFieldSliceSelFpf1, 6, (offset + 5), 1); 512 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2SrcStatic, 513 _bcmFieldSliceSelFpf1, 6, (offset + 6), 1); 514 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2DestHit, 515 _bcmFieldSliceSelFpf1, 6, (offset + 7), 1); 516 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3Routable, 517 _bcmFieldSliceSelFpf1, 6, (offset + 8), 1); 518 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2CacheHit, 519 _bcmFieldSliceSelFpf1, 6, (offset + 9), 1); 520 #if defined(BCM_RAVEN_SUPPORT) 521 if (SOC_IS_RAVEN(unit)) { 522 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3SrcHostHit, 523 _bcmFieldSliceSelFpf1, 6, (offset + 10), 1); 524 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3DestHostHit, 525 _bcmFieldSliceSelFpf1, 6, (offset + 11), 1); 526 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpmcStarGroupHit, 527 _bcmFieldSliceSelFpf1, 6, (offset + 12), 1); 528 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3DestRouteHit, 529 _bcmFieldSliceSelFpf1, 6, (offset + 13), 1); 530 } 531 #endif /* BCM_RAVEN_SUPPORT */ 532 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2StationMove, 533 _bcmFieldSliceSelFpf1, 6, (offset + 14), 1); 534 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDosAttack, 535 _bcmFieldSliceSelFpf1, 6, (offset + 15), 1); 536 #if defined(BCM_RAVEN_SUPPORT) 537 if (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 538 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyInnerVlan, 539 _bcmFieldDevSelInnerVlanOverlay, 0, 540 _bcmFieldSliceSelFpf1, 6, 541 _bcmFieldSliceSelDisable, 0, 0, 542 (offset + 16), 16, 0, 0, 0, 0, 0); 543 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanId, 544 _bcmFieldDevSelInnerVlanOverlay, 0, 545 _bcmFieldSliceSelFpf1, 6, 546 _bcmFieldSliceSelDisable, 0, 0, 547 (offset + 16), 12, 0, 0, 0, 0, 0); 548 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanCfi, 549 _bcmFieldDevSelInnerVlanOverlay, 0, 550 _bcmFieldSliceSelFpf1, 6, 551 _bcmFieldSliceSelDisable, 0, 0, 552 (offset + 28), 1, 0, 0, 0, 0, 0); 553 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanPri, 554 _bcmFieldDevSelInnerVlanOverlay, 0, 555 _bcmFieldSliceSelFpf1, 6, 556 _bcmFieldSliceSelDisable, 0, 0, 557 (offset + 29), 3, 0, 0, 0, 0, 0); 558 _FP_QUAL_EXT_ADD(unit, stage_fc, bcmFieldQualifyVrf, 559 _bcmFieldDevSelInnerVlanOverlay, 1, 560 _bcmFieldSliceSelFpf1, 6, 561 _bcmFieldSliceSelDisable, 0, 0, 562 (offset + 16), 6, 0, 0, 0, 0, 0); 563 } else 564 #endif /* BCM_RAVEN_SUPPORT */ 565 { 566 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerVlan, 567 _bcmFieldSliceSelFpf1, 6, (offset + 16), 16); 568 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanId, 569 _bcmFieldSliceSelFpf1, 6, (offset + 16), 12); 570 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanCfi, 571 _bcmFieldSliceSelFpf1, 6, (offset + 28), 1); 572 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerVlanPri, 573 _bcmFieldSliceSelFpf1, 6, (offset + 29), 3); 574 } 575 576 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlan, 577 _bcmFieldSliceSelFpf1, 7, offset, 16); 578 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanId, 579 _bcmFieldSliceSelFpf1, 7, offset, 12); 580 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanCfi, 581 _bcmFieldSliceSelFpf1, 7, (offset + 12), 1); 582 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanPri, 583 _bcmFieldSliceSelFpf1, 7, (offset + 13), 3); 584 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL2Format, 585 _bcmFieldSliceSelFpf1, 7, (offset + 16), 2); 586 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyVlanFormat, 587 _bcmFieldSliceSelFpf1, 7, (offset + 18), 2); 588 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyMHOpcode, 589 _bcmFieldSliceSelFpf1, 7, (offset + 22), 3); 590 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyPacketRes, 591 _bcmFieldSliceSelFpf1, 7, (offset + 25), 4); 592 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpInfo, 593 _bcmFieldSliceSelFpf1, 7, (offset + 29), 3); 594 595 #if defined(BCM_RAVEN_SUPPORT) 596 if (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 597 598 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlan, 599 _bcmFieldSliceSelFpf1, 0xc, offset, 16); 600 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanId, 601 _bcmFieldSliceSelFpf1, 0xc, offset, 12); 602 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanCfi, 603 _bcmFieldSliceSelFpf1, 0xc, (offset + 12), 1); 604 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyOuterVlanPri, 605 _bcmFieldSliceSelFpf1, 0xc, (offset + 13), 3); 606 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyVrf, 607 _bcmFieldSliceSelFpf1, 0xc, (offset + 16), 6); 608 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3Routable, 609 _bcmFieldSliceSelFpf1, 0xc, (offset + 31), 1); 610 611 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpProtocol, 612 _bcmFieldSliceSelFpf1, 0xd, offset , 8); 613 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyVrf, 614 _bcmFieldSliceSelFpf1, 0xd, (offset + 8) , 6); 615 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL3Routable, 616 _bcmFieldSliceSelFpf1, 0xd, (offset + 23) , 1); 617 _FP_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDSCP, 618 _bcmFieldSliceSelFpf1, 0xd, (offset + 24) , 8); 619 } 620 #endif /* BCM_FIREBOLT2_SUPPORT */ 621 return (BCM_E_NONE); 622 } 623 624 /* 625 * Function: 626 * _field_rp_qualifiers_init 627 * Purpose: 628 * Initialize device qaualifiers select codes & offsets 629 * Parameters: 630 * unit - (IN) BCM device number. 631 * stage_fc - (IN) Field Processor stage control structure. 632 * 633 * Returns: 634 * BCM_E_NONE 635 * Notes: 636 */ 637 STATIC int 638 _field_rp_qualifiers_init(int unit, _field_stage_t *stage_fc) 639 { 640 int rv; /* Operation return status. */ 641 642 /* Input parameters check. */ 643 if (NULL == stage_fc) { 644 return (BCM_E_PARAM); 645 } 646 647 /* Allocated stage qualifiers configuration array. */ 648 _FP_XGS3_ALLOC(stage_fc->f_qual_arr, 649 (_bcmFieldQualifyCount * sizeof(_bcm_field_qual_info_t *)), 650 "Field qualifiers"); 651 if (NULL == stage_fc->f_qual_arr) { 652 return (BCM_E_MEMORY); 653 } 654 655 switch (stage_fc->stage_id) { 656 case _BCM_FIELD_STAGE_INGRESS: 657 rv = _field_rp_ingress_qualifiers_init(unit, stage_fc); 658 break; 659 default: 660 sal_free(stage_fc->f_qual_arr); 661 return (BCM_E_PARAM); 662 } 663 return (rv); 664 } 665 666 /* 667 * Function: 668 * _bcm_field_raptor_init 669 * Purpose: 670 * Perform initializations that are specific to Raptor. This 671 * includes initializing the FP field select bit offset tables 672 * for FPF[1-4] 673 * Parameters: 674 * unit - (IN) BCM device number 675 * fc - (IN) FP control struct 676 * Returns: 677 * BCM_E_NONE 678 * Notes: 679 */ 680 int 681 _bcm_field_raptor_init(int unit, _field_control_t *fc) 682 { 683 _field_stage_t *stage_p; /* Stages iteration pointer */ 684 685 /* Input parameters check. */ 686 if (NULL == fc) { 687 return (BCM_E_PARAM); 688 } 689 690 stage_p = fc->stages; 691 692 if (stage_p == NULL || 693 _BCM_FIELD_STAGE_INGRESS != stage_p->stage_id) { 694 return (BCM_E_PARAM); 695 } 696 697 /* Clear the hardware tables */ 698 BCM_IF_ERROR_RETURN(_field_raptor_hw_clear(unit, stage_p)); 699 700 /* Initialize Qsets, bit offsets and width tables. */ 701 BCM_IF_ERROR_RETURN(_field_rp_qualifiers_init(unit, stage_p)); 702 703 if (!SOC_WARM_BOOT(unit)) { 704 /* Set the Filter Enable flags in the port table */ 705 BCM_IF_ERROR_RETURN(_field_port_filter_enable_set(unit, fc, TRUE)); 706 707 /* Set meter refreshing enable */ 708 BCM_IF_ERROR_RETURN(_field_meter_refresh_enable_set(unit, fc, TRUE)); 709 } 710 711 /* Initialize the function pointers */ 712 _field_raptor_functions_init(&fc->functions); 713 714 return (BCM_E_NONE); 715 } 716 717 /* 718 * _field_raptor_hw_clear 719 * Purpose: 720 * Clear hardware memory. 721 * Parameters: 722 * unit - (IN) BCM device number. 723 * stage_fc - (IN) Field Processor stage control structure. 724 * 725 * Returns: 726 * BCM_E_NONE 727 * Notes: 728 */ 729 STATIC int 730 _field_raptor_hw_clear(int unit, _field_stage_t *stage_fc) 731 { 732 if (SOC_WARM_BOOT(unit)) { 733 return (BCM_E_NONE); 734 } 735 736 COMPILER_REFERENCE(stage_fc); 737 738 /* Clear udf match criteria registers. */ 739 BCM_IF_ERROR_RETURN(_bcm_field_fb_udf_ipprotocol_delete_all(unit)); 740 BCM_IF_ERROR_RETURN(_bcm_field_fb_udf_ethertype_delete_all(unit)); 741 742 SOC_IF_ERROR_RETURN 743 (soc_mem_clear((unit), FP_UDF_OFFSETm, COPYNO_ALL, TRUE)); 744 SOC_IF_ERROR_RETURN 745 (soc_mem_clear((unit), FP_PORT_FIELD_SELm, COPYNO_ALL, TRUE)); 746 SOC_IF_ERROR_RETURN 747 (soc_mem_clear((unit), FP_RANGE_CHECKm, COPYNO_ALL, TRUE)); 748 SOC_IF_ERROR_RETURN 749 (soc_mem_clear((unit), FP_TCAMm, COPYNO_ALL, TRUE)); 750 SOC_IF_ERROR_RETURN 751 (soc_mem_clear((unit), FP_POLICY_TABLEm, COPYNO_ALL, TRUE)); 752 SOC_IF_ERROR_RETURN 753 (soc_mem_clear((unit), FP_SLICE_ENTRY_PORT_SELm, COPYNO_ALL, TRUE)); 754 SOC_IF_ERROR_RETURN 755 (soc_mem_clear((unit), FP_SLICE_MAPm, COPYNO_ALL, TRUE)); 756 SOC_IF_ERROR_RETURN 757 (soc_mem_clear((unit), FP_METER_TABLEm, COPYNO_ALL, TRUE)); 758 return (soc_mem_clear((unit), FP_COUNTER_TABLEm, COPYNO_ALL, TRUE)); 759 } 760 761 #if defined(BCM_WARM_BOOT_SUPPORT) && defined(BCM_RAVEN_SUPPORT) 762 typedef enum 763 { 764 _fieldRavenSliceModeSingle = 0, 765 _fieldRavenSliceModeDouble = 1, 766 _fieldRavenSliceModeTriple = 2, 767 _fieldRavenSliceModeCount 768 } _field_raven_slice_mode_t; 769 770 typedef struct 771 { 772 int8 fpf1; 773 int8 fpf2; 774 int8 fpf3; 775 int8 fpf4; 776 int8 inner_vlan_overlay; 777 } _field_raven_sel_codes_t; 778 779 STATIC int _field_raven_group_construct(int unit, _field_control_t *fc, 780 uint32 slice_mode, _field_stage_id_t stage_id, int slice_index, 781 bcm_port_t port, _field_raven_sel_codes_t *hw_sel_codes) 782 { 783 int rv; 784 _field_stage_t *stage_fc; 785 _field_group_t *fg_p; 786 int part_index; 787 bcm_field_group_t group_id; 788 int priority = -1; 789 int group_flags = 0; 790 uint16 qualifier_id; 791 _bcm_field_qual_info_t *stage_qualifier_p; 792 int config_index; 793 _bcm_field_qual_conf_t *config_p = NULL; 794 _bcm_field_selector_t selector; 795 int qualifier_id_index; 796 _bcm_field_group_qual_t *part_qualifier_p; 797 int old_qualifier_count; 798 int new_qualifier_count; 799 uint16 *qualifier_ids_p; 800 _bcm_field_qual_offset_t *qualifier_offsets_p; 801 _bcm_field_qual_offset_t *offset_p; 802 bcm_field_qset_t qset; 803 int action_res_id = BCM_FIELD_GROUP_ACTION_RES_ID_DEFAULT; 804 bcm_pbmp_t group_pbmp; 805 int idx; 806 807 bcm_field_qset_t_init(&qset); 808 809 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, stage_id, &stage_fc)); 810 811 for (fg_p = fc->groups; fg_p != NULL; fg_p = fg_p->next) 812 { 813 if (((slice_mode == _fieldRavenSliceModeSingle) && 814 ((fg_p->flags & _FP_GROUP_SPAN_SINGLE_SLICE) == 0)) || 815 ((slice_mode == _fieldRavenSliceModeDouble) && 816 ((fg_p->flags & _FP_GROUP_SPAN_DOUBLE_SLICE) == 0)) || 817 ((slice_mode == _fieldRavenSliceModeTriple) && 818 ((fg_p->flags & _FP_GROUP_SPAN_TRIPLE_SLICE) == 0))) 819 { 820 /* This group isn't the same width as the one 821 we're reconstructing */ 822 823 continue; 824 } 825 826 /* Check for primary slice numbers - there may be groups with the same 827 QSET but residing in different slices */ 828 if (slice_index != fg_p->slices[0].slice_number) { 829 continue; 830 } 831 832 /* See if selector codes match */ 833 834 for (part_index = 0; part_index <= slice_mode; ++part_index) 835 { 836 if ((fg_p->sel_codes[part_index].fpf1 != 837 hw_sel_codes[part_index].fpf1) || 838 (fg_p->sel_codes[part_index].fpf2 != 839 hw_sel_codes[part_index].fpf2) || 840 (fg_p->sel_codes[part_index].fpf3 != 841 hw_sel_codes[part_index].fpf3) || 842 (fg_p->sel_codes[part_index].fpf4 != 843 hw_sel_codes[part_index].fpf4)) 844 { 845 /* Selectors don't match */ 846 847 break; 848 } 849 } 850 851 if (part_index <= slice_mode) 852 { 853 /* Found a mismatch */ 854 855 continue; 856 } 857 858 /* If we've gotten this far, everything matches, so add 859 the port to the group's PBMP */ 860 861 BCM_PBMP_PORT_ADD(fg_p->pbmp, port); 862 BCM_PBMP_OR(fg_p->slices[0].pbmp, fg_p->pbmp); 863 864 group_flags = 0; 865 if (fc->l2warm) 866 { 867 /* Get stored group ID and qset for level 2 */ 868 869 BCM_IF_ERROR_RETURN(_field_group_info_retrieve(unit, 870 port, _FP_DEF_INST, 871 &group_id, 872 &priority, 873 &action_res_id, 874 &group_pbmp, 875 NULL, 876 &group_flags, 877 &qset, 878 fc 879 ) 880 ); 881 882 if (group_id != -1) 883 { 884 sal_memcpy(&fg_p->qset, &qset, sizeof(bcm_field_qset_t)); 885 886 fg_p->gid = group_id; 887 fg_p->action_res_id = action_res_id; 888 889 if (group_flags & _FP_GROUP_SELECT_AUTO_EXPANSION) { 890 fg_p->flags = fg_p->flags | 891 _FP_GROUP_SELECT_AUTO_EXPANSION; 892 } 893 894 } 895 } 896 897 return BCM_E_NONE; 898 } 899 900 /* No existing groups match; create a new one */ 901 902 _FP_XGS3_ALLOC(fg_p, sizeof(_field_group_t), "field group"); 903 904 if (fg_p == NULL) 905 { 906 return BCM_E_MEMORY; 907 } 908 909 /* Initialize action res id and VMAP group to default */ 910 action_res_id = BCM_FIELD_GROUP_ACTION_RES_ID_DEFAULT; 911 for (idx = 0; idx < _FP_PAIR_MAX; idx++) { 912 fg_p->vmap_group[idx] = BCM_FIELD_GROUP_ACTION_RES_ID_DEFAULT; 913 } 914 915 916 group_flags = 0; 917 if (fc->l2warm) 918 { 919 /* Get stored group ID */ 920 921 rv = _field_group_info_retrieve(unit, 922 port, _FP_DEF_INST, 923 &group_id, 924 &priority, 925 &action_res_id, 926 &group_pbmp, 927 NULL, 928 &group_flags, 929 &qset, 930 fc 931 ); 932 933 if (group_id != -1) 934 { 935 sal_memcpy(&fg_p->qset, &qset, sizeof(bcm_field_qset_t)); 936 } else { 937 sal_free(fg_p); 938 return rv; 939 } 940 } 941 else 942 { 943 if ((rv = _bcm_field_group_id_generate(unit, &group_id)) 944 == BCM_E_NONE) { 945 unsigned vslice; 946 947 for (vslice = 0; ; ++vslice) { 948 if (vslice >= COUNTOF(stage_fc->vmap[_FP_DEF_INST][0])) { 949 rv = BCM_E_INTERNAL; 950 951 break; 952 } 953 954 if (stage_fc->vmap[_FP_DEF_INST][0][vslice].vmap_key == slice_index) { 955 priority = stage_fc->vmap[_FP_DEF_INST][0][vslice].priority; 956 957 break; 958 } 959 } 960 961 if (priority == -1) { 962 rv = BCM_E_INTERNAL; 963 } 964 } 965 } 966 967 if (BCM_FAILURE(rv)) 968 { 969 sal_free(fg_p); 970 971 return rv; 972 } 973 974 fg_p->gid = group_id; 975 fg_p->priority = priority; 976 fg_p->action_res_id = action_res_id; 977 if (group_flags & _FP_GROUP_SELECT_AUTO_EXPANSION) { 978 fg_p->flags = fg_p->flags | _FP_GROUP_SELECT_AUTO_EXPANSION; 979 } 980 fg_p->stage_id = stage_id; 981 982 BCM_PBMP_PORT_ADD(fg_p->pbmp, port); 983 984 for (part_index = 0; part_index <= slice_mode; ++part_index) 985 { 986 fg_p->sel_codes[part_index].fpf1 = hw_sel_codes[part_index].fpf1; 987 fg_p->sel_codes[part_index].fpf2 = hw_sel_codes[part_index].fpf2; 988 fg_p->sel_codes[part_index].fpf3 = hw_sel_codes[part_index].fpf3; 989 fg_p->sel_codes[part_index].fpf4 = hw_sel_codes[part_index].fpf4; 990 fg_p->sel_codes[part_index].inner_vlan_overlay = 991 hw_sel_codes[part_index].inner_vlan_overlay; 992 } 993 994 switch (slice_mode) 995 { 996 case _fieldRavenSliceModeSingle: 997 fg_p->flags |= _FP_GROUP_SPAN_SINGLE_SLICE; 998 break; 999 1000 case _fieldRavenSliceModeDouble: 1001 fg_p->flags |= _FP_GROUP_SPAN_DOUBLE_SLICE; 1002 break; 1003 1004 case _fieldRavenSliceModeTriple: 1005 fg_p->flags |= _FP_GROUP_SPAN_TRIPLE_SLICE; 1006 break; 1007 1008 } 1009 1010 /* Build qset from selectors */ 1011 1012 for (part_index = 0; part_index <= slice_mode; ++part_index) 1013 { 1014 for (qualifier_id = 0; qualifier_id < _bcmFieldQualifyCount; 1015 ++qualifier_id) 1016 { 1017 stage_qualifier_p = stage_fc->f_qual_arr[qualifier_id]; 1018 1019 if (stage_qualifier_p == NULL) 1020 { 1021 /* Qualifier does not exist in this stage */ 1022 1023 continue; 1024 } 1025 1026 if (fc->l2warm && !BCM_FIELD_QSET_TEST(fg_p->qset, qualifier_id)) { 1027 continue; /* Qualifier not present in the group */ 1028 } 1029 1030 for (config_index = 0; config_index < stage_qualifier_p->conf_sz; 1031 ++config_index) 1032 { 1033 config_p = stage_qualifier_p->conf_arr + config_index; 1034 1035 selector = config_p->selector; 1036 1037 /* Check for F1 match */ 1038 1039 if ((selector.pri_sel == _bcmFieldSliceSelFpf1) && 1040 (selector.pri_sel_val == 1041 fg_p->sel_codes[part_index].fpf1)) 1042 { 1043 break; 1044 } 1045 1046 /* Check for F2 match */ 1047 1048 if ((selector.pri_sel == _bcmFieldSliceSelFpf2) && 1049 (selector.pri_sel_val == 1050 fg_p->sel_codes[part_index].fpf2)) 1051 { 1052 break; 1053 } 1054 1055 /* Check for F3 match */ 1056 1057 if ((selector.pri_sel == _bcmFieldSliceSelFpf3) && 1058 (selector.pri_sel_val == 1059 fg_p->sel_codes[part_index].fpf3)) 1060 { 1061 break; 1062 } 1063 1064 /* Check for F4 match */ 1065 1066 if ((selector.pri_sel == _bcmFieldSliceSelFpf4) && 1067 (selector.pri_sel_val == 1068 fg_p->sel_codes[part_index].fpf4)) 1069 { 1070 break; 1071 } 1072 1073 /* Check for Disabled match */ 1074 if ((qualifier_id == bcmFieldQualifyStage) 1075 || (qualifier_id == bcmFieldQualifyIpType) 1076 || (qualifier_id == bcmFieldQualifyStageIngress) 1077 || (qualifier_id == bcmFieldQualifyIp4) 1078 || (qualifier_id == bcmFieldQualifyIp6) 1079 || (qualifier_id == bcmFieldQualifyHiGig)) { 1080 if ((selector.pri_sel == 0) && 1081 (selector.pri_sel_val == 0)) 1082 { 1083 break; 1084 } 1085 } 1086 } 1087 1088 if (config_index < stage_qualifier_p->conf_sz) 1089 { 1090 /* Found a match; add the qualifier to the qset */ 1091 1092 BCM_FIELD_QSET_ADD(fg_p->qset, qualifier_id); 1093 1094 part_qualifier_p = &(fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part_index]); 1095 1096 for (qualifier_id_index = 0; 1097 qualifier_id_index < part_qualifier_p->size; 1098 ++qualifier_id_index) 1099 { 1100 if (part_qualifier_p->qid_arr[qualifier_id_index] == 1101 qualifier_id) 1102 { 1103 /* Qualifier already in the qset */ 1104 1105 break; 1106 } 1107 } 1108 1109 if (qualifier_id_index == part_qualifier_p->size) 1110 { 1111 /* Qualifier not already in the qset; add it */ 1112 1113 old_qualifier_count = part_qualifier_p->size; 1114 new_qualifier_count = old_qualifier_count + 1; 1115 1116 qualifier_ids_p = NULL; 1117 qualifier_offsets_p = NULL; 1118 1119 _FP_XGS3_ALLOC(qualifier_ids_p, new_qualifier_count * 1120 sizeof (uint16), "Group qualifier ids"); 1121 1122 if (qualifier_ids_p == NULL) 1123 { 1124 sal_free(fg_p); 1125 return BCM_E_MEMORY; 1126 } 1127 1128 _FP_XGS3_ALLOC(qualifier_offsets_p, new_qualifier_count * 1129 sizeof (_bcm_field_qual_offset_t), 1130 "Group qual offsets"); 1131 1132 if (qualifier_offsets_p == NULL) 1133 { 1134 sal_free(fg_p); 1135 sal_free(qualifier_ids_p); 1136 1137 return BCM_E_MEMORY; 1138 } 1139 1140 if (old_qualifier_count > 0) 1141 { 1142 /* Copy existing data */ 1143 1144 sal_memcpy(qualifier_ids_p, part_qualifier_p->qid_arr, 1145 old_qualifier_count * sizeof (uint16)); 1146 1147 sal_memcpy(qualifier_offsets_p, 1148 part_qualifier_p->offset_arr, 1149 old_qualifier_count * 1150 sizeof (_bcm_field_qual_offset_t)); 1151 1152 sal_free(part_qualifier_p->qid_arr); 1153 sal_free(part_qualifier_p->offset_arr); 1154 } 1155 1156 part_qualifier_p->qid_arr = qualifier_ids_p; 1157 part_qualifier_p->offset_arr = qualifier_offsets_p; 1158 1159 part_qualifier_p->qid_arr[old_qualifier_count] = 1160 qualifier_id; 1161 1162 offset_p = part_qualifier_p->offset_arr + 1163 old_qualifier_count; 1164 1165 sal_memcpy(offset_p, &config_p->offset, 1166 sizeof(config_p->offset)); 1167 1168 part_qualifier_p->size = new_qualifier_count; 1169 1170 _field_qset_udf_bmap_reinit(unit, 1171 stage_fc, 1172 &fg_p->qset, 1173 qualifier_id 1174 ); 1175 } 1176 } 1177 } 1178 } 1179 1180 /* Associate slice with group */ 1181 1182 if (fg_p->slices == NULL) 1183 { 1184 fg_p->slices = stage_fc->slices[_FP_DEF_INST] + slice_index; 1185 } 1186 1187 BCM_PBMP_OR(fg_p->slices[0].pbmp, fg_p->pbmp); 1188 1189 /* Initialize group default ASET list. */ 1190 rv = _field_group_default_aset_set(unit, fg_p); 1191 if (BCM_FAILURE(rv)) { 1192 return (rv); 1193 } 1194 1195 if (fc->l2warm 1196 && ((fc->wb_recovered_version) >= BCM_FIELD_WB_VERSION_1_15)) { 1197 if (group_flags & _FP_GROUP_LOOKUP_ENABLED) { 1198 fg_p->flags = fg_p->flags | _FP_GROUP_LOOKUP_ENABLED; 1199 } 1200 if (group_flags & _FP_GROUP_WLAN) { 1201 fg_p->flags = fg_p->flags | _FP_GROUP_WLAN; 1202 } 1203 } else { 1204 fg_p->flags |= _FP_GROUP_LOOKUP_ENABLED; 1205 } 1206 1207 fg_p->next = fc->groups; 1208 fc->groups = fg_p; 1209 1210 return BCM_E_NONE; 1211 } 1212 1213 static int _field_raven_counter_recover(int unit, _field_entry_t *entry_p, 1214 uint32 mode, uint32 counter_index, int part_index, bcm_field_stat_t sid) 1215 { 1216 _field_control_t *fc; 1217 _field_stage_t *stage_fc; 1218 _field_group_t *fg_p; 1219 _field_slice_t *fs_p; 1220 _field_stage_id_t stage_id; 1221 uint32 submode; 1222 uint8 stat_count = 1; 1223 uint8 hw_entry_count = 1; 1224 _field_entry_stat_t *entry_stat_p; 1225 int hash_index; 1226 _field_stat_t *stat_p = NULL; 1227 int stat_id; 1228 bcm_field_stat_t stat_arr[2]; 1229 int rv; 1230 1231 fg_p = entry_p->group; 1232 fs_p = entry_p[part_index].fs; 1233 1234 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 1235 1236 stage_id = fg_p->stage_id; 1237 1238 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, stage_id, &stage_fc)); 1239 1240 submode = mode & ~BCM_FIELD_COUNTER_MODE_BYTES; 1241 1242 switch (submode) 1243 { 1244 case BCM_FIELD_COUNTER_MODE_RED: 1245 case BCM_FIELD_COUNTER_MODE_YELLOW: 1246 case BCM_FIELD_COUNTER_MODE_GREEN: 1247 case BCM_FIELD_COUNTER_MODE_YES_NO: 1248 case BCM_FIELD_COUNTER_MODE_DEFAULT: 1249 hw_entry_count = 1; 1250 break; 1251 1252 default: 1253 hw_entry_count = 2; 1254 break; 1255 } 1256 1257 entry_stat_p = &entry_p->statistic; 1258 1259 if (((hw_entry_count == 1) && (mode % 2 == 0) && 1260 (_FP_COUNTER_BMP_TEST(fs_p->counter_bmp, counter_index * 2))) || 1261 ((hw_entry_count == 1) && (mode % 2) && 1262 (_FP_COUNTER_BMP_TEST(fs_p->counter_bmp, counter_index * 2 + 1))) || 1263 ((hw_entry_count == 2) && 1264 (_FP_COUNTER_BMP_TEST(fs_p->counter_bmp, counter_index * 2)) && 1265 (_FP_COUNTER_BMP_TEST(fs_p->counter_bmp, counter_index * 2 + 1)))) 1266 { 1267 /* Counter previously recovered; increment reference count */ 1268 1269 for (hash_index = 0; hash_index < _FP_HASH_SZ(fc); ++hash_index) 1270 { 1271 stat_p = fc->stat_hash[hash_index]; 1272 1273 while (stat_p != NULL) 1274 { 1275 if ((stat_p->hw_index == counter_index) && 1276 (stat_p->pool_index == fs_p->slice_number) && 1277 (stat_p->hw_mode == mode) && 1278 (stat_p->stage_id == stage_id)) 1279 { 1280 /* Found the counter */ 1281 1282 break; 1283 } 1284 1285 stat_p = stat_p->next; 1286 } 1287 1288 if (stat_p != NULL) 1289 { 1290 /* Found the counter */ 1291 1292 break; 1293 } 1294 } 1295 1296 if (stat_p == NULL) 1297 { 1298 /* Counter's bit set in bitmap but reference not found; 1299 this shouldn't happen */ 1300 1301 return BCM_E_INTERNAL; 1302 } 1303 1304 ++stat_p->hw_ref_count; 1305 ++stat_p->sw_ref_count; 1306 } 1307 else 1308 { 1309 /* Counter not previously recovered; create new stat object */ 1310 1311 if (fc->l2warm) 1312 { 1313 stat_id = sid; 1314 } 1315 else 1316 { 1317 BCM_IF_ERROR_RETURN(_bcm_field_stat_id_alloc(unit, &stat_id)); 1318 } 1319 1320 _FP_XGS3_ALLOC(stat_p, sizeof (_field_stat_t), "Field stat object"); 1321 1322 if (stat_p == NULL) 1323 { 1324 return BCM_E_MEMORY; 1325 } 1326 1327 entry_stat_p->flags |= _FP_ENTRY_STAT_INSTALLED; 1328 1329 stat_p->sw_ref_count = 2; 1330 stat_p->hw_ref_count = 1; 1331 stat_p->pool_index = fs_p->slice_number; 1332 stat_p->hw_index = counter_index; 1333 stat_p->sid = stat_id; 1334 stat_p->stage_id = fg_p->stage_id; 1335 stat_p->gid = fg_p->gid; 1336 stat_p->hw_mode = mode; 1337 1338 if (fg_p->stage_id == _BCM_FIELD_STAGE_INGRESS) 1339 { 1340 switch (submode) 1341 { 1342 case (0x1): 1343 case (0x2): 1344 stat_arr[0] = bcmFieldStatPackets; 1345 stat_count = 1; 1346 break; 1347 case (0x9): 1348 case (0xa): 1349 stat_arr[0] = bcmFieldStatBytes; 1350 stat_count = 1; 1351 break; 1352 case (0x3): 1353 stat_arr[0] = bcmFieldStatRedPackets; 1354 stat_arr[1] = bcmFieldStatNotRedPackets; 1355 stat_count = 2; 1356 break; 1357 case (0xb): 1358 stat_arr[0] = bcmFieldStatRedBytes; 1359 stat_arr[1] = bcmFieldStatNotRedBytes; 1360 stat_count = 2; 1361 break; 1362 case (0x4): 1363 stat_arr[0] = bcmFieldStatGreenPackets; 1364 stat_arr[1] = bcmFieldStatNotGreenPackets; 1365 stat_count = 2; 1366 break; 1367 case (0xc): 1368 stat_arr[0] = bcmFieldStatGreenBytes; 1369 stat_arr[1] = bcmFieldStatNotGreenBytes; 1370 stat_count = 2; 1371 break; 1372 case (0x5): 1373 stat_arr[0] = bcmFieldStatGreenPackets; 1374 stat_arr[1] = bcmFieldStatRedPackets; 1375 stat_count = 2; 1376 break; 1377 case (0xd): 1378 stat_arr[0] = bcmFieldStatGreenBytes; 1379 stat_arr[1] = bcmFieldStatRedBytes; 1380 stat_count = 2; 1381 break; 1382 case (0x6): 1383 stat_arr[0] = bcmFieldStatGreenPackets; 1384 stat_arr[1] = bcmFieldStatYellowPackets; 1385 stat_count = 2; 1386 break; 1387 case (0xe): 1388 stat_arr[0] = bcmFieldStatGreenBytes; 1389 stat_arr[1] = bcmFieldStatYellowBytes; 1390 stat_count = 2; 1391 break; 1392 case (0x7): 1393 stat_arr[0] = bcmFieldStatRedPackets; 1394 stat_arr[1] = bcmFieldStatYellowPackets; 1395 stat_count = 2; 1396 break; 1397 case (0xf): 1398 stat_arr[0] = bcmFieldStatRedBytes; 1399 stat_arr[1] = bcmFieldStatYellowBytes; 1400 stat_count = 2; 1401 break; 1402 default: 1403 sal_free(stat_p); 1404 return BCM_E_INTERNAL; 1405 } 1406 } 1407 else if (fg_p->stage_id == _BCM_FIELD_STAGE_EGRESS) 1408 { 1409 stat_arr[0] = bcmFieldStatPackets; 1410 } 1411 1412 rv = _bcm_field_stat_array_init(unit, fc, stat_p, stat_count, stat_arr); 1413 1414 if (BCM_FAILURE(rv)) 1415 { 1416 sal_free(stat_p); 1417 1418 return rv; 1419 } 1420 1421 if (part_index > 0) 1422 { 1423 entry_p->flags |= _FP_ENTRY_STAT_IN_SECONDARY_SLICE; 1424 } 1425 1426 _FP_HASH_INSERT(fc->stat_hash, stat_p, 1427 stat_id & _FP_HASH_INDEX_MASK(fc)); 1428 1429 ++fc->stat_count; 1430 1431 if (stat_p->hw_entry_count == 1) 1432 { 1433 if (mode % 2 == 0) { 1434 _FP_COUNTER_BMP_ADD(fs_p->counter_bmp, 2 * counter_index); 1435 } else { 1436 _FP_COUNTER_BMP_ADD(fs_p->counter_bmp, 2 * counter_index + 1); 1437 } 1438 } 1439 else 1440 { 1441 _FP_COUNTER_BMP_ADD(fs_p->counter_bmp, 2 * counter_index); 1442 _FP_COUNTER_BMP_ADD(fs_p->counter_bmp, 2 * counter_index + 1); 1443 } 1444 1445 ++fg_p->group_status.counter_count; 1446 } 1447 1448 entry_stat_p->flags |= _FP_ENTRY_STAT_VALID; 1449 entry_stat_p->sid = stat_p->sid; 1450 1451 return BCM_E_NONE; 1452 } 1453 1454 #define POLICY_FIELD_GET(_field_) \ 1455 PolicyGet(unit, FP_POLICY_TABLEm, policy_entry_p, (_field_)) 1456 1457 #define SET_PARAM0 \ 1458 if (action_map_item_p->param0_field != INVALIDf) \ 1459 param0 = POLICY_FIELD_GET(action_map_item_p->param0_field) 1460 1461 #define SET_ACTION_FROM_MAP(_map_p_) \ 1462 action_map_item_p = (_map_p_) + field_value; \ 1463 action = action_map_item_p->action; \ 1464 SET_PARAM0; 1465 1466 typedef struct 1467 { 1468 bcm_field_action_t action; 1469 soc_field_t param0_field; 1470 soc_field_t param1_field; 1471 } _action_map_t; 1472 1473 /* 1474 * Function: 1475 * _field_raven_meter_index_in_use 1476 * Purpose: 1477 * Returns success if meter index/meter pair is in use. 1478 * Parameters: 1479 * unit - (IN) BCM device number. 1480 * fs - (IN) Slice where meter resides. 1481 * meter_pair_mode - (IN) Meter mode. 1482 * meter_offset - (IN) Odd/Even meter offset value. 1483 * idx - (IN) Meter pair index. 1484 * Returns: 1485 * BCM_E_XXX 1486 */ 1487 STATIC 1488 int _field_raven_meter_index_in_use(int unit, 1489 _field_slice_t *fs, 1490 uint32 meter_pair_mode, 1491 uint32 meter_offset, 1492 int idx) 1493 { 1494 /* Input parameter check. */ 1495 if (NULL == fs) { 1496 return (BCM_E_INTERNAL); 1497 } 1498 1499 /* Meters are per-slice resource. */ 1500 if (meter_pair_mode == BCM_FIELD_METER_MODE_FLOW 1501 && _FP_METER_BMP_TEST(fs->meter_bmp, ((idx * 2) + meter_offset))) { 1502 /* Flow mode meter index in use. */ 1503 return (BCM_E_NONE); 1504 } else if (_FP_METER_BMP_TEST(fs->meter_bmp, (idx * 2)) 1505 && _FP_METER_BMP_TEST(fs->meter_bmp, ((idx * 2) + 1))) { 1506 /* Non-Flow mode meter pair index in use. */ 1507 return (BCM_E_NONE); 1508 } 1509 return (BCM_E_NOT_FOUND); 1510 } 1511 1512 int _field_raven_meter_recover(int unit, _field_entry_t *entry_p, 1513 fp_policy_table_entry_t *policy_entry_p, int part_index, 1514 bcm_policer_t pid) 1515 { 1516 uint8 mode; 1517 uint8 meter_index; 1518 int rv; 1519 _field_group_t *fg_p; 1520 _field_slice_t *fs_p; 1521 _field_control_t *fc; 1522 _field_stage_t *stage_fc; 1523 _field_stage_id_t stage_id; 1524 int hash_index; 1525 _field_policer_t *policer_p = NULL; 1526 bcm_policer_config_t *policer_config_p; 1527 int meter_offset = 0; 1528 int meter_table_index; 1529 uint32 ent[SOC_MAX_MEM_FIELD_WORDS]; 1530 uint32 refresh_count; 1531 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1532 uint32 bucket_size; 1533 #endif 1534 int policer_id; 1535 _field_entry_policer_t *entry_policer_p; 1536 uint32 bucket_count; 1537 1538 meter_index = POLICY_FIELD_GET(METER_INDEX_EVENf); 1539 mode = POLICY_FIELD_GET(METER_PAIR_MODEf); 1540 1541 if ((mode == 0) && (meter_index == 0)) 1542 { 1543 return BCM_E_NONE; 1544 } 1545 1546 fg_p = entry_p->group; 1547 fs_p = entry_p[part_index].fs; 1548 stage_id = fg_p->stage_id; 1549 1550 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 1551 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, stage_id, &stage_fc)); 1552 1553 if (BCM_FIELD_METER_MODE_FLOW == mode) { 1554 if (POLICY_FIELD_GET(METER_UPDATE_EVENf) 1555 && POLICY_FIELD_GET(METER_TEST_EVENf)) { 1556 meter_offset = 0; 1557 } else if (POLICY_FIELD_GET(METER_UPDATE_ODDf) 1558 && POLICY_FIELD_GET(METER_TEST_ODDf)) { 1559 meter_offset = 1; 1560 } else { 1561 return (BCM_E_INTERNAL); 1562 } 1563 } 1564 1565 if (BCM_SUCCESS(_field_raven_meter_index_in_use(unit, fs_p, 1566 mode, meter_offset, meter_index))) 1567 { 1568 /* Policer previously found; increment reference count */ 1569 1570 for (hash_index = 0; hash_index < _FP_HASH_SZ(fc); ++hash_index) 1571 { 1572 policer_p = fc->policer_hash[hash_index]; 1573 1574 while (policer_p != NULL) 1575 { 1576 if ((policer_p->hw_index == meter_index) && 1577 (policer_p->pool_index = fs_p->slice_number) && 1578 (policer_p->stage_id == stage_id)) 1579 { 1580 /* Found it */ 1581 1582 break; 1583 } 1584 } 1585 1586 if (policer_p != NULL) 1587 { 1588 /* Found it */ 1589 1590 break; 1591 } 1592 } 1593 1594 if (policer_p == NULL) 1595 { 1596 /* Bit set in bitmap but reference not found; This should 1597 never happen */ 1598 1599 return BCM_E_INTERNAL; 1600 } 1601 1602 ++policer_p->hw_ref_count; 1603 ++policer_p->sw_ref_count; 1604 } 1605 else 1606 { 1607 /* Policer not previously recovered; create new object */ 1608 1609 if (fc->l2warm) 1610 { 1611 policer_id = pid; 1612 } 1613 else 1614 { 1615 BCM_IF_ERROR_RETURN(_field_policer_id_alloc(unit, &policer_id)); 1616 } 1617 1618 LOG_DEBUG(BSL_LS_BCM_FP, 1619 (BSL_META_U(unit, 1620 "Creating policer id %d.\n"), 1621 policer_id)); 1622 1623 _FP_XGS3_ALLOC(policer_p, sizeof (_field_policer_t), 1624 "Field policer object"); 1625 1626 if (policer_p == NULL) 1627 { 1628 return BCM_E_MEMORY; 1629 } 1630 1631 policer_p->sw_ref_count = 2; 1632 policer_p->hw_ref_count = 1; 1633 policer_p->pool_index = fs_p->slice_number; 1634 policer_p->hw_index = meter_index; 1635 policer_p->pid = policer_id; 1636 1637 policer_config_p = &policer_p->cfg; 1638 1639 switch (mode) { 1640 case BCM_FIELD_METER_MODE_DEFAULT: 1641 policer_config_p->mode = bcmPolicerModeGreen; 1642 break; 1643 case BCM_FIELD_METER_MODE_FLOW: 1644 policer_config_p->mode = bcmPolicerModeCommitted; 1645 if (meter_offset) { 1646 /* Flow mode using committed hardware meter. */ 1647 _FP_POLICER_EXCESS_HW_METER_CLEAR(policer_p); 1648 } else { 1649 /* Flow mode using excess hardware meter. */ 1650 _FP_POLICER_EXCESS_HW_METER_SET(policer_p); 1651 } 1652 meter_table_index = 1653 stage_fc->slices[_FP_DEF_INST][policer_p->pool_index] 1654 .start_tcam_idx + 2 * policer_p->hw_index + meter_offset; 1655 rv = soc_mem_read(unit, FP_METER_TABLEm, MEM_BLOCK_ANY, 1656 meter_table_index, ent); 1657 1658 if (BCM_FAILURE(rv)) { 1659 sal_free(policer_p); 1660 return rv; 1661 } 1662 1663 refresh_count = soc_mem_field32_get(unit, FP_METER_TABLEm, 1664 ent, REFRESHCOUNTf); 1665 bucket_count = soc_mem_field32_get(unit, FP_METER_TABLEm, 1666 ent, BUCKETCOUNTf); 1667 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1668 bucket_size = soc_mem_field32_get(unit, FP_METER_TABLEm, 1669 ent, BUCKETSIZEf); 1670 #endif 1671 policer_config_p->ckbits_sec = refresh_count 1672 * _FP_POLICER_REFRESH_RATE; 1673 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1674 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_SC_CQ(unit)) { 1675 policer_config_p->ckbits_burst 1676 = _bcm_fb2_bucket_encoding_to_kbits(bucket_size, TRUE); 1677 } else 1678 #endif 1679 { 1680 policer_config_p->ckbits_burst = bucket_count / 2 / 1024; 1681 /* Refer to _field_fb_bucket_calc */ 1682 } 1683 1684 break; 1685 1686 case BCM_FIELD_METER_MODE_trTCM_COLOR_BLIND: 1687 policer_config_p->flags |= BCM_POLICER_COLOR_BLIND; 1688 /* Fall through */ 1689 case BCM_FIELD_METER_MODE_trTCM_COLOR_AWARE: 1690 policer_config_p->mode = bcmPolicerModeTrTcm; 1691 /* Get the peak attributes */ 1692 meter_table_index = 1693 stage_fc->slices[_FP_DEF_INST][policer_p->pool_index] 1694 .start_tcam_idx + (2 * policer_p->hw_index); 1695 rv = soc_mem_read(unit, FP_METER_TABLEm, MEM_BLOCK_ANY, 1696 meter_table_index, ent); 1697 if (BCM_FAILURE(rv)) { 1698 sal_free(policer_p); 1699 return rv; 1700 } 1701 refresh_count = soc_mem_field32_get(unit, FP_METER_TABLEm, ent, 1702 REFRESHCOUNTf); 1703 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1704 bucket_size = soc_mem_field32_get(unit, FP_METER_TABLEm, ent, 1705 BUCKETSIZEf); 1706 #endif 1707 bucket_count = soc_mem_field32_get(unit, FP_METER_TABLEm, 1708 ent, BUCKETCOUNTf); 1709 policer_config_p->pkbits_sec 1710 = refresh_count * _FP_POLICER_REFRESH_RATE; 1711 1712 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1713 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_SC_CQ(unit)) { 1714 policer_config_p->pkbits_burst 1715 = _bcm_fb2_bucket_encoding_to_kbits(bucket_size, TRUE); 1716 } else 1717 #endif 1718 { 1719 policer_config_p->pkbits_burst = bucket_count / 2 / 1024; 1720 /* Refer to _field_fb_bucket_calc */ 1721 } 1722 1723 /* Get the committed attributes */ 1724 meter_table_index = 1725 stage_fc->slices[_FP_DEF_INST][policer_p->pool_index] 1726 .start_tcam_idx + (2 * policer_p->hw_index) + 1; 1727 rv = soc_mem_read(unit, FP_METER_TABLEm, MEM_BLOCK_ANY, 1728 meter_table_index, ent); 1729 if (BCM_FAILURE(rv)) { 1730 sal_free(policer_p); 1731 return rv; 1732 } 1733 1734 refresh_count = soc_mem_field32_get(unit, FP_METER_TABLEm, ent, 1735 REFRESHCOUNTf); 1736 bucket_count = soc_mem_field32_get(unit, FP_METER_TABLEm, 1737 ent, BUCKETCOUNTf); 1738 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1739 bucket_size = soc_mem_field32_get(unit, FP_METER_TABLEm, ent, 1740 BUCKETSIZEf); 1741 #endif 1742 policer_config_p->ckbits_sec = refresh_count * _FP_POLICER_REFRESH_RATE; 1743 1744 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1745 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_SC_CQ(unit)) { 1746 policer_config_p->ckbits_burst 1747 = _bcm_fb2_bucket_encoding_to_kbits(bucket_size, TRUE); 1748 } else 1749 #endif 1750 { 1751 policer_config_p->ckbits_burst = bucket_count / 2 / 1024; 1752 /* Refer to _field_fb_bucket_calc */ 1753 } 1754 break; 1755 case 4: 1756 if (stage_id == _BCM_FIELD_STAGE_EGRESS) { 1757 policer_config_p->mode = bcmPolicerModePassThrough; 1758 } 1759 break; 1760 case 5: 1761 break; 1762 case BCM_FIELD_METER_MODE_srTCM_COLOR_BLIND: 1763 policer_config_p->flags |= BCM_POLICER_COLOR_BLIND; 1764 /* Fall through */ 1765 case BCM_FIELD_METER_MODE_srTCM_COLOR_AWARE: 1766 policer_config_p->mode = bcmPolicerModeSrTcm; 1767 /* Get the peak attributes */ 1768 meter_table_index = 1769 stage_fc->slices[_FP_DEF_INST][policer_p->pool_index] 1770 .start_tcam_idx + (2 * policer_p->hw_index); 1771 rv = soc_mem_read(unit, FP_METER_TABLEm, MEM_BLOCK_ANY, 1772 meter_table_index, ent); 1773 if (BCM_FAILURE(rv)) { 1774 sal_free(policer_p); 1775 return rv; 1776 } 1777 refresh_count = soc_mem_field32_get(unit, FP_METER_TABLEm, ent, 1778 REFRESHCOUNTf); 1779 bucket_count = soc_mem_field32_get(unit, FP_METER_TABLEm, 1780 ent, BUCKETCOUNTf); 1781 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1782 bucket_size = soc_mem_field32_get(unit, FP_METER_TABLEm, ent, 1783 BUCKETSIZEf); 1784 #endif 1785 policer_config_p->pkbits_sec 1786 = refresh_count * _FP_POLICER_REFRESH_RATE; 1787 1788 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1789 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_SC_CQ(unit)) { 1790 policer_config_p->pkbits_burst 1791 = _bcm_fb2_bucket_encoding_to_kbits(bucket_size, TRUE); 1792 } else 1793 #endif 1794 { 1795 policer_config_p->pkbits_burst = bucket_count / 2 / 1024; 1796 /* Refer to _field_fb_bucket_calc */ 1797 } 1798 1799 /* Get the committed attributes */ 1800 meter_table_index = 1801 stage_fc->slices[_FP_DEF_INST][policer_p->pool_index] 1802 .start_tcam_idx + (2 * policer_p->hw_index) + 1; 1803 rv = soc_mem_read(unit, FP_METER_TABLEm, MEM_BLOCK_ANY, 1804 meter_table_index, ent); 1805 if (BCM_FAILURE(rv)) { 1806 sal_free(policer_p); 1807 return rv; 1808 } 1809 1810 refresh_count = soc_mem_field32_get(unit, FP_METER_TABLEm, ent, 1811 REFRESHCOUNTf); 1812 bucket_count = soc_mem_field32_get(unit, FP_METER_TABLEm, 1813 ent, BUCKETCOUNTf); 1814 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1815 bucket_size = soc_mem_field32_get(unit, FP_METER_TABLEm, ent, 1816 BUCKETSIZEf); 1817 #endif 1818 policer_config_p->ckbits_sec 1819 = refresh_count * _FP_POLICER_REFRESH_RATE; 1820 1821 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 1822 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_SC_CQ(unit)) { 1823 policer_config_p->ckbits_burst 1824 = _bcm_fb2_bucket_encoding_to_kbits(bucket_size, TRUE); 1825 } else 1826 #endif 1827 { 1828 policer_config_p->ckbits_burst = bucket_count / 2 / 1024; 1829 /* Refer to _field_fb_bucket_calc */ 1830 } 1831 break; 1832 default: 1833 break; 1834 } 1835 1836 if (part_index > 0) 1837 { 1838 entry_p->flags |= _FP_ENTRY_POLICER_IN_SECONDARY_SLICE; 1839 } 1840 1841 _FP_HASH_INSERT(fc->policer_hash, policer_p, 1842 (policer_id & _FP_HASH_INDEX_MASK(fc))); 1843 ++fc->policer_count; 1844 1845 /* Mark as used in the slice */ 1846 if (!_FP_POLICER_IS_FLOW_MODE(policer_p)) { 1847 _FP_METER_BMP_ADD(fs_p->meter_bmp, (meter_index * 2)); 1848 _FP_METER_BMP_ADD(fs_p->meter_bmp, ((meter_index * 2) + 1)); 1849 } else { 1850 _FP_METER_BMP_ADD(fs_p->meter_bmp, ((meter_index * 2) + meter_offset)); 1851 } 1852 ++fg_p->group_status.meter_count; 1853 } 1854 1855 /* Associate policer with entry */ 1856 entry_policer_p = entry_p->policer; 1857 entry_policer_p->flags |= _FP_POLICER_VALID; 1858 entry_policer_p->flags |= _FP_POLICER_INSTALLED; 1859 entry_policer_p->pid = policer_p->pid; 1860 1861 return BCM_E_NONE; 1862 } 1863 1864 int _field_raven_actions_recover(int unit, 1865 fp_policy_table_entry_t *policy_entry_p, _field_entry_t *entry_p, 1866 int part_index, _field_entry_wb_info_t *f_ent_wb_info) 1867 { 1868 _action_map_t green_action_map[2][16] = 1869 { 1870 { 1871 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1872 {bcmFieldActionCosQNew, NEWPRIf, INVALIDf}, 1873 {bcmFieldActionCosQCpuNew, NEWPRIf, INVALIDf}, 1874 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1875 {bcmFieldActionPrioPktAndIntCopy, INVALIDf, INVALIDf}, 1876 {bcmFieldActionPrioPktAndIntNew, NEWPRIf, INVALIDf}, 1877 {bcmFieldActionPrioPktAndIntTos, INVALIDf, INVALIDf}, 1878 {bcmFieldActionPrioPktAndIntCancel, INVALIDf, INVALIDf}, 1879 {bcmFieldActionPrioPktCopy, INVALIDf, INVALIDf}, 1880 {bcmFieldActionPrioPktNew, NEWPRIf, INVALIDf}, 1881 {bcmFieldActionPrioPktTos, INVALIDf, INVALIDf}, 1882 {bcmFieldActionPrioPktCancel, INVALIDf, INVALIDf}, 1883 {bcmFieldActionPrioIntCopy, INVALIDf, INVALIDf}, 1884 {bcmFieldActionPrioIntNew, NEWPRIf, INVALIDf}, 1885 {bcmFieldActionPrioIntTos, INVALIDf, INVALIDf}, 1886 {bcmFieldActionPrioIntCancel, INVALIDf, INVALIDf} 1887 }, 1888 { 1889 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1890 {bcmFieldActionGpCosQNew, NEWPRIf, INVALIDf}, 1891 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1892 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1893 {bcmFieldActionGpPrioPktAndIntCopy, INVALIDf, INVALIDf}, 1894 {bcmFieldActionGpPrioPktAndIntNew, NEWPRIf, INVALIDf}, 1895 {bcmFieldActionGpPrioPktAndIntTos, INVALIDf, INVALIDf}, 1896 {bcmFieldActionGpPrioPktAndIntCancel, INVALIDf, INVALIDf}, 1897 {bcmFieldActionGpPrioPktCopy, INVALIDf, INVALIDf}, 1898 {bcmFieldActionGpPrioPktNew, NEWPRIf, INVALIDf}, 1899 {bcmFieldActionGpPrioPktTos, INVALIDf, INVALIDf}, 1900 {bcmFieldActionGpPrioPktCancel, INVALIDf, INVALIDf}, 1901 {bcmFieldActionGpPrioIntCopy, INVALIDf, INVALIDf}, 1902 {bcmFieldActionGpPrioIntNew, NEWPRIf, INVALIDf}, 1903 {bcmFieldActionGpPrioIntTos, INVALIDf, INVALIDf}, 1904 {bcmFieldActionGpPrioIntCancel, INVALIDf, INVALIDf} 1905 } 1906 }; 1907 1908 _action_map_t yellow_action_map[16] = 1909 { 1910 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1911 {bcmFieldActionYpCosQNew, NEWPRIf, INVALIDf}, 1912 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1913 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1914 {bcmFieldActionYpPrioPktAndIntCopy, INVALIDf, INVALIDf}, 1915 {bcmFieldActionYpPrioPktAndIntNew, NEWPRIf, INVALIDf}, 1916 {bcmFieldActionYpPrioPktAndIntTos, INVALIDf, INVALIDf}, 1917 {bcmFieldActionYpPrioPktAndIntCancel, INVALIDf, INVALIDf}, 1918 {bcmFieldActionYpPrioPktCopy, INVALIDf, INVALIDf}, 1919 {bcmFieldActionYpPrioPktNew, NEWPRIf, INVALIDf}, 1920 {bcmFieldActionYpPrioPktTos, INVALIDf, INVALIDf}, 1921 {bcmFieldActionYpPrioPktCancel, INVALIDf, INVALIDf}, 1922 {bcmFieldActionYpPrioIntCopy, INVALIDf, INVALIDf}, 1923 {bcmFieldActionYpPrioIntNew, NEWPRIf, INVALIDf}, 1924 {bcmFieldActionYpPrioIntTos, INVALIDf, INVALIDf}, 1925 {bcmFieldActionYpPrioIntCancel, INVALIDf, INVALIDf} 1926 }; 1927 1928 _action_map_t red_action_map[16] = 1929 { 1930 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1931 {bcmFieldActionRpCosQNew, NEWPRIf, INVALIDf}, 1932 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1933 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1934 {bcmFieldActionRpPrioPktAndIntCopy, INVALIDf, INVALIDf}, 1935 {bcmFieldActionRpPrioPktAndIntNew, NEWPRIf, INVALIDf}, 1936 {bcmFieldActionRpPrioPktAndIntTos, INVALIDf, INVALIDf}, 1937 {bcmFieldActionRpPrioPktAndIntCancel, INVALIDf, INVALIDf}, 1938 {bcmFieldActionRpPrioPktCopy, INVALIDf, INVALIDf}, 1939 {bcmFieldActionRpPrioPktNew, NEWPRIf, INVALIDf}, 1940 {bcmFieldActionRpPrioPktTos, INVALIDf, INVALIDf}, 1941 {bcmFieldActionRpPrioPktCancel, INVALIDf, INVALIDf}, 1942 {bcmFieldActionRpPrioIntCopy, INVALIDf, INVALIDf}, 1943 {bcmFieldActionRpPrioIntNew, NEWPRIf, INVALIDf}, 1944 {bcmFieldActionRpPrioIntTos, INVALIDf, INVALIDf}, 1945 {bcmFieldActionRpPrioIntCancel, INVALIDf, INVALIDf} 1946 }; 1947 1948 _action_map_t change_dscp_tos_action_map[8] = 1949 { 1950 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1951 {bcmFieldActionTosNew, NEWDSCP_TOSf, INVALIDf}, 1952 {bcmFieldActionTosCopy, INVALIDf, INVALIDf}, 1953 {bcmFieldActionDscpNew, NEWDSCP_TOSf, INVALIDf}, 1954 {bcmFieldActionDscpCancel, INVALIDf, INVALIDf}, 1955 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1956 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1957 {bcmFieldActionCount, INVALIDf, INVALIDf} 1958 }; 1959 1960 _action_map_t copy_to_cpu_action_map[4] = 1961 { 1962 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1963 {bcmFieldActionCopyToCpu, INVALIDf, MATCHED_RULEf}, 1964 {bcmFieldActionCopyToCpuCancel, INVALIDf, INVALIDf}, 1965 {bcmFieldActionSwitchToCpuCancel, INVALIDf, INVALIDf} 1966 }; 1967 1968 _action_map_t gp_copy_to_cpu_action_map[4] = 1969 { 1970 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1971 {bcmFieldActionGpCopyToCpu, INVALIDf, MATCHED_RULEf}, 1972 {bcmFieldActionGpCopyToCpuCancel, INVALIDf, INVALIDf}, 1973 {bcmFieldActionCount, INVALIDf, INVALIDf} 1974 }; 1975 1976 _action_map_t yp_copy_to_cpu_action_map[4] = 1977 { 1978 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1979 {bcmFieldActionYpCopyToCpu, INVALIDf, MATCHED_RULEf}, 1980 {bcmFieldActionYpCopyToCpuCancel, INVALIDf, INVALIDf}, 1981 {bcmFieldActionCount, INVALIDf, INVALIDf} 1982 }; 1983 1984 _action_map_t rp_copy_to_cpu_action_map[4] = 1985 { 1986 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1987 {bcmFieldActionRpCopyToCpu, INVALIDf, MATCHED_RULEf}, 1988 {bcmFieldActionRpCopyToCpuCancel, INVALIDf, INVALIDf}, 1989 {bcmFieldActionCount, INVALIDf, INVALIDf} 1990 }; 1991 1992 _action_map_t packet_redirection_action_map[8] = 1993 { 1994 {bcmFieldActionCount, INVALIDf, INVALIDf}, 1995 {bcmFieldActionCount, INVALIDf, INVALIDf}, /* Handled in code */ 1996 {bcmFieldActionRedirectCancel, INVALIDf, INVALIDf}, 1997 {bcmFieldActionRedirectPbmp, REDIRECTIONf, INVALIDf}, 1998 {bcmFieldActionEgressMask, REDIRECTIONf, INVALIDf}, 1999 {bcmFieldActionCount, INVALIDf, INVALIDf}, 2000 {bcmFieldActionCount, INVALIDf, INVALIDf}, 2001 {bcmFieldActionCount, INVALIDf, INVALIDf} 2002 }; 2003 2004 _action_map_t drop_action_map[4] = 2005 { 2006 {bcmFieldActionCount, INVALIDf, INVALIDf}, 2007 {bcmFieldActionDrop, INVALIDf, INVALIDf}, 2008 {bcmFieldActionDropCancel, INVALIDf, INVALIDf}, 2009 {bcmFieldActionCount, INVALIDf, INVALIDf} 2010 }; 2011 2012 _action_map_t yp_drop_action_map[4] = 2013 { 2014 {bcmFieldActionCount, INVALIDf, INVALIDf}, 2015 {bcmFieldActionYpDrop, INVALIDf, INVALIDf}, 2016 {bcmFieldActionYpDropCancel, INVALIDf, INVALIDf}, 2017 {bcmFieldActionCount, INVALIDf, INVALIDf} 2018 }; 2019 2020 _action_map_t rp_drop_action_map[4] = 2021 { 2022 {bcmFieldActionCount, INVALIDf, INVALIDf}, 2023 {bcmFieldActionRpDrop, INVALIDf, INVALIDf}, 2024 {bcmFieldActionRpDropCancel, INVALIDf, INVALIDf}, 2025 {bcmFieldActionCount, INVALIDf, INVALIDf} 2026 }; 2027 2028 _action_map_t l3sw_change_macda_or_vlan_action_map[8] = 2029 { 2030 {bcmFieldActionCount, INVALIDf, INVALIDf}, 2031 {bcmFieldActionL3ChangeVlan, INVALIDf, INVALIDf}, 2032 {bcmFieldActionL3ChangeVlanCancel, INVALIDf, INVALIDf}, 2033 {bcmFieldActionAddClassTag, CLASSIFICATION_TAGf, INVALIDf}, 2034 {bcmFieldActionL3ChangeMacDa, INVALIDf, INVALIDf}, 2035 {bcmFieldActionL3ChangeMacDaCancel, INVALIDf, INVALIDf}, 2036 {bcmFieldActionL3Switch, INVALIDf, INVALIDf}, 2037 {bcmFieldActionL3SwitchCancel, INVALIDf, INVALIDf} 2038 }; 2039 2040 int field_index; 2041 bcm_field_action_t action; 2042 uint32 param0; 2043 uint32 param1; 2044 soc_field_t field; 2045 uint32 field_value; 2046 uint32 priority_mode; 2047 uint32 mtp_index; 2048 im_mtp_index_entry_t im_mtp_index_entry; 2049 em_mtp_index_entry_t em_mtp_index_entry; 2050 _field_action_t *fa_p; 2051 int ecmp_count; 2052 int nh_ecmp; 2053 _action_map_t *action_map_item_p; 2054 uint32 redirection_value; 2055 2056 if (f_ent_wb_info == NULL) { 2057 return BCM_E_INTERNAL; 2058 } 2059 2060 for (field_index = 0; 2061 field_index < SOC_MEM_INFO(unit, FP_POLICY_TABLEm).nFields; 2062 ++field_index) 2063 { 2064 action = bcmFieldActionCount; 2065 param0 = 0; 2066 param1 = 0; 2067 fa_p = NULL; 2068 2069 field = 2070 SOC_MEM_INFO(unit, FP_POLICY_TABLEm).fields[field_index].field; 2071 2072 field_value = POLICY_FIELD_GET(field); 2073 2074 if (field_value != 0) 2075 { 2076 switch (field) 2077 { 2078 case CHANGE_PRIORITYf: 2079 priority_mode = POLICY_FIELD_GET(PRI_MODEf); 2080 2081 SET_ACTION_FROM_MAP(green_action_map[priority_mode]); 2082 2083 break; 2084 2085 case YP_CHANGE_PRIORITYf: 2086 SET_ACTION_FROM_MAP(yellow_action_map); 2087 break; 2088 2089 case RP_CHANGE_PRIORITYf: 2090 SET_ACTION_FROM_MAP(red_action_map); 2091 break; 2092 2093 case ECN_CNGf: 2094 action = bcmFieldActionEcnNew; 2095 2096 break; 2097 2098 case DROP_PRECEDENCEf: 2099 action = bcmFieldActionDropPrecedence; 2100 param0 = field_value; 2101 2102 break; 2103 2104 case YP_DROP_PRECEDENCEf: 2105 /* Only set this action if all three aren't the same */ 2106 2107 if (field_value != POLICY_FIELD_GET(DROP_PRECEDENCEf) || 2108 field_value != POLICY_FIELD_GET(RP_DROP_PRECEDENCEf)) 2109 { 2110 action = bcmFieldActionYpDropPrecedence; 2111 param0 = field_value; 2112 } 2113 2114 break; 2115 2116 case RP_DROP_PRECEDENCEf: 2117 /* Only set this action if all three aren't the same */ 2118 2119 if (field_value != POLICY_FIELD_GET(DROP_PRECEDENCEf) || 2120 field_value != POLICY_FIELD_GET(YP_DROP_PRECEDENCEf)) 2121 { 2122 action = bcmFieldActionRpDropPrecedence; 2123 param0 = field_value; 2124 } 2125 2126 break; 2127 2128 case CHANGE_DSCP_TOSf: 2129 SET_ACTION_FROM_MAP(change_dscp_tos_action_map); 2130 break; 2131 2132 case YP_CHANGE_DSCPf: 2133 action = bcmFieldActionYpDscpNew; 2134 param0 = POLICY_FIELD_GET(YP_DSCPf); 2135 break; 2136 2137 case RP_CHANGE_DSCPf: 2138 action = bcmFieldActionRpDscpNew; 2139 param0 = POLICY_FIELD_GET(RP_DSCPf); 2140 break; 2141 2142 case COPY_TO_CPUf: 2143 if (field_value == 1 && POLICY_FIELD_GET(COPY_TO_CPUf) == 1 && 2144 POLICY_FIELD_GET(YP_COPY_TO_CPUf) != 1 && 2145 POLICY_FIELD_GET(RP_COPY_TO_CPUf) != 1) { 2146 /* Part of bcmFieldActionGpCopyToCpu */ 2147 SET_ACTION_FROM_MAP(gp_copy_to_cpu_action_map); 2148 } else if (field_value == 2 && POLICY_FIELD_GET(COPY_TO_CPUf) 2149 == 2 && POLICY_FIELD_GET(YP_COPY_TO_CPUf) != 2 2150 && POLICY_FIELD_GET(RP_COPY_TO_CPUf) != 2) { 2151 /* Part of bcmFieldActionGpCopyToCpuCancel */ 2152 SET_ACTION_FROM_MAP(gp_copy_to_cpu_action_map); 2153 break; 2154 } else { 2155 SET_ACTION_FROM_MAP(copy_to_cpu_action_map); 2156 } 2157 param1 = POLICY_FIELD_GET(MATCHED_RULEf); 2158 if (param1 != 0) 2159 { 2160 param0 = 1; 2161 } 2162 2163 break; 2164 2165 case YP_COPY_TO_CPUf: 2166 if (field_value == 1 && POLICY_FIELD_GET(COPY_TO_CPUf) == 1) 2167 { 2168 /* Part of bcmFieldActionCopyToCpu */ 2169 2170 break; 2171 } 2172 2173 if (field_value == 2 && POLICY_FIELD_GET(COPY_TO_CPUf) == 2 && 2174 POLICY_FIELD_GET(RP_COPY_TO_CPUf) == 2) 2175 { 2176 /* Part of bcmFieldActionCopyToCpuCancel */ 2177 2178 break; 2179 } 2180 2181 if (field_value == 3 && POLICY_FIELD_GET(COPY_TO_CPUf) == 3 && 2182 POLICY_FIELD_GET(RP_COPY_TO_CPUf) == 3) 2183 { 2184 /* Part of bcmFieldActionSwitchToCpuCancel */ 2185 2186 break; 2187 } 2188 2189 SET_ACTION_FROM_MAP(yp_copy_to_cpu_action_map); 2190 param1 = POLICY_FIELD_GET(MATCHED_RULEf); 2191 if (param1 != 0) 2192 { 2193 param0 = 1; 2194 } 2195 break; 2196 2197 case RP_COPY_TO_CPUf: 2198 if (field_value == 1 && POLICY_FIELD_GET(COPY_TO_CPUf) == 1) 2199 { 2200 /* Part of bcmFieldActionCopyToCpu */ 2201 2202 break; 2203 } 2204 2205 if (field_value == 2 && POLICY_FIELD_GET(COPY_TO_CPUf) == 2 && 2206 POLICY_FIELD_GET(YP_COPY_TO_CPUf) == 2) 2207 { 2208 /* Part of bcmFieldActionCopyToCpuCancel */ 2209 2210 break; 2211 } 2212 2213 if (field_value == 3 && POLICY_FIELD_GET(COPY_TO_CPUf) == 3 && 2214 POLICY_FIELD_GET(YP_COPY_TO_CPUf) == 3) 2215 { 2216 /* Part of bcmFieldActionSwitchToCpuCancel */ 2217 2218 break; 2219 } 2220 2221 SET_ACTION_FROM_MAP(rp_copy_to_cpu_action_map); 2222 param1 = POLICY_FIELD_GET(MATCHED_RULEf); 2223 if (param1 != 0) 2224 { 2225 param0 = 1; 2226 } 2227 break; 2228 2229 case PACKET_REDIRECTIONf: 2230 if (field_value == 1) 2231 { 2232 redirection_value = POLICY_FIELD_GET(REDIRECTIONf); 2233 2234 if ((redirection_value & 0x40) != 0) 2235 { 2236 /* Trunk bit is set */ 2237 2238 action = bcmFieldActionRedirectTrunk; 2239 param0 = redirection_value & 0x3F; 2240 } 2241 else 2242 { 2243 /* Mod+port */ 2244 2245 action = bcmFieldActionRedirect; 2246 param0 = (redirection_value >> 7) & 0x0F; 2247 param1 = redirection_value & 0x7F; 2248 } 2249 } 2250 else 2251 { 2252 SET_ACTION_FROM_MAP(packet_redirection_action_map); 2253 } 2254 2255 break; 2256 2257 case DROPf: 2258 SET_ACTION_FROM_MAP(drop_action_map); 2259 break; 2260 2261 case YP_DROPf: 2262 /* Only set this action if not all three are the same */ 2263 2264 if (field_value != POLICY_FIELD_GET(DROPf) || 2265 field_value != POLICY_FIELD_GET(RP_DROPf)) 2266 { 2267 SET_ACTION_FROM_MAP(yp_drop_action_map); 2268 } 2269 2270 break; 2271 2272 case RP_DROPf: 2273 /* Only set this action if not all three are the same */ 2274 2275 if (field_value != POLICY_FIELD_GET(DROPf) || 2276 field_value != POLICY_FIELD_GET(YP_DROPf)) 2277 { 2278 SET_ACTION_FROM_MAP(rp_drop_action_map); 2279 } 2280 2281 break; 2282 2283 case MIRROR_OVERRIDEf: 2284 action = bcmFieldActionMirrorOverride; 2285 break; 2286 2287 case MIRRORf: 2288 /* Because this field corresponds to two independent 2289 actions simultaneously, actions are added directly 2290 here rather than setting the action variable */ 2291 2292 if (field_value & 0x01) 2293 { 2294 /* Ingress */ 2295 2296 mtp_index = POLICY_FIELD_GET(IM_MTP_INDEXf); 2297 2298 SOC_IF_ERROR_RETURN(soc_mem_read(unit, IM_MTP_INDEXm, 2299 MEM_BLOCK_ANY, mtp_index, &im_mtp_index_entry)); 2300 2301 param0 = soc_IM_MTP_INDEXm_field32_get(unit, 2302 &im_mtp_index_entry, MODULE_IDf); 2303 2304 param1 = soc_IM_MTP_INDEXm_field32_get(unit, 2305 &im_mtp_index_entry, PORT_TGIDf); 2306 2307 BCM_IF_ERROR_RETURN(_field_action_alloc(unit, 2308 bcmFieldActionMirrorIngress, 2309 param0, param1, 0, 0, 0, 0, &fa_p)); 2310 2311 /* Mark action installed */ 2312 2313 fa_p->flags &= ~_FP_ACTION_DIRTY; 2314 2315 /* Add to entry's action list */ 2316 2317 fa_p->next = entry_p->actions; 2318 entry_p->actions = fa_p; 2319 } 2320 2321 if (field_value & 0x02) 2322 { 2323 /* Egress */ 2324 2325 mtp_index = POLICY_FIELD_GET(EM_MTP_INDEXf); 2326 2327 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EM_MTP_INDEXm, 2328 MEM_BLOCK_ANY, mtp_index, &em_mtp_index_entry)); 2329 2330 param0 = soc_EM_MTP_INDEXm_field32_get(unit, 2331 &em_mtp_index_entry, MODULE_IDf); 2332 2333 param1 = soc_EM_MTP_INDEXm_field32_get(unit, 2334 &em_mtp_index_entry, PORT_TGIDf); 2335 2336 BCM_IF_ERROR_RETURN(_field_action_alloc(unit, 2337 bcmFieldActionMirrorEgress, 2338 param0, param1, 0, 0, 0, 0, &fa_p)); 2339 2340 /* Mark action installed */ 2341 2342 fa_p->flags &= ~_FP_ACTION_DIRTY; 2343 2344 /* Add to entry's action list */ 2345 2346 fa_p->next = entry_p->actions; 2347 entry_p->actions = fa_p; 2348 } 2349 2350 break; 2351 2352 case L3SW_CHANGE_MACDA_OR_VLANf: 2353 SET_ACTION_FROM_MAP(l3sw_change_macda_or_vlan_action_map); 2354 2355 if (field_value == 1 || field_value == 4 || field_value == 6) 2356 { 2357 if (POLICY_FIELD_GET(ECMPf) != 0) 2358 { 2359 ecmp_count = POLICY_FIELD_GET(ECMP_COUNTf) + 1; 2360 nh_ecmp = POLICY_FIELD_GET(ECMP_PTRf); 2361 2362 param0 = _FP_L3_ACTION_PACK_ECMP(nh_ecmp, ecmp_count); 2363 } 2364 else 2365 { 2366 nh_ecmp = POLICY_FIELD_GET(NEXT_HOP_INDEXf); 2367 2368 param0 = _FP_L3_ACTION_PACK_NEXT_HOP(nh_ecmp); 2369 } 2370 } 2371 2372 break; 2373 2374 case COUNTER_MODEf: 2375 BCM_IF_ERROR_RETURN(_field_raven_counter_recover(unit, 2376 entry_p, field_value, POLICY_FIELD_GET(COUNTER_INDEXf), 2377 part_index, f_ent_wb_info->sid)); 2378 2379 break; 2380 2381 case METER_PAIR_MODEf: 2382 BCM_IF_ERROR_RETURN(_field_raven_meter_recover(unit, 2383 entry_p, policy_entry_p, part_index, f_ent_wb_info->pid)); 2384 2385 break; 2386 2387 default: 2388 break; 2389 } 2390 2391 if (action != bcmFieldActionCount) 2392 { 2393 /* Attach to entry's action list */ 2394 2395 BCM_IF_ERROR_RETURN(_field_action_alloc(unit, action, 2396 param0, param1, 0, 0, 0, 0, &fa_p)); 2397 2398 /* Mark action installed */ 2399 2400 fa_p->flags &= ~_FP_ACTION_DIRTY; 2401 2402 fa_p->next = entry_p->actions; 2403 entry_p->actions = fa_p; 2404 } 2405 } 2406 } 2407 2408 return BCM_E_NONE; 2409 } 2410 2411 #define _FP_RAVEN_IF_FAILURE_CLEANUP(op) \ 2412 rv = (op); if (BCM_FAILURE(rv)) goto cleanup; 2413 2414 int _field_raven_stage_reinit(int unit, _field_control_t *fc, 2415 _field_stage_t *stage_fc) 2416 { 2417 int temp, idx1; 2418 int rv, i, k, qual_idx, size; 2419 int *slice_is_expanded_flags = NULL; 2420 int *slice_master_idx = NULL; 2421 char *fp_tcam_buffer = NULL; 2422 char *fp_port_field_sel_buffer = NULL; 2423 int slice_index; 2424 int vslice_index; 2425 int slice_mode; 2426 int max; 2427 int master_slice; 2428 _field_slice_t *fs_p; 2429 int entry_index; 2430 bcm_port_t port; 2431 _field_raven_sel_codes_t sel_codes[_fieldRavenSliceModeCount]; 2432 _field_raven_sel_codes_t *sel_codes_p; 2433 int port_sel_entry_index; 2434 char *fp_policy_table_buffer = NULL; 2435 fp_tcam_entry_t *fp_tcam_entry_p; 2436 fp_port_field_sel_entry_t *port_field_sel_entry_p; 2437 uint32 port_enabled_for_entry; 2438 bcm_pbmp_t entry_pbmp; 2439 _field_group_t *fg_p; 2440 _field_slice_t *group_slice_p; 2441 int part_count; 2442 _field_entry_t *entries_p; 2443 int primary_tcam_index; 2444 int part_slice_index; 2445 int part_tcam_index; 2446 int part_index; 2447 _field_entry_t *entry_p = NULL; 2448 _bcm_field_group_qual_t *part_qualifier_p; 2449 int group_qualifier_index; 2450 int qualifier_id; 2451 _bcm_field_qual_info_t *stage_qualifier_p; 2452 int config_index; 2453 _bcm_field_qual_offset_t *config_offset_p; 2454 _bcm_field_qual_offset_t *group_qualifier_offset_p; 2455 fp_policy_table_entry_t *policy_entry_p; 2456 _bcm_field_selector_t config_selector; 2457 _bcm_field_slice_sel_t selector; 2458 uint8 selector_value; 2459 int multigroup; 2460 int prev_prio; 2461 int slice_is_primary; 2462 int extra_qual; 2463 char pbmp_string[SOC_PBMP_FMT_LEN]; 2464 uint32 hw_data, hw_mask; 2465 _bcm_field_qual_info_t *f_qual_arr = NULL; 2466 _bcm_field_qual_offset_t *q_offset_arr = NULL; 2467 uint16 *qid_arr = NULL; 2468 uint8 *buf = fc->scache_ptr[_FIELD_SCACHE_PART_0]; 2469 uint8 *buf1 = fc->scache_ptr[_FIELD_SCACHE_PART_1]; 2470 #if defined(BCM_RAVEN_SUPPORT) 2471 uint32 inner_vlan_overlay = _FP_SELCODE_DONT_CARE, rval; 2472 #endif 2473 _field_entry_wb_info_t f_ent_wb_info; 2474 bcm_pbmp_t temp_pbmp; 2475 _field_slice_t *fs_temp = NULL; 2476 uint8 old_physical_slice, slice_num; 2477 uint32 entry_flags; 2478 soc_field_t slice_f1_fields[16] = 2479 { 2480 SLICE0_F1f, SLICE1_F1f, SLICE2_F1f, SLICE3_F1f, 2481 SLICE4_F1f, SLICE5_F1f, SLICE6_F1f, SLICE7_F1f, 2482 SLICE8_F1f, SLICE9_F1f, SLICE10_F1f, SLICE11_F1f, 2483 SLICE12_F1f, SLICE13_F1f, SLICE14_F1f, SLICE15_F1f, 2484 }; 2485 2486 soc_field_t slice_f2_fields[16] = 2487 { 2488 SLICE0_F2f, SLICE1_F2f, SLICE2_F2f, SLICE3_F2f, 2489 SLICE4_F2f, SLICE5_F2f, SLICE6_F2f, SLICE7_F2f, 2490 SLICE8_F2f, SLICE9_F2f, SLICE10_F2f, SLICE11_F2f, 2491 SLICE12_F2f, SLICE13_F2f, SLICE14_F2f, SLICE15_F2f, 2492 }; 2493 2494 soc_field_t slice_f3_fields[16] = 2495 { 2496 SLICE0_F3f, SLICE1_F3f, SLICE2_F3f, SLICE3_F3f, 2497 SLICE4_F3f, SLICE5_F3f, SLICE6_F3f, SLICE7_F3f, 2498 SLICE8_F3f, SLICE9_F3f, SLICE10_F3f, SLICE11_F3f, 2499 SLICE12_F3f, SLICE13_F3f, SLICE14_F3f, SLICE15_F3f, 2500 }; 2501 2502 soc_field_t slice_f4_fields[16] = 2503 { 2504 SLICE0_F4f, SLICE1_F4f, SLICE2_F4f, SLICE3_F4f, 2505 SLICE4_F4f, SLICE5_F4f, SLICE6_F4f, SLICE7_F4f, 2506 SLICE8_F4f, SLICE9_F4f, SLICE10_F4f, SLICE11_F4f, 2507 SLICE12_F4f, SLICE13_F4f, SLICE14_F4f, SLICE15_F4f, 2508 }; 2509 2510 _field_action_bmp_t action_bmp; 2511 2512 /* Reset Action bitmap to NULL. */ 2513 action_bmp.w = NULL; 2514 2515 sal_memset(sel_codes, _FP_SELCODE_DONT_CARE, sizeof(sel_codes)); 2516 2517 fc->scache_pos = 0; 2518 fc->scache_pos1 = 0; 2519 2520 if (fc->l2warm) { 2521 if ((fc->wb_recovered_version) > (fc->wb_current_version)) { 2522 /* Notify the application with an event */ 2523 /* The application will then need to reconcile the 2524 version differences using the documented behavioral 2525 differences on per module (handle) basis */ 2526 SOC_IF_ERROR_RETURN 2527 (soc_event_generate(unit, SOC_SWITCH_EVENT_WARM_BOOT_DOWNGRADE, 2528 BCM_MODULE_FIELD, (fc->wb_recovered_version), 2529 (fc->wb_current_version))); 2530 } 2531 2532 fc->scache_pos += SOC_WB_SCACHE_CONTROL_SIZE; 2533 2534 if(NULL != fc->scache_ptr[_FIELD_SCACHE_PART_1]) { 2535 if ((fc->wb_recovered_version) > (fc->wb_current_version)) { 2536 /* Notify the application with an event */ 2537 /* The application will then need to reconcile the 2538 version differences using the documented behavioral 2539 differences on per module (handle) basis */ 2540 SOC_IF_ERROR_RETURN 2541 (soc_event_generate(unit, 2542 SOC_SWITCH_EVENT_WARM_BOOT_DOWNGRADE, 2543 BCM_MODULE_FIELD, (fc->wb_recovered_version), 2544 (fc->wb_current_version))); 2545 } 2546 2547 fc->scache_pos1 += SOC_WB_SCACHE_CONTROL_SIZE; 2548 } 2549 } 2550 2551 if (stage_fc->stage_id != _BCM_FIELD_STAGE_INGRESS) 2552 { 2553 return BCM_E_PARAM; 2554 } 2555 2556 LOG_DEBUG(BSL_LS_BCM_FP, 2557 (BSL_META_U(unit, 2558 "Beginning ingress stage recovery.\n"))); 2559 2560 if (fc->l2warm) { 2561 rv = _field_scache_stage_hdr_chk(fc, _FIELD_IFP_DATA_START); 2562 if (BCM_FAILURE(rv)) { 2563 return (rv); 2564 } 2565 } 2566 2567 /* Read TCAM into memory */ 2568 _FP_RAVEN_IF_FAILURE_CLEANUP(_field_table_read(unit, FP_TCAMm, 2569 &fp_tcam_buffer, "FP_TCAM buffer")); 2570 2571 /* Read FP_PORT_FIELD_SEL into memory */ 2572 _FP_RAVEN_IF_FAILURE_CLEANUP(_field_table_read(unit, 2573 FP_PORT_FIELD_SELm, &fp_port_field_sel_buffer, 2574 "FP_PORT_FIELD_SEL buffer")); 2575 2576 /* Read FP_POLICY_TABLE table into memory */ 2577 _FP_RAVEN_IF_FAILURE_CLEANUP(_field_table_read(unit, 2578 FP_POLICY_TABLEm, &fp_policy_table_buffer, 2579 "FP_POLICY_TABLE")); 2580 2581 /* Recover range checkers */ 2582 rv = _field_range_check_reinit(unit, stage_fc, fc); 2583 if (BCM_FAILURE(rv)) { 2584 goto cleanup; 2585 } 2586 2587 /* Recover data qualifiers */ 2588 rv = _field_data_qual_recover(unit, fc, stage_fc); 2589 if (BCM_FAILURE(rv)) { 2590 goto cleanup; 2591 } 2592 2593 #if defined(BCM_RAVEN_SUPPORT) 2594 /* Get per-device selectors */ 2595 if ((rv = READ_ING_MISC_CONFIG2r(unit, &rval)) < 0) { 2596 goto cleanup; 2597 } 2598 inner_vlan_overlay = soc_reg_field_get(unit, ING_MISC_CONFIG2r, rval, 2599 FP_INNER_VLAN_OVERLAY_ENABLEf); 2600 #endif 2601 2602 slice_is_expanded_flags = 2603 sal_alloc(stage_fc->tcam_slices * sizeof(int), 2604 "slice_is_expanded_flags"); 2605 2606 if (slice_is_expanded_flags == NULL) 2607 { 2608 rv = BCM_E_MEMORY; 2609 goto cleanup; 2610 } 2611 sal_memset(slice_is_expanded_flags, 0, stage_fc->tcam_slices * sizeof(int)); 2612 2613 slice_master_idx = 2614 sal_alloc(stage_fc->tcam_slices * sizeof(int), 2615 "slice_is_expanded_flags"); 2616 2617 if (slice_master_idx == NULL) 2618 { 2619 rv = BCM_E_MEMORY; 2620 goto cleanup; 2621 } 2622 sal_memset(slice_master_idx, 0, stage_fc->tcam_slices * sizeof(int)); 2623 2624 _FP_RAVEN_IF_FAILURE_CLEANUP(_field_slice_expanded_status_get(unit, 2625 fc, stage_fc, slice_is_expanded_flags, slice_master_idx)); 2626 2627 for (slice_index = 0; slice_index < stage_fc->tcam_slices; ++slice_index) 2628 { 2629 LOG_DEBUG(BSL_LS_BCM_FP, 2630 (BSL_META_U(unit, 2631 " Checking slice %d...\n"), 2632 slice_index)); 2633 2634 _FP_RAVEN_IF_FAILURE_CLEANUP(_field_fb_slice_is_primary(unit, 2635 slice_index, &slice_is_primary, &slice_mode)); 2636 2637 if (!slice_is_primary) 2638 { 2639 /* Don't need selectors for second slice of double or for 2640 second and third slices of triple */ 2641 2642 LOG_DEBUG(BSL_LS_BCM_FP, 2643 (BSL_META_U(unit, 2644 " Not a primary slice.\n"))); 2645 2646 continue; 2647 } 2648 2649 if (slice_is_expanded_flags[slice_index] != 0) 2650 { 2651 /* Don't need selectors for an expanded slice */ 2652 2653 continue; 2654 } 2655 2656 /* Check if the slice has any valid entries */ 2657 2658 fs_p = stage_fc->slices[_FP_DEF_INST] + slice_index; 2659 2660 for (entry_index = 0; entry_index < fs_p->entry_count; ++entry_index) 2661 { 2662 fp_tcam_entry_p = soc_mem_table_idx_to_pointer(unit, FP_TCAMm, 2663 fp_tcam_entry_t *, fp_tcam_buffer, 2664 entry_index + fs_p->entry_count * slice_index); 2665 2666 if (soc_FP_TCAMm_field32_get(unit, fp_tcam_entry_p, VALIDf) != 0) 2667 { 2668 /* There's at least one valid entry in the slice */ 2669 2670 break; 2671 } 2672 } 2673 2674 if ((entry_index == fs_p->entry_count) && !fc->l2warm) 2675 { 2676 /* No valid groups and entries in the slice */ 2677 2678 LOG_DEBUG(BSL_LS_BCM_FP, 2679 (BSL_META_U(unit, 2680 " No valid groups and entries in slice.\n"))); 2681 2682 continue; 2683 } 2684 2685 if (fc->l2warm) 2686 { 2687 /* Retrieve the group IDs in this slice */ 2688 2689 rv = _field_scache_slice_group_recover(unit, fc, 2690 slice_index, &multigroup); 2691 2692 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 2693 fc->l2warm = 0; 2694 goto cleanup; 2695 } 2696 if (rv == BCM_E_NOT_FOUND) { 2697 rv = BCM_E_NONE; 2698 continue; 2699 } 2700 } 2701 2702 PBMP_ALL_ITER(unit, port) 2703 { 2704 port_field_sel_entry_p = soc_mem_table_idx_to_pointer( 2705 unit, FP_PORT_FIELD_SELm, fp_port_field_sel_entry_t *, 2706 fp_port_field_sel_buffer, port); 2707 2708 for (part_index = 0; part_index <= slice_mode; ++part_index) 2709 { 2710 sel_codes_p = sel_codes + part_index; 2711 2712 sel_codes_p->fpf1 = soc_FP_PORT_FIELD_SELm_field32_get( 2713 unit, port_field_sel_entry_p, 2714 slice_f1_fields[slice_index + part_index]); 2715 2716 sel_codes_p->fpf2 = soc_FP_PORT_FIELD_SELm_field32_get( 2717 unit, port_field_sel_entry_p, 2718 slice_f2_fields[slice_index + part_index]); 2719 2720 sel_codes_p->fpf3 = soc_FP_PORT_FIELD_SELm_field32_get( 2721 unit, port_field_sel_entry_p, 2722 slice_f3_fields[slice_index + part_index]); 2723 2724 sel_codes_p->fpf4 = soc_FP_PORT_FIELD_SELm_field32_get( 2725 unit, port_field_sel_entry_p, 2726 slice_f4_fields[slice_index + part_index]); 2727 2728 #if defined(BCM_RAVEN_SUPPORT) 2729 if (inner_vlan_overlay) { 2730 sel_codes_p->inner_vlan_overlay = inner_vlan_overlay; 2731 } else 2732 #endif 2733 { 2734 sel_codes_p->inner_vlan_overlay = _FP_SELCODE_DONT_CARE; 2735 } 2736 } 2737 2738 _FP_RAVEN_IF_FAILURE_CLEANUP(_field_raven_group_construct(unit, 2739 fc, slice_mode, stage_fc->stage_id, slice_index, port, 2740 sel_codes)); 2741 } 2742 2743 /* Adjust group's QSET to potentially add InPort/InPorts */ 2744 2745 for (fg_p = fc->groups; fg_p != NULL; fg_p = fg_p->next) { 2746 for (extra_qual = 0; extra_qual < 2; extra_qual++) { 2747 if (extra_qual == 1) { 2748 qual_idx = bcmFieldQualifyInPort; 2749 } else { 2750 qual_idx = bcmFieldQualifyInPorts; 2751 } 2752 f_qual_arr = stage_fc->f_qual_arr[qual_idx]; 2753 BCM_FIELD_QSET_ADD(fg_p->qset, qual_idx); 2754 /* Allocate memory for this qualfier and its 2755 associated offset information if not already added 2756 to fg->qual_arr[i] */ 2757 _FP_RAVEN_IF_FAILURE_CLEANUP( 2758 _bcm_field_entry_tcam_parts_count(unit, fg_p->stage_id, 2759 fg_p->flags, &part_count)); 2760 for (i = 0; i < part_count; i++) { 2761 for (k = 0; k < fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].size; k++) { 2762 if (fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].qid_arr[k] == qual_idx) { 2763 break; /* Qualifier already added */ 2764 } 2765 } 2766 if (k == fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].size) { 2767 size = fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].size + 1; 2768 qid_arr = NULL; 2769 _FP_XGS3_ALLOC(qid_arr, size * sizeof (uint16), 2770 "Group qual id"); 2771 if (NULL == qid_arr) { 2772 rv = BCM_E_MEMORY; 2773 goto cleanup; 2774 } 2775 q_offset_arr = NULL; 2776 _FP_XGS3_ALLOC(q_offset_arr, size * 2777 sizeof (_bcm_field_qual_offset_t), 2778 "Group qual offset"); 2779 if (NULL == q_offset_arr) { 2780 sal_free (qid_arr); 2781 rv = BCM_E_MEMORY; 2782 goto cleanup; 2783 } 2784 if (size) { 2785 sal_memcpy(qid_arr, fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].qid_arr, 2786 fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].size * 2787 sizeof (uint16)); 2788 sal_memcpy(q_offset_arr, 2789 fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].offset_arr, 2790 fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].size * 2791 sizeof (_bcm_field_qual_offset_t)); 2792 if (fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].size) { 2793 sal_free(fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].qid_arr); 2794 sal_free(fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].offset_arr); 2795 } 2796 } 2797 fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].qid_arr = qid_arr; 2798 fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].offset_arr = q_offset_arr; 2799 fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].qid_arr[size - 1] = qual_idx; 2800 sal_memcpy(&fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].offset_arr[size - 1], 2801 &f_qual_arr->conf_arr[0].offset, 2802 sizeof(f_qual_arr->conf_arr[0].offset)); 2803 fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][i].size = size; 2804 break; /* Just added the qualifier */ 2805 } 2806 } 2807 } 2808 } 2809 2810 /* Recover entries in this slice */ 2811 2812 fs_p = stage_fc->slices[_FP_DEF_INST] + slice_index; 2813 prev_prio = -1; 2814 2815 for (entry_index = 0; entry_index < fs_p->entry_count; ++entry_index) 2816 { 2817 fp_tcam_entry_p = soc_mem_table_idx_to_pointer(unit, FP_TCAMm, 2818 fp_tcam_entry_t *, fp_tcam_buffer, entry_index + 2819 slice_index * fs_p->entry_count); 2820 2821 if (soc_FP_TCAMm_field32_get(unit, fp_tcam_entry_p, VALIDf) == 0) 2822 { 2823 /* Skip empty entry */ 2824 2825 continue; 2826 } 2827 2828 LOG_DEBUG(BSL_LS_BCM_FP, 2829 (BSL_META_U(unit, 2830 " Checking entry %d...\n"), 2831 entry_index)); 2832 2833 /* Determine pbmp for this entry */ 2834 2835 BCM_PBMP_CLEAR(entry_pbmp); 2836 PBMP_ALL_ITER(unit, port) 2837 { 2838 port_sel_entry_index = _BCM_RP_FIELD_IPBM_INDEX(unit, 2839 port, slice_index); 2840 2841 _FP_RAVEN_IF_FAILURE_CLEANUP( 2842 _field_raptor_ipbm_entry_get(unit, port_sel_entry_index, 2843 entry_index, &port_enabled_for_entry)); 2844 2845 if (port_enabled_for_entry) 2846 { 2847 BCM_PBMP_PORT_ADD(entry_pbmp, port); 2848 } 2849 } 2850 2851 SOC_PBMP_FMT(entry_pbmp, pbmp_string); 2852 LOG_DEBUG(BSL_LS_BCM_FP, 2853 (BSL_META_U(unit, 2854 "Entry PBMP: %s\n"), 2855 pbmp_string)); 2856 2857 /* Find a matching group */ 2858 2859 for (fg_p = fc->groups; fg_p != NULL; fg_p = fg_p->next) 2860 { 2861 LOG_DEBUG(BSL_LS_BCM_FP, 2862 (BSL_META_U(unit, 2863 " Checking group %d...\n"), 2864 fg_p->gid)); 2865 2866 group_slice_p = fg_p->slices; 2867 2868 if (group_slice_p->slice_number != slice_index) 2869 { 2870 /* Not this slice */ 2871 2872 continue; 2873 } 2874 2875 SOC_PBMP_FMT(fg_p->pbmp, pbmp_string); 2876 LOG_DEBUG(BSL_LS_BCM_FP, 2877 (BSL_META_U(unit, 2878 "Group PBMP: %s\n"), 2879 pbmp_string)); 2880 2881 SOC_PBMP_CLEAR(temp_pbmp); 2882 SOC_PBMP_ASSIGN(temp_pbmp, fg_p->pbmp); 2883 SOC_PBMP_OR(temp_pbmp, PBMP_LB(unit)); 2884 SOC_PBMP_AND(temp_pbmp, entry_pbmp); 2885 if (SOC_PBMP_EQ(temp_pbmp, entry_pbmp)) 2886 { 2887 /* Found a match */ 2888 2889 break; 2890 } 2891 2892 /* Check if entry pbmp is a subset of the group pbmp */ 2893 2894 SOC_PBMP_ITER(entry_pbmp, port) 2895 { 2896 if (SOC_PBMP_MEMBER(fg_p->pbmp, port) == 0) 2897 { 2898 break; 2899 } 2900 } 2901 2902 if (port == SOC_PBMP_PORT_MAX) 2903 { 2904 /* Got all the way through with no mismatches */ 2905 2906 break; 2907 } 2908 } 2909 2910 if (fg_p == NULL) 2911 { 2912 /* This should never happen */ 2913 LOG_ERROR(BSL_LS_BCM_FP, 2914 (BSL_META_U(unit, 2915 "Could not find a matching group for entry %d.\n"), 2916 entry_index)); 2917 rv = BCM_E_INTERNAL; 2918 goto cleanup; 2919 } 2920 2921 /* Allocate the entry */ 2922 2923 _FP_RAVEN_IF_FAILURE_CLEANUP( 2924 _bcm_field_entry_tcam_parts_count(unit, fg_p->stage_id, 2925 fg_p->flags, &part_count)); 2926 2927 entries_p = NULL; 2928 2929 _FP_XGS3_ALLOC(entries_p, part_count * sizeof (_field_entry_t), 2930 "field entry"); 2931 2932 if (entries_p == NULL) 2933 { 2934 rv = BCM_E_MEMORY; 2935 2936 goto cleanup; 2937 } 2938 2939 LOG_DEBUG(BSL_LS_BCM_FP, 2940 (BSL_META_U(unit, 2941 " Entry matches group %d.\n"), 2942 fg_p->gid)); 2943 2944 sal_memset(&f_ent_wb_info, 0, sizeof(_field_entry_wb_info_t)); 2945 f_ent_wb_info.sid = -1; 2946 f_ent_wb_info.pid = -1; 2947 2948 if (fc->l2warm) 2949 { 2950 if ((fc->wb_recovered_version) >= BCM_FIELD_WB_VERSION_1_15) { 2951 action_bmp.w = NULL; 2952 _FP_XGS3_ALLOC(action_bmp.w, 2953 SHR_BITALLOCSIZE(_bcmFieldActionNoParamCount), 2954 "Action No Param Bitmap"); 2955 if (action_bmp.w == NULL) { 2956 rv = BCM_E_MEMORY; 2957 sal_free(entries_p); 2958 goto cleanup; 2959 } 2960 } 2961 f_ent_wb_info.action_bmp = &action_bmp; 2962 2963 rv = _field_entry_info_retrieve(unit, fc, stage_fc, 2964 multigroup, &prev_prio, &f_ent_wb_info); 2965 2966 if (BCM_FAILURE(rv)) 2967 { 2968 LOG_ERROR(BSL_LS_BCM_FP, 2969 (BSL_META_U(unit, 2970 "Failed to retrieve entry info."))); 2971 sal_free(entries_p); 2972 goto cleanup; 2973 } 2974 } 2975 else 2976 { 2977 _bcm_field_last_alloc_eid_incr(unit); 2978 2979 f_ent_wb_info.eid = _bcm_field_last_alloc_eid_get(unit); 2980 } 2981 2982 vslice_index = _field_physical_to_virtual(unit, _FP_DEF_INST, 2983 slice_index, stage_fc); 2984 if (vslice_index == -1) 2985 { 2986 rv = BCM_E_INTERNAL; 2987 sal_free(entries_p); 2988 goto cleanup; 2989 } 2990 2991 primary_tcam_index = 2992 slice_index * fs_p->entry_count + entry_index; 2993 2994 for (part_index = 0; part_index < part_count; ++part_index) 2995 { 2996 entry_p = entries_p + part_index; 2997 2998 entry_p->eid = f_ent_wb_info.eid; 2999 entry_p->group = fg_p; 3000 /* Set retrieved dvp_type and svp_type */ 3001 entry_p->dvp_type = f_ent_wb_info.dvp_type[part_index]; 3002 entry_p->svp_type = f_ent_wb_info.svp_type[part_index]; 3003 3004 if (part_index == 0) { 3005 BCM_PBMP_ASSIGN(entry_p->pbmp.data, entry_pbmp); 3006 BCM_PBMP_ASSIGN(entry_p->pbmp.mask, PBMP_ALL(unit)); 3007 } 3008 3009 /* Set entry flags */ 3010 3011 rv = _bcm_field_tcam_part_to_entry_flags(unit, part_index, 3012 fg_p, &entry_p->flags); 3013 3014 if (BCM_FAILURE(rv)) { 3015 sal_free(entries_p); 3016 goto cleanup; 3017 } 3018 3019 if (f_ent_wb_info.color_independent) 3020 { 3021 entry_p->flags |= _FP_ENTRY_COLOR_INDEPENDENT; 3022 } 3023 3024 /* Get index of entry in tcam */ 3025 3026 rv = _bcm_field_entry_part_tcam_idx_get(unit, entries_p, 3027 primary_tcam_index, part_index, &part_tcam_index); 3028 3029 if (BCM_FAILURE(rv)) { 3030 sal_free(entries_p); 3031 goto cleanup; 3032 } 3033 3034 /* Get slice and index within the slice */ 3035 3036 rv = _bcm_field_tcam_idx_to_slice_offset(unit, stage_fc, 3037 _FP_DEF_INST, part_tcam_index, &part_slice_index, 3038 (int *) (&entry_p->slice_idx)); 3039 3040 if (BCM_FAILURE(rv)) { 3041 sal_free(entries_p); 3042 goto cleanup; 3043 } 3044 3045 /* Point the entry to its slice */ 3046 3047 entry_p->fs = stage_fc->slices[_FP_DEF_INST] + part_slice_index; 3048 --entry_p->fs->free_count; 3049 3050 /* Set the slice pbmp */ 3051 3052 BCM_PBMP_OR(entry_p->fs->pbmp, fg_p->pbmp); 3053 3054 /* Assign entry to slice */ 3055 3056 entry_p->fs->entries[entry_p->slice_idx] = entry_p; 3057 entry_p->flags |= _FP_ENTRY_INSTALLED; 3058 3059 if (soc_FP_TCAMm_field32_get(unit, fp_tcam_entry_p, VALIDf) == 3) { 3060 entry_p->flags |= _FP_ENTRY_ENABLED; 3061 } 3062 3063 fp_tcam_entry_p = 3064 (fp_tcam_entry_t *) soc_mem_table_idx_to_pointer(unit, 3065 FP_TCAMm, fp_tcam_entry_t *, fp_tcam_buffer, 3066 part_tcam_index); 3067 3068 part_qualifier_p = &(fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part_index]); 3069 3070 for (group_qualifier_index = 0; 3071 group_qualifier_index < part_qualifier_p->size; 3072 ++group_qualifier_index) 3073 { 3074 qualifier_id = 3075 part_qualifier_p->qid_arr[group_qualifier_index]; 3076 3077 stage_qualifier_p = stage_fc->f_qual_arr[qualifier_id]; 3078 3079 for (config_index = 0; 3080 config_index < stage_qualifier_p->conf_sz; 3081 ++config_index) 3082 { 3083 config_offset_p = &((stage_qualifier_p->conf_arr + 3084 config_index)->offset); 3085 3086 group_qualifier_offset_p = 3087 part_qualifier_p->offset_arr + 3088 group_qualifier_index; 3089 3090 if (_mask_is_set(unit, config_offset_p, 3091 (uint32 *) fp_tcam_entry_p, 3092 stage_fc->stage_id) != 0) 3093 { 3094 config_selector = stage_qualifier_p-> 3095 conf_arr[config_index].selector; 3096 3097 selector = config_selector.pri_sel; 3098 selector_value = config_selector.pri_sel_val; 3099 3100 if ((selector == _bcmFieldSliceSelFpf1 && 3101 selector_value == sel_codes[part_index].fpf1) || 3102 (selector == _bcmFieldSliceSelFpf2 && 3103 selector_value == sel_codes[part_index].fpf2) || 3104 (selector == _bcmFieldSliceSelFpf3 && 3105 selector_value == sel_codes[part_index].fpf3) || 3106 (selector == _bcmFieldSliceSelFpf4 && 3107 selector_value == sel_codes[part_index].fpf4)) 3108 { 3109 /* This qualifier exists in this entry */ 3110 3111 *group_qualifier_offset_p = *config_offset_p; 3112 3113 /* No need to check more configs */ 3114 3115 break; 3116 } 3117 } 3118 } 3119 } 3120 3121 /* Get IP type and mask values. */ 3122 hw_data = soc_FP_TCAMm_field32_get(unit, 3123 fp_tcam_entry_p, IP_TYPEf); 3124 hw_mask = soc_FP_TCAMm_field32_get(unit, 3125 fp_tcam_entry_p, 3126 IP_TYPE_MASKf); 3127 3128 if ((hw_data == 0) && (hw_mask == 0)) { 3129 entry_p->tcam.ip_type = bcmFieldIpTypeAny; 3130 } else if ((hw_data == 0) && (hw_mask == 3)) { 3131 entry_p->tcam.ip_type = bcmFieldIpTypeNonIp; 3132 } else if ((hw_data == 0) && (hw_mask == 1)) { 3133 entry_p->tcam.ip_type = bcmFieldIpTypeIpv4Not; 3134 } else if ((hw_data == 1) && (hw_mask == 3)) { 3135 entry_p->tcam.ip_type = bcmFieldIpTypeIpv4NoOpts; 3136 } else if ((hw_data == 3) && (hw_mask == 3)) { 3137 entry_p->tcam.ip_type = bcmFieldIpTypeIpv4WithOpts; 3138 } else if ((hw_data == 1) && (hw_mask == 1)) { 3139 entry_p->tcam.ip_type = bcmFieldIpTypeIpv4Any; 3140 } else if ((hw_data == 2) && (hw_mask == 3)) { 3141 entry_p->tcam.ip_type = bcmFieldIpTypeIpv6; 3142 } 3143 3144 /* Get Higig data and mask values. */ 3145 hw_data = soc_FP_TCAMm_field32_get(unit, 3146 fp_tcam_entry_p, HIGIG_PKTf); 3147 hw_mask = soc_FP_TCAMm_field32_get(unit, 3148 fp_tcam_entry_p, 3149 HIGIG_PKT_MASKf); 3150 entry_p->tcam.higig = hw_data; 3151 entry_p->tcam.higig_mask = hw_mask; 3152 3153 /* Get the actions for this part of the entry */ 3154 3155 policy_entry_p = soc_mem_table_idx_to_pointer(unit, 3156 FP_POLICY_TABLEm, fp_policy_table_entry_t *, 3157 fp_policy_table_buffer, part_tcam_index); 3158 3159 rv = _field_raven_actions_recover(unit, policy_entry_p, 3160 entries_p, part_index, &f_ent_wb_info); 3161 3162 if (BCM_FAILURE(rv)) { 3163 sal_free(entries_p); 3164 goto cleanup; 3165 } 3166 3167 if (action_bmp.w != NULL) { 3168 _FP_ACTION_BMP_FREE(action_bmp); 3169 action_bmp.w = NULL; 3170 } 3171 entry_p->prio = fc->l2warm ? f_ent_wb_info.prio : 3172 (vslice_index << 10) | (fs_p->entry_count - entry_index); 3173 3174 } 3175 LOG_DEBUG(BSL_LS_BCM_FP, 3176 (BSL_META_U(unit, 3177 " Entry id = %d, priority = %d.\n"), 3178 entries_p->eid, 3179 entries_p->prio)); 3180 3181 /* Add the entry to the group */ 3182 3183 rv = _field_group_entry_add(unit, fg_p, entries_p); 3184 if (BCM_FAILURE(rv)) { 3185 sal_free(entries_p); 3186 goto cleanup; 3187 } 3188 } 3189 3190 if (fc->l2warm) 3191 { 3192 _field_scache_slice_group_free(unit, fc, slice_index); 3193 } 3194 } 3195 3196 /* Now go over the expanded slices */ 3197 for (slice_index = 0; slice_index < stage_fc->tcam_slices; ++slice_index) 3198 { 3199 LOG_DEBUG(BSL_LS_BCM_FP, 3200 (BSL_META_U(unit, 3201 " Checking slice %d...\n"), 3202 slice_index)); 3203 3204 if (slice_is_expanded_flags[slice_index] == 0) 3205 { 3206 continue; 3207 } 3208 3209 _FP_RAVEN_IF_FAILURE_CLEANUP(_field_fb_slice_is_primary(unit, 3210 slice_index, &slice_is_primary, &slice_mode)); 3211 3212 if (!slice_is_primary) 3213 { 3214 LOG_DEBUG(BSL_LS_BCM_FP, 3215 (BSL_META_U(unit, 3216 " Not a primary slice.\n"))); 3217 continue; 3218 } 3219 3220 /* Check if the slice has any valid entries */ 3221 3222 fs_p = stage_fc->slices[_FP_DEF_INST] + slice_index; 3223 3224 for (entry_index = 0; entry_index < fs_p->entry_count; ++entry_index) 3225 { 3226 fp_tcam_entry_p = soc_mem_table_idx_to_pointer(unit, FP_TCAMm, 3227 fp_tcam_entry_t *, fp_tcam_buffer, 3228 entry_index + fs_p->entry_count * slice_index); 3229 3230 if (soc_FP_TCAMm_field32_get(unit, fp_tcam_entry_p, VALIDf) != 0) 3231 { 3232 /* There's at least one valid entry in the slice */ 3233 3234 break; 3235 } 3236 } 3237 3238 if (entry_index == fs_p->entry_count) 3239 { 3240 /* No valid entries in the slice */ 3241 3242 LOG_DEBUG(BSL_LS_BCM_FP, 3243 (BSL_META_U(unit, 3244 " No valid entries in slice.\n"))); 3245 3246 continue; 3247 } 3248 3249 if (fc->l2warm) 3250 { 3251 /* Retrieve the group IDs in this slice */ 3252 3253 rv = _field_scache_slice_group_recover(unit, fc, 3254 slice_index, &multigroup); 3255 3256 if (BCM_FAILURE(rv)) 3257 { 3258 LOG_ERROR(BSL_LS_BCM_FP, 3259 (BSL_META_U(unit, 3260 "Failed to retrieve group IDs in slice %d."), 3261 slice_index)); 3262 3263 goto cleanup; 3264 } 3265 } 3266 3267 /* Now find the master slice for this virtual group */ 3268 vslice_index = _field_physical_to_virtual(unit, _FP_DEF_INST, 3269 slice_index, stage_fc); 3270 if (fc->l2warm 3271 && ((fc->wb_recovered_version) >= BCM_FIELD_WB_VERSION_1_8)) { 3272 master_slice = slice_master_idx[slice_index]; 3273 } else { 3274 max = -1; 3275 for (i = 0; i < stage_fc->tcam_slices; i++) { 3276 if ((stage_fc->vmap[_FP_DEF_INST][0][vslice_index].virtual_group == 3277 stage_fc->vmap[_FP_DEF_INST][0][i].virtual_group) && (i != vslice_index)) { 3278 if (i > max) { 3279 max = i; 3280 } 3281 } 3282 } 3283 3284 /* max - Must be a valid hardware slice index value */ 3285 if (-1 == max) { 3286 rv = BCM_E_INTERNAL; 3287 goto cleanup; 3288 } 3289 3290 master_slice = stage_fc->vmap[_FP_DEF_INST][0][max].vmap_key; 3291 } 3292 3293 /* See which group is in this slice - can be only one */ 3294 fg_p = fc->groups; 3295 while (fg_p != NULL) { 3296 /* Check if group is in this slice */ 3297 fs_p = &fg_p->slices[0]; 3298 if ((fg_p->stage_id == stage_fc->stage_id) 3299 && (fs_p->slice_number == master_slice)) { 3300 break; 3301 } 3302 fg_p = fg_p->next; 3303 } 3304 3305 if (fg_p == NULL) 3306 { 3307 rv = BCM_E_INTERNAL; 3308 goto cleanup; 3309 } 3310 3311 /* Get number of entry parts. */ 3312 _FP_RAVEN_IF_FAILURE_CLEANUP( 3313 _bcm_field_entry_tcam_parts_count (unit, fg_p->stage_id, 3314 fg_p->flags, &part_count)); 3315 3316 old_physical_slice = fs_p->slice_number; 3317 3318 /* Set up the new physical slice parameters in Software */ 3319 for(part_index = part_count - 1; part_index >= 0; part_index--) { 3320 /* Get entry flags. */ 3321 _FP_RAVEN_IF_FAILURE_CLEANUP( 3322 _bcm_field_tcam_part_to_entry_flags(unit, 3323 part_index, fg_p, &entry_flags)); 3324 3325 /* Get slice id for entry part */ 3326 _FP_RAVEN_IF_FAILURE_CLEANUP( 3327 _bcm_field_tcam_part_to_slice_number(unit, part_index, 3328 fg_p, &slice_num)); 3329 3330 /* Get slice pointer. */ 3331 fs_p = stage_fc->slices[_FP_DEF_INST] + slice_index + slice_num; 3332 3333 if (0 == (entry_flags & _FP_ENTRY_SECOND_HALF)) { 3334 /* Set per slice configuration & number of free entries in the slice.*/ 3335 fs_p->free_count = fs_p->entry_count; 3336 if (fg_p->flags & _FP_GROUP_INTRASLICE_DOUBLEWIDE) { 3337 fs_p->free_count >>= 1; 3338 } 3339 /* Set group flags in in slice.*/ 3340 fs_p->group_flags = fg_p->flags & _FP_GROUP_STATUS_MASK; 3341 3342 /* Add slice to slices linked list . */ 3343 fs_temp = stage_fc->slices[_FP_DEF_INST] + old_physical_slice + slice_num; 3344 /* To handle more than one auto expanded slice in a group */ 3345 while (fs_temp->next != NULL) { 3346 fs_temp = fs_temp->next; 3347 } 3348 fs_temp->next = fs_p; 3349 fs_p->prev = fs_temp; 3350 } 3351 } 3352 3353 fs_p = stage_fc->slices[_FP_DEF_INST] + slice_index; 3354 /* Recover entries in this slice */ 3355 3356 prev_prio = -1; 3357 3358 for (entry_index = 0; entry_index < fs_p->entry_count; ++entry_index) 3359 { 3360 fp_tcam_entry_p = soc_mem_table_idx_to_pointer(unit, FP_TCAMm, 3361 fp_tcam_entry_t *, fp_tcam_buffer, entry_index + 3362 slice_index * fs_p->entry_count); 3363 3364 if (soc_FP_TCAMm_field32_get(unit, fp_tcam_entry_p, VALIDf) == 0) 3365 { 3366 /* Skip empty entry */ 3367 3368 continue; 3369 } 3370 3371 LOG_DEBUG(BSL_LS_BCM_FP, 3372 (BSL_META_U(unit, 3373 " Checking entry %d...\n"), 3374 entry_index)); 3375 3376 /* Determine pbmp for this entry */ 3377 3378 BCM_PBMP_CLEAR(entry_pbmp); 3379 PBMP_ALL_ITER(unit, port) 3380 { 3381 port_sel_entry_index = _BCM_RP_FIELD_IPBM_INDEX(unit, 3382 port, slice_index); 3383 3384 _FP_RAVEN_IF_FAILURE_CLEANUP( 3385 _field_raptor_ipbm_entry_get(unit, port_sel_entry_index, 3386 entry_index, &port_enabled_for_entry)); 3387 3388 if (port_enabled_for_entry) 3389 { 3390 BCM_PBMP_PORT_ADD(entry_pbmp, port); 3391 } 3392 } 3393 3394 SOC_PBMP_FMT(entry_pbmp, pbmp_string); 3395 LOG_DEBUG(BSL_LS_BCM_FP, 3396 (BSL_META_U(unit, 3397 "Entry PBMP: %s\n"), 3398 pbmp_string)); 3399 3400 /* Find a matching group */ 3401 3402 for (fg_p = fc->groups; fg_p != NULL; fg_p = fg_p->next) 3403 { 3404 LOG_DEBUG(BSL_LS_BCM_FP, 3405 (BSL_META_U(unit, 3406 " Checking group %d...\n"), 3407 fg_p->gid)); 3408 3409 group_slice_p = fg_p->slices; 3410 3411 if ((fg_p->stage_id != stage_fc->stage_id) 3412 || (group_slice_p->slice_number != master_slice)) 3413 { 3414 /* Not this slice */ 3415 3416 continue; 3417 } 3418 3419 SOC_PBMP_FMT(fg_p->pbmp, pbmp_string); 3420 LOG_DEBUG(BSL_LS_BCM_FP, 3421 (BSL_META_U(unit, 3422 "Group PBMP: %s\n"), 3423 pbmp_string)); 3424 3425 SOC_PBMP_CLEAR(temp_pbmp); 3426 SOC_PBMP_ASSIGN(temp_pbmp, fg_p->pbmp); 3427 SOC_PBMP_OR(temp_pbmp, PBMP_LB(unit)); 3428 SOC_PBMP_AND(temp_pbmp, entry_pbmp); 3429 if (SOC_PBMP_EQ(temp_pbmp, entry_pbmp)) 3430 { 3431 /* Found a match */ 3432 3433 break; 3434 } 3435 3436 /* Check if entry pbmp is a subset of the group pbmp */ 3437 3438 SOC_PBMP_ITER(entry_pbmp, port) 3439 { 3440 if (SOC_PBMP_MEMBER(fg_p->pbmp, port) == 0) 3441 { 3442 break; 3443 } 3444 } 3445 3446 if (port == SOC_PBMP_PORT_MAX) 3447 { 3448 /* Got all the way through with no mismatches */ 3449 3450 break; 3451 } 3452 } 3453 3454 if (fg_p == NULL) 3455 { 3456 /* This should never happen */ 3457 LOG_ERROR(BSL_LS_BCM_FP, 3458 (BSL_META_U(unit, 3459 "Could not find a matching group for entry %d.\n"), 3460 entry_index)); 3461 rv = BCM_E_INTERNAL; 3462 goto cleanup; 3463 } 3464 3465 /* Allocate the entry */ 3466 3467 _FP_RAVEN_IF_FAILURE_CLEANUP( 3468 _bcm_field_entry_tcam_parts_count(unit, fg_p->stage_id, 3469 fg_p->flags, &part_count)); 3470 3471 entries_p = NULL; 3472 3473 _FP_XGS3_ALLOC(entries_p, part_count * sizeof (_field_entry_t), 3474 "field entry"); 3475 3476 for (idx1 = 0; idx1 < _FP_POLICER_LEVEL_COUNT; idx1++) { 3477 entries_p->policer[idx1].pid = _FP_INVALID_INDEX; 3478 } 3479 3480 if (entries_p == NULL) 3481 { 3482 rv = BCM_E_MEMORY; 3483 3484 goto cleanup; 3485 } 3486 3487 LOG_DEBUG(BSL_LS_BCM_FP, 3488 (BSL_META_U(unit, 3489 " Entry matches group %d.\n"), 3490 fg_p->gid)); 3491 3492 sal_memset(&f_ent_wb_info, 0, sizeof(_field_entry_wb_info_t)); 3493 f_ent_wb_info.sid = -1; 3494 f_ent_wb_info.pid = -1; 3495 3496 if (fc->l2warm) 3497 { 3498 if ((fc->wb_recovered_version) >= BCM_FIELD_WB_VERSION_1_15) { 3499 action_bmp.w = NULL; 3500 _FP_XGS3_ALLOC(action_bmp.w, 3501 SHR_BITALLOCSIZE(_bcmFieldActionNoParamCount), 3502 "Action No Param Bitmap"); 3503 if (action_bmp.w == NULL) { 3504 rv = BCM_E_MEMORY; 3505 sal_free(entries_p); 3506 goto cleanup; 3507 } 3508 } 3509 f_ent_wb_info.action_bmp = &action_bmp; 3510 3511 rv = _field_entry_info_retrieve(unit, fc, stage_fc, 3512 multigroup, &prev_prio, &f_ent_wb_info); 3513 3514 if (BCM_FAILURE(rv)) 3515 { 3516 LOG_ERROR(BSL_LS_BCM_FP, 3517 (BSL_META_U(unit, 3518 "Failed to retrieve entry info."))); 3519 sal_free(entries_p); 3520 goto cleanup; 3521 } 3522 } 3523 else 3524 { 3525 _bcm_field_last_alloc_eid_incr(unit); 3526 3527 f_ent_wb_info.eid = _bcm_field_last_alloc_eid_get(unit); 3528 } 3529 3530 primary_tcam_index = 3531 slice_index * fs_p->entry_count + entry_index; 3532 3533 for (part_index = 0; part_index < part_count; ++part_index) 3534 { 3535 entry_p = entries_p + part_index; 3536 3537 entry_p->eid = f_ent_wb_info.eid; 3538 entry_p->group = fg_p; 3539 /* Set retrieved dvp_type and svp_type */ 3540 entry_p->dvp_type = f_ent_wb_info.dvp_type[part_index]; 3541 entry_p->svp_type = f_ent_wb_info.svp_type[part_index]; 3542 3543 if (part_index == 0) { 3544 BCM_PBMP_ASSIGN(entry_p->pbmp.data, entry_pbmp); 3545 BCM_PBMP_ASSIGN(entry_p->pbmp.mask, PBMP_ALL(unit)); 3546 } 3547 3548 /* Set entry flags */ 3549 3550 rv = _bcm_field_tcam_part_to_entry_flags(unit, part_index, 3551 fg_p, &entry_p->flags); 3552 3553 if (BCM_FAILURE(rv)) { 3554 sal_free(entries_p); 3555 goto cleanup; 3556 } 3557 3558 if (f_ent_wb_info.color_independent) 3559 { 3560 entry_p->flags |= _FP_ENTRY_COLOR_INDEPENDENT; 3561 } 3562 3563 /* Get index of entry in tcam */ 3564 3565 rv = _bcm_field_entry_part_tcam_idx_get(unit, entries_p, 3566 primary_tcam_index, part_index, &part_tcam_index); 3567 3568 if (BCM_FAILURE(rv)) { 3569 sal_free(entries_p); 3570 goto cleanup; 3571 } 3572 3573 /* Get slice and index within the slice */ 3574 3575 rv = _bcm_field_tcam_idx_to_slice_offset(unit, stage_fc, 3576 _FP_DEF_INST, part_tcam_index, &part_slice_index, 3577 (int *) (&entry_p->slice_idx)); 3578 3579 if (BCM_FAILURE(rv)) { 3580 sal_free(entries_p); 3581 goto cleanup; 3582 } 3583 3584 /* Point the entry to its slice */ 3585 3586 entry_p->fs = stage_fc->slices[_FP_DEF_INST] 3587 + part_slice_index; 3588 --entry_p->fs->free_count; 3589 3590 /* Set the slice pbmp */ 3591 3592 BCM_PBMP_OR(entry_p->fs->pbmp, fg_p->pbmp); 3593 3594 /* Assign entry to slice */ 3595 3596 entry_p->fs->entries[entry_p->slice_idx] = entry_p; 3597 entry_p->flags |= _FP_ENTRY_INSTALLED; 3598 3599 fp_tcam_entry_p = 3600 (fp_tcam_entry_t *) soc_mem_table_idx_to_pointer(unit, 3601 FP_TCAMm, fp_tcam_entry_t *, fp_tcam_buffer, 3602 part_tcam_index); 3603 3604 part_qualifier_p = &(fg_p->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part_index]); 3605 3606 for (group_qualifier_index = 0; 3607 group_qualifier_index < part_qualifier_p->size; 3608 ++group_qualifier_index) 3609 { 3610 qualifier_id = 3611 part_qualifier_p->qid_arr[group_qualifier_index]; 3612 3613 stage_qualifier_p = stage_fc->f_qual_arr[qualifier_id]; 3614 3615 for (config_index = 0; 3616 config_index < stage_qualifier_p->conf_sz; 3617 ++config_index) 3618 { 3619 config_offset_p = &((stage_qualifier_p->conf_arr + 3620 config_index)->offset); 3621 3622 group_qualifier_offset_p = 3623 part_qualifier_p->offset_arr + 3624 group_qualifier_index; 3625 3626 if (_mask_is_set(unit, config_offset_p, 3627 (uint32 *) fp_tcam_entry_p, 3628 stage_fc->stage_id) != 0) 3629 { 3630 config_selector = stage_qualifier_p-> 3631 conf_arr[config_index].selector; 3632 3633 selector = config_selector.pri_sel; 3634 selector_value = config_selector.pri_sel_val; 3635 3636 if ((selector == _bcmFieldSliceSelFpf1 && 3637 selector_value == sel_codes[part_index].fpf1) || 3638 (selector == _bcmFieldSliceSelFpf2 && 3639 selector_value == sel_codes[part_index].fpf2) || 3640 (selector == _bcmFieldSliceSelFpf3 && 3641 selector_value == sel_codes[part_index].fpf3) || 3642 (selector == _bcmFieldSliceSelFpf4 && 3643 selector_value == sel_codes[part_index].fpf4)) 3644 { 3645 /* This qualifier exists in this entry */ 3646 3647 *group_qualifier_offset_p = *config_offset_p; 3648 3649 /* No need to check more configs */ 3650 3651 break; 3652 } 3653 } 3654 } 3655 } 3656 3657 /* Get IP type and mask values. */ 3658 hw_data = soc_FP_TCAMm_field32_get(unit, 3659 fp_tcam_entry_p, IP_TYPEf); 3660 hw_mask = soc_FP_TCAMm_field32_get(unit, 3661 fp_tcam_entry_p, 3662 IP_TYPE_MASKf); 3663 3664 if ((hw_data == 0) && (hw_mask == 0)) { 3665 entry_p->tcam.ip_type = bcmFieldIpTypeAny; 3666 } else if ((hw_data == 0) && (hw_mask == 3)) { 3667 entry_p->tcam.ip_type = bcmFieldIpTypeNonIp; 3668 } else if ((hw_data == 0) && (hw_mask == 1)) { 3669 entry_p->tcam.ip_type = bcmFieldIpTypeIpv4Not; 3670 } else if ((hw_data == 1) && (hw_mask == 3)) { 3671 entry_p->tcam.ip_type = bcmFieldIpTypeIpv4NoOpts; 3672 } else if ((hw_data == 3) && (hw_mask == 3)) { 3673 entry_p->tcam.ip_type = bcmFieldIpTypeIpv4WithOpts; 3674 } else if ((hw_data == 1) && (hw_mask == 1)) { 3675 entry_p->tcam.ip_type = bcmFieldIpTypeIpv4Any; 3676 } else if ((hw_data == 2) && (hw_mask == 3)) { 3677 entry_p->tcam.ip_type = bcmFieldIpTypeIpv6; 3678 } 3679 3680 /* Get the actions for this part of the entry */ 3681 3682 policy_entry_p = soc_mem_table_idx_to_pointer(unit, 3683 FP_POLICY_TABLEm, fp_policy_table_entry_t *, 3684 fp_policy_table_buffer, part_tcam_index); 3685 3686 rv = _field_raven_actions_recover(unit, 3687 policy_entry_p, entries_p, part_index, 3688 &f_ent_wb_info); 3689 3690 if (BCM_FAILURE(rv)) { 3691 sal_free(entries_p); 3692 goto cleanup; 3693 } 3694 3695 if (action_bmp.w != NULL) { 3696 _FP_ACTION_BMP_FREE(action_bmp); 3697 action_bmp.w = NULL; 3698 } 3699 entry_p->prio = fc->l2warm ? f_ent_wb_info.prio : 3700 (vslice_index << 10) | (fs_p->entry_count - entry_index); 3701 } 3702 3703 LOG_DEBUG(BSL_LS_BCM_FP, 3704 (BSL_META_U(unit, 3705 " Entry id = %d, priority = %d.\n"), 3706 entries_p->eid, 3707 entries_p->prio)); 3708 3709 /* Add the entry to the group */ 3710 3711 rv = _field_group_entry_add(unit, fg_p, entries_p); 3712 if (BCM_FAILURE(rv)) { 3713 sal_free(entries_p); 3714 goto cleanup; 3715 } 3716 } 3717 3718 if (fc->l2warm) 3719 { 3720 _field_scache_slice_group_free(unit, fc, slice_index); 3721 } 3722 3723 } 3724 3725 if (fc->l2warm) { 3726 3727 /* Mark end of Slice Info */ 3728 if ((fc->wb_recovered_version) >= BCM_FIELD_WB_VERSION_1_15) { 3729 fc->scache_pos++; 3730 } 3731 3732 /* Group Slice Selectors */ 3733 if ((fc->wb_recovered_version) >= BCM_FIELD_WB_VERSION_1_15) { 3734 rv = _field_group_slice_selectors_recover(unit, 3735 &buf[fc->scache_pos], stage_fc->stage_id); 3736 if (BCM_FAILURE(rv)) { 3737 goto cleanup; 3738 } 3739 } 3740 3741 temp = 0; 3742 temp |= buf[fc->scache_pos]; 3743 fc->scache_pos++; 3744 temp |= buf[fc->scache_pos] << 8; 3745 fc->scache_pos++; 3746 temp |= buf[fc->scache_pos] << 16; 3747 fc->scache_pos++; 3748 temp |= buf[fc->scache_pos] << 24; 3749 fc->scache_pos++; 3750 if (temp != _FIELD_IFP_DATA_END) { 3751 fc->l2warm = 0; 3752 rv = BCM_E_INTERNAL; 3753 } 3754 3755 if (NULL != buf1) { 3756 temp = 0; 3757 temp |= buf1[fc->scache_pos1]; 3758 fc->scache_pos1++; 3759 temp |= buf1[fc->scache_pos1] << 8; 3760 fc->scache_pos1++; 3761 temp |= buf1[fc->scache_pos1] << 16; 3762 fc->scache_pos1++; 3763 temp |= buf1[fc->scache_pos1] << 24; 3764 fc->scache_pos1++; 3765 if (temp != _FIELD_IFP_DATA_END) { 3766 fc->l2warm = 0; 3767 rv = BCM_E_INTERNAL; 3768 } 3769 } 3770 } 3771 3772 if (BCM_SUCCESS(rv)) { 3773 _field_group_slice_vmap_recovery(unit, fc, stage_fc); 3774 } 3775 3776 LOG_DEBUG(BSL_LS_BCM_FP, 3777 (BSL_META_U(unit, 3778 "Ingress stage recovery complete.\n"))); 3779 3780 cleanup: 3781 if (slice_is_expanded_flags != NULL) 3782 { 3783 sal_free(slice_is_expanded_flags); 3784 } 3785 if (slice_master_idx != NULL) 3786 { 3787 sal_free(slice_master_idx); 3788 } 3789 if (fp_tcam_buffer != NULL) 3790 { 3791 soc_cm_sfree(unit, fp_tcam_buffer); 3792 } 3793 if (fp_port_field_sel_buffer != NULL) 3794 { 3795 soc_cm_sfree(unit, fp_port_field_sel_buffer); 3796 } 3797 if (fp_policy_table_buffer != NULL) 3798 { 3799 soc_cm_sfree(unit, fp_policy_table_buffer); 3800 } 3801 if (action_bmp.w != NULL) { 3802 _FP_ACTION_BMP_FREE(action_bmp); 3803 action_bmp.w = NULL; 3804 } 3805 LOG_DEBUG(BSL_LS_BCM_FP, 3806 (BSL_META_U(unit, 3807 "Leaving ingress stage recovery.\n"))); 3808 3809 return rv; 3810 } 3811 #else 3812 #define _field_raven_stage_reinit (NULL) 3813 #endif /* BCM_WARM_BOOT_SUPPORT && BCM_RAVEN_SUPPORT */ 3814 3815 /* 3816 * Function: 3817 * _field_raptor_qualify_ip_type 3818 * Purpose: 3819 * Install ip type qualifier into TCAM 3820 * Parameters: 3821 * unit - (IN) BCM device number 3822 * entry - (IN) Field entry index 3823 * type - (IN) Ip Type. 3824 * qual - (IN) Qualifier(IpType) 3825 * Returns: 3826 * BCM_E_XXX 3827 * Notes: 3828 */ 3829 #define BCM_FIELD_IPTYPE_BAD 0xff 3830 STATIC int 3831 _field_raptor_qualify_ip_type(int unit, bcm_field_entry_t entry, 3832 bcm_field_IpType_t type, 3833 bcm_field_qualify_t qual) 3834 { 3835 _field_group_t *fg; 3836 _field_entry_t *f_ent; 3837 uint32 data = BCM_FIELD_IPTYPE_BAD, 3838 mask = BCM_FIELD_IPTYPE_BAD; 3839 3840 BCM_IF_ERROR_RETURN 3841 (_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent)); 3842 3843 /* Confirm that IpType is in group's Qset. */ 3844 fg = f_ent->group; 3845 if (!BCM_FIELD_QSET_TEST(fg->qset, bcmFieldQualifyIpType)) { 3846 LOG_ERROR(BSL_LS_BCM_FP, 3847 (BSL_META_U(unit, 3848 "FP(unit %d) Error: IpType not in entry=%d Qset.\n"), 3849 unit, f_ent->eid)); 3850 return (BCM_E_PARAM); 3851 } 3852 3853 switch (type) { 3854 case bcmFieldIpTypeAny: 3855 data = 0x0; 3856 mask = 0x0; 3857 break; 3858 case bcmFieldIpTypeNonIp: 3859 data = 0x0; 3860 mask = 0x3; 3861 break; 3862 case bcmFieldIpTypeIpv4Not: 3863 data = 0x0; 3864 mask = 0x1; 3865 break; 3866 case bcmFieldIpTypeIpv4NoOpts: 3867 data = 0x1; 3868 mask = 0x3; 3869 break; 3870 case bcmFieldIpTypeIpv4WithOpts: 3871 data = 0x3; 3872 mask = 0x3; 3873 break; 3874 case bcmFieldIpTypeIpv4Any: 3875 data = 0x1; 3876 mask = 0x1; 3877 break; 3878 case bcmFieldIpTypeIpv6: 3879 data = 0x2; 3880 mask = 0x3; 3881 break; 3882 default: 3883 break; 3884 } 3885 3886 if ((data == BCM_FIELD_IPTYPE_BAD) || 3887 (mask == BCM_FIELD_IPTYPE_BAD)) { 3888 return (BCM_E_UNAVAIL); 3889 } 3890 3891 BCM_IF_ERROR_RETURN 3892 (_bcm_field_entry_qual_get(unit, f_ent->eid, 3893 bcmFieldQualifyIpType, &f_ent)); 3894 3895 /* Add data & mask to entry. */ 3896 f_ent->tcam.ip_type = type; 3897 f_ent->flags |= _FP_ENTRY_DIRTY; 3898 3899 return (BCM_E_NONE); 3900 } 3901 #undef BCM_FIELD_IPTYPE_BAD 3902 /* 3903 * Function: 3904 * _bcm_field_raptor_qualify_ip_type_get 3905 * Purpose: 3906 * Read ip type qualifier match criteria from the HW. 3907 * Parameters: 3908 * unit - (IN) BCM device number 3909 * entry - (IN) Field entry index 3910 * type - (OUT) Ip Type. 3911 * qual - (IN) Qualifier(IpType) 3912 * Returns: 3913 * BCM_E_XXX 3914 * Notes: 3915 */ 3916 int 3917 _bcm_field_raptor_qualify_ip_type_get(int unit, bcm_field_entry_t entry, 3918 bcm_field_IpType_t *type, 3919 bcm_field_qualify_t qual) 3920 { 3921 _field_entry_t *f_ent; 3922 3923 /* Input parameters checks. */ 3924 if ((NULL == type)) { 3925 return (BCM_E_PARAM); 3926 } 3927 3928 BCM_IF_ERROR_RETURN 3929 (_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent)); 3930 3931 *type = f_ent->tcam.ip_type; 3932 return (BCM_E_NONE); 3933 } 3934 /* 3935 * Function: 3936 * _field_raptor_action_support_check 3937 * 3938 * Purpose: 3939 * Check if action is supported by device. 3940 * 3941 * Parameters: 3942 * unit -(IN)BCM device number 3943 * f_ent -(IN)Field entry structure. 3944 * action -(IN) Action to check(bcmFieldActionXXX) 3945 * result -(OUT) 3946 * TRUE - action is supported by device 3947 * FALSE - action is NOT supported by device 3948 * 3949 * Returns: 3950 * BCM_E_XXX 3951 */ 3952 STATIC int 3953 _field_raptor_action_support_check(int unit, _field_entry_t *f_ent, 3954 bcm_field_action_t action, int *result) 3955 { 3956 /* Input parameters check */ 3957 if ((NULL == f_ent) || (NULL == result)) { 3958 return (BCM_E_PARAM); 3959 } 3960 3961 switch (action) { 3962 case bcmFieldActionCosQNew: 3963 case bcmFieldActionCosQCpuNew: 3964 case bcmFieldActionPrioPktAndIntCopy: 3965 case bcmFieldActionPrioPktAndIntNew: 3966 case bcmFieldActionPrioPktAndIntTos: 3967 case bcmFieldActionPrioPktAndIntCancel: 3968 case bcmFieldActionPrioPktCopy: 3969 case bcmFieldActionPrioPktNew: 3970 case bcmFieldActionPrioPktTos: 3971 case bcmFieldActionPrioPktCancel: 3972 case bcmFieldActionPrioIntCopy: 3973 case bcmFieldActionPrioIntNew: 3974 case bcmFieldActionPrioIntTos: 3975 case bcmFieldActionPrioIntCancel: 3976 case bcmFieldActionTosNew: 3977 case bcmFieldActionTosCopy: 3978 case bcmFieldActionTosCancel: 3979 case bcmFieldActionDscpNew: 3980 case bcmFieldActionDscpCancel: 3981 case bcmFieldActionCopyToCpu: 3982 case bcmFieldActionCopyToCpuCancel: 3983 case bcmFieldActionSwitchToCpuCancel: 3984 case bcmFieldActionRedirect: 3985 case bcmFieldActionRedirectTrunk: 3986 case bcmFieldActionRedirectCancel: 3987 case bcmFieldActionRedirectPbmp: 3988 case bcmFieldActionEgressMask: 3989 case bcmFieldActionDrop: 3990 case bcmFieldActionDropCancel: 3991 case bcmFieldActionMirrorOverride: 3992 case bcmFieldActionMirrorIngress: 3993 case bcmFieldActionMirrorEgress: 3994 case bcmFieldActionL3ChangeVlan: 3995 case bcmFieldActionL3ChangeVlanCancel: 3996 case bcmFieldActionL3ChangeMacDa: 3997 case bcmFieldActionL3ChangeMacDaCancel: 3998 case bcmFieldActionL3Switch: 3999 case bcmFieldActionL3SwitchCancel: 4000 case bcmFieldActionAddClassTag: 4001 case bcmFieldActionEcnNew: 4002 case bcmFieldActionDropPrecedence: 4003 case bcmFieldActionRpDrop: 4004 case bcmFieldActionRpDropCancel: 4005 case bcmFieldActionRpDropPrecedence: 4006 case bcmFieldActionRpCopyToCpu: 4007 case bcmFieldActionRpCopyToCpuCancel: 4008 case bcmFieldActionRpDscpNew: 4009 case bcmFieldActionYpDrop: 4010 case bcmFieldActionYpDropCancel: 4011 case bcmFieldActionYpDropPrecedence: 4012 case bcmFieldActionYpCopyToCpu: 4013 case bcmFieldActionYpCopyToCpuCancel: 4014 case bcmFieldActionYpDscpNew: 4015 case bcmFieldActionGpDrop: 4016 case bcmFieldActionGpDropCancel: 4017 case bcmFieldActionGpDropPrecedence: 4018 case bcmFieldActionGpCopyToCpu: 4019 case bcmFieldActionGpCopyToCpuCancel: 4020 case bcmFieldActionGpDscpNew: 4021 case bcmFieldActionColorIndependent: 4022 *result = TRUE; 4023 break; 4024 case bcmFieldActionGpCosQNew: 4025 case bcmFieldActionGpPrioPktAndIntCopy: 4026 case bcmFieldActionGpPrioPktAndIntNew: 4027 case bcmFieldActionGpPrioPktAndIntTos: 4028 case bcmFieldActionGpPrioPktAndIntCancel: 4029 case bcmFieldActionGpPrioPktCopy: 4030 case bcmFieldActionGpPrioPktNew: 4031 case bcmFieldActionGpPrioPktTos: 4032 case bcmFieldActionGpPrioPktCancel: 4033 case bcmFieldActionGpPrioIntCopy: 4034 case bcmFieldActionGpPrioIntNew: 4035 case bcmFieldActionGpPrioIntTos: 4036 case bcmFieldActionGpPrioIntCancel: 4037 case bcmFieldActionRpCosQNew: 4038 case bcmFieldActionRpPrioPktAndIntCopy: 4039 case bcmFieldActionRpPrioPktAndIntNew: 4040 case bcmFieldActionRpPrioPktAndIntTos: 4041 case bcmFieldActionRpPrioPktAndIntCancel: 4042 case bcmFieldActionRpPrioPktCopy: 4043 case bcmFieldActionRpPrioPktNew: 4044 case bcmFieldActionRpPrioPktTos: 4045 case bcmFieldActionRpPrioPktCancel: 4046 case bcmFieldActionRpPrioIntCopy: 4047 case bcmFieldActionRpPrioIntNew: 4048 case bcmFieldActionRpPrioIntTos: 4049 case bcmFieldActionRpPrioIntCancel: 4050 case bcmFieldActionYpCosQNew: 4051 case bcmFieldActionYpPrioPktAndIntCopy: 4052 case bcmFieldActionYpPrioPktAndIntNew: 4053 case bcmFieldActionYpPrioPktAndIntTos: 4054 case bcmFieldActionYpPrioPktAndIntCancel: 4055 case bcmFieldActionYpPrioPktCopy: 4056 case bcmFieldActionYpPrioPktNew: 4057 case bcmFieldActionYpPrioPktTos: 4058 case bcmFieldActionYpPrioPktCancel: 4059 case bcmFieldActionYpPrioIntCopy: 4060 case bcmFieldActionYpPrioIntNew: 4061 case bcmFieldActionYpPrioIntTos: 4062 case bcmFieldActionYpPrioIntCancel: 4063 *result = (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) ? TRUE : FALSE; 4064 break; 4065 default: 4066 *result = FALSE; 4067 } 4068 return (BCM_E_NONE); 4069 } 4070 4071 /* 4072 * Function: 4073 * _field_raptor_action_conflict_check 4074 * 4075 * Purpose: 4076 * Check if two action conflict (occupy the same field in FP policy table) 4077 * 4078 * Parameters: 4079 * unit -(IN)BCM device number 4080 * f_ent -(IN)Field entry structure. 4081 * action -(IN) Action to check(bcmFieldActionXXX) 4082 * action1 -(IN) Action to check(bcmFieldActionXXX) 4083 * 4084 * Returns: 4085 * BCM_E_CONFIG - if actions do conflict 4086 * BCM_E_NONE - if there is no conflict 4087 */ 4088 STATIC int 4089 _field_raptor_action_conflict_check(int unit, _field_entry_t *f_ent, 4090 bcm_field_action_t action1, 4091 bcm_field_action_t action) 4092 { 4093 /* Input parameters check */ 4094 if (NULL == f_ent) { 4095 return (BCM_E_PARAM); 4096 } 4097 4098 /* Two identical actions are forbidden. */ 4099 _FP_ACTIONS_CONFLICT(action1); 4100 4101 switch (action1) { 4102 case bcmFieldActionCosQNew: 4103 case bcmFieldActionCosQCpuNew: 4104 case bcmFieldActionPrioPktAndIntCopy: 4105 case bcmFieldActionPrioPktAndIntNew: 4106 case bcmFieldActionPrioPktAndIntTos: 4107 case bcmFieldActionPrioPktAndIntCancel: 4108 case bcmFieldActionPrioPktCopy: 4109 case bcmFieldActionPrioPktNew: 4110 case bcmFieldActionPrioPktTos: 4111 case bcmFieldActionPrioPktCancel: 4112 case bcmFieldActionPrioIntCopy: 4113 case bcmFieldActionPrioIntNew: 4114 case bcmFieldActionPrioIntTos: 4115 case bcmFieldActionPrioIntCancel: 4116 _FP_ACTIONS_CONFLICT(bcmFieldActionCosQNew); 4117 _FP_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew); 4118 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy); 4119 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew); 4120 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos); 4121 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel); 4122 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy); 4123 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew); 4124 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos); 4125 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel); 4126 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy); 4127 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew); 4128 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos); 4129 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel); 4130 _FP_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew); 4131 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCopy); 4132 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntNew); 4133 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntTos); 4134 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCancel); 4135 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCopy); 4136 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktNew); 4137 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktTos); 4138 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCancel); 4139 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy); 4140 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew); 4141 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos); 4142 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel); 4143 _FP_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew); 4144 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCopy); 4145 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntNew); 4146 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntTos); 4147 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCancel); 4148 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCopy); 4149 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktNew); 4150 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktTos); 4151 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCancel); 4152 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy); 4153 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew); 4154 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos); 4155 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel); 4156 _FP_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew); 4157 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCopy); 4158 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntNew); 4159 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntTos); 4160 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCancel); 4161 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCopy); 4162 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktNew); 4163 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktTos); 4164 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCancel); 4165 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy); 4166 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew); 4167 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos); 4168 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel); 4169 break; 4170 case bcmFieldActionRpCosQNew: 4171 case bcmFieldActionRpPrioPktAndIntCopy: 4172 case bcmFieldActionRpPrioPktAndIntNew: 4173 case bcmFieldActionRpPrioPktAndIntTos: 4174 case bcmFieldActionRpPrioPktAndIntCancel: 4175 case bcmFieldActionRpPrioPktCopy: 4176 case bcmFieldActionRpPrioPktNew: 4177 case bcmFieldActionRpPrioPktTos: 4178 case bcmFieldActionRpPrioPktCancel: 4179 case bcmFieldActionRpPrioIntCopy: 4180 case bcmFieldActionRpPrioIntNew: 4181 case bcmFieldActionRpPrioIntTos: 4182 case bcmFieldActionRpPrioIntCancel: 4183 _FP_ACTIONS_CONFLICT(bcmFieldActionCosQNew); 4184 _FP_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew); 4185 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy); 4186 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew); 4187 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos); 4188 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel); 4189 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy); 4190 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew); 4191 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos); 4192 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel); 4193 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy); 4194 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew); 4195 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos); 4196 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel); 4197 _FP_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew); 4198 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCopy); 4199 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntNew); 4200 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntTos); 4201 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCancel); 4202 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCopy); 4203 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktNew); 4204 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktTos); 4205 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCancel); 4206 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy); 4207 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew); 4208 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos); 4209 _FP_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel); 4210 break; 4211 case bcmFieldActionYpCosQNew: 4212 case bcmFieldActionYpPrioPktAndIntCopy: 4213 case bcmFieldActionYpPrioPktAndIntNew: 4214 case bcmFieldActionYpPrioPktAndIntTos: 4215 case bcmFieldActionYpPrioPktAndIntCancel: 4216 case bcmFieldActionYpPrioPktCopy: 4217 case bcmFieldActionYpPrioPktNew: 4218 case bcmFieldActionYpPrioPktTos: 4219 case bcmFieldActionYpPrioPktCancel: 4220 case bcmFieldActionYpPrioIntCopy: 4221 case bcmFieldActionYpPrioIntNew: 4222 case bcmFieldActionYpPrioIntTos: 4223 case bcmFieldActionYpPrioIntCancel: 4224 _FP_ACTIONS_CONFLICT(bcmFieldActionCosQNew); 4225 _FP_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew); 4226 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy); 4227 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew); 4228 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos); 4229 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel); 4230 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy); 4231 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew); 4232 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos); 4233 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel); 4234 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy); 4235 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew); 4236 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos); 4237 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel); 4238 _FP_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew); 4239 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCopy); 4240 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntNew); 4241 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntTos); 4242 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCancel); 4243 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCopy); 4244 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktNew); 4245 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktTos); 4246 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCancel); 4247 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy); 4248 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew); 4249 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos); 4250 _FP_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel); 4251 break; 4252 case bcmFieldActionGpCosQNew: 4253 case bcmFieldActionGpPrioPktAndIntCopy: 4254 case bcmFieldActionGpPrioPktAndIntNew: 4255 case bcmFieldActionGpPrioPktAndIntTos: 4256 case bcmFieldActionGpPrioPktAndIntCancel: 4257 case bcmFieldActionGpPrioPktCopy: 4258 case bcmFieldActionGpPrioPktNew: 4259 case bcmFieldActionGpPrioPktTos: 4260 case bcmFieldActionGpPrioPktCancel: 4261 case bcmFieldActionGpPrioIntCopy: 4262 case bcmFieldActionGpPrioIntNew: 4263 case bcmFieldActionGpPrioIntTos: 4264 case bcmFieldActionGpPrioIntCancel: 4265 _FP_ACTIONS_CONFLICT(bcmFieldActionCosQNew); 4266 _FP_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew); 4267 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy); 4268 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew); 4269 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos); 4270 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel); 4271 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy); 4272 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew); 4273 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos); 4274 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel); 4275 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy); 4276 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew); 4277 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos); 4278 _FP_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel); 4279 _FP_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew); 4280 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCopy); 4281 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntNew); 4282 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntTos); 4283 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCancel); 4284 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCopy); 4285 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktNew); 4286 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktTos); 4287 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCancel); 4288 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy); 4289 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew); 4290 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos); 4291 _FP_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel); 4292 break; 4293 case bcmFieldActionTosNew: 4294 case bcmFieldActionTosCopy: 4295 case bcmFieldActionTosCancel: 4296 _FP_ACTIONS_CONFLICT(bcmFieldActionTosNew); 4297 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCopy); 4298 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCancel); 4299 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpNew); 4300 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpCancel); 4301 _FP_ACTIONS_CONFLICT(bcmFieldActionRpDscpNew); 4302 _FP_ACTIONS_CONFLICT(bcmFieldActionYpDscpNew); 4303 _FP_ACTIONS_CONFLICT(bcmFieldActionGpDscpNew); 4304 _FP_ACTIONS_CONFLICT(bcmFieldActionEcnNew); 4305 break; 4306 case bcmFieldActionDscpNew: 4307 case bcmFieldActionDscpCancel: 4308 _FP_ACTIONS_CONFLICT(bcmFieldActionTosNew); 4309 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCopy); 4310 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCancel); 4311 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpNew); 4312 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpCancel); 4313 _FP_ACTIONS_CONFLICT(bcmFieldActionRpDscpNew); 4314 _FP_ACTIONS_CONFLICT(bcmFieldActionYpDscpNew); 4315 _FP_ACTIONS_CONFLICT(bcmFieldActionGpDscpNew); 4316 break; 4317 case bcmFieldActionRpDscpNew: 4318 _FP_ACTIONS_CONFLICT(bcmFieldActionTosNew); 4319 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCopy); 4320 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCancel); 4321 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpNew); 4322 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpCancel); 4323 _FP_ACTIONS_CONFLICT(bcmFieldActionRpDscpNew); 4324 break; 4325 case bcmFieldActionYpDscpNew: 4326 _FP_ACTIONS_CONFLICT(bcmFieldActionTosNew); 4327 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCopy); 4328 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCancel); 4329 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpNew); 4330 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpCancel); 4331 _FP_ACTIONS_CONFLICT(bcmFieldActionYpDscpNew); 4332 break; 4333 case bcmFieldActionGpDscpNew: 4334 _FP_ACTIONS_CONFLICT(bcmFieldActionTosNew); 4335 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCopy); 4336 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCancel); 4337 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpNew); 4338 _FP_ACTIONS_CONFLICT(bcmFieldActionDscpCancel); 4339 _FP_ACTIONS_CONFLICT(bcmFieldActionGpDscpNew); 4340 break; 4341 case bcmFieldActionEcnNew: 4342 _FP_ACTIONS_CONFLICT(bcmFieldActionTosNew); 4343 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCopy); 4344 _FP_ACTIONS_CONFLICT(bcmFieldActionTosCancel); 4345 break; 4346 4347 case bcmFieldActionCopyToCpu: 4348 case bcmFieldActionCopyToCpuCancel: 4349 case bcmFieldActionSwitchToCpuCancel: 4350 _FP_ACTIONS_CONFLICT(bcmFieldActionCopyToCpu); 4351 _FP_ACTIONS_CONFLICT(bcmFieldActionCopyToCpuCancel); 4352 _FP_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuCancel); 4353 _FP_ACTIONS_CONFLICT(bcmFieldActionRpCopyToCpu); 4354 _FP_ACTIONS_CONFLICT(bcmFieldActionRpCopyToCpuCancel); 4355 _FP_ACTIONS_CONFLICT(bcmFieldActionYpCopyToCpu); 4356 _FP_ACTIONS_CONFLICT(bcmFieldActionYpCopyToCpuCancel); 4357 _FP_ACTIONS_CONFLICT(bcmFieldActionGpCopyToCpu); 4358 _FP_ACTIONS_CONFLICT(bcmFieldActionGpCopyToCpuCancel); 4359 break; 4360 case bcmFieldActionRpCopyToCpu: 4361 case bcmFieldActionRpCopyToCpuCancel: 4362 _FP_ACTIONS_CONFLICT(bcmFieldActionCopyToCpu); 4363 _FP_ACTIONS_CONFLICT(bcmFieldActionCopyToCpuCancel); 4364 _FP_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuCancel); 4365 _FP_ACTIONS_CONFLICT(bcmFieldActionRpCopyToCpu); 4366 _FP_ACTIONS_CONFLICT(bcmFieldActionRpCopyToCpuCancel); 4367 break; 4368 case bcmFieldActionYpCopyToCpu: 4369 case bcmFieldActionYpCopyToCpuCancel: 4370 _FP_ACTIONS_CONFLICT(bcmFieldActionCopyToCpu); 4371 _FP_ACTIONS_CONFLICT(bcmFieldActionCopyToCpuCancel); 4372 _FP_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuCancel); 4373 _FP_ACTIONS_CONFLICT(bcmFieldActionYpCopyToCpu); 4374 _FP_ACTIONS_CONFLICT(bcmFieldActionYpCopyToCpuCancel); 4375 break; 4376 case bcmFieldActionGpCopyToCpu: 4377 case bcmFieldActionGpCopyToCpuCancel: 4378 _FP_ACTIONS_CONFLICT(bcmFieldActionCopyToCpu); 4379 _FP_ACTIONS_CONFLICT(bcmFieldActionCopyToCpuCancel); 4380 _FP_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuCancel); 4381 _FP_ACTIONS_CONFLICT(bcmFieldActionGpCopyToCpu); 4382 _FP_ACTIONS_CONFLICT(bcmFieldActionGpCopyToCpuCancel); 4383 break; 4384 case bcmFieldActionDropPrecedence: 4385 _FP_ACTIONS_CONFLICT(bcmFieldActionRpDropPrecedence); 4386 _FP_ACTIONS_CONFLICT(bcmFieldActionYpDropPrecedence); 4387 _FP_ACTIONS_CONFLICT(bcmFieldActionGpDropPrecedence); 4388 break; 4389 case bcmFieldActionRpDropPrecedence: 4390 _FP_ACTIONS_CONFLICT(bcmFieldActionDropPrecedence); 4391 break; 4392 case bcmFieldActionYpDropPrecedence: 4393 _FP_ACTIONS_CONFLICT(bcmFieldActionDropPrecedence); 4394 break; 4395 case bcmFieldActionGpDropPrecedence: 4396 _FP_ACTIONS_CONFLICT(bcmFieldActionDropPrecedence); 4397 break; 4398 case bcmFieldActionRedirect: 4399 case bcmFieldActionRedirectTrunk: 4400 case bcmFieldActionRedirectCancel: 4401 case bcmFieldActionRedirectPbmp: 4402 case bcmFieldActionEgressMask: 4403 _FP_ACTIONS_CONFLICT(bcmFieldActionRedirect); 4404 _FP_ACTIONS_CONFLICT(bcmFieldActionRedirectTrunk); 4405 _FP_ACTIONS_CONFLICT(bcmFieldActionRedirectCancel); 4406 _FP_ACTIONS_CONFLICT(bcmFieldActionRedirectPbmp); 4407 _FP_ACTIONS_CONFLICT(bcmFieldActionEgressMask); 4408 break; 4409 case bcmFieldActionDrop: 4410 case bcmFieldActionDropCancel: 4411 _FP_ACTIONS_CONFLICT(bcmFieldActionDrop); 4412 _FP_ACTIONS_CONFLICT(bcmFieldActionDropCancel); 4413 _FP_ACTIONS_CONFLICT(bcmFieldActionRpDrop); 4414 _FP_ACTIONS_CONFLICT(bcmFieldActionRpDropCancel); 4415 _FP_ACTIONS_CONFLICT(bcmFieldActionYpDrop); 4416 _FP_ACTIONS_CONFLICT(bcmFieldActionYpDropCancel); 4417 _FP_ACTIONS_CONFLICT(bcmFieldActionGpDrop); 4418 _FP_ACTIONS_CONFLICT(bcmFieldActionGpDropCancel); 4419 break; 4420 case bcmFieldActionRpDrop: 4421 case bcmFieldActionRpDropCancel: 4422 _FP_ACTIONS_CONFLICT(bcmFieldActionDrop); 4423 _FP_ACTIONS_CONFLICT(bcmFieldActionDropCancel); 4424 _FP_ACTIONS_CONFLICT(bcmFieldActionRpDrop); 4425 _FP_ACTIONS_CONFLICT(bcmFieldActionRpDropCancel); 4426 break; 4427 case bcmFieldActionYpDrop: 4428 case bcmFieldActionYpDropCancel: 4429 _FP_ACTIONS_CONFLICT(bcmFieldActionDrop); 4430 _FP_ACTIONS_CONFLICT(bcmFieldActionDropCancel); 4431 _FP_ACTIONS_CONFLICT(bcmFieldActionYpDrop); 4432 _FP_ACTIONS_CONFLICT(bcmFieldActionYpDropCancel); 4433 break; 4434 case bcmFieldActionGpDrop: 4435 case bcmFieldActionGpDropCancel: 4436 _FP_ACTIONS_CONFLICT(bcmFieldActionDrop); 4437 _FP_ACTIONS_CONFLICT(bcmFieldActionDropCancel); 4438 _FP_ACTIONS_CONFLICT(bcmFieldActionGpDrop); 4439 _FP_ACTIONS_CONFLICT(bcmFieldActionGpDropCancel); 4440 break; 4441 case bcmFieldActionMirrorIngress: 4442 _FP_ACTIONS_CONFLICT(bcmFieldActionMirrorOverride); 4443 break; 4444 case bcmFieldActionMirrorEgress: 4445 _FP_ACTIONS_CONFLICT(bcmFieldActionMirrorOverride); 4446 break; 4447 case bcmFieldActionMirrorOverride: 4448 _FP_ACTIONS_CONFLICT(bcmFieldActionMirrorIngress); 4449 _FP_ACTIONS_CONFLICT(bcmFieldActionMirrorEgress); 4450 break; 4451 case bcmFieldActionL3ChangeVlan: 4452 case bcmFieldActionL3ChangeVlanCancel: 4453 case bcmFieldActionL3ChangeMacDa: 4454 case bcmFieldActionL3ChangeMacDaCancel: 4455 case bcmFieldActionL3Switch: 4456 case bcmFieldActionL3SwitchCancel: 4457 case bcmFieldActionAddClassTag: 4458 _FP_ACTIONS_CONFLICT(bcmFieldActionAddClassTag); 4459 _FP_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlan); 4460 _FP_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlanCancel); 4461 _FP_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDa); 4462 _FP_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDaCancel); 4463 _FP_ACTIONS_CONFLICT(bcmFieldActionL3Switch); 4464 _FP_ACTIONS_CONFLICT(bcmFieldActionL3SwitchCancel); 4465 break; 4466 case bcmFieldActionColorIndependent: 4467 break; 4468 default: 4469 break; 4470 } 4471 return (BCM_E_NONE); 4472 } 4473 4474 /* 4475 * Function: 4476 * _field_raptor_functions_init 4477 * Purpose: 4478 * Set up functions pointers 4479 * Parameters: 4480 * functions - pointers to device specific functions 4481 * Returns: 4482 * nothing 4483 * Notes: 4484 * Some function pointers point to functions in ../firebolt/field.c 4485 */ 4486 STATIC void 4487 _field_raptor_functions_init(_field_funct_t *functions) 4488 { 4489 functions->fp_detach = _field_raptor_detach; 4490 functions->fp_group_install = _field_raptor_group_install; 4491 functions->fp_selcodes_install = _field_raptor_selcodes_install; 4492 functions->fp_slice_clear = _bcm_field_fb_slice_clear; 4493 functions->fp_entry_remove = _field_raptor_entry_remove; 4494 functions->fp_entry_move = _field_raptor_entry_move; 4495 functions->fp_selcode_get = _bcm_field_selcode_get; 4496 functions->fp_selcode_to_qset = _bcm_field_selcode_to_qset; 4497 functions->fp_qual_list_get = _bcm_field_qual_lists_get; 4498 functions->fp_tcam_policy_clear = _field_raptor_tables_entry_clear; 4499 functions->fp_tcam_policy_install = _field_raptor_entry_install; 4500 functions->fp_tcam_policy_reinstall = _field_raptor_entry_reinstall; 4501 functions->fp_action_params_check = _field_raptor_action_params_check; 4502 functions->fp_policer_install = _bcm_field_fb_policer_install; 4503 functions->fp_write_slice_map = _bcm_field_fb_write_slice_map; 4504 functions->fp_qualify_ip_type = _field_raptor_qualify_ip_type; 4505 functions->fp_qualify_ip_type_get = _bcm_field_raptor_qualify_ip_type_get; 4506 functions->fp_action_support_check = _field_raptor_action_support_check; 4507 functions->fp_action_conflict_check = _field_raptor_action_conflict_check; 4508 functions->fp_counter_get = _bcm_field_fb_counter_get; 4509 functions->fp_counter_set = _bcm_field_fb_counter_set; 4510 functions->fp_stat_index_get = _bcm_field_fb_stat_index_get; 4511 functions->fp_egress_key_match_type_set = NULL; 4512 functions->fp_external_entry_install = NULL; 4513 functions->fp_external_entry_reinstall = NULL; 4514 functions->fp_external_entry_remove = NULL; 4515 functions->fp_external_entry_prio_set = NULL; 4516 functions->fp_data_qualifier_ethertype_add = 4517 _bcm_field_fb_data_qualifier_ethertype_add; 4518 functions->fp_data_qualifier_ethertype_delete= 4519 _bcm_field_fb_data_qualifier_ethertype_delete; 4520 functions->fp_data_qualifier_ip_protocol_add = 4521 _bcm_field_fb_data_qualifier_ip_protocol_add; 4522 functions->fp_data_qualifier_ip_protocol_delete= 4523 _bcm_field_fb_data_qualifier_ip_protocol_delete; 4524 functions->fp_data_qualifier_packet_format_add= 4525 _bcm_field_fb_data_qualifier_packet_format_add; 4526 functions->fp_data_qualifier_packet_format_delete= 4527 _bcm_field_fb_data_qualifier_packet_format_delete; 4528 functions->fp_stat_value_get = NULL; 4529 functions->fp_stat_value_set = NULL; 4530 functions->fp_control_set = _bcm_field_control_set; 4531 functions->fp_control_get = _bcm_field_control_get; 4532 functions->fp_stat_hw_mode_get = _bcm_field_stat_hw_mode_get; 4533 functions->fp_stat_hw_alloc = _bcm_field_stat_hw_alloc; 4534 functions->fp_stat_hw_free = _bcm_field_stat_hw_free; 4535 functions->fp_group_add = NULL; 4536 functions->fp_qualify_trunk = _bcm_field_qualify_trunk; 4537 functions->fp_qualify_trunk_get = _bcm_field_qualify_trunk_get; 4538 functions->fp_qualify_inports = _bcm_field_qualify_InPorts; 4539 functions->fp_entry_stat_extended_attach = NULL; 4540 functions->fp_entry_stat_extended_get = NULL; 4541 functions->fp_entry_stat_detach = _bcm_field_entry_stat_detach; 4542 functions->fp_class_size_get = NULL; 4543 functions->fp_qualify_packet_res = _field_qualify_PacketRes; 4544 functions->fp_qualify_packet_res_get = _field_qualify_PacketRes_get; 4545 } 4546 4547 /* 4548 * Function: 4549 * _field_raptor_detach 4550 * Purpose: 4551 * Deallocates field tables. 4552 * Parameters: 4553 * unit - (IN) BCM device number 4554 * fc - (IN) Control Structure 4555 * Returns: 4556 * BCM_E_NONE 4557 * Notes: 4558 */ 4559 STATIC int 4560 _field_raptor_detach(int unit, _field_control_t *fc) 4561 { 4562 _field_stage_t *stage_p; /* Stage iteration pointer. */ 4563 4564 if (NULL == fc) { 4565 return BCM_E_PARAM; 4566 } 4567 stage_p = fc->stages; 4568 4569 if (NULL == stage_p || 4570 _BCM_FIELD_STAGE_INGRESS != stage_p->stage_id) { 4571 return BCM_E_PARAM; 4572 } 4573 4574 /* Clear the hardware tables */ 4575 BCM_IF_ERROR_RETURN(_field_raptor_hw_clear(unit, stage_p)); 4576 4577 /* Don't disable port controls during Warmboot or Reloading state */ 4578 if (0 == SOC_HW_ACCESS_DISABLE(unit)) { 4579 /* Clear the Filter Enable flags in the port table */ 4580 BCM_IF_ERROR_RETURN 4581 (_field_port_filter_enable_set(unit, fc, FALSE)); 4582 } 4583 4584 /* Disable field meter refreshing */ 4585 return (_field_meter_refresh_enable_set(unit, fc, FALSE)); 4586 } 4587 4588 /* 4589 * Function: 4590 * _field_raptor_group_install 4591 * Purpose: 4592 * Writes the Group's mode and field select codes into hardware. This 4593 * should be called both at group creation time and any time the select 4594 * codes change (i.e. bcm_field_group_set calls). 4595 * Parameters: 4596 * unit - BCM device number 4597 * fg - group to install 4598 * Returns: 4599 * BCM_E_INTERNAL - On read/write errors 4600 * BCM_E_NONE - Success 4601 * Note: 4602 * Unit lock should be held by calling function. 4603 * Uses function common to firebolt: _bcm_field_fb_mode_install 4604 */ 4605 STATIC int 4606 _field_raptor_group_install(int unit, _field_group_t *fg) 4607 { 4608 assert(fg != NULL); 4609 4610 if (fg->flags & _FP_GROUP_INTRASLICE_DOUBLEWIDE) { 4611 return (BCM_E_INTERNAL); 4612 } 4613 4614 /* Write the field select codes*/ 4615 if (fg->flags & _FP_GROUP_SPAN_TRIPLE_SLICE) { 4616 BCM_IF_ERROR_RETURN 4617 (_field_raptor_selcodes_install(unit, fg, 4618 fg->slices[2].slice_number, 4619 fg->pbmp, 2)); 4620 } 4621 4622 if ((fg->flags & _FP_GROUP_SPAN_DOUBLE_SLICE) || 4623 (fg->flags & _FP_GROUP_SPAN_TRIPLE_SLICE)) { 4624 BCM_IF_ERROR_RETURN 4625 (_field_raptor_selcodes_install(unit, fg, 4626 fg->slices[1].slice_number, 4627 fg->pbmp, 1)); 4628 } 4629 BCM_IF_ERROR_RETURN 4630 (_field_raptor_selcodes_install(unit, fg, 4631 fg->slices[0].slice_number, 4632 fg->pbmp, 0)); 4633 4634 return BCM_E_NONE; 4635 } 4636 4637 /* 4638 * Function: 4639 * _field_raptor_selcodes_install 4640 * Purpose: 4641 * Writes the field select codes (ie. FPFx). 4642 * Parameters: 4643 * unit - BCM device number 4644 * fs - slice that needs its select codes written 4645 * Returns: 4646 * BCM_E_INTERNAL - On read/write errors 4647 * BCM_E_NONE - Success 4648 * Note: 4649 * Unit lock should be held by calling function. 4650 */ 4651 STATIC int 4652 _field_raptor_selcodes_install(int unit, _field_group_t *fg, 4653 uint8 slice_numb, bcm_pbmp_t pbmp, 4654 int selcode_index) 4655 { 4656 bcm_port_t port; 4657 fp_port_field_sel_entry_t pfs_entry; 4658 bcm_pbmp_t all_pbmp; 4659 #if defined(BCM_RAVEN_SUPPORT) 4660 static int field_tbl[16][4] = { 4661 {SLICE0_F1f, SLICE0_F2f, SLICE0_F3f, SLICE0_F4f}, 4662 {SLICE1_F1f, SLICE1_F2f, SLICE1_F3f, SLICE1_F4f}, 4663 {SLICE2_F1f, SLICE2_F2f, SLICE2_F3f, SLICE2_F4f}, 4664 {SLICE3_F1f, SLICE3_F2f, SLICE3_F3f, SLICE3_F4f}, 4665 {SLICE4_F1f, SLICE4_F2f, SLICE4_F3f, SLICE4_F4f}, 4666 {SLICE5_F1f, SLICE5_F2f, SLICE5_F3f, SLICE5_F4f}, 4667 {SLICE6_F1f, SLICE6_F2f, SLICE6_F3f, SLICE6_F4f}, 4668 {SLICE7_F1f, SLICE7_F2f, SLICE7_F3f, SLICE7_F4f}, 4669 {SLICE8_F1f, SLICE8_F2f, SLICE8_F3f, SLICE8_F4f}, 4670 {SLICE9_F1f, SLICE9_F2f, SLICE9_F3f, SLICE9_F4f}, 4671 {SLICE10_F1f, SLICE10_F2f, SLICE10_F3f, SLICE10_F4f}, 4672 {SLICE11_F1f, SLICE11_F2f, SLICE11_F3f, SLICE11_F4f}, 4673 {SLICE12_F1f, SLICE12_F2f, SLICE12_F3f, SLICE12_F4f}, 4674 {SLICE13_F1f, SLICE13_F2f, SLICE13_F3f, SLICE13_F4f}, 4675 {SLICE14_F1f, SLICE14_F2f, SLICE14_F3f, SLICE14_F4f}, 4676 {SLICE15_F1f, SLICE15_F2f, SLICE15_F3f, SLICE15_F4f}}; 4677 #else /* BCM_RAVEN_SUPPORT */ 4678 static int field_tbl[8][4] = { 4679 {SLICE0_F1f, SLICE0_F2f, SLICE0_F3f, SLICE0_F4f}, 4680 {SLICE1_F1f, SLICE1_F2f, SLICE1_F3f, SLICE1_F4f}, 4681 {SLICE2_F1f, SLICE2_F2f, SLICE2_F3f, SLICE2_F4f}, 4682 {SLICE3_F1f, SLICE3_F2f, SLICE3_F3f, SLICE3_F4f}, 4683 {SLICE4_F1f, SLICE4_F2f, SLICE4_F3f, SLICE4_F4f}, 4684 {SLICE5_F1f, SLICE5_F2f, SLICE5_F3f, SLICE5_F4f}, 4685 {SLICE6_F1f, SLICE6_F2f, SLICE6_F3f, SLICE6_F4f}, 4686 {SLICE7_F1f, SLICE7_F2f, SLICE7_F3f, SLICE7_F4f}}; 4687 #endif /* BCM_RAVEN_SUPPORT */ 4688 soc_field_t f1_field, f2_field, f3_field, f4_field; 4689 _field_sel_t *sel = NULL; 4690 4691 if (_BCM_FIELD_STAGE_INGRESS == fg->stage_id) { 4692 /* Write the group mode into appropriate slices for 4693 * wide-mode devices. 4694 */ 4695 if (soc_feature(unit, soc_feature_field_wide)) { 4696 BCM_IF_ERROR_RETURN(_bcm_field_fb_mode_set(unit, slice_numb, 4697 fg, fg->flags)); 4698 } 4699 4700 sel = &fg->sel_codes[selcode_index]; 4701 4702 sal_memcpy(&pfs_entry, soc_mem_entry_null(unit, FP_PORT_FIELD_SELm), 4703 sizeof(pfs_entry)); 4704 4705 /* Determine which 4 fields will be modified */ 4706 f1_field = field_tbl[slice_numb][0]; 4707 f2_field = field_tbl[slice_numb][1]; 4708 f3_field = field_tbl[slice_numb][2]; 4709 f4_field = field_tbl[slice_numb][3]; 4710 4711 /* Iterate over all ports */ 4712 PBMP_ITER(pbmp, port) { 4713 /* Read Port's current entry in FP_PORT_FIELD_SEL table */ 4714 SOC_IF_ERROR_RETURN(READ_FP_PORT_FIELD_SELm(unit, MEM_BLOCK_ANY, 4715 port, &pfs_entry)); 4716 4717 /* modify 0-4 fields depending on state of SELCODE_DONT_CARE */ 4718 if (sel->fpf1 != _FP_SELCODE_DONT_CARE) { 4719 soc_FP_PORT_FIELD_SELm_field32_set(unit, &pfs_entry, f1_field, 4720 sel->fpf1); 4721 } 4722 if (sel->fpf2 != _FP_SELCODE_DONT_CARE) { 4723 soc_FP_PORT_FIELD_SELm_field32_set(unit, &pfs_entry, f2_field, 4724 sel->fpf2); 4725 } 4726 if (sel->fpf3 != _FP_SELCODE_DONT_CARE) { 4727 soc_FP_PORT_FIELD_SELm_field32_set(unit, &pfs_entry, f3_field, 4728 sel->fpf3); 4729 } 4730 if (sel->fpf4 != _FP_SELCODE_DONT_CARE) { 4731 soc_FP_PORT_FIELD_SELm_field32_set(unit, &pfs_entry, f4_field, 4732 sel->fpf4); 4733 } 4734 4735 /* Write each port's new entry */ 4736 SOC_IF_ERROR_RETURN(WRITE_FP_PORT_FIELD_SELm(unit, MEM_BLOCK_ALL, 4737 port, &pfs_entry)); 4738 #if defined(BCM_RAVEN_SUPPORT) 4739 /* IFP_PORT_FIELD_SEL table will be used to generate IFP_TCAM key 4740 when a port is configured in HIGIG mode (PORT_TAB.HIGIG_PACKET). 4741 This table will be automatically updated for other HG ports by 4742 the hardware when a value is configured in the FP_PORT_FIELD_SEL 4743 table except for cpu port */ 4744 if (SOC_IS_RAVEN(unit) && IS_CPU_PORT(unit, port)) { 4745 SOC_IF_ERROR_RETURN(WRITE_IFP_PORT_FIELD_SELm(unit, 4746 MEM_BLOCK_ALL, port, &pfs_entry)); 4747 } 4748 #endif 4749 } 4750 #if defined(BCM_RAVEN_SUPPORT) 4751 /* Set inner vlan overlay config. */ 4752 if (_FP_SELCODE_DONT_CARE != fg->sel_codes[0].inner_vlan_overlay) { 4753 if (SOC_REG_FIELD_VALID(unit, ING_MISC_CONFIG2r, 4754 FP_INNER_VLAN_OVERLAY_ENABLEf)) { 4755 BCM_IF_ERROR_RETURN( 4756 soc_reg_field32_modify(unit, 4757 ING_MISC_CONFIG2r, 4758 REG_PORT_ANY, FP_INNER_VLAN_OVERLAY_ENABLEf, 4759 fg->sel_codes[0].inner_vlan_overlay)); 4760 } 4761 } 4762 #endif 4763 BCM_IF_ERROR_RETURN(_bcm_field_valid_pbmp_get(unit, &all_pbmp)); 4764 if (BCM_PBMP_NEQ(all_pbmp, pbmp)) { 4765 /* Update Group Flags to denote Port based Group */ 4766 fg->flags |= _FP_GROUP_PER_PORT_OR_PBMP; 4767 } 4768 } else { 4769 return (BCM_E_UNAVAIL); 4770 } 4771 return (BCM_E_NONE); 4772 } 4773 4774 /* 4775 * Function: 4776 * _field_raptor_entry_reinstall 4777 * Purpose: 4778 * Write policy table entry information into the chip's memory. 4779 * Parameters: 4780 * unit - BCM Unit 4781 * f_ent - Physical entry structure to be installed 4782 * tcam_idx - common index of various tables 4783 * Returns: 4784 * BCM_E_XXX On TCAM read/write errors 4785 * BCM_E_NONE 4786 * Note: 4787 * Unit lock should be held by calling function. 4788 */ 4789 STATIC int 4790 _field_raptor_entry_reinstall(int unit, _field_entry_t *f_ent, int tcam_idx) 4791 { 4792 assert(f_ent != NULL); 4793 assert(tcam_idx >= soc_mem_index_min(unit, FP_TCAMm)); 4794 assert(tcam_idx <= soc_mem_index_max(unit, FP_TCAMm)); 4795 4796 /* Next Write the Actions */ 4797 BCM_IF_ERROR_RETURN( 4798 _field_raptor_policy_install(unit, f_ent, tcam_idx)); 4799 4800 return BCM_E_NONE; 4801 } 4802 4803 /* 4804 * Function: 4805 * _field_raptor_entry_install 4806 * Purpose: 4807 * Write entry into the chip's memory. 4808 * Parameters: 4809 * unit - BCM Unit 4810 * f_ent - Physical entry structure to be installed 4811 * tcam_idx - common index of various tables 4812 * Returns: 4813 * BCM_E_XXX On TCAM read/write errors 4814 * BCM_E_NONE 4815 * Note: 4816 * Unit lock should be held by calling function. 4817 */ 4818 STATIC int 4819 _field_raptor_entry_install(int unit, _field_entry_t *f_ent, int tcam_idx) 4820 { 4821 assert(f_ent != NULL); 4822 assert(tcam_idx >= soc_mem_index_min(unit, FP_TCAMm)); 4823 assert(tcam_idx <= soc_mem_index_max(unit, FP_TCAMm)); 4824 4825 /* Next Write the Actions */ 4826 BCM_IF_ERROR_RETURN( 4827 _field_raptor_policy_install(unit, f_ent, tcam_idx)); 4828 4829 /* Next write the IPBM */ 4830 BCM_IF_ERROR_RETURN( 4831 _field_raptor_ipbm_install(unit, f_ent)); 4832 4833 /* Finally Write the TCAM, Valid bits = b11 */ 4834 BCM_IF_ERROR_RETURN( 4835 _field_raptor_tcam_install(unit, f_ent, tcam_idx)); 4836 4837 return BCM_E_NONE; 4838 } 4839 4840 /* 4841 * Function: 4842 * _field_raptor_ipbm_entry_set 4843 * Purpose: 4844 * Set a bit in IPBM in the chip's memory. 4845 * Helper function for ipbm related functions 4846 * Parameters: 4847 * unit - BCM Unit 4848 * row - row in IPBM: The port/slice # 4849 * col - col. in IPBM: The entry # 4850 * enable - value (bit) to be written 4851 * Returns: 4852 * BCM_E_PARAM - incorrect col. 4853 * BEM_E_NONE 4854 * Note: 4855 */ 4856 STATIC int 4857 _field_raptor_ipbm_entry_set(int unit, int row, 4858 int col, uint32 enable) 4859 { 4860 fp_slice_entry_port_sel_entry_t ipbm_entry; 4861 soc_field_t all_fields[4] = {ENTRIES_PER_PORT_31_0f, 4862 ENTRIES_PER_PORT_63_32f, 4863 ENTRIES_PER_PORT_95_64f, 4864 ENTRIES_PER_PORT_127_96f}; 4865 soc_field_t field; 4866 uint32 field_offsets[4] = {0, 32, 64, 96}; 4867 uint32 index; 4868 uint32 curr_value, new_value; 4869 4870 SOC_IF_ERROR_RETURN(READ_FP_SLICE_ENTRY_PORT_SELm 4871 (unit, MEM_BLOCK_ANY, row, &ipbm_entry)); 4872 4873 field = all_fields[col/32]; 4874 index = col - field_offsets[col/32]; 4875 4876 curr_value = soc_FP_SLICE_ENTRY_PORT_SELm_field32_get 4877 (unit, &ipbm_entry, field); 4878 4879 new_value = enable ? 4880 (curr_value | (1 << index)) : 4881 (curr_value & ~(1 << index)); 4882 4883 /* This is an optimization: writing only if the bit is different */ 4884 if (new_value != curr_value) { 4885 soc_FP_SLICE_ENTRY_PORT_SELm_field32_set 4886 (unit, &ipbm_entry, field, new_value); 4887 4888 SOC_IF_ERROR_RETURN(WRITE_FP_SLICE_ENTRY_PORT_SELm 4889 (unit, MEM_BLOCK_ALL, row, &ipbm_entry)); 4890 } 4891 4892 return BCM_E_NONE; 4893 } 4894 4895 /* 4896 * Function: 4897 * _field_raptor_ipbm_entry_get 4898 * Purpose: 4899 * Get a bit in IPBM in the chip's memory. 4900 * Helper function for ipbm related functions 4901 * Parameters: 4902 * unit - BCM Unit 4903 * row - row in IPBM: The port/slice # 4904 * col - col. in IPBM: The entry # 4905 * enable - (OUT) value (bit) read 4906 * Returns: 4907 * BCM_E_PARAM - incorrect col. 4908 * BEM_E_NONE 4909 * Note: 4910 */ 4911 STATIC int 4912 _field_raptor_ipbm_entry_get(int unit, int row, 4913 int col, uint32 *enable) 4914 { 4915 fp_slice_entry_port_sel_entry_t ipbm_entry; 4916 soc_field_t all_fields[4] = {ENTRIES_PER_PORT_31_0f, 4917 ENTRIES_PER_PORT_63_32f, 4918 ENTRIES_PER_PORT_95_64f, 4919 ENTRIES_PER_PORT_127_96f}; 4920 soc_field_t field; 4921 uint32 field_offsets[4] = {0, 32, 64, 96}; 4922 uint32 index, result; 4923 4924 SOC_IF_ERROR_RETURN(READ_FP_SLICE_ENTRY_PORT_SELm 4925 (unit, MEM_BLOCK_ANY, row, &ipbm_entry)); 4926 4927 field = all_fields[col/32]; 4928 index = col - field_offsets[col/32]; 4929 4930 result = soc_FP_SLICE_ENTRY_PORT_SELm_field32_get 4931 (unit, &ipbm_entry, field); 4932 4933 *enable = (result >> index) & 0x1; /* Return the bit at col. */ 4934 4935 return BCM_E_NONE; 4936 } 4937 4938 /* 4939 * Function: 4940 * _field_raptor_ipbm_install 4941 * Purpose: 4942 * Write IPBM into the chip's memory. 4943 * Parameters: 4944 * unit - BCM Unit 4945 * f_ent - Physical entry structure to be installed 4946 * tcam_idx - location 4947 * Returns: 4948 * BCM_E_NONE 4949 * Note: 4950 * Unit lock should be held by calling function. 4951 */ 4952 STATIC int 4953 _field_raptor_ipbm_install(int unit, _field_entry_t *f_ent) 4954 { 4955 bcm_port_t p; 4956 bcm_pbmp_t pbmp, pbmp_mask; 4957 uint32 result; 4958 int ipbm_index; 4959 _field_stage_t *stage_fc; 4960 bcm_port_config_t port_config; 4961 4962 pbmp = f_ent->pbmp.data; 4963 pbmp_mask = f_ent->pbmp.mask; 4964 4965 /* Read device port configuration. */ 4966 BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config)); 4967 4968 BCM_IF_ERROR_RETURN 4969 (_field_stage_control_get(unit, f_ent->group->stage_id, &stage_fc)); 4970 4971 PBMP_ITER(port_config.all, p) { 4972 if (BCM_PBMP_MEMBER(pbmp_mask, p)) { 4973 if (BCM_PBMP_MEMBER(pbmp, p)) { 4974 result = 1; 4975 } else { 4976 result = 0; 4977 } 4978 } else { 4979 result = 1; 4980 } 4981 4982 /* set result at the appropriate location */ 4983 ipbm_index = _BCM_RP_FIELD_IPBM_INDEX(unit, p, f_ent->fs->slice_number); 4984 BCM_IF_ERROR_RETURN (_field_raptor_ipbm_entry_set(unit, ipbm_index, 4985 f_ent->slice_idx, 4986 result)); 4987 } 4988 4989 return BCM_E_NONE; 4990 } 4991 4992 /* 4993 * Function: 4994 * _field_raptor_tcam_install 4995 * Purpose: 4996 * Write rules into the chip's memory. 4997 * Parameters: 4998 * unit - BCM Unit 4999 * f_ent - Physical entry structure to be installed 5000 * tcam_idx - location in TCAM 5001 * Returns: 5002 * BCM_E_XXX On read/write errors 5003 * BCM_E_NONE 5004 * Note: 5005 * Unit lock should be held by calling function. 5006 */ 5007 STATIC int 5008 _field_raptor_tcam_install(int unit, _field_entry_t *f_ent, int tcam_idx) 5009 { 5010 fp_tcam_entry_t t_entry; 5011 5012 assert(f_ent != NULL); 5013 assert(tcam_idx >= soc_mem_index_min(unit, FP_TCAMm)); 5014 assert(tcam_idx <= soc_mem_index_max(unit, FP_TCAMm)); 5015 5016 /* Start with an empty TCAM entry */ 5017 sal_memcpy(&t_entry, soc_mem_entry_null(unit, FP_TCAMm), 5018 sizeof(t_entry)); 5019 5020 /* Extract the qualifier info from the entry structure. */ 5021 BCM_IF_ERROR_RETURN( 5022 _field_raptor_tcam_get(unit, f_ent, &t_entry)); 5023 5024 /* Write the TCAM Table */ 5025 SOC_IF_ERROR_RETURN 5026 (WRITE_FP_TCAMm(unit, MEM_BLOCK_ALL, tcam_idx, &t_entry)); 5027 5028 return BCM_E_NONE; 5029 } 5030 5031 /* 5032 * Function: 5033 * _field_raptor_tcam_get 5034 * Purpose: 5035 * Get the rules to be written into tcam. 5036 * Parameters: 5037 * unit - BCM Unit 5038 * f_ent - entry structure to get tcam info from. 5039 * t_entry - (OUT) TCAM entry 5040 * Returns: 5041 * BCM_E_NONE - Success 5042 * Note: 5043 * Unit lock should be held by calling function. 5044 */ 5045 STATIC int 5046 _field_raptor_tcam_get(int unit, _field_entry_t *f_ent, fp_tcam_entry_t *t_entry) 5047 { 5048 _field_tcam_t *tcam = NULL; 5049 5050 assert(f_ent != NULL); 5051 assert(t_entry != NULL); 5052 5053 tcam = &f_ent->tcam; 5054 5055 soc_mem_field_set(unit, FP_TCAMm, (uint32 *)t_entry, KEYf, tcam->key); 5056 soc_mem_field_set(unit, FP_TCAMm, (uint32 *)t_entry, MASKf, tcam->mask); 5057 5058 soc_FP_TCAMm_field32_set(unit, t_entry, F4f, tcam->f4); 5059 soc_FP_TCAMm_field32_set(unit, t_entry, F4_MASKf, tcam->f4_mask); 5060 5061 /* Qualify on IP_TYPE */ 5062 if (BCM_FIELD_QSET_TEST(f_ent->group->qset, 5063 bcmFieldQualifyIpType)) { 5064 int data, mask; 5065 switch (tcam->ip_type) { 5066 case bcmFieldIpTypeAny: 5067 data = 0x0; 5068 mask = 0x0; 5069 break; 5070 case bcmFieldIpTypeNonIp: 5071 data = 0x0; 5072 mask = 0x3; 5073 break; 5074 case bcmFieldIpTypeIpv4Not: 5075 data = 0x0; 5076 mask = 0x1; 5077 break; 5078 case bcmFieldIpTypeIpv4NoOpts: 5079 data = 0x1; 5080 mask = 0x3; 5081 break; 5082 case bcmFieldIpTypeIpv4WithOpts: 5083 data = 0x3; 5084 mask = 0x3; 5085 break; 5086 case bcmFieldIpTypeIpv4Any: 5087 data = 0x1; 5088 mask = 0x1; 5089 break; 5090 case bcmFieldIpTypeIpv6: 5091 data = 0x2; 5092 mask = 0x3; 5093 break; 5094 case bcmFieldIpTypeIpv6Not: 5095 default: 5096 /* Should not come here */ 5097 data = 0x0; 5098 mask = 0x0; 5099 break; 5100 } 5101 soc_FP_TCAMm_field32_set(unit, t_entry, IP_TYPEf, data); 5102 soc_FP_TCAMm_field32_set(unit, t_entry, IP_TYPE_MASKf, mask); 5103 } else { 5104 soc_FP_TCAMm_field32_set(unit, t_entry, IP_TYPEf, 0); 5105 soc_FP_TCAMm_field32_set(unit, t_entry, IP_TYPE_MASKf, 0); 5106 } 5107 5108 /* Qualify on HiGig packets. */ 5109 if (BCM_FIELD_QSET_TEST(f_ent->group->qset, 5110 bcmFieldQualifyHiGig)) { 5111 soc_FP_TCAMm_field32_set(unit, t_entry, HIGIG_PKTf, tcam->higig ? 1 : 0); 5112 soc_FP_TCAMm_field32_set(unit, t_entry, HIGIG_PKT_MASKf, tcam->higig_mask ? 1 : 0); 5113 } else { 5114 soc_FP_TCAMm_field32_set(unit, t_entry, HIGIG_PKTf, 0); 5115 soc_FP_TCAMm_field32_set(unit, t_entry, HIGIG_PKT_MASKf, 0); 5116 } 5117 #if defined(BCM_RAVEN_SUPPORT) 5118 if (soc_mem_field_valid(unit, FP_TCAMm, RESERVED_MASKf)) { 5119 soc_mem_field32_set(unit, FP_TCAMm, t_entry, RESERVED_MASKf, 0); 5120 } 5121 if (soc_mem_field_valid(unit, FP_TCAMm, RESERVED_KEYf)) { 5122 soc_mem_field32_set(unit, FP_TCAMm, t_entry, RESERVED_KEYf, 0); 5123 } 5124 #endif /* BCM_RAVEN_SUPPORT */ 5125 /* Set the Valid bits */ 5126 soc_FP_TCAMm_field32_set(unit, t_entry, VALIDf, 3); 5127 5128 return BCM_E_NONE; 5129 } 5130 5131 /* 5132 * Function: 5133 * _field_raptor_stat_action_set 5134 * 5135 * Purpose: 5136 * Get counter portion of Policy Table. 5137 * 5138 * Parameters: 5139 * unit - (IN)BCM device number. 5140 * f_ent - (IN)Software entry structure to get tcam info from. 5141 * mem - (IN)Policy table memory. 5142 * buf - (IN/OUT)Hardware policy entry 5143 * 5144 * Returns: 5145 * BCM_E_XXX 5146 */ 5147 STATIC int 5148 _field_raptor_stat_action_set(int unit, _field_entry_t *f_ent, 5149 fp_policy_table_entry_t *p_entry) 5150 { 5151 _field_stat_t *f_st; /* Field policer descriptor. */ 5152 int mode; /* Counter hw mode. */ 5153 int idx; /* Counter index. */ 5154 5155 /* Input parameter check. */ 5156 if ((NULL == f_ent) || (NULL == p_entry)) { 5157 return (BCM_E_PARAM); 5158 } 5159 5160 /* Disable counting if counter was not attached to the entry. */ 5161 if ((0 == (f_ent->statistic.flags & _FP_ENTRY_STAT_INSTALLED)) || 5162 ((f_ent->flags & _FP_ENTRY_PRIMARY) && 5163 (f_ent->flags & _FP_ENTRY_STAT_IN_SECONDARY_SLICE))) { 5164 mode = 0; 5165 idx = 0; 5166 } else { 5167 /* Get statistics entity description structure. */ 5168 BCM_IF_ERROR_RETURN(_bcm_field_stat_get(unit, f_ent->statistic.sid, &f_st)); 5169 idx = f_st->hw_index; 5170 mode = f_st->hw_mode; 5171 /* Adjust counter hw mode for COUNTER_MODE_YES_NO/NO_YES */ 5172 if (f_ent->statistic.flags & _FP_ENTRY_STAT_USE_ODD) { 5173 mode++; 5174 } 5175 } 5176 5177 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, COUNTER_INDEXf, idx); 5178 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, COUNTER_MODEf, mode); 5179 return (BCM_E_NONE); 5180 } 5181 5182 /* 5183 * Function: 5184 * _field_raptor_policy_install 5185 * Purpose: 5186 * Write policy into the chip's memory. 5187 * Parameters: 5188 * unit - BCM Unit 5189 * f_ent - Physical entry structure to be installed 5190 * tcam_idx - location in TCAM 5191 * Returns: 5192 * BCM_E_XXX On read/write errors 5193 * BCM_E_NONE 5194 * Note: 5195 * Unit lock should be held by calling function. 5196 */ 5197 STATIC int 5198 _field_raptor_policy_install(int unit, _field_entry_t *f_ent, int tcam_idx) 5199 { 5200 fp_policy_table_entry_t p_entry; 5201 _field_action_t *fa = NULL; 5202 5203 assert(f_ent != NULL); 5204 assert(tcam_idx >= soc_mem_index_min(unit, FP_POLICY_TABLEm)); 5205 assert(tcam_idx <= soc_mem_index_max(unit, FP_POLICY_TABLEm)); 5206 5207 /* Start with an empty POLICY entry */ 5208 sal_memcpy(&p_entry, soc_mem_entry_null(unit, FP_POLICY_TABLEm), 5209 sizeof(p_entry)); 5210 5211 /* Extract the policy info from the entry structure. */ 5212 for (fa = f_ent->actions; 5213 ((fa != NULL) && (_FP_ACTION_VALID & fa->flags)); fa = fa->next) { 5214 if ((f_ent->flags & _FP_ENTRY_POLICER_IN_SECONDARY_SLICE) && 5215 (_FP_ACTION_IS_COLOR_BASED(fa->action))) { 5216 continue; 5217 } 5218 BCM_IF_ERROR_RETURN( 5219 _field_raptor_action_get(unit, f_ent, tcam_idx, fa, &p_entry)); 5220 } 5221 5222 /* Handle color dependence/independence */ 5223 if (soc_feature(unit, soc_feature_field_color_indep)) { 5224 if (f_ent->flags & _FP_ENTRY_COLOR_INDEPENDENT) { 5225 soc_mem_field32_set(unit, FP_POLICY_TABLEm, &p_entry, 5226 GREEN_TO_PIDf, 1); 5227 } else { 5228 soc_mem_field32_set(unit, FP_POLICY_TABLEm, &p_entry, 5229 GREEN_TO_PIDf, 0); 5230 } 5231 } 5232 5233 /* If the entry has a meter, get its index. */ 5234 if (f_ent->policer[0].flags & _FP_POLICER_INSTALLED) { 5235 BCM_IF_ERROR_RETURN(_field_raptor_meter_action_set(unit, f_ent, 5236 &p_entry)); 5237 } 5238 5239 /* Install statistics entity. */ 5240 BCM_IF_ERROR_RETURN(_field_raptor_stat_action_set(unit, f_ent, &p_entry)); 5241 5242 /* Write the POLICY Table */ 5243 SOC_IF_ERROR_RETURN 5244 (WRITE_FP_POLICY_TABLEm(unit, MEM_BLOCK_ALL, tcam_idx, &p_entry)); 5245 5246 return BCM_E_NONE; 5247 } 5248 5249 /* 5250 * Function: 5251 * _field_raptor_action_get 5252 * Purpose: 5253 * Get the actions to be written 5254 * Parameters: 5255 * unit - BCM device number 5256 * tcam_idx - index into TCAM 5257 * fa - field action 5258 * p_entry - (OUT) Field Policy table entry 5259 * Returns: 5260 * BCM_E_NONE 5261 * BCM_E_PARAM - Action parameter out-of-range or unrecognized action. 5262 * Notes: 5263 * This is a simple read/modify/write pattern. 5264 * FP unit lock should be held by calling function. 5265 */ 5266 STATIC int 5267 _field_raptor_action_get(int unit, _field_entry_t *f_ent, int tcam_idx, 5268 _field_action_t *fa, fp_policy_table_entry_t *p_entry) 5269 { 5270 uint32 reg_val; 5271 uint32 redir_field; 5272 uint8 raptor_actions_enable = TRUE; 5273 5274 LOG_DEBUG(BSL_LS_BCM_FP, 5275 (BSL_META_U(unit, 5276 "FP(unit %d) vverb: BEGIN _field_raptor_action_get(eid=%d, tcam_idx=0x%x, "), 5277 unit, f_ent->eid, tcam_idx)); 5278 5279 #if defined(BCM_RAVEN_SUPPORT) 5280 /* First deal with Raven-only actions */ 5281 if (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 5282 raptor_actions_enable = FALSE; 5283 switch (fa->action) { 5284 case bcmFieldActionGpCosQNew: 5285 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5286 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 1); 5287 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWPRIf, fa->param[0]); 5288 break; 5289 case bcmFieldActionGpPrioPktAndIntCopy: 5290 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5291 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 4); 5292 break; 5293 case bcmFieldActionGpPrioPktAndIntNew: 5294 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5295 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 5); 5296 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWPRIf, fa->param[0]); 5297 break; 5298 case bcmFieldActionGpPrioPktAndIntTos: 5299 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5300 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 6); 5301 break; 5302 case bcmFieldActionGpPrioPktAndIntCancel: 5303 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5304 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 7); 5305 break; 5306 case bcmFieldActionGpPrioPktCopy: 5307 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5308 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 8); 5309 break; 5310 case bcmFieldActionGpPrioPktNew: 5311 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5312 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 9); 5313 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWPRIf, fa->param[0]); 5314 break; 5315 case bcmFieldActionGpPrioPktTos: 5316 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5317 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 10); 5318 break; 5319 case bcmFieldActionGpPrioPktCancel: 5320 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5321 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 11); 5322 break; 5323 case bcmFieldActionGpPrioIntCopy: 5324 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5325 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 12); 5326 break; 5327 case bcmFieldActionGpPrioIntNew: 5328 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5329 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 13); 5330 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWPRIf, fa->param[0]); 5331 break; 5332 case bcmFieldActionGpPrioIntTos: 5333 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5334 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 14); 5335 break; 5336 case bcmFieldActionGpPrioIntCancel: 5337 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5338 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 15); 5339 break; 5340 case bcmFieldActionYpCosQNew: 5341 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5342 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 1); 5343 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_NEWPRIf, fa->param[0]); 5344 break; 5345 case bcmFieldActionYpPrioPktAndIntCopy: 5346 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5347 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 4); 5348 break; 5349 case bcmFieldActionYpPrioPktAndIntNew: 5350 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5351 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 5); 5352 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_NEWPRIf, fa->param[0]); 5353 break; 5354 case bcmFieldActionYpPrioPktAndIntTos: 5355 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5356 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 6); 5357 break; 5358 case bcmFieldActionYpPrioPktAndIntCancel: 5359 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5360 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 7); 5361 break; 5362 case bcmFieldActionYpPrioPktCopy: 5363 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5364 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 8); 5365 break; 5366 case bcmFieldActionYpPrioPktNew: 5367 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5368 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 9); 5369 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_NEWPRIf, fa->param[0]); 5370 break; 5371 case bcmFieldActionYpPrioPktTos: 5372 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5373 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 10); 5374 break; 5375 case bcmFieldActionYpPrioPktCancel: 5376 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5377 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 11); 5378 break; 5379 case bcmFieldActionYpPrioIntCopy: 5380 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5381 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 12); 5382 break; 5383 case bcmFieldActionYpPrioIntNew: 5384 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5385 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 13); 5386 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_NEWPRIf, fa->param[0]); 5387 break; 5388 case bcmFieldActionYpPrioIntTos: 5389 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5390 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 14); 5391 break; 5392 case bcmFieldActionYpPrioIntCancel: 5393 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5394 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_PRIORITYf, 15); 5395 break; 5396 case bcmFieldActionRpCosQNew: 5397 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5398 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 1); 5399 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_NEWPRIf, fa->param[0]); 5400 break; 5401 case bcmFieldActionRpPrioPktAndIntCopy: 5402 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5403 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 4); 5404 break; 5405 case bcmFieldActionRpPrioPktAndIntNew: 5406 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5407 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 5); 5408 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_NEWPRIf, fa->param[0]); 5409 break; 5410 case bcmFieldActionRpPrioPktAndIntTos: 5411 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5412 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 6); 5413 break; 5414 case bcmFieldActionRpPrioPktAndIntCancel: 5415 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5416 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 7); 5417 break; 5418 case bcmFieldActionRpPrioPktCopy: 5419 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5420 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 8); 5421 break; 5422 case bcmFieldActionRpPrioPktNew: 5423 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5424 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 9); 5425 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_NEWPRIf, fa->param[0]); 5426 break; 5427 case bcmFieldActionRpPrioPktTos: 5428 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5429 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 10); 5430 break; 5431 case bcmFieldActionRpPrioPktCancel: 5432 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5433 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 11); 5434 break; 5435 case bcmFieldActionRpPrioIntCopy: 5436 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5437 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 12); 5438 break; 5439 case bcmFieldActionRpPrioIntNew: 5440 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5441 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 13); 5442 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_NEWPRIf, fa->param[0]); 5443 break; 5444 case bcmFieldActionRpPrioIntTos: 5445 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5446 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 14); 5447 break; 5448 case bcmFieldActionRpPrioIntCancel: 5449 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PRI_MODEf, 1); 5450 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_PRIORITYf, 15); 5451 break; 5452 default: 5453 raptor_actions_enable = TRUE; /* Check for Raptor / 5454 Raven common actions. */ 5455 break; 5456 } 5457 } 5458 #endif /* BCM_RAVEN_SUPPORT */ 5459 if (raptor_actions_enable) { 5460 switch (fa->action) { 5461 case bcmFieldActionCosQNew: 5462 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 1); 5463 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWPRIf, fa->param[0]); 5464 break; 5465 case bcmFieldActionCosQCpuNew: 5466 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 2); 5467 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWPRIf, fa->param[0]); 5468 break; 5469 case bcmFieldActionPrioPktAndIntCopy: 5470 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 4); 5471 break; 5472 case bcmFieldActionPrioPktAndIntNew: 5473 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 5); 5474 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWPRIf, fa->param[0]); 5475 break; 5476 case bcmFieldActionPrioPktAndIntTos: 5477 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 6); 5478 break; 5479 case bcmFieldActionPrioPktAndIntCancel: 5480 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 7); 5481 break; 5482 case bcmFieldActionPrioPktCopy: 5483 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 8); 5484 break; 5485 case bcmFieldActionPrioPktNew: 5486 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 9); 5487 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWPRIf, fa->param[0]); 5488 break; 5489 case bcmFieldActionPrioPktTos: 5490 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 10); 5491 break; 5492 case bcmFieldActionPrioPktCancel: 5493 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 11); 5494 break; 5495 case bcmFieldActionPrioIntCopy: 5496 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 12); 5497 break; 5498 case bcmFieldActionPrioIntNew: 5499 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 13); 5500 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWPRIf, fa->param[0]); 5501 break; 5502 case bcmFieldActionPrioIntTos: 5503 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 14); 5504 break; 5505 case bcmFieldActionPrioIntCancel: 5506 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_PRIORITYf, 15); 5507 break; 5508 case bcmFieldActionTosNew: 5509 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_DSCP_TOSf, 1); 5510 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWDSCP_TOSf, fa->param[0]); 5511 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_DSCPf, 1); 5512 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_DSCPf, fa->param[0]); 5513 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_DSCPf, 1); 5514 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_DSCPf, fa->param[0]); 5515 break; 5516 case bcmFieldActionTosCopy: 5517 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_DSCP_TOSf, 2); 5518 break; 5519 case bcmFieldActionDscpNew: 5520 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_DSCP_TOSf, 3); 5521 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWDSCP_TOSf, fa->param[0]); 5522 break; 5523 case bcmFieldActionTosCancel: 5524 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_DSCP_TOSf, 4); 5525 break; 5526 case bcmFieldActionDscpCancel: 5527 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_DSCP_TOSf, 4); 5528 break; 5529 case bcmFieldActionCopyToCpu: 5530 /* if the action is CopyToCpu, and param0 is nonzero, which means the user 5531 * wants to install the value of param1 as the MATCHED_RULEf, we want to 5532 * make sure that param1 can fit into 8 bits 5533 */ 5534 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_COPY_TO_CPUf, 1); 5535 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_COPY_TO_CPUf, 1); 5536 PolicySet(unit, FP_POLICY_TABLEm, p_entry, COPY_TO_CPUf, 1); 5537 if(fa->param[0] != 0) { 5538 PolicySet(unit, FP_POLICY_TABLEm, p_entry, MATCHED_RULEf, fa->param[1]); 5539 } 5540 break; 5541 case bcmFieldActionCopyToCpuCancel: 5542 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_COPY_TO_CPUf, 2); 5543 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_COPY_TO_CPUf, 2); 5544 PolicySet(unit, FP_POLICY_TABLEm, p_entry, COPY_TO_CPUf, 2); 5545 break; 5546 case bcmFieldActionSwitchToCpuCancel: 5547 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_COPY_TO_CPUf, 3); 5548 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_COPY_TO_CPUf, 3); 5549 PolicySet(unit, FP_POLICY_TABLEm, p_entry, COPY_TO_CPUf, 3); 5550 break; 5551 case bcmFieldActionRedirect: /* param0 = modid, param1 = port/tgid */ 5552 /* modid = 4 bits, port/tgid = 7 bits */ 5553 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PACKET_REDIRECTIONf, 1); 5554 if (soc_feature(unit, soc_feature_table_hi)) { 5555 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTION_LOf, (fa->param[0] << 7) | fa->param[1]); 5556 } else { 5557 redir_field = PolicyGet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTIONf); 5558 redir_field &= (0xfffff800); /* Zero mod/port[11:0] bits */ 5559 redir_field |= (fa->param[0] << 7) | fa->param[1]; 5560 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTIONf, redir_field); 5561 } 5562 break; 5563 case bcmFieldActionRedirectTrunk: /* param0 = trunk ID */ 5564 /* Trunk indicator is bit 6 (7th from right) */ 5565 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PACKET_REDIRECTIONf, 1); 5566 if (soc_feature(unit, soc_feature_table_hi)) { 5567 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTION_LOf, (fa->param[0] & 0x3f) | 0x40); 5568 } else { 5569 redir_field = PolicyGet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTIONf); 5570 redir_field &= (0xffffff80); /* Zero trunk [6:0] bits */ 5571 redir_field |= (fa->param[0] & 0x3f) | 0x40; 5572 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTIONf, redir_field); 5573 } 5574 break; 5575 case bcmFieldActionRedirectCancel: 5576 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PACKET_REDIRECTIONf, 2); 5577 break; 5578 case bcmFieldActionRedirectPbmp: 5579 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PACKET_REDIRECTIONf, 3); 5580 if (soc_feature(unit, soc_feature_table_hi)) { 5581 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTION_LOf, fa->param[0]); 5582 #if defined(BCM_RAPTOR1_SUPPORT) 5583 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTION_HIf, fa->param[1]); 5584 #endif 5585 } else { 5586 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTIONf, fa->param[0]); 5587 } 5588 break; 5589 case bcmFieldActionEgressMask: 5590 PolicySet(unit, FP_POLICY_TABLEm, p_entry, PACKET_REDIRECTIONf, 4); 5591 if (soc_feature(unit, soc_feature_table_hi)) { 5592 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTION_LOf, fa->param[0]); 5593 #if defined(BCM_RAPTOR1_SUPPORT) 5594 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTION_HIf, fa->param[1]); 5595 #endif 5596 } else { 5597 PolicySet(unit, FP_POLICY_TABLEm, p_entry, REDIRECTIONf, fa->param[0]); 5598 } 5599 break; 5600 case bcmFieldActionDrop: 5601 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_DROPf, 1); 5602 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_DROPf, 1); 5603 PolicySet(unit, FP_POLICY_TABLEm, p_entry, DROPf, 1); 5604 break; 5605 case bcmFieldActionDropCancel: 5606 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_DROPf, 2); 5607 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_DROPf, 2); 5608 PolicySet(unit, FP_POLICY_TABLEm, p_entry, DROPf, 2); 5609 break; 5610 case bcmFieldActionMirrorOverride: 5611 if (soc_feature(unit, soc_feature_field_mirror_ovr)) { 5612 PolicySet(unit, FP_POLICY_TABLEm, p_entry, MIRROR_OVERRIDEf, 1); 5613 } else { 5614 return BCM_E_PARAM; 5615 } 5616 break; 5617 case bcmFieldActionMirrorIngress: /* param0=modid, param1=port/tgid */ 5618 PolicySet(unit, FP_POLICY_TABLEm, p_entry, MIRRORf, 5619 PolicyGet(unit, FP_POLICY_TABLEm, p_entry, MIRRORf) | 1); 5620 PolicySet(unit, FP_POLICY_TABLEm, p_entry, IM_MTP_INDEXf, fa->hw_index); 5621 if (soc_feature(unit, soc_feature_field_mirror_pkts_ctl)) { 5622 SOC_IF_ERROR_RETURN(READ_ING_CONFIGr(unit, ®_val)); 5623 soc_reg_field_set(unit, ING_CONFIGr, ®_val, 5624 ENABLE_FP_FOR_MIRROR_PKTSf, 1 ); 5625 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIGr(unit, reg_val)); 5626 } 5627 break; 5628 case bcmFieldActionMirrorEgress: /* param0=modid, param1=port/tgid */ 5629 PolicySet(unit, FP_POLICY_TABLEm, p_entry, MIRRORf, 5630 PolicyGet(unit, FP_POLICY_TABLEm, p_entry, MIRRORf) | 2); 5631 PolicySet(unit, FP_POLICY_TABLEm, p_entry, EM_MTP_INDEXf, fa->hw_index); 5632 if (soc_feature(unit, soc_feature_field_mirror_pkts_ctl)) { 5633 SOC_IF_ERROR_RETURN(READ_ING_CONFIGr(unit, ®_val)); 5634 soc_reg_field_set(unit, ING_CONFIGr, ®_val, 5635 ENABLE_FP_FOR_MIRROR_PKTSf, 1 ); 5636 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIGr(unit, reg_val)); 5637 } 5638 break; 5639 #ifdef INCLUDE_L3 5640 case bcmFieldActionL3ChangeVlan: 5641 PolicySet(unit, FP_POLICY_TABLEm, p_entry, L3SW_CHANGE_MACDA_OR_VLANf, 1); 5642 BCM_IF_ERROR_RETURN 5643 (_bcm_field_policy_set_l3_info(unit, FP_POLICY_TABLEm, 5644 fa->param[0], (uint32 *)p_entry)); 5645 break; 5646 case bcmFieldActionL3ChangeVlanCancel: 5647 PolicySet(unit, FP_POLICY_TABLEm, p_entry, L3SW_CHANGE_MACDA_OR_VLANf, 2); 5648 break; 5649 case bcmFieldActionL3ChangeMacDa: 5650 PolicySet(unit, FP_POLICY_TABLEm, p_entry, L3SW_CHANGE_MACDA_OR_VLANf, 4); 5651 BCM_IF_ERROR_RETURN 5652 (_bcm_field_policy_set_l3_info(unit, FP_POLICY_TABLEm, 5653 fa->param[0], (uint32 *)p_entry)); 5654 break; 5655 case bcmFieldActionL3ChangeMacDaCancel: 5656 PolicySet(unit, FP_POLICY_TABLEm, p_entry, L3SW_CHANGE_MACDA_OR_VLANf, 5); 5657 break; 5658 case bcmFieldActionL3Switch: 5659 PolicySet(unit, FP_POLICY_TABLEm, p_entry, L3SW_CHANGE_MACDA_OR_VLANf, 6); 5660 BCM_IF_ERROR_RETURN 5661 (_bcm_field_policy_set_l3_info(unit, FP_POLICY_TABLEm, 5662 fa->param[0], (uint32 *)p_entry)); 5663 break; 5664 case bcmFieldActionL3SwitchCancel: 5665 PolicySet(unit, FP_POLICY_TABLEm, p_entry, L3SW_CHANGE_MACDA_OR_VLANf, 7); 5666 break; 5667 #endif /* INCLUDE_L3 */ 5668 case bcmFieldActionAddClassTag: 5669 PolicySet(unit, FP_POLICY_TABLEm, p_entry, L3SW_CHANGE_MACDA_OR_VLANf, 3); 5670 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CLASSIFICATION_TAGf, fa->param[0]); 5671 break; 5672 case bcmFieldActionEcnNew: 5673 PolicySet(unit, FP_POLICY_TABLEm, p_entry, ECN_CNGf, 0x1); 5674 /* coverity[MISSING_BREAK : FALSE] */ 5675 /* passthru */ 5676 case bcmFieldActionDropPrecedence: 5677 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_DROP_PRECEDENCEf, fa->param[0]); 5678 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_DROP_PRECEDENCEf, fa->param[0]); 5679 PolicySet(unit, FP_POLICY_TABLEm, p_entry, DROP_PRECEDENCEf, fa->param[0]); 5680 break; 5681 case bcmFieldActionRpDrop: 5682 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_DROPf, 1); 5683 break; 5684 case bcmFieldActionRpDropCancel: 5685 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_DROPf, 2); 5686 break; 5687 case bcmFieldActionRpDropPrecedence: 5688 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_DROP_PRECEDENCEf, fa->param[0]); 5689 break; 5690 case bcmFieldActionRpCopyToCpu: 5691 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_COPY_TO_CPUf, 1); 5692 if(fa->param[0] != 0) { 5693 PolicySet(unit, FP_POLICY_TABLEm, p_entry, MATCHED_RULEf, fa->param[1]); 5694 } 5695 break; 5696 case bcmFieldActionRpCopyToCpuCancel: 5697 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_COPY_TO_CPUf, 2); 5698 break; 5699 case bcmFieldActionRpDscpNew: 5700 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_CHANGE_DSCPf, 1); 5701 PolicySet(unit, FP_POLICY_TABLEm, p_entry, RP_DSCPf, fa->param[0]); 5702 break; 5703 case bcmFieldActionYpDrop: 5704 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_DROPf, 1); 5705 break; 5706 case bcmFieldActionYpDropCancel: 5707 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_DROPf, 2); 5708 break; 5709 case bcmFieldActionYpDropPrecedence: 5710 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_DROP_PRECEDENCEf, fa->param[0]); 5711 break; 5712 case bcmFieldActionYpCopyToCpu: 5713 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_COPY_TO_CPUf, 1); 5714 if(fa->param[0] != 0) { 5715 PolicySet(unit, FP_POLICY_TABLEm, p_entry, MATCHED_RULEf, fa->param[1]); 5716 } 5717 break; 5718 case bcmFieldActionYpCopyToCpuCancel: 5719 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_COPY_TO_CPUf, 2); 5720 break; 5721 case bcmFieldActionYpDscpNew: 5722 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_CHANGE_DSCPf, 1); 5723 PolicySet(unit, FP_POLICY_TABLEm, p_entry, YP_DSCPf, fa->param[0]); 5724 break; 5725 case bcmFieldActionGpDrop: 5726 PolicySet(unit, FP_POLICY_TABLEm, p_entry, DROPf, 1); 5727 break; 5728 case bcmFieldActionGpDropCancel: 5729 PolicySet(unit, FP_POLICY_TABLEm, p_entry, DROPf, 2); 5730 break; 5731 case bcmFieldActionGpDropPrecedence: 5732 PolicySet(unit, FP_POLICY_TABLEm, p_entry, DROP_PRECEDENCEf, fa->param[0]); 5733 break; 5734 case bcmFieldActionGpCopyToCpu: 5735 PolicySet(unit, FP_POLICY_TABLEm, p_entry, COPY_TO_CPUf, 1); 5736 if(fa->param[0] != 0) { 5737 PolicySet(unit, FP_POLICY_TABLEm, p_entry, MATCHED_RULEf, fa->param[1]); 5738 } 5739 break; 5740 case bcmFieldActionGpCopyToCpuCancel: 5741 PolicySet(unit, FP_POLICY_TABLEm, p_entry, COPY_TO_CPUf, 2); 5742 break; 5743 case bcmFieldActionGpDscpNew: 5744 PolicySet(unit, FP_POLICY_TABLEm, p_entry, CHANGE_DSCP_TOSf, 3); 5745 PolicySet(unit, FP_POLICY_TABLEm, p_entry, NEWDSCP_TOSf, fa->param[0]); 5746 break; 5747 default: 5748 LOG_ERROR(BSL_LS_BCM_FP, 5749 (BSL_META_U(unit, 5750 "FP(unit %d) Error: Unknown action (%d)\n"), 5751 unit, (uint32)fa->action)); 5752 return BCM_E_PARAM; 5753 } 5754 } 5755 5756 fa->flags &= ~_FP_ACTION_DIRTY; /* Mark action as installed. */ 5757 5758 LOG_DEBUG(BSL_LS_BCM_FP, 5759 (BSL_META_U(unit, 5760 "FP(unit %d) vverb: END _field_raptor_action_get()\n"), 5761 unit)); 5762 return BCM_E_NONE; 5763 5764 } 5765 5766 /* 5767 * Function: 5768 * _field_raptor_action_params_check 5769 * Purpose: 5770 * Check field action parameters. 5771 * Parameters: 5772 * unit - BCM device number 5773 * f_ent - Field entry structure. 5774 * fa - field action 5775 * Returns: 5776 * BCM_E_XXX 5777 */ 5778 STATIC int 5779 _field_raptor_action_params_check(int unit,_field_entry_t *f_ent, 5780 _field_action_t *fa) 5781 { 5782 #if defined(INCLUDE_L3) 5783 uint32 flags; /* L3 forwarding flags. */ 5784 int nh_ecmp_id; /* Next hop/Ecmp group id. */ 5785 #endif /* INCLUDE_L3 */ 5786 int rv; /* Operation return value. */ 5787 int raptor_actions_enable = TRUE; 5788 5789 #if defined(BCM_RAVEN_SUPPORT) 5790 /* First deal with Raven-only actions */ 5791 if (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 5792 raptor_actions_enable = FALSE; 5793 switch (fa->action) { 5794 case bcmFieldActionGpCosQNew: 5795 PolicyCheck(unit, FP_POLICY_TABLEm, NEWPRIf, fa->param[0]); 5796 break; 5797 case bcmFieldActionGpPrioPktAndIntNew: 5798 PolicyCheck(unit, FP_POLICY_TABLEm, NEWPRIf, fa->param[0]); 5799 break; 5800 case bcmFieldActionGpPrioPktNew: 5801 PolicyCheck(unit, FP_POLICY_TABLEm, NEWPRIf, fa->param[0]); 5802 break; 5803 case bcmFieldActionGpPrioIntNew: 5804 PolicyCheck(unit, FP_POLICY_TABLEm, NEWPRIf, fa->param[0]); 5805 break; 5806 case bcmFieldActionYpCosQNew: 5807 PolicyCheck(unit, FP_POLICY_TABLEm, YP_NEWPRIf, fa->param[0]); 5808 break; 5809 case bcmFieldActionYpPrioPktAndIntNew: 5810 PolicyCheck(unit, FP_POLICY_TABLEm, YP_NEWPRIf, fa->param[0]); 5811 break; 5812 case bcmFieldActionYpPrioPktNew: 5813 PolicyCheck(unit, FP_POLICY_TABLEm, YP_NEWPRIf, fa->param[0]); 5814 break; 5815 case bcmFieldActionYpPrioIntNew: 5816 PolicyCheck(unit, FP_POLICY_TABLEm, YP_NEWPRIf, fa->param[0]); 5817 break; 5818 case bcmFieldActionRpCosQNew: 5819 PolicyCheck(unit, FP_POLICY_TABLEm, RP_NEWPRIf, fa->param[0]); 5820 break; 5821 case bcmFieldActionRpPrioPktAndIntNew: 5822 PolicyCheck(unit, FP_POLICY_TABLEm, RP_NEWPRIf, fa->param[0]); 5823 break; 5824 case bcmFieldActionRpPrioPktNew: 5825 PolicyCheck(unit, FP_POLICY_TABLEm, RP_NEWPRIf, fa->param[0]); 5826 break; 5827 case bcmFieldActionRpPrioIntNew: 5828 PolicyCheck(unit, FP_POLICY_TABLEm, RP_NEWPRIf, fa->param[0]); 5829 break; 5830 default: 5831 raptor_actions_enable = TRUE; /* Check for Raptor / 5832 Raven common actions. */ 5833 break; 5834 } 5835 } 5836 #endif /* BCM_RAVEN_SUPPORT */ 5837 if (raptor_actions_enable) { 5838 switch (fa->action) { 5839 case bcmFieldActionCosQNew: 5840 PolicyCheck(unit, FP_POLICY_TABLEm, NEWPRIf, fa->param[0]); 5841 break; 5842 case bcmFieldActionCosQCpuNew: 5843 PolicyCheck(unit, FP_POLICY_TABLEm, NEWPRIf, fa->param[0]); 5844 break; 5845 case bcmFieldActionPrioPktAndIntNew: 5846 PolicyCheck(unit, FP_POLICY_TABLEm, NEWPRIf, fa->param[0]); 5847 break; 5848 case bcmFieldActionPrioPktNew: 5849 PolicyCheck(unit, FP_POLICY_TABLEm, NEWPRIf, fa->param[0]); 5850 break; 5851 case bcmFieldActionPrioIntNew: 5852 PolicyCheck(unit, FP_POLICY_TABLEm, NEWPRIf, fa->param[0]); 5853 break; 5854 case bcmFieldActionTosNew: 5855 PolicyCheck(unit, FP_POLICY_TABLEm, NEWDSCP_TOSf, fa->param[0]); 5856 PolicyCheck(unit, FP_POLICY_TABLEm, YP_DSCPf, fa->param[0]); 5857 PolicyCheck(unit, FP_POLICY_TABLEm, RP_DSCPf, fa->param[0]); 5858 break; 5859 case bcmFieldActionDscpNew: 5860 PolicyCheck(unit, FP_POLICY_TABLEm, NEWDSCP_TOSf, fa->param[0]); 5861 break; 5862 case bcmFieldActionCopyToCpu: 5863 case bcmFieldActionRpCopyToCpu: 5864 case bcmFieldActionYpCopyToCpu: 5865 case bcmFieldActionGpCopyToCpu: 5866 /* if the action is Gp/Yp/Rp CopyToCpu, and param0 is nonzero, 5867 * which means the user wants to install the value of param1 as 5868 * the MATCHED_RULEf, we want to make sure that param1 can fit 5869 * into 8 bits. 5870 */ 5871 if ((fa->param[0] != 0) && (fa->param[1] >= (1 << 8))) { 5872 return BCM_E_PARAM; 5873 } 5874 5875 if(fa->param[0] != 0) { 5876 PolicyCheck(unit, FP_POLICY_TABLEm, MATCHED_RULEf, fa->param[1]); 5877 } 5878 break; 5879 case bcmFieldActionRedirect: 5880 /* param0 = modid, param1 = port/tgid */ 5881 /* modid = 4 bits, port/tgid = 7 bits */ 5882 rv = _bcm_field_action_dest_check(unit, fa); 5883 BCM_IF_ERROR_RETURN(rv); 5884 if (fa->param[0] > 0xf || fa->param[1] > 0x7f) { 5885 return BCM_E_PARAM; 5886 } 5887 break; 5888 case bcmFieldActionRedirectTrunk: /* param0 = trunk ID */ 5889 if (fa->param[0] > 0x3f) { 5890 return BCM_E_PARAM; 5891 } 5892 break; 5893 case bcmFieldActionRedirectPbmp: 5894 if (soc_feature(unit, soc_feature_table_hi)) { 5895 PolicyCheck(unit, FP_POLICY_TABLEm, REDIRECTION_LOf, fa->param[0]); 5896 #if defined(BCM_RAPTOR1_SUPPORT) 5897 PolicyCheck(unit, FP_POLICY_TABLEm, REDIRECTION_HIf, fa->param[1]); 5898 #endif 5899 } else { 5900 PolicyCheck(unit, FP_POLICY_TABLEm, REDIRECTIONf, fa->param[0]); 5901 } 5902 break; 5903 case bcmFieldActionEgressMask: 5904 if (soc_feature(unit, soc_feature_table_hi)) { 5905 PolicyCheck(unit, FP_POLICY_TABLEm, REDIRECTION_LOf, fa->param[0]); 5906 #if defined(BCM_RAPTOR1_SUPPORT) 5907 PolicyCheck(unit, FP_POLICY_TABLEm, REDIRECTION_HIf, fa->param[1]); 5908 #endif 5909 } else { 5910 PolicyCheck(unit, FP_POLICY_TABLEm, REDIRECTIONf, fa->param[0]); 5911 } 5912 break; 5913 case bcmFieldActionMirrorIngress: 5914 case bcmFieldActionMirrorEgress: 5915 rv = _bcm_field_action_dest_check(unit, fa); 5916 BCM_IF_ERROR_RETURN(rv); 5917 break; 5918 #ifdef INCLUDE_L3 5919 case bcmFieldActionL3ChangeVlan: 5920 case bcmFieldActionL3ChangeMacDa: 5921 case bcmFieldActionL3Switch: 5922 rv = _bcm_field_policy_set_l3_nh_resolve(unit, fa->param[0], 5923 &flags, &nh_ecmp_id); 5924 5925 BCM_IF_ERROR_RETURN(rv); 5926 if (flags & BCM_L3_MULTIPATH) { 5927 PolicyCheck(unit, FP_POLICY_TABLEm, ECMP_PTRf, nh_ecmp_id); 5928 } else { 5929 PolicyCheck(unit, FP_POLICY_TABLEm, NEXT_HOP_INDEXf, nh_ecmp_id); 5930 } 5931 break; 5932 #endif /* INCLUDE_L3 */ 5933 case bcmFieldActionAddClassTag: 5934 PolicyCheck(unit, FP_POLICY_TABLEm, CLASSIFICATION_TAGf, fa->param[0]); 5935 break; 5936 case bcmFieldActionEcnNew: 5937 case bcmFieldActionDropPrecedence: 5938 PolicyCheck(unit, FP_POLICY_TABLEm, RP_DROP_PRECEDENCEf, fa->param[0]); 5939 PolicyCheck(unit, FP_POLICY_TABLEm, YP_DROP_PRECEDENCEf, fa->param[0]); 5940 PolicyCheck(unit, FP_POLICY_TABLEm, DROP_PRECEDENCEf, fa->param[0]); 5941 break; 5942 case bcmFieldActionRpDropPrecedence: 5943 PolicyCheck(unit, FP_POLICY_TABLEm, RP_DROP_PRECEDENCEf, fa->param[0]); 5944 break; 5945 case bcmFieldActionRpDscpNew: 5946 PolicyCheck(unit, FP_POLICY_TABLEm, RP_DSCPf, fa->param[0]); 5947 break; 5948 case bcmFieldActionYpDropPrecedence: 5949 PolicyCheck(unit, FP_POLICY_TABLEm, YP_DROP_PRECEDENCEf, fa->param[0]); 5950 break; 5951 case bcmFieldActionYpDscpNew: 5952 PolicyCheck(unit, FP_POLICY_TABLEm, YP_DSCPf, fa->param[0]); 5953 break; 5954 case bcmFieldActionGpDropPrecedence: 5955 PolicyCheck(unit, FP_POLICY_TABLEm, DROP_PRECEDENCEf, fa->param[0]); 5956 break; 5957 case bcmFieldActionGpDscpNew: 5958 PolicyCheck(unit, FP_POLICY_TABLEm, NEWDSCP_TOSf, fa->param[0]); 5959 break; 5960 default: 5961 return (BCM_E_NONE); 5962 } 5963 } 5964 return BCM_E_NONE; 5965 } 5966 5967 /* 5968 * Function: 5969 * _field_raptor_meter_action_set 5970 * Purpose: 5971 * Get metering portion of Policy Table. 5972 * Parameters: 5973 * unit - BCM Unit 5974 * f_ent - entry structure to get tcam info from. 5975 * p_entry - (OUT) Policy hardware entry 5976 * Returns: 5977 * BCM_E_NONE - Success 5978 * Note: 5979 * Unit lock should be held by calling function. 5980 */ 5981 STATIC int 5982 _field_raptor_meter_action_set(int unit, _field_entry_t *f_ent, 5983 fp_policy_table_entry_t *p_entry) 5984 { 5985 _field_policer_t *f_pl; 5986 uint32 meter_pair_mode; 5987 5988 if ((NULL == f_ent) || (NULL == p_entry)) { 5989 return (BCM_E_PARAM); 5990 } 5991 5992 BCM_IF_ERROR_RETURN 5993 (_bcm_field_policer_get(unit, f_ent->policer[0].pid, &f_pl)); 5994 5995 if (((f_ent->flags & _FP_ENTRY_PRIMARY) && 5996 (f_ent->flags & _FP_ENTRY_POLICER_IN_SECONDARY_SLICE))) { 5997 /* If no meter, install default meter pair mode. 5998 * Default meter pair mode doesn't need to burn a real meter. 5999 */ 6000 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, METER_PAIR_MODEf, 0); 6001 return (BCM_E_NONE); 6002 } 6003 6004 /* Get hw encoding for meter mode. */ 6005 BCM_IF_ERROR_RETURN 6006 (_bcm_field_meter_pair_mode_get(unit, f_pl, &meter_pair_mode)); 6007 6008 6009 /* Set the even and odd indexes from the entry */ 6010 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, METER_INDEX_EVENf, 6011 f_pl->hw_index); 6012 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, METER_INDEX_ODDf, 6013 f_pl->hw_index); 6014 6015 /* 6016 * Flow mode is the only one that cares about the test and update bits. 6017 * Even = BCM_FIELD_METER_PEAK 6018 * Odd = BCM_FIELD_METER_COMMITTED 6019 */ 6020 if (_FP_POLICER_EXCESS_HW_METER(f_pl)) { 6021 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, 6022 METER_TEST_EVENf, 1); 6023 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, 6024 METER_UPDATE_EVENf, 1); 6025 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, 6026 METER_TEST_ODDf, 0); 6027 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, 6028 METER_UPDATE_ODDf, 0); 6029 } else if (_FP_POLICER_COMMITTED_HW_METER(f_pl)) { 6030 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, 6031 METER_TEST_EVENf, 0); 6032 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, 6033 METER_UPDATE_EVENf, 0); 6034 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, 6035 METER_TEST_ODDf, 1); 6036 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, 6037 METER_UPDATE_ODDf, 1); 6038 } 6039 6040 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, METER_PAIR_MODEf, 6041 meter_pair_mode); 6042 return BCM_E_NONE; 6043 } 6044 6045 /* 6046 * Function: 6047 * _field_raptor_entry_remove 6048 * Purpose: 6049 * Remove a previously installed physical entry. 6050 * Parameters: 6051 * unit - BCM device number 6052 * f_ent - Physical entry data 6053 * tcam_idx - TCAM index to remove entry from. 6054 * Returns: 6055 * BCM_E_XXX 6056 * BCM_E_NONE 6057 * Notes: 6058 * FP unit lock should be held by calling function. 6059 * Not clearing the policy, ipbm tables; only TCAM. 6060 */ 6061 STATIC int 6062 _field_raptor_entry_remove(int unit, _field_entry_t *f_ent, int tcam_idx) 6063 { 6064 fp_tcam_entry_t t_entry; 6065 6066 sal_memcpy(&t_entry, soc_mem_entry_null(unit, FP_TCAMm), 6067 sizeof(t_entry)); 6068 soc_FP_TCAMm_field32_set(unit, &t_entry, VALIDf, 0); 6069 6070 SOC_IF_ERROR_RETURN(WRITE_FP_TCAMm(unit, MEM_BLOCK_ALL, 6071 tcam_idx, &t_entry)); 6072 6073 f_ent->flags |= _FP_ENTRY_DIRTY; /* Mark entry as not installed */ 6074 6075 return BCM_E_NONE; 6076 } 6077 6078 /* 6079 * Function: 6080 * _field_raptor_tables_entry_clear 6081 * Purpose: 6082 * Writes a null entry into the the tables. 6083 * Parameters: 6084 * unit - (IN)BCM device number. 6085 * stage_id - (IN)FP stage pipeline id. 6086 * tcam_idx - (IN)Entry tcam index. 6087 * Returns: 6088 * BCM_E_XXX 6089 * Note: 6090 * Unit lock should be held by calling function. 6091 * Not clearing the policy, ipbm tables, only TCAM. 6092 */ 6093 STATIC int 6094 _field_raptor_tables_entry_clear(int unit, _field_entry_t *f_ent, 6095 _field_stage_id_t stage_id, int tcam_idx) 6096 { 6097 fp_tcam_entry_t t_entry; 6098 6099 if (_BCM_FIELD_STAGE_INGRESS != stage_id) { 6100 return (BCM_E_PARAM); 6101 } 6102 6103 /* Memory index sanity check. */ 6104 if (tcam_idx > soc_mem_index_max(unit, FP_TCAMm)) { 6105 return (BCM_E_PARAM); 6106 } 6107 6108 sal_memcpy(&t_entry, soc_mem_entry_null(unit, FP_TCAMm), 6109 sizeof(t_entry)); 6110 6111 soc_FP_TCAMm_field32_set(unit, &t_entry, VALIDf, 0); 6112 6113 SOC_IF_ERROR_RETURN(WRITE_FP_TCAMm(unit, MEM_BLOCK_ALL, 6114 tcam_idx, &t_entry)); 6115 6116 return (BCM_E_NONE); 6117 } 6118 6119 6120 /* 6121 * Function: 6122 * _field_raptor_entry_rule_copy 6123 * Purpose: 6124 * Helper function for _field_raptor_entry_move_single/double/triple 6125 * Parameters: 6126 * unit - BCM unit 6127 * old_index - old index 6128 * new_index - new_index 6129 * Returns: 6130 * BCM_E_XXX - Hardware R/W errors 6131 * BCM_E_NONE - Success 6132 * Note: 6133 */ 6134 STATIC int 6135 _field_raptor_entry_rule_copy(int unit, int old_index, int new_index) 6136 { 6137 fp_tcam_entry_t t_entry; 6138 6139 /* Read the entry rules from current tcam index. */ 6140 SOC_IF_ERROR_RETURN(READ_FP_TCAMm(unit, MEM_BLOCK_ANY, 6141 old_index, &t_entry)); 6142 6143 /* Write these at the new index */ 6144 SOC_IF_ERROR_RETURN(WRITE_FP_TCAMm(unit, MEM_BLOCK_ALL, 6145 new_index, &t_entry)); 6146 6147 return BCM_E_NONE; 6148 } 6149 6150 /* 6151 * Function: 6152 * _field_raptor_entry_rule_del 6153 * Purpose: 6154 * Helper function for _field_raptor_entry_move_single/double/triple 6155 * Parameters: 6156 * unit - BCM unit 6157 * index - old index 6158 * Returns: 6159 * BCM_E_XXX - Hardware R/W errors 6160 * BCM_E_NONE - Success 6161 * Note: 6162 */ 6163 STATIC int 6164 _field_raptor_entry_rule_del(int unit, int index) 6165 { 6166 fp_tcam_entry_t t_entry; 6167 6168 /* Invalidate index entry. */ 6169 sal_memcpy(&t_entry, soc_mem_entry_null(unit, FP_TCAMm), 6170 sizeof(t_entry)); 6171 soc_FP_TCAMm_field32_set(unit, &t_entry, VALIDf, 0); 6172 6173 SOC_IF_ERROR_RETURN(WRITE_FP_TCAMm(unit, MEM_BLOCK_ALL, 6174 index, &t_entry)); 6175 6176 return BCM_E_NONE; 6177 } 6178 6179 /* 6180 * Function: 6181 * _field_raptor_entry_ipbm_copy 6182 * Purpose: 6183 * Helper function for _field_raptor_entry_move_single/double/triple 6184 * Parameters: 6185 * unit - BCM device number. 6186 * f_ent - Field entry structure. 6187 * part - Entry part. 6188 * new_tcam_idx - New tcam index. 6189 * Returns: 6190 * 6191 * Note: 6192 */ 6193 STATIC int 6194 _field_raptor_entry_ipbm_copy(int unit, _field_entry_t *f_ent, 6195 int part, int tcam_idx_new) 6196 { 6197 bcm_port_config_t port_config;/* Device port config structure. */ 6198 int new_slice_numb = 0; /* Entry new slice number. */ 6199 int new_slice_idx = 0; /* Entry new offset in a slice */ 6200 _field_stage_t *stage_fc; /* Stage field control structure.*/ 6201 int old_slice_num; /* Entry's old slice number. */ 6202 bcm_port_t p; /* Port number iterator. */ 6203 uint32 value = 0; /* IPBM value. */ 6204 int ipbm_index; /* IPBM index. */ 6205 int rv; /* Opeartion return status. */ 6206 6207 if (NULL == f_ent) { 6208 return (BCM_E_PARAM); 6209 } 6210 6211 /* Read device port configuration. */ 6212 BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config)); 6213 6214 /* Get stage field control structure. */ 6215 rv = _field_stage_control_get(unit, f_ent->group->stage_id, &stage_fc); 6216 BCM_IF_ERROR_RETURN(rv); 6217 6218 old_slice_num = f_ent->fs->slice_number; 6219 6220 /* Calculate primary entry new slice & offset in the slice. */ 6221 rv = _bcm_field_tcam_idx_to_slice_offset(unit, stage_fc, _FP_DEF_INST, 6222 tcam_idx_new, &new_slice_numb, 6223 &new_slice_idx); 6224 BCM_IF_ERROR_RETURN(rv); 6225 6226 PBMP_ITER(port_config.all, p) { 6227 ipbm_index = _BCM_RP_FIELD_IPBM_INDEX(unit, p, old_slice_num); 6228 BCM_IF_ERROR_RETURN(_field_raptor_ipbm_entry_get(unit, ipbm_index, 6229 f_ent->slice_idx, 6230 &value)); 6231 ipbm_index = _BCM_RP_FIELD_IPBM_INDEX(unit, p, new_slice_numb); 6232 BCM_IF_ERROR_RETURN(_field_raptor_ipbm_entry_set(unit, ipbm_index, 6233 new_slice_idx, value)); 6234 } 6235 return BCM_E_NONE; 6236 } 6237 6238 /* 6239 * Function: 6240 * _field_raptor_entry_move 6241 * Purpose: 6242 * Moves an entry (rules + policies) from one index to another. 6243 * It copies the values in hardware from the old index 6244 * to the new index. The old index is then cleared and set invalid. 6245 * Parameters: 6246 * unit - BCM device number. 6247 * f_ent - Field entry pointer. 6248 * parts_count - (IN) Field entry parts count. 6249 * tcam_idx_old - (IN) Source entry tcam index. 6250 * tcam_idx_new - (IN) Destination entry tcam index. 6251 * Returns: 6252 * BCM_E_XXX 6253 */ 6254 STATIC int 6255 _field_raptor_entry_move(int unit, _field_entry_t *f_ent, int parts_count, 6256 int *tcam_idx_old, int *tcam_idx_new) 6257 { 6258 fp_policy_table_entry_t p_entry[_FP_MAX_ENTRY_WIDTH]; 6259 _field_policer_t *f_pl = NULL; /* Field policer descriptor. */ 6260 _field_stat_t *f_st = NULL; /* Field statistic descriptor. */ 6261 _field_group_t *fg; /* Field group structure. */ 6262 int new_slice_numb = 0; /* Entry new slice number. */ 6263 int new_slice_idx = 0; /* Entry new offset in a slice */ 6264 _field_stage_t *stage_fc; /* Stage control structure. */ 6265 int idx; /* Entry parts iterator. */ 6266 int rv; /* Operation return status. */ 6267 int is_backup_entry = 0; /* Flag ,checks the entry is backup entry or not*/ 6268 int const tcam_idx_max = soc_mem_index_max(unit, FP_TCAMm); 6269 6270 if ((NULL == f_ent) || (NULL == tcam_idx_old) || (NULL == tcam_idx_new)) { 6271 return (BCM_E_PARAM); 6272 } 6273 6274 fg = f_ent->group; 6275 6276 /* Get stage field control structure. */ 6277 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 6278 BCM_IF_ERROR_RETURN(rv); 6279 6280 /* Get number of entry parts. */ 6281 rv = _bcm_field_entry_tcam_parts_count (unit, fg->stage_id, 6282 fg->flags, &parts_count); 6283 BCM_IF_ERROR_RETURN(rv); 6284 6285 /* Update policy entry if moving across the slices. */ 6286 if (((NULL != f_ent->ent_copy) && 6287 (f_ent->ent_copy->eid == _FP_INTERNAL_RESERVED_ID))) { 6288 is_backup_entry = 1; 6289 } 6290 6291 /* Entry read & destination clear loop. */ 6292 for (idx = 0; idx < parts_count; idx++) { 6293 /* Index sanity check. */ 6294 if ((tcam_idx_old[idx] < 0) || (tcam_idx_old[idx] > tcam_idx_max) || 6295 (tcam_idx_new[idx] < 0) || (tcam_idx_new[idx] > tcam_idx_max)) { 6296 return (BCM_E_PARAM); 6297 } 6298 6299 /* Invalidate the entry at new index 6300 * To avoid intermediate state as there are 3 tables in raptor: 6301 * ipbm, rules, policy */ 6302 rv = _field_raptor_entry_rule_del(unit, tcam_idx_new[idx]); 6303 BCM_IF_ERROR_RETURN(rv); 6304 6305 /* Copy the IPBM */ 6306 rv = _field_raptor_entry_ipbm_copy(unit, f_ent + idx, idx, tcam_idx_new[idx]); 6307 BCM_IF_ERROR_RETURN(rv); 6308 6309 /* Copy the policies */ 6310 /* Read the entry policies from current index. */ 6311 rv = READ_FP_POLICY_TABLEm(unit, MEM_BLOCK_ANY, tcam_idx_old[idx], 6312 p_entry + idx); 6313 BCM_IF_ERROR_RETURN(rv); 6314 6315 } 6316 6317 /* Calculate primary entry new slice & offset in the slice. */ 6318 rv = _bcm_field_tcam_idx_to_slice_offset(unit, stage_fc, _FP_DEF_INST, 6319 tcam_idx_new[0], 6320 &new_slice_numb, &new_slice_idx); 6321 BCM_IF_ERROR_RETURN(rv); 6322 6323 /* Update policy entry if moving across the slices. */ 6324 if ((1 != is_backup_entry) && (f_ent->slice_idx != new_slice_numb)) { 6325 if ( (f_ent->policer[0].flags & _FP_POLICER_INSTALLED)) { 6326 rv = _bcm_field_policer_get(unit, f_ent->policer[0].pid, &f_pl); 6327 BCM_IF_ERROR_RETURN(rv); 6328 } 6329 if ( (f_ent->statistic.flags & _FP_ENTRY_STAT_INSTALLED)) { 6330 rv = _bcm_field_stat_get(unit, f_ent->statistic.sid, &f_st); 6331 BCM_IF_ERROR_RETURN(rv); 6332 } 6333 6334 if (fg->flags & _FP_GROUP_SPAN_SINGLE_SLICE) { 6335 if (NULL != f_st) { 6336 /* 6337 * Set the index of the counter for entry in new slice 6338 * The new index has already been calculated in 6339 * _field_entry_move 6340 */ 6341 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, COUNTER_INDEXf, 6342 f_st->hw_index); 6343 } 6344 if (NULL != f_pl) { 6345 /* 6346 * Set the index of the meter for entry in new slice 6347 * The new index has already been calculated in 6348 * _field_entry_move 6349 */ 6350 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, METER_INDEX_EVENf, 6351 f_pl->hw_index); 6352 soc_FP_POLICY_TABLEm_field32_set(unit, p_entry, METER_INDEX_ODDf, 6353 f_pl->hw_index); 6354 } 6355 } else { 6356 if (NULL != f_st) { 6357 _bcm_field_fb_counter_adjust_wide_mode(unit, FP_POLICY_TABLEm, 6358 f_st, f_ent, f_ent + 1, 6359 new_slice_numb, 6360 (uint32*)&p_entry[0], 6361 (uint32*)&p_entry[1]); 6362 } 6363 if (NULL != f_pl) { 6364 _bcm_field_fb_meter_adjust_wide_mode(unit, FP_POLICY_TABLEm, 6365 f_pl, f_ent, f_ent + 1, 6366 (uint32*)&p_entry[0], 6367 (uint32*)&p_entry[1]); 6368 } 6369 } 6370 } 6371 6372 /* 6373 * Write entry to the destination 6374 * ORDER is important 6375 */ 6376 for (idx = parts_count - 1; idx >= 0; idx--) { 6377 6378 /* Write these at the new index */ 6379 rv = WRITE_FP_POLICY_TABLEm(unit, MEM_BLOCK_ALL, tcam_idx_new[idx], 6380 p_entry + idx); 6381 BCM_IF_ERROR_RETURN(rv); 6382 6383 /* Copy rules */ 6384 rv = _field_raptor_entry_rule_copy(unit, tcam_idx_old[idx], 6385 tcam_idx_new[idx]); 6386 BCM_IF_ERROR_RETURN(rv); 6387 } 6388 6389 /* 6390 * fp_entry_move is invoked even for backup entry create 6391 * to copy TCAM and FP_POLICY_TABLE tables. In this case 6392 * TCAM and FP_POLICY_TABLEs should not be erased for 6393 * original entry. 6394 */ 6395 if (1 != is_backup_entry) { 6396 /* 6397 * Clear old location 6398 * ORDER is important 6399 */ 6400 for (idx = 0; idx < parts_count; idx++) { 6401 /* Invalidate the old entries */ 6402 rv = _field_raptor_entry_rule_del(unit, tcam_idx_old[idx]); 6403 } 6404 } 6405 return BCM_E_NONE; 6406 } 6407 6408 /* 6409 * Function: _bcm_field_raven_qualify_ttl_get 6410 * 6411 * Purpose: 6412 * Add a field qualification to a filter entry. 6413 * 6414 * Parameters: 6415 * unit - (IN)BCM device number 6416 * entry - (IN)Field entry array. 6417 * data - (OUT)Data to qualify with 6418 * mask - (OUT)Mask to qualify with 6419 * 6420 * Returns: 6421 * BCM_E_XXX Other errors 6422 */ 6423 int 6424 _bcm_field_raven_qualify_ttl_get(int unit, bcm_field_entry_t entry, 6425 uint8 *data, uint8 *mask) 6426 { 6427 _field_entry_t *entry_arr[_FP_MAX_ENTRY_WIDTH]; 6428 _field_group_t *fg = NULL; 6429 uint8 result; 6430 int entry_idx = -1; 6431 int rv; 6432 6433 rv = _bcm_field_entry_get_by_id(unit, entry, entry_arr); 6434 BCM_IF_ERROR_RETURN(rv); 6435 6436 fg = entry_arr[0]->group; 6437 /* Check if ttl is part of group qset. */ 6438 rv = _bcm_field_qset_test(bcmFieldQualifyTtl, &fg->qset, &result); 6439 BCM_IF_ERROR_RETURN(rv); 6440 6441 if (TRUE == result) { 6442 return _bcm_field_entry_qualifier_uint8_get(unit, entry, 6443 bcmFieldQualifyTtl, 6444 data, mask); 6445 } 6446 6447 /* Find the entry for which f4 == 0 and write TTL_ENCODE */ 6448 if (fg->flags & _FP_GROUP_SPAN_SINGLE_SLICE) { 6449 if (fg->sel_codes[0].fpf4 != 1) { 6450 entry_idx = 0; 6451 } 6452 } else if (fg->flags & _FP_GROUP_SPAN_DOUBLE_SLICE) { 6453 if (fg->sel_codes[0].fpf4 != 1) { 6454 entry_idx = 0; 6455 } else if (fg->sel_codes[1].fpf4 != 1) { 6456 entry_idx = 1; 6457 } 6458 } else if (fg->flags & _FP_GROUP_SPAN_TRIPLE_SLICE) { 6459 if (fg->sel_codes[0].fpf4 != 1) { 6460 entry_idx = 0; 6461 } else if (fg->sel_codes[1].fpf4 != 1) { 6462 entry_idx = 1; 6463 } else if (fg->sel_codes[2].fpf4 != 1) { 6464 entry_idx = 2; 6465 } 6466 } 6467 6468 if (entry_idx == -1) { 6469 return BCM_E_PARAM; 6470 } 6471 6472 /* bcmFieldQualifyTtl not present, use TTL_ENCODE (if present) */ 6473 switch (entry_arr[entry_idx]->tcam.f4 & 0x3) { 6474 case 0: 6475 *data = 0x0; 6476 *mask = 0xff; 6477 break; 6478 case 1: 6479 *data = 0x1; 6480 *mask = 0x3; 6481 break; 6482 case 3: 6483 *data = 0xff; 6484 *mask = 0xff; 6485 break; 6486 default: 6487 return (BCM_E_UNAVAIL); 6488 } 6489 return BCM_E_NONE; 6490 } 6491 6492 /* 6493 * Function: _bcm_field_raven_qualify_ttl 6494 * 6495 * Purpose: 6496 * Add a field qualification to a filter entry. 6497 * 6498 * Parameters: 6499 * unit - BCM device number 6500 * entry - Field entry array. 6501 * data - Data to qualify with 6502 * mask - Mask to qualify with 6503 * 6504 * Returns: 6505 * BCM_E_XXX Other errors 6506 */ 6507 int 6508 _bcm_field_raven_qualify_ttl(int unit, bcm_field_entry_t entry, 6509 uint8 data, uint8 mask) 6510 { 6511 _field_entry_t *entry_arr[_FP_MAX_ENTRY_WIDTH]; 6512 _field_group_t *fg = NULL; 6513 uint8 result; 6514 int entry_idx = -1; 6515 int rv; 6516 6517 rv = _bcm_field_entry_get_by_id(unit, entry, entry_arr); 6518 BCM_IF_ERROR_RETURN(rv); 6519 6520 fg = entry_arr[0]->group; 6521 /* Check if ttl is part of group qset. */ 6522 rv = _bcm_field_qset_test(bcmFieldQualifyTtl, &fg->qset, &result); 6523 BCM_IF_ERROR_RETURN(rv); 6524 6525 if (TRUE == result) { 6526 return _field_qualify32(unit, entry, bcmFieldQualifyTtl, data, mask); 6527 } 6528 6529 /* bcmFieldQualifyTtl not present, use TTL_ENCODE (if present) */ 6530 switch (data & mask) { 6531 case 0: 6532 data = 0x0; 6533 mask &= 0x3; 6534 break; 6535 case 1: 6536 data = 0x1; 6537 mask &= 0x3; 6538 break; 6539 case 255: 6540 data = 0x3; 6541 mask &= 0x3; 6542 break; 6543 default: 6544 data = 0x2; 6545 mask &= 0x3; 6546 } 6547 6548 /* Find the entry for which f4 == 0 and write TTL_ENCODE */ 6549 if (fg->flags & _FP_GROUP_SPAN_SINGLE_SLICE) { 6550 if (fg->sel_codes[0].fpf4 != 1) { 6551 entry_idx = 0; 6552 } 6553 } else if (fg->flags & _FP_GROUP_SPAN_DOUBLE_SLICE) { 6554 if (fg->sel_codes[0].fpf4 != 1) { 6555 entry_idx = 0; 6556 } else if (fg->sel_codes[1].fpf4 != 1) { 6557 entry_idx = 1; 6558 } 6559 } else if (fg->flags & _FP_GROUP_SPAN_TRIPLE_SLICE) { 6560 if (fg->sel_codes[0].fpf4 != 1) { 6561 entry_idx = 0; 6562 } else if (fg->sel_codes[1].fpf4 != 1) { 6563 entry_idx = 1; 6564 } else if (fg->sel_codes[2].fpf4 != 1) { 6565 entry_idx = 2; 6566 } 6567 } 6568 6569 if (entry_idx == -1) { 6570 return BCM_E_PARAM; 6571 } 6572 6573 entry_arr[entry_idx]->tcam.f4 &= ~(mask); 6574 entry_arr[entry_idx]->tcam.f4 |= data; 6575 6576 entry_arr[entry_idx]->tcam.f4_mask &= ~(mask); 6577 entry_arr[entry_idx]->tcam.f4_mask |= mask; 6578 6579 entry_arr[entry_idx]->flags |= _FP_ENTRY_DIRTY; 6580 return BCM_E_NONE; 6581 } 6582 #else 6583 int _raptor_field_not_empty; 6584 #endif /* BCM_RAPTOR_SUPPORT) && BCM_FIELD_SUPPORT */