field_wb.c (764817B)
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 module routines specific to BCM56960 9 */ 10 #include <bcm/error.h> 11 #include <bcm_int/esw/field.h> 12 #include <bcm_int/esw/tomahawk.h> 13 #include <soc/drv.h> 14 #include <soc/scache.h> 15 #include <bcm_int/esw/mirror.h> 16 #include <bcm_int/esw/tomahawk.h> 17 #include <bcm_int/esw/virtual.h> 18 #include <bcm_int/esw/trunk.h> 19 #include <bcm_int/esw/trx.h> 20 #include "include/soc/esw/cancun.h" 21 22 #if defined(BCM_TOMAHAWK3_SUPPORT) 23 #include <bcm_int/esw/tomahawk3.h> 24 #endif 25 26 #if defined(BCM_HELIX5_SUPPORT) 27 #include <bcm_int/esw/helix5.h> 28 #endif 29 30 #ifdef BCM_WARM_BOOT_SUPPORT 31 #ifdef BCM_TOMAHAWK_SUPPORT 32 33 extern uint8 em_action_profile_bitmap[17]; 34 extern uint8 em_th2_action_profile_bitmap[23]; 35 extern uint8 em_td3_action_profile_bitmap[37]; 36 extern uint8 ifp_td3_action_profile_bitmap[44]; 37 extern uint8 em_th3_action_profile_bitmap[24]; 38 39 typedef struct _field_wb_em_actions_addr_s { 40 bcm_field_action_t action; /* Action to sync */ 41 _field_action_bmp_t ent_bmp; /* Entry tcam idx and pipe pbm */ 42 } _field_wb_em_act_ent_bmp_t; 43 44 void *tlv_em_act[BCM_MAX_NUM_UNITS]; 45 #define _FP_EM_NUM_WB_SUPPORTED_ACTIONS 50 46 47 #define _FP_IS_EM_WB_ACTION(_x_) (((_x_) == bcmFieldActionAssignOpaqueObject1) \ 48 ||((_x_) == bcmFieldActionGbpSrcIdNew) \ 49 ||((_x_) == bcmFieldActionAssignOpaqueObject2) \ 50 ||((_x_) == bcmFieldActionEgressFlowControlEnable) \ 51 ||((_x_) == bcmFieldActionAssignNatClassId) \ 52 ||((_x_) == bcmFieldActionAssignChangeL2FieldsClassId) \ 53 ||((_x_) == bcmFieldActionAssignOpaqueObject3) \ 54 ||((_x_) == bcmFieldActionGbpDstIdNew)) 55 int 56 _field_wb_change_cpu_cos_set_recover(int unit, _field_entry_t *f_ent, 57 uint32 *ebuf, _field_action_bmp_t *act_bmp); 58 int 59 _field_wb_mirror_set_recover(int unit, _field_entry_t *f_ent, 60 uint32 *ebuf, _field_action_bmp_t *act_bmp); 61 int 62 _field_wb_l3swl2_set_recover(int unit, _field_entry_t *f_ent, 63 uint32 *ebuf, _field_action_bmp_t *act_bmp); 64 int 65 _field_wb_emredirect_set_recover(int unit, _field_entry_t *f_ent, 66 uint32 *ebuf, _field_action_bmp_t *act_bmp); 67 int 68 _field_wb_counter_set_recover(int unit, _field_entry_t *f_ent, 69 uint32 *ebuf, _field_action_bmp_t *act_bmp); 70 int 71 _field_wb_change_ecn_set_recover(int unit, _field_entry_t *f_ent, 72 uint32 *act_data, _field_action_bmp_t *act_bmp); 73 int 74 _field_wb_pkt_pri_set_recover(int unit, _field_entry_t *f_ent, 75 uint32 *act_data, _field_action_bmp_t *act_bmp); 76 int 77 _field_wb_extraction_ctrl_id_set_recover(int unit, _field_entry_t *f_ent, 78 uint32 *ebuf, 79 _field_action_bmp_t *act_bmp); 80 int 81 _field_wb_edit_ctrl_id_set_recover(int unit, _field_entry_t *f_ent, 82 uint32 *ebuf, _field_action_bmp_t *act_bmp); 83 int 84 _field_wb_opaque1_set_recover(int unit, _field_entry_t *f_ent, uint32 *ebuf, 85 _field_action_bmp_t *act_bmp); 86 int 87 _field_wb_opaque2_set_recover(int unit, _field_entry_t *f_ent, uint32 *ebuf, 88 _field_action_bmp_t *act_bmp); 89 int 90 _field_wb_opaque3_set_recover(int unit, _field_entry_t *f_ent, uint32 *ebuf, 91 _field_action_bmp_t *act_bmp); 92 int 93 _field_wb_opaque4_set_recover(int unit, _field_entry_t *f_ent, uint32 *ebuf, 94 _field_action_bmp_t *act_bmp); 95 96 void* _field_wb_action_recovery_func_ptr[_FieldActionSetCount] = { 97 NULL, /* _FieldActionSetNone */ 98 NULL, 99 /* _FieldActionProtectionSwitchingDropOverrideSet */ 100 NULL, 101 /* _FieldActionIfpDlbAlternatePathControlSet */ 102 NULL, /* _FieldActionEcmpDlbActionSet */ 103 NULL, /* _FieldActionHgtLagDlbActionSet */ 104 NULL, /* _FieldActionEcmp2RhActionSet */ 105 NULL, /* _FieldActionEcmp1RhActionSet */ 106 NULL, /* _FieldActionLagRhActionSet */ 107 NULL, /* _FieldActionHgtRhActionSet*/ 108 NULL, /* _FieldActionLoopbackProfileSet */ 109 _field_wb_extraction_ctrl_id_set_recover, /* _FieldActionExtractionCtrlId */ 110 _field_wb_opaque4_set_recover, /* _FieldActionOpaque4Set */ 111 _field_wb_opaque3_set_recover, /* _FieldActionOpaque3Set */ 112 _field_wb_opaque2_set_recover, /* _FieldActionOpaque2Set */ 113 _field_wb_opaque1_set_recover, /* _FieldActionOpaque1Set */ 114 NULL, /*_FieldActionTxTimestampInsertionSet */ 115 NULL, /*_FieldActionRxTimestampInsertionSet */ 116 NULL, /*_FieldActionIgnoreFCOEZoneCheckSet */ 117 NULL, 118 /* _FieldActionGreenToPidSet */ 119 NULL, 120 /* _FieldActionMirrorOverrideSet */ 121 NULL, 122 /* _FieldActionNatOverrideSet */ 123 NULL, 124 /* _FieldActionSflowSet */ 125 NULL, 126 /* _FieldActionCutThrOverrideSet */ 127 NULL, 128 /* _FieldActionUrpfOverrideSet */ 129 NULL, 130 /* _FieldActionTtlOverrideSet */ 131 NULL, 132 /* _FieldActionLbControlSet */ 133 NULL, 134 /* _FieldActionDropSet */ 135 _field_wb_change_cpu_cos_set_recover, 136 /* _FieldActionChangeCpuCosSet */ 137 _field_wb_mirror_set_recover, 138 /* _FieldActionMirrorSet */ 139 NULL, 140 /* _FieldActionNatSet */ 141 NULL, 142 /* _FieldActionCopyToCpuSet */ 143 _field_wb_l3swl2_set_recover, 144 /* _FieldActionL3SwChangeL2Set */ 145 _field_wb_emredirect_set_recover, 146 /* IFP _FieldActionRedirectSet */ 147 _field_wb_counter_set_recover, 148 /* _FieldActionCounterSet */ 149 _field_wb_change_ecn_set_recover, 150 /* _FieldActionChangeEcnSet */ 151 _field_wb_pkt_pri_set_recover, 152 /* _FieldActionChangePktPriSet */ 153 NULL, 154 /* _FieldActionChangeDscpTosSet */ 155 NULL, 156 /*_FieldActionChangeDropPrecendenceSet */ 157 NULL, 158 /* _FieldActionChangeCosOrIntPriSet */ 159 NULL, 160 /* _FieldActionChangeIntCNSet */ 161 NULL, 162 /* _FieldActionChangeInputPrioritySet */ 163 NULL, 164 /* _FieldActionInstrumentationSet */ 165 _field_wb_edit_ctrl_id_set_recover, /* _FieldActionEditCtrlIdSet */ 166 NULL, /* _FieldActionFcoeVsanSet */ 167 NULL, 168 /*_FieldActionMeterSet */ 169 NULL 170 /*_FieldActionTimestampInsertionSet*/ 171 }; 172 173 STATIC int _aset_fcoe_vsan_act_arr[] = { 174 bcmFieldActionFibreChanIntVsanPri, 175 bcmFieldActionFibreChanVsanId, 176 bcmFieldActionCount 177 }; 178 179 STATIC int _aset_timestamp_act_arr[] = { 180 bcmFieldActionIngressTimeStampInsert, 181 bcmFieldActionIngressTimeStampInsertCancel, 182 bcmFieldActionEgressTimeStampInsert, 183 bcmFieldActionEgressTimeStampInsertCancel, 184 bcmFieldActionCount 185 }; 186 187 STATIC int _aset_change_int_cn_act_arr[] = { 188 bcmFieldActionGpIntCongestionNotificationNew, 189 bcmFieldActionYpIntCongestionNotificationNew, 190 bcmFieldActionRpIntCongestionNotificationNew, 191 bcmFieldActionCount 192 }; 193 194 STATIC int _aset_nat_act_arr[] = { 195 bcmFieldActionNat, 196 bcmFieldActionNatEgressOverride, 197 bcmFieldActionCount 198 }; 199 200 STATIC int _aset_change_ecn_act_arr[] = { 201 bcmFieldActionRpEcnNew, 202 bcmFieldActionYpEcnNew, 203 bcmFieldActionGpEcnNew, 204 bcmFieldActionEcnNew, 205 bcmFieldActionCount 206 }; 207 208 STATIC int _aset_cos_or_int_pri_act_arr[] = { 209 bcmFieldActionPrioIntNew, 210 bcmFieldActionGpPrioIntNew, 211 bcmFieldActionYpPrioIntNew, 212 bcmFieldActionRpPrioIntNew, 213 bcmFieldActionPrioIntCopy, 214 bcmFieldActionRpPrioIntCopy, 215 bcmFieldActionGpPrioIntCopy, 216 bcmFieldActionYpPrioIntCopy, 217 bcmFieldActionPrioIntTos, 218 bcmFieldActionRpPrioIntTos, 219 bcmFieldActionGpPrioIntTos, 220 bcmFieldActionYpPrioIntTos, 221 bcmFieldActionPrioIntCancel, 222 bcmFieldActionRpPrioIntCancel, 223 bcmFieldActionGpPrioIntCancel, 224 bcmFieldActionYpPrioIntCancel, 225 bcmFieldActionCosQNew, 226 bcmFieldActionRpCosQNew, 227 bcmFieldActionGpCosQNew, 228 bcmFieldActionYpCosQNew, 229 bcmFieldActionCosMapNew, 230 bcmFieldActionRpCosMapNew, 231 bcmFieldActionGpCosMapNew, 232 bcmFieldActionYpCosMapNew, 233 bcmFieldActionUcastCosQNew, 234 bcmFieldActionRpUcastCosQNew, 235 bcmFieldActionGpUcastCosQNew, 236 bcmFieldActionYpUcastCosQNew, 237 bcmFieldActionMcastCosQNew, 238 bcmFieldActionRpMcastCosQNew, 239 bcmFieldActionGpMcastCosQNew, 240 bcmFieldActionYpMcastCosQNew, 241 bcmFieldActionCount 242 }; 243 244 STATIC int _aset_instrumentation_act_arr[] = { 245 bcmFieldActionPacketTraceEnable, 246 bcmFieldActionCount 247 }; 248 249 STATIC int _aset_change_pkt_pri_act_arr[] = { 250 bcmFieldActionPrioPktCopy, 251 bcmFieldActionPrioPktNew, 252 bcmFieldActionPrioPktCancel, 253 bcmFieldActionPrioPktTos, 254 bcmFieldActionDot1pPreserve, 255 bcmFieldActionGpPrioPktCopy, 256 bcmFieldActionGpPrioPktNew, 257 bcmFieldActionGpPrioPktCancel, 258 bcmFieldActionGpPrioPktTos, 259 bcmFieldActionGpDot1pPreserve, 260 bcmFieldActionRpPrioPktCopy, 261 bcmFieldActionRpPrioPktNew, 262 bcmFieldActionRpPrioPktCancel, 263 bcmFieldActionRpPrioPktTos, 264 bcmFieldActionRpDot1pPreserve, 265 bcmFieldActionYpPrioPktCopy, 266 bcmFieldActionYpPrioPktNew, 267 bcmFieldActionYpPrioPktCancel, 268 bcmFieldActionYpPrioPktTos, 269 bcmFieldActionYpDot1pPreserve, 270 bcmFieldActionCount 271 }; 272 273 STATIC int _aset_change_dscp_tos_act_arr[] = { 274 bcmFieldActionDscpNew, 275 bcmFieldActionDscpCancel, 276 bcmFieldActionDscpPreserve, 277 bcmFieldActionRpDscpNew, 278 bcmFieldActionRpDscpCancel, 279 bcmFieldActionRpDscpPreserve, 280 bcmFieldActionYpDscpNew, 281 bcmFieldActionYpDscpCancel, 282 bcmFieldActionYpDscpPreserve, 283 bcmFieldActionGpDscpNew, 284 bcmFieldActionGpDscpCancel, 285 bcmFieldActionGpDscpPreserve, 286 bcmFieldActionGpTosPrecedenceNew, 287 bcmFieldActionGpTosPrecedenceCopy, 288 bcmFieldActionCount 289 }; 290 291 STATIC int _aset_drop_precedence_act_arr[] = { 292 bcmFieldActionGpDropPrecedence, 293 bcmFieldActionYpDropPrecedence, 294 bcmFieldActionRpDropPrecedence, 295 bcmFieldActionDropPrecedence, 296 bcmFieldActionCount 297 }; 298 299 STATIC int _aset_change_input_priority_act_arr[] = { 300 bcmFieldActionUntaggedPacketPriorityNew, 301 bcmFieldActionPfcClassNew, 302 bcmFieldActionCount 303 }; 304 305 STATIC int _aset_ttl_override_act_arr[] = { 306 bcmFieldActionDoNotChangeTtl, 307 bcmFieldActionCount 308 }; 309 310 STATIC int _aset_urpf_override_act_arr[] = { 311 bcmFieldActionDoNotCheckUrpf, 312 bcmFieldActionCount 313 }; 314 315 STATIC int _aset_cut_thru_override_act_arr[] = { 316 bcmFieldActionDoNotCutThrough, 317 bcmFieldActionCount 318 }; 319 320 STATIC int _aset_protection_switching_act_arr[] = { 321 bcmFieldActionRecoverableDropCancel, 322 bcmFieldActionCount 323 }; 324 325 STATIC int _aset_dlb_alternate_path_control_act_arr[] = { 326 bcmFieldActionDgm, 327 bcmFieldActionDgmCost, 328 bcmFieldActionDgmBias, 329 bcmFieldActionDgmThreshold, 330 bcmFieldActionCount 331 }; 332 333 STATIC int _aset_dlb_ecmp_act_arr[] = { 334 bcmFieldActionDynamicEcmpEnable, 335 bcmFieldActionDynamicEcmpCancel, 336 bcmFieldActionCount 337 }; 338 339 STATIC int _aset_dlb_hgt_lag_act_arr[] = { 340 bcmFieldActionDynamicTrunkEnable, 341 bcmFieldActionDynamicTrunkCancel, 342 bcmFieldActionDynamicHgTrunkEnable, 343 bcmFieldActionDynamicHgTrunkCancel, 344 bcmFieldActionCount 345 }; 346 347 STATIC int _aset_ecmp2_rh_act_arr[] = { 348 bcmFieldActionEcmpResilientHashEnable, 349 bcmFieldActionEcmpResilientHashDisable, 350 bcmFieldActionCount 351 }; 352 353 STATIC int _aset_lag_rh_act_arr[] = { 354 bcmFieldActionTrunkResilientHashEnable, 355 bcmFieldActionTrunkResilientHashDisable, 356 bcmFieldActionCount 357 }; 358 359 STATIC int _aset_hgt_rh_act_arr[] = { 360 bcmFieldActionHiGigTrunkResilientHashEnable, 361 bcmFieldActionHiGigTrunkResilientHashDisable, 362 bcmFieldActionCount 363 }; 364 365 STATIC int _aset_loopback_profile_act_arr[] = { 366 bcmFieldActionLoopbackType, 367 bcmFieldActionCount 368 }; 369 370 STATIC int _aset_tx_timestamp_insertion_act_arr[] = { 371 bcmFieldActionEgressTimeStampInsert, 372 bcmFieldActionEgressTimeStampInsertCancel, 373 bcmFieldActionCount 374 }; 375 376 STATIC int _aset_rx_timestamp_insertion_act_arr[] = { 377 bcmFieldActionIngressTimeStampInsert, 378 bcmFieldActionIngressTimeStampInsertCancel, 379 bcmFieldActionCount 380 }; 381 382 STATIC int _aset_ignore_fcoe_zone_check_act_arr[] = { 383 bcmFieldActionFibreChanZoneCheckActionCancel, 384 bcmFieldActionCount 385 }; 386 387 STATIC int _aset_mirror_override_act_arr[] = { 388 bcmFieldActionMirrorOverride, 389 bcmFieldActionCount 390 }; 391 392 STATIC int _aset_nat_override_act_arr[] = { 393 bcmFieldActionNatCancel, 394 bcmFieldActionCount 395 }; 396 397 STATIC int _aset_sflow_act_arr[] = { 398 bcmFieldActionIngSampleEnable, 399 bcmFieldActionCount 400 }; 401 402 STATIC int _aset_lb_controls_act_arr[] = { 403 bcmFieldActionHgTrunkRandomRoundRobinHashCancel, 404 bcmFieldActionTrunkRandomRoundRobinHashCancel, 405 bcmFieldActionEcmpRandomRoundRobinHashCancel, 406 bcmFieldActionCount 407 }; 408 409 STATIC int _aset_drop_act_arr[] = { 410 bcmFieldActionGpDrop, 411 bcmFieldActionGpDropCancel, 412 bcmFieldActionDrop, 413 bcmFieldActionDropCancel, 414 bcmFieldActionYpDrop, 415 bcmFieldActionYpDropCancel, 416 bcmFieldActionRpDrop, 417 bcmFieldActionRpDropCancel, 418 bcmFieldActionCount 419 }; 420 421 STATIC int _aset_copy_to_cpu_act_arr[] = { 422 bcmFieldActionCopyToCpu, 423 bcmFieldActionCopyToCpuCancel, 424 bcmFieldActionSwitchToCpuCancel, 425 bcmFieldActionSwitchToCpuReinstate, 426 bcmFieldActionTimeStampToCpu, 427 bcmFieldActionOamCopyToCpu, 428 bcmFieldActionGpCopyToCpu, 429 bcmFieldActionGpCopyToCpuCancel, 430 bcmFieldActionGpSwitchToCpuCancel, 431 bcmFieldActionGpSwitchToCpuReinstate, 432 bcmFieldActionGpTimeStampToCpu, 433 bcmFieldActionGpOamCopyToCpu, 434 bcmFieldActionYpCopyToCpu, 435 bcmFieldActionYpCopyToCpuCancel, 436 bcmFieldActionYpSwitchToCpuCancel, 437 bcmFieldActionYpSwitchToCpuReinstate, 438 bcmFieldActionYpTimeStampToCpu, 439 bcmFieldActionYpOamCopyToCpu, 440 bcmFieldActionRpCopyToCpu, 441 bcmFieldActionRpCopyToCpuCancel, 442 bcmFieldActionRpSwitchToCpuCancel, 443 bcmFieldActionRpSwitchToCpuReinstate, 444 bcmFieldActionRpTimeStampToCpu, 445 bcmFieldActionRpOamCopyToCpu, 446 bcmFieldActionCount 447 }; 448 449 STATIC 450 int *_field_aset_actions_array[] = { 451 NULL, /* _FieldActionSetNone */ 452 _aset_protection_switching_act_arr, /* _FieldActionProtectionSwitchingDropOverrideSet */ 453 _aset_dlb_alternate_path_control_act_arr, /* _FieldActionIfpDlbAlternatePathControlSet */ 454 _aset_dlb_ecmp_act_arr, /* _FieldActionEcmpDlbActionSet */ 455 _aset_dlb_hgt_lag_act_arr, /* _FieldActionHgtLagDlbActionSet */ 456 _aset_ecmp2_rh_act_arr, /* _FieldActionEcmp2RhActionSet */ 457 NULL, /* _FieldActionEcmp1RhActionSet */ 458 _aset_lag_rh_act_arr, /* _FieldActionLagRhActionSet */ 459 _aset_hgt_rh_act_arr, /* _FieldActionHgtRhActionSet */ 460 _aset_loopback_profile_act_arr, /* _FieldActionLoopbackProfileSet */ 461 NULL, 462 NULL, 463 NULL, 464 NULL, 465 NULL, 466 _aset_tx_timestamp_insertion_act_arr, /* _FieldActionTxTimestampInsertionSet*/ 467 _aset_rx_timestamp_insertion_act_arr, /* _FieldActionRxTimestampInsertionSet */ 468 _aset_ignore_fcoe_zone_check_act_arr, /* _FieldActionIgnoreFCOEZoneCheckSet */ 469 NULL, /* _FieldActionGreenToPidSet 470 Setting this action only adjusts flags in f_ent, as entry flags are 471 recovered from software nothing needs to be done */ 472 _aset_mirror_override_act_arr, /* _FieldActionMirrorOverrideSet */ 473 _aset_nat_override_act_arr, /* _FieldActionNatOverrideSet */ 474 _aset_sflow_act_arr, /* _FieldActionSflowSet */ 475 _aset_cut_thru_override_act_arr, /* _FieldActionCutThrOverrideSet */ 476 _aset_urpf_override_act_arr, /* _FieldActionUrpfOverrideSet */ 477 _aset_ttl_override_act_arr, /* _FieldActionTtlOverrideSet */ 478 _aset_lb_controls_act_arr, /* _FieldActionLbControlSet */ 479 _aset_drop_act_arr, /* _FieldActionDropSet */ 480 NULL, 481 NULL, 482 _aset_nat_act_arr, /* _FieldActionNatSet */ 483 _aset_copy_to_cpu_act_arr, /* _FieldActionCopyToCpuSet */ 484 NULL, 485 NULL, 486 NULL, 487 _aset_change_ecn_act_arr, /* _FieldActionChangeEcnSet */ 488 _aset_change_pkt_pri_act_arr, /* _FieldActionChangePktPriSet */ 489 _aset_change_dscp_tos_act_arr, /* _FieldActionChangeDscpTosSet */ 490 _aset_drop_precedence_act_arr, /* _FieldActionChangeDropPrecendenceSet */ 491 _aset_cos_or_int_pri_act_arr, /* _FieldActionChangeCosOrIntPriSet */ 492 _aset_change_int_cn_act_arr, /* _FieldActionChangeIntCNSet */ 493 _aset_change_input_priority_act_arr, /* _FieldActionChangeInputPrioritySet */ 494 _aset_instrumentation_act_arr, /* _FieldActionInstrumentationSet */ 495 NULL, 496 _aset_fcoe_vsan_act_arr, /* _FieldActionFcoeVsanSet */ 497 NULL, /* _FieldActionMeterSet */ 498 _aset_timestamp_act_arr /* _FieldActionTimestampInsertionSet */ 499 }; 500 501 int 502 _field_wb_action_profile_parse(int unit, _field_entry_t *f_ent, uint32 *ebuf, 503 uint32 *act_data, _field_action_bmp_t *act_bmp); 504 char *elem_name[] = { 505 "_bcmFieldInternalType", 506 "_bcmFieldInternalExtractor", 507 "_bcmFieldInternalGroup", 508 "_bcmFieldInternalGroupId", 509 "_bcmFieldInternalGroupPri", 510 "_bcmFieldInternalGroupQset", 511 "_bcmFieldInternalQsetW", 512 "_bcmFieldInternalQsetUdfMap", 513 "_bcmFieldInternalGroupFlags", 514 "_bcmFieldInternalGroupPbmp", 515 "_bcmFieldInternalGroupSlice", 516 "_bcmFieldInternalGroupQual", 517 "_bcmFieldInternalQualQid", 518 "_bcmFieldInternalQualOffset", 519 "_bcmFieldInternalQualSize", 520 "_bcmFieldInternalGroupStage", 521 "_bcmFieldInternalGroupEntry", 522 "_bcmFieldInternalGroupBlockCount", 523 "_bcmFieldInternalGroupGroupStatus", 524 "_bcmFieldInternalGroupGroupAset", 525 "_bcmFieldInternalGroupCounterBmp", 526 "_bcmFieldInternalGroupInstance", 527 "_bcmFieldInternalGroupExtCodes", 528 "_bcmFieldInternalGroupLtSlice", 529 "_bcmFieldInternalGroupLtConfig", 530 "_bcmFieldInternalGroupLtEntry", 531 "_bcmFieldInternalGroupLtEntrySize", 532 "_bcmFieldInternalGroupLtEntryStatus", 533 "_bcmFieldInternalLtStatusEntriesFree", 534 "_bcmFieldInternalLtStatusEntriesTotal", 535 "_bcmFieldInternalLtStatusEntriesCnt", 536 "_bcmFieldInternalGroupQsetSize", 537 "_bcmFieldInternalGroupHintId", 538 "_bcmFieldInternalGroupMaxSize", 539 "_bcmFieldInternalEndStructGroup", 540 "_bcmFieldInternalQualOffsetField", 541 "_bcmFieldInternalQualOffsetNumOffset", 542 "_bcmFieldInternalQualOffsetOffsetArr", 543 "_bcmFieldInternalQualOffsetWidth", 544 "_bcmFieldInternalQualOffsetSec", 545 "_bcmFieldInternalQualOffsetBitPos", 546 "_bcmFieldInternalQualOffsetQualWidth", 547 "_bcmFieldInternalGroupPartCount", 548 "_bcmFieldInternalEntryEid", 549 "_bcmFieldInternalEntryPrio", 550 "_bcmFieldInternalEntrySliceId", 551 "_bcmFieldInternalEntryFlagsPart1", 552 "_bcmFieldInternalEntryFlagsPart2", 553 "_bcmFieldInternalEntryFlagsPart3", 554 "_bcmFieldInternalEntryPbmp", 555 "_bcmFieldInternalEntryAction", 556 "_bcmFieldInternalEntrySlice", 557 "_bcmFieldInternalEntryGroup", 558 "_bcmFieldInternalEntryStat", 559 "_bcmFieldInternalEntryPolicer", 560 "_bcmFieldInternalEntryIngMtp", 561 "_bcmFieldInternalEntryEgrMtp", 562 "_bcmFieldInternalEntryDvp", 563 "_bcmFieldInternalEntryCopy", 564 "_bcmFieldInternalEntryCopyTypePointer", 565 "_bcmFieldInternalPbmpData", 566 "_bcmFieldInternalPbmpMask", 567 "_bcmFieldInternalEntryActionsPbmp", 568 "_bcmFieldInternalActionParam", 569 "_bcmFieldInternalGroupClassAct", 570 "_bcmFieldInternalActionHwIdx", 571 "_bcmFieldInternalActionFlags", 572 "_bcmFieldInternalStatFlags", 573 "_bcmFieldInternalPolicerFlags", 574 "_bcmFieldInternalExtl1e32Sel", 575 "_bcmFieldInternalExtl1e16Sel", 576 "_bcmFieldInternalExtl1e8Sel", 577 "_bcmFieldInternalExtl1e4Sel", 578 "_bcmFieldInternalExtl1e2Sel", 579 "_bcmFieldInternalExtl2e16Sel", 580 "_bcmFieldInternalExtl3e1Sel", 581 "_bcmFieldInternalExtl3e2Sel", 582 "_bcmFieldInternalExtl3e4Sel", 583 "_bcmFieldInternalExtPmuxSel", 584 "_bcmFieldInternalExtIntraSlice", 585 "_bcmFieldInternalExtSecondary", 586 "_bcmFieldInternalExtIpbmpRes", 587 "_bcmFieldInternalExtNorml3l4", 588 "_bcmFieldInternalExtNormmac", 589 "_bcmFieldInternalExtAuxTagaSel", 590 "_bcmFieldInternalExtAuxTagbSel", 591 "_bcmFieldInternalExtAuxTagcSel", 592 "_bcmFieldInternalExtAuxTagdSel", 593 "_bcmFieldInternalExtTcpFnSel", 594 "_bcmFieldInternalExtTosFnSel", 595 "_bcmFieldInternalExtTtlFnSel", 596 "_bcmFieldInternalExtClassIdaSel", 597 "_bcmFieldInternalExtClassIdbSel", 598 "_bcmFieldInternalExtClassIdcSel", 599 "_bcmFieldInternalExtClassIddSel", 600 "_bcmFieldInternalExtSrcContaSel", 601 "_bcmFieldInternalExtSrcContbSel", 602 "_bcmFieldInternalExtSrcDestCont0Sel", 603 "_bcmFieldInternalExtSrcDestCont1Sel", 604 "_bcmFieldInternalExtKeygenIndex", 605 "_bcmFieldInternalLtEntrySlice", 606 "_bcmFieldInternalLtEntryIndex", 607 "_bcmFieldInternalGroupCount", 608 "_bcmFieldInternalSliceCount", 609 "_bcmFieldInternalLtSliceCount", 610 "_bcmFieldInternalEndStructGroupQual", 611 "_bcmFieldInternalEndStructQualOffset", 612 "_bcmFieldInternalEndStructEntryDetails", 613 "_bcmFieldInternalEndStructEntry", 614 "_bcmFieldInternalEntryPbmpData", 615 "_bcmFieldInternalEntryPbmpMask", 616 "_bcmFieldInternalEndStructAction", 617 "_bcmFieldInternalGlobalEntryPolicer", 618 "_bcmFieldInternalGlobalEntryPolicerPid", 619 "_bcmFieldInternalGlobalEntryPolicerFlags", 620 "_bcmFieldInternalEndGroupExtractor", 621 "_bcmFieldInternalControl", 622 "_bcmFieldInternalControlFlags", 623 "_bcmFieldInternalStage", 624 "_bcmFieldInternalControlGroups", 625 "_bcmFieldInternalControlStages", 626 "_bcmFieldInternalControlPolicerHash", 627 "_bcmFieldInternalControlPolicerCount", 628 "_bcmFieldInternalControlStathash", 629 "_bcmFieldInternalControlStatCount", 630 "_bcmFieldInternalControlHintBmp", 631 "_bcmFieldInternalControlHintHash", 632 "_bcmFieldInternalControlLastAllocatedLtId", 633 "_bcmFieldInternalEndStructControl", 634 "_bcmFieldInternalPolicerPid", 635 "_bcmFieldInternalPolicerSwRefCount", 636 "_bcmFieldInternalPolicerHwRefCount", 637 "_bcmFieldInternalPolicerLevel", 638 "_bcmFieldInternalPolicerPoolIndex", 639 "_bcmFieldInternalPolicerHwIndex", 640 "_bcmFieldInternalPolicerHwFlags", 641 "_bcmFieldInternalPolicerStageId", 642 "_bcmFieldInternalEndStructPolicer", 643 "_bcmFieldInternalStatsId", 644 "_bcmFieldInternalStatSwRefCount", 645 "_bcmFieldInternalStatHwRefCount", 646 "_bcmFieldInternalStatOffsetMode", 647 "_bcmFieldInternalStatPoolIndex", 648 "_bcmFieldInternalStatHwIndex", 649 "_bcmFieldInternalStatHwFlags", 650 "_bcmFieldInternalEndStructStage", 651 "_bcmFieldInternalStatnStat", 652 "_bcmFieldInternalStatArr", 653 "_bcmFieldInternalStatHwStat", 654 "_bcmFieldInternalStatHwMode", 655 "_bcmFieldInternalStatHwEntryCount", 656 "_bcmFieldInternalStatGid", 657 "_bcmFieldInternalStatStageId", 658 "_bcmFieldInternalStatStatValues", 659 "_bcmFieldInternalStatFlexMode", 660 "_bcmFieldInternalEndStructStat", 661 "_bcmFieldInternalHintHintid", 662 "_bcmFieldInternalHintHints", 663 "_bcmFieldInternalHintsHinttype", 664 "_bcmFieldInternalHintsQual", 665 "_bcmFieldInternalHintsMaxValues", 666 "_bcmFieldInternalHintsStartbit", 667 "_bcmFieldInternalHintsEndbit", 668 "_bcmFieldInternalHintsFlags", 669 "_bcmFieldInternalHintsMaxGrpSize", 670 "_bcmFieldInternalEndStructHints", 671 "_bcmFieldInternalHintGrpRefCount", 672 "_bcmFieldInternalHintCount", 673 "_bcmFieldInternalEndStructHint", 674 "_bcmFieldInternalPolicerCfgFlags", 675 "_bcmFieldInternalPolicerCfgMode", 676 "_bcmFieldInternalPolicerCfgCkbitsSec", 677 "_bcmFieldInternalPolicerCfgMaxCkbitsSec", 678 "_bcmFieldInternalPolicerCfgCkbitsBurst", 679 "_bcmFieldInternalPolicerCfgPkbitsSec", 680 "_bcmFieldInternalPolicerCfgMaxPkbitsSec", 681 "_bcmFieldInternalPolicerCfgPkbitsBurst ", 682 "_bcmFieldInternalPolicerCfgKbitsCurrent", 683 "_bcmFieldInternalPolicerCfgActionId", 684 "_bcmFieldInternalPolicerCfgSharingMode", 685 "_bcmFieldInternalPolicerCfgEntropyId", 686 "_bcmFieldInternalPolicerCfgPoolId", 687 "_bcmFieldInternalControlEndStructUdf", 688 "_bcmFieldInternalHintHintsHintType", 689 "_bcmFieldInternalHintHintsQual", 690 "_bcmFieldInternalHintHintsMaxValues", 691 "_bcmFieldInternalHintHintsStartBit", 692 "_bcmFieldInternalHintHintsEndBit", 693 "_bcmFieldInternalHintHintsFlags", 694 "_bcmFieldInternalHintHintsMaxGrpSize", 695 "_bcmFieldInternalEndStructHintHints", 696 "_bcmFieldInternalStageStageid", 697 "_bcmFieldInternalStageFlags", 698 "_bcmFieldInternalStageTcamSz", 699 "_bcmFieldInternalStageTcamSlices", 700 "_bcmFieldInternalStageNumInstances", 701 "_bcmFieldInternalStageNumPipes", 702 "_bcmFieldInternalStageRanges", 703 "_bcmFieldInternalStageRangeId", 704 "_bcmFieldInternalStageNumMeterPools", 705 "_bcmFieldInternalStageMeterPool", 706 "_bcmFieldInternalStageNumCntrPools", 707 "_bcmFieldInternalStageCntrPools", 708 "_bcmFieldInternalStageLtTcamSz", 709 "_bcmFieldInternalStageNumLogicalTables", 710 "_bcmFieldInternalStageLtInfo", 711 "_bcmFieldInternalStageExtLevels", 712 "_bcmFieldInternalStageOperMode", 713 "_bcmFieldInternalRangeFlags", 714 "_bcmFieldInternalRangeRid", 715 "_bcmFieldInternalRangeMin", 716 "_bcmFieldInternalRangeMax", 717 "_bcmFieldInternalRangeHwIndex", 718 "_bcmFieldInternalRangeStyle", 719 "_bcmFieldInternalMeterLevel", 720 "_bcmFieldInternalMeterSliceId", 721 "_bcmFieldInternalMeterSize", 722 "_bcmFieldInternalMeterPoolSize", 723 "_bcmFieldInternalMeterFreeMeters", 724 "_bcmFieldInternalMeterNumMeterPairs", 725 "_bcmFieldInternalMeterBmp", 726 "_bcmFieldInternalCntrSliceId", 727 "_bcmFieldInternalCntrSize", 728 "_bcmFieldInternalCntrFreeCntrs", 729 "_bcmFieldInternalCntrBmp", 730 "_bcmFieldInternalLtConfigValid", 731 "_bcmFieldInternalLtConfigLtId", 732 "_bcmFieldInternalLtConfigLtPartPri", 733 "_bcmFieldInternalLtConfigLtPartMap", 734 "_bcmFieldInternalLtConfigLtActionPri", 735 "_bcmFieldInternalLtConfigPri", 736 "_bcmFieldInternalLtConfigFlags", 737 "_bcmFieldInternalLtConfigEntry", 738 "_bcmFieldInternalEndStructRanges", 739 "_bcmFieldInternalEndStructMeter", 740 "_bcmFieldInternalEndStructCntr", 741 "_bcmFieldInternalEndStructLtConfig", 742 "_bcmFieldInternalSlice", 743 "_bcmFieldInternalSliceStartTcamIdx", 744 "_bcmFieldInternalSliceNumber", 745 "_bcmFieldInternalSliceEntryCount", 746 "_bcmFieldInternalSliceFreeCount", 747 "_bcmFieldInternalSliceCountersCount", 748 "_bcmFieldInternalSliceMetersCount", 749 "_bcmFieldInternalSliceInstalledEntriesCount", 750 "_bcmFieldInternalSliceCounterBmp", 751 "_bcmFieldInternalSliceMeterBmp", 752 "_bcmFieldInternalSliceStageId", 753 "_bcmFieldInternalSlicePortPbmp", 754 "_bcmFieldInternalSliceEntriesInfo", 755 "_bcmFieldInternalSliceNextSlice", 756 "_bcmFieldInternalSlicePrevSlice", 757 "_bcmFieldInternalSliceFlags", 758 "_bcmFieldInternalSliceGroupFlags", 759 "_bcmFieldInternalSliceLtMap", 760 "_bcmFieldInternalEndStructSlice", 761 "_bcmFieldInternalEndStructExtractor", 762 "_bcmFieldInternalLtSliceSliceNum", 763 "_bcmFieldInternalLtSliceStartTcamIdx", 764 "_bcmFieldInternalLtSliceEntryCount", 765 "_bcmFieldInternalLtSliceFreeCount", 766 "_bcmFieldInternalLtSliceStageid", 767 "_bcmFieldInternalLtSliceEntryinfo", 768 "_bcmFieldInternalLtSliceNextSlice", 769 "_bcmFieldInternalLtSlicePrevSlice", 770 "_bcmFieldInternalLtSliceFlags", 771 "_bcmFieldInternalLtSliceGroupFlags", 772 "_bcmFieldInternalDataControlStart", 773 "_bcmFieldInternalDataControlUsageBmp", 774 "_bcmFieldInternalDataControlDataQualStruct", 775 "_bcmFieldInternalDataControlDataQualQid", 776 "_bcmFieldInternalDataControlDataQualUdfSpec", 777 "_bcmFieldInternalDataControlDataQualOffsetBase", 778 "_bcmFieldInternalDataControlDataQualOffset", 779 "_bcmFieldInternalDataControlDataQualByteOffset", 780 "_bcmFieldInternalDataControlDataQualHwBmp", 781 "_bcmFieldInternalDataControlDataQualFlags", 782 "_bcmFieldInternalDataControlDataQualElemCount", 783 "_bcmFieldInternalDataControlDataQualLength", 784 "_bcmFieldInternalDataControlEndStructDataQual", 785 "_bcmFieldInternalDataControlEthertypeStruct", 786 "_bcmFieldInternalDataControlEthertypeRefCount", 787 "_bcmFieldInternalDataControlEthertypeL2", 788 "_bcmFieldInternalDataControlEthertypeVlanTag", 789 "_bcmFieldInternalDataControlEthertypePortEt", 790 "_bcmFieldInternalDataControlEthertypeRelOffset", 791 "_bcmFieldInternalDataControlProtStart", 792 "_bcmFieldInternalDataControlProtIp4RefCount", 793 "_bcmFieldInternalDataControlProtIp6RefCount", 794 "_bcmFieldInternalDataControlProtFlags", 795 "_bcmFieldInternalDataControlProtIp", 796 "_bcmFieldInternalDataControlProtL2", 797 "_bcmFieldInternalDataControlProtVlanTag", 798 "_bcmFieldInternalDataControlProtRelOffset", 799 "_bcmFieldInternalDataControlTcamStruct", 800 "_bcmFieldInternalDataControlTcamRefCount", 801 "_bcmFieldInternalDataControlTcamPriority", 802 "_bcmFieldInternalDataControlElemSize", 803 "_bcmFieldInternalDataControlNumElem", 804 "_bcmFieldInternalEndStructDataControl", 805 "_bcmFieldInternalControlUdfValid", 806 "_bcmFieldInternalControlUdfUseCount", 807 "_bcmFieldInternalControlUdfNum", 808 "_bcmFieldInternalControlUdfUserNum", 809 "_bcmFieldInternalControlUdfDetails", 810 "_bcmFieldInternalDataControlEndStructEtype", 811 "_bcmFieldInternalDataControlEndStructProt", 812 "_bcmFieldInternalDataControlEndStructTcam", 813 "_bcmFieldInternalEntryStatSid", 814 "_bcmFieldInternalEntryStatExtendedSid", 815 "_bcmFieldInternalEntryStatFlags", 816 "_bcmFieldInternalEntryStatAction", 817 "_bcmFieldInternalEndStructLtEntryDetails", 818 "_bcmFieldInternalSliceLtPartitionPri", 819 "_bcmFieldInternalEntryPolicerPid", 820 "_bcmFieldInternalEntryPolicerFlags", 821 "_bcmFieldInternalEndStructEntPolicer", 822 "_bcmFieldInternalEndStructIFP", 823 "_bcmFieldInternalStageClass", 824 "_bcmFieldInternalClassFlags", 825 "_bcmFieldInternalClassEntUsed", 826 "_bcmFieldInternalClassBmp", 827 "_bcmFieldInternalEndStructClass", 828 "_bcmFieldInternalClassOperMode", 829 "_bcmFieldInternalEntryTcamIptype", 830 "_bcmFieldInternalEndStageClass", 831 "_bcmFieldInternalEntryPbmpFullData", 832 "_bcmFieldInternalEntryPbmpFullMask", 833 "_bcmFieldInternalStageLtActionPri", 834 "_bcmFieldInternalStagePreselQset", 835 "_bcmFieldInternalControlPreselInfo", 836 "_bcmFieldInternalGroupPreselQual", 837 "_bcmFieldInternalPreselId", 838 "_bcmFieldInternalPreselFlags", 839 "_bcmFieldInternalPreselPri", 840 "_bcmFieldInternalPreselHwIndex", 841 "_bcmFieldInternalPreselSliceIndex", 842 "_bcmFieldInternalPreselTcamIndex", 843 "_bcmFieldInternalPreselClassAction", 844 "_bcmFieldInternalPreselLtDataSize", 845 "_bcmFieldInternalPreselQset", 846 "_bcmFieldInternalEndStructPreselInfo", 847 "_bcmFieldInternalPreselInfoLimit", 848 "_bcmFieldInternalPreselLastAllocatedId", 849 "_bcmFieldInternalPreselSet", 850 "_bcmFieldInternalPreselOperationalSet", 851 "_bcmFieldInternalPreselKeySize", 852 "_bcmFieldInternalPreselEntrySlice", 853 "_bcmFieldInternalPreselEntryGroup", 854 "_bcmFieldInternalEMOperMode", 855 "_bcmFieldInternalEndStageEM", 856 "_bcmFieldInternalEMEntryarr", 857 "_bcmFieldInternalEMGroupMode", 858 "_bcmFieldInternalEMGroupAset", 859 "_bcmFieldInternalPreselPbmp", 860 "_bcmFieldInternalQualOffsetQualWidth16", 861 "_bcmFieldInternalStatBmp", 862 "_bcmFieldInternalQsetQual", 863 "_bcmFieldInternalQsetUdf", 864 "_bcmFieldInternalQualifyCount", 865 "_bcmFieldInternalHintHintsPri", 866 "_bcmFieldInternalEMGroupAset2", 867 "_bcmFieldInternalEntrySvpType", 868 "_bcmFieldInternalActionParam1", 869 "_bcmFieldInternalGroupActionProfIdx", 870 "_bcmFieldInternalGroupFlagsMsb16", 871 "_bcmFieldInternalSliceFlagsMsb24", 872 "_bcmFieldInternalExtAltTtlFnSel", 873 "_bcmFieldInternalStageClassInfo", 874 "_bcmFieldInternalControlMeterInUse", 875 "_bcmFieldInternalHintHintsDosAttackEventFlags", 876 "_bcmFieldInternalFTOperMode", 877 "_bcmFieldInternalFTEntryArr", 878 "_bcmFieldInternalEndStageFT", 879 "_bcmFieldInternalStageAuxTagIBusContStatus", 880 "_bcmFieldInternalAuxTagIbusContVal", 881 "_bcmFieldInternalAuxTagIbusRefCount", 882 "_bcmFieldInternalEndStructAuxTagIbus", 883 "_bcmFieldInternalStageGrpRunningPrio", 884 "_bcmfieldinternalElementCount", 885 }; 886 887 /* 888 * Elements mapped to their attributes. Attributes cannot be modified. 889 * If there is a change in attributes for any of the elements, new 890 * element type _bcm_field_internal_element_t has to be created and 891 * then needs to be added here with updated attributes 892 */ 893 static _field_type_map_t static_type_map[] = { 894 { _bcmFieldInternalType, 4, 0x0}, 895 { _bcmFieldInternalExtractor, 4, _FP_WB_TLV_LEN_ENCODED 896 | _FP_WB_TLV_LEN_PRESENT}, 897 { _bcmFieldInternalGroup, 0, _FP_WB_TLV_NO_VALUE 898 | _FP_WB_TLV_LEN_PRESENT}, 899 { _bcmFieldInternalGroupId, 4, _FP_WB_TLV_CLASS}, 900 { _bcmFieldInternalGroupPri, 4, _FP_WB_TLV_CLASS}, 901 { _bcmFieldInternalGroupQset, 4, _FP_WB_TLV_NO_VALUE}, 902 { _bcmFieldInternalQsetW, 4, _FP_WB_TLV_LEN_PRESENT 903 | _FP_WB_TLV_CLASS}, 904 { _bcmFieldInternalQsetUdfMap, 4, _FP_WB_TLV_LEN_PRESENT}, 905 { _bcmFieldInternalGroupFlags, 2, _FP_WB_TLV_CLASS}, 906 { _bcmFieldInternalGroupPbmp, 1, _FP_WB_TLV_CLASS 907 | _FP_WB_TLV_LEN_PRESENT}, 908 { _bcmFieldInternalGroupSlice, 4, 0x0}, 909 { _bcmFieldInternalGroupQual, 4, _FP_WB_TLV_NO_VALUE 910 | _FP_WB_TLV_LEN_PRESENT}, 911 { _bcmFieldInternalQualQid, 4, _FP_WB_TLV_LEN_PRESENT}, 912 { _bcmFieldInternalQualOffset, 4, _FP_WB_TLV_LEN_ENCODED 913 | _FP_WB_TLV_LEN_PRESENT}, 914 { _bcmFieldInternalQualSize, 4, 0x0}, 915 { _bcmFieldInternalGroupStage, 4, _FP_WB_TLV_CLASS}, 916 { _bcmFieldInternalGroupEntry, 4, _FP_WB_TLV_CLASS}, 917 { _bcmFieldInternalGroupBlockCount, 2, _FP_WB_TLV_CLASS}, 918 { _bcmFieldInternalGroupGroupStatus, 4, _FP_WB_TLV_CLASS 919 | _FP_WB_TLV_LEN_PRESENT}, 920 { _bcmFieldInternalGroupGroupAset, 4, _FP_WB_TLV_LEN_PRESENT 921 | _FP_WB_TLV_CLASS}, 922 { _bcmFieldInternalGroupCounterBmp, 4, _FP_WB_TLV_LEN_PRESENT}, 923 { _bcmFieldInternalGroupInstance, 4, _FP_WB_TLV_CLASS}, 924 { _bcmFieldInternalGroupExtCodes, 4, _FP_WB_TLV_NO_VALUE 925 | _FP_WB_TLV_LEN_ENCODED 926 | _FP_WB_TLV_LEN_PRESENT}, 927 { _bcmFieldInternalGroupLtSlice, 4, 0x0}, 928 { _bcmFieldInternalGroupLtConfig, 4, 0x0}, 929 { _bcmFieldInternalGroupLtEntry, 4, 0x0}, 930 { _bcmFieldInternalGroupLtEntrySize, 2, 0x0}, 931 { _bcmFieldInternalGroupLtEntryStatus, 4, _FP_WB_TLV_NO_VALUE}, 932 { _bcmFieldInternalLtStatusEntriesFree, 4, 0x0}, 933 { _bcmFieldInternalLtStatusEntriesTotal,4, 0x0}, 934 { _bcmFieldInternalLtStatusEntriesCnt, 4, 0x0}, 935 { _bcmFieldInternalGroupQsetSize, 4, 0x0}, 936 { _bcmFieldInternalGroupHintId, 4, 0x0}, 937 { _bcmFieldInternalGroupMaxSize, 4, _FP_WB_TLV_CLASS}, 938 { _bcmFieldInternalEndStructGroup, 4, _FP_WB_TLV_CLASS}, 939 { _bcmFieldInternalQualOffsetField, 4, _FP_WB_TLV_NO_TYPE}, 940 { _bcmFieldInternalQualOffsetNumOffset, 1, _FP_WB_TLV_NO_TYPE}, 941 { _bcmFieldInternalQualOffsetOffsetArr, 2, _FP_WB_TLV_NO_TYPE 942 | _FP_WB_TLV_LEN_PRESENT}, 943 { _bcmFieldInternalQualOffsetWidth, 1, _FP_WB_TLV_NO_TYPE 944 | _FP_WB_TLV_LEN_PRESENT}, 945 { _bcmFieldInternalQualOffsetSec, 1, _FP_WB_TLV_NO_TYPE}, 946 { _bcmFieldInternalQualOffsetBitPos, 1, _FP_WB_TLV_NO_TYPE}, 947 { _bcmFieldInternalQualOffsetQualWidth, 1, _FP_WB_TLV_NO_TYPE}, 948 { _bcmFieldInternalGroupPartCount, 4, 0x0}, 949 { _bcmFieldInternalEntryEid, 4, _FP_WB_TLV_CLASS}, 950 { _bcmFieldInternalEntryPrio, 4, _FP_WB_TLV_CLASS}, 951 { _bcmFieldInternalEntrySliceId, 4, _FP_WB_TLV_CLASS}, 952 { _bcmFieldInternalEntryFlagsPart1, 4, _FP_WB_TLV_CLASS}, 953 { _bcmFieldInternalEntryFlagsPart2, 4, 0x0}, 954 { _bcmFieldInternalEntryFlagsPart3, 4, 0x0}, 955 { _bcmFieldInternalEntryPbmp, 4, _FP_WB_TLV_CLASS}, 956 { _bcmFieldInternalEntryAction, 4, _FP_WB_TLV_LEN_ENCODED 957 | _FP_WB_TLV_LEN_PRESENT}, 958 { _bcmFieldInternalEntrySlice, 4, 0x0}, 959 { _bcmFieldInternalEntryGroup, 4, _FP_WB_TLV_CLASS}, 960 { _bcmFieldInternalEntryStat, 4, _FP_WB_TLV_LEN_PRESENT}, 961 { _bcmFieldInternalEntryPolicer, 4, _FP_WB_TLV_LEN_ENCODED 962 | _FP_WB_TLV_LEN_PRESENT}, 963 { _bcmFieldInternalEntryIngMtp, 1, 0x0}, 964 { _bcmFieldInternalEntryEgrMtp, 1, 0x0}, 965 { _bcmFieldInternalEntryDvp, 1, 0x0}, 966 { _bcmFieldInternalEntryCopy, 1, _FP_WB_TLV_NO_VALUE}, 967 { _bcmFieldInternalEntryCopyTypePointer,0, 0x0}, 968 { _bcmFieldInternalPbmpData, 4, 0x0}, 969 { _bcmFieldInternalPbmpMask, 4, 0x0}, 970 { _bcmFieldInternalEntryActionsPbmp, 4, _FP_WB_TLV_LEN_PRESENT 971 | _FP_WB_TLV_CLASS}, 972 { _bcmFieldInternalActionParam, 4, _FP_WB_TLV_LEN_PRESENT 973 | _FP_WB_TLV_CLASS}, 974 { _bcmFieldInternalGroupClassAct, 1, 0x0}, 975 { _bcmFieldInternalActionHwIdx, 4, _FP_WB_TLV_LEN_PRESENT 976 | _FP_WB_TLV_CLASS}, 977 { _bcmFieldInternalActionFlags, 1, _FP_WB_TLV_NO_TYPE}, 978 { _bcmFieldInternalStatFlags, 1, 0x0}, 979 { _bcmFieldInternalPolicerFlags, 1, 0x0}, 980 { _bcmFieldInternalExtl1e32Sel, 1, _FP_WB_TLV_NO_TYPE 981 | _FP_WB_TLV_LEN_PRESENT}, 982 { _bcmFieldInternalExtl1e16Sel, 1, _FP_WB_TLV_NO_TYPE 983 | _FP_WB_TLV_LEN_PRESENT}, 984 { _bcmFieldInternalExtl1e8Sel, 1, _FP_WB_TLV_NO_TYPE 985 | _FP_WB_TLV_LEN_PRESENT}, 986 { _bcmFieldInternalExtl1e4Sel, 1, _FP_WB_TLV_NO_TYPE 987 | _FP_WB_TLV_LEN_PRESENT}, 988 { _bcmFieldInternalExtl1e2Sel, 1, _FP_WB_TLV_NO_TYPE 989 | _FP_WB_TLV_LEN_PRESENT}, 990 { _bcmFieldInternalExtl2e16Sel, 1, _FP_WB_TLV_NO_TYPE 991 | _FP_WB_TLV_LEN_PRESENT}, 992 { _bcmFieldInternalExtl3e1Sel, 1, _FP_WB_TLV_NO_TYPE 993 | _FP_WB_TLV_LEN_PRESENT}, 994 { _bcmFieldInternalExtl3e2Sel, 1, _FP_WB_TLV_NO_TYPE 995 | _FP_WB_TLV_LEN_PRESENT}, 996 { _bcmFieldInternalExtl3e4Sel, 1, _FP_WB_TLV_NO_TYPE 997 | _FP_WB_TLV_LEN_PRESENT}, 998 { _bcmFieldInternalExtPmuxSel, 1, _FP_WB_TLV_NO_TYPE 999 | _FP_WB_TLV_LEN_PRESENT}, 1000 { _bcmFieldInternalExtIntraSlice, 1, _FP_WB_TLV_NO_TYPE}, 1001 { _bcmFieldInternalExtSecondary, 1, _FP_WB_TLV_NO_TYPE}, 1002 { _bcmFieldInternalExtIpbmpRes, 1, _FP_WB_TLV_NO_TYPE}, 1003 { _bcmFieldInternalExtNorml3l4, 1, _FP_WB_TLV_NO_TYPE}, 1004 { _bcmFieldInternalExtNormmac, 1, _FP_WB_TLV_NO_TYPE}, 1005 { _bcmFieldInternalExtAuxTagaSel, 1, _FP_WB_TLV_NO_TYPE}, 1006 { _bcmFieldInternalExtAuxTagbSel, 1, _FP_WB_TLV_NO_TYPE}, 1007 { _bcmFieldInternalExtAuxTagcSel, 1, _FP_WB_TLV_NO_TYPE}, 1008 { _bcmFieldInternalExtAuxTagdSel, 1, _FP_WB_TLV_NO_TYPE}, 1009 { _bcmFieldInternalExtTcpFnSel, 1, _FP_WB_TLV_NO_TYPE}, 1010 { _bcmFieldInternalExtTosFnSel, 1, _FP_WB_TLV_NO_TYPE}, 1011 { _bcmFieldInternalExtTtlFnSel, 1, _FP_WB_TLV_NO_TYPE}, 1012 { _bcmFieldInternalExtClassIdaSel, 1, _FP_WB_TLV_NO_TYPE}, 1013 { _bcmFieldInternalExtClassIdbSel, 1, _FP_WB_TLV_NO_TYPE}, 1014 { _bcmFieldInternalExtClassIdcSel, 1, _FP_WB_TLV_NO_TYPE}, 1015 { _bcmFieldInternalExtClassIddSel, 1, _FP_WB_TLV_NO_TYPE}, 1016 { _bcmFieldInternalExtSrcContaSel, 1, _FP_WB_TLV_NO_TYPE}, 1017 { _bcmFieldInternalExtSrcContbSel, 1, _FP_WB_TLV_NO_TYPE}, 1018 { _bcmFieldInternalExtSrcDestCont0Sel, 1, _FP_WB_TLV_NO_TYPE}, 1019 { _bcmFieldInternalExtSrcDestCont1Sel, 1, _FP_WB_TLV_NO_TYPE}, 1020 { _bcmFieldInternalExtKeygenIndex, 4, _FP_WB_TLV_NO_TYPE}, 1021 { _bcmFieldInternalLtEntrySlice, 4, 0x0}, 1022 { _bcmFieldInternalLtEntryIndex, 4, 0x0}, 1023 { _bcmFieldInternalGroupCount, 4, _FP_WB_TLV_CLASS}, 1024 { _bcmFieldInternalSliceCount, 4, 0x0}, 1025 { _bcmFieldInternalLtSliceCount, 4, 0x0}, 1026 { _bcmFieldInternalEndStructGroupQual, 4, 0x0}, 1027 { _bcmFieldInternalEndStructQualOffset, 4, _FP_WB_TLV_NO_TYPE}, 1028 { _bcmFieldInternalEndStructEntryDetails,4, _FP_WB_TLV_NO_VALUE}, 1029 { _bcmFieldInternalEndStructEntry, 4, _FP_WB_TLV_CLASS}, 1030 { _bcmFieldInternalEntryPbmpData, 4, 0x0}, 1031 { _bcmFieldInternalEntryPbmpMask, 4, 0x0}, 1032 { _bcmFieldInternalEndStructAction, 4, _FP_WB_TLV_NO_TYPE 1033 | _FP_WB_TLV_NO_VALUE}, 1034 { _bcmFieldInternalGlobalEntryPolicer, 4, 0x0}, 1035 { _bcmFieldInternalGlobalEntryPolicerPid,4, 0x0}, 1036 { _bcmFieldInternalGlobalEntryPolicerFlags,1,0x0}, 1037 { _bcmFieldInternalEndGroupExtractor, 4, 0x0}, 1038 { _bcmFieldInternalControl, 4, _FP_WB_TLV_NO_VALUE}, 1039 { _bcmFieldInternalControlFlags, 1, 0x0}, 1040 { _bcmFieldInternalStage, 4, _FP_WB_TLV_NO_VALUE}, 1041 { _bcmFieldInternalControlGroups, 4, _FP_WB_TLV_LEN_PRESENT}, 1042 { _bcmFieldInternalControlStages, 4, 0x0}, 1043 { _bcmFieldInternalControlPolicerHash, 4, _FP_WB_TLV_LEN_ENCODED 1044 | _FP_WB_TLV_LEN_PRESENT}, 1045 { _bcmFieldInternalControlPolicerCount, 4, 0x0}, 1046 { _bcmFieldInternalControlStathash, 4, _FP_WB_TLV_LEN_ENCODED 1047 | _FP_WB_TLV_LEN_PRESENT}, 1048 { _bcmFieldInternalControlStatCount, 4, 0x0}, 1049 { _bcmFieldInternalControlHintBmp, 1, _FP_WB_TLV_LEN_PRESENT}, 1050 { _bcmFieldInternalControlHintHash, 4, _FP_WB_TLV_NO_VALUE 1051 | _FP_WB_TLV_LEN_PRESENT}, 1052 { _bcmFieldInternalControlLastAllocatedLtId,4,0x0}, 1053 { _bcmFieldInternalEndStructControl, 4, 0x0}, 1054 { _bcmFieldInternalPolicerPid, 4, _FP_WB_TLV_NO_TYPE}, 1055 { _bcmFieldInternalPolicerSwRefCount, 2, _FP_WB_TLV_NO_TYPE}, 1056 { _bcmFieldInternalPolicerHwRefCount, 2, _FP_WB_TLV_NO_TYPE}, 1057 { _bcmFieldInternalPolicerLevel, 1, _FP_WB_TLV_NO_TYPE}, 1058 { _bcmFieldInternalPolicerPoolIndex, 1, _FP_WB_TLV_NO_TYPE}, 1059 { _bcmFieldInternalPolicerHwIndex, 4, _FP_WB_TLV_NO_TYPE}, 1060 { _bcmFieldInternalPolicerHwFlags, 4, _FP_WB_TLV_NO_TYPE}, 1061 { _bcmFieldInternalPolicerStageId, 4, _FP_WB_TLV_NO_TYPE}, 1062 { _bcmFieldInternalEndStructPolicer, 4, _FP_WB_TLV_NO_TYPE}, 1063 { _bcmFieldInternalStatsId, 4, _FP_WB_TLV_NO_TYPE}, 1064 { _bcmFieldInternalStatSwRefCount, 2, _FP_WB_TLV_NO_TYPE}, 1065 { _bcmFieldInternalStatHwRefCount, 2, _FP_WB_TLV_NO_TYPE}, 1066 { _bcmFieldInternalStatOffsetMode, 1, _FP_WB_TLV_NO_TYPE}, 1067 { _bcmFieldInternalStatPoolIndex, 1, _FP_WB_TLV_NO_TYPE}, 1068 { _bcmFieldInternalStatHwIndex, 4, _FP_WB_TLV_NO_TYPE}, 1069 { _bcmFieldInternalStatHwFlags, 4, _FP_WB_TLV_NO_TYPE}, 1070 { _bcmFieldInternalEndStructStage, 4, 0x0}, 1071 { _bcmFieldInternalStatnStat, 1, _FP_WB_TLV_NO_TYPE}, 1072 { _bcmFieldInternalStatArr, 4, _FP_WB_TLV_NO_TYPE 1073 | _FP_WB_TLV_LEN_PRESENT}, 1074 { _bcmFieldInternalStatHwStat, 4, _FP_WB_TLV_NO_TYPE}, 1075 { _bcmFieldInternalStatHwMode, 2, _FP_WB_TLV_NO_TYPE}, 1076 { _bcmFieldInternalStatHwEntryCount, 1, _FP_WB_TLV_NO_TYPE}, 1077 { _bcmFieldInternalStatGid, 4, _FP_WB_TLV_NO_TYPE}, 1078 { _bcmFieldInternalStatStageId, 4, _FP_WB_TLV_NO_TYPE}, 1079 { _bcmFieldInternalStatStatValues, 8, _FP_WB_TLV_NO_TYPE 1080 | _FP_WB_TLV_LEN_PRESENT}, 1081 { _bcmFieldInternalStatFlexMode, 4, _FP_WB_TLV_NO_TYPE}, 1082 { _bcmFieldInternalEndStructStat, 4, _FP_WB_TLV_NO_TYPE}, 1083 { _bcmFieldInternalHintHintid, 4, 0x0}, 1084 { _bcmFieldInternalHintHints, 0, _FP_WB_TLV_LEN_ENCODED 1085 | _FP_WB_TLV_LEN_PRESENT}, 1086 { _bcmFieldInternalHintsHinttype, 4, 0x0}, 1087 { _bcmFieldInternalHintsQual, 4, 0x0}, 1088 { _bcmFieldInternalHintsMaxValues, 4, 0x0}, 1089 { _bcmFieldInternalHintsStartbit, 4, 0x0}, 1090 { _bcmFieldInternalHintsEndbit, 4, 0x0}, 1091 { _bcmFieldInternalHintsFlags, 4, 0x0}, 1092 { _bcmFieldInternalHintsMaxGrpSize, 4, 0x0}, 1093 { _bcmFieldInternalEndStructHints, 4, 0x0}, 1094 { _bcmFieldInternalHintGrpRefCount, 2, 0x0}, 1095 { _bcmFieldInternalHintCount, 2, 0x0}, 1096 { _bcmFieldInternalEndStructHint, 4, 0x0}, 1097 { _bcmFieldInternalPolicerCfgFlags, 4, _FP_WB_TLV_NO_TYPE}, 1098 { _bcmFieldInternalPolicerCfgMode, 4, _FP_WB_TLV_NO_TYPE}, 1099 { _bcmFieldInternalPolicerCfgCkbitsSec, 4, _FP_WB_TLV_NO_TYPE}, 1100 { _bcmFieldInternalPolicerCfgMaxCkbitsSec,4,_FP_WB_TLV_NO_TYPE}, 1101 { _bcmFieldInternalPolicerCfgCkbitsBurst,4, _FP_WB_TLV_NO_TYPE}, 1102 { _bcmFieldInternalPolicerCfgPkbitsSec, 4, _FP_WB_TLV_NO_TYPE}, 1103 { _bcmFieldInternalPolicerCfgMaxPkbitsSec,4,_FP_WB_TLV_NO_TYPE}, 1104 { _bcmFieldInternalPolicerCfgPkbitsBurst,4,_FP_WB_TLV_NO_TYPE}, 1105 { _bcmFieldInternalPolicerCfgKbitsCurrent,4,_FP_WB_TLV_NO_TYPE}, 1106 { _bcmFieldInternalPolicerCfgActionId, 4, _FP_WB_TLV_NO_TYPE}, 1107 { _bcmFieldInternalPolicerCfgSharingMode,4, _FP_WB_TLV_NO_TYPE}, 1108 { _bcmFieldInternalPolicerCfgEntropyId, 4, _FP_WB_TLV_NO_TYPE}, 1109 { _bcmFieldInternalPolicerCfgPoolId, 4, _FP_WB_TLV_NO_TYPE}, 1110 { _bcmFieldInternalControlEndStructUdf, 4, _FP_WB_TLV_NO_TYPE 1111 | _FP_WB_TLV_LEN_PRESENT}, 1112 { _bcmFieldInternalHintHintsHintType, 4, _FP_WB_TLV_NO_TYPE}, 1113 { _bcmFieldInternalHintHintsQual, 4, _FP_WB_TLV_NO_TYPE}, 1114 { _bcmFieldInternalHintHintsMaxValues, 4, _FP_WB_TLV_NO_TYPE}, 1115 { _bcmFieldInternalHintHintsStartBit, 4, _FP_WB_TLV_NO_TYPE}, 1116 { _bcmFieldInternalHintHintsEndBit, 4, _FP_WB_TLV_NO_TYPE}, 1117 { _bcmFieldInternalHintHintsFlags, 4, _FP_WB_TLV_NO_TYPE}, 1118 { _bcmFieldInternalHintHintsMaxGrpSize, 4, _FP_WB_TLV_NO_TYPE}, 1119 { _bcmFieldInternalEndStructHintHints, 4, _FP_WB_TLV_NO_TYPE 1120 | _FP_WB_TLV_NO_VALUE}, 1121 { _bcmFieldInternalStageStageid, 4, 0x0}, 1122 { _bcmFieldInternalStageFlags, 4, 0x0}, 1123 { _bcmFieldInternalStageTcamSz, 4, 0x0}, 1124 { _bcmFieldInternalStageTcamSlices, 4, 0x0}, 1125 { _bcmFieldInternalStageNumInstances, 4, 0x0}, 1126 { _bcmFieldInternalStageNumPipes, 4, 0x0}, 1127 { _bcmFieldInternalStageRanges, 4, _FP_WB_TLV_LEN_ENCODED 1128 | _FP_WB_TLV_LEN_PRESENT}, 1129 { _bcmFieldInternalStageRangeId, 4, 0x0}, 1130 { _bcmFieldInternalStageNumMeterPools, 4, 0x0}, 1131 { _bcmFieldInternalStageMeterPool, 4, _FP_WB_TLV_LEN_ENCODED 1132 | _FP_WB_TLV_LEN_PRESENT}, 1133 { _bcmFieldInternalStageNumCntrPools, 4, 0x0}, 1134 { _bcmFieldInternalStageCntrPools, 4, _FP_WB_TLV_LEN_ENCODED 1135 | _FP_WB_TLV_LEN_PRESENT}, 1136 { _bcmFieldInternalStageLtTcamSz, 4, 0x0}, 1137 { _bcmFieldInternalStageNumLogicalTables,4, 0x0}, 1138 { _bcmFieldInternalStageLtInfo, 4, _FP_WB_TLV_LEN_ENCODED 1139 | _FP_WB_TLV_LEN_PRESENT}, 1140 { _bcmFieldInternalStageExtLevels, 4, 0x0}, 1141 { _bcmFieldInternalStageOperMode, 4, 0x0}, 1142 { _bcmFieldInternalRangeFlags, 4, _FP_WB_TLV_NO_TYPE}, 1143 { _bcmFieldInternalRangeRid, 4, _FP_WB_TLV_NO_TYPE}, 1144 { _bcmFieldInternalRangeMin, 4, _FP_WB_TLV_NO_TYPE}, 1145 { _bcmFieldInternalRangeMax, 4, _FP_WB_TLV_NO_TYPE}, 1146 { _bcmFieldInternalRangeHwIndex, 4, _FP_WB_TLV_NO_TYPE}, 1147 { _bcmFieldInternalRangeStyle, 1, _FP_WB_TLV_NO_TYPE}, 1148 { _bcmFieldInternalMeterLevel, 1, _FP_WB_TLV_NO_TYPE}, 1149 { _bcmFieldInternalMeterSliceId, 4, _FP_WB_TLV_NO_TYPE}, 1150 { _bcmFieldInternalMeterSize, 2, _FP_WB_TLV_NO_TYPE}, 1151 { _bcmFieldInternalMeterPoolSize, 2, _FP_WB_TLV_NO_TYPE}, 1152 { _bcmFieldInternalMeterFreeMeters, 2, _FP_WB_TLV_NO_TYPE}, 1153 { _bcmFieldInternalMeterNumMeterPairs, 2, _FP_WB_TLV_NO_TYPE}, 1154 { _bcmFieldInternalMeterBmp, 4, _FP_WB_TLV_NO_TYPE 1155 | _FP_WB_TLV_LEN_PRESENT}, 1156 { _bcmFieldInternalCntrSliceId, 1, _FP_WB_TLV_NO_TYPE}, 1157 { _bcmFieldInternalCntrSize, 2, _FP_WB_TLV_NO_TYPE}, 1158 { _bcmFieldInternalCntrFreeCntrs, 2, _FP_WB_TLV_NO_TYPE}, 1159 { _bcmFieldInternalCntrBmp, 4, _FP_WB_TLV_NO_TYPE}, 1160 { _bcmFieldInternalLtConfigValid, 4, _FP_WB_TLV_NO_TYPE}, 1161 { _bcmFieldInternalLtConfigLtId, 4, _FP_WB_TLV_NO_TYPE}, 1162 { _bcmFieldInternalLtConfigLtPartPri, 4, _FP_WB_TLV_NO_TYPE 1163 | _FP_WB_TLV_LEN_PRESENT}, 1164 { _bcmFieldInternalLtConfigLtPartMap, 4, _FP_WB_TLV_NO_TYPE}, 1165 { _bcmFieldInternalLtConfigLtActionPri, 4, _FP_WB_TLV_NO_TYPE}, 1166 { _bcmFieldInternalLtConfigPri, 4, _FP_WB_TLV_NO_TYPE}, 1167 { _bcmFieldInternalLtConfigFlags, 4, _FP_WB_TLV_NO_TYPE}, 1168 { _bcmFieldInternalLtConfigEntry, 4, _FP_WB_TLV_NO_TYPE}, 1169 { _bcmFieldInternalEndStructRanges, 4, _FP_WB_TLV_NO_TYPE}, 1170 { _bcmFieldInternalEndStructMeter, 4, _FP_WB_TLV_NO_TYPE}, 1171 { _bcmFieldInternalEndStructCntr, 4, _FP_WB_TLV_NO_TYPE}, 1172 { _bcmFieldInternalEndStructLtConfig, 4, _FP_WB_TLV_NO_TYPE}, 1173 { _bcmFieldInternalSlice, 0, _FP_WB_TLV_NO_VALUE}, 1174 { _bcmFieldInternalSliceStartTcamIdx, 4, 0x0}, 1175 { _bcmFieldInternalSliceNumber, 1, 0x0 }, 1176 { _bcmFieldInternalSliceEntryCount, 4, 0x0}, 1177 { _bcmFieldInternalSliceFreeCount, 4, 0x0}, 1178 { _bcmFieldInternalSliceCountersCount, 4, 0x0}, 1179 { _bcmFieldInternalSliceMetersCount, 4, 0x0}, 1180 { _bcmFieldInternalSliceInstalledEntriesCount, 4, 0x0}, 1181 { _bcmFieldInternalSliceCounterBmp, 4, _FP_WB_TLV_LEN_PRESENT}, 1182 { _bcmFieldInternalSliceMeterBmp, 4, _FP_WB_TLV_LEN_PRESENT}, 1183 { _bcmFieldInternalSliceStageId, 4, 0x0}, 1184 { _bcmFieldInternalSlicePortPbmp, 1, _FP_WB_TLV_LEN_PRESENT}, 1185 { _bcmFieldInternalSliceEntriesInfo, 4, _FP_WB_TLV_LEN_PRESENT}, 1186 { _bcmFieldInternalSliceNextSlice, 4, 0x0}, 1187 { _bcmFieldInternalSlicePrevSlice, 4, 0x0}, 1188 { _bcmFieldInternalSliceFlags, 1, 0x0}, 1189 { _bcmFieldInternalSliceGroupFlags, 1, 0x0}, 1190 { _bcmFieldInternalSliceLtMap, 4, 0x0}, 1191 { _bcmFieldInternalEndStructSlice, 4, 0x0}, 1192 { _bcmFieldInternalEndStructExtractor, 4, _FP_WB_TLV_NO_TYPE 1193 | _FP_WB_TLV_NO_VALUE}, 1194 { _bcmFieldInternalLtSliceSliceNum, 1, 0x0}, 1195 { _bcmFieldInternalLtSliceStartTcamIdx, 4, 0x0}, 1196 { _bcmFieldInternalLtSliceEntryCount, 4, 0x0}, 1197 { _bcmFieldInternalLtSliceFreeCount, 4, 0x0}, 1198 { _bcmFieldInternalLtSliceStageid, 4, 0x0}, 1199 { _bcmFieldInternalLtSliceEntryinfo, 4, 0x0}, 1200 { _bcmFieldInternalLtSliceNextSlice, 4, _FP_WB_TLV_LEN_PRESENT}, 1201 { _bcmFieldInternalLtSlicePrevSlice, 4, _FP_WB_TLV_LEN_PRESENT}, 1202 { _bcmFieldInternalLtSliceFlags, 2, 0x0}, 1203 { _bcmFieldInternalLtSliceGroupFlags, 2, 0x0}, 1204 { _bcmFieldInternalDataControlStart, 0, _FP_WB_TLV_NO_VALUE 1205 | _FP_WB_TLV_LEN_PRESENT}, 1206 { _bcmFieldInternalDataControlUsageBmp, 4, 0x0}, 1207 { _bcmFieldInternalDataControlDataQualStruct, 0, _FP_WB_TLV_NO_VALUE 1208 | _FP_WB_TLV_LEN_PRESENT}, 1209 { _bcmFieldInternalDataControlDataQualQid, 4, 0x0}, 1210 { _bcmFieldInternalDataControlDataQualUdfSpec, 4, _FP_WB_TLV_LEN_PRESENT}, 1211 { _bcmFieldInternalDataControlDataQualOffsetBase,4,0x0}, 1212 { _bcmFieldInternalDataControlDataQualOffset, 4, 0x0}, 1213 { _bcmFieldInternalDataControlDataQualByteOffset,1,0x0}, 1214 { _bcmFieldInternalDataControlDataQualHwBmp, 4, 0x0}, 1215 { _bcmFieldInternalDataControlDataQualFlags, 4, 0x0}, 1216 { _bcmFieldInternalDataControlDataQualElemCount,1, 0x0}, 1217 { _bcmFieldInternalDataControlDataQualLength, 4, 0x0}, 1218 { _bcmFieldInternalDataControlEndStructDataQual,4, _FP_WB_TLV_LEN_PRESENT}, 1219 { _bcmFieldInternalDataControlEthertypeStruct, 0, _FP_WB_TLV_LEN_ENCODED 1220 | _FP_WB_TLV_LEN_PRESENT}, 1221 { _bcmFieldInternalDataControlEthertypeRefCount,4, _FP_WB_TLV_NO_TYPE}, 1222 { _bcmFieldInternalDataControlEthertypeL2, 2, _FP_WB_TLV_NO_TYPE}, 1223 { _bcmFieldInternalDataControlEthertypeVlanTag, 2, _FP_WB_TLV_NO_TYPE}, 1224 { _bcmFieldInternalDataControlEthertypePortEt, 2, _FP_WB_TLV_NO_TYPE}, 1225 { _bcmFieldInternalDataControlEthertypeRelOffset,4,_FP_WB_TLV_NO_TYPE}, 1226 { _bcmFieldInternalDataControlProtStart, 0, _FP_WB_TLV_LEN_ENCODED 1227 | _FP_WB_TLV_LEN_PRESENT}, 1228 { _bcmFieldInternalDataControlProtIp4RefCount, 4, _FP_WB_TLV_NO_TYPE}, 1229 { _bcmFieldInternalDataControlProtIp6RefCount, 4, _FP_WB_TLV_NO_TYPE}, 1230 { _bcmFieldInternalDataControlProtFlags, 4, _FP_WB_TLV_NO_TYPE}, 1231 { _bcmFieldInternalDataControlProtIp, 1, _FP_WB_TLV_NO_TYPE}, 1232 { _bcmFieldInternalDataControlProtL2, 2, _FP_WB_TLV_NO_TYPE}, 1233 { _bcmFieldInternalDataControlProtVlanTag, 2, _FP_WB_TLV_NO_TYPE}, 1234 { _bcmFieldInternalDataControlProtRelOffset, 4, _FP_WB_TLV_NO_TYPE}, 1235 { _bcmFieldInternalDataControlTcamStruct, 4, _FP_WB_TLV_LEN_ENCODED 1236 |_FP_WB_TLV_LEN_PRESENT}, 1237 { _bcmFieldInternalDataControlTcamRefCount, 1, _FP_WB_TLV_NO_TYPE}, 1238 { _bcmFieldInternalDataControlTcamPriority, 1, _FP_WB_TLV_NO_TYPE}, 1239 { _bcmFieldInternalDataControlElemSize, 4, 0x0}, 1240 { _bcmFieldInternalDataControlNumElem, 4, 0x0}, 1241 { _bcmFieldInternalEndStructDataControl, 4, 0x0}, 1242 { _bcmFieldInternalControlUdfValid, 1, _FP_WB_TLV_NO_TYPE}, 1243 { _bcmFieldInternalControlUdfUseCount, 4, _FP_WB_TLV_NO_TYPE}, 1244 { _bcmFieldInternalControlUdfNum, 4, _FP_WB_TLV_NO_TYPE}, 1245 { _bcmFieldInternalControlUdfUserNum, 1, _FP_WB_TLV_NO_TYPE}, 1246 { _bcmFieldInternalControlUdfDetails, 0, _FP_WB_TLV_LEN_ENCODED 1247 | _FP_WB_TLV_LEN_PRESENT}, 1248 { _bcmFieldInternalDataControlEndStructEtype, 4, _FP_WB_TLV_NO_TYPE 1249 | _FP_WB_TLV_LEN_PRESENT}, 1250 { _bcmFieldInternalDataControlEndStructProt, 4, _FP_WB_TLV_NO_TYPE 1251 | _FP_WB_TLV_LEN_PRESENT}, 1252 { _bcmFieldInternalDataControlEndStructTcam, 4, _FP_WB_TLV_NO_TYPE 1253 | _FP_WB_TLV_LEN_PRESENT}, 1254 { _bcmFieldInternalEntryStatSid, 4, 0}, 1255 { _bcmFieldInternalEntryStatExtendedSid,4, 0}, 1256 { _bcmFieldInternalEntryStatFlags, 2, 0}, 1257 { _bcmFieldInternalEntryStatAction, 4, 0}, 1258 { _bcmFieldInternalEndStructLtEntryDetails, 4, _FP_WB_TLV_NO_VALUE}, 1259 { _bcmFieldInternalSliceLtPartitionPri, 1, 0x0}, 1260 { _bcmFieldInternalEntryPolicerPid, 4, _FP_WB_TLV_NO_TYPE}, 1261 { _bcmFieldInternalEntryPolicerFlags, 1, _FP_WB_TLV_NO_TYPE}, 1262 { _bcmFieldInternalEndStructEntPolicer, 0, _FP_WB_TLV_NO_TYPE 1263 | _FP_WB_TLV_NO_VALUE}, 1264 { _bcmFieldInternalEndStructIFP, 0, 0x0}, 1265 { _bcmFieldInternalStageClass, 0, _FP_WB_TLV_LEN_ENCODED 1266 | _FP_WB_TLV_LEN_PRESENT 1267 | _FP_WB_TLV_NO_INGRESS 1268 | _FP_WB_TLV_CLASS}, 1269 { _bcmFieldInternalClassFlags, 4, _FP_WB_TLV_NO_TYPE 1270 | _FP_WB_TLV_NO_INGRESS 1271 | _FP_WB_TLV_CLASS}, 1272 { _bcmFieldInternalClassEntUsed, 4, _FP_WB_TLV_NO_TYPE 1273 | _FP_WB_TLV_NO_INGRESS 1274 | _FP_WB_TLV_CLASS}, 1275 { _bcmFieldInternalClassBmp, 4, _FP_WB_TLV_NO_TYPE 1276 | _FP_WB_TLV_LEN_PRESENT 1277 | _FP_WB_TLV_NO_INGRESS 1278 | _FP_WB_TLV_CLASS}, 1279 { _bcmFieldInternalEndStructClass, 4, _FP_WB_TLV_NO_TYPE 1280 |_FP_WB_TLV_NO_VALUE 1281 | _FP_WB_TLV_NO_INGRESS 1282 | _FP_WB_TLV_CLASS}, 1283 { _bcmFieldInternalClassOperMode, 4, _FP_WB_TLV_NO_INGRESS 1284 | _FP_WB_TLV_CLASS}, 1285 { _bcmFieldInternalEntryTcamIptype, 1, _FP_WB_TLV_NO_INGRESS 1286 | _FP_WB_TLV_CLASS}, 1287 { _bcmFieldInternalEndStageClass, 4, _FP_WB_TLV_NO_INGRESS 1288 | _FP_WB_TLV_CLASS}, 1289 { _bcmFieldInternalEntryPbmpFullData, 4, _FP_WB_TLV_LEN_PRESENT}, 1290 { _bcmFieldInternalEntryPbmpFullMask, 4, _FP_WB_TLV_LEN_PRESENT}, 1291 { _bcmFieldInternalStageLtActionPri, 4, 0x0}, 1292 { _bcmFieldInternalStagePreselQset, 4, _FP_WB_TLV_LEN_PRESENT}, 1293 { _bcmFieldInternalControlPreselInfo, 0, _FP_WB_TLV_LEN_ENCODED 1294 | _FP_WB_TLV_LEN_PRESENT}, 1295 { _bcmFieldInternalGroupPreselQual, 0, _FP_WB_TLV_NO_VALUE 1296 | _FP_WB_TLV_LEN_PRESENT}, 1297 { _bcmFieldInternalPreselId, 4, _FP_WB_TLV_NO_TYPE}, 1298 { _bcmFieldInternalPreselFlags, 4, _FP_WB_TLV_NO_TYPE}, 1299 { _bcmFieldInternalPreselPri, 4, _FP_WB_TLV_NO_TYPE}, 1300 { _bcmFieldInternalPreselHwIndex, 4, _FP_WB_TLV_NO_TYPE}, 1301 { _bcmFieldInternalPreselSliceIndex, 4, _FP_WB_TLV_NO_TYPE}, 1302 { _bcmFieldInternalPreselTcamIndex, 4, _FP_WB_TLV_NO_TYPE}, 1303 { _bcmFieldInternalPreselClassAction, 4, _FP_WB_TLV_NO_TYPE 1304 | _FP_WB_TLV_LEN_PRESENT}, 1305 { _bcmFieldInternalPreselLtDataSize, 2, _FP_WB_TLV_NO_TYPE}, 1306 { _bcmFieldInternalPreselQset, 4, _FP_WB_TLV_NO_TYPE 1307 | _FP_WB_TLV_LEN_PRESENT}, 1308 { _bcmFieldInternalEndStructPreselInfo, 4, _FP_WB_TLV_NO_TYPE}, 1309 { _bcmFieldInternalPreselInfoLimit, 4, 0x0}, 1310 { _bcmFieldInternalPreselLastAllocatedId, 4, 0x0}, 1311 { _bcmFieldInternalPreselSet, 4, _FP_WB_TLV_LEN_PRESENT}, 1312 { _bcmFieldInternalPreselOperationalSet,4, _FP_WB_TLV_LEN_PRESENT}, 1313 { _bcmFieldInternalPreselKeySize, 2, _FP_WB_TLV_NO_TYPE}, 1314 { _bcmFieldInternalPreselEntrySlice, 1, _FP_WB_TLV_NO_TYPE 1315 | _FP_WB_TLV_LEN_PRESENT}, 1316 { _bcmFieldInternalPreselEntryGroup, 4, _FP_WB_TLV_NO_TYPE}, 1317 { _bcmFieldInternalEMOperMode, 4, _FP_WB_TLV_NO_INGRESS}, 1318 { _bcmFieldInternalEndStageEM, 4, _FP_WB_TLV_NO_INGRESS 1319 | _FP_WB_TLV_NO_VALUE}, 1320 { _bcmFieldInternalEMEntryarr, 4, _FP_WB_TLV_NO_INGRESS 1321 | _FP_WB_TLV_LEN_PRESENT}, 1322 { _bcmFieldInternalEMGroupMode, 4, _FP_WB_TLV_NO_INGRESS}, 1323 { _bcmFieldInternalEMGroupAset, 1, _FP_WB_TLV_NO_INGRESS}, 1324 { _bcmFieldInternalPreselPbmp, 4, _FP_WB_TLV_NO_TYPE 1325 | _FP_WB_TLV_LEN_PRESENT}, 1326 { _bcmFieldInternalQualOffsetQualWidth16, 2, _FP_WB_TLV_NO_TYPE}, 1327 { _bcmFieldInternalStatBmp, 4, _FP_WB_TLV_NO_TYPE 1328 | _FP_WB_TLV_LEN_PRESENT}, 1329 { _bcmFieldInternalQsetQual, 4, _FP_WB_TLV_LEN_PRESENT 1330 | _FP_WB_TLV_CLASS}, 1331 { _bcmFieldInternalQsetUdf, 4, _FP_WB_TLV_LEN_PRESENT 1332 | _FP_WB_TLV_CLASS}, 1333 { _bcmFieldInternalQualifyCount, 4, _FP_WB_TLV_CLASS}, 1334 { _bcmFieldInternalHintHintsPri, 4, _FP_WB_TLV_NO_TYPE}, 1335 { _bcmFieldInternalEMGroupAset2, 4, _FP_WB_TLV_NO_INGRESS 1336 | _FP_WB_TLV_LEN_PRESENT}, 1337 { _bcmFieldInternalEntrySvpType, 1, 0x0}, 1338 { _bcmFieldInternalActionParam1, 4, _FP_WB_TLV_LEN_PRESENT 1339 | _FP_WB_TLV_CLASS}, 1340 { _bcmFieldInternalGroupActionProfIdx, 1, _FP_WB_TLV_LEN_PRESENT}, 1341 { _bcmFieldInternalGroupFlagsMsb16, 2, _FP_WB_TLV_CLASS}, 1342 { _bcmFieldInternalSliceFlagsMsb24, 3, 0x0}, 1343 { _bcmFieldInternalExtAltTtlFnSel, 1, _FP_WB_TLV_NO_TYPE}, 1344 { _bcmFieldInternalStageClassInfo, 0, _FP_WB_TLV_NO_VALUE 1345 | _FP_WB_TLV_NO_INGRESS 1346 | _FP_WB_TLV_CLASS}, 1347 { _bcmFieldInternalControlMeterInUse, 1, _FP_WB_TLV_LEN_PRESENT}, 1348 {_bcmFieldInternalHintHintsDosAttackEventFlags, 4, _FP_WB_TLV_NO_TYPE}, 1349 {_bcmFieldInternalFTOperMode, 4, _FP_WB_TLV_NO_INGRESS 1350 | _FP_WB_TLV_NO_EM}, 1351 { _bcmFieldInternalFTEntryArr, 4, _FP_WB_TLV_NO_INGRESS 1352 | _FP_WB_TLV_NO_EM 1353 | _FP_WB_TLV_LEN_PRESENT}, 1354 {_bcmFieldInternalEndStageFT, 4, _FP_WB_TLV_NO_INGRESS 1355 |_FP_WB_TLV_NO_VALUE}, 1356 {_bcmFieldInternalStageAuxTagIBusContStatus, 4, _FP_WB_TLV_LEN_ENCODED | 1357 _FP_WB_TLV_LEN_PRESENT}, 1358 {_bcmFieldInternalAuxTagIbusContVal, 4, _FP_WB_TLV_NO_TYPE}, 1359 {_bcmFieldInternalAuxTagIbusRefCount, 4, _FP_WB_TLV_NO_TYPE}, 1360 {_bcmFieldInternalEndStructAuxTagIbus, 4, _FP_WB_TLV_NO_TYPE}, 1361 {_bcmFieldInternalStageGrpRunningPrio, 4, 0x0}, 1362 {_bcmFieldInternalEMActionPbmOpaqueObject1,4, _FP_WB_TLV_LEN_PRESENT}, 1363 {_bcmFieldInternalEMActionPbmOpaqueObject2,4, _FP_WB_TLV_LEN_PRESENT}, 1364 {_bcmFieldInternalEMActionPbmGbpSrcIdNew, 4, _FP_WB_TLV_LEN_PRESENT}, 1365 {_bcmFieldInternalEMActionPbmGbpDstIdNew, 4, _FP_WB_TLV_LEN_PRESENT}, 1366 {_bcmFieldInternalEMActionPbmEgressFlowControlEnable, 4, _FP_WB_TLV_LEN_PRESENT}, 1367 {_bcmFieldInternalEMActionPbmOpaqueObject3, 4, _FP_WB_TLV_LEN_PRESENT}, 1368 {_bcmFieldInternalEMActionPbmAssignNatClassId, 4, _FP_WB_TLV_LEN_PRESENT}, 1369 {_bcmFieldInternalEMActionPbmAssignChangeL2FieldsClassId, 4, _FP_WB_TLV_LEN_PRESENT}, 1370 }; 1371 1372 /* Static map used for Downgrades */ 1373 _field_type_map_t *recovery_type_map[BCM_MAX_NUM_UNITS]; 1374 1375 uint8 downgrade[BCM_MAX_NUM_UNITS] = {FALSE}; 1376 1377 #define _DYNAMIC_MAP_INSERT( _ptr_, _node_, _tail_) \ 1378 do { \ 1379 if (_tail_ == NULL) { \ 1380 _ptr_ = _node_; \ 1381 _tail_ = _node_; \ 1382 } else { \ 1383 _tail_->next = _node_; \ 1384 _tail_ = _tail_->next; \ 1385 } \ 1386 } while(0); 1387 1388 #define _DYNAMIC_MAP_DELETE_ALL(_ptr_, _entry_type_) \ 1389 do { \ 1390 _entry_type_ *node = NULL; \ 1391 while (_ptr_ != NULL) { \ 1392 node = _ptr_; \ 1393 _ptr_ = _ptr_->next; \ 1394 sal_free(node); \ 1395 node = NULL; \ 1396 } \ 1397 } while(0); \ 1398 1399 void dynamic_map_free(_field_dynamic_map_t dynamic_map) { 1400 _DYNAMIC_MAP_DELETE_ALL(dynamic_map.entry_map, _field_dynamic_map_entry_t); 1401 _DYNAMIC_MAP_DELETE_ALL(dynamic_map.lt_entry_map, 1402 _field_dynamic_map_lt_entry_t); 1403 } 1404 1405 /* 1406 * Function: 1407 * _tlv_print_array 1408 * Purpose: 1409 * print the array of values 1410 * Parameters: 1411 * unit - (IN) StrataSwitch unit #. 1412 * value - (IN) Pointer to the array of values 1413 * length - (IN) length of the array. 1414 * Returns: 1415 * BCM_E_XXX 1416 */ 1417 int 1418 _tlv_print_array(int unit, void *value, int length, int chunk_sz) 1419 { 1420 int i = 0; /* local variable for loop */ 1421 uint8 *val8 = 0; /* variable to hold 8 bit values */ 1422 uint16 *val16 = 0; /* variable to hold 16 bit values */ 1423 uint32 *val32 = 0; /* variable to hold 32 bit values */ 1424 long long unsigned int *val64 = 0; 1425 /* variable to hold 64 bit values */ 1426 1427 switch (chunk_sz) { 1428 case 2: 1429 val16 = (uint16 *)value; 1430 for (i = 0; i < length/chunk_sz; i++) { 1431 LOG_DEBUG(BSL_LS_BCM_FP, 1432 (BSL_META_U(unit, "TLV Value array: %x\n"), val16[i])); 1433 } 1434 break; 1435 case 4: 1436 val32 = (uint32 *)value; 1437 for (i = 0; i < length/chunk_sz; i++) { 1438 LOG_DEBUG(BSL_LS_BCM_FP, 1439 (BSL_META_U(unit, "TLV Value array: %x\n"), val32[i])); 1440 } 1441 break; 1442 case 8: 1443 val64 = (long long unsigned int *)value; 1444 for (i = 0; i < length/chunk_sz; i++) { 1445 LOG_DEBUG(BSL_LS_BCM_FP, 1446 (BSL_META_U(unit, "TLV Value array: %llx\n"), val64[i])); 1447 } 1448 break; 1449 default: 1450 val8 = (uint8 *)value; 1451 for (i = 0; i < length; i++) { 1452 LOG_DEBUG(BSL_LS_BCM_FP, 1453 (BSL_META_U(unit, "TLV Value array: %02x\n"), val8[i])); 1454 } 1455 1456 1457 } 1458 1459 return BCM_E_NONE; 1460 } 1461 /* 1462 * Function: 1463 * tlv_write 1464 * Purpose: 1465 * Element stored in scache =_internal_element_t | ((array/variable) << 28) 1466 * if (_FP_WB_TLV_LEN_PRESENT) -> write length to scache 1467 * if !(_FP_WB_TLV_NO_VALUE) 1468 * -> if variable -> get size from static map and write 1469 * -> if array -> length times (size of each component from static map) 1470 * if length was encoded, types will be added later as variables with 1471 * _bcmfieldinternaltype as element type where we write only a uint32(which 1472 * is considered as value for the main type. If more types are added, it 1473 * will be a array 1474 * Will add an example here later about encoded. 1475 * Parameters: 1476 * unit - (IN) StrataSwitch unit #. 1477 * tlv - (IN) input structure containing type to be written, 1478 its length & value 1479 * ptr - (IN) pointer to scache; obtained from 1480 field_control->scache_ptr[PART]; 1481 * pos - (IN/OUT) Current offset from the base of scache part in use. 1482 * Returns: 1483 * BCM_E_XXX 1484 */ 1485 1486 int 1487 tlv_write(int unit, _field_tlv_t *tlv, uint8 *ptr, uint32 *position) 1488 { 1489 uint32 pos, data = 0; /* local variables for 1490 * scache_pos and data 1491 */ 1492 _bcm_field_internal_element_t elem; /* local variable for elem type */ 1493 int write_size = 0; /* size used for value field */ 1494 1495 if (tlv == NULL) { 1496 return BCM_E_PARAM; 1497 } 1498 pos = *position; 1499 1500 elem = tlv->type; 1501 /* Write Type */ 1502 if (!(static_type_map[elem].flags & _FP_WB_TLV_NO_TYPE)) 1503 { data = (tlv->basic_type << _FP_WB_TLV_BASIC_TYPE_SHIFT); 1504 data |= elem; 1505 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "TLV Write Enum: %s\n"), 1506 elem_name[elem])); 1507 if (wb_write_disable != 1) { 1508 sal_memcpy(&ptr[pos], &data, sizeof(uint32)); 1509 } 1510 pos += sizeof(uint32); 1511 } else { 1512 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "Writing For Enum: %s\n"), 1513 elem_name[tlv->type])); 1514 } 1515 /* Write Length */ 1516 if (static_type_map[elem].flags & _FP_WB_TLV_LEN_PRESENT) { 1517 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "TLV Write Length: %x\n"), 1518 tlv->length)); 1519 if (wb_write_disable != 1) { 1520 sal_memcpy(&ptr[pos], &(tlv->length), sizeof(uint32)); 1521 } 1522 pos += sizeof(uint32); 1523 } 1524 1525 if ((tlv->value != NULL) && 1526 !(static_type_map[elem].flags & 1527 _FP_WB_TLV_NO_VALUE)) { 1528 if (tlv->basic_type == _bcmFieldInternalVariable) { 1529 write_size = static_type_map[elem].size; 1530 } else if (tlv->basic_type == _bcmFieldInternalArray) { 1531 write_size = ((tlv->length) * 1532 (static_type_map[elem].size)); 1533 } else { 1534 return BCM_E_INTERNAL; 1535 } 1536 if (static_type_map[elem].flags & _FP_WB_TLV_LEN_ENCODED) { 1537 write_size = (((tlv->length) & _FP_WB_TLV_TYPES_MASK) >> 1538 _FP_WB_TLV_TYPE_SHIFT) * 1539 sizeof(tlv->type); 1540 } 1541 } 1542 1543 /* Write Value */ 1544 if (write_size > 0) { 1545 BCM_IF_ERROR_RETURN(_tlv_print_array(unit, tlv->value, write_size, 1546 static_type_map[elem].size)); 1547 if (wb_write_disable != 1) { 1548 sal_memcpy(&ptr[pos], tlv->value, write_size); 1549 } 1550 pos += write_size; 1551 } 1552 1553 *position = pos; 1554 1555 return BCM_E_NONE; 1556 1557 } 1558 1559 /* 1560 * Function: 1561 * tlv_read 1562 * Purpose: 1563 * Read a chunck from scache. Chunk size depends on the type read/passed. 1564 * Call function needs to free the memory allocated to tlv structure/value 1565 * field in tlv structure. 1566 * Function flow: 1567 * Read type (if input type is not a valid one) 1568 * Get corresponding flags, read length if it is present. 1569 * If value is present, read the corresponding value/array of values 1570 * If not, and length is encoded, read value array which contains the 1571 * list of types that are encoded. Later tlv_read has to be called 1572 * with corresponding type to get the value of each instance. 1573 * Parameters: 1574 * unit - (IN) StrataSwitch unit #. 1575 * tlv - (OUT) structure containing type, length and value/value array 1576 * read(based on flags from static_type_map) 1577 * ptr - (IN) pointer to scache; obtained from 1578 * field_control->scache_ptr[PART]; 1579 * pos - (IN/OUT) Current offset from the base of scache part in use. 1580 * Returns: 1581 * BCM_E_XXXX 1582 */ 1583 1584 int 1585 tlv_read(int unit, _field_tlv_t *tlv, uint8 *ptr, uint32 *position) 1586 { 1587 uint32 pos, data = 0; /* local variables for scache_pos and data */ 1588 int read_size = 0; /* size used for value field */ 1589 1590 if (tlv == NULL) { 1591 return BCM_E_PARAM; 1592 } 1593 pos = *position; 1594 1595 /* Read Type */ 1596 if (tlv->type == -1) { 1597 sal_memcpy(&data, &ptr[pos], sizeof(uint32)); 1598 pos += sizeof(uint32); 1599 1600 tlv->type = data & _FP_WB_TLV_ELEM_TYPE_MASK; 1601 tlv->basic_type = ((data & _FP_WB_TLV_BASIC_TYPE_MASK) >> 1602 _FP_WB_TLV_BASIC_TYPE_SHIFT); 1603 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "TLV Read Enum: %s\n"), 1604 elem_name[tlv->type])); 1605 } else { 1606 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 1607 "Reading For Enum: %s\n"), 1608 elem_name[tlv->type])); 1609 } 1610 1611 /* Read Length */ 1612 if (recovery_type_map[unit][tlv->type].flags 1613 & _FP_WB_TLV_LEN_PRESENT) { 1614 sal_memcpy(&(tlv->length), &ptr[pos], sizeof(uint32)); 1615 pos += sizeof(uint32); 1616 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "TLV READ Length: %x\n"), 1617 tlv->length)); 1618 } 1619 1620 1621 if (!(recovery_type_map[unit][tlv->type].flags 1622 & _FP_WB_TLV_NO_VALUE)) { 1623 if (tlv->basic_type == _bcmFieldInternalVariable) { 1624 read_size = recovery_type_map[unit][tlv->type].size; 1625 } else if (tlv->basic_type == _bcmFieldInternalArray) { 1626 read_size = ((tlv->length) * recovery_type_map[unit][tlv->type].size); 1627 } else { 1628 return BCM_E_INTERNAL; 1629 } 1630 if (recovery_type_map[unit][tlv->type].flags 1631 & _FP_WB_TLV_LEN_ENCODED) { 1632 data = (((tlv->length) & _FP_WB_TLV_TYPES_MASK) >> 1633 _FP_WB_TLV_TYPE_SHIFT); 1634 read_size = data * sizeof(uint32); 1635 } 1636 } 1637 1638 /* Read Value */ 1639 if (read_size > 0) { 1640 _FP_XGS3_ALLOC(tlv->value, read_size, "wb read values"); 1641 if (tlv->value == NULL) { 1642 return BCM_E_MEMORY; 1643 } 1644 sal_memcpy(tlv->value, &ptr[pos], read_size); 1645 pos += read_size; 1646 BCM_IF_ERROR_RETURN( 1647 _tlv_print_array(unit, tlv->value, read_size, 1648 recovery_type_map[unit][tlv->type].size)); 1649 } 1650 if (read_size == 0) { 1651 tlv->value = NULL; 1652 } 1653 *position = pos; 1654 1655 return BCM_E_NONE; 1656 } 1657 1658 1659 /* Function: 1660 * _field_tlv_create 1661 * 1662 * Purpose: 1663 * Create memory for tlv and set basic fields 1664 * 1665 * Parameters: 1666 * type -(IN) element type 1667 * basic_type -(IN) basic type of the element 1668 * length -(IN) length of element in case of arrays 1669 * tlv -(OUT) tlv output 1670 * 1671 * Returns: 1672 * BCM_E_XXXX 1673 */ 1674 1675 int 1676 _field_tlv_create(_bcm_field_internal_element_t type, 1677 _bcm_field_internal_type_t basic_type, 1678 uint32 length, _field_tlv_t **tlv) 1679 { 1680 _field_tlv_t *tlv_new = NULL; /* TLV data structure instance */ 1681 1682 if (*tlv != NULL) { 1683 sal_free(*tlv); 1684 *tlv = NULL; 1685 } 1686 _FP_XGS3_ALLOC(tlv_new,sizeof(_field_tlv_t),"tlv alloc"); 1687 1688 if (tlv_new == NULL) { 1689 return BCM_E_MEMORY; 1690 } 1691 tlv_new->type = type; 1692 tlv_new->basic_type = basic_type; 1693 tlv_new->length = length; 1694 1695 *tlv = tlv_new; 1696 return BCM_E_NONE; 1697 } 1698 1699 /* Must Point to the current stage which is being synced */ 1700 /* Checck _field_tlv_validate_and_write for usage */ 1701 _field_stage_t *curr_stage_fc; 1702 1703 /* Function: 1704 * _field_tlv_validate_and_write 1705 * 1706 * Purpose: 1707 * Check if the type is valid for the current stage and write it to 1708 * scache. 1709 * 1710 * Parameters: 1711 * unit -(IN) unit number 1712 * tlv -(IN) tlv structure 1713 * ptr -(IN) pointer to fc->scache_ptr (usually) 1714 * position -(IN) position 1715 * 1716 * Returns: 1717 * BCM_E_XXXX 1718 */ 1719 int 1720 _field_tlv_validate_and_write(int unit, _field_tlv_t *tlv, uint8 *ptr, 1721 uint32 *position) 1722 { 1723 if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 1724 if (static_type_map[tlv->type].flags & _FP_WB_TLV_NO_INGRESS) { 1725 return BCM_E_NONE; 1726 } 1727 } 1728 1729 if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_CLASS) { 1730 if (!(static_type_map[tlv->type].flags & _FP_WB_TLV_CLASS)) { 1731 return BCM_E_NONE; 1732 } 1733 } 1734 1735 if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 1736 if (static_type_map[tlv->type].flags & _FP_WB_TLV_NO_EM) { 1737 return BCM_E_NONE; 1738 } 1739 } 1740 1741 #if defined(BCM_HELIX5_SUPPORT) 1742 if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_FLOWTRACKER) { 1743 if (static_type_map[tlv->type].flags & _FP_WB_TLV_NO_FT) { 1744 return BCM_E_NONE; 1745 } 1746 } 1747 #endif 1748 1749 return tlv_write(unit, tlv, ptr, position); 1750 } 1751 1752 1753 /* Basic function calls required in all Functions */ 1754 1755 #define WB_FIELD_CONTROL_GET(fc, s_ptr, s_pos) \ 1756 do { \ 1757 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); \ 1758 s_ptr = fc->scache_ptr[_FIELD_SCACHE_PART_0]; \ 1759 s_pos = &(fc->scache_pos); \ 1760 } while (0); 1761 1762 #define WB_FIELD_CONTROL_GET_WITH_LOCK(fc, s_ptr, s_pos) \ 1763 do { \ 1764 FP_LOCK(unit); \ 1765 rv = _field_control_get(unit, &fc); \ 1766 if (BCM_FAILURE(rv)) { \ 1767 FP_UNLOCK(unit); \ 1768 return rv; \ 1769 } \ 1770 s_ptr = fc->scache_ptr[_FIELD_SCACHE_PART_0]; \ 1771 s_pos = &(fc->scache_pos); \ 1772 } while (0); 1773 1774 #define TLV_WRITE(unit, tlv, ptr, pos) \ 1775 BCM_IF_ERROR_RETURN(_field_tlv_validate_and_write(unit,tlv,ptr,pos)); 1776 1777 #define TLV_CREATE(_type_, _inttype_, _size_, _value_) \ 1778 BCM_IF_ERROR_RETURN(_field_tlv_create(_type_, _inttype_, _size_, _value_)); 1779 1780 /* Cleanup version of TLV Write and Create */ 1781 #define TLV_WRITE_IF_ERR_CLEANUP(unit, tlv, ptr, pos) \ 1782 BCM_IF_ERROR_CLEANUP(_field_tlv_validate_and_write(unit,tlv,ptr,pos)); 1783 1784 #define TLV_CREATE_IF_ERR_CLEANUP(_type_, _inttype_, _size_, _value_) \ 1785 BCM_IF_ERROR_CLEANUP(_field_tlv_create(_type_, _inttype_, _size_, _value_)); 1786 1787 1788 /* Function: 1789 * _field_hash_sync 1790 * 1791 * Purpose: 1792 * Sync hashes for stat, policer, hint structure 1793 * 1794 * Paramaters: 1795 * unit - (IN) BCM device number 1796 * 1797 * Returns: 1798 * BCM_E_XXX 1799 */ 1800 1801 int 1802 _field_hash_sync(int unit) 1803 { 1804 1805 _field_tlv_t *tlv = NULL; /* tlv data */ 1806 _field_control_t *fc; /* Field control structure. */ 1807 _field_policer_t *f_pl; /* Internal policer descriptor. */ 1808 _field_stat_t *f_st; /* Internal Stat descriptor */ 1809 _field_hints_t *f_ht; /* Internal Hints Descriptor */ 1810 int idx = 0; /* Iterator */ 1811 int policer_count = 0; /* number of policers */ 1812 int stat_count = 0; /* number of stats */ 1813 int hints_count = 0; /* number of hints */ 1814 uint32 endmarkerpolicer = _FIELD_WB_EM_POLICER; 1815 /* End marker for policer */ 1816 uint32 endmarkerstat = _FIELD_WB_EM_STAT; 1817 /* End marker for stat */ 1818 uint32 endmarkerhint = _FIELD_WB_EM_HINT; 1819 /* End marker for hint */ 1820 _field_hint_t *hint; /* temporary field for hint */ 1821 int hintidx = 0; /* hint id variable */ 1822 _field_stat_bmp_t stat_bmp; /* Field Stat Bitmap */ 1823 int type_policer[22] = { /* types in _field_policer_t */ 1824 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1825 | _bcmFieldInternalPolicerPid), 1826 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1827 | _bcmFieldInternalPolicerCfgFlags), 1828 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1829 | _bcmFieldInternalPolicerCfgMode), 1830 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1831 | _bcmFieldInternalPolicerCfgCkbitsSec), 1832 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1833 | _bcmFieldInternalPolicerCfgMaxCkbitsSec), 1834 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1835 | _bcmFieldInternalPolicerCfgCkbitsBurst), 1836 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1837 | _bcmFieldInternalPolicerCfgPkbitsSec), 1838 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1839 | _bcmFieldInternalPolicerCfgMaxPkbitsSec), 1840 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1841 | _bcmFieldInternalPolicerCfgPkbitsBurst), 1842 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1843 | _bcmFieldInternalPolicerCfgKbitsCurrent), 1844 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1845 | _bcmFieldInternalPolicerCfgActionId), 1846 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1847 | _bcmFieldInternalPolicerCfgSharingMode), 1848 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1849 | _bcmFieldInternalPolicerCfgEntropyId), 1850 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1851 | _bcmFieldInternalPolicerCfgPoolId), 1852 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1853 | _bcmFieldInternalPolicerSwRefCount), 1854 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1855 | _bcmFieldInternalPolicerHwRefCount), 1856 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1857 | _bcmFieldInternalPolicerLevel), 1858 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1859 | _bcmFieldInternalPolicerPoolIndex), 1860 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1861 | _bcmFieldInternalPolicerHwIndex), 1862 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1863 | _bcmFieldInternalPolicerHwFlags), 1864 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1865 | _bcmFieldInternalPolicerStageId), 1866 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1867 | _bcmFieldInternalEndStructPolicer) 1868 }; 1869 1870 int type_stat[6] = { /* types in _field_stat_t */ 1871 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1872 | _bcmFieldInternalStatsId), 1873 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1874 | _bcmFieldInternalStatnStat), 1875 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1876 | _bcmFieldInternalStatFlexMode), 1877 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1878 | _bcmFieldInternalStatHwFlags), 1879 (int)((_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1880 | _bcmFieldInternalStatBmp), 1881 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1882 | _bcmFieldInternalEndStructStat) 1883 }; 1884 int type_hint[10] = { /* types in _field_hint_t */ 1885 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1886 | _bcmFieldInternalHintHintsHintType), 1887 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1888 | _bcmFieldInternalHintHintsQual), 1889 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1890 | _bcmFieldInternalHintHintsMaxValues), 1891 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1892 | _bcmFieldInternalHintHintsStartBit), 1893 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1894 | _bcmFieldInternalHintHintsEndBit), 1895 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1896 | _bcmFieldInternalHintHintsFlags), 1897 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1898 | _bcmFieldInternalHintHintsMaxGrpSize), 1899 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1900 | _bcmFieldInternalHintHintsPri), 1901 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1902 | _bcmFieldInternalHintHintsDosAttackEventFlags), 1903 (int) (( _bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 1904 | _bcmFieldInternalEndStructHintHints) 1905 }; 1906 uint8 *ptr; /* Pointer to scache_pos */ 1907 uint32 *position; /* Scache position */ 1908 int i = 0; /* Iterator */ 1909 1910 WB_FIELD_CONTROL_GET(fc, ptr, position); 1911 1912 stat_bmp.w = NULL; 1913 1914 /* Iterate over all hash buckets. */ 1915 for (idx = 0; idx < _FP_HASH_SZ(fc); idx++) { 1916 /* Iterate over entries in each bucket. */ 1917 f_pl = fc->policer_hash[idx]; 1918 while (NULL != f_pl) { 1919 if((f_pl->pid != -1) && ((f_pl->stage_id == _BCM_FIELD_STAGE_INGRESS) 1920 || (f_pl->stage_id == _BCM_FIELD_STAGE_EXACTMATCH))) { 1921 policer_count ++; 1922 } 1923 f_pl = f_pl->next; 1924 } 1925 } 1926 1927 /* Iterate over all hash buckets. */ 1928 for (idx = 0; idx < _FP_HASH_SZ(fc); idx++) { 1929 /* Iterate over entries in each bucket. */ 1930 f_st = fc->stat_hash[idx]; 1931 while (NULL != f_st) { 1932 if((f_st->sid != -1) && ((f_st->stage_id == _BCM_FIELD_STAGE_INGRESS) 1933 || (f_st->stage_id == _BCM_FIELD_STAGE_EXACTMATCH))) { 1934 stat_count ++; 1935 } 1936 f_st = f_st->next; 1937 } 1938 } 1939 1940 /* Iterate over all hash buckets. */ 1941 for (idx = 0; idx < _FP_HASH_SZ(fc); idx++) { 1942 /* Iterate over entries in each bucket. */ 1943 f_ht = fc->hints_hash[idx]; 1944 while (NULL != f_ht) { 1945 if(f_ht->hintid != -1) { 1946 hints_count ++; 1947 } 1948 f_ht = f_ht->next; 1949 } 1950 } 1951 1952 1953 /* _field_policer_t */ 1954 1955 /* In the encoded length below , first ten bits is value 22 [no of types], 1956 * next 22 bits is policer count in hash. Here number of types indicate 1957 * count of elements in the current datastructure. 1958 */ 1959 1960 TLV_CREATE(_bcmFieldInternalControlPolicerHash, _bcmFieldInternalArray, 1961 (policer_count | (22 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 1962 tlv->value = &(type_policer); 1963 TLV_WRITE(unit, tlv, ptr, position); 1964 1965 1966 /* Iterate over all hash buckets. */ 1967 for (idx = 0; idx < _FP_HASH_SZ(fc); idx++) { 1968 /* Iterate over entries in each bucket. */ 1969 f_pl = fc->policer_hash[idx]; 1970 while (NULL != f_pl) { 1971 if((f_pl->pid != -1) && ((f_pl->stage_id == _BCM_FIELD_STAGE_INGRESS) || 1972 (f_pl->stage_id == _BCM_FIELD_STAGE_EXACTMATCH))) { 1973 TLV_CREATE(_bcmFieldInternalPolicerPid, 1974 _bcmFieldInternalVariable,0, &tlv); 1975 tlv->value = &(f_pl->pid); 1976 TLV_WRITE(unit, tlv, ptr, position); 1977 TLV_CREATE(_bcmFieldInternalPolicerCfgFlags, 1978 _bcmFieldInternalVariable,0, &tlv); 1979 tlv->value = &(f_pl->cfg.flags); 1980 TLV_WRITE(unit, tlv, ptr, position); 1981 TLV_CREATE(_bcmFieldInternalPolicerCfgMode, 1982 _bcmFieldInternalVariable,0, &tlv); 1983 tlv->value = &(f_pl->cfg.mode); 1984 TLV_WRITE(unit, tlv, ptr, position); 1985 TLV_CREATE(_bcmFieldInternalPolicerCfgCkbitsSec, 1986 _bcmFieldInternalVariable,0, &tlv); 1987 tlv->value = &(f_pl->cfg.ckbits_sec); 1988 TLV_WRITE(unit, tlv, ptr, position); 1989 TLV_CREATE(_bcmFieldInternalPolicerCfgMaxCkbitsSec, 1990 _bcmFieldInternalVariable,0, &tlv); 1991 tlv->value = &(f_pl->cfg.max_ckbits_sec); 1992 TLV_WRITE(unit, tlv, ptr, position); 1993 TLV_CREATE(_bcmFieldInternalPolicerCfgCkbitsBurst, 1994 _bcmFieldInternalVariable,0, &tlv); 1995 tlv->value = &(f_pl->cfg.ckbits_burst); 1996 TLV_WRITE(unit, tlv, ptr, position); 1997 TLV_CREATE(_bcmFieldInternalPolicerCfgPkbitsSec, 1998 _bcmFieldInternalVariable,0, &tlv); 1999 tlv->value = &(f_pl->cfg.pkbits_sec); 2000 TLV_WRITE(unit, tlv, ptr, position); 2001 TLV_CREATE(_bcmFieldInternalPolicerCfgMaxPkbitsSec, 2002 _bcmFieldInternalVariable,0, &tlv); 2003 tlv->value = &(f_pl->cfg.max_pkbits_sec); 2004 TLV_WRITE(unit, tlv, ptr, position); 2005 TLV_CREATE(_bcmFieldInternalPolicerCfgPkbitsBurst , 2006 _bcmFieldInternalVariable,0, &tlv); 2007 tlv->value = &(f_pl->cfg.pkbits_burst); 2008 TLV_WRITE(unit, tlv, ptr, position); 2009 TLV_CREATE(_bcmFieldInternalPolicerCfgKbitsCurrent, 2010 _bcmFieldInternalVariable,0, &tlv); 2011 tlv->value = &(f_pl->cfg.kbits_current); 2012 TLV_WRITE(unit, tlv, ptr, position); 2013 TLV_CREATE(_bcmFieldInternalPolicerCfgActionId, 2014 _bcmFieldInternalVariable,0, &tlv); 2015 tlv->value = &(f_pl->cfg.action_id); 2016 TLV_WRITE(unit, tlv, ptr, position); 2017 TLV_CREATE(_bcmFieldInternalPolicerCfgSharingMode, 2018 _bcmFieldInternalVariable,0, &tlv); 2019 tlv->value = &(f_pl->cfg.sharing_mode); 2020 TLV_WRITE(unit, tlv, ptr, position); 2021 TLV_CREATE(_bcmFieldInternalPolicerCfgEntropyId, 2022 _bcmFieldInternalVariable,0, &tlv); 2023 tlv->value = &(f_pl->cfg.entropy_id); 2024 TLV_WRITE(unit, tlv, ptr, position); 2025 TLV_CREATE(_bcmFieldInternalPolicerCfgPoolId, 2026 _bcmFieldInternalVariable,0, &tlv); 2027 tlv->value = &(f_pl->cfg.pool_id); 2028 TLV_WRITE(unit, tlv, ptr, position); 2029 TLV_CREATE(_bcmFieldInternalPolicerSwRefCount, 2030 _bcmFieldInternalVariable,0, &tlv); 2031 tlv->value = &(f_pl->sw_ref_count); 2032 TLV_WRITE(unit, tlv, ptr, position); 2033 TLV_CREATE(_bcmFieldInternalPolicerHwRefCount, 2034 _bcmFieldInternalVariable,0, &tlv); 2035 tlv->value = &(f_pl->hw_ref_count); 2036 TLV_WRITE(unit, tlv, ptr, position); 2037 TLV_CREATE(_bcmFieldInternalPolicerLevel, 2038 _bcmFieldInternalVariable,0, &tlv); 2039 tlv->value = &(f_pl->level); 2040 TLV_WRITE(unit, tlv, ptr, position); 2041 TLV_CREATE(_bcmFieldInternalPolicerPoolIndex, 2042 _bcmFieldInternalVariable,0,&tlv); 2043 tlv->value = &(f_pl->pool_index); 2044 TLV_WRITE(unit, tlv, ptr, position); 2045 TLV_CREATE(_bcmFieldInternalPolicerHwIndex, 2046 _bcmFieldInternalVariable,0, &tlv); 2047 tlv->value = &(f_pl->hw_index); 2048 TLV_WRITE(unit, tlv, ptr, position); 2049 TLV_CREATE(_bcmFieldInternalPolicerHwFlags, 2050 _bcmFieldInternalVariable,0, &tlv); 2051 tlv->value = &(f_pl->hw_flags); 2052 TLV_WRITE(unit, tlv, ptr, position); 2053 TLV_CREATE(_bcmFieldInternalPolicerStageId, 2054 _bcmFieldInternalVariable,0, &tlv); 2055 tlv->value = &(f_pl->stage_id); 2056 TLV_WRITE(unit, tlv, ptr, position); 2057 2058 TLV_CREATE(_bcmFieldInternalEndStructPolicer, 2059 _bcmFieldInternalVariable, 0, &tlv); 2060 tlv->value = &endmarkerpolicer; 2061 TLV_WRITE(unit, tlv, ptr, position); 2062 2063 } 2064 f_pl = f_pl->next; 2065 } 2066 } 2067 2068 2069 /* _field_stat_t */ 2070 2071 /* In the encoded length below , first ten bits is value 17 [no of types], 2072 * next 22 bits is stat count in hash. Here number of types indicate counts 2073 * of elements in the current datastructure. 2074 */ 2075 2076 TLV_CREATE(_bcmFieldInternalControlStathash, _bcmFieldInternalVariable, 2077 (stat_count | (6 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 2078 tlv->value = &(type_stat); 2079 TLV_WRITE(unit, tlv, ptr, position); 2080 2081 /* Iterate over all hash buckets. */ 2082 for (idx = 0; idx < _FP_HASH_SZ(fc); idx++) { 2083 /* Iterate over entries in each bucket. */ 2084 f_st = fc->stat_hash[idx]; 2085 while (NULL != f_st) { 2086 if((f_st->sid != -1) && ((f_st->stage_id == _BCM_FIELD_STAGE_INGRESS) 2087 || (f_st->stage_id == _BCM_FIELD_STAGE_EXACTMATCH))) { 2088 2089 TLV_CREATE(_bcmFieldInternalStatsId, 2090 _bcmFieldInternalVariable,0, &tlv); 2091 tlv->value = &(f_st->sid); 2092 TLV_WRITE(unit, tlv, ptr, position); 2093 TLV_CREATE(_bcmFieldInternalStatnStat, 2094 _bcmFieldInternalVariable,0, &tlv); 2095 tlv->value = &(f_st->nstat); 2096 TLV_WRITE(unit, tlv, ptr, position); 2097 2098 TLV_CREATE(_bcmFieldInternalStatFlexMode, 2099 _bcmFieldInternalVariable,0, &tlv); 2100 tlv->value = &(f_st->flex_mode); 2101 TLV_WRITE(unit, tlv, ptr, position); 2102 2103 TLV_CREATE(_bcmFieldInternalStatHwFlags, 2104 _bcmFieldInternalVariable,0, &tlv); 2105 tlv->value = &(f_st->hw_flags); 2106 TLV_WRITE(unit, tlv, ptr, position); 2107 2108 _FP_XGS3_ALLOC(stat_bmp.w, 2109 SHR_BITALLOCSIZE(_bcmFieldStatCount), 2110 "Stat BMP"); 2111 if (stat_bmp.w == NULL) { 2112 return BCM_E_MEMORY; 2113 } 2114 2115 for (i = 0; i < f_st->nstat; i++) { 2116 _FP_STAT_BMP_ADD(stat_bmp, f_st->stat_arr[i]); 2117 } 2118 2119 TLV_CREATE(_bcmFieldInternalStatBmp, 2120 _bcmFieldInternalArray, _SHR_BITDCLSIZE(_bcmFieldStatCount), 2121 &tlv); 2122 tlv->value = stat_bmp.w; 2123 TLV_WRITE(unit, tlv, ptr, position); 2124 2125 if (stat_bmp.w !=NULL) { 2126 _FP_STAT_BMP_FREE(stat_bmp); 2127 } 2128 2129 stat_bmp.w = NULL; 2130 2131 TLV_CREATE(_bcmFieldInternalEndStructStat, 2132 _bcmFieldInternalVariable, 0, &tlv); 2133 tlv->value = &endmarkerstat; 2134 TLV_WRITE(unit, tlv, ptr, position); 2135 2136 } 2137 f_st = f_st->next; 2138 } 2139 } 2140 2141 /* _field_hints_t */ 2142 2143 TLV_CREATE(_bcmFieldInternalControlHintHash, 2144 _bcmFieldInternalVariable, hints_count, &tlv); 2145 TLV_WRITE(unit, tlv, ptr, position); 2146 /* Iterate over all hash buckets. */ 2147 for (idx = 0; idx < _FP_HASH_SZ(fc); idx++) { 2148 /* Iterate over entries in each bucket. */ 2149 f_ht = fc->hints_hash[idx]; 2150 while (NULL != f_ht) { 2151 if(f_ht->hintid != -1) { 2152 TLV_CREATE(_bcmFieldInternalHintHintid, 2153 _bcmFieldInternalVariable,0, &tlv); 2154 tlv->value = &(f_ht->hintid); 2155 TLV_WRITE(unit, tlv, ptr, position); 2156 2157 /* _field_hint_t */ 2158 /* In the encoded length below , first ten bits is value 8 [no of 2159 * types], next 22 bits is hints count in hash. Here number of types 2160 * indicate counts of elements in the current datastructure. 2161 */ 2162 2163 2164 TLV_CREATE(_bcmFieldInternalHintHints, _bcmFieldInternalArray, 2165 f_ht->hint_count 2166 | (9 << _FP_WB_TLV_TYPE_SHIFT), &tlv); 2167 tlv->value = &(type_hint); 2168 TLV_WRITE(unit, tlv, ptr, position); 2169 hint = f_ht->hints; 2170 2171 for (hintidx = 0; hintidx < f_ht->hint_count; hintidx++) { 2172 2173 TLV_CREATE(_bcmFieldInternalHintHintsHintType, 2174 _bcmFieldInternalVariable,0,&tlv); 2175 tlv->value = &(hint->hint->hint_type); 2176 TLV_WRITE(unit, tlv, ptr, position); 2177 2178 TLV_CREATE(_bcmFieldInternalHintHintsQual, 2179 _bcmFieldInternalVariable,0, &tlv); 2180 tlv->value = &(hint->hint->qual); 2181 TLV_WRITE(unit, tlv, ptr, position); 2182 2183 TLV_CREATE(_bcmFieldInternalHintHintsMaxValues, 2184 _bcmFieldInternalVariable,0, &tlv); 2185 tlv->value = &(hint->hint->max_values); 2186 TLV_WRITE(unit, tlv, ptr, position); 2187 2188 TLV_CREATE(_bcmFieldInternalHintHintsStartBit, 2189 _bcmFieldInternalVariable,0, &tlv); 2190 tlv->value = &(hint->hint->start_bit); 2191 TLV_WRITE(unit, tlv, ptr, position); 2192 2193 TLV_CREATE(_bcmFieldInternalHintHintsEndBit, 2194 _bcmFieldInternalVariable,0, &tlv); 2195 tlv->value = &(hint->hint->end_bit); 2196 TLV_WRITE(unit, tlv, ptr, position); 2197 2198 TLV_CREATE(_bcmFieldInternalHintHintsFlags, 2199 _bcmFieldInternalVariable,0, &tlv); 2200 tlv->value = &(hint->hint->flags); 2201 TLV_WRITE(unit, tlv, ptr, position); 2202 2203 TLV_CREATE(_bcmFieldInternalHintHintsMaxGrpSize, 2204 _bcmFieldInternalVariable,0, &tlv); 2205 tlv->value = &(hint->hint->max_group_size); 2206 TLV_WRITE(unit, tlv, ptr, position); 2207 2208 TLV_CREATE(_bcmFieldInternalHintHintsPri, 2209 _bcmFieldInternalVariable,0, &tlv); 2210 tlv->value = &(hint->hint->priority); 2211 TLV_WRITE(unit, tlv, ptr, position); 2212 2213 TLV_CREATE(_bcmFieldInternalHintHintsDosAttackEventFlags, 2214 _bcmFieldInternalVariable,0, &tlv); 2215 tlv->value = &(hint->hint->dosattack_event_flags); 2216 TLV_WRITE(unit, tlv, ptr, position); 2217 2218 TLV_CREATE(_bcmFieldInternalEndStructHintHints, 2219 _bcmFieldInternalVariable, 0, &tlv); 2220 TLV_WRITE(unit, tlv, ptr, position); 2221 2222 hint = hint->next; 2223 } 2224 2225 2226 TLV_CREATE(_bcmFieldInternalHintGrpRefCount, 2227 _bcmFieldInternalVariable,0, &tlv); 2228 tlv->value = &(f_ht->grp_ref_count); 2229 TLV_WRITE(unit, tlv, ptr, position); 2230 2231 TLV_CREATE(_bcmFieldInternalHintCount, 2232 _bcmFieldInternalVariable,0, &tlv); 2233 tlv->value = &(f_ht->hint_count); 2234 TLV_WRITE(unit, tlv, ptr, position); 2235 2236 TLV_CREATE(_bcmFieldInternalEndStructHint, 2237 _bcmFieldInternalVariable, 0, &tlv); 2238 tlv->value = &endmarkerhint; 2239 TLV_WRITE(unit, tlv, ptr, position); 2240 2241 } 2242 f_ht = f_ht->next; 2243 } 2244 } 2245 2246 sal_free(tlv); 2247 return BCM_E_NONE; 2248 } 2249 2250 2251 /* Function: 2252 * _field_presel_entry_sync 2253 * 2254 * Purpose: 2255 * Sync presel entries 2256 * 2257 * Paramaters: 2258 * unit - (IN) BCM device number 2259 * 2260 * Returns: 2261 * BCM_E_XXX 2262 */ 2263 2264 int 2265 _field_presel_entry_sync(int unit) 2266 { 2267 2268 _field_tlv_t *tlv = NULL; /* tlv data */ 2269 _field_control_t *fc; /* Field control structure. */ 2270 _field_presel_entry_t *f_pr; /* Internal Presel Descriptor */ 2271 int idx = 0; /* Iterator */ 2272 int presel_ent_count = 0; /* number of presel entries */ 2273 uint32 endmarkerpresel = _FIELD_WB_EM_PRESEL; 2274 /* End marker for Presel */ 2275 int type_presel[12] = { /* types in _field_presel_entry_t */ 2276 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2277 | _bcmFieldInternalPreselId), 2278 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2279 | _bcmFieldInternalPreselFlags), 2280 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2281 | _bcmFieldInternalPreselPri), 2282 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2283 | _bcmFieldInternalPreselSliceIndex), 2284 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2285 | _bcmFieldInternalPreselEntryGroup), 2286 (int)((_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2287 | _bcmFieldInternalPreselEntrySlice), 2288 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2289 | _bcmFieldInternalPreselKeySize), 2290 (int)((_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2291 | _bcmFieldInternalPreselQset), 2292 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2293 | _bcmFieldInternalPreselHwIndex), 2294 (int)((_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2295 | _bcmFieldInternalPreselClassAction), 2296 (int)((_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2297 | _bcmFieldInternalPreselPbmp), 2298 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2299 | _bcmFieldInternalEndStructPreselInfo) 2300 }; 2301 2302 uint8 *ptr; /* Pointer to scache_pos */ 2303 uint32 *position; /* Scache position */ 2304 bcm_field_qualify_t stage_qual= bcmFieldQualifyStage; /* Stage Qualifier */ 2305 int empty = -1; /* Dummy data */ 2306 2307 if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 2308 stage_qual = bcmFieldQualifyStageIngress; 2309 } else if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 2310 stage_qual = bcmFieldQualifyStageIngressExactMatch; 2311 } else if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_FLOWTRACKER) { 2312 stage_qual = bcmFieldQualifyStageIngressFlowtracker; 2313 } 2314 2315 WB_FIELD_CONTROL_GET(fc, ptr, position); 2316 2317 /* Iterate over entry array. */ 2318 for (idx = 0; idx < BCM_FIELD_PRESEL_SEL_MAX; idx++) { 2319 /* Iterate over entries in each bucket. */ 2320 f_pr = fc->presel_db[idx]; 2321 if ((NULL != f_pr) && (f_pr->presel_id != -1) 2322 && (BCM_FIELD_QSET_TEST(f_pr->p_qset, 2323 stage_qual))) { 2324 presel_ent_count ++; 2325 } 2326 } 2327 2328 /* _field_presel_entry_t */ 2329 2330 /* In the encoded length below , first ten bits is value 12 [no of types], 2331 * next 22 bits is presel entry count in hash. 2332 * Here number of types indicate counts 2333 * of elements in the current datastructure. 2334 */ 2335 2336 TLV_CREATE(_bcmFieldInternalControlPreselInfo, _bcmFieldInternalVariable, 2337 (presel_ent_count | (12 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 2338 tlv->value = &(type_presel); 2339 TLV_WRITE(unit, tlv, ptr, position); 2340 2341 /* Iterate over all hash buckets. */ 2342 for (idx = 0; idx < BCM_FIELD_PRESEL_SEL_MAX ; idx++) { 2343 /* Iterate over entries in each bucket. */ 2344 f_pr = fc->presel_db[idx]; 2345 if ((NULL != f_pr) && (f_pr->presel_id != -1) 2346 && (BCM_FIELD_QSET_TEST(f_pr->p_qset, 2347 stage_qual))) { 2348 TLV_CREATE(_bcmFieldInternalPreselId, 2349 _bcmFieldInternalVariable,0, &tlv); 2350 tlv->value = &(f_pr->presel_id); 2351 TLV_WRITE(unit, tlv, ptr, position); 2352 TLV_CREATE(_bcmFieldInternalPreselFlags, 2353 _bcmFieldInternalVariable,0, &tlv); 2354 tlv->value = &(f_pr->flags); 2355 TLV_WRITE(unit, tlv, ptr, position); 2356 TLV_CREATE(_bcmFieldInternalPreselPri, 2357 _bcmFieldInternalVariable,0, &tlv); 2358 tlv->value = &(f_pr->priority); 2359 TLV_WRITE(unit, tlv, ptr, position); 2360 TLV_CREATE(_bcmFieldInternalPreselSliceIndex, 2361 _bcmFieldInternalVariable,0, &tlv); 2362 tlv->value = &(f_pr->slice_index); 2363 TLV_WRITE(unit, tlv, ptr, position); 2364 TLV_CREATE(_bcmFieldInternalPreselEntryGroup, 2365 _bcmFieldInternalVariable,0, &tlv); 2366 if (f_pr->group != NULL) { 2367 tlv->value = &(f_pr->group->gid); 2368 } else { 2369 tlv->value = ∅ 2370 } 2371 TLV_WRITE(unit, tlv, ptr, position); 2372 if (f_pr->lt_fs != NULL) { 2373 TLV_CREATE(_bcmFieldInternalPreselEntrySlice, 2374 _bcmFieldInternalArray,1, &tlv); 2375 tlv->value = &(f_pr->lt_fs->slice_number); 2376 } else { 2377 TLV_CREATE(_bcmFieldInternalPreselEntrySlice, 2378 _bcmFieldInternalArray,0, &tlv); 2379 } 2380 TLV_WRITE(unit, tlv, ptr, position); 2381 TLV_CREATE(_bcmFieldInternalPreselKeySize, 2382 _bcmFieldInternalVariable,0, &tlv); 2383 tlv->value = &(f_pr->lt_tcam.key_size); 2384 TLV_WRITE(unit, tlv, ptr, position); 2385 TLV_CREATE(_bcmFieldInternalPreselQset, 2386 _bcmFieldInternalArray, 2387 _SHR_BITDCLSIZE(BCM_FIELD_QUALIFY_MAX), &tlv); 2388 tlv->value = &(f_pr->p_qset.w); 2389 TLV_WRITE(unit, tlv, ptr, position); 2390 TLV_CREATE(_bcmFieldInternalPreselHwIndex, 2391 _bcmFieldInternalVariable,0, &tlv); 2392 tlv->value = &(f_pr->hw_index); 2393 TLV_WRITE(unit, tlv, ptr, position); 2394 2395 if (f_pr->actions != NULL) { 2396 TLV_CREATE(_bcmFieldInternalPreselClassAction, 2397 _bcmFieldInternalArray,1, &tlv); 2398 tlv->value = &(f_pr->actions->param[0]); 2399 } else { 2400 TLV_CREATE(_bcmFieldInternalPreselClassAction, 2401 _bcmFieldInternalArray,0, &tlv); 2402 } 2403 TLV_WRITE(unit, tlv, ptr, position); 2404 2405 TLV_CREATE(_bcmFieldInternalPreselPbmp, 2406 _bcmFieldInternalArray, 2407 _SHR_PBMP_WORD_MAX, &tlv); 2408 tlv->value = &(f_pr->mixed_src_class_pbmp.pbits); 2409 TLV_WRITE(unit, tlv, ptr, position); 2410 2411 TLV_CREATE(_bcmFieldInternalEndStructPreselInfo, 2412 _bcmFieldInternalVariable, 0, &tlv); 2413 tlv->value = &endmarkerpresel; 2414 TLV_WRITE(unit, tlv, ptr, position); 2415 2416 } 2417 } 2418 2419 sal_free(tlv); 2420 return BCM_E_NONE; 2421 2422 } 2423 2424 /* Function: 2425 * _field_udf_sync 2426 * 2427 * Purpose: 2428 * Sync _field_udf_t structure 2429 * 2430 * Paramaters: 2431 * unit - (IN) BCM device number 2432 * scache_ptr - (IN) Pointer to device field control structure 2433 * ptr - 2434 * udf - 2435 * Returns: 2436 * BCM_E_XXX 2437 */ 2438 int 2439 _field_udf_sync(int unit, uint8 *ptr, uint32 *pos, _field_udf_t *udf) 2440 { 2441 _field_tlv_t *tlv = NULL; /* TLV data structure */ 2442 int endmarker = _FIELD_WB_EM_UDF; /* End marker for UDF */ 2443 2444 TLV_CREATE(_bcmFieldInternalControlUdfValid, 2445 _bcmFieldInternalVariable, 0, &tlv); 2446 tlv->value = &(udf->valid); 2447 TLV_WRITE(unit,tlv,ptr,pos); 2448 2449 TLV_CREATE(_bcmFieldInternalControlUdfUseCount, 2450 _bcmFieldInternalVariable, 0, &tlv); 2451 tlv->value = &(udf->use_count); 2452 TLV_WRITE(unit,tlv,ptr,pos); 2453 2454 TLV_CREATE(_bcmFieldInternalControlUdfNum, 2455 _bcmFieldInternalVariable, 0, &tlv); 2456 tlv->value = &(udf->udf_num); 2457 TLV_WRITE(unit,tlv,ptr,pos); 2458 2459 TLV_CREATE(_bcmFieldInternalControlUdfUserNum, 2460 _bcmFieldInternalVariable, 0, &tlv); 2461 tlv->value = &(udf->user_num); 2462 TLV_WRITE(unit,tlv,ptr,pos); 2463 2464 TLV_CREATE(_bcmFieldInternalControlEndStructUdf, 2465 _bcmFieldInternalVariable, 0, &tlv); 2466 tlv->value = &endmarker; 2467 TLV_WRITE(unit,tlv,ptr,pos); 2468 2469 sal_free(tlv); 2470 return BCM_E_NONE; 2471 2472 } 2473 2474 /* Function: 2475 * _field_control_sync 2476 * 2477 * Purpose: 2478 * Sync _field_control_t structure 2479 * 2480 * Paramaters: 2481 * unit - (IN) BCM device number 2482 * fc - (IN) Pointer to device field control structure 2483 * 2484 * Returns: 2485 * BCM_E_XXX 2486 */ 2487 2488 int 2489 _field_control_sync(int unit) 2490 { 2491 2492 _field_tlv_t *tlv = NULL; /* Tlv data structure */ 2493 uint8 *scache_ptr = NULL; 2494 /* Scache Pointer */ 2495 _field_group_t *fg; /* Group information */ 2496 int group_count = 0; /* Number of groups */ 2497 int *gid = NULL; /* Array of groupids */ 2498 int hintbmp_length = 0; /* length of hint bmp */ 2499 uint32 endmarker = _FIELD_WB_EM_CONTROL; 2500 /* End marker for fc */ 2501 int pos = 0; /* variable for loops */ 2502 2503 int type_udf[5] = { /* types in _field_udf_t */ 2504 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2505 | _bcmFieldInternalControlUdfValid), 2506 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2507 | _bcmFieldInternalControlUdfUseCount), 2508 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2509 | _bcmFieldInternalControlUdfNum), 2510 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2511 | _bcmFieldInternalControlUdfUserNum), 2512 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 2513 | _bcmFieldInternalControlEndStructUdf), 2514 }; 2515 uint32 *position; /* Scache position */ 2516 _field_control_t *fc; /* field control Structure */ 2517 int rv = 0; /* Return variable */ 2518 2519 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 2520 2521 2522 TLV_CREATE(_bcmFieldInternalControl, 2523 _bcmFieldInternalVariable, 0, &tlv); 2524 TLV_WRITE(unit, tlv, scache_ptr, position); 2525 2526 TLV_CREATE(_bcmFieldInternalControlFlags, 2527 _bcmFieldInternalVariable, 0, &tlv); 2528 tlv->value = &(fc->flags); 2529 TLV_WRITE(unit, tlv, scache_ptr, position); 2530 2531 fg = fc->groups; 2532 while (fg != NULL) { 2533 if (fg->stage_id == _BCM_FIELD_STAGE_INGRESS) { 2534 group_count ++ ; 2535 } 2536 fg = fg->next; 2537 } 2538 2539 _FP_XGS3_ALLOC(gid, (sizeof(uint32) * group_count), "alloc for groups"); 2540 if (gid == NULL) { 2541 rv = BCM_E_MEMORY; 2542 goto cleanup; 2543 } 2544 2545 fg = fc->groups; 2546 while (fg != NULL) { 2547 if (fg->stage_id == _BCM_FIELD_STAGE_INGRESS) { 2548 gid[pos++] = fg->gid; 2549 } 2550 fg = fg->next; 2551 } 2552 2553 /* In the encoded length below , first ten bits is value 5 [no of types], 2554 * next 22 bits is no of udfs. Here number of types indicate counts of 2555 * elements in the current datastructure. 2556 */ 2557 2558 TLV_CREATE(_bcmFieldInternalControlUdfDetails, _bcmFieldInternalArray, 2559 (BCM_FIELD_USER_NUM_UDFS | (5 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 2560 tlv->value = &type_udf; 2561 /* coverity[resource_leak] */ 2562 /* coverity[leaked_storage] */ 2563 TLV_WRITE(unit, tlv, scache_ptr, position); 2564 2565 for (pos = 0; pos < BCM_FIELD_USER_NUM_UDFS; pos++) { 2566 rv = _field_udf_sync(unit, scache_ptr, 2567 position, &(fc->udf[pos])); 2568 BCM_IF_ERROR_CLEANUP(rv); 2569 } 2570 2571 2572 TLV_CREATE(_bcmFieldInternalControlGroups, 2573 _bcmFieldInternalArray, group_count, &tlv); 2574 tlv->value = &gid; 2575 TLV_WRITE(unit, tlv, scache_ptr, position); 2576 2577 2578 TLV_CREATE(_bcmFieldInternalControlPolicerCount, 2579 _bcmFieldInternalVariable,0,&tlv); 2580 tlv->value = &(fc->policer_count); 2581 TLV_WRITE(unit, tlv, scache_ptr, position); 2582 2583 TLV_CREATE(_bcmFieldInternalControlStatCount, 2584 _bcmFieldInternalVariable,0,&tlv); 2585 tlv->value = &(fc->stat_count); 2586 TLV_WRITE(unit, tlv, scache_ptr, position); 2587 2588 hintbmp_length = SHR_BITALLOCSIZE(_FP_HINT_ID_MAX); 2589 TLV_CREATE(_bcmFieldInternalControlHintBmp, 2590 _bcmFieldInternalArray, 2591 hintbmp_length, &tlv); 2592 tlv->value = fc->hintid_bmp.w; 2593 TLV_WRITE(unit, tlv, scache_ptr, position); 2594 2595 TLV_CREATE(_bcmFieldInternalControlLastAllocatedLtId, 2596 _bcmFieldInternalVariable,0,&tlv); 2597 tlv->value = &(fc->last_allocated_lt_eid); 2598 TLV_WRITE(unit, tlv, scache_ptr, position); 2599 2600 rv = _field_hash_sync(unit); 2601 BCM_IF_ERROR_CLEANUP(rv); 2602 2603 2604 TLV_CREATE(_bcmFieldInternalPreselInfoLimit, 2605 _bcmFieldInternalVariable,0,&tlv); 2606 tlv->value = &(fc->presel_info->presel_limit); 2607 TLV_WRITE(unit, tlv, scache_ptr, position); 2608 2609 TLV_CREATE(_bcmFieldInternalPreselLastAllocatedId, 2610 _bcmFieldInternalVariable,0,&tlv); 2611 tlv->value = &(fc->presel_info->last_allocated_id); 2612 TLV_WRITE(unit, tlv, scache_ptr, position); 2613 2614 TLV_CREATE(_bcmFieldInternalPreselSet, 2615 _bcmFieldInternalArray, 2616 _SHR_BITDCLSIZE(BCM_FIELD_PRESEL_SEL_MAX),&tlv); 2617 tlv->value = &(fc->presel_info->presel_set); 2618 TLV_WRITE(unit, tlv, scache_ptr, position); 2619 2620 TLV_CREATE(_bcmFieldInternalPreselOperationalSet, 2621 _bcmFieldInternalArray, 2622 _SHR_BITDCLSIZE(BCM_FIELD_PRESEL_SEL_MAX),&tlv); 2623 tlv->value = &(fc->presel_info->operational_set); 2624 TLV_WRITE(unit, tlv, scache_ptr, position); 2625 2626 TLV_CREATE(_bcmFieldInternalControlMeterInUse, 2627 _bcmFieldInternalArray, 2628 (_FP_MAX_NUM_PIPES * _FIELD_MAX_METER_POOLS),&tlv); 2629 tlv->value = &(fc->ifp_em_meter_in_use); 2630 TLV_WRITE(unit, tlv, scache_ptr, position); 2631 2632 TLV_CREATE(_bcmFieldInternalEndStructControl, 2633 _bcmFieldInternalVariable, 0, &tlv); 2634 tlv->value = &endmarker; 2635 TLV_WRITE(unit, tlv, scache_ptr, position); 2636 2637 cleanup: 2638 sal_free(gid); 2639 sal_free(tlv); 2640 return rv; 2641 2642 2643 } 2644 /* Function: 2645 * _field_datacontroldataqualifier_sync 2646 * 2647 * Purpose: 2648 * Sync _field_data_qualifier_p structure 2649 * 2650 * Paramaters: 2651 * unit - (IN) BCM device number 2652 * fdp - (IN) Pointer to Field Data Qualifier structure 2653 * 2654 * Returns: 2655 * BCM_E_XXX 2656 */ 2657 2658 int 2659 _field_datacontroldataqualifier_sync(int unit, _field_data_qualifier_p fdp) 2660 { 2661 2662 _field_tlv_t *tlv = NULL; /* &tlv data */ 2663 uint8 *ptr = NULL; /* Scache Pointer */ 2664 _field_control_t *fc = NULL; /* Field control structure. */ 2665 uint32 *position = NULL; /* Scache Position */ 2666 int endmarker = _FIELD_WB_EM_DATAQUAL; 2667 /* End Marker */ 2668 2669 WB_FIELD_CONTROL_GET(fc, ptr, position); 2670 2671 2672 TLV_CREATE(_bcmFieldInternalDataControlDataQualQid, 2673 _bcmFieldInternalVariable,0, &tlv); 2674 tlv->value = &(fdp->qid); 2675 TLV_WRITE(unit, tlv, ptr, position); 2676 2677 2678 TLV_CREATE(_bcmFieldInternalDataControlDataQualUdfSpec, 2679 _bcmFieldInternalArray, 384, &tlv); 2680 tlv->value = (fdp->spec); 2681 TLV_WRITE(unit, tlv, ptr, position); 2682 2683 2684 TLV_CREATE(_bcmFieldInternalDataControlDataQualOffsetBase, 2685 _bcmFieldInternalVariable,0, &tlv); 2686 tlv->value = &(fdp->offset_base); 2687 TLV_WRITE(unit, tlv, ptr, position); 2688 2689 2690 TLV_CREATE(_bcmFieldInternalDataControlDataQualOffset, 2691 _bcmFieldInternalVariable,0, &tlv); 2692 tlv->value = &(fdp->offset); 2693 TLV_WRITE(unit, tlv, ptr, position); 2694 2695 TLV_CREATE(_bcmFieldInternalDataControlDataQualByteOffset, 2696 _bcmFieldInternalVariable,0, &tlv); 2697 tlv->value = &(fdp->byte_offset); 2698 TLV_WRITE(unit, tlv, ptr, position); 2699 2700 2701 TLV_CREATE(_bcmFieldInternalDataControlDataQualHwBmp, 2702 _bcmFieldInternalVariable,0, &tlv); 2703 tlv->value = &(fdp->hw_bmap); 2704 TLV_WRITE(unit, tlv, ptr, position); 2705 2706 TLV_CREATE(_bcmFieldInternalDataControlDataQualFlags, 2707 _bcmFieldInternalVariable,0, &tlv); 2708 tlv->value = &(fdp->flags); 2709 TLV_WRITE(unit, tlv, ptr, position); 2710 2711 2712 TLV_CREATE(_bcmFieldInternalDataControlDataQualElemCount, 2713 _bcmFieldInternalVariable,0, &tlv); 2714 tlv->value = &(fdp->elem_count); 2715 TLV_WRITE(unit, tlv, ptr, position); 2716 2717 2718 TLV_CREATE(_bcmFieldInternalDataControlDataQualLength, 2719 _bcmFieldInternalVariable,0, &tlv); 2720 tlv->value = &(fdp->length); 2721 TLV_WRITE(unit, tlv, ptr, position); 2722 2723 TLV_CREATE(_bcmFieldInternalDataControlEndStructDataQual, 2724 _bcmFieldInternalVariable, 0, &tlv); 2725 tlv->value = &(endmarker); 2726 TLV_WRITE(unit, tlv, ptr, position); 2727 2728 sal_free(tlv); 2729 2730 return BCM_E_NONE; 2731 } 2732 2733 /* Function: 2734 * _field_extractor_sync 2735 * 2736 * Purpose: 2737 * recover _field_slice_t structure 2738 * 2739 * Paramaters: 2740 * unit - (IN) BCM device number 2741 * fc - (IN) field control structure of the unit. 2742 * ext_sel - (IN) address of start of array in slice structure. 2743 * count - (IN) Number of extractor structures to be synced. 2744 * 2745 * Returns: 2746 * BCM_E_XXX 2747 */ 2748 int 2749 _field_extractor_sync(int unit, 2750 _field_ext_sel_t *ext_sel, int count) 2751 { 2752 2753 _field_tlv_t *tlv = NULL; /* tlv structure */ 2754 int i = 0; /* loop variable */ 2755 int endmarker = _FIELD_WB_EM_EXTRACTOR; 2756 /* End marker */ 2757 uint8 *ptr; /* pointer to scache_ptr (base) */ 2758 uint32 *pos; /* Pointer to scache_pos (offset) */ 2759 _field_control_t *fc; /* field Control structure */ 2760 _field_ext_sel_t *ext_sel_temp; /* temp pointer to ext_sel */ 2761 int type_ext_sel[33] = { /* types in _field_ext_sel_t */ 2762 (int) (_bcmFieldInternalExtl1e32Sel 2763 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2764 (int) (_bcmFieldInternalExtl1e16Sel 2765 |(_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2766 (int) (_bcmFieldInternalExtl1e8Sel 2767 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2768 (int) (_bcmFieldInternalExtl1e4Sel 2769 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2770 (int) (_bcmFieldInternalExtl1e2Sel 2771 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2772 (int) (_bcmFieldInternalExtl2e16Sel 2773 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2774 (int) (_bcmFieldInternalExtl3e1Sel 2775 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2776 (int) (_bcmFieldInternalExtl3e2Sel 2777 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2778 (int) (_bcmFieldInternalExtl3e4Sel 2779 |(_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2780 (int) (_bcmFieldInternalExtPmuxSel 2781 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2782 (int) (_bcmFieldInternalExtIntraSlice 2783 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2784 (int) (_bcmFieldInternalExtSecondary 2785 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2786 (int) (_bcmFieldInternalExtIpbmpRes 2787 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2788 (int) (_bcmFieldInternalExtNorml3l4 2789 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2790 (int) (_bcmFieldInternalExtNormmac 2791 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2792 (int) (_bcmFieldInternalExtAuxTagaSel 2793 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2794 (int) (_bcmFieldInternalExtAuxTagbSel 2795 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2796 (int) (_bcmFieldInternalExtAuxTagcSel 2797 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2798 (int) (_bcmFieldInternalExtAuxTagdSel 2799 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2800 (int) (_bcmFieldInternalExtTcpFnSel 2801 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2802 (int) (_bcmFieldInternalExtTosFnSel 2803 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2804 (int) (_bcmFieldInternalExtTtlFnSel 2805 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2806 (int) (_bcmFieldInternalExtClassIdaSel 2807 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2808 (int) (_bcmFieldInternalExtClassIdbSel 2809 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2810 (int) (_bcmFieldInternalExtClassIdcSel 2811 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2812 (int) (_bcmFieldInternalExtClassIddSel 2813 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2814 (int) (_bcmFieldInternalExtSrcContaSel 2815 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2816 (int) (_bcmFieldInternalExtSrcContbSel 2817 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2818 (int) (_bcmFieldInternalExtSrcDestCont0Sel 2819 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2820 (int) (_bcmFieldInternalExtSrcDestCont1Sel 2821 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2822 (int) (_bcmFieldInternalExtKeygenIndex 2823 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2824 (int) (_bcmFieldInternalExtAltTtlFnSel 2825 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2826 (int) (_bcmFieldInternalEndStructExtractor 2827 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 2828 }; 2829 2830 WB_FIELD_CONTROL_GET(fc, ptr, pos); 2831 2832 2833 /* In the encoded length below , first ten bits is value 33 [no of types], 2834 * next 22 bits is count of extractors. Here number of types indicate counts 2835 * of elements in the current datastructure. 2836 */ 2837 2838 TLV_CREATE(_bcmFieldInternalExtractor, 2839 _bcmFieldInternalArray, (count 2840 | (33 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 2841 tlv->value = &type_ext_sel[0]; 2842 TLV_WRITE(unit,tlv,ptr,pos); 2843 2844 for (i = 0; i < count; i++) { 2845 ext_sel_temp = &ext_sel[i]; 2846 TLV_CREATE(_bcmFieldInternalExtl1e32Sel, 2847 _bcmFieldInternalArray, 4, &tlv); 2848 tlv->value = ext_sel_temp->l1_e32_sel; 2849 TLV_WRITE(unit,tlv,ptr,pos); 2850 2851 TLV_CREATE(_bcmFieldInternalExtl1e16Sel, 2852 _bcmFieldInternalArray, 7, &tlv); 2853 tlv->value = ext_sel_temp->l1_e16_sel; 2854 TLV_WRITE(unit,tlv,ptr,pos); 2855 2856 TLV_CREATE(_bcmFieldInternalExtl1e8Sel, 2857 _bcmFieldInternalArray, 7, &tlv); 2858 tlv->value = ext_sel_temp->l1_e8_sel; 2859 TLV_WRITE(unit,tlv,ptr,pos); 2860 2861 TLV_CREATE(_bcmFieldInternalExtl1e4Sel, 2862 _bcmFieldInternalArray, 8, &tlv); 2863 tlv->value = ext_sel_temp->l1_e4_sel; 2864 TLV_WRITE(unit,tlv,ptr,pos); 2865 2866 TLV_CREATE(_bcmFieldInternalExtl1e2Sel, 2867 _bcmFieldInternalArray, 8, &tlv); 2868 tlv->value = ext_sel_temp->l1_e2_sel; 2869 TLV_WRITE(unit,tlv,ptr,pos); 2870 2871 TLV_CREATE(_bcmFieldInternalExtl2e16Sel, 2872 _bcmFieldInternalArray, 10, &tlv); 2873 tlv->value = ext_sel_temp->l2_e16_sel; 2874 TLV_WRITE(unit,tlv,ptr,pos); 2875 2876 TLV_CREATE(_bcmFieldInternalExtl3e1Sel, 2877 _bcmFieldInternalArray, 2, &tlv); 2878 tlv->value = ext_sel_temp->l3_e1_sel; 2879 TLV_WRITE(unit,tlv,ptr,pos); 2880 2881 TLV_CREATE(_bcmFieldInternalExtl3e2Sel, 2882 _bcmFieldInternalArray, 5, &tlv); 2883 tlv->value = ext_sel_temp->l3_e2_sel; 2884 TLV_WRITE(unit,tlv,ptr,pos); 2885 2886 TLV_CREATE(_bcmFieldInternalExtl3e4Sel, 2887 _bcmFieldInternalArray, 21, &tlv); 2888 tlv->value = ext_sel_temp->l3_e4_sel; 2889 TLV_WRITE(unit,tlv,ptr,pos); 2890 2891 TLV_CREATE(_bcmFieldInternalExtPmuxSel, 2892 _bcmFieldInternalArray, 15, &tlv); 2893 tlv->value = ext_sel_temp->pmux_sel; 2894 TLV_WRITE(unit,tlv,ptr,pos); 2895 2896 TLV_CREATE(_bcmFieldInternalExtIntraSlice, 2897 _bcmFieldInternalVariable, 4, &tlv); 2898 tlv->value = &ext_sel_temp->intraslice; 2899 TLV_WRITE(unit,tlv,ptr,pos); 2900 2901 TLV_CREATE(_bcmFieldInternalExtSecondary, 2902 _bcmFieldInternalVariable, 4, &tlv); 2903 tlv->value = &ext_sel_temp->secondary; 2904 TLV_WRITE(unit,tlv,ptr,pos); 2905 2906 TLV_CREATE(_bcmFieldInternalExtIpbmpRes, 2907 _bcmFieldInternalVariable, 4, &tlv); 2908 tlv->value = &ext_sel_temp->ipbm_present; 2909 TLV_WRITE(unit,tlv,ptr,pos); 2910 2911 TLV_CREATE(_bcmFieldInternalExtNorml3l4, 2912 _bcmFieldInternalVariable, 4, &tlv); 2913 tlv->value = &ext_sel_temp->normalize_l3_l4_sel; 2914 TLV_WRITE(unit,tlv,ptr,pos); 2915 2916 TLV_CREATE(_bcmFieldInternalExtNormmac, 2917 _bcmFieldInternalVariable, 4, &tlv); 2918 tlv->value = &ext_sel_temp->normalize_mac_sel; 2919 TLV_WRITE(unit,tlv,ptr,pos); 2920 2921 TLV_CREATE(_bcmFieldInternalExtAuxTagaSel, 2922 _bcmFieldInternalVariable, 4, &tlv); 2923 tlv->value = &ext_sel_temp->aux_tag_a_sel; 2924 TLV_WRITE(unit,tlv,ptr,pos); 2925 2926 TLV_CREATE(_bcmFieldInternalExtAuxTagbSel, 2927 _bcmFieldInternalVariable, 4, &tlv); 2928 tlv->value = &ext_sel_temp->aux_tag_b_sel; 2929 TLV_WRITE(unit,tlv,ptr,pos); 2930 2931 2932 TLV_CREATE(_bcmFieldInternalExtAuxTagcSel, 2933 _bcmFieldInternalVariable, 4, &tlv); 2934 tlv->value = &ext_sel_temp->aux_tag_c_sel; 2935 TLV_WRITE(unit,tlv,ptr,pos); 2936 2937 TLV_CREATE(_bcmFieldInternalExtAuxTagdSel, 2938 _bcmFieldInternalVariable, 4, &tlv); 2939 tlv->value = &ext_sel_temp->aux_tag_d_sel; 2940 TLV_WRITE(unit,tlv,ptr,pos); 2941 2942 TLV_CREATE(_bcmFieldInternalExtTcpFnSel, 2943 _bcmFieldInternalVariable, 4, &tlv); 2944 tlv->value = &ext_sel_temp->tcp_fn_sel; 2945 TLV_WRITE(unit,tlv,ptr,pos); 2946 2947 TLV_CREATE(_bcmFieldInternalExtTosFnSel, 2948 _bcmFieldInternalVariable, 4, &tlv); 2949 tlv->value = &ext_sel_temp->tos_fn_sel; 2950 TLV_WRITE(unit,tlv,ptr,pos); 2951 2952 TLV_CREATE(_bcmFieldInternalExtTtlFnSel, 2953 _bcmFieldInternalVariable, 4, &tlv); 2954 tlv->value = &ext_sel_temp->ttl_fn_sel; 2955 TLV_WRITE(unit,tlv,ptr,pos); 2956 2957 TLV_CREATE(_bcmFieldInternalExtClassIdaSel, 2958 _bcmFieldInternalVariable, 4, &tlv); 2959 tlv->value = &ext_sel_temp->class_id_cont_a_sel; 2960 TLV_WRITE(unit,tlv,ptr,pos); 2961 2962 TLV_CREATE(_bcmFieldInternalExtClassIdbSel, 2963 _bcmFieldInternalVariable, 4, &tlv); 2964 tlv->value = &ext_sel_temp->class_id_cont_b_sel; 2965 TLV_WRITE(unit,tlv,ptr,pos); 2966 2967 TLV_CREATE(_bcmFieldInternalExtClassIdcSel, 2968 _bcmFieldInternalVariable, 4, &tlv); 2969 tlv->value = &ext_sel_temp->class_id_cont_c_sel; 2970 TLV_WRITE(unit,tlv,ptr,pos); 2971 2972 TLV_CREATE(_bcmFieldInternalExtClassIddSel, 2973 _bcmFieldInternalVariable, 4, &tlv); 2974 tlv->value = &ext_sel_temp->class_id_cont_d_sel; 2975 TLV_WRITE(unit,tlv,ptr,pos); 2976 2977 TLV_CREATE(_bcmFieldInternalExtSrcContaSel, 2978 _bcmFieldInternalVariable, 4, &tlv); 2979 tlv->value = &ext_sel_temp->src_cont_a_sel; 2980 TLV_WRITE(unit,tlv,ptr,pos); 2981 2982 TLV_CREATE(_bcmFieldInternalExtSrcContbSel, 2983 _bcmFieldInternalVariable, 4, &tlv); 2984 tlv->value = &ext_sel_temp->src_cont_b_sel; 2985 TLV_WRITE(unit,tlv,ptr,pos); 2986 2987 TLV_CREATE(_bcmFieldInternalExtSrcDestCont0Sel, 2988 _bcmFieldInternalVariable, 4, &tlv); 2989 tlv->value = &ext_sel_temp->src_dest_cont_0_sel; 2990 TLV_WRITE(unit,tlv,ptr,pos); 2991 2992 TLV_CREATE(_bcmFieldInternalExtSrcDestCont1Sel, 2993 _bcmFieldInternalVariable, 4, &tlv); 2994 tlv->value = &ext_sel_temp->src_dest_cont_1_sel; 2995 TLV_WRITE(unit,tlv,ptr,pos); 2996 2997 2998 TLV_CREATE(_bcmFieldInternalExtKeygenIndex, 2999 _bcmFieldInternalVariable, 4, &tlv); 3000 tlv->value = &ext_sel_temp->keygen_index; 3001 TLV_WRITE(unit,tlv,ptr,pos); 3002 3003 TLV_CREATE(_bcmFieldInternalExtAltTtlFnSel, 3004 _bcmFieldInternalVariable, 4, &tlv); 3005 tlv->value = &ext_sel_temp->alt_ttl_fn_sel; 3006 TLV_WRITE(unit,tlv,ptr,pos); 3007 3008 TLV_CREATE(_bcmFieldInternalEndStructExtractor, 3009 _bcmFieldInternalVariable, 4, &tlv); 3010 tlv->value = &endmarker; 3011 TLV_WRITE(unit,tlv,ptr,pos); 3012 3013 } 3014 sal_free(tlv); 3015 return BCM_E_NONE; 3016 3017 } 3018 /* Function: 3019 * _field_datacontrolethertype_sync 3020 * 3021 * Purpose: 3022 * Sync _field_data_ethertype_t structure 3023 * 3024 * Paramaters: 3025 * unit - (IN) BCM device number 3026 * fd - (IN) Pointer to Field Data Control structure 3027 * 3028 * Returns: 3029 * BCM_E_XXX 3030 */ 3031 3032 int 3033 _field_datacontrolethertype_sync(int unit, _field_data_control_t *fd) 3034 { 3035 3036 _field_tlv_t *tlv = NULL; /* Tlv data structure */ 3037 uint8 *ptr = NULL; /* Scache Pointer */ 3038 _field_control_t *fc = NULL; /* Field control structure. */ 3039 uint32 *position = NULL; /* Scache Position */ 3040 int endmarker = _FIELD_WB_EM_DATAETYPE; 3041 /* End marker */ 3042 int i = 0; /* Loop variable */ 3043 int type_etype[6] = { /* types in _field_ethertype_t */ 3044 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3045 | _bcmFieldInternalDataControlEthertypeRefCount), 3046 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3047 | _bcmFieldInternalDataControlEthertypeL2), 3048 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3049 | _bcmFieldInternalDataControlEthertypeVlanTag), 3050 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3051 | _bcmFieldInternalDataControlEthertypePortEt), 3052 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3053 | _bcmFieldInternalDataControlEthertypeRelOffset), 3054 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3055 | _bcmFieldInternalDataControlEndStructEtype) 3056 }; 3057 3058 WB_FIELD_CONTROL_GET(fc, ptr, position); 3059 3060 /* In the encoded length below , first ten bits is value 6 [no of types], 3061 * next 22 bits is ethertype count. Here number of types indicate counts of 3062 * elements in the current datastructure. 3063 */ 3064 3065 TLV_CREATE(_bcmFieldInternalDataControlEthertypeStruct, 3066 _bcmFieldInternalArray, _FP_DATA_ETHERTYPE_MAX 3067 | (6 << _FP_WB_TLV_TYPE_SHIFT), &tlv); 3068 tlv->value = &(type_etype); 3069 TLV_WRITE(unit, tlv, ptr, position); 3070 3071 3072 for (i = 0; i < _FP_DATA_ETHERTYPE_MAX; i++) { 3073 3074 TLV_CREATE(_bcmFieldInternalDataControlEthertypeRefCount, 3075 _bcmFieldInternalVariable,0, &tlv); 3076 tlv->value = &(fd->etype[i].ref_count); 3077 TLV_WRITE(unit, tlv, ptr, position); 3078 3079 3080 TLV_CREATE(_bcmFieldInternalDataControlEthertypeL2, 3081 _bcmFieldInternalVariable,0, &tlv); 3082 tlv->value = &(fd->etype[i].l2); 3083 TLV_WRITE(unit, tlv, ptr, position); 3084 3085 TLV_CREATE(_bcmFieldInternalDataControlEthertypeVlanTag, 3086 _bcmFieldInternalVariable,0, &tlv); 3087 tlv->value = &(fd->etype[i].vlan_tag); 3088 TLV_WRITE(unit, tlv, ptr, position); 3089 3090 3091 3092 TLV_CREATE(_bcmFieldInternalDataControlEthertypePortEt, 3093 _bcmFieldInternalVariable,0, &tlv); 3094 tlv->value = &(fd->etype[i].ethertype); 3095 TLV_WRITE(unit, tlv, ptr, position); 3096 3097 3098 TLV_CREATE(_bcmFieldInternalDataControlEthertypeRelOffset, 3099 _bcmFieldInternalVariable,0, &tlv); 3100 tlv->value = &(fd->etype[i].relative_offset); 3101 TLV_WRITE(unit, tlv, ptr, position); 3102 3103 TLV_CREATE(_bcmFieldInternalDataControlEndStructEtype, 3104 _bcmFieldInternalVariable, 0, &tlv); 3105 tlv->value = &(endmarker); 3106 TLV_WRITE(unit, tlv, ptr, position); 3107 } 3108 3109 sal_free(tlv); 3110 3111 return BCM_E_NONE; 3112 3113 } 3114 3115 int 3116 _field_datacontrolprot_sync(int unit, _field_data_control_t *fd) 3117 { 3118 3119 _field_tlv_t *tlv = NULL; /* Tlv data structure */ 3120 uint8 *ptr = NULL; /* Scache Pointer */ 3121 _field_control_t *fc = NULL; /* Field control structure. */ 3122 uint32 *position = NULL; /* Scache Position */ 3123 int endmarker = _FIELD_WB_EM_DATAPROT; /* End marker */ 3124 int i = 0; /* Loop local variable */ 3125 int type_prot[8] = { /* types in _field_protocol_t */ 3126 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3127 | _bcmFieldInternalDataControlProtIp4RefCount), 3128 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3129 | _bcmFieldInternalDataControlProtIp6RefCount), 3130 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3131 | _bcmFieldInternalDataControlProtFlags), 3132 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3133 | _bcmFieldInternalDataControlProtIp), 3134 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3135 | _bcmFieldInternalDataControlProtL2), 3136 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3137 | _bcmFieldInternalDataControlProtVlanTag), 3138 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3139 | _bcmFieldInternalDataControlProtRelOffset), 3140 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3141 | _bcmFieldInternalDataControlEndStructProt) 3142 }; 3143 3144 WB_FIELD_CONTROL_GET(fc, ptr, position); 3145 3146 /* In the encoded length below , first ten bits is value 8 [no of types], 3147 * next 22 bits is protocol count. Here number of types indicate counts of 3148 * elements in the current datastructure. 3149 */ 3150 3151 TLV_CREATE(_bcmFieldInternalDataControlProtStart, 3152 _bcmFieldInternalArray, 3153 _FP_DATA_IP_PROTOCOL_MAX 3154 | (8 << _FP_WB_TLV_TYPE_SHIFT), &tlv); 3155 tlv->value = &(type_prot); 3156 TLV_WRITE(unit, tlv, ptr, position); 3157 3158 3159 for (i = 0; i < _FP_DATA_IP_PROTOCOL_MAX; i++) { 3160 3161 3162 TLV_CREATE(_bcmFieldInternalDataControlProtIp4RefCount, 3163 _bcmFieldInternalVariable,0, &tlv); 3164 tlv->value = &(fd->ip[i].ip4_ref_count); 3165 TLV_WRITE(unit, tlv, ptr, position); 3166 3167 3168 TLV_CREATE(_bcmFieldInternalDataControlProtIp6RefCount, 3169 _bcmFieldInternalVariable,0, &tlv); 3170 tlv->value = &(fd->ip[i].ip6_ref_count); 3171 TLV_WRITE(unit, tlv, ptr, position); 3172 3173 3174 TLV_CREATE(_bcmFieldInternalDataControlProtFlags, 3175 _bcmFieldInternalVariable,0, &tlv); 3176 tlv->value = &(fd->ip[i].flags); 3177 TLV_WRITE(unit, tlv, ptr, position); 3178 3179 3180 TLV_CREATE(_bcmFieldInternalDataControlProtIp, 3181 _bcmFieldInternalVariable,0, &tlv); 3182 tlv->value = &(fd->ip[i].ip); 3183 TLV_WRITE(unit, tlv, ptr, position); 3184 3185 3186 TLV_CREATE(_bcmFieldInternalDataControlProtL2, 3187 _bcmFieldInternalVariable,0, &tlv); 3188 tlv->value = &(fd->ip[i].l2); 3189 TLV_WRITE(unit, tlv, ptr, position); 3190 3191 3192 TLV_CREATE(_bcmFieldInternalDataControlProtVlanTag, 3193 _bcmFieldInternalVariable, 0,&tlv); 3194 tlv->value = &(fd->etype[i].vlan_tag); 3195 TLV_WRITE(unit, tlv, ptr, position); 3196 3197 3198 TLV_CREATE(_bcmFieldInternalDataControlProtRelOffset, 3199 _bcmFieldInternalVariable,0, &tlv); 3200 tlv->value = &(fd->etype[i].relative_offset); 3201 TLV_WRITE(unit, tlv, ptr, position); 3202 3203 TLV_CREATE(_bcmFieldInternalDataControlEndStructProt, 3204 _bcmFieldInternalVariable, 0, &tlv); 3205 tlv->value = &(endmarker); 3206 TLV_WRITE(unit, tlv, ptr, position); 3207 3208 } 3209 sal_free(tlv); 3210 3211 return BCM_E_NONE; 3212 3213 } 3214 3215 int 3216 _field_datacontroltcamentry_sync(int unit, _field_data_control_t *fd) 3217 { 3218 3219 _field_tlv_t *tlv = NULL; /* Tlv data structure*/ 3220 uint8 *ptr = NULL; /* Scache Pointer */ 3221 _field_control_t *fc = NULL; /* Field control structure. */ 3222 uint32 *position = NULL; /* Scache Position */ 3223 int endmarker = _FIELD_WB_EM_DATATCAM; /* End marker */ 3224 int tcam_count = 0; /* Count of TCAM */ 3225 _field_data_tcam_entry_t *tarr= NULL; /* Tcam entry pointer */ 3226 int i = 0; /* Loop local variable */ 3227 int type_tcam[3] = { /* types in _field_data_tcam_entry_t */ 3228 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3229 | _bcmFieldInternalDataControlTcamRefCount), 3230 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3231 | _bcmFieldInternalDataControlTcamPriority), 3232 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3233 | _bcmFieldInternalDataControlEndStructTcam) 3234 }; 3235 3236 WB_FIELD_CONTROL_GET(fc, ptr, position); 3237 3238 tarr = fd->tcam_entry_arr; 3239 tcam_count = soc_mem_index_count(unit, FP_UDF_TCAMm); 3240 3241 /* In the encoded length below , first ten bits is value 3 [no of types], 3242 * next 22 bits is tcam count. Here number of types indicate counts of 3243 * elements in the current datastructure. 3244 */ 3245 3246 3247 TLV_CREATE(_bcmFieldInternalDataControlTcamStruct, 3248 _bcmFieldInternalArray, tcam_count 3249 | (3 << _FP_WB_TLV_TYPE_SHIFT), 3250 &tlv); 3251 tlv->value = &(type_tcam); 3252 TLV_WRITE(unit, tlv, ptr, position); 3253 3254 3255 for (i = 0; i < tcam_count; i++) { 3256 3257 TLV_CREATE(_bcmFieldInternalDataControlTcamRefCount, 3258 _bcmFieldInternalVariable,0, &tlv); 3259 tlv->value = &(tarr[i].ref_count); 3260 TLV_WRITE(unit, tlv, ptr, position); 3261 3262 3263 TLV_CREATE(_bcmFieldInternalDataControlTcamPriority, 3264 _bcmFieldInternalVariable,0, &tlv); 3265 tlv->value = &(tarr[i].priority); 3266 TLV_WRITE(unit, tlv, ptr, position); 3267 3268 3269 TLV_CREATE(_bcmFieldInternalDataControlEndStructTcam, 3270 _bcmFieldInternalVariable, 0, &tlv); 3271 tlv->value = &(endmarker); 3272 TLV_WRITE(unit, tlv, ptr, position); 3273 3274 } 3275 3276 sal_free(tlv); 3277 3278 return BCM_E_NONE; 3279 3280 } 3281 3282 3283 /* Function: 3284 * _field_data_control_sync 3285 * 3286 * Purpose: 3287 * Sync _field_data_control_t structure 3288 * 3289 * Paramaters: 3290 * unit - (IN) BCM device number 3291 * stage_fc - (IN) Pointer to device stage structure 3292 * 3293 * Returns: 3294 * BCM_E_XXX 3295 */ 3296 3297 int 3298 _field_data_control_sync(int unit, _field_stage_t *stage_fc) 3299 { 3300 int qual_count = 0; /* Number of Qualifiers */ 3301 _field_data_qualifier_p temp = NULL; /* Field data qualifier */ 3302 _field_data_control_t *fd = NULL; /* Field data control structure */ 3303 _field_tlv_t *tlv = NULL; /* Tlv data */ 3304 uint8 *ptr = NULL; /* Scache Pointer */ 3305 _field_control_t *fc = NULL; /* Field control structure. */ 3306 uint32 *position = NULL; /* Scache Position */ 3307 int endmarker = _FIELD_WB_EM_DATACONTROL; 3308 /* End marker for data control */ 3309 3310 WB_FIELD_CONTROL_GET(fc, ptr, position); 3311 fd = stage_fc->data_ctrl; 3312 3313 TLV_CREATE(_bcmFieldInternalDataControlStart, 3314 _bcmFieldInternalVariable,0, &tlv); 3315 TLV_WRITE(unit, tlv, ptr, position); 3316 3317 3318 TLV_CREATE(_bcmFieldInternalDataControlUsageBmp, 3319 _bcmFieldInternalVariable,0, &tlv); 3320 tlv->value = &(fd->usage_bmap); 3321 TLV_WRITE(unit, tlv, ptr, position); 3322 3323 temp = fd->data_qual; 3324 while (temp != NULL) 3325 { 3326 qual_count++ ; 3327 temp=temp->next; 3328 } 3329 3330 3331 TLV_CREATE(_bcmFieldInternalDataControlDataQualStruct, 3332 _bcmFieldInternalVariable, qual_count , &tlv); 3333 TLV_WRITE(unit, tlv, ptr, position); 3334 3335 temp = fd->data_qual; 3336 while (temp != NULL) 3337 { 3338 BCM_IF_ERROR_RETURN(_field_datacontroldataqualifier_sync(unit,temp)); 3339 temp=temp->next; 3340 } 3341 BCM_IF_ERROR_RETURN(_field_datacontrolethertype_sync(unit,fd)); 3342 BCM_IF_ERROR_RETURN(_field_datacontrolprot_sync(unit,fd)); 3343 BCM_IF_ERROR_RETURN(_field_datacontroltcamentry_sync(unit,fd)); 3344 3345 TLV_CREATE(_bcmFieldInternalDataControlElemSize, 3346 _bcmFieldInternalVariable,0, &tlv); 3347 tlv->value = &(fd->elem_size); 3348 TLV_WRITE(unit, tlv, ptr, position); 3349 3350 3351 TLV_CREATE(_bcmFieldInternalDataControlNumElem, 3352 _bcmFieldInternalVariable,0, &tlv); 3353 tlv->value = &(fd->num_elems); 3354 TLV_WRITE(unit, tlv, ptr, position); 3355 3356 TLV_CREATE(_bcmFieldInternalEndStructDataControl, 3357 _bcmFieldInternalVariable, 0, &tlv); 3358 tlv->value = &(endmarker); 3359 TLV_WRITE(unit, tlv, ptr, position); 3360 3361 sal_free(tlv); 3362 3363 return BCM_E_NONE; 3364 3365 } 3366 3367 /* Function: 3368 * _field_ltinfo_sync 3369 * 3370 * Purpose: 3371 * Sync _field_lt_info_t structure 3372 * 3373 * Paramaters: 3374 * unit - (IN) BCM device number 3375 * lt_info - (IN) Pointer to device stage structure 3376 * 3377 * Returns: 3378 * BCM_E_XXX 3379 */ 3380 int 3381 _field_ltinfo_sync(int unit, _field_lt_config_t *lt_info) 3382 { 3383 _field_tlv_t *tlv = NULL; /* Tlv data */ 3384 uint8 *ptr = NULL; /* Scache Pointer */ 3385 _field_control_t *fc = NULL; /* Field control structure. */ 3386 uint32 *position = NULL; /* Scache Position */ 3387 uint32 endmarkerltconf = _FIELD_WB_EM_LTCONF; 3388 /* End Marker */ 3389 uint32 max_lt_parts = _FP_MAX_LT_PARTS(unit); /* Lt Parts */ 3390 3391 WB_FIELD_CONTROL_GET(fc, ptr, position); 3392 3393 3394 TLV_CREATE(_bcmFieldInternalLtConfigValid, 3395 _bcmFieldInternalVariable,0, &tlv); 3396 tlv->value = &(lt_info->valid); 3397 TLV_WRITE(unit, tlv, ptr, position); 3398 3399 TLV_CREATE(_bcmFieldInternalLtConfigLtId, 3400 _bcmFieldInternalVariable,0, &tlv); 3401 tlv->value = &(lt_info->lt_id); 3402 TLV_WRITE(unit, tlv, ptr, position); 3403 3404 TLV_CREATE(_bcmFieldInternalLtConfigLtPartPri, 3405 _bcmFieldInternalArray, max_lt_parts, &tlv); 3406 tlv->value = (lt_info->lt_part_pri); 3407 TLV_WRITE(unit, tlv, ptr, position); 3408 3409 TLV_CREATE(_bcmFieldInternalLtConfigLtPartMap, 3410 _bcmFieldInternalVariable,0, &tlv); 3411 tlv->value = &(lt_info->lt_part_map); 3412 TLV_WRITE(unit, tlv, ptr, position); 3413 3414 TLV_CREATE(_bcmFieldInternalLtConfigLtActionPri, 3415 _bcmFieldInternalVariable,0, &tlv); 3416 tlv->value = &(lt_info->lt_action_pri); 3417 TLV_WRITE(unit, tlv, ptr, position); 3418 3419 TLV_CREATE(_bcmFieldInternalLtConfigPri, 3420 _bcmFieldInternalVariable,0, &tlv); 3421 tlv->value = &(lt_info->priority); 3422 TLV_WRITE(unit, tlv, ptr, position); 3423 3424 TLV_CREATE(_bcmFieldInternalLtConfigFlags, 3425 _bcmFieldInternalVariable,0, &tlv); 3426 tlv->value = &(lt_info->flags); 3427 TLV_WRITE(unit, tlv, ptr, position); 3428 3429 TLV_CREATE(_bcmFieldInternalLtConfigEntry, 3430 _bcmFieldInternalVariable,0, &tlv); 3431 tlv->value = &(lt_info->lt_entry); 3432 TLV_WRITE(unit,tlv, ptr, position); 3433 3434 3435 TLV_CREATE(_bcmFieldInternalEndStructLtConfig, 3436 _bcmFieldInternalVariable,0, &tlv); 3437 tlv->value = &(endmarkerltconf); 3438 TLV_WRITE(unit, tlv, ptr, position); 3439 3440 sal_free(tlv); 3441 3442 return BCM_E_NONE; 3443 } 3444 /* Function: 3445 * _field_stage_sync 3446 * 3447 * Purpose: 3448 * Sync _field_stage_t structure 3449 * 3450 * Paramaters: 3451 * unit - (IN) BCM device number 3452 * stage_fc - (IN) Pointer to device stage structure 3453 * 3454 * Returns: 3455 * BCM_E_XXX 3456 */ 3457 3458 int 3459 _field_stage_sync(int unit, _field_stage_t *stage_fc) 3460 { 3461 _field_tlv_t *tlv = NULL; /* Tlv data */ 3462 uint8 *ptr; /* Scache Pointer */ 3463 uint32 endmarkerstage = _FIELD_WB_EM_STAGE; 3464 /* endmarker for stage */ 3465 uint32 endmarkerrange = _FIELD_WB_EM_RANGE; 3466 /* endmarker for range */ 3467 uint32 endmarkermeter = _FIELD_WB_EM_METER; 3468 /* endmarker for meter */ 3469 uint32 endmarkercntr = _FIELD_WB_EM_CNTR; 3470 #if defined BCM_TRIDENT3_SUPPORT 3471 /* endmarker for cntr */ 3472 uint32 endmarkerauxtagibus = _FIELD_WB_EM_AUXTAG_IBUS; 3473 #endif 3474 /* endmarker for auxtag */ 3475 int num_pipes = 0; /* Number of pipes */ 3476 _field_control_t *fc; /* Field control structure. */ 3477 uint32 *position; /* Scache Position */ 3478 int range_count = 0; /* Count of ranges */ 3479 _field_range_t *fr; /* field Range structure */ 3480 int type_range[7] = { /* Types for _field_range_t structure */ 3481 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3482 |_bcmFieldInternalRangeFlags), 3483 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3484 |_bcmFieldInternalRangeRid), 3485 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3486 |_bcmFieldInternalRangeMin), 3487 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3488 |_bcmFieldInternalRangeMax), 3489 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3490 |_bcmFieldInternalRangeHwIndex), 3491 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3492 |_bcmFieldInternalRangeStyle), 3493 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3494 |_bcmFieldInternalEndStructRanges) 3495 }; 3496 int type_meter[8] = { /* Types for _field_meterpool_t structure */ 3497 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3498 | _bcmFieldInternalMeterLevel), 3499 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3500 | _bcmFieldInternalMeterSliceId), 3501 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3502 | _bcmFieldInternalMeterSize), 3503 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3504 | _bcmFieldInternalMeterPoolSize), 3505 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3506 | _bcmFieldInternalMeterFreeMeters), 3507 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3508 | _bcmFieldInternalMeterNumMeterPairs), 3509 (int)((_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3510 | _bcmFieldInternalMeterBmp), 3511 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3512 | _bcmFieldInternalEndStructMeter) 3513 }; 3514 int type_cntr[5] = { /* Types for _field_cntrpool_t structure */ 3515 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3516 | _bcmFieldInternalCntrSliceId), 3517 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3518 | _bcmFieldInternalCntrSize), 3519 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3520 | _bcmFieldInternalCntrFreeCntrs), 3521 (int)((_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3522 | _bcmFieldInternalCntrBmp), 3523 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3524 | _bcmFieldInternalEndStructCntr) 3525 }; 3526 3527 int type_ltconf[9] = { /* Types for _field_ltinfo_t structure */ 3528 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3529 | _bcmFieldInternalLtConfigValid), 3530 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3531 | _bcmFieldInternalLtConfigLtId), 3532 (int)((_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3533 | _bcmFieldInternalLtConfigLtPartPri), 3534 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3535 | _bcmFieldInternalLtConfigLtPartMap), 3536 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3537 | _bcmFieldInternalLtConfigLtActionPri), 3538 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3539 | _bcmFieldInternalLtConfigPri), 3540 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3541 | _bcmFieldInternalLtConfigFlags), 3542 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3543 | _bcmFieldInternalLtConfigEntry), 3544 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3545 | _bcmFieldInternalEndStructLtConfig) 3546 }; 3547 #if defined BCM_TRIDENT3_SUPPORT 3548 int type_auxtag_ibus[3] = { /* Types for _field_auxtag_ing_fbus_cont_status_t structure */ 3549 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3550 | _bcmFieldInternalAuxTagIbusContVal), 3551 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3552 | _bcmFieldInternalAuxTagIbusRefCount), 3553 (int)((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 3554 | _bcmFieldInternalEndStructAuxTagIbus) 3555 }; 3556 #endif 3557 3558 int i = 0,j = 0; /* Local loop variable */ 3559 3560 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 3561 num_pipes = 1; 3562 } else if (stage_fc->oper_mode == bcmFieldGroupOperModePipeLocal) { 3563 num_pipes = stage_fc->num_pipes; 3564 } 3565 3566 3567 WB_FIELD_CONTROL_GET(fc, ptr, position); 3568 3569 TLV_CREATE(_bcmFieldInternalStage, 3570 _bcmFieldInternalVariable,0, &tlv); 3571 TLV_WRITE(unit, tlv, ptr, position); 3572 3573 TLV_CREATE(_bcmFieldInternalStageOperMode, 3574 _bcmFieldInternalVariable,0, &tlv); 3575 tlv->value = &(stage_fc-> oper_mode); 3576 TLV_WRITE(unit, tlv, ptr, position); 3577 3578 TLV_CREATE(_bcmFieldInternalStageStageid, 3579 _bcmFieldInternalVariable,0, &tlv); 3580 tlv->value = &(stage_fc-> stage_id); 3581 TLV_WRITE(unit, tlv, ptr, position); 3582 3583 TLV_CREATE(_bcmFieldInternalStageFlags, 3584 _bcmFieldInternalVariable,0, &tlv); 3585 tlv->value = &(stage_fc->flags); 3586 TLV_WRITE(unit, tlv, ptr, position); 3587 3588 TLV_CREATE(_bcmFieldInternalStageTcamSz, 3589 _bcmFieldInternalVariable,0, &tlv); 3590 tlv->value = &(stage_fc->tcam_sz); 3591 TLV_WRITE(unit, tlv, ptr, position); 3592 3593 TLV_CREATE(_bcmFieldInternalStageTcamSlices, 3594 _bcmFieldInternalVariable,0,&tlv); 3595 tlv->value = &(stage_fc->tcam_slices); 3596 TLV_WRITE(unit, tlv, ptr, position); 3597 3598 TLV_CREATE(_bcmFieldInternalStageNumInstances, 3599 _bcmFieldInternalVariable,0, &tlv); 3600 tlv->value = &(stage_fc->num_instances); 3601 TLV_WRITE(unit, tlv, ptr, position); 3602 3603 TLV_CREATE(_bcmFieldInternalStageNumPipes, 3604 _bcmFieldInternalVariable,0, &tlv); 3605 tlv->value = &(stage_fc->num_pipes); 3606 TLV_WRITE(unit, tlv, ptr, position); 3607 3608 TLV_CREATE(_bcmFieldInternalStageRangeId, 3609 _bcmFieldInternalVariable,0,&tlv); 3610 tlv->value = &(stage_fc->range_id); 3611 TLV_WRITE(unit, tlv, ptr, position); 3612 3613 TLV_CREATE(_bcmFieldInternalStageNumMeterPools, 3614 _bcmFieldInternalVariable,0, &tlv); 3615 tlv->value = &(stage_fc->num_meter_pools); 3616 TLV_WRITE(unit, tlv, ptr, position); 3617 3618 TLV_CREATE(_bcmFieldInternalStageNumCntrPools, 3619 _bcmFieldInternalVariable,0,&tlv); 3620 tlv->value = &(stage_fc->num_cntr_pools); 3621 TLV_WRITE(unit, tlv, ptr, position); 3622 3623 TLV_CREATE(_bcmFieldInternalStageLtTcamSz, 3624 _bcmFieldInternalVariable,0, &tlv); 3625 tlv->value = &(stage_fc-> lt_tcam_sz); 3626 TLV_WRITE(unit, tlv, ptr, position); 3627 3628 TLV_CREATE(_bcmFieldInternalStageNumLogicalTables, 3629 _bcmFieldInternalVariable,0, &tlv); 3630 tlv->value = &(stage_fc-> num_logical_tables); 3631 TLV_WRITE(unit, tlv, ptr, position); 3632 3633 TLV_CREATE(_bcmFieldInternalStageExtLevels, 3634 _bcmFieldInternalVariable,0, &tlv); 3635 tlv->value = &(stage_fc-> num_ext_levels); 3636 TLV_WRITE(unit, tlv, ptr, position); 3637 3638 TLV_CREATE(_bcmFieldInternalStageLtActionPri, 3639 _bcmFieldInternalVariable,0, &tlv); 3640 tlv->value = &(stage_fc-> lt_action_pri); 3641 TLV_WRITE(unit, tlv, ptr, position); 3642 3643 TLV_CREATE(_bcmFieldInternalStagePreselQset, _bcmFieldInternalArray, 3644 _SHR_BITDCLSIZE(BCM_FIELD_QUALIFY_MAX), &tlv); 3645 tlv->value = &(stage_fc->presel_qset.w); 3646 TLV_WRITE(unit, tlv, ptr, position); 3647 3648 TLV_CREATE(_bcmFieldInternalStageGrpRunningPrio, 3649 _bcmFieldInternalVariable,0, &tlv); 3650 tlv->value = &(stage_fc->group_running_prio); 3651 TLV_WRITE(unit, tlv, ptr, position); 3652 3653 /* _field_range_t */ 3654 fr = stage_fc->ranges; 3655 while (fr != NULL) { 3656 range_count ++; 3657 fr = fr ->next; 3658 } 3659 3660 /* In the encoded length below , first ten bits is value 7 [no of types], 3661 * next 22 bits is range count. Here number of types indicate counts of 3662 * elements in the current datastructure. 3663 */ 3664 3665 3666 TLV_CREATE(_bcmFieldInternalStageRanges, 3667 _bcmFieldInternalVariable,range_count 3668 | (7 << _FP_WB_TLV_TYPE_SHIFT), &tlv); 3669 tlv->value = &(type_range); 3670 TLV_WRITE(unit, tlv, ptr, position); 3671 3672 fr = stage_fc->ranges; 3673 while (fr != NULL) { 3674 3675 TLV_CREATE(_bcmFieldInternalRangeFlags, 3676 _bcmFieldInternalVariable,0, &tlv); 3677 tlv->value = &(fr->flags); 3678 TLV_WRITE(unit, tlv, ptr, position); 3679 3680 TLV_CREATE(_bcmFieldInternalRangeRid, 3681 _bcmFieldInternalVariable,0, &tlv); 3682 tlv->value = &(fr->rid); 3683 TLV_WRITE(unit, tlv, ptr, position); 3684 3685 TLV_CREATE(_bcmFieldInternalRangeMin, 3686 _bcmFieldInternalVariable,0, &tlv); 3687 tlv->value = &(fr->min); 3688 TLV_WRITE(unit, tlv, ptr, position); 3689 3690 TLV_CREATE(_bcmFieldInternalRangeMax, 3691 _bcmFieldInternalVariable,0, &tlv); 3692 tlv->value = &(fr->max); 3693 TLV_WRITE(unit, tlv, ptr, position); 3694 3695 TLV_CREATE(_bcmFieldInternalRangeHwIndex, 3696 _bcmFieldInternalVariable,0, &tlv); 3697 tlv->value = &(fr->hw_index); 3698 TLV_WRITE(unit, tlv, ptr, position); 3699 3700 TLV_CREATE(_bcmFieldInternalRangeStyle, 3701 _bcmFieldInternalVariable,0, &tlv); 3702 tlv->value = &(fr->style); 3703 TLV_WRITE(unit, tlv, ptr, position); 3704 3705 TLV_CREATE(_bcmFieldInternalEndStructRanges, 3706 _bcmFieldInternalVariable, 0, &tlv); 3707 tlv->value = &(endmarkerrange); 3708 TLV_WRITE(unit, tlv, ptr, position); 3709 3710 fr = fr ->next; 3711 } 3712 3713 /* _field_meter_pool_t */ 3714 3715 /* In the encoded length below , first ten bits is value 8 [no of types], 3716 * next 12 bits is num_meter_pools and next 10 bits is num_pipes.Here number 3717 * of types indicate counts of elements in the current datastructure. 3718 */ 3719 3720 TLV_CREATE(_bcmFieldInternalStageMeterPool, _bcmFieldInternalVariable, 3721 ((num_pipes) | (stage_fc->num_meter_pools << 10) 3722 | (8 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 3723 tlv->value = &(type_meter); 3724 TLV_WRITE(unit, tlv, ptr, position); 3725 3726 for (i = 0; i < num_pipes; i++) { 3727 if (!(fc->pipe_map & (1 << i))) { 3728 continue; 3729 } 3730 for (j = 0; j < stage_fc->num_meter_pools; j++) { 3731 3732 TLV_CREATE(_bcmFieldInternalMeterLevel, 3733 _bcmFieldInternalVariable,0, &tlv); 3734 tlv->value = &(stage_fc->meter_pool[i][j]->level); 3735 TLV_WRITE(unit, tlv, ptr, position); 3736 3737 TLV_CREATE(_bcmFieldInternalMeterSliceId, 3738 _bcmFieldInternalVariable,0, &tlv); 3739 tlv->value = &(stage_fc->meter_pool[i][j]->slice_id); 3740 TLV_WRITE(unit, tlv, ptr, position); 3741 3742 TLV_CREATE(_bcmFieldInternalMeterSize, 3743 _bcmFieldInternalVariable,0, &tlv); 3744 tlv->value = &(stage_fc->meter_pool[i][j]->size); 3745 TLV_WRITE(unit, tlv, ptr, position); 3746 3747 TLV_CREATE(_bcmFieldInternalMeterPoolSize, 3748 _bcmFieldInternalVariable,0, &tlv); 3749 tlv->value = &( stage_fc->meter_pool[i][j]->pool_size); 3750 TLV_WRITE(unit, tlv, ptr, position); 3751 3752 TLV_CREATE(_bcmFieldInternalMeterFreeMeters, 3753 _bcmFieldInternalVariable,0, &tlv); 3754 tlv->value = &(stage_fc->meter_pool[i][j]->free_meters); 3755 TLV_WRITE(unit, tlv, ptr, position); 3756 3757 TLV_CREATE(_bcmFieldInternalMeterNumMeterPairs, 3758 _bcmFieldInternalVariable,0, &tlv); 3759 tlv->value = &(stage_fc->meter_pool[i][j]->num_meter_pairs); 3760 TLV_WRITE(unit, tlv, ptr, position); 3761 3762 TLV_CREATE(_bcmFieldInternalMeterBmp, _bcmFieldInternalArray, 3763 _SHR_BITDCLSIZE(stage_fc->meter_pool[i][j]->size), &tlv); 3764 tlv->value = (stage_fc->meter_pool[i][j]->meter_bmp.w); 3765 TLV_WRITE(unit, tlv, ptr, position); 3766 3767 TLV_CREATE(_bcmFieldInternalEndStructMeter, 3768 _bcmFieldInternalVariable, 0, &tlv); 3769 tlv->value = &(endmarkermeter); 3770 TLV_WRITE(unit, tlv, ptr, position); 3771 3772 } 3773 } 3774 3775 /* _field_cntr_pool_t */ 3776 3777 /* In the encoded length below , first ten bits is value 5 [no of types], 3778 * next 22 bits is num_cntr_pools. Here number of types indicate counts of 3779 * elements in the current datastructure. 3780 */ 3781 3782 TLV_CREATE(_bcmFieldInternalStageCntrPools, 3783 _bcmFieldInternalVariable, 3784 (stage_fc->num_cntr_pools 3785 | (5 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 3786 tlv->value = &(type_cntr); 3787 TLV_WRITE(unit, tlv, ptr, position); 3788 3789 for (i = 0; i < stage_fc->num_cntr_pools;i++) { 3790 3791 TLV_CREATE(_bcmFieldInternalCntrSliceId, 3792 _bcmFieldInternalVariable,0, &tlv); 3793 tlv->value = &(stage_fc->cntr_pool[i]->slice_id); 3794 TLV_WRITE(unit, tlv, ptr, position); 3795 3796 TLV_CREATE(_bcmFieldInternalCntrSize, 3797 _bcmFieldInternalVariable,0, &tlv); 3798 tlv->value = &(stage_fc->cntr_pool[i]->size); 3799 TLV_WRITE(unit, tlv, ptr, position); 3800 3801 TLV_CREATE(_bcmFieldInternalCntrFreeCntrs, 3802 _bcmFieldInternalVariable,0, &tlv); 3803 tlv->value = &(stage_fc->cntr_pool[i]->free_cntrs); 3804 TLV_WRITE(unit, tlv, ptr, position); 3805 3806 TLV_CREATE(_bcmFieldInternalCntrBmp,_bcmFieldInternalArray, 3807 _SHR_BITDCLSIZE(stage_fc->cntr_pool[i]->size), 3808 &tlv); 3809 tlv->value = (stage_fc->cntr_pool[i]->cntr_bmp.w); 3810 TLV_WRITE(unit, tlv, ptr, position); 3811 3812 TLV_CREATE(_bcmFieldInternalEndStructCntr, 3813 _bcmFieldInternalVariable, 0, &tlv); 3814 tlv->value = &(endmarkercntr); 3815 TLV_WRITE(unit, tlv, ptr, position); 3816 } 3817 3818 /* _field_lt_info_t */ 3819 /* In the encoded length below , first ten bits is value 9 [no of types], 3820 * next 12 bits is no of logical tables and next 10 bits is num_pipes. 3821 * Here number of types indicate counts of elements 3822 * in the current datastructure. 3823 */ 3824 3825 TLV_CREATE(_bcmFieldInternalStageLtInfo, 3826 _bcmFieldInternalVariable, 3827 ((num_pipes) | (_FP_MAX_NUM_LT << 10) 3828 | (9 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 3829 tlv->value = &(type_ltconf); 3830 TLV_WRITE(unit, tlv, ptr, position); 3831 3832 for (i = 0; i < num_pipes;i++) { 3833 if (!(fc->pipe_map & (1 << i))) { 3834 continue; 3835 } 3836 for (j = 0; j < _FP_MAX_NUM_LT;j++) { 3837 _field_ltinfo_sync(unit, fc->lt_info[i][j]); 3838 } 3839 } 3840 3841 /* data_control_t sync */ 3842 if(!soc_feature(unit, soc_feature_td3_style_fp)) { 3843 BCM_IF_ERROR_RETURN(_field_data_control_sync(unit, stage_fc)); 3844 } 3845 3846 #if defined BCM_TRIDENT3_SUPPORT 3847 if(soc_feature(unit, soc_feature_td3_style_fp)) { 3848 /* _field_auxtag_ing_fbus_cont_status_t */ 3849 3850 /* In the encoded length below , first ten bits is value 8 [no of types], 3851 * next 12 bits is for num Aux tags and next 10 bits is num_pipes.Here number 3852 * of types indicate counts of elements in the current datastructure. 3853 */ 3854 3855 TLV_CREATE(_bcmFieldInternalStageAuxTagIBusContStatus, _bcmFieldInternalVariable, 3856 ((num_pipes) | (_FP_MAX_IBUS_CONTS << 10) 3857 | (8 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 3858 tlv->value = &(type_auxtag_ibus); 3859 TLV_WRITE(unit, tlv, ptr, position); 3860 3861 for (i = 0; i < num_pipes; i++) { 3862 if (!(fc->pipe_map & (1 << i))) { 3863 continue; 3864 } 3865 for (j = 0; j < _FP_MAX_IBUS_CONTS; j++) { 3866 TLV_CREATE(_bcmFieldInternalAuxTagIbusContVal, 3867 _bcmFieldInternalVariable,0, &tlv); 3868 tlv->value = &(stage_fc->ifbus_cont_stat[i][j].cont_val); 3869 TLV_WRITE(unit, tlv, ptr, position); 3870 3871 TLV_CREATE(_bcmFieldInternalAuxTagIbusRefCount, 3872 _bcmFieldInternalVariable,0, &tlv); 3873 tlv->value = &(stage_fc->ifbus_cont_stat[i][j].ref_count); 3874 TLV_WRITE(unit, tlv, ptr, position); 3875 3876 TLV_CREATE(_bcmFieldInternalEndStructAuxTagIbus, 3877 _bcmFieldInternalVariable, 0, &tlv); 3878 tlv->value = &(endmarkerauxtagibus); 3879 TLV_WRITE(unit, tlv, ptr, position); 3880 } 3881 } 3882 } 3883 #endif 3884 TLV_CREATE(_bcmFieldInternalEndStructStage, 3885 _bcmFieldInternalVariable, 0, &tlv); 3886 tlv->value = &endmarkerstage; 3887 TLV_WRITE(unit, tlv, ptr, position); 3888 3889 sal_free(tlv); 3890 3891 return BCM_E_NONE; 3892 } 3893 3894 3895 /* Function: 3896 * _field_slice_sync 3897 * 3898 * Purpose: 3899 * Sync _field_slice_t structure 3900 * 3901 * Paramaters: 3902 * unit - (IN) BCM device number 3903 * slice - (IN) Pointer to device slice structure 3904 * 3905 * Returns: 3906 * BCM_E_XXX 3907 */ 3908 3909 int 3910 _field_slice_sync(int unit, _field_slice_t *slice) 3911 { 3912 _field_tlv_t *tlv = NULL; /* Tlv structure */ 3913 _field_control_t *fc = NULL; /* Field control structure */ 3914 uint8 *ptr; /* Pointer to scache_pos */ 3915 uint32 *position; /* Scache position */ 3916 uint8 slice_flags8 = 0; /* LSB 8-bit slice flags */ 3917 uint32 slice_flags24 = 0; /* MSB 24-bit slice flags */ 3918 uint32 endmarker = _FIELD_WB_EM_SLICE; 3919 /* End marker */ 3920 WB_FIELD_CONTROL_GET(fc, ptr, position); 3921 3922 3923 TLV_CREATE(_bcmFieldInternalSliceNumber, 3924 _bcmFieldInternalVariable, 0, &tlv); 3925 tlv->value = &(slice->slice_number); 3926 TLV_WRITE(unit, tlv, ptr, position); 3927 3928 TLV_CREATE(_bcmFieldInternalSliceStartTcamIdx, 3929 _bcmFieldInternalVariable, 0, &tlv); 3930 tlv->value = &(slice->start_tcam_idx); 3931 TLV_WRITE(unit, tlv, ptr, position); 3932 3933 TLV_CREATE(_bcmFieldInternalSliceEntryCount, 3934 _bcmFieldInternalVariable, 0, &tlv); 3935 tlv->value = &(slice->entry_count); 3936 TLV_WRITE(unit, tlv, ptr, position); 3937 3938 TLV_CREATE(_bcmFieldInternalSliceFreeCount, 3939 _bcmFieldInternalVariable, 0, &tlv); 3940 tlv->value = &(slice->free_count); 3941 TLV_WRITE(unit, tlv, ptr, position); 3942 3943 TLV_CREATE(_bcmFieldInternalSliceCountersCount, 3944 _bcmFieldInternalVariable, 0, &tlv); 3945 tlv->value = &(slice->counters_count); 3946 TLV_WRITE(unit, tlv, ptr, position); 3947 3948 TLV_CREATE(_bcmFieldInternalSliceMetersCount, 3949 _bcmFieldInternalVariable, 0, &tlv); 3950 tlv->value = &(slice->meters_count); 3951 TLV_WRITE(unit, tlv, ptr, position); 3952 3953 TLV_CREATE(_bcmFieldInternalSliceInstalledEntriesCount, 3954 _bcmFieldInternalVariable, 0, &tlv); 3955 tlv->value = &(slice->hw_ent_count); 3956 TLV_WRITE(unit, tlv, ptr, position); 3957 3958 /* IFP uses global meter pools and counter pools, so no need to 3959 * save below fields 3960 * 3961 * TLV_CREATE(_bcmFieldInternalSliceCounterBmp, 3962 * _bcmFieldInternalVariable, 0, &tlv); 3963 *tlv->value = &(slice->counter_bmp); 3964 *TLV_WRITE(unit, tlv, ptr, position); 3965 3966 *TLV_CREATE(_bcmFieldInternalSliceMeterBmp, 3967 * _bcmFieldInternalVariable, 0, &tlv); 3968 *tlv->value = &(slice->meter_bmp); 3969 *TLV_WRITE(unit, tlv, ptr, position); 3970 */ 3971 TLV_CREATE(_bcmFieldInternalSliceStageId, 3972 _bcmFieldInternalVariable, 0, &tlv); 3973 tlv->value = &(slice->stage_id); 3974 TLV_WRITE(unit, tlv, ptr, position); 3975 3976 TLV_CREATE(_bcmFieldInternalSlicePortPbmp, 3977 _bcmFieldInternalArray, 32, &tlv); 3978 tlv->value = &(slice->pbmp); 3979 TLV_WRITE(unit, tlv, ptr, position); 3980 3981 if (slice->next != NULL) { 3982 TLV_CREATE(_bcmFieldInternalSliceNextSlice, 3983 _bcmFieldInternalVariable, 0, &tlv); 3984 tlv->value = &(slice->next->slice_number); 3985 TLV_WRITE(unit, tlv, ptr, position); 3986 } 3987 if (slice->prev != NULL) { 3988 TLV_CREATE(_bcmFieldInternalSlicePrevSlice, 3989 _bcmFieldInternalVariable, 0, &tlv); 3990 tlv->value = &(slice->prev->slice_number); 3991 TLV_WRITE(unit, tlv, ptr, position); 3992 } 3993 3994 TLV_CREATE(_bcmFieldInternalSliceGroupFlags, 3995 _bcmFieldInternalVariable, 0, &tlv); 3996 tlv->value = &(slice->group_flags); 3997 TLV_WRITE(unit, tlv, ptr, position); 3998 3999 TLV_CREATE(_bcmFieldInternalSliceFlags, 4000 _bcmFieldInternalVariable, 0, &tlv); 4001 slice_flags8 = slice->slice_flags & 0xFF; 4002 tlv->value = &(slice_flags8); 4003 TLV_WRITE(unit, tlv, ptr, position); 4004 4005 TLV_CREATE(_bcmFieldInternalSliceFlagsMsb24, 4006 _bcmFieldInternalVariable, 0, &tlv); 4007 slice_flags24 = (slice->slice_flags >> 8) & 0xFFFFFF; 4008 tlv->value = &(slice_flags24); 4009 TLV_WRITE(unit, tlv, ptr, position); 4010 4011 TLV_CREATE(_bcmFieldInternalSliceLtMap, 4012 _bcmFieldInternalVariable, 0, &tlv); 4013 tlv->value = &(slice->lt_map); 4014 TLV_WRITE(unit, tlv, ptr, position); 4015 4016 TLV_CREATE(_bcmFieldInternalSliceLtPartitionPri, 4017 _bcmFieldInternalVariable, 0, &tlv); 4018 tlv->value = &(slice->lt_partition_pri); 4019 TLV_WRITE(unit, tlv, ptr, position); 4020 4021 BCM_IF_ERROR_RETURN(_field_extractor_sync(unit, slice->ext_sel, 4022 _FP_MAX_NUM_LT)); 4023 4024 TLV_CREATE(_bcmFieldInternalEndStructSlice, 4025 _bcmFieldInternalVariable, 0, &tlv); 4026 tlv->value = &endmarker; 4027 TLV_WRITE(unit, tlv, ptr, position); 4028 4029 sal_free(tlv); 4030 return BCM_E_NONE; 4031 } 4032 4033 4034 /* Function: 4035 * _field_lt_slice_sync 4036 * 4037 * Purpose: 4038 * Sync _field_lt_slice_t structure 4039 * 4040 * Paramaters: 4041 * unit - (IN) BCM device number 4042 * lt_slice - (IN) Pointer to device lt_slice structure 4043 * 4044 * Returns: 4045 * BCM_E_XXX 4046 */ 4047 4048 int 4049 _field_lt_slice_sync(int unit, _field_lt_slice_t *lt_slice) 4050 { 4051 4052 _field_tlv_t *tlv = NULL; /* Tlv structure */ 4053 _field_control_t *fc = NULL; /* field control structure */ 4054 uint8 *ptr; /* pointer to scache_pos */ 4055 uint32 *position; /* Scache position */ 4056 uint32 endmarker = _FIELD_WB_EM_LTSLICE; 4057 /* End marker */ 4058 4059 WB_FIELD_CONTROL_GET(fc, ptr, position); 4060 4061 TLV_CREATE(_bcmFieldInternalLtSliceSliceNum, 4062 _bcmFieldInternalVariable, 0, &tlv); 4063 tlv->value = &(lt_slice->slice_number); 4064 TLV_WRITE(unit, tlv, ptr, position); 4065 4066 TLV_CREATE(_bcmFieldInternalLtSliceStartTcamIdx, 4067 _bcmFieldInternalVariable, 0, &tlv); 4068 tlv->value = &(lt_slice->start_tcam_idx); 4069 TLV_WRITE(unit, tlv, ptr, position); 4070 4071 TLV_CREATE(_bcmFieldInternalLtSliceEntryCount, 4072 _bcmFieldInternalVariable, 0, &tlv); 4073 tlv->value = &(lt_slice->entry_count); 4074 TLV_WRITE(unit, tlv, ptr, position); 4075 4076 TLV_CREATE(_bcmFieldInternalLtSliceFreeCount, 4077 _bcmFieldInternalVariable, 0, &tlv); 4078 tlv->value = &(lt_slice->free_count); 4079 TLV_WRITE(unit, tlv, ptr, position); 4080 4081 TLV_CREATE(_bcmFieldInternalLtSliceStageid, 4082 _bcmFieldInternalVariable, 0, &tlv); 4083 tlv->value = &(lt_slice->stage_id); 4084 TLV_WRITE(unit, tlv, ptr, position); 4085 4086 if (lt_slice->next != NULL) { 4087 TLV_CREATE(_bcmFieldInternalLtSliceNextSlice, 4088 _bcmFieldInternalVariable, 0, &tlv); 4089 tlv->value = &(lt_slice->next->slice_number); 4090 TLV_WRITE(unit, tlv, ptr, position); 4091 } 4092 if (lt_slice->prev != NULL) { 4093 TLV_CREATE(_bcmFieldInternalLtSlicePrevSlice, 4094 _bcmFieldInternalVariable, 0, &tlv); 4095 tlv->value = &(lt_slice->prev->slice_number); 4096 TLV_WRITE(unit, tlv, ptr, position); 4097 } 4098 4099 TLV_CREATE(_bcmFieldInternalLtSliceFlags, 4100 _bcmFieldInternalVariable, 0, &tlv); 4101 tlv->value = &(lt_slice->slice_flags); 4102 TLV_WRITE(unit, tlv, ptr, position); 4103 4104 TLV_CREATE(_bcmFieldInternalLtSliceGroupFlags, 4105 _bcmFieldInternalVariable, 0, &tlv); 4106 tlv->value = &(lt_slice->group_flags); 4107 TLV_WRITE(unit, tlv, ptr, position); 4108 4109 TLV_CREATE(_bcmFieldInternalEndStructSlice, 4110 _bcmFieldInternalVariable, 0, &tlv); 4111 tlv->value = &endmarker; 4112 TLV_WRITE(unit, tlv, ptr, position); 4113 4114 sal_free(tlv); 4115 return BCM_E_NONE; 4116 4117 } 4118 4119 int 4120 _field_em_actions_sync(int unit, _field_group_t *fg) 4121 { 4122 _field_tlv_t *tlv = NULL; /* pointer to tlv structure */ 4123 _bcm_field_internal_element_t wb_act_elem = _bcmFieldInternalElementCount; 4124 bcm_error_t rv = BCM_E_NONE; /* Error handle */ 4125 _field_entry_t *f_ent = NULL; /* pointers to entry structures */ 4126 _field_action_t *f_act = NULL; /* pointers to action structures */ 4127 uint8 *ptr = NULL; /* pointer to scache_ptr */ 4128 uint32 *pos = NULL; /* pointer to scache_pos */ 4129 _field_control_t *fc = NULL; /* pointer to field control struc */ 4130 _field_stage_t *stage_fc = NULL; /* pointer to stage structure */ 4131 int count = 0; 4132 int entry = 0; 4133 int size = 0; 4134 int ent_count = 0, hw_index = 0; /* entry count, hw index */ 4135 exact_match_2_entry_t ebuf_nar; /* Narrow Entry Buffer. */ 4136 exact_match_4_entry_t ebuf_wide; /* Wide Entry Buffer. */ 4137 soc_mem_t mem = INVALIDm; /* Memory Identifier. */ 4138 uint32 tbuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 4139 /* Temp Buffer One. */ 4140 uint32 *bufp = NULL; /* Hardware Buffer Ptr. */ 4141 _field_wb_em_act_ent_bmp_t *f_ent_bmp = NULL; 4142 4143 WB_FIELD_CONTROL_GET(fc, ptr, pos); 4144 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 4145 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 4146 4147 _FP_XGS3_ALLOC(f_ent_bmp, 4148 sizeof(_field_wb_em_act_ent_bmp_t) * _FP_EM_NUM_WB_SUPPORTED_ACTIONS, 4149 "WB EM act Entry struct"); 4150 if (NULL == f_ent_bmp) { 4151 return BCM_E_MEMORY; 4152 } 4153 4154 /* Set to invalid action */ 4155 for (count = 0; count < _FP_EM_NUM_WB_SUPPORTED_ACTIONS; count++) { 4156 f_ent_bmp[count].action = bcmFieldActionCount; 4157 f_ent_bmp[count].ent_bmp.w = NULL; 4158 } 4159 4160 for(; (NULL != fg); fg = fg->next) { 4161 if (_BCM_FIELD_STAGE_EXACTMATCH != fg->stage_id) { 4162 continue; 4163 } 4164 4165 ent_count = fg->group_status.entry_count; 4166 if ((fg->em_mode == _FieldExactMatchMode128) || 4167 (fg->em_mode == _FieldExactMatchMode160)) { 4168 bufp = (uint32 *)&ebuf_nar; 4169 sal_memset(bufp, 0, sizeof(exact_match_2_entry_t)); 4170 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4171 mem = EXACT_MATCH_2m; 4172 } else { 4173 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 4174 EXACT_MATCH_2m, 4175 fg->instance, &mem)); 4176 } 4177 } else { 4178 bufp = (uint32 *)&ebuf_wide; 4179 sal_memset(bufp, 0, sizeof(exact_match_4_entry_t)); 4180 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4181 mem = EXACT_MATCH_4m; 4182 } else { 4183 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 4184 EXACT_MATCH_4m, 4185 fg->instance, &mem)); 4186 } 4187 } 4188 4189 for (entry = 0 ; entry < ent_count; entry++) { 4190 f_ent = fg->entry_arr[entry]; 4191 if ((f_ent->flags & _FP_ENTRY_DIRTY) 4192 || (0 == (f_ent->flags & _FP_ENTRY_INSTALLED))) { 4193 continue; 4194 } 4195 4196 for (f_act = f_ent->actions; NULL != f_act; f_act= f_act->next) { 4197 if (0 == _FP_IS_EM_WB_ACTION(f_act->action)) { 4198 continue; 4199 } 4200 if ((bcmFieldActionEgressFlowControlEnable == f_act->action) 4201 && (bcmFieldEgressFlowControlAppendIncomingOuterVlan != f_act->param[0])) { 4202 continue; 4203 } 4204 /* Construct Action and entry bimap to sync */ 4205 for (count = 0; 4206 count < _FP_EM_NUM_WB_SUPPORTED_ACTIONS; 4207 count++) { 4208 /* Is the action already present or need to alloc new pbm */ 4209 if ((f_act->action != f_ent_bmp[count].action) 4210 && (bcmFieldActionCount != f_ent_bmp[count].action)) { 4211 continue; 4212 } 4213 if (bcmFieldActionCount == f_ent_bmp[count].action) { 4214 _FP_XGS3_ALLOC(f_ent_bmp[count].ent_bmp.w, 4215 SHR_BITALLOCSIZE(stage_fc->tcam_sz + 16), 4216 "EM entry BMP"); 4217 if (NULL == f_ent_bmp[count].ent_bmp.w) { 4218 rv = BCM_E_MEMORY; 4219 BCM_IF_ERROR_CLEANUP(rv); 4220 } 4221 } 4222 f_ent_bmp[count].action = f_act->action; 4223 sal_memset(&ebuf_nar, 0x0, sizeof(exact_match_2_entry_t)); 4224 sal_memset(&ebuf_wide, 0x0, sizeof(exact_match_4_entry_t)); 4225 rv = _field_td3_em_entry_set(unit, f_ent, mem, bufp, 1); 4226 BCM_IF_ERROR_CLEANUP(rv); 4227 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &hw_index, 4228 bufp, tbuf, 0 ); 4229 BCM_IF_ERROR_CLEANUP(rv); 4230 /* Create Entry tcam idx bitmap */ 4231 _FP_ACTION_BMP_ADD(f_ent_bmp[count].ent_bmp, hw_index); 4232 if (stage_fc->oper_mode == bcmFieldGroupOperModePipeLocal) { 4233 /* Add pipe instance to the bitmap */ 4234 _FP_ACTION_BMP_ADD(f_ent_bmp[count].ent_bmp, stage_fc->tcam_sz + fg->instance); 4235 } 4236 break; 4237 } 4238 } 4239 } 4240 } 4241 4242 for (count = 0; 4243 (count < _FP_EM_NUM_WB_SUPPORTED_ACTIONS) \ 4244 && (bcmFieldActionCount != f_ent_bmp[count].action); 4245 count++) { 4246 switch (f_ent_bmp[count].action) { 4247 case bcmFieldActionGbpSrcIdNew: 4248 wb_act_elem = _bcmFieldInternalEMActionPbmGbpSrcIdNew; 4249 break; 4250 case bcmFieldActionGbpDstIdNew: 4251 wb_act_elem = _bcmFieldInternalEMActionPbmGbpDstIdNew; 4252 break; 4253 case bcmFieldActionAssignOpaqueObject1: 4254 wb_act_elem = _bcmFieldInternalEMActionPbmOpaqueObject1; 4255 break; 4256 case bcmFieldActionAssignOpaqueObject2: 4257 wb_act_elem = _bcmFieldInternalEMActionPbmOpaqueObject2; 4258 break; 4259 case bcmFieldActionAssignOpaqueObject3: 4260 wb_act_elem = _bcmFieldInternalEMActionPbmOpaqueObject3; 4261 break; 4262 case bcmFieldActionEgressFlowControlEnable: 4263 wb_act_elem = _bcmFieldInternalEMActionPbmEgressFlowControlEnable; 4264 break; 4265 case bcmFieldActionAssignNatClassId: 4266 wb_act_elem = _bcmFieldInternalEMActionPbmAssignNatClassId; 4267 break; 4268 case bcmFieldActionAssignChangeL2FieldsClassId: 4269 wb_act_elem = _bcmFieldInternalEMActionPbmAssignChangeL2FieldsClassId; 4270 break; 4271 default: 4272 rv = BCM_E_INTERNAL; 4273 BCM_IF_ERROR_CLEANUP(rv); 4274 } 4275 /* bitmap for maximum possible number of entries of EM and pipe pbm(16 bits) */ 4276 size = SHR_BITALLOCSIZE(stage_fc->tcam_sz + 16); 4277 size = (size-1)/static_type_map[wb_act_elem].size + 1; 4278 TLV_CREATE_IF_ERR_CLEANUP(wb_act_elem, _bcmFieldInternalArray, 4279 size, &tlv); 4280 tlv->value = f_ent_bmp[count].ent_bmp.w; 4281 TLV_WRITE_IF_ERR_CLEANUP(unit, tlv, ptr, pos); 4282 } 4283 4284 cleanup: 4285 for (count = 0; 4286 count < _FP_EM_NUM_WB_SUPPORTED_ACTIONS; 4287 count++) { 4288 if (NULL != f_ent_bmp[count].ent_bmp.w) { 4289 _FP_ACTION_BMP_FREE(f_ent_bmp[count].ent_bmp); 4290 f_ent_bmp[count].ent_bmp.w = NULL; 4291 f_ent_bmp[count].action = bcmFieldActionCount; 4292 } 4293 } 4294 4295 if (NULL != f_ent_bmp) { 4296 sal_free(f_ent_bmp); 4297 } 4298 4299 return rv; 4300 } 4301 4302 /* Function: 4303 * _field_actions_sync 4304 * 4305 * Purpose: 4306 * Sync _field_action_t structure 4307 * Mirror actions need special treatment as they are the only actions which 4308 * can be added multiple times. 4309 * 4310 * Paramaters: 4311 * unit - (IN) BCM device number 4312 * _field_control_t - (IN) _field_control_t structure pointer 4313 * _field_action_t - (IN) Pointer to action structure 4314 * 4315 * Returns: 4316 * BCM_E_XXX 4317 */ 4318 int 4319 _field_actions_sync(int unit, _field_action_t *act) 4320 { 4321 4322 _field_tlv_t *tlv = NULL; /* pointer to tlv structure */ 4323 _field_control_t *fc = NULL; /* Pointer to field control structure*/ 4324 uint8 *ptr; /* Pointer to scache_pos (offset) in 4325 * field control structure 4326 */ 4327 uint32 *position; /* Scache position */ 4328 _field_action_bmp_t action_bmp; /* bit map of actions used for entry*/ 4329 _field_action_t *f_act = NULL; /* pointer to action structure */ 4330 int size, param_id, action_id, mirror_id; 4331 /* loop variables */ 4332 int hw_count = 0, count = 0,count1 = 0; 4333 /* count of params and hw index */ 4334 int val_array[100] = { -1 }; /* Array to hold values of 4335 * params for some actions.Count is 100 4336 * since we cannot predict what 4337 * type of actions will be added 4338 */ 4339 int val_array1[100] = { -1 }; /* Array to hold values of 4340 * params for some actions.Count is 100 4341 * since we cannot predict what 4342 * type of actions will be added 4343 */ 4344 4345 int hw_idx_array[100] = { -1 }; /* Array to hold hw_index in actions */ 4346 int mirror_params_array[(BCM_MIRROR_MTP_COUNT * 2)] = { -1 }; 4347 /* params of mirror actions */ 4348 int mirror_hw_idx_array[BCM_MIRROR_MTP_COUNT] = { -1 }; 4349 /* hw_index for mirror actions */ 4350 _field_action_t *fa = NULL; /* Pointer to actions structure */ 4351 4352 f_act = act; 4353 WB_FIELD_CONTROL_GET(fc, ptr, position); 4354 action_bmp.w = NULL; 4355 _FP_XGS3_ALLOC(action_bmp.w, SHR_BITALLOCSIZE(bcmFieldActionCount), 4356 "Action BMP"); 4357 if (action_bmp.w == NULL) { 4358 return BCM_E_MEMORY; 4359 } 4360 4361 while (act != NULL) { 4362 _FP_ACTION_BMP_ADD(action_bmp, act->action); 4363 act = act->next; 4364 } 4365 for (action_id = 0; action_id < bcmFieldActionCount; action_id++) { 4366 if (!_FP_ACTION_BMP_TEST(action_bmp, action_id)) { 4367 continue; 4368 } 4369 act = f_act; 4370 while (act->action != action_id) { 4371 act = act->next; 4372 } 4373 switch (act->action) { 4374 case bcmFieldActionCosQNew: 4375 case bcmFieldActionGpCosQNew: 4376 case bcmFieldActionYpCosQNew: 4377 case bcmFieldActionRpCosQNew: 4378 case bcmFieldActionUcastCosQNew: 4379 case bcmFieldActionGpUcastCosQNew: 4380 case bcmFieldActionYpUcastCosQNew: 4381 case bcmFieldActionRpUcastCosQNew: 4382 case bcmFieldActionMcastCosQNew: 4383 case bcmFieldActionGpMcastCosQNew: 4384 case bcmFieldActionYpMcastCosQNew: 4385 case bcmFieldActionRpMcastCosQNew: 4386 case bcmFieldActionEgressClassSelect: 4387 case bcmFieldActionHiGigClassSelect: 4388 case bcmFieldActionFabricQueue: 4389 case bcmFieldActionL3Switch: 4390 case bcmFieldActionRedirectMcast: 4391 case bcmFieldActionRedirectEgrNextHop: 4392 case bcmFieldActionRedirectIpmc: 4393 case bcmFieldActionRedirectCancel: 4394 case bcmFieldActionOuterVlanNew: 4395 for (param_id = 0; param_id < 1; param_id++) { 4396 val_array[count++]= act->param[param_id]; 4397 val_array1[count1++]= act->param[param_id]; 4398 4399 } 4400 break; 4401 case bcmFieldActionCopyToCpu: 4402 case bcmFieldActionTimeStampToCpu: 4403 case bcmFieldActionRpCopyToCpu: 4404 case bcmFieldActionRpTimeStampToCpu: 4405 case bcmFieldActionYpCopyToCpu: 4406 case bcmFieldActionYpTimeStampToCpu: 4407 case bcmFieldActionGpCopyToCpu: 4408 case bcmFieldActionGpTimeStampToCpu: 4409 for (param_id = 0; param_id < 2; param_id++) { 4410 val_array1[count1++]= act->param[param_id]; 4411 } 4412 break; 4413 case bcmFieldActionDstMacNew: 4414 case bcmFieldActionSrcMacNew: 4415 case bcmFieldActionUnmodifiedPacketRedirectPort: 4416 case bcmFieldActionRedirect: 4417 case bcmFieldActionEtagNew: 4418 case bcmFieldActionVnTagNew: 4419 case bcmFieldActionRedirectTrunk: 4420 for (param_id = 0; param_id < 2; param_id++) { 4421 val_array[count++]= act->param[param_id]; 4422 val_array1[count1++]= act->param[param_id]; 4423 } 4424 break; 4425 case bcmFieldActionRedirectPbmp: 4426 case bcmFieldActionEgressMask: 4427 case bcmFieldActionEgressPortsAdd: 4428 case bcmFieldActionRedirectBcastPbmp: 4429 for (param_id = 0; param_id < 4; param_id++) { 4430 val_array1[count1++]= act->param[param_id]; 4431 } 4432 /*To store port larger than 128.*/ 4433 val_array[count++]= act->param[4]; 4434 /*store opposite values and use as flag when recover*/ 4435 val_array[count++]= ~act->param[1]; 4436 val_array[count++]= ~act->param[2]; 4437 val_array[count++]= ~act->param[3]; 4438 break; 4439 case bcmFieldActionMirrorIngress: 4440 case bcmFieldActionMirrorEgress: 4441 fa = act; 4442 for (mirror_id = 0; mirror_id < (BCM_MIRROR_MTP_COUNT * 2); 4443 mirror_id++) { 4444 mirror_params_array[mirror_id] = -1; 4445 } 4446 mirror_id = 0; 4447 /* For all remaining mirror actions add parameters now */ 4448 while (fa != NULL) { 4449 if (fa ->action == action_id) { 4450 for (param_id = 0; param_id < 2; param_id++) { 4451 mirror_params_array[mirror_id++] = 4452 fa->param[param_id]; 4453 } 4454 } 4455 fa = fa->next; 4456 } 4457 /* Mirror will have BCM_MIRROR_MTP_COUNT * 2 parameters */ 4458 for (mirror_id = 0;mirror_id < (BCM_MIRROR_MTP_COUNT * 2); 4459 mirror_id++) { 4460 val_array[count++] = mirror_params_array[mirror_id]; 4461 val_array1[count1++] = mirror_params_array[mirror_id]; 4462 4463 } 4464 break; 4465 case bcmFieldActionRedirectVlan: 4466 case bcmFieldActionVnTagDelete: 4467 case bcmFieldActionEtagDelete: 4468 default: 4469 break; 4470 } 4471 switch (act->action) { 4472 case bcmFieldActionDstMacNew: 4473 case bcmFieldActionSrcMacNew: 4474 case bcmFieldActionOuterVlanNew: 4475 case bcmFieldActionVnTagNew: 4476 case bcmFieldActionVnTagDelete: 4477 case bcmFieldActionEtagNew: 4478 case bcmFieldActionEtagDelete: 4479 case bcmFieldActionRedirectPbmp: 4480 case bcmFieldActionEgressMask: 4481 case bcmFieldActionEgressPortsAdd: 4482 case bcmFieldActionRedirectBcastPbmp: 4483 case bcmFieldActionRedirectEgrNextHop: 4484 case bcmFieldActionL3Switch: 4485 hw_idx_array[hw_count++] = act->hw_index; 4486 break; 4487 case bcmFieldActionMirrorIngress: 4488 case bcmFieldActionMirrorEgress: 4489 fa = act; 4490 for (mirror_id = 0; mirror_id < BCM_MIRROR_MTP_COUNT; 4491 mirror_id++) { 4492 mirror_hw_idx_array[mirror_id]= -1; 4493 } 4494 mirror_id = 0; 4495 /* For all remaining mirror actions add hw_idx now */ 4496 while (fa != NULL) { 4497 if (fa ->action == action_id) { 4498 mirror_hw_idx_array[mirror_id++]= fa->hw_index; 4499 } 4500 fa = fa->next; 4501 } 4502 /* Mirror will have BCM_MIRROR_MTP_COUNT hw indices */ 4503 for (mirror_id = 0; mirror_id < BCM_MIRROR_MTP_COUNT; 4504 mirror_id++) { 4505 hw_idx_array[hw_count++] = mirror_hw_idx_array[mirror_id]; 4506 } 4507 4508 default: 4509 break; 4510 } 4511 4512 4513 } 4514 size = SHR_BITALLOCSIZE(bcmFieldActionCount); 4515 size = (size-1)/static_type_map[_bcmFieldInternalEntryActionsPbmp].size + 1; 4516 TLV_CREATE(_bcmFieldInternalEntryActionsPbmp, _bcmFieldInternalArray, 4517 size, &tlv); 4518 tlv->value = action_bmp.w; 4519 TLV_WRITE(unit, tlv, ptr, position); 4520 4521 if (val_array[0] != -1) { 4522 TLV_CREATE(_bcmFieldInternalActionParam, _bcmFieldInternalArray, 4523 count, &tlv); 4524 tlv->value = &val_array[0]; 4525 TLV_WRITE(unit, tlv, ptr, position); 4526 } 4527 4528 if (val_array1[0] != -1) { 4529 TLV_CREATE(_bcmFieldInternalActionParam1, _bcmFieldInternalArray, 4530 count1, &tlv); 4531 tlv->value = &val_array1[0]; 4532 TLV_WRITE(unit, tlv, ptr, position); 4533 } 4534 4535 if (hw_idx_array[0] != -1) { 4536 TLV_CREATE(_bcmFieldInternalActionHwIdx, _bcmFieldInternalArray, 4537 hw_count, &tlv); 4538 tlv->value = &hw_idx_array[0]; 4539 TLV_WRITE(unit, tlv, ptr, position); 4540 } 4541 4542 if (action_bmp.w !=NULL) { 4543 _FP_ACTION_BMP_FREE(action_bmp); 4544 } 4545 4546 sal_free(tlv); 4547 return BCM_E_NONE; 4548 } 4549 4550 /* Function: 4551 * _field_statistic_sync 4552 * 4553 * Purpose: 4554 * sync _field_entry_stat_t structure 4555 * 4556 * Paramaters: 4557 * unit - (IN) BCM device number 4558 * fc - (IN) _field_control_t structure pointer 4559 * stat - (IN) Pointer to _field_entry_stat_t structure. 4560 * 4561 * Returns: 4562 * BCM_E_XXX 4563 */ 4564 int 4565 _field_statistic_sync(int unit, _field_control_t *fc, 4566 _field_entry_stat_t stat) { 4567 4568 _field_tlv_t *tlv = NULL; /* pointer to tlv structure */ 4569 uint8 *ptr; /* pointer to scache_pos (offset) */ 4570 uint32 *position; /* Scache position */ 4571 4572 WB_FIELD_CONTROL_GET(fc, ptr, position); 4573 4574 TLV_CREATE(_bcmFieldInternalEntryStatSid, 4575 _bcmFieldInternalVariable, 0, &tlv); 4576 tlv->value = &(stat.sid); 4577 TLV_WRITE(unit, tlv, ptr, position); 4578 4579 TLV_CREATE(_bcmFieldInternalEntryStatExtendedSid, 4580 _bcmFieldInternalVariable, 0, &tlv); 4581 tlv->value = &(stat.extended_sid); 4582 TLV_WRITE(unit, tlv, ptr, position); 4583 4584 TLV_CREATE(_bcmFieldInternalEntryStatFlags, 4585 _bcmFieldInternalVariable, 0, &tlv); 4586 tlv->value = &(stat.flags); 4587 TLV_WRITE(unit, tlv, ptr, position); 4588 4589 TLV_CREATE(_bcmFieldInternalEntryStatAction, 4590 _bcmFieldInternalVariable, 0, &tlv); 4591 tlv->value = &(stat.stat_action); 4592 TLV_WRITE(unit, tlv, ptr, position); 4593 4594 sal_free(tlv); 4595 return BCM_E_NONE; 4596 4597 } 4598 /* Function: 4599 * _field_lt_entry_sync 4600 * 4601 * Purpose: 4602 * Sync _field_lt_entry_t structure 4603 * 4604 * Paramaters: 4605 * unit - (IN) BCM device number 4606 * f_lt_ent - (IN) _field_lt_entry_t structure. 4607 * parts_count - (IN) Number of TCAM Parts. 4608 * 4609 * Returns: 4610 * BCM_E_XXX 4611 */ 4612 int 4613 _field_lt_entry_info_sync(int unit, _field_lt_entry_t *f_lt_ent, 4614 int parts_count) 4615 { 4616 _field_tlv_t *tlv = NULL; /* tlv data */ 4617 int j = 0; /* j -> loop variable */ 4618 uint32 end_marker = _FIELD_WB_EM_LTENTRY; 4619 /* end marker for the LT entry structure */ 4620 uint8 *ptr; /* pointer to scache_pos(offset) */ 4621 _field_control_t *fc = NULL; /* pointer to field_control structure */ 4622 int temp; /* temporary variable */ 4623 uint32 *position; /* Scache position */ 4624 4625 int flag_enums[3] = { _bcmFieldInternalEntryFlagsPart1, 4626 _bcmFieldInternalEntryFlagsPart2, 4627 _bcmFieldInternalEntryFlagsPart3 4628 }; /* If there are multiple parts in an 4629 * lt_entry, only flags differ 4630 * for each part. Save complete info about 4631 * part1, and only flags info for 4632 * the remaining parts using FlagsPart2 and 4633 * so on. 4634 */ 4635 4636 4637 WB_FIELD_CONTROL_GET(fc, ptr, position); 4638 4639 for (j = 0; j < parts_count; j++) { 4640 TLV_CREATE(flag_enums[j], _bcmFieldInternalVariable, 0, &tlv); 4641 tlv->value = &((f_lt_ent+j)->flags); 4642 TLV_WRITE(unit, tlv, ptr, position); 4643 } 4644 4645 TLV_CREATE(_bcmFieldInternalEntryEid, 4646 _bcmFieldInternalVariable, 0, &tlv); 4647 tlv->value = &(f_lt_ent->eid); 4648 TLV_WRITE(unit, tlv, ptr, position); 4649 4650 TLV_CREATE(_bcmFieldInternalEntrySliceId, 4651 _bcmFieldInternalVariable, 0, &tlv); 4652 tlv->value = &(f_lt_ent->index); 4653 TLV_WRITE(unit, tlv, ptr,position); 4654 4655 TLV_CREATE( _bcmFieldInternalEntryPrio, 4656 _bcmFieldInternalVariable, 0, &tlv); 4657 tlv->value = &(f_lt_ent->prio); 4658 TLV_WRITE(unit, tlv, ptr, position); 4659 4660 4661 TLV_CREATE(_bcmFieldInternalEntryGroup, 4662 _bcmFieldInternalVariable, 0, &tlv); 4663 tlv->value = &(f_lt_ent->group->gid); 4664 TLV_WRITE(unit, tlv, ptr, position); 4665 4666 4667 TLV_CREATE(_bcmFieldInternalEntrySlice, 4668 _bcmFieldInternalVariable, 0, &tlv); 4669 temp = ((int) (f_lt_ent->lt_fs->slice_number)); 4670 tlv->value = &temp; 4671 TLV_WRITE(unit, tlv, ptr, position); 4672 4673 /* Currently LT actions support only one action */ 4674 if (f_lt_ent->actions != NULL) { 4675 TLV_CREATE(_bcmFieldInternalGroupClassAct, 4676 _bcmFieldInternalVariable, 0, &tlv); 4677 tlv->value = &(f_lt_ent->actions->param[0]); 4678 TLV_WRITE(unit, tlv, ptr, position); 4679 } 4680 4681 TLV_CREATE(_bcmFieldInternalEndStructEntry, 4682 _bcmFieldInternalVariable, 0, &tlv); 4683 tlv->value = &end_marker; 4684 TLV_WRITE(unit, tlv, ptr, position); 4685 4686 sal_free(tlv); 4687 return BCM_E_NONE; 4688 4689 } 4690 4691 /* Function: 4692 * _field_entry_info_sync 4693 * 4694 * Purpose: 4695 * Sync _field_entry_t structure 4696 * 4697 * Paramaters: 4698 * unit - (IN) BCM device number 4699 * f_ent - (IN) _field_entry_t structure. 4700 * fc - (IN) _field_control_t structure. 4701 * parts_count - (IN) Number of TCAM Parts. 4702 * 4703 * Returns: 4704 * BCM_E_XXX 4705 */ 4706 int 4707 _field_entry_info_sync(int unit, _field_entry_t *f_ent, int parts_count) 4708 { 4709 _field_tlv_t *tlv = NULL; /* tlv structure */ 4710 uint32 end_marker = _FIELD_WB_EM_ENTRY; 4711 /* end marker */ 4712 uint8 *ptr; /* pointer to scache_structure */ 4713 _field_control_t *fc = NULL; /* pointer to field_control_t structure */ 4714 int j = 0; /* j - loop variable */ 4715 int temp; /* temporary variable */ 4716 int flag_enums[_FP_TH_MAX_ENTRY_WIDTH] = { 4717 _bcmFieldInternalEntryFlagsPart1, 4718 _bcmFieldInternalEntryFlagsPart2, 4719 _bcmFieldInternalEntryFlagsPart3 4720 }; 4721 /* If there are multiple parts in an entry, 4722 * only flags differ. 4723 * save complete info about part1, 4724 * and only flags info for the 4725 * remaining parts using FlagsPart2 4726 * and soon. 4727 */ 4728 int type_entrypolicer[_FP_TH_MAX_ENTRY_WIDTH] = { 4729 (int) (_bcmFieldInternalEntryPolicerPid 4730 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 4731 (int) (_bcmFieldInternalEntryPolicerFlags 4732 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 4733 (int) (_bcmFieldInternalEndStructEntPolicer 4734 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)) 4735 }; 4736 4737 /* Holds types for all fields 4738 * in _field_entry_policer_t structure 4739 */ 4740 uint32 *position; /* Scache position */ 4741 4742 WB_FIELD_CONTROL_GET(fc, ptr, position); 4743 4744 TLV_CREATE(_bcmFieldInternalEntryEid, 4745 _bcmFieldInternalVariable, 0, &tlv); 4746 tlv->value = &(f_ent->eid); 4747 TLV_WRITE(unit, tlv, ptr, position); 4748 4749 TLV_CREATE( _bcmFieldInternalEntryPrio, 4750 _bcmFieldInternalVariable, 0, &tlv); 4751 tlv->value = &(f_ent->prio); 4752 TLV_WRITE(unit, tlv, ptr, position); 4753 4754 4755 TLV_CREATE(_bcmFieldInternalEntrySliceId, 4756 _bcmFieldInternalVariable, 0, &tlv); 4757 tlv->value = &(f_ent->slice_idx); 4758 TLV_WRITE(unit, tlv, ptr,position); 4759 4760 for (j = 0; j < parts_count; j++) { 4761 TLV_CREATE(flag_enums[j], _bcmFieldInternalVariable, 0, &tlv); 4762 tlv->value = &((f_ent+j)->flags); 4763 TLV_WRITE(unit, tlv, ptr, position); 4764 } 4765 4766 TLV_CREATE(_bcmFieldInternalEntryPbmpFullData, 4767 _bcmFieldInternalArray, _SHR_PBMP_WORD_MAX, &tlv); 4768 tlv->value = &(f_ent->pbmp.data.pbits); 4769 TLV_WRITE(unit,tlv, ptr, position); 4770 4771 TLV_CREATE(_bcmFieldInternalEntryPbmpFullMask, 4772 _bcmFieldInternalArray, _SHR_PBMP_WORD_MAX, &tlv); 4773 tlv->value = &(f_ent->pbmp.mask.pbits); 4774 TLV_WRITE(unit,tlv, ptr, position); 4775 4776 4777 TLV_CREATE(_bcmFieldInternalEntryGroup, 4778 _bcmFieldInternalVariable, 0, &tlv); 4779 tlv->value = &(f_ent->group->gid); 4780 TLV_WRITE(unit, tlv, ptr, position); 4781 4782 4783 if (f_ent->fs != NULL) { 4784 TLV_CREATE(_bcmFieldInternalEntrySlice, 4785 _bcmFieldInternalVariable, 0, &tlv); 4786 temp = ((int) (f_ent->fs->slice_number)); 4787 tlv->value = &temp; 4788 TLV_WRITE(unit, tlv, ptr, position); 4789 } 4790 4791 if (f_ent->actions != NULL) { 4792 BCM_IF_ERROR_RETURN(_field_actions_sync(unit, f_ent->actions)); 4793 } 4794 _field_statistic_sync(unit, fc, (f_ent->statistic)); 4795 4796 /* In the encoded length below , first ten bits is value 3 [no of types], 4797 * next 22 bits is policer level count. Here number of types indicate counts 4798 * of elements in the current datastructure. 4799 */ 4800 4801 TLV_CREATE(_bcmFieldInternalEntryPolicer, 4802 _bcmFieldInternalVariable, (_FP_POLICER_LEVEL_COUNT 4803 | (3 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 4804 4805 tlv->value = &type_entrypolicer[0]; 4806 TLV_WRITE(unit, tlv, ptr, position); 4807 4808 for (j = 0; j < _FP_POLICER_LEVEL_COUNT; j++) { 4809 TLV_CREATE(_bcmFieldInternalEntryPolicerPid, 4810 _bcmFieldInternalVariable, 0, &tlv); 4811 tlv->value = &(f_ent->policer[j].pid); 4812 TLV_WRITE(unit, tlv, ptr, position); 4813 4814 TLV_CREATE(_bcmFieldInternalEntryPolicerFlags, 4815 _bcmFieldInternalVariable, 0, &tlv); 4816 tlv->value = &(f_ent->policer[j].flags); 4817 TLV_WRITE(unit, tlv, ptr, position); 4818 4819 TLV_CREATE(_bcmFieldInternalEndStructEntPolicer, 4820 _bcmFieldInternalVariable, 0, &tlv); 4821 TLV_WRITE(unit, tlv, ptr, position); 4822 } 4823 4824 TLV_CREATE(_bcmFieldInternalGlobalEntryPolicerPid, 4825 _bcmFieldInternalVariable, 0, &tlv); 4826 tlv->value = &(f_ent->global_meter_policer.pid); 4827 TLV_WRITE(unit, tlv, ptr, position); 4828 4829 TLV_CREATE(_bcmFieldInternalGlobalEntryPolicerFlags, 4830 _bcmFieldInternalVariable, 0, &tlv); 4831 tlv->value = &(f_ent->global_meter_policer.flags); 4832 TLV_WRITE(unit, tlv, ptr, position); 4833 4834 TLV_CREATE(_bcmFieldInternalEntryIngMtp, 4835 _bcmFieldInternalVariable, 0, &tlv); 4836 tlv->value = &(f_ent->ing_mtp_slot_map); 4837 TLV_WRITE(unit, tlv, ptr, position); 4838 4839 TLV_CREATE(_bcmFieldInternalEntryEgrMtp, 4840 _bcmFieldInternalVariable, 0, &tlv); 4841 tlv->value = &(f_ent->egr_mtp_slot_map); 4842 TLV_WRITE(unit, tlv, ptr, position); 4843 4844 TLV_CREATE(_bcmFieldInternalEntryDvp, 4845 _bcmFieldInternalVariable, 0, &tlv); 4846 tlv->value = &(f_ent->dvp_type); 4847 TLV_WRITE(unit, tlv, ptr, position); 4848 4849 TLV_CREATE(_bcmFieldInternalEntrySvpType, 4850 _bcmFieldInternalVariable, 0, &tlv); 4851 tlv->value = &(f_ent->svp_type); 4852 TLV_WRITE(unit, tlv, ptr, position); 4853 4854 TLV_CREATE(_bcmFieldInternalEntryTcamIptype, 4855 _bcmFieldInternalVariable, 0, &tlv); 4856 tlv->value = &(f_ent->tcam.ip_type); 4857 TLV_WRITE(unit, tlv, ptr, position); 4858 4859 4860 /* Disabling saveing entry copy for now to reduce scache_size 4861 * if (f_ent->ent_copy != NULL) { 4862 */ 4863 if (0) { 4864 TLV_CREATE(_bcmFieldInternalEntryCopy, 4865 _bcmFieldInternalVariable, 0, &tlv); 4866 TLV_WRITE(unit, tlv, ptr, position); 4867 4868 _field_entry_info_sync(unit, f_ent->ent_copy, parts_count); 4869 } 4870 TLV_CREATE(_bcmFieldInternalEndStructEntry, 4871 _bcmFieldInternalVariable, 0, &tlv); 4872 tlv->value = &end_marker; 4873 TLV_WRITE(unit, tlv, ptr, position); 4874 4875 sal_free(tlv); 4876 return BCM_E_NONE; 4877 4878 } 4879 /* Function: 4880 * _field_entry_sync 4881 * 4882 * Purpose: 4883 * call functions for _field_entry_sync and _field_lt_entry_sync. 4884 * 4885 * Paramaters: 4886 * unit - (IN) BCM device number 4887 * 4888 * Returns: 4889 * BCM_E_XXX 4890 */ 4891 int 4892 _field_entry_sync(int unit) 4893 { 4894 _field_tlv_t *tlv = NULL; /* Pointer to tlv structure */ 4895 _field_control_t *fc = NULL; /* Pointer to field control structure. */ 4896 _field_group_t *fg = NULL; /* Pointer to traverse over groups */ 4897 _field_entry_t *f_ent = NULL; /* to traverse entries in each group */ 4898 _field_lt_entry_t *f_lt_ent = NULL; /*to traverse over lt_entries */ 4899 int parts_count = 0; /* Number of parts for that group, 4900 interslice double wide can have two and 4901 interslice triple wide can have three */ 4902 int i = 0; /* local variable */ 4903 uint8 *ptr; /* pointer to scache position(offset) */ 4904 uint32 *position; /* Scache position */ 4905 4906 WB_FIELD_CONTROL_GET(fc, ptr, position); 4907 4908 fg = fc->groups; 4909 while (fg != NULL) { 4910 if (fg->stage_id != _BCM_FIELD_STAGE_INGRESS) { 4911 fg = fg->next; 4912 continue; 4913 } 4914 BCM_IF_ERROR_RETURN(_bcm_field_entry_tcam_parts_count (unit, 4915 fg->stage_id, fg->flags, &parts_count)); 4916 4917 TLV_CREATE(_bcmFieldInternalGroupPartCount, 4918 _bcmFieldInternalVariable, 0, &tlv); 4919 tlv->value = &parts_count; 4920 TLV_WRITE(unit, tlv, ptr, position); 4921 4922 /* _field_entry_t */ 4923 TLV_CREATE(_bcmFieldInternalGroupEntry, 4924 _bcmFieldInternalVariable, 0, &tlv); 4925 tlv->value = &(fg->group_status.entry_count); 4926 TLV_WRITE(unit, tlv, ptr, position); 4927 4928 for (i = 0; i < fg->group_status.entry_count; i++) { 4929 if (fg->entry_arr[i] == NULL) { 4930 continue; 4931 } 4932 f_ent = fg->entry_arr[i]; 4933 _field_entry_info_sync(unit, f_ent, parts_count); 4934 } 4935 4936 /* _field_ltentry_t */ 4937 TLV_CREATE(_bcmFieldInternalGroupLtEntry, 4938 _bcmFieldInternalVariable, 0, &tlv); 4939 tlv->value = &(fg->lt_grp_status.entry_count); 4940 TLV_WRITE(unit, tlv, ptr, position); 4941 4942 4943 for (i = 0; i < (fg->lt_grp_status.entry_count); i++) { 4944 if (fg->lt_entry_arr[i] == NULL) { 4945 continue; 4946 } 4947 f_lt_ent = fg->lt_entry_arr[i]; 4948 _field_lt_entry_info_sync(unit, f_lt_ent, parts_count); 4949 } 4950 4951 fg = fg->next; 4952 } 4953 4954 TLV_CREATE(_bcmFieldInternalEndStructEntryDetails, 4955 _bcmFieldInternalVariable, 0, &tlv); 4956 TLV_WRITE(unit, tlv, ptr, position); 4957 4958 sal_free(tlv); 4959 return BCM_E_NONE; 4960 4961 } 4962 4963 4964 /* Function: 4965 * _field_group_qualifier_sync 4966 * 4967 * Purpose: 4968 * Sync _bcm_field_group_qual_t structure 4969 * 4970 * Paramaters: 4971 * unit - (IN) BCM device number 4972 * qual_arr - (IN) Pointer to field group qual structure 4973 * 4974 * Returns: 4975 * BCM_E_XXX 4976 */ 4977 4978 int 4979 _field_group_qualifier_sync(int unit, 4980 _bcm_field_group_qual_t *qual_arr) 4981 { 4982 _field_tlv_t *tlv = NULL; /* TLV data */ 4983 uint8 *scache_ptr = NULL; /* Pointer to Scache */ 4984 _bcm_field_qual_offset_t *offset = NULL; 4985 /* Pointer to Qualifier offset */ 4986 _field_control_t *fc; /* Field control structure. */ 4987 int i =0; /* Loop local variable */ 4988 uint32 endmarker = _FIELD_WB_EM_QUAL; 4989 /* End marker */ 4990 uint32 endmarkeroffset = _FIELD_WB_EM_QUALOFFSET; 4991 /* End marker */ 4992 uint32 *position; /* pointer to scache position */ 4993 int type_qual[7] = /* types in _bcm_field_qual_offset_t */ 4994 { 4995 (int)(_bcmFieldInternalQualOffsetNumOffset 4996 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 4997 (int)(_bcmFieldInternalQualOffsetOffsetArr 4998 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 4999 (int)(_bcmFieldInternalQualOffsetWidth 5000 | (_bcmFieldInternalArray << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 5001 (int)(_bcmFieldInternalQualOffsetSec 5002 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 5003 (int)(_bcmFieldInternalQualOffsetBitPos 5004 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 5005 (int)(_bcmFieldInternalQualOffsetQualWidth16 5006 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)), 5007 (int)(_bcmFieldInternalEndStructQualOffset 5008 | (_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT)) 5009 5010 }; 5011 5012 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 5013 5014 TLV_CREATE(_bcmFieldInternalQualQid, _bcmFieldInternalArray, 5015 qual_arr->size, &tlv); 5016 tlv->value = qual_arr->qid_arr; 5017 TLV_WRITE(unit, tlv, scache_ptr, position); 5018 5019 TLV_CREATE(_bcmFieldInternalQualSize, _bcmFieldInternalVariable, 0, &tlv); 5020 tlv->value = &(qual_arr->size); 5021 TLV_WRITE(unit, tlv, scache_ptr, position); 5022 5023 /* In the encoded length below , first ten bits is value 8 [no of types], 5024 * next 22 bits is qualifier array size . Here number of types indicate 5025 * counts of elements in the current datastructure. 5026 */ 5027 5028 TLV_CREATE(_bcmFieldInternalQualOffset, _bcmFieldInternalArray, 5029 (qual_arr->size | (7 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 5030 tlv->value = &type_qual; 5031 TLV_WRITE(unit, tlv, scache_ptr, position); 5032 5033 offset = qual_arr->offset_arr; 5034 for (i = 0; i < qual_arr->size; i++) { 5035 5036 TLV_CREATE(_bcmFieldInternalQualOffsetNumOffset, 5037 _bcmFieldInternalVariable,0, &tlv); 5038 tlv->value = &offset->num_offsets; 5039 TLV_WRITE(unit, tlv, scache_ptr, position); 5040 5041 TLV_CREATE(_bcmFieldInternalQualOffsetOffsetArr, 5042 _bcmFieldInternalArray, _BCM_FIELD_QUAL_OFFSET_MAX, &tlv); 5043 tlv->value = &offset->offset; 5044 TLV_WRITE(unit, tlv, scache_ptr, position); 5045 5046 TLV_CREATE(_bcmFieldInternalQualOffsetWidth, 5047 _bcmFieldInternalArray, _BCM_FIELD_QUAL_OFFSET_MAX, &tlv); 5048 tlv->value = &offset->width; 5049 TLV_WRITE(unit, tlv, scache_ptr, position); 5050 5051 TLV_CREATE(_bcmFieldInternalQualOffsetSec, 5052 _bcmFieldInternalVariable, 0, &tlv); 5053 tlv->value = &offset->secondary; 5054 TLV_WRITE(unit, tlv, scache_ptr, position); 5055 5056 TLV_CREATE(_bcmFieldInternalQualOffsetBitPos, 5057 _bcmFieldInternalVariable, 0, &tlv); 5058 tlv->value = &offset->bit_pos; 5059 TLV_WRITE(unit, tlv, scache_ptr, position); 5060 5061 TLV_CREATE(_bcmFieldInternalQualOffsetQualWidth16, 5062 _bcmFieldInternalVariable, 0, &tlv); 5063 tlv->value = &offset->qual_width; 5064 TLV_WRITE(unit, tlv, scache_ptr, position); 5065 5066 5067 TLV_CREATE(_bcmFieldInternalEndStructQualOffset, 5068 _bcmFieldInternalVariable, 0, &tlv); 5069 tlv->value = &endmarkeroffset; 5070 TLV_WRITE(unit, tlv, scache_ptr, position); 5071 5072 offset++; 5073 } 5074 5075 TLV_CREATE(_bcmFieldInternalEndStructGroupQual, 5076 _bcmFieldInternalVariable, 0, &tlv); 5077 tlv->value = &endmarker; 5078 TLV_WRITE(unit, tlv, scache_ptr, position); 5079 5080 return BCM_E_NONE; 5081 } 5082 5083 5084 /* Function: 5085 * _field_group_sync 5086 * 5087 * Purpose: 5088 * Sync _field_group_t structure 5089 * 5090 * Paramaters: 5091 * unit - (IN) BCM device number 5092 * fg - (IN) Pointer to device group structure 5093 * 5094 * Returns: 5095 * BCM_E_XXX 5096 */ 5097 int 5098 _field_group_sync(int unit, _field_group_t *fg) 5099 { 5100 _field_tlv_t *tlv = NULL; /* TLV data */ 5101 uint8 *scache_ptr = NULL; /* Pointer to Scache */ 5102 _field_control_t *fc; /* Field control structure. */ 5103 uint32 endmarker = _FIELD_WB_EM_GROUP; /* End marker */ 5104 int parts_count = 0; /* Number of entry parts. */ 5105 int rv = 0; /* Return Variable */ 5106 int partidx = 0; /* Id to field entry part */ 5107 int temp = 0; /* temporary variable */ 5108 uint32 *position; /* Pointer to scache pos */ 5109 uint32 qual_count = bcmFieldQualifyCount; 5110 /* Qualifier Count */ 5111 uint16 grp_flags16 = 0; /* 16-bit group flags */ 5112 5113 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 5114 5115 TLV_CREATE(_bcmFieldInternalGroupId, 5116 _bcmFieldInternalVariable, 0, &tlv); 5117 tlv->value = &fg->gid; 5118 TLV_WRITE(unit, tlv, scache_ptr, position); 5119 5120 TLV_CREATE(_bcmFieldInternalGroupPri, 5121 _bcmFieldInternalVariable, 0, &tlv); 5122 tlv->value = &fg->priority; 5123 TLV_WRITE(unit, tlv, scache_ptr, position); 5124 5125 /* this could be synced once but it is synced 5126 per group for easy processing */ 5127 5128 TLV_CREATE(_bcmFieldInternalQualifyCount, 5129 _bcmFieldInternalVariable, 0, &tlv); 5130 tlv->value = &qual_count; 5131 TLV_WRITE(unit, tlv, scache_ptr, position); 5132 5133 TLV_CREATE(_bcmFieldInternalQsetW, _bcmFieldInternalArray, 5134 _SHR_BITDCLSIZE(_bcmFieldQualifyCount), &tlv); 5135 tlv->value = &fg->qset.w; 5136 TLV_WRITE(unit, tlv, scache_ptr, position); 5137 5138 TLV_CREATE(_bcmFieldInternalQsetUdfMap, _bcmFieldInternalArray, 5139 _SHR_BITDCLSIZE(BCM_FIELD_USER_NUM_UDFS), &tlv); 5140 tlv->value = &fg->qset.udf_map; 5141 TLV_WRITE(unit, tlv, scache_ptr, position); 5142 5143 TLV_CREATE(_bcmFieldInternalGroupFlags,_bcmFieldInternalVariable,0,&tlv); 5144 grp_flags16 = fg->flags & 0xFFFF; 5145 tlv->value = &grp_flags16; 5146 TLV_WRITE(unit, tlv, scache_ptr, position); 5147 5148 TLV_CREATE(_bcmFieldInternalGroupFlagsMsb16,_bcmFieldInternalVariable,0,&tlv); 5149 grp_flags16 = (fg->flags >> 16) & 0xFFFF; 5150 tlv->value = &grp_flags16; 5151 TLV_WRITE(unit, tlv, scache_ptr, position); 5152 5153 5154 TLV_CREATE(_bcmFieldInternalGroupInstance,_bcmFieldInternalVariable,0,&tlv); 5155 tlv->value = &fg->instance; 5156 TLV_WRITE(unit, tlv, scache_ptr, position); 5157 5158 if (fg->slices != NULL) { 5159 TLV_CREATE(_bcmFieldInternalGroupSlice, _bcmFieldInternalVariable,0, &tlv); 5160 temp = (int) fg->slices->slice_number; 5161 tlv->value = &temp; 5162 TLV_WRITE(unit, tlv, scache_ptr, position); 5163 } 5164 5165 TLV_CREATE(_bcmFieldInternalGroupPbmp, _bcmFieldInternalArray,64, &tlv); 5166 tlv->value = &fg->pbmp; 5167 TLV_WRITE(unit, tlv, scache_ptr, position); 5168 5169 /* Get number of entry parts we have to read. */ 5170 rv = _bcm_field_entry_tcam_parts_count (unit, fg->stage_id, 5171 fg->flags, &parts_count); 5172 5173 TLV_CREATE(_bcmFieldInternalGroupQual, 5174 _bcmFieldInternalArray, parts_count, &tlv); 5175 TLV_WRITE(unit, tlv, scache_ptr, position); 5176 5177 for (partidx = 0; partidx < parts_count; partidx++) { 5178 BCM_IF_ERROR_RETURN( _field_group_qualifier_sync(unit, 5179 &(fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][partidx]))); 5180 } 5181 5182 TLV_CREATE(_bcmFieldInternalGroupPreselQual, 5183 _bcmFieldInternalArray, parts_count, &tlv); 5184 TLV_WRITE(unit, tlv, scache_ptr, position); 5185 5186 for (partidx = 0; partidx < parts_count; partidx++) { 5187 BCM_IF_ERROR_RETURN( _field_group_qualifier_sync(unit, 5188 &(fg->presel_qual_arr[_FP_ENTRY_TYPE_DEFAULT][partidx]))); 5189 } 5190 5191 TLV_CREATE(_bcmFieldInternalGroupStage, _bcmFieldInternalVariable, 0, &tlv); 5192 tlv->value = &fg->stage_id; 5193 TLV_WRITE(unit, tlv, scache_ptr, position); 5194 5195 TLV_CREATE(_bcmFieldInternalGroupBlockCount, 5196 _bcmFieldInternalVariable, 0, &tlv); 5197 tlv->value = &fg->ent_block_count; 5198 TLV_WRITE(unit, tlv, scache_ptr, position); 5199 5200 TLV_CREATE(_bcmFieldInternalGroupGroupStatus, _bcmFieldInternalArray, 5201 (sizeof(bcm_field_group_status_t)/sizeof(int)), &tlv); 5202 tlv->value = &fg->group_status; 5203 TLV_WRITE(unit, tlv, scache_ptr, position); 5204 5205 5206 TLV_CREATE(_bcmFieldInternalGroupGroupAset, _bcmFieldInternalArray, 5207 _SHR_BITDCLSIZE(bcmFieldActionCount), &tlv); 5208 tlv->value = &fg->aset.w; 5209 TLV_WRITE(unit, tlv, scache_ptr, position); 5210 5211 TLV_CREATE(_bcmFieldInternalGroupCounterBmp, _bcmFieldInternalArray, 5212 _FIELD_MAX_COUNTER_POOLS, &tlv); 5213 tlv->value = &fg->counter_pool_bmp.w; 5214 TLV_WRITE(unit, tlv, scache_ptr, position); 5215 5216 5217 if (fg->lt_slices != NULL) { 5218 TLV_CREATE(_bcmFieldInternalGroupLtSlice, _bcmFieldInternalVariable,0, 5219 &tlv); 5220 temp = (int) fg->lt_slices->slice_number; 5221 tlv->value = &temp; 5222 TLV_WRITE(unit, tlv, scache_ptr, position); 5223 } 5224 5225 BCM_IF_ERROR_RETURN(_field_extractor_sync(unit, 5226 (fg->ext_codes), _FP_MAX_ENTRY_WIDTH)); 5227 5228 /* _field_ltinfo_t -> we save lt_id and link to the _field_lt_info_t 5229 structure recovered during stage reinit */ 5230 5231 TLV_CREATE(_bcmFieldInternalGroupLtConfig, _bcmFieldInternalVariable, 5232 0, &tlv); 5233 tlv->value = &fg->lt_id; 5234 TLV_WRITE(unit, tlv, scache_ptr, position); 5235 5236 TLV_CREATE(_bcmFieldInternalGroupLtEntrySize, 5237 _bcmFieldInternalVariable, 0, &tlv); 5238 tlv->value = &fg->lt_ent_blk_cnt; 5239 TLV_WRITE(unit, tlv, scache_ptr, position); 5240 5241 5242 TLV_CREATE(_bcmFieldInternalLtStatusEntriesCnt, 5243 _bcmFieldInternalVariable, 0, &tlv); 5244 tlv->value = &fg->lt_grp_status.entry_count; 5245 TLV_WRITE(unit, tlv, scache_ptr, position); 5246 5247 TLV_CREATE(_bcmFieldInternalLtStatusEntriesFree, 5248 _bcmFieldInternalVariable, 0, &tlv); 5249 tlv->value = &fg->lt_grp_status.entries_free; 5250 TLV_WRITE(unit, tlv, scache_ptr, position); 5251 5252 TLV_CREATE(_bcmFieldInternalLtStatusEntriesTotal, 5253 _bcmFieldInternalVariable, 0, &tlv); 5254 tlv->value = &fg->lt_grp_status.entries_total; 5255 TLV_WRITE(unit, tlv, scache_ptr, position); 5256 5257 TLV_CREATE(_bcmFieldInternalGroupHintId, 5258 _bcmFieldInternalVariable, 0, &tlv); 5259 tlv->value = &fg->hintid; 5260 TLV_WRITE(unit, tlv, scache_ptr, position); 5261 5262 TLV_CREATE(_bcmFieldInternalGroupMaxSize, 5263 _bcmFieldInternalVariable, 0, &tlv); 5264 tlv->value = &fg->max_group_size; 5265 TLV_WRITE(unit, tlv, scache_ptr, position); 5266 5267 TLV_CREATE(_bcmFieldInternalEMGroupMode, 5268 _bcmFieldInternalVariable, 0, &tlv); 5269 tlv->value = &fg->em_mode; 5270 TLV_WRITE(unit, tlv, scache_ptr, position); 5271 5272 temp = _SHR_BITDCLSIZE(bcmFieldActionCount); 5273 TLV_CREATE(_bcmFieldInternalEMGroupAset2, 5274 _bcmFieldInternalArray, temp, &tlv); 5275 tlv->value = &fg->aset.w; 5276 TLV_WRITE(unit, tlv, scache_ptr, position); 5277 5278 TLV_CREATE(_bcmFieldInternalGroupActionProfIdx, 5279 _bcmFieldInternalArray, 3, &tlv); 5280 tlv->value = &fg->action_profile_idx; 5281 TLV_WRITE(unit, tlv, scache_ptr, position); 5282 5283 TLV_CREATE(_bcmFieldInternalEndStructGroup, 5284 _bcmFieldInternalVariable, 0, &tlv); 5285 tlv->value = &endmarker; 5286 TLV_WRITE(unit, tlv, scache_ptr, position); 5287 5288 return rv; 5289 5290 } 5291 /* Function: 5292 * _field_class_info_sync 5293 * 5294 * Purpose: 5295 * sync function for _field_class_info_t structure 5296 * 5297 * Parameters: 5298 * unit - (IN) unit number 5299 * class_info_arr - (IN) pointer to array of pointers to structures 5300 * count - (IN) Number of _field_class_info_t structure pointers 5301 * Returns: 5302 * BCM_E_XXX 5303 */ 5304 int 5305 _field_class_info_sync(int unit, _field_class_info_t **class_info_arr, 5306 int count) { 5307 _field_tlv_t *tlv = NULL; /* tlv structure */ 5308 _field_control_t *fc = NULL; /* pointer to field control structure */ 5309 uint32 *pos = NULL; /* position in fc */ 5310 uint8 *ptr = NULL; /* pointer to fc->scache_ptr */ 5311 int i, bmp_length = 0, max_entries; 5312 /* loop var, bitmap length, num of entries 5313 * to calculate bitmap length 5314 */ 5315 int type_class_info[6] = { /* types in _field_class_info_t */ 5316 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 5317 | _bcmFieldInternalClassFlags), 5318 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 5319 | _bcmFieldInternalClassEntUsed), 5320 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 5321 | _bcmFieldInternalClassBmp), 5322 (int) ((_bcmFieldInternalVariable << _FP_WB_TLV_BASIC_TYPE_SHIFT) 5323 | _bcmFieldInternalEndStructClass) 5324 }; 5325 5326 WB_FIELD_CONTROL_GET(fc, ptr, pos); 5327 5328 if ((class_info_arr != NULL) && (count != 0)) { 5329 max_entries = (**class_info_arr).total_entries_available; 5330 bmp_length = SHR_BITALLOCSIZE(max_entries << 1); 5331 } 5332 5333 TLV_CREATE(_bcmFieldInternalStageClass, _bcmFieldInternalVariable, 5334 (count | (4 << _FP_WB_TLV_TYPE_SHIFT)), &tlv); 5335 tlv->value = &type_class_info; 5336 TLV_WRITE(unit, tlv, ptr, pos); 5337 5338 for (i=0; i < _FP_MAX_NUM_CLASS_TYPES; i++) { 5339 if (_bcm_field_th_class_ctype_supported(unit, i) == BCM_E_NONE) { 5340 TLV_CREATE(_bcmFieldInternalClassFlags, 5341 _bcmFieldInternalVariable, 0, &tlv); 5342 tlv->value = &(class_info_arr[i]->flags); 5343 TLV_WRITE(unit, tlv, ptr, pos); 5344 5345 TLV_CREATE(_bcmFieldInternalClassEntUsed, 5346 _bcmFieldInternalVariable, 0, &tlv); 5347 tlv->value = &(class_info_arr[i]->total_entries_used); 5348 TLV_WRITE(unit, tlv, ptr, pos); 5349 5350 TLV_CREATE(_bcmFieldInternalClassBmp, 5351 _bcmFieldInternalVariable, bmp_length, &tlv); 5352 tlv->value = class_info_arr[i]->class_bmp.w; 5353 TLV_WRITE(unit, tlv, ptr, pos); 5354 5355 TLV_CREATE(_bcmFieldInternalEndStructClass, 5356 _bcmFieldInternalVariable, 0, &tlv); 5357 TLV_WRITE(unit, tlv, ptr, pos); 5358 } 5359 5360 } 5361 5362 return BCM_E_NONE; 5363 } 5364 /* Function: 5365 * _bcm_field_th_stage_class_sync 5366 * 5367 * Purpose: 5368 * Main sync function for stage class 5369 * 5370 * Parameters: 5371 * uinit - (IN) unit number 5372 * fc - (IN) pointer to field control structure 5373 * stage_fc - (IN) pointer to stage class structure 5374 * Returns: 5375 * BCM_E_XXX 5376 */ 5377 int 5378 _bcm_field_th_stage_class_sync(int unit, _field_control_t *fc, 5379 _field_stage_t *stage_fc) 5380 { 5381 int pipe, num_pipes = 0; /* current pipe id, number of pipes */ 5382 _field_tlv_t *tlv = NULL; /* tlv structure */ 5383 _field_group_t *fg; /* pointer to group structure */ 5384 _field_entry_t *f_ent = NULL; 5385 /* pointer to entry structure */ 5386 uint8 *ptr; /* pointer to position in field control */ 5387 uint32 *pos; /* pointer to fc->scache_pos */ 5388 int group_count = 0, rv = 0, i = 0; 5389 /* group coutn, ret val, loop var */ 5390 uint32 end_marker = _FIELD_WB_EM_CLASS; 5391 /* end marker */ 5392 int valid_ctypes_count = 0, ctype = 0; /* Count of ctypes supported */ 5393 5394 WB_FIELD_CONTROL_GET_WITH_LOCK(fc, ptr, pos); 5395 curr_stage_fc = stage_fc; 5396 5397 if (stage_fc->oper_mode == 0 ) { 5398 num_pipes = 1; 5399 } else { 5400 num_pipes = stage_fc->num_pipes; 5401 } 5402 5403 5404 5405 fg = fc->groups; 5406 while (fg != NULL) { 5407 if (fg->stage_id == _BCM_FIELD_STAGE_CLASS) { 5408 group_count += 1; 5409 } 5410 fg = fg->next; 5411 } 5412 5413 for (ctype = 0; ctype < _FP_MAX_NUM_CLASS_TYPES; ctype ++) { 5414 if (_bcm_field_th_class_ctype_supported(unit, ctype) == BCM_E_NONE) { 5415 valid_ctypes_count++; 5416 } 5417 } 5418 5419 if (group_count > 0) { 5420 5421 TLV_CREATE(_bcmFieldInternalClassOperMode, 5422 _bcmFieldInternalVariable, 0, &tlv); 5423 tlv->value = &stage_fc->oper_mode; 5424 TLV_WRITE(unit, tlv, ptr, pos); 5425 5426 TLV_CREATE(_bcmFieldInternalStageClassInfo, 5427 _bcmFieldInternalVariable, 0, &tlv); 5428 TLV_WRITE(unit, tlv, ptr, pos); 5429 5430 for (pipe = 0; pipe < num_pipes; pipe++) { 5431 if (!(fc->pipe_map & (1 << pipe))) { 5432 continue; 5433 } 5434 rv = _field_class_info_sync(unit, 5435 stage_fc->class_info_arr[pipe], 5436 valid_ctypes_count); 5437 BCM_IF_ERROR_CLEANUP(rv); 5438 } 5439 5440 TLV_CREATE(_bcmFieldInternalGroupCount, 5441 _bcmFieldInternalVariable, 0, &tlv); 5442 tlv->value = &group_count; 5443 TLV_WRITE(unit, tlv, ptr, pos); 5444 5445 /* Iterate over the groups linked-list */ 5446 fg = fc->groups; 5447 while (fg != NULL) { 5448 if (fg->stage_id == _BCM_FIELD_STAGE_CLASS) { 5449 rv = _field_group_sync(unit,fg); 5450 BCM_IF_ERROR_CLEANUP(rv); 5451 } 5452 fg = fg->next; 5453 } 5454 fg = fc->groups; 5455 5456 while (fg != NULL) { 5457 if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) { 5458 fg = fg->next; 5459 continue; 5460 } 5461 5462 TLV_CREATE(_bcmFieldInternalGroupEntry, 5463 _bcmFieldInternalVariable, 0, &tlv); 5464 tlv->value = &(fg->group_status.entry_count); 5465 TLV_WRITE(unit, tlv, ptr, &(fc->scache_pos)); 5466 5467 for (i=0; i < fg->group_status.entry_count; i++) { 5468 if (fg->entry_arr[i] == NULL) { 5469 continue; 5470 } 5471 f_ent = fg->entry_arr[i]; 5472 /* parts_count hardcoded to 1, 5473 * as compression entries cannot 5474 span across multiple TCAMS */ 5475 rv = _field_entry_info_sync(unit, f_ent, 1); 5476 BCM_IF_ERROR_CLEANUP(rv); 5477 } 5478 5479 fg = fg->next; 5480 5481 } 5482 } 5483 TLV_CREATE(_bcmFieldInternalEndStageClass, 5484 _bcmFieldInternalVariable, 0, &tlv); 5485 tlv->value = &end_marker; 5486 TLV_WRITE(unit, tlv, ptr, pos); 5487 5488 cleanup: 5489 sal_free(tlv); 5490 tlv = NULL; 5491 FP_UNLOCK(unit); 5492 return rv; 5493 5494 } 5495 5496 /* 5497 * Function: 5498 * _field_em_group_entries_sync 5499 * Purpose: 5500 * sync necessary information for each entry in a group 5501 * save entry id, flags, (part 2 flags in case of double wide), 5502 * and hw index in order for each entry. Hw index is obtained by 5503 * populating key and searching for the entry in corresponding 5504 * memory 5505 * 5506 * Parameters: 5507 * unit - (IN) StrataSwitch unit #. 5508 * fg - (IN) pointer to group structure whose entries 5509 * have to be synced. 5510 * Returns: 5511 * BCM_E_XXX 5512 */ 5513 int 5514 _field_em_group_entries_sync(int unit, _field_group_t *fg) 5515 { 5516 5517 _field_tlv_t *tlv = NULL; /* tlv pointer */ 5518 _field_entry_t *f_ent = NULL; /* pointers to entry structures */ 5519 uint8 *ptr = NULL; /* pointer to scache_ptr */ 5520 uint32 *pos = NULL; /* pointer to scache_pos */ 5521 _field_control_t *fc = NULL; /* pointer to field control struc */ 5522 _field_stage_t *stage_fc = NULL; /* pointer to stage structure */ 5523 int count = 0; /* to hold the current postion in array */ 5524 uint32 *array = NULL; /* to hold the values that are to be syced */ 5525 int ent_count = 0, hw_index = 0; /* entry count, hw index */ 5526 int rv = 0, parts_count = 0; /* rv, number of parts */ 5527 exact_match_2_entry_t ebuf_nar; /* Narrow Entry Buffer. */ 5528 exact_match_4_entry_t ebuf_wide; /* Wide Entry Buffer. */ 5529 soc_mem_t mem = INVALIDm; /* Memory Identifier. */ 5530 uint32 tbuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 5531 /* Temp Buffer One. */ 5532 uint32 *bufp = NULL; /* Hardware Buffer Ptr. */ 5533 int num_attr = 0; /* Number of attributes stored per entry */ 5534 5535 ent_count = fg->group_status.entry_count; 5536 WB_FIELD_CONTROL_GET(fc, ptr, pos); 5537 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 5538 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 5539 5540 5541 /* Get Hardware Buffer Pointer and memory identifier. */ 5542 if ((fg->em_mode == _FieldExactMatchMode128) || 5543 (fg->em_mode == _FieldExactMatchMode160)) { 5544 bufp = (uint32 *)&ebuf_nar; 5545 sal_memset(bufp, 0, sizeof(exact_match_2_entry_t)); 5546 num_attr = 5; 5547 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5548 mem = EXACT_MATCH_2m; 5549 } else { 5550 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 5551 EXACT_MATCH_2m, 5552 fg->instance, &mem)); 5553 } 5554 } else { 5555 bufp = (uint32 *)&ebuf_wide; 5556 sal_memset(bufp, 0, sizeof(exact_match_4_entry_t)); 5557 num_attr = 6; 5558 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5559 mem = EXACT_MATCH_4m; 5560 } else { 5561 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 5562 EXACT_MATCH_4m, 5563 fg->instance, &mem)); 5564 } 5565 } 5566 rv = _bcm_field_entry_tcam_parts_count(unit, fg->stage_id, 5567 fg->flags, &parts_count); 5568 BCM_IF_ERROR_CLEANUP(rv); 5569 5570 _FP_XGS3_ALLOC(array, num_attr * ent_count * sizeof(int), 5571 "em entires array"); 5572 if (array == NULL) { 5573 rv = BCM_E_MEMORY; 5574 goto cleanup; 5575 } 5576 5577 while (count != (num_attr * ent_count)) { 5578 f_ent = fg->entry_arr[count/num_attr]; 5579 array[count++] = f_ent->eid; 5580 array[count++] = f_ent->flags; 5581 if (fg->em_mode == _FieldExactMatchMode320) { 5582 array[count++] = (f_ent + 1)->flags; 5583 } 5584 if (f_ent->statistic.flags & _FP_ENTRY_STAT_VALID) { 5585 array[count++] = f_ent->statistic.sid; 5586 } else { 5587 array[count++] = -1; 5588 } 5589 if (f_ent->policer[0].flags & _FP_POLICER_INSTALLED) { 5590 array[count++] = f_ent->policer[0].pid; 5591 } else { 5592 array[count++] = -1; 5593 } 5594 if (!(f_ent->flags & _FP_ENTRY_INSTALLED)) { 5595 array[count++] = -1; 5596 continue; 5597 } 5598 if (f_ent->flags & _FP_ENTRY_EXACT_MATCH_GROUP_DEFAULT) { 5599 array[count++] = -1; 5600 continue; 5601 } 5602 if (soc_feature(unit, soc_feature_th3_style_fp)) { 5603 rv = _field_th3_em_entry_set(unit, f_ent, mem, bufp, 1); 5604 } else if (soc_feature(unit, soc_feature_td3_style_fp)) { 5605 rv = _field_td3_em_entry_set(unit, f_ent, mem, bufp, 1); 5606 } else { 5607 rv = _field_th_em_entry_set(unit, f_ent, mem, bufp, 1); 5608 } 5609 BCM_IF_ERROR_CLEANUP(rv); 5610 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &hw_index, 5611 bufp, tbuf, 0 ); 5612 BCM_IF_ERROR_CLEANUP(rv); 5613 array[count++] = hw_index; 5614 } 5615 5616 TLV_CREATE(_bcmFieldInternalEMEntryarr, _bcmFieldInternalArray, 5617 num_attr * ent_count, &tlv); 5618 tlv->value = array; 5619 TLV_WRITE(unit, tlv, ptr, pos); 5620 5621 cleanup: 5622 if (array != NULL) { 5623 sal_free(array); 5624 } 5625 return rv; 5626 5627 5628 } 5629 5630 /* 5631 * Function: 5632 * _bcm_field_th_stage_em_sync 5633 * Purpose: 5634 * Main sync for exact match stage 5635 * Parameters: 5636 * unit - (IN) StrataSwitch unit #. 5637 * fc - (IN) _field_control_t structure 5638 * stage_fc - (IN) Pointer to exactmatch stage structure 5639 * Returns: 5640 * BCM_E_XXX 5641 */ 5642 int 5643 _bcm_field_th_stage_em_sync(int unit, _field_control_t *fc, 5644 _field_stage_t *stage_fc) 5645 { 5646 _field_tlv_t *tlv = NULL; /* pointer to tlv structure */ 5647 uint8 *ptr = NULL; /* pointer to scache_ptr */ 5648 uint32 *pos = NULL; /* pointer to sacache_pos */ 5649 int num_pipes, pipe_id = 0; /* Number of pipes */ 5650 int slice_id, lt_id = 0; /* slice id, lt slice id */ 5651 _field_slice_t *curr_slice = NULL; 5652 /* Pointer to curr slice, lt slice */ 5653 _field_lt_slice_t *curr_ltslice = NULL; 5654 int rv = 0, i = 0; /* return value, loop variable */ 5655 _field_group_t *fg = NULL; 5656 /* Number of groups, 5657 partitions in each group */ 5658 int group_count = 0, parts_count = 0; 5659 _field_lt_entry_t *f_lt_ent = NULL; 5660 /* pointer to lt entry */ 5661 5662 WB_FIELD_CONTROL_GET_WITH_LOCK(fc, ptr, pos); 5663 curr_stage_fc = stage_fc; 5664 5665 if (stage_fc->oper_mode == 0) { 5666 num_pipes = 1; 5667 } else { 5668 num_pipes = stage_fc->num_pipes; 5669 } 5670 5671 5672 fg = fc->groups; 5673 while (fg != NULL) { 5674 if (fg->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 5675 group_count ++; 5676 } 5677 fg = fg->next; 5678 } 5679 5680 5681 TLV_CREATE(_bcmFieldInternalEMOperMode, 5682 _bcmFieldInternalVariable, 0, &tlv); 5683 tlv->value = &stage_fc->oper_mode; 5684 TLV_WRITE(unit, tlv, ptr, pos); 5685 5686 5687 if (group_count > 0) { 5688 5689 if ((soc_feature(unit, soc_feature_td3_style_fp)) 5690 && (BCM_FIELD_WB_VERSION_1_27 <= fc->wb_current_version)) { 5691 fg = fc->groups; 5692 rv = _field_em_actions_sync(unit, fg); 5693 BCM_IF_ERROR_CLEANUP(rv); 5694 } 5695 5696 TLV_CREATE(_bcmFieldInternalSlice, 5697 _bcmFieldInternalVariable, 0, &tlv); 5698 TLV_WRITE(unit, tlv, ptr, pos); 5699 5700 for (pipe_id = 0; pipe_id < num_pipes; pipe_id++) { 5701 if (!(fc->pipe_map & (1 << pipe_id))) { 5702 continue; 5703 } 5704 curr_slice = stage_fc->slices[pipe_id]; 5705 curr_ltslice = stage_fc->lt_slices[pipe_id]; 5706 if (curr_slice != NULL) { 5707 for (slice_id= 0; slice_id < stage_fc->tcam_slices; slice_id ++) { 5708 rv = _field_slice_sync(unit, (curr_slice + slice_id)); 5709 BCM_IF_ERROR_CLEANUP(rv); 5710 5711 } 5712 } else { 5713 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 5714 "No slices to sync\n"))); 5715 } 5716 if (curr_ltslice != NULL) { 5717 for (lt_id = 0; lt_id < stage_fc->tcam_slices; lt_id++) { 5718 rv = _field_lt_slice_sync(unit, (curr_ltslice + lt_id)); 5719 BCM_IF_ERROR_CLEANUP(rv); 5720 } 5721 } else { 5722 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 5723 "No LT slices to sync\n"))); 5724 } 5725 } 5726 5727 TLV_CREATE(_bcmFieldInternalGroupCount, 5728 _bcmFieldInternalVariable, 0, &tlv); 5729 tlv->value = &group_count; 5730 TLV_WRITE(unit, tlv, ptr, pos); 5731 5732 fg = fc->groups; 5733 while (fg != NULL) { 5734 if (fg->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 5735 rv = _field_group_sync(unit,fg); 5736 if (fg->em_mode == _FieldExactMatchMode320) { 5737 parts_count = 2; 5738 } else { 5739 parts_count = 1; 5740 } 5741 BCM_IF_ERROR_CLEANUP(rv); 5742 if (fg->group_status.entry_count > 0) { 5743 rv = _field_em_group_entries_sync(unit, fg); 5744 BCM_IF_ERROR_CLEANUP(rv); 5745 } 5746 for (i = 0; i < (fg->lt_grp_status.entry_count); i++) { 5747 if (fg->lt_entry_arr[i] == NULL) { 5748 continue; 5749 } 5750 f_lt_ent = fg->lt_entry_arr[i]; 5751 _field_lt_entry_info_sync(unit, f_lt_ent, parts_count); 5752 } 5753 } 5754 fg = fg->next; 5755 } 5756 5757 rv = _field_presel_entry_sync(unit); 5758 BCM_IF_ERROR_CLEANUP(rv); 5759 } 5760 5761 TLV_CREATE(_bcmFieldInternalEndStageEM, _bcmFieldInternalVariable, 0, &tlv); 5762 TLV_WRITE(unit, tlv, ptr, pos); 5763 5764 5765 cleanup: 5766 FP_UNLOCK(unit); 5767 sal_free(tlv); 5768 return rv; 5769 } 5770 /* 5771 * Function: 5772 * _bcm_field_th_stage_ingress_sync 5773 * 5774 * Purpose: 5775 * Save field module software state to external cache. 5776 * 5777 * Parameters: 5778 * unit - (IN) BCM device number 5779 * fc - (IN) Pointer to device field control structure 5780 * stage_fc - (IN) FP stage control info. 5781 * 5782 * Returns: 5783 * BCM_E_XXX 5784 */ 5785 int 5786 _bcm_field_th_stage_ingress_sync(int unit, 5787 _field_stage_t *stage_fc) 5788 { 5789 uint32 group_count = 0; /* Number of groups */ 5790 uint32 slice_id,pipe_id,lt_id; /* Iterator varaiables */ 5791 struct _field_slice_s *curr_slice; /* Slice information */ 5792 struct _field_lt_slice_s *curr_ltslice; /* LT slice information */ 5793 _field_group_t *fg; /* Group information */ 5794 _field_tlv_t *tlv = NULL; /* TLV data */ 5795 uint8 *scache_ptr = NULL; /* Scache Pointer */ 5796 int num_pipes = 0; /* Number of pipes */ 5797 int size = 0; /* size of scache for IFP */ 5798 int rv = BCM_E_NONE; /* return value */ 5799 _field_control_t *fc; /* Field Control Structure */ 5800 uint32 *position; /* Pointer to scache pos */ 5801 uint32 enum_properties_type = BCM_FIELD_TYPE_ENUM_PROPERTIES; 5802 /* Type for Enum Properties */ 5803 uint32 enum_total_count = _bcmFieldInternalElementCount; 5804 /* Count of Enums */ 5805 uint32 enum_properties[(enum_total_count * 3)]; 5806 /* Enum properties */ 5807 uint32 prop_pos = 0; /* To index Enum Properties array */ 5808 uint32 enum_count = 0; /* Enum index Variable */ 5809 5810 WB_FIELD_CONTROL_GET_WITH_LOCK(fc, scache_ptr, position); 5811 size = fc->scache_pos; 5812 curr_stage_fc = stage_fc; 5813 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5814 num_pipes = 1; 5815 } else if (stage_fc->oper_mode == bcmFieldGroupOperModePipeLocal) { 5816 num_pipes = stage_fc->num_pipes; 5817 } 5818 5819 5820 fg = fc->groups; 5821 while (fg != NULL) { 5822 if (fg->stage_id == _BCM_FIELD_STAGE_INGRESS) { 5823 group_count ++ ; 5824 } 5825 fg = fg->next; 5826 } 5827 5828 /* Sync new enum properties during downgrade */ 5829 5830 if (fc->wb_current_version < BCM_FIELD_WB_DEFAULT_VERSION) { 5831 sal_memcpy(&scache_ptr[*position], &enum_properties_type, 5832 sizeof(uint32)); 5833 *position += sizeof(uint32); 5834 sal_memcpy(&scache_ptr[*position], &enum_total_count, sizeof(uint32)); 5835 *position += sizeof(uint32); 5836 5837 prop_pos = 0; 5838 for (enum_count = 0; enum_count < enum_total_count; enum_count++) { 5839 enum_properties[prop_pos++] = (uint32)static_type_map[enum_count].element; 5840 enum_properties[prop_pos++] = static_type_map[enum_count].size; 5841 enum_properties[prop_pos++] = static_type_map[enum_count].flags; 5842 } 5843 sal_memcpy(&scache_ptr[*position], &enum_properties, 5844 ((3 * sizeof(uint32)) * enum_total_count)); 5845 *position += ((3 * sizeof(uint32)) * enum_total_count); 5846 5847 } 5848 5849 5850 /* Sync _field_control_t structure, 5851 * since this is common to all stages 5852 */ 5853 5854 /* _field_control_t */ 5855 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 5856 "_bcm_field_th_stage_ingress_sync -" 5857 "Syncing _field_control_t " 5858 "from pos = %d\r\n"),unit, 5859 fc->scache_pos)); 5860 rv = _field_control_sync(unit); 5861 BCM_IF_ERROR_CLEANUP(rv); 5862 5863 if (group_count > 0) { 5864 /*_field_stage_t */ 5865 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 5866 "_bcm_field_th_stage_ingress_sync -" 5867 "Syncing _field_stage_t " 5868 "from pos = %d\r\n"),unit, 5869 fc->scache_pos)); 5870 5871 rv = _field_stage_sync(unit,stage_fc); 5872 BCM_IF_ERROR_CLEANUP(rv); 5873 5874 TLV_CREATE(_bcmFieldInternalSlice, 5875 _bcmFieldInternalVariable, 0, &tlv); 5876 TLV_WRITE(unit, tlv, scache_ptr, position); 5877 5878 /* _field_slice_t and _field_lt_slice_t */ 5879 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 5880 "_bcm_field_th_stage_ingress_sync -" 5881 "Syncing _field_slice_t," 5882 "_field_lt_slice_t from pos = %d\r\n"), 5883 unit,fc->scache_pos)); 5884 5885 for (pipe_id = 0; pipe_id < num_pipes; pipe_id++) { 5886 if (!(fc->pipe_map & (1 << pipe_id))) { 5887 continue; 5888 } 5889 curr_slice = stage_fc->slices[pipe_id]; 5890 curr_ltslice = stage_fc->lt_slices[pipe_id]; 5891 if (curr_slice != NULL) { 5892 for (slice_id= 0; slice_id < stage_fc->tcam_slices; slice_id ++) { 5893 rv = _field_slice_sync(unit, (curr_slice + slice_id)); 5894 BCM_IF_ERROR_CLEANUP(rv); 5895 5896 } 5897 } else { 5898 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 5899 "No slices to sync\n"))); 5900 } 5901 if (curr_ltslice != NULL) { 5902 for (lt_id = 0; lt_id < stage_fc->tcam_slices; lt_id++) { 5903 rv = _field_lt_slice_sync(unit, (curr_ltslice + lt_id)); 5904 BCM_IF_ERROR_CLEANUP(rv); 5905 } 5906 } else { 5907 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 5908 "No LT slices to sync\n"))); 5909 } 5910 } 5911 5912 /* _field_group_t */ 5913 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 5914 "_bcm_field_th_stage_ingress_sync -" 5915 "Syncing _field_group_t " 5916 "from pos = %d\r\n"),unit, 5917 fc->scache_pos)); 5918 5919 TLV_CREATE(_bcmFieldInternalGroupCount, 5920 _bcmFieldInternalVariable, 0, &tlv); 5921 tlv->value = &group_count; 5922 TLV_WRITE(unit, tlv, scache_ptr, position); 5923 5924 /* Iterate over the groups linked-list */ 5925 fg = fc->groups; 5926 while (fg != NULL) { 5927 if (fg->stage_id == _BCM_FIELD_STAGE_INGRESS) { 5928 rv = _field_group_sync(unit,fg); 5929 BCM_IF_ERROR_CLEANUP(rv); 5930 } 5931 fg = fg->next; 5932 } 5933 5934 /* _field_entry_t and _field_lt_entry_t */ 5935 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 5936 "_bcm_field_th_stage_ingress_sync -" 5937 "Syncing _field_entry_t," 5938 "_field_lt_entry_t from pos = %d\r\n"), 5939 unit,fc->scache_pos)); 5940 5941 rv = _field_entry_sync(unit); 5942 BCM_IF_ERROR_CLEANUP(rv); 5943 5944 /* _field_presel_entry_t */ 5945 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 5946 "_bcm_field_th_stage_ingress_sync -" 5947 "Syncing _field_presel_entry_t," 5948 "from pos = %d\r\n"), 5949 unit,fc->scache_pos)); 5950 5951 rv = _field_presel_entry_sync(unit); 5952 BCM_IF_ERROR_CLEANUP(rv); 5953 5954 5955 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 5956 "_bcm_field_th_stage_ingress_sync -" 5957 "End of structures sync " 5958 "at pos = %d\r\n"),unit, 5959 fc->scache_pos)); 5960 } 5961 5962 TLV_CREATE(_bcmFieldInternalEndStructIFP, 5963 _bcmFieldInternalVariable, 0, &tlv); 5964 TLV_WRITE(unit, tlv, scache_ptr, position); 5965 5966 5967 size = (fc->scache_pos - size); 5968 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "Final scache_size = %d\n"), 5969 size)); 5970 5971 cleanup: 5972 if (tlv != NULL) { 5973 sal_free(tlv); 5974 tlv = NULL; 5975 } 5976 FP_UNLOCK(unit); 5977 5978 return rv; 5979 } 5980 /* Function: 5981 * _field_wb_stage_class_size 5982 * 5983 * Purpose: 5984 * Calculate size required for IFP Compression section 5985 * 5986 * Parameters: 5987 * uinit - (IN) unit number 5988 * size - (out) Returns the size needed 5989 * 5990 * Returns: 5991 * BCM_E_XXX 5992 */ 5993 int 5994 _field_wb_stage_class_size(int unit, int *size) 5995 { 5996 int num_groups = 0; 5997 int num_entries = 0; 5998 int size_classinfo = 0; 5999 int sum = 0; 6000 6001 num_groups = _FieldClassCount; 6002 num_entries = 16 + 256 + 256 + 256 + 256 + 16 + 16 + 128 + 128; 6003 size_classinfo = 256; 6004 6005 sum = size_classinfo + num_groups * 386 + num_entries * 133; 6006 /* To account for (type and values )of group and entry count */ 6007 sum += (8 + num_groups * 8); 6008 /* Account for 4 pipes */ 6009 *size = _FP_MAX_NUM_PIPES *sum; 6010 return BCM_E_NONE; 6011 } 6012 6013 #define _FP_ENTRY_COUNT 512 6014 #define _FP_SLICE_COUNT 14 6015 #define _FP_EM_ENTRY_COUNT 256000 6016 #define _FP_STAT_COUNT (34 * 1024 * _FP_MAX_NUM_PIPES) 6017 #define _FP_METER_COUNT 6144 6018 #define BITS_PER_BYTE 8 6019 6020 /* Function: 6021 * _field_wb_size_calc 6022 * 6023 * Purpose: 6024 * Calculate size required for IFP WB section 6025 * 6026 * Parameters: 6027 * total_size - (OUT) Total size required for allocation 6028 * fc - (IN) Pointer to device field control structure 6029 * 6030 * Returns: 6031 * BCM_E_XXX 6032 */ 6033 6034 int 6035 _field_wb_size_calc(int unit, uint32* total_size, _field_control_t *fc) 6036 { 6037 6038 int basic_size_slice,basic_size_fc,basic_size_stage,basic_size_ltslice = 0; 6039 /* Basic sizes of structures */ 6040 int basic_size_group,basic_size_entry,basic_size_ltentry = 0; 6041 int basic_size_datafc,basic_size_presel = 0; 6042 /* Basic sizes of structures */ 6043 int size_slice,size_fc,size_stage,size_ltslice,size_presel = 0; 6044 /* Total sizes of structures */ 6045 int size_group,size_entry,size_ltentry,size_datafc = 0; 6046 /* Total sizes of structures */ 6047 int type_slice,type_fc,type_stage,type_ltslice,type_presel = 0; 6048 /* Total size of types of structures */ 6049 int type_group,type_entry,type_ltentry,type_datafc = 0; 6050 /* Total size of types of structures */ 6051 6052 int length_slice,length_fc,length_stage,length_ltslice,length_presel = 0; 6053 /* Total size of length of structures */ 6054 int length_group,length_entry,length_ltentry,length_datafc = 0; 6055 /* Total size of length of structures */ 6056 int total_type = 0, total_length = 0; 6057 int compression_size = 0; 6058 int exactmatch_size = 0; 6059 int enum_size = 0; 6060 int flowtracker_size = 0; 6061 _field_stage_t *stage_fc = NULL; 6062 6063 /* 6064 * This size includes only size of variables which are not arrays or 6065 * pointers in the respective structure. Size for array and pointers 6066 * are calculated in a different way 6067 */ 6068 basic_size_slice = 46; 6069 basic_size_stage = 596 + 64; /* added 64 for presel */ 6070 basic_size_ltslice = 32; 6071 basic_size_group = 108; 6072 basic_size_entry = 47 + 48 + 12 + (20 * 12); 6073 /* 20 actions needs software cache */ 6074 basic_size_ltentry = 28; 6075 basic_size_datafc = 799756; 6076 basic_size_fc = 21 + 264 + (_FP_MAX_NUM_PIPES *_FIELD_MAX_METER_POOLS); 6077 /* added 264 for presel, ifp_meter_in_use */ 6078 basic_size_presel = 36; 6079 6080 size_slice = basic_size_slice + (_FP_ENTRY_COUNT * 4) 6081 + ((_FP_ENTRY_COUNT * 5)/BITS_PER_BYTE) 6082 + (BCM_PBMP_PORT_MAX/BITS_PER_BYTE) + (111 * _FP_MAX_NUM_LT) ; 6083 6084 size_stage = basic_size_stage + ( _FP_MAX_NUM_PIPES *_FIELD_MAX_METER_POOLS 6085 * (13 + ((_FP_ENTRY_COUNT * 2)/BITS_PER_BYTE))) 6086 + (_FIELD_MAX_CNTR_POOLS * (5 + ((_FP_ENTRY_COUNT 6087 * 3)/BITS_PER_BYTE))) 6088 + (_FP_MAX_NUM_PIPES * _FP_SLICE_COUNT * 4) 6089 + (_FP_MAX_NUM_PIPES *_FP_MAX_NUM_LT * 76); 6090 6091 size_ltslice = basic_size_ltslice + (_FP_ENTRY_COUNT * 4); 6092 6093 size_group = basic_size_group + ((BCM_FIELD_QUALIFY_MAX/BITS_PER_BYTE) 6094 + (BCM_FIELD_USER_NUM_UDFS/BITS_PER_BYTE)) 6095 + (BCM_PBMP_PORT_MAX/BITS_PER_BYTE) 6096 + (_FP_MAX_ENTRY_TYPES * _FP_MAX_ENTRY_WIDTH * 10304) 6097 + (_FP_ENTRY_COUNT * 4) + (bcmFieldActionCount/BITS_PER_BYTE) 6098 + (4 *_FIELD_MAX_COUNTER_POOLS) + (111 * _FP_MAX_ENTRY_WIDTH) 6099 + (_FP_ENTRY_COUNT * 4) + (_FP_SLICE_COUNT * 80) ; 6100 6101 size_entry = (basic_size_entry + ((BCM_PBMP_PORT_MAX/BITS_PER_BYTE) * 2) 6102 + (5 * _FP_POLICER_LEVEL_COUNT)); 6103 6104 size_ltentry = basic_size_ltentry; 6105 6106 size_datafc = basic_size_datafc + (_FP_DATA_ETHERTYPE_MAX * 16) 6107 + (_FP_DATA_IP_PROTOCOL_MAX * 21); 6108 6109 size_fc = basic_size_fc + (10 * BCM_FIELD_USER_NUM_UDFS) 6110 + (_FP_MAX_NUM_LT * 4) 6111 + ((_FP_METER_COUNT * 97) + (20 * _FP_STAT_COUNT)) 6112 /* policer and stats hash - 34k stats per pipe*/ 6113 + (8 + (44 * 1)); 6114 /* Size for one hint */ 6115 6116 size_presel = basic_size_presel + (BCM_FIELD_QUALIFY_MAX/BITS_PER_BYTE) 6117 + (_SHR_PBMP_WORD_MAX * 4); 6118 6119 /* Currently Tomahawk has one hint added. 6120 * Total size required for hints 6121 * as per max limit calculation is (1024 * (8 + (40 * 256))) 6122 * i.e 1024 hint structures and 256 hints per structure 6123 */ 6124 6125 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "slice size = %d\n"), 6126 (_FP_SLICE_COUNT *size_slice))); 6127 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "lt slice size = %d\n"), 6128 (_FP_SLICE_COUNT * size_ltslice))); 6129 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "stage size = %d\n"), 6130 size_stage)); 6131 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "group size = %d\n"), 6132 (_FP_MAX_NUM_LT * _FP_MAX_NUM_PIPES * size_group))); 6133 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "entry size = %d\n"), 6134 (_FP_SLICE_COUNT * _FP_ENTRY_COUNT * _FP_MAX_NUM_PIPES 6135 * size_entry))); 6136 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "ltentry size = %d\n"), 6137 (_FP_SLICE_COUNT * _FP_MAX_NUM_LT * _FP_MAX_NUM_PIPES 6138 * size_ltentry))); 6139 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "fc size = %d\n"),size_fc)); 6140 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "datafc size = %d\n"), 6141 size_datafc)); 6142 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "presel size = %d\n"), 6143 BCM_FIELD_PRESEL_SEL_MAX * size_presel)); 6144 6145 *total_size = size_fc + size_datafc + size_stage + (_FP_SLICE_COUNT 6146 * (size_slice + size_ltslice)) 6147 + (_FP_MAX_NUM_LT * _FP_MAX_NUM_PIPES * size_group) 6148 + (_FP_SLICE_COUNT * _FP_MAX_NUM_LT * 6149 _FP_MAX_NUM_PIPES * size_ltentry) 6150 + (_FP_SLICE_COUNT * _FP_ENTRY_COUNT * 6151 _FP_MAX_NUM_PIPES * size_entry) 6152 + (BCM_FIELD_PRESEL_SEL_MAX * size_presel); 6153 6154 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "total value = %d\n"), 6155 *total_size)); 6156 6157 6158 type_fc = 64 + (13 * 256) + 16 + 4; /* added 16 for presel */ 6159 type_datafc = 23 + (10 *512); 6160 type_stage = 48 + 8; /* added 8 for presel */ 6161 type_slice = 50; 6162 type_ltslice = 10; 6163 type_group = 22 + 9 + (3 *12) + 4; 6164 type_ltentry = 7; 6165 type_entry = 25; 6166 type_presel = 44; 6167 total_type = type_fc + type_datafc + type_stage + (_FP_SLICE_COUNT 6168 * (type_slice + type_ltslice)) 6169 + (_FP_MAX_NUM_LT * _FP_MAX_NUM_PIPES * type_group) 6170 + (_FP_SLICE_COUNT * _FP_MAX_NUM_LT * 6171 _FP_MAX_NUM_PIPES * type_ltentry) 6172 + (_FP_SLICE_COUNT * _FP_ENTRY_COUNT * 6173 _FP_MAX_NUM_PIPES * type_entry) 6174 + (type_presel); 6175 6176 total_type = total_type * 4; 6177 6178 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "total type = %d\n"), 6179 total_type)); 6180 6181 6182 length_slice = 32 *10; 6183 length_fc = 8; /* added 8 for presel */ 6184 length_stage = 4; /* added 4 for presel */ 6185 length_datafc= length_stage = length_ltslice = length_entry= 0; 6186 length_ltentry = 2; 6187 length_group = 10; 6188 length_presel = 4; 6189 6190 total_length = length_fc + length_datafc + length_stage + (_FP_SLICE_COUNT 6191 * (length_slice + length_ltslice)) 6192 + (_FP_MAX_NUM_LT * _FP_MAX_NUM_PIPES * length_group) 6193 + (_FP_SLICE_COUNT * _FP_MAX_NUM_LT * 6194 _FP_MAX_NUM_PIPES * length_ltentry) 6195 + (_FP_SLICE_COUNT * _FP_ENTRY_COUNT * 6196 _FP_MAX_NUM_PIPES * length_entry) 6197 + length_presel; 6198 6199 total_length = total_length * 4; 6200 6201 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "total length = %d\n"), 6202 total_length)); 6203 6204 if (soc_feature(unit, soc_feature_field_compression)) { 6205 _field_wb_stage_class_size(unit, &compression_size); 6206 } 6207 6208 if (soc_feature(unit, soc_feature_field_exact_match_support)) { 6209 /* Exactmatch has 64k entries per pipe 6210 * and each entry has at max 5 attr 6211 */ 6212 exactmatch_size = size_stage + sizeof(int) * 5 * _FP_EM_ENTRY_COUNT; 6213 if (soc_feature(unit, soc_feature_td3_style_fp)) { 6214 SOC_IF_ERROR_RETURN(_field_stage_control_get(unit, _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 6215 /* bitmap for maximum possible number of entries of EM and pipe pbm(16 bits) */ 6216 exactmatch_size += (SHR_BITALLOCSIZE(stage_fc->tcam_sz + 16) + \ 6217 sizeof(_bcm_field_internal_element_t) + \ 6218 sizeof(uint32)) * _FP_EM_NUM_WB_SUPPORTED_ACTIONS; 6219 } 6220 } 6221 6222 #if defined(BCM_FLOWTRACKER_SUPPORT) 6223 if (soc_feature(unit, soc_feature_field_flowtracker_support)) { 6224 /* Flowtracker has 2k entries and following fields are saved per entry. */ 6225 /* eid, prio, flags (2 for DW), slice Idx, action_count, 2 * field actions */ 6226 flowtracker_size = size_stage + sizeof(int) * (6 + 3*2) * 2048; 6227 } 6228 #endif 6229 6230 enum_size = (_bcmFieldInternalElementCount * 4 * 3); 6231 /* 4 bytes each for 3 properties of enum */ 6232 6233 *total_size = *total_size + total_type + total_length + compression_size 6234 + enum_size + exactmatch_size + flowtracker_size; 6235 6236 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, "total value = %d\n"), 6237 *total_size)); 6238 6239 6240 return BCM_E_NONE; 6241 6242 } 6243 6244 /* Function: 6245 * _bcm_field_scache_th_pointer_realloc 6246 * 6247 * Purpose: 6248 * Initialize scache pointers for warmboot 6249 * 6250 * Parameters: 6251 * unit - (IN) BCM device number 6252 * fc - (IN) Pointer to device field control structure 6253 * 6254 * Returns: 6255 * BCM_E_XXX 6256 */ 6257 6258 int 6259 _bcm_field_scache_th_pointer_realloc(int unit, _field_control_t *fc) 6260 { 6261 int stable_size; /* Total scache size */ 6262 int rv; /* Return variable */ 6263 uint32 alloc_get; /* Allocated size */ 6264 soc_scache_handle_t handle; /* scache handle */ 6265 6266 if ((NULL != fc->scache_ptr[_FIELD_SCACHE_PART_0]) || 6267 (NULL != fc->scache_ptr[_FIELD_SCACHE_PART_1])) { 6268 6269 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 6270 SOC_SCACHE_HANDLE_SET(handle, unit, BCM_MODULE_FIELD, 6271 _FIELD_SCACHE_PART_0); 6272 if ((stable_size > 0) && !SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 6273 6274 /* Partition 0 size validation */ 6275 6276 /* Get the pointer for the Level 2 cache */ 6277 rv = soc_scache_ptr_get(unit, handle, 6278 &(fc->scache_ptr[_FIELD_SCACHE_PART_0]), 6279 &alloc_get); 6280 if (BCM_FAILURE(rv)) { 6281 return rv; 6282 } else if (alloc_get != (fc->scache_size[_FIELD_SCACHE_PART_0] 6283 + SOC_WB_SCACHE_CONTROL_SIZE)) { 6284 /* Allocated size is less than expected size */ 6285 SOC_IF_ERROR_RETURN 6286 (soc_scache_realloc(unit, handle, 6287 (fc->scache_size[_FIELD_SCACHE_PART_0] - (alloc_get 6288 - SOC_WB_SCACHE_CONTROL_SIZE)))); 6289 rv = soc_scache_ptr_get(unit, handle, 6290 &(fc->scache_ptr[_FIELD_SCACHE_PART_0]), 6291 &alloc_get); 6292 if (BCM_FAILURE(rv)) { 6293 return rv; 6294 } else if (alloc_get != 6295 (fc->scache_size[_FIELD_SCACHE_PART_0] + 6296 SOC_WB_SCACHE_CONTROL_SIZE)) { 6297 /* Expected size doesn't match retrieved size */ 6298 return BCM_E_INTERNAL; 6299 } else if (NULL == fc->scache_ptr[_FIELD_SCACHE_PART_0]) { 6300 return BCM_E_MEMORY; 6301 } 6302 } else if (NULL == fc->scache_ptr[_FIELD_SCACHE_PART_0]) { 6303 return BCM_E_MEMORY; 6304 } 6305 6306 } 6307 } 6308 return BCM_E_NONE; 6309 } 6310 6311 /* Function: 6312 * _bcm_field_scache_th_pointer_init 6313 * 6314 * Purpose: 6315 * Initialize scache pointers for warmboot 6316 * 6317 * Parameters: 6318 * unit - (IN) BCM device number 6319 * fc - (IN) Pointer to device field control structure 6320 * 6321 * Returns: 6322 * BCM_E_XXX 6323 */ 6324 6325 int 6326 _bcm_field_scache_th_pointer_init(int unit, _field_control_t *fc) 6327 { 6328 int stable_size; /* Total scache size */ 6329 int rv; /* Return variable */ 6330 uint32 alloc_get; /* Allocated size */ 6331 soc_scache_handle_t handle; /* scache handle */ 6332 uint32 ifp_calculated_size; 6333 /* total scache size for IFP */ 6334 uint32 scache_size = 0; /* total scache size */ 6335 6336 if ((NULL == fc->scache_ptr[_FIELD_SCACHE_PART_0]) || 6337 (NULL == fc->scache_ptr[_FIELD_SCACHE_PART_1])) { 6338 6339 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 6340 SOC_SCACHE_HANDLE_SET(handle, unit, BCM_MODULE_FIELD, 6341 _FIELD_SCACHE_PART_0); 6342 if ((stable_size > 0) && !SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)) { 6343 6344 scache_size = soc_property_get(unit, 6345 spn_FIELD_SCACHE_SIZE,0); 6346 if (scache_size == 0) { 6347 BCM_IF_ERROR_RETURN(_field_wb_size_calc(unit, 6348 &ifp_calculated_size,fc)); 6349 /* value should be a multiple of 1024 */ 6350 ifp_calculated_size = (((ifp_calculated_size + 1023) / 1024) 6351 * 1024); 6352 scache_size = ((294 * 1024) + (ifp_calculated_size)); 6353 /* 6354 * Scache size is increased to sync the bitmap of slice 6355 * indexes that is used to store the slice indexes of the 6356 * disabled entries. 6357 * This is added from WB version BCM_FIELD_WB_VERSION_1_27 6358 * The size is to accomodate both efp and vfp assuming each 6359 * stage have 1024 slice indexes at max. 6360 * so size is bitmap will be 6361 * ((1024/32)bits * 4)bytes*2(efp and vfp)*_FP_MAX_NUM_PIPES 6362 * (((1024/32)*4*2 * _FP_MAX_NUM_PIPES)) 6363 */ 6364 scache_size += ((1024/32)*4 *2*_FP_MAX_NUM_PIPES); 6365 } 6366 6367 fc->scache_size[_FIELD_SCACHE_PART_0] = scache_size; 6368 6369 fc->scache_size[_FIELD_SCACHE_PART_1] = 20 * 1024; 6370 6371 /* Partition 0 size validation */ 6372 6373 /* Get the pointer for the Level 2 cache */ 6374 rv = soc_scache_ptr_get(unit, handle, 6375 &(fc->scache_ptr[_FIELD_SCACHE_PART_0]), 6376 &alloc_get); 6377 if (!SOC_WARM_BOOT(unit) && (SOC_E_NOT_FOUND == rv)) { 6378 /* Not yet allocated in Cold Boot */ 6379 SOC_IF_ERROR_RETURN 6380 (soc_scache_alloc(unit, handle, 6381 (fc->scache_size[_FIELD_SCACHE_PART_0] 6382 + SOC_WB_SCACHE_CONTROL_SIZE))); 6383 rv = soc_scache_ptr_get(unit, handle, 6384 &(fc->scache_ptr[_FIELD_SCACHE_PART_0]), 6385 &alloc_get); 6386 } 6387 6388 /* Fetch WB Recovered Version */ 6389 if (SOC_WARM_BOOT(unit)) { 6390 sal_memcpy(&(fc->wb_recovered_version), 6391 fc->scache_ptr[_FIELD_SCACHE_PART_0], 6392 sizeof(fc->wb_recovered_version)); 6393 } 6394 6395 6396 if (BCM_FAILURE(rv)) { 6397 return rv; 6398 } else if (alloc_get != (fc->scache_size[_FIELD_SCACHE_PART_0] 6399 + SOC_WB_SCACHE_CONTROL_SIZE)) { 6400 if (!SOC_WARM_BOOT(unit)) { 6401 /* Allocated size is greater than expected size */ 6402 return BCM_E_INTERNAL; 6403 } 6404 } else if (NULL == fc->scache_ptr[_FIELD_SCACHE_PART_0]) { 6405 return BCM_E_MEMORY; 6406 } 6407 6408 /* Partition 1 size validation*/ 6409 6410 SOC_SCACHE_HANDLE_SET(handle, unit, BCM_MODULE_FIELD, 1); 6411 SOC_SCACHE_MODULE_MAX_PARTITIONS_SET(unit, BCM_MODULE_FIELD, 1); 6412 6413 /* Get the pointer for the Level 2 cache */ 6414 rv = soc_scache_ptr_get(unit, handle, 6415 &(fc->scache_ptr[_FIELD_SCACHE_PART_1]), 6416 &alloc_get); 6417 if (!SOC_WARM_BOOT(unit) && (SOC_E_NOT_FOUND == rv)) { 6418 /* Not yet allocated in Cold Boot */ 6419 SOC_IF_ERROR_RETURN 6420 (soc_scache_alloc(unit, handle, 6421 (fc->scache_size[_FIELD_SCACHE_PART_1] 6422 + SOC_WB_SCACHE_CONTROL_SIZE))); 6423 rv = soc_scache_ptr_get(unit, handle, 6424 &(fc->scache_ptr[_FIELD_SCACHE_PART_1]), 6425 &alloc_get); 6426 } 6427 6428 if (BCM_FAILURE(rv)) { 6429 return rv; 6430 } else if (alloc_get != (fc->scache_size[_FIELD_SCACHE_PART_1] 6431 + SOC_WB_SCACHE_CONTROL_SIZE)) { 6432 /* Expected size doesn't match retrieved size */ 6433 return BCM_E_INTERNAL; 6434 } else if (NULL == fc->scache_ptr[_FIELD_SCACHE_PART_1]) { 6435 return BCM_E_MEMORY; 6436 } 6437 6438 } 6439 } 6440 return BCM_E_NONE; 6441 } 6442 6443 #define TLV_INIT(tlv) \ 6444 do { \ 6445 tlv.type = -1; \ 6446 tlv.length = 0; \ 6447 if (NULL != tlv.value) { \ 6448 sal_free(tlv.value); \ 6449 } \ 6450 tlv.value = NULL; \ 6451 } while(0); 6452 6453 /* Function: 6454 * _field_policer_recover 6455 * 6456 * Purpose: 6457 * recover _field_policer_t structure 6458 * 6459 * Paramaters: 6460 * unit - (IN) BCM device number 6461 * tlv - (IN) TLV structure for field 6462 * Returns: 6463 * BCM_E_XXX 6464 */ 6465 6466 int 6467 _field_policer_recover(int unit, _field_tlv_t *tlv) 6468 { 6469 6470 int type_pos = 0; /* position of type */ 6471 int i = 0; /* local variable for loops */ 6472 int num_instances = 0; /* number of instances */ 6473 int num_types = 0; /* Number of types */ 6474 _field_tlv_t tlv2; /* TLV structure */ 6475 uint32 *type; /* Elem type */ 6476 uint8 *scache_ptr; /* Scache pointer */ 6477 uint32 *position; /* Scache position */ 6478 _field_policer_t *f_pl = NULL; /* Field policer structure */ 6479 _field_control_t *fc; /* Field control structure. */ 6480 int rv = 0; 6481 6482 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 6483 tlv2.value = NULL; 6484 TLV_INIT(tlv2); 6485 type = (uint32 *)tlv->value; 6486 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 6487 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 6488 _FP_WB_TLV_TYPE_SHIFT); 6489 6490 for (i = 0; i < num_instances; i++) { 6491 6492 _FP_XGS3_ALLOC(f_pl, sizeof (_field_policer_t), "Field policer"); 6493 if (NULL == f_pl) { 6494 return (BCM_E_MEMORY); 6495 } 6496 type_pos = 0; 6497 6498 while ((tlv2.type != _bcmFieldInternalEndStructPolicer) 6499 && (type_pos != num_types)) { 6500 TLV_INIT(tlv2); 6501 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 6502 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 6503 _FP_WB_TLV_BASIC_TYPE_SHIFT); 6504 rv = tlv_read(unit, &tlv2, scache_ptr, position); 6505 BCM_IF_ERROR_CLEANUP(rv); 6506 6507 switch (tlv2.type) { 6508 6509 case _bcmFieldInternalPolicerPid: 6510 f_pl->pid = *(bcm_policer_t *)tlv2.value; 6511 break; 6512 case _bcmFieldInternalPolicerCfgFlags: 6513 f_pl->cfg.flags= *(uint32 *)tlv2.value; 6514 break; 6515 6516 case _bcmFieldInternalPolicerCfgMode: 6517 f_pl->cfg.mode = *(bcm_policer_mode_t *)tlv2.value; 6518 break; 6519 6520 case _bcmFieldInternalPolicerCfgCkbitsSec: 6521 f_pl->cfg.ckbits_sec = *(uint32 *)tlv2.value; 6522 break; 6523 6524 case _bcmFieldInternalPolicerCfgMaxCkbitsSec: 6525 f_pl->cfg.max_ckbits_sec = *(uint32 *)tlv2.value; 6526 break; 6527 6528 6529 case _bcmFieldInternalPolicerCfgCkbitsBurst: 6530 f_pl->cfg.ckbits_burst = *(uint32 *)tlv2.value; 6531 break; 6532 6533 case _bcmFieldInternalPolicerCfgPkbitsSec: 6534 f_pl->cfg.pkbits_sec = *(uint32 *)tlv2.value; 6535 break; 6536 6537 case _bcmFieldInternalPolicerCfgMaxPkbitsSec: 6538 f_pl->cfg.max_pkbits_sec = *(uint32 *)tlv2.value; 6539 break; 6540 6541 case _bcmFieldInternalPolicerCfgPkbitsBurst : 6542 f_pl->cfg.pkbits_burst = *(uint32 *)tlv2.value; 6543 break; 6544 6545 case _bcmFieldInternalPolicerCfgKbitsCurrent: 6546 f_pl->cfg.kbits_current = *(uint32 *)tlv2.value; 6547 break; 6548 6549 case _bcmFieldInternalPolicerCfgActionId: 6550 f_pl->cfg.action_id = *(uint32 *)tlv2.value; 6551 break; 6552 6553 6554 case _bcmFieldInternalPolicerCfgSharingMode: 6555 f_pl->cfg.action_id = *(uint32 *)tlv2.value; 6556 break; 6557 6558 case _bcmFieldInternalPolicerCfgEntropyId: 6559 f_pl->cfg.entropy_id = *(uint32 *)tlv2.value; 6560 break; 6561 6562 case _bcmFieldInternalPolicerCfgPoolId: 6563 f_pl->cfg.pool_id = *(bcm_policer_pool_t *)tlv2.value; 6564 break; 6565 6566 case _bcmFieldInternalPolicerSwRefCount: 6567 f_pl->sw_ref_count = *(uint16 *)tlv2.value; 6568 break; 6569 6570 case _bcmFieldInternalPolicerHwRefCount: 6571 f_pl->hw_ref_count = *(uint16 *)tlv2.value; 6572 break; 6573 6574 case _bcmFieldInternalPolicerLevel: 6575 f_pl->level = *(uint8 *)tlv2.value; 6576 break; 6577 6578 case _bcmFieldInternalPolicerPoolIndex: 6579 f_pl->pool_index = *(int8 *)tlv2.value; 6580 break; 6581 6582 case _bcmFieldInternalPolicerHwIndex: 6583 f_pl->hw_index = *(int *)tlv2.value; 6584 break; 6585 6586 case _bcmFieldInternalPolicerHwFlags: 6587 f_pl->hw_flags = *(uint32 *)tlv2.value; 6588 break; 6589 6590 case _bcmFieldInternalPolicerStageId: 6591 f_pl->stage_id = *(_field_stage_id_t *)tlv2.value; 6592 break; 6593 6594 case _bcmFieldInternalEndStructPolicer: 6595 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_POLICER) { 6596 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 6597 "END MARKER CHECK FAILED : POLICER\n"))); 6598 rv = BCM_E_INTERNAL; 6599 goto cleanup; 6600 } 6601 break; 6602 default : 6603 break; 6604 } 6605 type_pos++; 6606 } 6607 6608 TLV_INIT(tlv2); 6609 6610 _FP_HASH_INSERT(fc->policer_hash, f_pl, 6611 ((f_pl->pid) & _FP_HASH_INDEX_MASK(fc))); 6612 f_pl = NULL; 6613 } 6614 6615 return BCM_E_NONE; 6616 6617 cleanup: 6618 TLV_INIT(tlv2); 6619 if (f_pl != NULL) { 6620 sal_free(f_pl); 6621 f_pl = NULL; 6622 } 6623 return rv; 6624 6625 6626 } 6627 6628 6629 /* Function: 6630 * 6631 * _field_presel_entry_recover 6632 * 6633 * Purpose: 6634 * recover _field_stat_t structure 6635 * 6636 * Paramaters: 6637 * unit - (IN) BCM device number 6638 * tlv - (IN) TLV structure for field 6639 * new_fg - (IN) Array of groups in order of gids. 6640 * total_qual_count - (IN) qual count in image used to sync 6641 * 6642 * Returns: 6643 * BCM_E_XXX 6644 */ 6645 6646 int 6647 _field_presel_entry_recover(int unit, _field_tlv_t *tlv, 6648 _field_group_t *new_fg, int total_qual_count) 6649 { 6650 6651 int type_pos = 0; /* position of type */ 6652 int i = 0; /* local variable for loops */ 6653 int num_instances = 0; /* number of instances */ 6654 int num_types = 0; /* Number of types */ 6655 _field_tlv_t tlv2 ; /* TLV structure */ 6656 uint32 *type; /* Elem type */ 6657 uint8 *scache_ptr; /* Scahce pointer */ 6658 uint32 *position; /* Scache position */ 6659 _field_presel_entry_t *f_pr = NULL; /* Field Presel Structure */ 6660 _field_control_t *fc; /* Field control structure. */ 6661 int rv = 0; /* Return variable */ 6662 _field_action_t *action = NULL; /* Field Action Structure */ 6663 int entry_idx = -1; /* Field Presel Tcam Index */ 6664 soc_mem_t fp_presel_mem = INVALIDm; /* Presel TCAM memeory */ 6665 char *fp_presel_buf[_FP_MAX_NUM_PIPES] = {0}; 6666 /* Buffer to read the 6667 * IFP_LOGICAL_TABLE_SELECT_DATA_ONLY 6668 * table 6669 */ 6670 int index_min = -1, index_max = -1; /* Min and max index Tcam memory */ 6671 int pipe = 0; /* Pipe variable */ 6672 uint32 *e_buf = NULL; /* Buffer for corresponding entry */ 6673 int temp = 0; /* Temporary Variable */ 6674 int parts_count = 0 ; /* Number of parts of Entry */ 6675 _field_group_t *fg = NULL; /* Field Group Structure */ 6676 _field_presel_entry_t *f_presel_p; /* Field Presel Structure */ 6677 _field_lt_slice_t *f_lt; /* Field Presel Structure */ 6678 int pri_tcam_idx = 0; /* Primary Tcam Index */ 6679 int part_index = 0; /* Entry Part Index */ 6680 int slice_num = 0; /* Slice Number */ 6681 int id =0,idx =0; /* Loop Variables */ 6682 uint32 flags = 0; /* Entry Part Flags */ 6683 _field_group_t *temp_fg= NULL; /* temp pointer to group list */ 6684 soc_profile_mem_t *keygen_profile = NULL; 6685 int added_qual_cnt =0; 6686 bcm_field_qset_t temp_qset; 6687 6688 tlv2.value = NULL; 6689 TLV_INIT(tlv2); 6690 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 6691 6692 type = (uint32 *)tlv->value; 6693 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 6694 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 6695 _FP_WB_TLV_TYPE_SHIFT); 6696 6697 for (pipe = 0; pipe < curr_stage_fc->num_pipes; pipe++) { 6698 if (!(fc->pipe_map & (1 << pipe))) { 6699 continue; 6700 } 6701 if (curr_stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 6702 if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 6703 fp_presel_mem = IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm; 6704 } else if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 6705 fp_presel_mem = EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm; 6706 } else if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_FLOWTRACKER) { 6707 fp_presel_mem = BSK_FTFP_LTS_LOGICAL_TBL_SEL_TCAMm; 6708 } else { 6709 return BCM_E_INTERNAL; 6710 } 6711 } else { 6712 if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 6713 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 6714 IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm, 6715 pipe, &fp_presel_mem)); 6716 } else if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 6717 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 6718 EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm, 6719 pipe, &fp_presel_mem)); 6720 } else { 6721 return BCM_E_INTERNAL; 6722 } 6723 } 6724 /* coverity[var_deref_op] */ 6725 fp_presel_buf[pipe] = soc_cm_salloc(unit, 6726 SOC_MEM_TABLE_BYTES(unit, fp_presel_mem), 6727 "FP POLICY TABLE buffer"); 6728 if (NULL == fp_presel_buf[pipe]) { 6729 rv = BCM_E_MEMORY; 6730 goto cleanup; 6731 } 6732 6733 index_min = soc_mem_index_min(unit, fp_presel_mem); 6734 index_max = soc_mem_index_max(unit, fp_presel_mem); 6735 rv = soc_mem_read_range(unit, fp_presel_mem, MEM_BLOCK_ALL, 6736 index_min, index_max, fp_presel_buf[pipe]); 6737 BCM_IF_ERROR_CLEANUP(rv); 6738 6739 } 6740 6741 for (i = 0; i < num_instances; i++) { 6742 6743 f_pr = NULL; 6744 _FP_XGS3_ALLOC(f_pr, sizeof (_field_presel_entry_t), 6745 "Field Presel entity"); 6746 if (NULL == f_pr) { 6747 return (BCM_E_MEMORY); 6748 } 6749 type_pos = 0; 6750 6751 while ((tlv2.type != _bcmFieldInternalEndStructPreselInfo) 6752 && (type_pos != num_types)) { 6753 TLV_INIT(tlv2); 6754 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 6755 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 6756 _FP_WB_TLV_BASIC_TYPE_SHIFT); 6757 /* coverity[no_write_call : FALSE] */ 6758 rv = tlv_read(unit, &tlv2, scache_ptr, position); 6759 BCM_IF_ERROR_CLEANUP(rv); 6760 6761 switch (tlv2.type) { 6762 case _bcmFieldInternalPreselId: 6763 f_pr->presel_id = *(uint32 *)tlv2.value; 6764 break; 6765 case _bcmFieldInternalPreselFlags: 6766 f_pr->flags = *(uint32 *)tlv2.value; 6767 break; 6768 case _bcmFieldInternalPreselPri: 6769 f_pr->priority = *(int *)tlv2.value; 6770 break; 6771 case _bcmFieldInternalPreselHwIndex: 6772 if (f_pr->group != NULL) { 6773 uint32 enable = 0; 6774 soc_mem_t lt_data_mem = INVALIDm; 6775 6776 f_pr->hw_index = *(int *)tlv2.value; 6777 pipe = f_pr->group->instance; 6778 rv = _bcm_field_presel_entry_tcam_idx_get(unit, 6779 f_pr, 6780 f_pr->lt_fs, 6781 &entry_idx); 6782 BCM_IF_ERROR_CLEANUP(rv); 6783 if (curr_stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 6784 if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 6785 fp_presel_mem = IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm; 6786 lt_data_mem = IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm; 6787 } else if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 6788 fp_presel_mem = EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm; 6789 lt_data_mem = EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm; 6790 } else if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_FLOWTRACKER) { 6791 fp_presel_mem = BSK_FTFP_LTS_LOGICAL_TBL_SEL_TCAMm; 6792 } else { 6793 return BCM_E_INTERNAL; 6794 } 6795 } else { 6796 if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 6797 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 6798 IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm, 6799 pipe, &fp_presel_mem)); 6800 lt_data_mem = IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm; 6801 } else if (curr_stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 6802 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 6803 EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm, 6804 pipe, &fp_presel_mem)); 6805 lt_data_mem = EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm; 6806 } else { 6807 return BCM_E_INTERNAL; 6808 } 6809 lt_data_mem = SOC_MEM_UNIQUE_ACC(unit, lt_data_mem)[pipe]; 6810 } 6811 /* Get memory for tcam index */ 6812 e_buf = soc_mem_table_idx_to_pointer( 6813 unit, 6814 fp_presel_mem, 6815 uint32 *, 6816 fp_presel_buf[pipe], 6817 entry_idx); 6818 6819 /* Allocate memory for TCAM Key and Mask. */ 6820 rv = _bcm_field_th_presel_tcam_key_mask_get(unit, 6821 curr_stage_fc, 6822 f_pr->group->instance, 6823 f_pr, 6824 &f_pr->lt_tcam); 6825 BCM_IF_ERROR_CLEANUP(rv); 6826 soc_mem_field_get(unit,fp_presel_mem, 6827 e_buf, KEYf, f_pr->lt_tcam.key); 6828 soc_mem_field_get(unit,fp_presel_mem, 6829 e_buf, MASKf, f_pr->lt_tcam.mask); 6830 6831 6832 /* Recover 'GroupLookupDisable' action if 'ENABLEf' is 0. */ 6833 if (lt_data_mem != INVALIDm) { 6834 uint32 ent[SOC_MAX_MEM_FIELD_WORDS]; /* to hold the mem entry */ 6835 6836 rv = soc_mem_read(unit, lt_data_mem, MEM_BLOCK_ANY, 6837 entry_idx, ent); 6838 if (BCM_FAILURE(rv)) { 6839 return rv; 6840 } 6841 soc_mem_field_get(unit, lt_data_mem, ent, ENABLEf, &enable); 6842 if (enable == 0) { 6843 action = NULL; 6844 _FP_XGS3_ALLOC(action, sizeof(_field_action_t), 6845 "actions"); 6846 if (action == NULL) { 6847 rv = BCM_E_MEMORY; 6848 goto cleanup; 6849 } 6850 action->action = bcmFieldActionGroupLookupDisable; 6851 f_pr->actions = action; 6852 } 6853 } 6854 } 6855 break; 6856 case _bcmFieldInternalPreselSliceIndex: 6857 f_pr->slice_index = *(int *)tlv2.value; 6858 break; 6859 case _bcmFieldInternalPreselEntrySlice: 6860 if (tlv2.length == 1) { 6861 temp = *(uint8 *)tlv2.value; 6862 if (f_pr->group != NULL) { 6863 f_pr->lt_fs = 6864 &curr_stage_fc->lt_slices[f_pr->group->instance][temp]; 6865 } 6866 } 6867 break; 6868 case _bcmFieldInternalPreselEntryGroup: 6869 temp = *(int *)tlv2.value; 6870 if (temp != -1) { 6871 temp_fg = new_fg; 6872 while (temp_fg != NULL) { 6873 if(temp_fg->gid == temp) { 6874 break; 6875 } 6876 temp_fg = temp_fg->next; 6877 } 6878 6879 if (temp_fg == NULL) { 6880 rv = BCM_E_INTERNAL; 6881 goto cleanup; 6882 } 6883 6884 f_pr->group = temp_fg; 6885 } 6886 break; 6887 case _bcmFieldInternalPreselKeySize: 6888 f_pr->lt_tcam.key_size = *(uint16 *)tlv2.value; 6889 break; 6890 case _bcmFieldInternalPreselQset: 6891 if (downgrade[unit] == TRUE) { 6892 sal_memcpy(f_pr->p_qset.w, tlv2.value, 6893 ((recovery_type_map[unit][tlv2.type].size) * 6894 _SHR_BITDCLSIZE(BCM_FIELD_QUALIFY_MAX))); 6895 if ((total_qual_count != -1) && 6896 (bcmFieldQualifyCount < total_qual_count)) { 6897 BCM_FIELD_QSET_INIT(temp_qset); 6898 /* copy the internal qids from recovered qset 6899 * to temp qset 6900 */ 6901 SHR_BITCOPY_RANGE(temp_qset.w, 0,f_pr->p_qset.w, 6902 (total_qual_count), 6903 (_bcmFieldQualifyCount-bcmFieldQualifyCount)); 6904 /* copy the internal qids that are stored from 6905 * recovered qset to the current qset 6906 */ 6907 SHR_BITCOPY_RANGE(f_pr->p_qset.w, 6908 (bcmFieldQualifyCount), 6909 temp_qset.w, 0, 6910 (_bcmFieldQualifyCount-bcmFieldQualifyCount)); 6911 } 6912 } else { 6913 sal_memcpy(f_pr->p_qset.w, tlv2.value, 6914 ((recovery_type_map[unit][tlv2.type].size) * tlv2.length)); 6915 /* if the qualifiers are added in the latest code 6916 * when compared to the old image synced, then qset 6917 * recovered should be aligned by unsetting the 6918 * newly added qids and shift the internal qids 6919 * by no of newly added qids 6920 */ 6921 6922 if ((total_qual_count != -1) && 6923 (bcmFieldQualifyCount > total_qual_count)) { 6924 /* get no of new quals added in current version */ 6925 added_qual_cnt = 6926 bcmFieldQualifyCount-total_qual_count; 6927 BCM_FIELD_QSET_INIT(temp_qset); 6928 /* copy the old qualifiers into temporary qset*/ 6929 SHR_BITCOPY_RANGE(temp_qset.w, 0,f_pr->p_qset.w, 6930 (total_qual_count), 6931 (_bcmFieldQualifyCount-total_qual_count)); 6932 /* clear the qids that were added in new qset*/ 6933 SHR_BITCLR_RANGE(f_pr->p_qset.w, 6934 total_qual_count, added_qual_cnt); 6935 /* copy the qids from temp qset 6936 * starting after the current qid count 6937 */ 6938 SHR_BITCOPY_RANGE(f_pr->p_qset.w, 6939 (total_qual_count+added_qual_cnt), 6940 temp_qset.w, 0, 6941 (_bcmFieldQualifyCount-total_qual_count)); 6942 } 6943 } 6944 break; 6945 case _bcmFieldInternalPreselClassAction: 6946 if (tlv2.length == 1) { 6947 _field_action_t *fa; 6948 6949 action = NULL; 6950 _FP_XGS3_ALLOC(action, sizeof(_field_action_t), 6951 "actions"); 6952 if (action == NULL) { 6953 rv = BCM_E_MEMORY; 6954 goto cleanup; 6955 } 6956 action->action = bcmFieldActionGroupClassSet; 6957 action->param[0] = *(uint32 *)tlv2.value; 6958 fa = f_pr->actions; 6959 if (fa == NULL) { 6960 f_pr->actions = action; 6961 } else { 6962 while (fa != NULL) { 6963 if (fa->next == NULL) { 6964 break; 6965 } 6966 fa = fa->next; 6967 } 6968 fa->next = action; 6969 } 6970 } 6971 break; 6972 case _bcmFieldInternalEndStructPreselInfo: 6973 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_PRESEL) { 6974 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 6975 "END MARKER CHECK FAILED : PRESEL\n"))); 6976 rv = BCM_E_INTERNAL; 6977 goto cleanup; 6978 } 6979 break; 6980 case _bcmFieldInternalPreselPbmp: 6981 sal_memcpy(f_pr->mixed_src_class_pbmp.pbits, tlv2.value, 6982 ((recovery_type_map[unit][tlv2.type].size) * tlv2.length)); 6983 break; 6984 default: 6985 break; 6986 } 6987 type_pos++; 6988 } 6989 6990 if (f_pr->group !=NULL) 6991 { 6992 fg = f_pr->group; 6993 /* Get number of entry parts based on group flags. */ 6994 BCM_IF_ERROR_RETURN(_bcm_field_th_lt_entry_tcam_parts_count(unit, 6995 fg->stage_id, 6996 fg->flags, 6997 &parts_count)); 6998 /* Get entry TCAM index given slice number 6999 * and entry offset in slice. 7000 */ 7001 rv = _bcm_field_th_lt_slice_offset_to_tcam_index(unit, 7002 curr_stage_fc, 7003 fg->instance, f_pr->lt_fs->slice_number, 7004 f_pr->hw_index, &pri_tcam_idx); 7005 BCM_IF_ERROR_CLEANUP(rv); 7006 7007 /* Prior to WB version 18, the group flags are not recovered 7008 * hence, the flag need to be set during recovery 7009 */ 7010 if (fc->wb_recovered_version < BCM_FIELD_WB_VERSION_1_18) { 7011 /* set the flag as this group has presel attached */ 7012 fg->flags |= _FP_GROUP_PRESELECTOR_SUPPORT; 7013 } 7014 7015 /* Adjust the presel entry as per the priority. */ 7016 for (id = 0; id < _FP_PRESEL_ENTRIES_MAX_PER_GROUP; id++) { 7017 if (fg->presel_ent_arr[id] == NULL) { 7018 fg->presel_ent_arr[id] = f_pr; 7019 break; 7020 } else { 7021 if (fg->presel_ent_arr[id]->priority < f_pr->priority) { 7022 /* Move down all the entries */ 7023 for (idx = _FP_PRESEL_ENTRIES_MAX_PER_GROUP-1; idx > id; 7024 idx--) { 7025 fg->presel_ent_arr[idx] = fg->presel_ent_arr[idx - 1]; 7026 } 7027 fg->presel_ent_arr[id] = f_pr; 7028 break; 7029 } 7030 } 7031 } 7032 7033 if (parts_count > 1) { 7034 _field_presel_entry_t *p_ent_alloc; 7035 7036 f_presel_p = f_pr; 7037 /* Allocate memory for presel entries for 7038 * double/triple wide modes. 7039 */ 7040 for (idx = 1; idx < parts_count; idx++) { 7041 p_ent_alloc = NULL; 7042 _FP_XGS3_ALLOC(p_ent_alloc, sizeof(_field_presel_entry_t), 7043 "Presel Entry Alloc."); 7044 if (NULL == p_ent_alloc) { 7045 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 7046 "Error: allocation failure for Presel[%d] " 7047 "Parts entry[%d]\n"), 7048 f_pr->presel_id, idx)); 7049 return (BCM_E_MEMORY); 7050 } 7051 /* Copy the base presel entry contents to its 7052 * allocated part entry 7053 */ 7054 sal_memcpy(p_ent_alloc, f_presel_p, 7055 sizeof(_field_presel_entry_t)); 7056 f_presel_p->next = p_ent_alloc; 7057 f_presel_p = p_ent_alloc; 7058 } 7059 } 7060 7061 f_presel_p = f_pr; 7062 keygen_profile = 7063 &curr_stage_fc->keygen_profile[fg->instance].profile; 7064 7065 /* Fill entry primitives. */ 7066 for (idx = 0; (idx < parts_count && f_presel_p != NULL); idx++) { 7067 7068 /* Allocate the Preselector Data Memory and get data*/ 7069 BCM_IF_ERROR_RETURN (_bcm_field_th_presel_mem_data_get( 7070 unit, curr_stage_fc, 7071 fg->instance, 7072 f_presel_p, 7073 &f_presel_p->lt_data)); 7074 flags = 0; 7075 /* Get entry part flags. */ 7076 rv = _bcm_field_th_tcam_part_to_entry_flags(unit, idx, 7077 fg->flags, 7078 &(flags)); 7079 7080 /* Reset primary flags for other parts of entry */ 7081 if (idx > 0) { 7082 f_presel_p->flags &= ~(_FP_ENTRY_PRIMARY); 7083 } 7084 7085 f_presel_p->flags = (f_presel_p->flags | flags); 7086 7087 if (BCM_FAILURE(rv)) { 7088 goto cleanup; 7089 } 7090 7091 /* Update keygen profile reference 7092 * count for each part 7093 */ 7094 /* For WB version prior to 23, the extractors are recovered 7095 * at the end of recovery and hence below code is not 7096 * required for WB version < 24. 7097 */ 7098 if ((fc->wb_recovered_version) >= BCM_FIELD_WB_VERSION_1_24) { 7099 if (fg->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 7100 rv = soc_profile_mem_reference(unit, keygen_profile, 7101 fg->ext_codes[idx].keygen_index, 1); 7102 7103 if (BCM_FAILURE(rv)) { 7104 goto cleanup; 7105 } 7106 } 7107 } 7108 7109 /* Given primary entry TCAM index calculate 7110 * entry part tcam index. 7111 */ 7112 if (0 != idx) { 7113 rv = _bcm_field_th_lt_entry_part_tcam_idx_get(unit, fg, 7114 pri_tcam_idx, 7115 idx, &part_index); 7116 if (BCM_FAILURE(rv)) { 7117 goto cleanup; 7118 } 7119 7120 /* 7121 * Given entry part TCAM index, determine the slice number 7122 * and slice offset index. 7123 */ 7124 rv = _bcm_field_th_lt_tcam_idx_to_slice_offset(unit, 7125 curr_stage_fc, 7126 fg->instance, part_index, &slice_num, 7127 (int *)&f_pr->hw_index); 7128 if (BCM_FAILURE(rv)) { 7129 goto cleanup; 7130 } 7131 f_presel_p->lt_fs = curr_stage_fc->lt_slices[fg->instance] 7132 + slice_num; 7133 } 7134 7135 /* Assign entry to a slice. */ 7136 f_presel_p->lt_fs->p_entries[f_presel_p->hw_index] = f_presel_p; 7137 f_lt = f_presel_p->lt_fs; 7138 while (f_lt !=NULL) { 7139 f_lt ->p_entries[f_presel_p->hw_index] 7140 = f_presel_p; 7141 f_lt = f_lt->next; 7142 } 7143 7144 /* Next Entry Part */ 7145 f_presel_p = f_presel_p->next; 7146 } 7147 } 7148 7149 fc->presel_db[f_pr->presel_id] = f_pr; 7150 TLV_INIT(tlv2); 7151 7152 } 7153 return BCM_E_NONE; 7154 7155 cleanup: 7156 TLV_INIT(tlv2); 7157 for (pipe = 0; pipe < curr_stage_fc->num_pipes; pipe++) { 7158 if (!(fc->pipe_map & (1 << pipe))) { 7159 continue; 7160 } 7161 if (fp_presel_buf[pipe] != NULL) { 7162 soc_cm_sfree(unit, fp_presel_buf[pipe]); 7163 } 7164 } 7165 if (f_pr != NULL) { 7166 if (f_pr->actions != NULL) { 7167 sal_free(f_pr->actions); 7168 } 7169 sal_free(f_pr); 7170 f_pr = NULL; 7171 } 7172 return rv; 7173 } 7174 7175 /* Function: 7176 * _field_stat_recover 7177 * 7178 * Purpose: 7179 * recover _field_stat_t structure 7180 * 7181 * Paramaters: 7182 * unit - (IN) BCM device number 7183 * tlv - (IN) TLV structure for field 7184 * Returns: 7185 * BCM_E_XXX 7186 */ 7187 7188 int 7189 _field_stat_recover(int unit, _field_tlv_t *tlv) 7190 { 7191 7192 int type_pos = 0; /* position of type */ 7193 int i = 0; /* local variable for loops */ 7194 int num_instances = 0; /* number of instances */ 7195 int num_types = 0; /* Number of types */ 7196 _field_tlv_t tlv2 ; /* TLV structure */ 7197 uint32 *type; /* Elem type */ 7198 uint8 *scache_ptr; /* Scahce pointer */ 7199 uint32 *position; /* Scache position */ 7200 _field_stat_t *f_st = NULL; /* Field Stat Structure */ 7201 _field_control_t *fc; /* Field control structure. */ 7202 int rv = 0; /* Return variable */ 7203 _field_stat_bmp_t stat_bmp; /* Stat BMP structure */ 7204 uint8 idx; /* Index to carry loop count. */ 7205 int pos = 0; /* Iterator */ 7206 7207 tlv2.value = NULL; 7208 stat_bmp.w = NULL; 7209 TLV_INIT(tlv2); 7210 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 7211 7212 type = (uint32 *)tlv->value; 7213 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 7214 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 7215 _FP_WB_TLV_TYPE_SHIFT); 7216 for (i = 0; i < num_instances; i++) { 7217 7218 _FP_XGS3_ALLOC(f_st, sizeof (_field_stat_t), "Field stat entity"); 7219 if (NULL == f_st) { 7220 return (BCM_E_MEMORY); 7221 } 7222 type_pos = 0; 7223 7224 while ((tlv2.type != _bcmFieldInternalEndStructStat) 7225 && (type_pos != num_types)) { 7226 TLV_INIT(tlv2); 7227 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 7228 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 7229 _FP_WB_TLV_BASIC_TYPE_SHIFT); 7230 rv = tlv_read(unit, &tlv2, scache_ptr, position); 7231 BCM_IF_ERROR_CLEANUP(rv); 7232 7233 switch (tlv2.type) { 7234 case _bcmFieldInternalStatsId: 7235 f_st->sid = *(uint32 *)tlv2.value; 7236 break; 7237 case _bcmFieldInternalStatSwRefCount: 7238 f_st->sw_ref_count = *(uint16 *)tlv2.value; 7239 break; 7240 case _bcmFieldInternalStatHwRefCount: 7241 f_st->hw_ref_count = *(uint16 *)tlv2.value; 7242 break; 7243 case _bcmFieldInternalStatOffsetMode: 7244 f_st->offset_mode = *(int8 *)tlv2.value; 7245 break; 7246 case _bcmFieldInternalStatPoolIndex: 7247 f_st->pool_index = *(int8 *)tlv2.value; 7248 break; 7249 case _bcmFieldInternalStatHwIndex : 7250 f_st->hw_index = *(int *)tlv2.value; 7251 break; 7252 case _bcmFieldInternalStatHwFlags: 7253 f_st->hw_flags = *(uint32 *)tlv2.value; 7254 break; 7255 case _bcmFieldInternalStatnStat: 7256 f_st->nstat = *(uint8 *)tlv2.value; 7257 break; 7258 case _bcmFieldInternalStatArr: 7259 _FP_XGS3_ALLOC(f_st->stat_arr, 7260 (tlv2.length * (recovery_type_map[unit][tlv2.type].size)), 7261 "Field stat array"); 7262 if (NULL == f_st->stat_arr) { 7263 rv = (BCM_E_MEMORY); 7264 goto cleanup; 7265 } 7266 sal_memcpy(f_st->stat_arr, tlv2.value, 7267 ((recovery_type_map[unit][tlv2.type].size) * tlv2.length)); 7268 break; 7269 case _bcmFieldInternalStatBmp: 7270 _FP_XGS3_ALLOC(stat_bmp.w, 7271 (tlv2.length * (recovery_type_map[unit][tlv2.type].size)), 7272 "Field stat array"); 7273 if (NULL == stat_bmp.w) { 7274 rv = (BCM_E_MEMORY); 7275 goto cleanup; 7276 } 7277 sal_memcpy(stat_bmp.w, tlv2.value, 7278 ((recovery_type_map[unit][tlv2.type].size) 7279 * tlv2.length)); 7280 7281 _FP_XGS3_ALLOC(f_st->stat_arr, (f_st->nstat * 7282 sizeof (bcm_field_stat_t)), 7283 "Field stat array"); 7284 if (NULL == f_st->stat_arr) { 7285 return (BCM_E_MEMORY); 7286 } 7287 7288 pos = 0; 7289 for (idx = 0; idx < ((tlv2.length) 7290 * (recovery_type_map[unit][tlv2.type].size) 7291 * 8); idx++) { 7292 if (_FP_STAT_BMP_TEST(stat_bmp, idx)) { 7293 f_st->stat_arr[pos] = idx; 7294 pos++; 7295 } 7296 } 7297 7298 if (stat_bmp.w !=NULL) { 7299 _FP_STAT_BMP_FREE(stat_bmp); 7300 } 7301 stat_bmp.w = NULL; 7302 break; 7303 case _bcmFieldInternalStatHwStat: 7304 f_st->hw_stat = *(uint32 *)tlv2.value; 7305 break; 7306 case _bcmFieldInternalStatHwMode: 7307 f_st->hw_mode = *(uint16 *)tlv2.value; 7308 break; 7309 case _bcmFieldInternalStatHwEntryCount: 7310 f_st->hw_entry_count = *(uint8 *)tlv2.value; 7311 break; 7312 case _bcmFieldInternalStatGid: 7313 f_st->gid = *(bcm_field_group_t *)tlv2.value; 7314 break; 7315 case _bcmFieldInternalStatStageId: 7316 f_st->stage_id = *(_field_stage_id_t *)tlv2.value; 7317 break; 7318 case _bcmFieldInternalStatStatValues: 7319 _FP_XGS3_ALLOC(f_st->stat_values, 7320 (tlv2.length * sizeof (uint64)), 7321 "Field stat values array"); 7322 if (NULL == f_st->stat_values) { 7323 rv = (BCM_E_MEMORY); 7324 goto cleanup; 7325 } 7326 sal_memcpy(f_st->stat_values, tlv2.value, 7327 ((recovery_type_map[unit][tlv2.type].size) * tlv2.length)); 7328 break; 7329 case _bcmFieldInternalStatFlexMode: 7330 f_st->flex_mode = *(uint32 *)tlv2.value; 7331 break; 7332 case _bcmFieldInternalEndStructStat: 7333 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_STAT) { 7334 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 7335 "END MARKER CHECK FAILED : STAT\n"))); 7336 rv = BCM_E_INTERNAL; 7337 goto cleanup; 7338 } 7339 break; 7340 default: 7341 break; 7342 } 7343 type_pos++; 7344 } 7345 TLV_INIT(tlv2); 7346 7347 /* Allocate memory for stat_values */ 7348 if (NULL == f_st->stat_values) { 7349 _FP_XGS3_ALLOC(f_st->stat_values,(f_st->nstat * sizeof (uint64)), 7350 "Field stat values array"); 7351 if (NULL == f_st->stat_values) { 7352 rv = (BCM_E_MEMORY); 7353 goto cleanup; 7354 } 7355 } 7356 7357 /* Initialize sw ref count */ 7358 f_st->sw_ref_count = 1; 7359 f_st->pool_index = _FP_INVALID_INDEX; 7360 f_st->hw_index = _FP_INVALID_INDEX; 7361 f_st->hw_mode = _FP_INVALID_INDEX; 7362 f_st->hw_entry_count = _FP_INVALID_INDEX; 7363 f_st->hw_stat = _FP_INVALID_INDEX; 7364 f_st->hw_ref_count = 0; 7365 f_st->gid = _FP_INVALID_INDEX; 7366 7367 _FP_HASH_INSERT(fc->stat_hash, f_st, 7368 (f_st->sid & _FP_HASH_INDEX_MASK(fc))); 7369 f_st = NULL; 7370 } 7371 7372 return BCM_E_NONE; 7373 7374 cleanup: 7375 TLV_INIT(tlv2); 7376 if (f_st != NULL) { 7377 if (f_st->stat_arr != NULL) { 7378 sal_free(f_st->stat_arr); 7379 f_st->stat_arr = NULL; 7380 } 7381 sal_free(f_st); 7382 f_st = NULL; 7383 } 7384 return rv; 7385 } 7386 7387 /* Function: 7388 * _field_hint_count_array_recover 7389 * 7390 * Purpose: 7391 * recover _bcm_field_hint_t structure 7392 * 7393 * Paramaters: 7394 * unit - (IN) BCM device number 7395 * tlv - (IN) TLV structure for field 7396 * f_ht - (OUT) Field hints are stored 7397 * Returns: 7398 * BCM_E_XXX 7399 */ 7400 7401 int 7402 _field_hint_count_array_recover(int unit, _field_tlv_t *tlv, 7403 _field_hints_t *f_ht) 7404 { 7405 int type_pos = 0; /* position of type */ 7406 int i = 0; /* local variable for loops */ 7407 int num_instances = 0; /* number of instances */ 7408 int num_types = 0; /* Number of types */ 7409 _field_tlv_t tlv2; /* TLV structure */ 7410 uint32 *type; /* Elem type */ 7411 uint8 *scache_ptr; /* Scahce pointer */ 7412 uint32 *position; /* Scache position */ 7413 _field_hint_t *hint_entry = NULL; /* Field hint structure */ 7414 _field_control_t *fc; /* Field control structure. */ 7415 int rv = 0; /* Return variable */ 7416 7417 tlv2.value = NULL; 7418 TLV_INIT(tlv2); 7419 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 7420 7421 type = (uint32 *)tlv->value; 7422 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 7423 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 7424 _FP_WB_TLV_TYPE_SHIFT); 7425 7426 for (i = 0; i < num_instances; i++) { 7427 _FP_XGS3_ALLOC (hint_entry, sizeof (_field_hint_t), 7428 "Field Hint Entry Structure"); 7429 if (hint_entry == NULL) { 7430 rv = BCM_E_MEMORY; 7431 goto cleanup; 7432 } 7433 _FP_XGS3_ALLOC (hint_entry->hint, sizeof (bcm_field_hint_t), 7434 "Field Hint Entry"); 7435 if (hint_entry->hint == NULL) { 7436 rv = BCM_E_MEMORY; 7437 goto cleanup; 7438 } 7439 7440 hint_entry->next = NULL; 7441 type_pos = 0; 7442 7443 tlv2.value = NULL; 7444 TLV_INIT(tlv2); 7445 while ((tlv2.type != _bcmFieldInternalEndStructHintHints) 7446 && (type_pos != num_types)) { 7447 TLV_INIT(tlv2); 7448 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 7449 tlv2.basic_type =((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 7450 _FP_WB_TLV_BASIC_TYPE_SHIFT); 7451 rv = tlv_read(unit, &tlv2, scache_ptr, position); 7452 BCM_IF_ERROR_CLEANUP(rv); 7453 switch (tlv2.type) { 7454 case _bcmFieldInternalHintHintsHintType: 7455 hint_entry->hint->hint_type = 7456 *(bcm_field_hint_type_t *)tlv2.value; 7457 break; 7458 case _bcmFieldInternalHintHintsQual: 7459 hint_entry->hint->qual = 7460 *(bcm_field_qualify_t *)tlv2.value; 7461 break; 7462 case _bcmFieldInternalHintHintsMaxValues: 7463 hint_entry->hint->max_values = *(uint32 *)tlv2.value; 7464 break; 7465 case _bcmFieldInternalHintHintsStartBit: 7466 hint_entry->hint->start_bit = *(uint32 *)tlv2.value; 7467 break; 7468 case _bcmFieldInternalHintHintsEndBit: 7469 hint_entry->hint->end_bit = *(uint32 *)tlv2.value; 7470 break; 7471 case _bcmFieldInternalHintHintsFlags: 7472 hint_entry->hint->flags = *(uint32 *)tlv2.value; 7473 break; 7474 case _bcmFieldInternalHintHintsMaxGrpSize: 7475 hint_entry->hint->max_group_size = *(uint32 *)tlv2.value; 7476 break; 7477 case _bcmFieldInternalHintHintsPri: 7478 hint_entry->hint->priority = *(uint32 *)tlv2.value; 7479 break; 7480 case _bcmFieldInternalHintHintsDosAttackEventFlags: 7481 hint_entry->hint->dosattack_event_flags = *(uint32 *)tlv2.value; 7482 break; 7483 case _bcmFieldInternalEndStructHintHints: 7484 break; 7485 default: 7486 break; 7487 } 7488 type_pos++; 7489 } 7490 _FP_HINTS_LINKLIST_INSERT(&(f_ht->hints),hint_entry); 7491 hint_entry = NULL; 7492 7493 } 7494 TLV_INIT(tlv2); 7495 return BCM_E_NONE; 7496 cleanup: 7497 TLV_INIT(tlv2); 7498 if (hint_entry != NULL) { 7499 if (hint_entry->hint != NULL) { 7500 sal_free(hint_entry->hint); 7501 hint_entry->hint = NULL; 7502 } 7503 sal_free(hint_entry); 7504 hint_entry = NULL; 7505 } 7506 return rv; 7507 7508 } 7509 7510 /* Function: 7511 * _field_hint_recover 7512 * 7513 * Purpose: 7514 * recover _field_hint_t structure 7515 * 7516 * Paramaters: 7517 * unit - (IN) BCM device number 7518 * tlv - (IN) TLV structure for field 7519 * Returns: 7520 * BCM_E_XXX 7521 */ 7522 7523 int 7524 _field_hint_recover(int unit, _field_tlv_t *tlv) 7525 { 7526 int i = 0; /* local variable for loops */ 7527 int num_instances = 0; /* number of instances */ 7528 _field_tlv_t tlv2; /* TLV structure */ 7529 uint8 *scache_ptr; /* Scahce pointer */ 7530 uint32 *position; /* Scache position */ 7531 _field_hints_t *f_ht = NULL; /* field Hints structure */ 7532 _field_control_t *fc; /* Field control structure */ 7533 int rv = 0; /* Return variable */ 7534 7535 tlv2.value = NULL; 7536 TLV_INIT(tlv2); 7537 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 7538 num_instances = (int) tlv->length; 7539 7540 for (i = 0; i < num_instances; i++) { 7541 _FP_XGS3_ALLOC(f_ht, _FP_HASH_SZ(fc) * \ 7542 sizeof(_field_hints_t), "Hints hash"); 7543 if (f_ht == NULL) { 7544 rv = BCM_E_MEMORY; 7545 goto cleanup; 7546 } 7547 7548 while (tlv2.type != _bcmFieldInternalEndStructHint) { 7549 TLV_INIT(tlv2); 7550 /* coverity[no_write_call : FALSE] */ 7551 rv = tlv_read(unit, &tlv2, scache_ptr, position); 7552 BCM_IF_ERROR_CLEANUP(rv); 7553 switch (tlv2.type) { 7554 case _bcmFieldInternalHintHintid: 7555 f_ht->hintid = *(bcm_field_hintid_t *)tlv2.value; 7556 break; 7557 case _bcmFieldInternalHintHints: 7558 _field_hint_count_array_recover(unit, &tlv2, f_ht); 7559 break; 7560 case _bcmFieldInternalHintGrpRefCount: 7561 f_ht->grp_ref_count = *(uint16 *)tlv2.value; 7562 break; 7563 case _bcmFieldInternalHintCount: 7564 f_ht->hint_count = *(uint16 *)tlv2.value; 7565 break; 7566 case _bcmFieldInternalEndStructHint: 7567 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_HINT) { 7568 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 7569 "END MARKER CHECK FAILED : HINT\n"))); 7570 rv = BCM_E_INTERNAL; 7571 goto cleanup; 7572 } 7573 break; 7574 default: 7575 break; 7576 } 7577 } 7578 TLV_INIT(tlv2); 7579 7580 _FP_HASH_INSERT(fc->hints_hash, f_ht, 7581 (f_ht->hintid & _FP_HASH_INDEX_MASK(fc))); 7582 7583 } 7584 return BCM_E_NONE; 7585 cleanup: 7586 TLV_INIT(tlv2); 7587 if (f_ht != NULL) { 7588 sal_free(f_ht); 7589 f_ht = NULL; 7590 } 7591 return rv; 7592 7593 } 7594 /* Function: 7595 * _field_udf_recover 7596 * 7597 * Purpose: 7598 * recover _field_udf_t structure 7599 * 7600 * Paramaters: 7601 * unit - (IN) BCM device number 7602 * fc - (IN) Pointer to device field control structure 7603 * 7604 * Returns: 7605 * BCM_E_XXX 7606 */ 7607 int 7608 _field_udf_recover(int unit, uint8 *ptr, uint32 *pos, _field_udf_t *udf, 7609 _field_tlv_t *tlv) 7610 { 7611 int type_pos = 0; /* position of type */ 7612 int i = 0; /* local variable for loops */ 7613 int num_instances = 0; /* number of instances */ 7614 int num_types = 0; /* Number of types */ 7615 _field_tlv_t tlv2; /* TLV structure */ 7616 uint32 *type; /* Elem type */ 7617 7618 tlv2.value = NULL; 7619 TLV_INIT(tlv2); 7620 type = (uint32 *)tlv->value; 7621 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 7622 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 7623 _FP_WB_TLV_TYPE_SHIFT); 7624 7625 for (i = 1; i <= num_instances; i++) { 7626 type_pos = 0; 7627 7628 while ((tlv2.type != _bcmFieldInternalControlEndStructUdf) 7629 && (type_pos != num_types)) { 7630 TLV_INIT(tlv2); 7631 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 7632 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 7633 _FP_WB_TLV_BASIC_TYPE_SHIFT); 7634 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, ptr, pos)); 7635 type_pos++; 7636 /* 7637 * Do not update fc->udf more than BCM_FIELD_USER_NUM_UDFS 7638 * This is possible while downgrading from a version that has 7639 * mode udf structures than current version. 7640 */ 7641 if ( i > BCM_FIELD_USER_NUM_UDFS) { 7642 if (tlv2.type == _bcmFieldInternalControlEndStructUdf) { 7643 TLV_INIT(tlv2); 7644 } 7645 continue; 7646 } 7647 switch (tlv2.type) { 7648 case _bcmFieldInternalControlUdfValid: 7649 udf->valid = *(uint8 *)tlv2.value; 7650 break; 7651 case _bcmFieldInternalControlUdfUseCount: 7652 udf->use_count = *(int *)tlv2.value; 7653 break; 7654 case _bcmFieldInternalControlUdfNum: 7655 udf->udf_num = *(bcm_field_qualify_t *)tlv2.value; 7656 break; 7657 case _bcmFieldInternalControlUdfUserNum: 7658 udf->user_num = *(uint8 *)tlv2.value; 7659 break; 7660 case _bcmFieldInternalControlEndStructUdf: 7661 TLV_INIT(tlv2); 7662 break; 7663 default: 7664 break; 7665 } 7666 } 7667 /* 7668 * Don not increment fc->udf more than BCM_FIELD_USER_NUM_UDFS 7669 */ 7670 if (BCM_FIELD_USER_NUM_UDFS > i) { 7671 udf++; 7672 } 7673 } 7674 TLV_INIT(tlv2); 7675 return BCM_E_NONE; 7676 7677 } 7678 7679 /* Function: 7680 * _field_control_recover 7681 * 7682 * Purpose: 7683 * recover _field_control_t structure 7684 * 7685 * Paramaters: 7686 * unit - (IN) BCM device number 7687 * fc - (IN) Pointer to device field control structure 7688 * 7689 * Returns: 7690 * BCM_E_XXX 7691 */ 7692 7693 int 7694 _field_control_recover(int unit, _field_control_t *fc) 7695 { 7696 7697 _field_tlv_t tlv; /* Field TLV structure */ 7698 uint8 *scache_ptr = fc->scache_ptr[_FIELD_SCACHE_PART_0]; 7699 /* Pointer to Scache */ 7700 uint32 *position = &(fc->scache_pos); 7701 /* Position in Scache */ 7702 tlv.value = NULL; 7703 TLV_INIT(tlv); 7704 7705 while (tlv.type != _bcmFieldInternalEndStructControl) { 7706 TLV_INIT(tlv); 7707 /* coverity[no_write_call : FALSE] */ 7708 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv, scache_ptr, position)); 7709 7710 switch (tlv.type) 7711 { 7712 case _bcmFieldInternalControlFlags: 7713 fc->flags = *(uint8 *)tlv.value; 7714 break; 7715 case _bcmFieldInternalControlUdfDetails: 7716 BCM_IF_ERROR_RETURN(_field_udf_recover(unit, scache_ptr, 7717 position, fc->udf, &tlv)); 7718 break; 7719 case _bcmFieldInternalControlGroups: 7720 break; 7721 case _bcmFieldInternalControlStages: 7722 break; 7723 case _bcmFieldInternalControlPolicerCount: 7724 fc->policer_count = *(uint32 *)tlv.value; 7725 break; 7726 case _bcmFieldInternalControlStatCount: 7727 fc->stat_count = *(uint32 *)tlv.value; 7728 break; 7729 case _bcmFieldInternalControlHintBmp: 7730 sal_memcpy(fc->hintid_bmp.w, tlv.value, 7731 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 7732 break; 7733 case _bcmFieldInternalControlLastAllocatedLtId: 7734 fc->last_allocated_lt_eid = *(uint32 *)tlv.value; 7735 break; 7736 case _bcmFieldInternalControlPolicerHash: 7737 BCM_IF_ERROR_RETURN(_field_policer_recover(unit, &tlv)); 7738 break; 7739 case _bcmFieldInternalControlStathash: 7740 BCM_IF_ERROR_RETURN(_field_stat_recover(unit, &tlv)); 7741 break; 7742 case _bcmFieldInternalControlHintHash: 7743 BCM_IF_ERROR_RETURN(_field_hint_recover(unit, &tlv)); 7744 break; 7745 case _bcmFieldInternalPreselInfoLimit: 7746 fc->presel_info->presel_limit = *(uint32 *)tlv.value; 7747 break; 7748 case _bcmFieldInternalPreselLastAllocatedId: 7749 fc->presel_info->last_allocated_id = *(uint32 *)tlv.value; 7750 break; 7751 case _bcmFieldInternalPreselSet: 7752 sal_memcpy(fc->presel_info->presel_set.w, tlv.value, 7753 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 7754 break; 7755 case _bcmFieldInternalPreselOperationalSet: 7756 sal_memcpy(fc->presel_info->operational_set.w, tlv.value, 7757 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 7758 break; 7759 case _bcmFieldInternalControlMeterInUse: 7760 sal_memcpy(fc->ifp_em_meter_in_use, tlv.value, 7761 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 7762 break; 7763 case _bcmFieldInternalEndStructControl: 7764 if (*(uint32 *)tlv.value != _FIELD_WB_EM_CONTROL) { 7765 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 7766 "END MARKER CHECK FAILED : CONTROL\n"))); 7767 TLV_INIT(tlv); 7768 return BCM_E_INTERNAL; 7769 } 7770 break; 7771 default: 7772 break; 7773 } 7774 } 7775 TLV_INIT(tlv); 7776 return BCM_E_NONE; 7777 } 7778 7779 7780 7781 /* Function: 7782 * _field_meterpool_recover 7783 * 7784 * Purpose: 7785 * recover _field_meter_pool_t structure 7786 * 7787 * Paramaters: 7788 * unit - (IN) BCM device number 7789 * tlv - (IN) TLV structure for field 7790 * stage_fc - (OUT) Pointer to field stage structure 7791 * 7792 * Returns: 7793 * BCM_E_XXX 7794 */ 7795 7796 int 7797 _field_meterpool_recover(int unit, _field_tlv_t *tlv, _field_stage_t *stage_fc) 7798 { 7799 int i = 0; /* local variable for loops */ 7800 int j = 0; 7801 uint32 *type; /* Elem type */ 7802 int num_types = 0; /* Number of types */ 7803 _field_tlv_t tlv2; /* TLV structure */ 7804 uint8 *scache_ptr; /* Scahce pointer */ 7805 uint32 *position; /* Scache position */ 7806 _field_control_t *fc; /* Field control structure.*/ 7807 int type_pos = 0; /* position of type */ 7808 int num_i_instances = 0; /* num_instances in 1st dimension */ 7809 int num_j_instances = 0; /* num_instances in 2nd dimension */ 7810 7811 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 7812 tlv2.value = NULL; 7813 TLV_INIT(tlv2); 7814 type = (uint32 *)tlv->value; 7815 num_i_instances = (tlv->length) & 0x000003ff; 7816 num_j_instances = ((tlv->length) & 0x003ffc00) >> 10; 7817 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 7818 _FP_WB_TLV_TYPE_SHIFT); 7819 7820 for (i = 0; i < num_i_instances; i++) { 7821 if (!(fc->pipe_map & (1 << i))) { 7822 continue; 7823 } 7824 for (j = 0; j < num_j_instances; j++) { 7825 type_pos = 0; 7826 7827 while ((tlv2.type != _bcmFieldInternalEndStructMeter) 7828 && (type_pos != num_types)) { 7829 TLV_INIT(tlv2); 7830 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 7831 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 7832 _FP_WB_TLV_BASIC_TYPE_SHIFT); 7833 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, scache_ptr, position)); 7834 switch (tlv2.type) { 7835 case _bcmFieldInternalMeterLevel: 7836 stage_fc->meter_pool[i][j]->level = *(int8 *)tlv2.value; 7837 break; 7838 case _bcmFieldInternalMeterSliceId: 7839 stage_fc->meter_pool[i][j]->slice_id = *(int *)tlv2.value; 7840 break; 7841 case _bcmFieldInternalMeterSize: 7842 stage_fc->meter_pool[i][j]->size = *(uint16 *)tlv2.value; 7843 break; 7844 case _bcmFieldInternalMeterPoolSize: 7845 stage_fc->meter_pool[i][j]->pool_size = 7846 *(uint16 *)tlv2.value; 7847 break; 7848 case _bcmFieldInternalMeterFreeMeters: 7849 stage_fc->meter_pool[i][j]->free_meters = 7850 *(uint16 *)tlv2.value; 7851 break; 7852 case _bcmFieldInternalMeterNumMeterPairs: 7853 stage_fc->meter_pool[i][j]->num_meter_pairs = 7854 *(uint16 *)tlv2.value; 7855 break; 7856 case _bcmFieldInternalMeterBmp: 7857 sal_memcpy(stage_fc->meter_pool[i][j]->meter_bmp.w, 7858 tlv2.value, ((tlv2.length) * 7859 (recovery_type_map[unit][tlv2.type].size))); 7860 break; 7861 case _bcmFieldInternalEndStructMeter: 7862 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_METER) { 7863 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 7864 "END MARKER CHECK FAILED : METER(stage)\n"))); 7865 TLV_INIT(tlv2); 7866 return BCM_E_INTERNAL; 7867 } 7868 break; 7869 default: 7870 break; 7871 } 7872 type_pos++; 7873 7874 } 7875 TLV_INIT(tlv2); 7876 } 7877 } 7878 7879 return BCM_E_NONE; 7880 } 7881 7882 #if defined (BCM_TRIDENT3_SUPPORT) 7883 /* Function: 7884 * _field_auxtag_ibus_cont_recover 7885 * 7886 * Purpose: 7887 * recover _field_auxtag_ing_fbus_cont_status_t structure 7888 * 7889 * Paramaters: 7890 * unit - (IN) BCM device number 7891 * tlv - (IN) TLV structure for field 7892 * stage_fc - (OUT) Pointer to field stage structure 7893 * 7894 * Returns: 7895 * BCM_E_XXX 7896 */ 7897 7898 int 7899 _field_auxtag_ibus_cont_recover(int unit, _field_tlv_t *tlv, _field_stage_t *stage_fc) 7900 { 7901 int i = 0; /* local variable for loops */ 7902 int j = 0; 7903 uint32 *type; /* Elem type */ 7904 int num_types = 0; /* Number of types */ 7905 _field_tlv_t tlv2; /* TLV structure */ 7906 uint8 *scache_ptr; /* Scahce pointer */ 7907 uint32 *position; /* Scache position */ 7908 _field_control_t *fc; /* Field control structure.*/ 7909 int type_pos = 0; /* position of type */ 7910 int num_i_instances = 0; /* num_instances in 1st dimension */ 7911 int num_j_instances = 0; /* num_instances in 2nd dimension */ 7912 7913 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 7914 tlv2.value = NULL; 7915 TLV_INIT(tlv2); 7916 type = (uint32 *)tlv->value; 7917 num_i_instances = (tlv->length) & 0x000003ff; 7918 num_j_instances = ((tlv->length) & 0x003ffc00) >> 10; 7919 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 7920 _FP_WB_TLV_TYPE_SHIFT); 7921 7922 for (i = 0; i < num_i_instances; i++) { 7923 if (!(fc->pipe_map & (1 << i))) { 7924 continue; 7925 } 7926 for (j = 0; j < num_j_instances; j++) { 7927 type_pos = 0; 7928 7929 while ((tlv2.type != _bcmFieldInternalEndStructAuxTagIbus) 7930 && (type_pos != num_types)) { 7931 TLV_INIT(tlv2); 7932 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 7933 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 7934 _FP_WB_TLV_BASIC_TYPE_SHIFT); 7935 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, scache_ptr, position)); 7936 switch (tlv2.type) { 7937 case _bcmFieldInternalAuxTagIbusContVal: 7938 stage_fc->ifbus_cont_stat[i][j].cont_val = *(_field_ing_field_bus_cont_t *)tlv2.value; 7939 break; 7940 case _bcmFieldInternalAuxTagIbusRefCount: 7941 stage_fc->ifbus_cont_stat[i][j].ref_count = *(uint32 *)tlv2.value; 7942 break; 7943 case _bcmFieldInternalEndStructAuxTagIbus: 7944 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_AUXTAG_IBUS) { 7945 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 7946 "END MARKER CHECK FAILED : AUXTAG_IBUS(stage)\n"))); 7947 TLV_INIT(tlv2); 7948 return BCM_E_INTERNAL; 7949 } 7950 break; 7951 default: 7952 break; 7953 } 7954 type_pos++; 7955 7956 } 7957 TLV_INIT(tlv2); 7958 } 7959 } 7960 7961 return BCM_E_NONE; 7962 } 7963 #endif /* BCM_TRIDENT3_SUPPORT */ 7964 7965 /* 7966 * Function: 7967 * _field_th_wb_group_extractors_init 7968 * Purpose: 7969 * Initialize field group extractor codes. 7970 * Parameters: 7971 * unit - (IN) BCM unit number. 7972 * fg - (IN/OUT) Field Group structure. 7973 * Returns: 7974 * BCM_E_XXX 7975 */ 7976 STATIC int 7977 _field_th_wb_group_extractors_init(int unit, _field_group_t *fg) 7978 { 7979 /* Input parameters check. */ 7980 if (NULL == fg) { 7981 return (BCM_E_NONE); 7982 } 7983 7984 /* 7985 * Initialize group extractor code flags based on group mode being 7986 * created. 7987 */ 7988 if (fg->flags & _FP_GROUP_SPAN_DOUBLE_SLICE) { 7989 fg->ext_codes[1].intraslice = _FP_EXT_SELCODE_DONT_USE; 7990 } else if (fg->flags & _FP_GROUP_SPAN_TRIPLE_SLICE) { 7991 fg->ext_codes[1].intraslice = _FP_EXT_SELCODE_DONT_USE; 7992 fg->ext_codes[2].intraslice = _FP_EXT_SELCODE_DONT_USE; 7993 } 7994 7995 fg->ext_codes[0].secondary = _FP_EXT_SELCODE_DONT_USE; 7996 if (fg->flags & _FP_GROUP_SPAN_DOUBLE_SLICE) { 7997 fg->ext_codes[1].secondary = _FP_EXT_SELCODE_DONT_USE; 7998 } else if (fg->flags & _FP_GROUP_SPAN_TRIPLE_SLICE) { 7999 fg->ext_codes[1].secondary = _FP_EXT_SELCODE_DONT_USE; 8000 fg->ext_codes[2].secondary = _FP_EXT_SELCODE_DONT_USE; 8001 } 8002 8003 return (BCM_E_NONE); 8004 } 8005 8006 8007 /* 8008 * Function: 8009 * _field_th_wb_keygen_profiles_mem_get 8010 * Purpose: 8011 * Get LT keygen program profile memory names. 8012 * Parameters: 8013 * unit - (IN) BCM device number. 8014 * stage_fc - (IN) Stage field control structure. 8015 * fg - (IN) Field group structure. 8016 * mem_arr - (IN/OUT) Pointer to memory name array. 8017 * arr_len - (IN) Memory name array length. 8018 * Returns: 8019 * BCM_E_XXX 8020 */ 8021 STATIC int 8022 _field_th_wb_keygen_profiles_mem_get(int unit, _field_stage_t *stage_fc, 8023 _field_group_t *fg, soc_mem_t *mem_arr, 8024 int arr_len) 8025 { 8026 int idx; /* Array index iterator. */ 8027 /* Per-Pipe KeyGen program profile table identifiers. */ 8028 static const soc_mem_t ifp_pipe_mem[_FP_MAX_NUM_PIPES][2] = 8029 { 8030 { 8031 IFP_KEY_GEN_PROGRAM_PROFILE_PIPE0m, 8032 IFP_KEY_GEN_PROGRAM_PROFILE2_PIPE0m 8033 }, 8034 { 8035 IFP_KEY_GEN_PROGRAM_PROFILE_PIPE1m, 8036 IFP_KEY_GEN_PROGRAM_PROFILE2_PIPE1m 8037 }, 8038 { 8039 IFP_KEY_GEN_PROGRAM_PROFILE_PIPE2m, 8040 IFP_KEY_GEN_PROGRAM_PROFILE2_PIPE2m 8041 }, 8042 { 8043 IFP_KEY_GEN_PROGRAM_PROFILE_PIPE3m, 8044 IFP_KEY_GEN_PROGRAM_PROFILE2_PIPE3m 8045 } 8046 }; 8047 static const soc_mem_t em_pipe_mem[_FP_MAX_NUM_PIPES][2] = 8048 { 8049 { 8050 EXACT_MATCH_KEY_GEN_PROGRAM_PROFILE_PIPE0m, 8051 EXACT_MATCH_KEY_GEN_MASK_PIPE0m 8052 }, 8053 { 8054 EXACT_MATCH_KEY_GEN_PROGRAM_PROFILE_PIPE1m, 8055 EXACT_MATCH_KEY_GEN_MASK_PIPE1m 8056 }, 8057 { 8058 EXACT_MATCH_KEY_GEN_PROGRAM_PROFILE_PIPE2m, 8059 EXACT_MATCH_KEY_GEN_MASK_PIPE2m 8060 }, 8061 { 8062 EXACT_MATCH_KEY_GEN_PROGRAM_PROFILE_PIPE3m, 8063 EXACT_MATCH_KEY_GEN_MASK_PIPE3m 8064 } 8065 }; 8066 static const soc_mem_t ifp_global_mem[2] = 8067 { 8068 IFP_KEY_GEN_PROGRAM_PROFILEm, 8069 IFP_KEY_GEN_PROGRAM_PROFILE2m 8070 }; 8071 static const soc_mem_t em_global_mem[2] = 8072 { 8073 EXACT_MATCH_KEY_GEN_PROGRAM_PROFILEm, 8074 EXACT_MATCH_KEY_GEN_MASKm 8075 }; 8076 8077 8078 /* Input parameters check. */ 8079 if ((NULL == stage_fc) || (NULL == fg) || (NULL == mem_arr)) { 8080 return (BCM_E_PARAM); 8081 } 8082 8083 /* 8084 * Assign keygen memory identifier name based on stage group oper mode. 8085 */ 8086 switch (stage_fc->oper_mode) { 8087 case bcmFieldGroupOperModeGlobal: 8088 if (stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 8089 for (idx = 0; idx < arr_len; idx++) { 8090 mem_arr[idx] = ifp_global_mem[idx]; 8091 } 8092 } else if (stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 8093 for (idx = 0; idx < arr_len; idx++) { 8094 mem_arr[idx] = em_global_mem[idx]; 8095 } 8096 } else { 8097 return (BCM_E_PARAM); 8098 } 8099 break; 8100 case bcmFieldGroupOperModePipeLocal: 8101 if (stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 8102 for (idx = 0; idx < arr_len; idx++) { 8103 mem_arr[idx] = ifp_pipe_mem[fg->instance][idx]; 8104 } 8105 } else if (stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 8106 for (idx = 0; idx < arr_len; idx++) { 8107 mem_arr[idx] = em_pipe_mem[fg->instance][idx]; 8108 } 8109 } else { 8110 return (BCM_E_PARAM); 8111 } 8112 break; 8113 default: 8114 return (BCM_E_INTERNAL); 8115 } 8116 return (BCM_E_NONE); 8117 } 8118 8119 /* 8120 * Function: 8121 * _bcm_field_th_update_ext_codes_from_lt_table 8122 * Purpose: 8123 * fill extractor structure from Logical tables 8124 * Parameters: 8125 * unit (IN) BCM device number. 8126 * fg (IN) field group. 8127 * part (IN) part no to recover data for 8128 * mem (IN) profile memory 8129 * prof1_entry (IN) profile data 8130 * 8131 * Returns: 8132 * BCM_E_XXX 8133 */ 8134 STATIC int 8135 _bcm_field_th_update_ext_codes_from_lt_table(int unit, 8136 _field_group_t *fg, 8137 int part, 8138 soc_mem_t lt_data_mem, 8139 uint32 *data) { 8140 /* Input parameters check. */ 8141 if ((NULL == fg) || (NULL == data)) { 8142 return (BCM_E_PARAM); 8143 } 8144 8145 /* Check and set keygen index value. */ 8146 fg->ext_codes[part].keygen_index = 8147 soc_mem_field32_get(unit, lt_data_mem, data, 8148 KEY_GEN_PROGRAM_PROFILE_INDEXf); 8149 8150 /* Check and set IP Normalize control. */ 8151 fg->ext_codes[part].normalize_l3_l4_sel = 8152 soc_mem_field32_get(unit, lt_data_mem, data, 8153 NORMALIZE_L3_L4f); 8154 8155 /* Check and set MAC Normalize control. */ 8156 fg->ext_codes[part].normalize_mac_sel = 8157 soc_mem_field32_get(unit, lt_data_mem, data, 8158 NORMALIZE_L2f); 8159 8160 /* Check and set AUX TAG A selector value. */ 8161 fg->ext_codes[part].aux_tag_a_sel = 8162 soc_mem_field32_get(unit, lt_data_mem, data, 8163 AUX_TAG_A_SELf ); 8164 8165 /* Check and set AUX TAG B selector value. */ 8166 fg->ext_codes[part].aux_tag_b_sel = 8167 soc_mem_field32_get(unit, lt_data_mem, data, 8168 AUX_TAG_B_SELf ); 8169 8170 /* Check and set AUX TAG C selector value. */ 8171 fg->ext_codes[part].aux_tag_c_sel = 8172 soc_mem_field32_get(unit, lt_data_mem, data, 8173 AUX_TAG_C_SELf ); 8174 8175 /* Check and set AUX TAG D selector value. */ 8176 fg->ext_codes[part].aux_tag_d_sel = 8177 soc_mem_field32_get(unit, lt_data_mem, data, 8178 AUX_TAG_D_SELf ); 8179 8180 /* Check and set TCP function selector. */ 8181 fg->ext_codes[part].tcp_fn_sel = 8182 soc_mem_field32_get(unit, lt_data_mem, data, 8183 TCP_FN_SELf ); 8184 8185 /* Check and set TOS function selector. */ 8186 fg->ext_codes[part].tos_fn_sel = 8187 soc_mem_field32_get(unit, lt_data_mem, data, 8188 TOS_FN_SELf ); 8189 8190 /* Check and set TTL function selector. */ 8191 fg->ext_codes[part].ttl_fn_sel = 8192 soc_mem_field32_get(unit, lt_data_mem, data, 8193 TTL_FN_SELf ); 8194 8195 /* Check and set Class ID container A selector. */ 8196 fg->ext_codes[part].class_id_cont_a_sel = 8197 soc_mem_field32_get(unit, lt_data_mem, data, 8198 CLASS_ID_CONTAINER_A_SELf ); 8199 8200 /* Check and set Class ID container B selector. */ 8201 fg->ext_codes[part].class_id_cont_b_sel = 8202 soc_mem_field32_get(unit, lt_data_mem, data, 8203 CLASS_ID_CONTAINER_B_SELf ); 8204 8205 /* Check and set Class ID container C selector. */ 8206 fg->ext_codes[part].class_id_cont_c_sel = 8207 soc_mem_field32_get(unit, lt_data_mem, data, 8208 CLASS_ID_CONTAINER_C_SELf ); 8209 8210 /* Check and set Class ID container D selector. */ 8211 fg->ext_codes[part].class_id_cont_d_sel = 8212 soc_mem_field32_get(unit, lt_data_mem, data, 8213 CLASS_ID_CONTAINER_D_SELf ); 8214 8215 /* Check and set Source Container A selector. */ 8216 fg->ext_codes[part].src_cont_a_sel = 8217 soc_mem_field32_get(unit, lt_data_mem, data, 8218 SRC_CONTAINER_A_SELf); 8219 8220 /* Check and set Source Container B selector. */ 8221 fg->ext_codes[part].src_cont_b_sel = 8222 soc_mem_field32_get(unit, lt_data_mem, data, 8223 SRC_CONTAINER_B_SELf); 8224 8225 if (fg->stage_id == _BCM_FIELD_STAGE_INGRESS) { 8226 /* Check and set IPBM selector. */ 8227 fg->ext_codes[part].ipbm_present = 8228 soc_mem_field32_get(unit, lt_data_mem, data, 8229 IPBM_PRESENTf); 8230 8231 /* Check and set Src Dest Container 0 selector. */ 8232 fg->ext_codes[part].src_dest_cont_0_sel = 8233 soc_mem_field32_get(unit, lt_data_mem, data, 8234 SRC_DST_CONTAINER_0_SELf); 8235 8236 /* Check and set Src Dest Container 1 selector. */ 8237 fg->ext_codes[part].src_dest_cont_1_sel = 8238 soc_mem_field32_get(unit, lt_data_mem, data, 8239 SRC_DST_CONTAINER_1_SELf); 8240 } 8241 return (BCM_E_NONE); 8242 } 8243 8244 /* 8245 * Function: 8246 * _field_th_keygen_profile2_entry_pack_get 8247 * Purpose: 8248 * fill extractor structure from IFP profile2 tables 8249 * Parameters: 8250 * unit (IN) BCM device number. 8251 * stage_fc (IN) field control stage 8252 * fg (IN) field group. 8253 * part (IN) part no to recover data for 8254 * mem (IN) profile memory 8255 * prof1_entry (IN) profile data 8256 * 8257 * Returns: 8258 * BCM_E_XXX 8259 */ 8260 STATIC int 8261 _field_th_keygen_profile2_entry_pack_get(int unit, _field_stage_t *stage_fc, 8262 _field_group_t *fg, int part, soc_mem_t mem, 8263 ifp_key_gen_program_profile2_entry_t *prof2_entry) 8264 { 8265 int idx; /* Iterator index. */ 8266 static const soc_field_t pmux_sel[] = /* Post mux selectors. */ 8267 { 8268 POST_EXTRACTOR_MUX_0_SELf, 8269 POST_EXTRACTOR_MUX_1_SELf, 8270 POST_EXTRACTOR_MUX_2_SELf, 8271 POST_EXTRACTOR_MUX_3_SELf, 8272 POST_EXTRACTOR_MUX_4_SELf, 8273 POST_EXTRACTOR_MUX_5_SELf, 8274 POST_EXTRACTOR_MUX_6_SELf, 8275 POST_EXTRACTOR_MUX_7_SELf, 8276 POST_EXTRACTOR_MUX_8_SELf, 8277 POST_EXTRACTOR_MUX_9_SELf, 8278 POST_EXTRACTOR_MUX_10_SELf, 8279 POST_EXTRACTOR_MUX_11_SELf, 8280 POST_EXTRACTOR_MUX_12_SELf, 8281 POST_EXTRACTOR_MUX_13_SELf, 8282 POST_EXTRACTOR_MUX_14_SELf 8283 }; 8284 8285 /* Input parameters check. */ 8286 if ((NULL == stage_fc) || (NULL == fg) || (NULL == prof2_entry)) { 8287 return (BCM_E_PARAM); 8288 } 8289 /* Set Post MUX extractor selcode values. */ 8290 for (idx = 0; idx < 15; idx++) { 8291 fg->ext_codes[part].pmux_sel[idx] = 8292 soc_mem_field32_get(unit, mem, prof2_entry, pmux_sel[idx]); 8293 } 8294 return (BCM_E_NONE); 8295 } 8296 8297 /* 8298 * Function: 8299 * _field_th_keygen_profile1_entry_pack_get 8300 * Purpose: 8301 * fill extractor structure from IFP profile1 tables 8302 * Parameters: 8303 * unit (IN) BCM device number. 8304 * stage_fc (IN) field control stage 8305 * fg (IN) field group. 8306 * part (IN) part no to recover data for 8307 * mem (IN) profile memory 8308 * prof1_entry (IN) profile data 8309 * 8310 * Returns: 8311 * BCM_E_XXX 8312 */ 8313 8314 STATIC int 8315 _field_th_keygen_profile1_entry_pack_get(int unit, _field_stage_t *stage_fc, 8316 _field_group_t *fg, int part, soc_mem_t mem, 8317 ifp_key_gen_program_profile_entry_t *prof1_entry) 8318 { 8319 int idx; /* Iterator index. */ 8320 static const soc_field_t l1_32_sel[] = /* 32 bit extractors. */ 8321 { 8322 L1_E32_SEL_0f, 8323 L1_E32_SEL_1f, 8324 L1_E32_SEL_2f, 8325 L1_E32_SEL_3f 8326 }; 8327 static const soc_field_t l1_16_sel[] = /* 16 bit extractors. */ 8328 { 8329 L1_E16_SEL_0f, 8330 L1_E16_SEL_1f, 8331 L1_E16_SEL_2f, 8332 L1_E16_SEL_3f, 8333 L1_E16_SEL_4f, 8334 L1_E16_SEL_5f, 8335 L1_E16_SEL_6f 8336 }; 8337 static const soc_field_t l1_8_sel[] = /* 8 bit extractors. */ 8338 { 8339 L1_E8_SEL_0f, 8340 L1_E8_SEL_1f, 8341 L1_E8_SEL_2f, 8342 L1_E8_SEL_3f, 8343 L1_E8_SEL_4f, 8344 L1_E8_SEL_5f, 8345 L1_E8_SEL_6f 8346 }; 8347 static const soc_field_t l1_4_sel[] = /* 4 bit extractors. */ 8348 { 8349 L1_E4_SEL_0f, 8350 L1_E4_SEL_1f, 8351 L1_E4_SEL_2f, 8352 L1_E4_SEL_3f, 8353 L1_E4_SEL_4f, 8354 L1_E4_SEL_5f, 8355 L1_E4_SEL_6f, 8356 L1_E4_SEL_7f 8357 }; 8358 static const soc_field_t l1_2_sel[] = /* 2 bit extractors. */ 8359 { 8360 L1_E2_SEL_0f, 8361 L1_E2_SEL_1f, 8362 L1_E2_SEL_2f, 8363 L1_E2_SEL_3f, 8364 L1_E2_SEL_4f, 8365 L1_E2_SEL_5f, 8366 L1_E2_SEL_6f, 8367 L1_E2_SEL_7f 8368 }; 8369 static const soc_field_t l2_16_sel[] = /* 16 bit extractors. */ 8370 { 8371 L2_E16_SEL_0f, 8372 L2_E16_SEL_1f, 8373 L2_E16_SEL_2f, 8374 L2_E16_SEL_3f, 8375 L2_E16_SEL_4f, 8376 L2_E16_SEL_5f, 8377 L2_E16_SEL_6f, 8378 L2_E16_SEL_7f, 8379 L2_E16_SEL_8f, 8380 L2_E16_SEL_9f 8381 }; 8382 static const soc_field_t l3_4_sel[] = /* 4 bit extractors. */ 8383 { 8384 L3_E4_SEL_0f, 8385 L3_E4_SEL_1f, 8386 L3_E4_SEL_2f, 8387 L3_E4_SEL_3f, 8388 L3_E4_SEL_4f, 8389 L3_E4_SEL_5f, 8390 L3_E4_SEL_6f, 8391 L3_E4_SEL_7f, 8392 L3_E4_SEL_8f, 8393 L3_E4_SEL_9f, 8394 L3_E4_SEL_10f, 8395 L3_E4_SEL_11f, 8396 L3_E4_SEL_12f, 8397 L3_E4_SEL_13f, 8398 L3_E4_SEL_14f, 8399 L3_E4_SEL_15f, 8400 L3_E4_SEL_16f, 8401 L3_E4_SEL_17f, 8402 L3_E4_SEL_18f, 8403 L3_E4_SEL_19f, 8404 L3_E4_SEL_20f 8405 }; 8406 static const soc_field_t l3_2_sel[] = /* 2 bit extractors. */ 8407 { 8408 L3_E2_SEL_0f, 8409 L3_E2_SEL_1f, 8410 L3_E2_SEL_2f, 8411 L3_E2_SEL_3f, 8412 L3_E2_SEL_4f 8413 }; 8414 static const soc_field_t l3_1_sel[] = /* 1 bit extractors. */ 8415 { 8416 L3_E1_SEL_0f, 8417 L3_E1_SEL_1f 8418 }; 8419 8420 /* Input parameters check. */ 8421 if ((NULL == stage_fc) || (NULL == fg) || (NULL == prof1_entry)) { 8422 return (BCM_E_PARAM); 8423 } 8424 8425 /* Set 32bit extractor selcode values. */ 8426 for (idx = 0; idx < 4; idx++) { 8427 fg->ext_codes[part].l1_e32_sel[idx] = 8428 soc_mem_field32_get(unit, mem, prof1_entry, l1_32_sel[idx]); 8429 } 8430 8431 /* Set 16bit extractor selcode values. */ 8432 for (idx = 0; idx < 7; idx++) { 8433 fg->ext_codes[part].l1_e16_sel[idx] = 8434 soc_mem_field32_get(unit, mem, prof1_entry, l1_16_sel[idx]); 8435 } 8436 8437 /* Set 8bit extractor selcode values. */ 8438 for (idx = 0; idx < 7; idx++) { 8439 fg->ext_codes[part].l1_e8_sel[idx] = 8440 soc_mem_field32_get(unit, mem, prof1_entry, l1_8_sel[idx]); 8441 } 8442 8443 /* Set 4bit extractor selcode values. */ 8444 for (idx = 0; idx < 8; idx++) { 8445 fg->ext_codes[part].l1_e4_sel[idx] = 8446 soc_mem_field32_get(unit, mem, prof1_entry, l1_4_sel[idx]); 8447 } 8448 8449 /* Set 2bit extractor selcode values. */ 8450 for (idx = 0; idx < 8; idx++) { 8451 fg->ext_codes[part].l1_e2_sel[idx] = 8452 soc_mem_field32_get(unit, mem, prof1_entry, l1_2_sel[idx]); 8453 } 8454 8455 /* Set 16bit extractor selcode values. */ 8456 for (idx = 0; idx < 10; idx++) { 8457 fg->ext_codes[part].l2_e16_sel[idx] = 8458 soc_mem_field32_get(unit, mem, prof1_entry, l2_16_sel[idx]); 8459 } 8460 8461 /* Set 4bit extractor selcode values. */ 8462 for (idx = 0; idx < 21; idx++) { 8463 fg->ext_codes[part].l3_e4_sel[idx] = 8464 soc_mem_field32_get(unit, mem, prof1_entry, l3_4_sel[idx]); 8465 } 8466 8467 /* Set 2bit extractor selcode values. */ 8468 for (idx = 0; idx < 5; idx++) { 8469 fg->ext_codes[part].l3_e2_sel[idx] = 8470 soc_mem_field32_get(unit, mem, prof1_entry, l3_2_sel[idx]); 8471 } 8472 8473 /* Set 1bit extractor selcode values. */ 8474 for (idx = 0; idx < 2; idx++) { 8475 fg->ext_codes[part].l3_e1_sel[idx] = 8476 soc_mem_field32_get(unit, mem, prof1_entry, l3_1_sel[idx]); 8477 } 8478 8479 return (BCM_E_NONE); 8480 } 8481 /* 8482 * Function: 8483 * _field_th_keygen_em_profile_entry_pack_get 8484 * Purpose: 8485 * fill extractor structure from em profile tables 8486 * Parameters: 8487 * unit (IN) BCM device number. 8488 * stage_fc (IN) field control stage 8489 * fg (IN) field group. 8490 * part (IN) part no to recover data for 8491 * mem (IN) profile memory 8492 * prof_entry (IN) profile data 8493 * 8494 * Returns: 8495 * BCM_E_XXX 8496 */ 8497 int 8498 _field_th_keygen_em_profile_entry_pack_get(int unit, _field_stage_t *stage_fc, 8499 _field_group_t *fg, int part, soc_mem_t mem, 8500 exact_match_key_gen_program_profile_entry_t *prof_entry) 8501 { 8502 int idx; /* Iterator index. */ 8503 static const soc_field_t l1_32_sel[] = /* 32 bit extractors. */ 8504 { 8505 L1_E32_SEL_0f, 8506 L1_E32_SEL_1f, 8507 L1_E32_SEL_2f, 8508 L1_E32_SEL_3f 8509 }; 8510 static const soc_field_t l1_16_sel[] = /* 16 bit extractors. */ 8511 { 8512 L1_E16_SEL_0f, 8513 L1_E16_SEL_1f, 8514 L1_E16_SEL_2f, 8515 L1_E16_SEL_3f, 8516 L1_E16_SEL_4f, 8517 L1_E16_SEL_5f, 8518 L1_E16_SEL_6f 8519 }; 8520 static const soc_field_t l1_8_sel[] = /* 8 bit extractors. */ 8521 { 8522 L1_E8_SEL_0f, 8523 L1_E8_SEL_1f, 8524 L1_E8_SEL_2f, 8525 L1_E8_SEL_3f, 8526 L1_E8_SEL_4f, 8527 L1_E8_SEL_5f, 8528 L1_E8_SEL_6f 8529 }; 8530 static const soc_field_t l1_4_sel[] = /* 4 bit extractors. */ 8531 { 8532 L1_E4_SEL_0f, 8533 L1_E4_SEL_1f, 8534 L1_E4_SEL_2f, 8535 L1_E4_SEL_3f, 8536 L1_E4_SEL_4f, 8537 L1_E4_SEL_5f, 8538 L1_E4_SEL_6f, 8539 L1_E4_SEL_7f 8540 }; 8541 static const soc_field_t l1_2_sel[] = /* 2 bit extractors. */ 8542 { 8543 L1_E2_SEL_0f, 8544 L1_E2_SEL_1f, 8545 L1_E2_SEL_2f, 8546 L1_E2_SEL_3f, 8547 L1_E2_SEL_4f, 8548 L1_E2_SEL_5f, 8549 L1_E2_SEL_6f, 8550 L1_E2_SEL_7f 8551 }; 8552 static const soc_field_t l2_16_sel[] = /* 16 bit extractors. */ 8553 { 8554 L2_E16_SEL_0f, 8555 L2_E16_SEL_1f, 8556 L2_E16_SEL_2f, 8557 L2_E16_SEL_3f, 8558 L2_E16_SEL_4f, 8559 L2_E16_SEL_5f, 8560 L2_E16_SEL_6f, 8561 L2_E16_SEL_7f, 8562 L2_E16_SEL_8f, 8563 L2_E16_SEL_9f 8564 }; 8565 static const soc_field_t l3_4_sel[] = /* 4 bit extractors. */ 8566 { 8567 L3_E4_SEL_0f, 8568 L3_E4_SEL_1f, 8569 L3_E4_SEL_2f, 8570 L3_E4_SEL_3f, 8571 L3_E4_SEL_4f, 8572 L3_E4_SEL_5f, 8573 L3_E4_SEL_6f, 8574 L3_E4_SEL_7f, 8575 L3_E4_SEL_8f, 8576 L3_E4_SEL_9f, 8577 L3_E4_SEL_10f, 8578 L3_E4_SEL_11f, 8579 L3_E4_SEL_12f, 8580 L3_E4_SEL_13f, 8581 L3_E4_SEL_14f, 8582 L3_E4_SEL_15f, 8583 L3_E4_SEL_16f, 8584 L3_E4_SEL_17f, 8585 L3_E4_SEL_18f, 8586 L3_E4_SEL_19f, 8587 L3_E4_SEL_20f 8588 }; 8589 static const soc_field_t l3_2_sel[] = /* 2 bit extractors. */ 8590 { 8591 L3_E2_SEL_0f, 8592 L3_E2_SEL_1f, 8593 L3_E2_SEL_2f, 8594 L3_E2_SEL_3f, 8595 L3_E2_SEL_4f 8596 }; 8597 static const soc_field_t l3_1_sel[] = /* 1 bit extractors. */ 8598 { 8599 L3_E1_SEL_0f, 8600 L3_E1_SEL_1f 8601 }; 8602 8603 /* Input parameters check. */ 8604 if ((NULL == stage_fc) || (NULL == fg) || (NULL == prof_entry)) { 8605 return (BCM_E_PARAM); 8606 } 8607 8608 /* Set 32bit extractor selcode values. */ 8609 for (idx = 0; idx < 4; idx++) { 8610 fg->ext_codes[part].l1_e32_sel[idx] = 8611 soc_mem_field32_get(unit, mem, prof_entry, l1_32_sel[idx]); 8612 } 8613 8614 /* Set 16bit extractor selcode values. */ 8615 for (idx = 0; idx < 7; idx++) { 8616 fg->ext_codes[part].l1_e16_sel[idx] = 8617 soc_mem_field32_get(unit, mem, prof_entry, l1_16_sel[idx]); 8618 } 8619 8620 /* Set 8bit extractor selcode values. */ 8621 for (idx = 0; idx < 7; idx++) { 8622 fg->ext_codes[part].l1_e8_sel[idx] = 8623 soc_mem_field32_get(unit, mem, prof_entry, l1_8_sel[idx]); 8624 } 8625 8626 /* Set 4bit extractor selcode values. */ 8627 for (idx = 0; idx < 8; idx++) { 8628 fg->ext_codes[part].l1_e4_sel[idx] = 8629 soc_mem_field32_get(unit, mem, prof_entry, l1_4_sel[idx]); 8630 } 8631 8632 /* Set 2bit extractor selcode values. */ 8633 for (idx = 0; idx < 8; idx++) { 8634 fg->ext_codes[part].l1_e2_sel[idx] = 8635 soc_mem_field32_get(unit, mem, prof_entry, l1_2_sel[idx]); 8636 } 8637 8638 /* Set 16bit extractor selcode values. */ 8639 for (idx = 0; idx < 10; idx++) { 8640 fg->ext_codes[part].l2_e16_sel[idx] = 8641 soc_mem_field32_get(unit, mem, prof_entry, l2_16_sel[idx]); 8642 } 8643 8644 /* Set 4bit extractor selcode values. */ 8645 for (idx = 0; idx < 21; idx++) { 8646 fg->ext_codes[part].l3_e4_sel[idx] = 8647 soc_mem_field32_get(unit, mem, prof_entry, l3_4_sel[idx]); 8648 } 8649 8650 /* Set 2bit extractor selcode values. */ 8651 for (idx = 0; idx < 5; idx++) { 8652 fg->ext_codes[part].l3_e2_sel[idx] = 8653 soc_mem_field32_get(unit, mem, prof_entry, l3_2_sel[idx]); 8654 } 8655 8656 /* Set 1bit extractor selcode values. */ 8657 for (idx = 0; idx < 2; idx++) { 8658 fg->ext_codes[part].l3_e1_sel[idx] = 8659 soc_mem_field32_get(unit, mem, prof_entry, l3_1_sel[idx]); 8660 } 8661 8662 return (BCM_E_NONE); 8663 } 8664 8665 /* 8666 * Function: 8667 * _bcm_field_th_group_update_ext_codes_from_keygen_profiles 8668 * Purpose: 8669 * update extractor structureby reading from profile tables 8670 * Parameters: 8671 * unit (IN) BCM device number. 8672 * fg (IN) field group. 8673 * part_index (IN) part no to recover data for 8674 * key_gen_prof_idx (IN) index to lt table 8675 * 8676 * Returns: 8677 * BCM_E_XXX 8678 */ 8679 int 8680 _bcm_field_th_group_update_ext_codes_from_keygen_profiles(int unit, 8681 _field_group_t *fg, 8682 int part_index, 8683 uint32 key_gen_prof_idx) 8684 { 8685 ifp_key_gen_program_profile_entry_t *ifp_prof1_entry; 8686 /* IFP Keygen profile1. */ 8687 ifp_key_gen_program_profile2_entry_t *ifp_prof2_entry; 8688 /* IFP Keygen profile2. */ 8689 exact_match_key_gen_program_profile_entry_t *em_prof_entry; 8690 /* Exact Match Profile. */ 8691 exact_match_key_gen_mask_entry_t *em_prof_mask_entry; 8692 /* Exact Match Mask Profile. */ 8693 void *entries[2]; /* Entries array. */ 8694 soc_mem_t mem[2]; /* Keygen profile memory identifier. */ 8695 int rv; /* Operation return status. */ 8696 _field_stage_t *stage_fc; /* stage fc */ 8697 8698 /* Input parameters check. */ 8699 if (NULL == fg) { 8700 return (BCM_E_PARAM); 8701 } 8702 8703 /* Retreive Stage Control. */ 8704 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 8705 if (BCM_FAILURE(rv)) { 8706 return (rv); 8707 } 8708 8709 if (stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 8710 /* Get keygen program profiles memory name identifer. */ 8711 BCM_IF_ERROR_RETURN(_field_th_wb_keygen_profiles_mem_get(unit, stage_fc, fg, 8712 mem, COUNTOF(mem))); 8713 ifp_prof1_entry = sal_alloc(sizeof(ifp_key_gen_program_profile_entry_t), 8714 "ifp_key_gen_profile1_mem"); 8715 if (ifp_prof1_entry == NULL) { 8716 return BCM_E_MEMORY; 8717 } 8718 ifp_prof2_entry = sal_alloc(sizeof(ifp_key_gen_program_profile2_entry_t), 8719 "ifp_key_gen_profile2_mem"); 8720 if (ifp_prof2_entry == NULL) { 8721 sal_free(ifp_prof1_entry); 8722 return BCM_E_MEMORY; 8723 } 8724 /* Clear keygen profile entry. */ 8725 sal_memcpy(ifp_prof1_entry, soc_mem_entry_null(unit, mem[0]), 8726 soc_mem_entry_words(unit, mem[0]) * sizeof(uint32)); 8727 /* Clear keygen profile entry. */ 8728 sal_memcpy(ifp_prof2_entry, soc_mem_entry_null(unit, mem[1]), 8729 soc_mem_entry_words(unit, mem[1]) * sizeof(uint32)); 8730 8731 entries[0] = ifp_prof1_entry; 8732 entries[1] = ifp_prof2_entry; 8733 rv = soc_profile_mem_get(unit, 8734 &stage_fc->keygen_profile[fg->instance].profile, 8735 key_gen_prof_idx, 1, entries); 8736 if (SOC_SUCCESS(rv)) { 8737 ifp_prof1_entry = entries[0]; 8738 rv = _field_th_keygen_profile1_entry_pack_get(unit, stage_fc, fg, 8739 part_index, mem[0], ifp_prof1_entry); 8740 if (SOC_SUCCESS(rv)) { 8741 ifp_prof2_entry = entries[1]; 8742 rv = _field_th_keygen_profile2_entry_pack_get(unit, 8743 stage_fc, fg,part_index, 8744 mem[1], ifp_prof2_entry); 8745 } 8746 } 8747 sal_free(ifp_prof1_entry); 8748 sal_free(ifp_prof2_entry); 8749 } else if (stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 8750 /* Get keygen program profiles memory name identifer. */ 8751 BCM_IF_ERROR_RETURN(_field_th_wb_keygen_profiles_mem_get(unit, stage_fc, fg, 8752 mem, COUNTOF(mem))); 8753 em_prof_entry = sal_alloc(sizeof(exact_match_key_gen_program_profile_entry_t), 8754 "em_key_gen_profile1_mem"); 8755 if (em_prof_entry == NULL) { 8756 return BCM_E_MEMORY; 8757 } 8758 em_prof_mask_entry = sal_alloc(sizeof(exact_match_key_gen_mask_entry_t), 8759 "em_key_gen_profile_mask_mem"); 8760 if (em_prof_mask_entry == NULL) { 8761 sal_free(em_prof_entry); 8762 return BCM_E_MEMORY; 8763 } 8764 /* Clear keygen profile entry. */ 8765 sal_memcpy(em_prof_entry, soc_mem_entry_null(unit, mem[0]), 8766 soc_mem_entry_words(unit, mem[0]) * sizeof(uint32)); 8767 sal_memcpy(em_prof_entry, soc_mem_entry_null(unit, mem[1]), 8768 soc_mem_entry_words(unit, mem[1]) * sizeof(uint32)); 8769 /* read profile memory */ 8770 entries[0] = em_prof_entry; 8771 entries[1] = em_prof_mask_entry; 8772 rv = soc_profile_mem_get(unit, 8773 &stage_fc->keygen_profile[fg->instance].profile, 8774 key_gen_prof_idx, 1, entries); 8775 if (SOC_SUCCESS(rv)) { 8776 em_prof_entry = entries[0]; 8777 em_prof_mask_entry = entries[1]; 8778 rv = _field_th_keygen_em_profile_entry_pack_get(unit, stage_fc, fg, 8779 part_index, mem[0], em_prof_entry); 8780 } 8781 sal_free(em_prof_entry); 8782 sal_free(em_prof_mask_entry); 8783 } else { 8784 /* Invalid Stage */ 8785 rv = BCM_E_PARAM; 8786 } 8787 8788 return (rv); 8789 } 8790 /* 8791 * Function: 8792 * _field_th_lt_mem_get 8793 * Purpose: 8794 * Get logica table memory identifier based on stage group operational mode. 8795 * Parameters: 8796 * unit - (IN) BCM device number. 8797 * lt_tcam_mem - (IN/OUT) LT memory identifer pointer. 8798 * 8799 * Returns: 8800 * BCM_E_XXX 8801 */ 8802 int 8803 _field_th_lt_mem_get(int unit, _field_group_t *fg, soc_mem_t *lt_tcam_mem) { 8804 _field_stage_t *stage_fc; /*stage fieldcontrol */ 8805 int rv; /* Operation return status. */ 8806 8807 /* Per-Pipe IFP Logical Table TCAM view. */ 8808 static const soc_mem_t lt_ifp_tcam[] = 8809 { 8810 IFP_LOGICAL_TABLE_SELECT_PIPE0m, 8811 IFP_LOGICAL_TABLE_SELECT_PIPE1m, 8812 IFP_LOGICAL_TABLE_SELECT_PIPE2m, 8813 IFP_LOGICAL_TABLE_SELECT_PIPE3m 8814 }; 8815 8816 /* Per-Pipe Exact Match Logical Table TCAM view. */ 8817 static const soc_mem_t lt_em_tcam[] = 8818 { 8819 EXACT_MATCH_LOGICAL_TABLE_SELECT_PIPE0m, 8820 EXACT_MATCH_LOGICAL_TABLE_SELECT_PIPE1m, 8821 EXACT_MATCH_LOGICAL_TABLE_SELECT_PIPE2m, 8822 EXACT_MATCH_LOGICAL_TABLE_SELECT_PIPE3m 8823 }; 8824 8825 /* Input parameters check. */ 8826 if ((NULL == fg) || (NULL == lt_tcam_mem)) { 8827 return (BCM_E_PARAM); 8828 } 8829 8830 /* Retreive Stage Control. */ 8831 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 8832 if (BCM_FAILURE(rv)) { 8833 return (rv); 8834 } 8835 8836 /* Set LT selection memory identifier based on stage group oper mode. */ 8837 switch (stage_fc->oper_mode) { 8838 case bcmFieldGroupOperModeGlobal: 8839 if (stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 8840 *lt_tcam_mem = IFP_LOGICAL_TABLE_SELECTm; 8841 } else if (stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 8842 *lt_tcam_mem = EXACT_MATCH_LOGICAL_TABLE_SELECTm; 8843 } else { 8844 return (BCM_E_INTERNAL); 8845 } 8846 break; 8847 case bcmFieldGroupOperModePipeLocal: 8848 if (stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 8849 *lt_tcam_mem = lt_ifp_tcam[fg->instance]; 8850 } else if (stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 8851 *lt_tcam_mem = lt_em_tcam[fg->instance]; 8852 } else { 8853 return (BCM_E_INTERNAL); 8854 } 8855 break; 8856 default: 8857 return (BCM_E_INTERNAL); 8858 } 8859 return (BCM_E_NONE); 8860 } 8861 /* Function: 8862 * _field_recover_multi_part_extractor_codes 8863 * 8864 * Purpose: 8865 * recover extractor codes for multi parts of a group 8866 * from hardware and populate ext_sel structure of group 8867 * There was an issue with sync of extractor code for TH WB prior to WB ver 23. 8868 * The extractor codes of the first part is copied to remaining 8869 * parts of the group. The is fixed both in sync and recovery 8870 * This is requied only for versions prior to 23. 8871 * 8872 * 8873 * Paramaters: 8874 * unit - (IN) BCM device number 8875 * Returns: 8876 * BCM_E_XXX 8877 */ 8878 int 8879 _field_recover_multi_part_extractor_codes(int unit) { 8880 _field_control_t *fc; /* Field control structure.*/ 8881 _field_group_t *fg; /* Group information */ 8882 _field_stage_t *stage_fc; /*stage fieldcontrol */ 8883 int parts_cnt; /*part counts of group */ 8884 soc_mem_t lt_tcam_mem; /* lt table memory */ 8885 uint32 ent[SOC_MAX_MEM_FIELD_WORDS]; /* to hold the mem entry */ 8886 _field_presel_entry_t *f_presel; /* Field Presel Structure */ 8887 int tcam_idx; 8888 int i, idx, is_first; 8889 int rv = BCM_E_NONE; /* Operation return status.*/ 8890 _field_lt_entry_t *lt_entry_arr_temp = NULL; 8891 /* get the stage fc */ 8892 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 8893 fg = fc->groups; 8894 while (fg != NULL) { 8895 if ((fg->stage_id == _BCM_FIELD_STAGE_INGRESS) || 8896 (fg->stage_id == _BCM_FIELD_STAGE_EXACTMATCH)) { 8897 /* Get Field Entry Parts. */ 8898 BCM_IF_ERROR_RETURN(_bcm_field_entry_tcam_parts_count(unit, 8899 fg->stage_id, 8900 fg->flags, 8901 &parts_cnt)); 8902 /* Retreive Stage Control. */ 8903 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 8904 fg->stage_id, 8905 &stage_fc)); 8906 BCM_IF_ERROR_RETURN(_field_th_lt_mem_get(unit, fg, <_tcam_mem)); 8907 _field_th_wb_group_extractors_init(unit, fg); 8908 if ( (fg->lt_entry_arr != NULL ) && 8909 (fg->lt_entry_arr[0] != NULL) ) { 8910 /* recover using lt_array */ 8911 for (i= 0; i<parts_cnt; i++) { 8912 if ( i == 0 ) { 8913 /* first part is already recovered from SW*/ 8914 rv = soc_profile_mem_reference(unit, 8915 &stage_fc->keygen_profile[fg->instance].profile, 8916 fg->ext_codes[i].keygen_index, 1); 8917 if (BCM_FAILURE(rv)) { 8918 return rv; 8919 } 8920 continue; 8921 } 8922 lt_entry_arr_temp = fg->lt_entry_arr[0]; 8923 tcam_idx = (lt_entry_arr_temp[i].index) + 8924 ((lt_entry_arr_temp[i].lt_fs)->start_tcam_idx); 8925 rv = soc_mem_read(unit, lt_tcam_mem, MEM_BLOCK_ANY, 8926 tcam_idx, ent); 8927 if (BCM_FAILURE(rv)) { 8928 return rv; 8929 } 8930 /* update ext codes from lt table */ 8931 rv = _bcm_field_th_update_ext_codes_from_lt_table(unit, 8932 fg, i, lt_tcam_mem, 8933 ent); 8934 if (BCM_FAILURE(rv)) { 8935 return rv; 8936 } 8937 rv = soc_profile_mem_reference(unit, 8938 &stage_fc->keygen_profile[fg->instance].profile, 8939 fg->ext_codes[i].keygen_index, 1); 8940 if (BCM_FAILURE(rv)) { 8941 return rv; 8942 } 8943 /* update the ext_codes from profile table */ 8944 rv = 8945 _bcm_field_th_group_update_ext_codes_from_keygen_profiles( 8946 unit, 8947 fg, 8948 i, 8949 fg->ext_codes[i].keygen_index); 8950 if (BCM_FAILURE(rv)) { 8951 return rv; 8952 } 8953 } 8954 } else { 8955 /* recover using presels */ 8956 f_presel = NULL; 8957 is_first = 0; 8958 /*loop throu for each presel attached to group */ 8959 for (idx = 0; idx < _FP_PRESEL_ENTRIES_MAX_PER_GROUP; idx++) { 8960 if (fg->presel_ent_arr[idx] != NULL) { 8961 f_presel = fg->presel_ent_arr[idx]; 8962 is_first++; 8963 } else { 8964 continue; 8965 } 8966 8967 for (i= 0; i<parts_cnt; i++) { 8968 /* first part is already recovered from SW */ 8969 if ( (i == 0 ) || (is_first != 1) ) { 8970 rv = soc_profile_mem_reference(unit, 8971 &stage_fc->keygen_profile[fg->instance].profile, 8972 fg->ext_codes[i].keygen_index, 1); 8973 8974 if (BCM_FAILURE(rv)) { 8975 return rv; 8976 } 8977 f_presel = f_presel->next; 8978 continue; 8979 } 8980 /*get the lt table kengen_index */ 8981 if (f_presel != NULL) { 8982 tcam_idx = f_presel->hw_index + 8983 f_presel->lt_fs->start_tcam_idx; 8984 } else { 8985 return BCM_E_INTERNAL; 8986 } 8987 rv = soc_mem_read(unit, lt_tcam_mem, MEM_BLOCK_ANY, 8988 tcam_idx, ent); 8989 if (BCM_FAILURE(rv)) { 8990 return rv; 8991 } 8992 /* update ext codes from lt table */ 8993 rv = _bcm_field_th_update_ext_codes_from_lt_table(unit, 8994 fg, i,lt_tcam_mem, 8995 ent); 8996 if (BCM_FAILURE(rv)) { 8997 return rv; 8998 } 8999 rv = soc_profile_mem_reference(unit, 9000 &stage_fc->keygen_profile[fg->instance].profile, 9001 fg->ext_codes[i].keygen_index, 1); 9002 if (BCM_FAILURE(rv)) { 9003 return rv; 9004 } 9005 /* update the ext_codes from profile table */ 9006 rv = 9007 _bcm_field_th_group_update_ext_codes_from_keygen_profiles( 9008 unit, 9009 fg, 9010 i, 9011 fg->ext_codes[i].keygen_index); 9012 if (BCM_FAILURE(rv)) { 9013 return rv; 9014 } 9015 f_presel = f_presel->next; 9016 } 9017 } 9018 } 9019 } 9020 fg = fg->next; 9021 } /* end of while */ 9022 return rv; 9023 } 9024 9025 /* Function: 9026 * _field_extractor_recover 9027 * 9028 * Purpose: 9029 * recover _field_slice_t structure 9030 * 9031 * Paramaters: 9032 * unit - (IN) BCM device number 9033 * ptr - (IN) Pointer to scache in field control 9034 * pos - (IN) Pointer to position in field control 9035 * tlv - (IN) tlv structure containing encoded types and number. 9036 * ext_sel - (IN) address of start of array in slice structure. 9037 * 9038 * Returns: 9039 * BCM_E_XXX 9040 */ 9041 int 9042 _field_extractor_recover(int unit, uint8 *ptr, uint32 *pos, 9043 _field_tlv_t *tlv, _field_ext_sel_t *ext_sel) 9044 { 9045 9046 int type_pos = 0; /* position of type */ 9047 int i = 0; /* local variable for loops */ 9048 int num_instances = 0; /* number of instances */ 9049 int num_types = 0; /* Number of types */ 9050 _field_tlv_t tlv2; /* TLV structure */ 9051 uint32 *type; /* Elem type */ 9052 9053 tlv2.value = NULL; 9054 TLV_INIT(tlv2); 9055 type = (uint32 *)tlv->value; 9056 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 9057 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 9058 _FP_WB_TLV_TYPE_SHIFT); 9059 9060 for (i = 0; i < num_instances; i++) { 9061 _FP_EXT_SELCODE_CLEAR(*ext_sel); 9062 type_pos = 0; 9063 TLV_INIT(tlv2); 9064 while ((tlv2.type != _bcmFieldInternalEndStructExtractor) 9065 && (type_pos != num_types)) { 9066 TLV_INIT(tlv2); 9067 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 9068 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 9069 _FP_WB_TLV_BASIC_TYPE_SHIFT); 9070 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, ptr, pos)); 9071 switch (tlv2.type) { 9072 case _bcmFieldInternalExtl1e32Sel: 9073 sal_memcpy(ext_sel->l1_e32_sel, tlv2.value, tlv2.length); 9074 break; 9075 case _bcmFieldInternalExtl1e16Sel: 9076 sal_memcpy(ext_sel->l1_e16_sel, tlv2.value, tlv2.length); 9077 break; 9078 case _bcmFieldInternalExtl1e8Sel: 9079 sal_memcpy(ext_sel->l1_e8_sel, tlv2.value, tlv2.length); 9080 break; 9081 case _bcmFieldInternalExtl1e4Sel: 9082 sal_memcpy(ext_sel->l1_e4_sel, tlv2.value, tlv2.length); 9083 break; 9084 case _bcmFieldInternalExtl1e2Sel: 9085 sal_memcpy(ext_sel->l1_e2_sel, tlv2.value, tlv2.length); 9086 break; 9087 case _bcmFieldInternalExtl2e16Sel: 9088 sal_memcpy(ext_sel->l2_e16_sel, tlv2.value, tlv2.length); 9089 break; 9090 case _bcmFieldInternalExtl3e1Sel: 9091 sal_memcpy(ext_sel->l3_e1_sel, tlv2.value, tlv2.length); 9092 break; 9093 case _bcmFieldInternalExtl3e2Sel: 9094 sal_memcpy(ext_sel->l3_e2_sel, tlv2.value, tlv2.length); 9095 break; 9096 case _bcmFieldInternalExtl3e4Sel: 9097 sal_memcpy(ext_sel->l3_e4_sel, tlv2.value, tlv2.length); 9098 break; 9099 case _bcmFieldInternalExtPmuxSel: 9100 sal_memcpy(ext_sel->pmux_sel, tlv2.value, tlv2.length); 9101 break; 9102 case _bcmFieldInternalExtIntraSlice: 9103 ext_sel->intraslice = *(int8 *)tlv2.value; 9104 break; 9105 case _bcmFieldInternalExtSecondary: 9106 ext_sel->secondary = *(int8 *)tlv2.value; 9107 break; 9108 case _bcmFieldInternalExtIpbmpRes: 9109 ext_sel->ipbm_present = *(int8 *)tlv2.value; 9110 break; 9111 case _bcmFieldInternalExtNorml3l4: 9112 ext_sel->normalize_l3_l4_sel= *(int8 *)tlv2.value; 9113 break; 9114 case _bcmFieldInternalExtNormmac: 9115 ext_sel->normalize_mac_sel = *(int8 *)tlv2.value; 9116 break; 9117 case _bcmFieldInternalExtAuxTagaSel: 9118 ext_sel->aux_tag_a_sel = *(int8 *)tlv2.value; 9119 break; 9120 case _bcmFieldInternalExtAuxTagbSel: 9121 ext_sel->aux_tag_b_sel = *(int8 *)tlv2.value; 9122 break; 9123 9124 case _bcmFieldInternalExtAuxTagcSel: 9125 ext_sel->aux_tag_c_sel = *(int8 *)tlv2.value; 9126 break; 9127 case _bcmFieldInternalExtAuxTagdSel: 9128 ext_sel->aux_tag_d_sel = *(int8 *)tlv2.value; 9129 break; 9130 case _bcmFieldInternalExtTcpFnSel: 9131 ext_sel->tcp_fn_sel = *(int8 *)tlv2.value; 9132 break; 9133 case _bcmFieldInternalExtTosFnSel: 9134 ext_sel->tos_fn_sel = *(int8 *)tlv2.value; 9135 break; 9136 case _bcmFieldInternalExtTtlFnSel: 9137 ext_sel->ttl_fn_sel = *(int8 *)tlv2.value; 9138 break; 9139 case _bcmFieldInternalExtClassIdaSel: 9140 ext_sel->class_id_cont_a_sel = *(int8 *)tlv2.value; 9141 break; 9142 case _bcmFieldInternalExtClassIdbSel: 9143 ext_sel->class_id_cont_b_sel = *(int8 *)tlv2.value; 9144 break; 9145 case _bcmFieldInternalExtClassIdcSel: 9146 ext_sel->class_id_cont_c_sel = *(int8 *)tlv2.value; 9147 break; 9148 case _bcmFieldInternalExtClassIddSel: 9149 ext_sel->class_id_cont_d_sel = *(int8 *)tlv2.value; 9150 break; 9151 case _bcmFieldInternalExtSrcContaSel: 9152 ext_sel->src_cont_a_sel = *(int8 *)tlv2.value; 9153 break; 9154 case _bcmFieldInternalExtSrcContbSel: 9155 ext_sel->src_cont_b_sel = *(int8 *)tlv2.value; 9156 break; 9157 case _bcmFieldInternalExtSrcDestCont0Sel: 9158 ext_sel->src_dest_cont_0_sel = *(int8 *)tlv2.value; 9159 break; 9160 case _bcmFieldInternalExtSrcDestCont1Sel: 9161 ext_sel->src_dest_cont_1_sel = *(int8 *)tlv2.value; 9162 break; 9163 case _bcmFieldInternalExtKeygenIndex: 9164 ext_sel->keygen_index = *(uint32 *)tlv2.value; 9165 break; 9166 case _bcmFieldInternalExtAltTtlFnSel: 9167 ext_sel->alt_ttl_fn_sel = *(int8 *)tlv2.value; 9168 break; 9169 case _bcmFieldInternalEndStructExtractor: 9170 break; 9171 default: 9172 break; 9173 } 9174 type_pos++; 9175 } 9176 ext_sel++; 9177 } 9178 TLV_INIT(tlv2); 9179 return BCM_E_NONE; 9180 9181 } 9182 #define SLICE_STRUCT(_stage_, _ptr_, _pipenum_, _sliceid_) \ 9183 (_stage_->_ptr_[_pipenum_][_sliceid_]) \ 9184 9185 /* Function: 9186 * _field_cntrpool_recover 9187 * 9188 * Purpose: 9189 * recover _field_cntr_pool_t structure 9190 * 9191 * Paramaters: 9192 * unit - (IN) BCM device number 9193 * tlv - (IN) TLV structure for field 9194 * stage_fc - (OUT) Pointer to field stage structure 9195 * 9196 * Returns: 9197 * BCM_E_XXX 9198 */ 9199 9200 int 9201 _field_cntrpool_recover(int unit, _field_tlv_t *tlv, _field_stage_t *stage_fc) 9202 { 9203 int i = 0; /* local variable for loops */ 9204 uint32 *type; /* Elem type */ 9205 int num_types = 0; /* Number of types */ 9206 _field_tlv_t tlv2; /* TLV structure */ 9207 uint8 *scache_ptr; /* Scahce pointer */ 9208 uint32 *position; /* Scache position */ 9209 _field_control_t *fc; /* Field control structure.*/ 9210 int type_pos = 0; /* position of type */ 9211 int num_i_instances = 0; /* number of instances */ 9212 _field_cntr_pool_t *f_cp = NULL; /* Field counter pool structure */ 9213 9214 9215 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 9216 tlv2.value = NULL; 9217 TLV_INIT(tlv2); 9218 type = (uint32 *)tlv->value; 9219 num_i_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 9220 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 9221 _FP_WB_TLV_TYPE_SHIFT); 9222 9223 for (i = 0; i < num_i_instances; i++) { 9224 f_cp = stage_fc->cntr_pool[i]; 9225 type_pos = 0; 9226 while ((tlv2.type != _bcmFieldInternalEndStructCntr) 9227 && (type_pos != num_types)) { 9228 TLV_INIT(tlv2); 9229 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 9230 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 9231 _FP_WB_TLV_BASIC_TYPE_SHIFT); 9232 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, scache_ptr, position)); 9233 switch (tlv2.type) { 9234 case _bcmFieldInternalCntrSliceId: 9235 f_cp->slice_id = *(int8 *)tlv2.value; 9236 break; 9237 case _bcmFieldInternalCntrSize: 9238 f_cp->size = *(uint16 *)tlv2.value; 9239 break; 9240 case _bcmFieldInternalCntrFreeCntrs: 9241 f_cp->free_cntrs = *(uint16 *)tlv2.value; 9242 break; 9243 case _bcmFieldInternalCntrBmp: 9244 sal_memcpy(f_cp->cntr_bmp.w, tlv2.value, 9245 ((tlv2.length) 9246 * (recovery_type_map[unit][tlv2.type].size))); 9247 9248 break; 9249 case _bcmFieldInternalEndStructCntr: 9250 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_CNTR) { 9251 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 9252 "END MARKER CHECK FAILED : COUNTER\n"))); 9253 TLV_INIT(tlv2); 9254 return BCM_E_INTERNAL; 9255 } 9256 break; 9257 default: 9258 break; 9259 } 9260 type_pos++; 9261 9262 } 9263 TLV_INIT(tlv2); 9264 } 9265 9266 return BCM_E_NONE; 9267 } 9268 9269 /* Function: 9270 * _field_groupqualoffset_recover 9271 * 9272 * Purpose: 9273 * recover _bcm_field_qual_offset_t structure 9274 * 9275 * Paramaters: 9276 * unit - (IN) BCM device number 9277 * tlv - (IN) TLV structure for field 9278 * offset_arr - (OUT) Pointer to qualifier offset array structure 9279 * 9280 * Returns: 9281 * BCM_E_XXX 9282 */ 9283 9284 int 9285 _field_groupqualoffset_recover(int unit, _field_tlv_t *tlv, 9286 _bcm_field_qual_offset_t *offset_arr) 9287 { 9288 int i = 0; /* local variable for loops */ 9289 int num_instances = 0; /* number of instances */ 9290 uint32 *type; /* Elem type */ 9291 int num_types = 0; /* Number of types */ 9292 _field_tlv_t tlv2; /* TLV structure */ 9293 uint8 *scache_ptr; /* Scahce pointer */ 9294 uint32 *position; /* Scache position */ 9295 _field_control_t *fc; /* Field control structure.*/ 9296 int type_pos = 0; /* Position of type */ 9297 9298 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 9299 tlv2.value = NULL; 9300 TLV_INIT(tlv2); 9301 type = (uint32 *)tlv->value; 9302 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 9303 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 9304 _FP_WB_TLV_TYPE_SHIFT); 9305 9306 for (i = 0; i < num_instances; i++) { 9307 type_pos = 0; 9308 offset_arr[i].field = KEYf; 9309 while ((tlv2.type != _bcmFieldInternalEndStructQualOffset) 9310 && (type_pos != num_types)) { 9311 TLV_INIT(tlv2); 9312 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 9313 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 9314 _FP_WB_TLV_BASIC_TYPE_SHIFT); 9315 BCM_IF_ERROR_RETURN (tlv_read(unit, &tlv2, scache_ptr, position)); 9316 switch (tlv2.type) { 9317 case _bcmFieldInternalQualOffsetField: 9318 break; 9319 case _bcmFieldInternalQualOffsetNumOffset: 9320 offset_arr[i].num_offsets = * (uint8 *)tlv2.value; 9321 break; 9322 case _bcmFieldInternalQualOffsetOffsetArr: 9323 sal_memcpy(offset_arr[i].offset, tlv2.value, 9324 ((recovery_type_map[unit][tlv2.type].size) * tlv2.length)); 9325 break; 9326 case _bcmFieldInternalQualOffsetWidth: 9327 sal_memcpy(offset_arr[i].width, tlv2.value, 9328 ((recovery_type_map[unit][tlv2.type].size) * tlv2.length)); 9329 break; 9330 case _bcmFieldInternalQualOffsetSec: 9331 offset_arr[i].secondary = * (uint8 *)tlv2.value; 9332 break; 9333 case _bcmFieldInternalQualOffsetBitPos: 9334 offset_arr[i].bit_pos = * (uint8 *)tlv2.value; 9335 break; 9336 case _bcmFieldInternalQualOffsetQualWidth: 9337 offset_arr[i].qual_width = * (uint8 *)tlv2.value; 9338 break; 9339 case _bcmFieldInternalQualOffsetQualWidth16: 9340 offset_arr[i].qual_width = * (uint16 *)tlv2.value; 9341 break; 9342 case _bcmFieldInternalEndStructQualOffset: 9343 if (*(uint32 *)tlv2.value 9344 != _FIELD_WB_EM_QUALOFFSET) { 9345 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 9346 "END MARKER CHECK FAILED : " 9347 "QUALOFFSET\n"))); 9348 TLV_INIT(tlv2); 9349 return BCM_E_INTERNAL; 9350 } 9351 break; 9352 default: 9353 break; 9354 } 9355 type_pos++; 9356 9357 } 9358 TLV_INIT(tlv2); 9359 9360 } 9361 return BCM_E_NONE; 9362 9363 } 9364 9365 9366 /* Function: 9367 * _field_groupqual_recover 9368 * 9369 * Purpose: 9370 * recover _bcm_field_group_qual_t structure 9371 * 9372 * Paramaters: 9373 * unit - (IN) BCM device number 9374 * tlv - (IN) TLV structure for field 9375 * fg - (OUT) Pointer to field group structure 9376 * 9377 * Returns: 9378 * BCM_E_XXX 9379 */ 9380 9381 int 9382 _field_groupqual_recover(int unit, _field_tlv_t *tlv, _field_group_t *fg, 9383 _bcm_field_group_qual_t qual_arr[_FP_MAX_ENTRY_TYPES] 9384 [_FP_MAX_ENTRY_WIDTH], uint32 qual_count) 9385 { 9386 int j = 0; 9387 _field_tlv_t tlv2; /* TLV structure */ 9388 uint8 *scache_ptr; /* Scache pointer */ 9389 uint32 *position; /* Scache position */ 9390 _field_control_t *fc; /* Field control structure.*/ 9391 int num_instances = 0; /* Number of instances */ 9392 int rv = 0; /* Return Variable */ 9393 uint8 entry_type; /* Index to tcam entries of 9394 multiple types */ 9395 _bcm_field_group_qual_t *q_arr; /* Qualifiers array. */ 9396 int idx = 0; /* Loop index Variable */ 9397 9398 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 9399 tlv2.value = NULL; 9400 TLV_INIT(tlv2); 9401 num_instances = (tlv->length); 9402 9403 entry_type = _FP_ENTRY_TYPE_DEFAULT; 9404 9405 for (j = 0; j < num_instances; j++) { 9406 9407 while ((tlv2.type != _bcmFieldInternalEndStructGroupQual)) { 9408 TLV_INIT(tlv2); 9409 q_arr = NULL; 9410 /* coverity[no_write_call : FALSE] */ 9411 rv = tlv_read(unit, &tlv2, scache_ptr, position); 9412 BCM_IF_ERROR_CLEANUP(rv); 9413 9414 switch (tlv2.type) { 9415 case _bcmFieldInternalQualQid: 9416 _FP_XGS3_ALLOC(qual_arr[entry_type][j].qid_arr, 9417 ((recovery_type_map[unit][tlv2.type].size) 9418 * tlv2.length) , "FP Qual Array"); 9419 if (qual_arr[entry_type][j].qid_arr == NULL) { 9420 rv = BCM_E_MEMORY; 9421 goto cleanup; 9422 } 9423 sal_memcpy(qual_arr[entry_type][j].qid_arr, 9424 tlv2.value, 9425 ((recovery_type_map[unit][tlv2.type].size) 9426 * tlv2.length)); 9427 break; 9428 case _bcmFieldInternalQualSize: 9429 qual_arr[entry_type][j].size = * (uint16*)tlv2.value; 9430 break; 9431 case _bcmFieldInternalQualOffset: 9432 _FP_XGS3_ALLOC(qual_arr[entry_type][j].offset_arr, 9433 (sizeof(_bcm_field_qual_offset_t) 9434 *(fg->qual_arr[entry_type][j].size)), 9435 "FP Qual Array"); 9436 9437 if (qual_arr[entry_type][j].offset_arr == NULL) { 9438 rv = BCM_E_MEMORY; 9439 goto cleanup; 9440 } 9441 BCM_IF_ERROR_RETURN( 9442 _field_groupqualoffset_recover(unit, 9443 &tlv2, 9444 qual_arr[entry_type][j].offset_arr)); 9445 break; 9446 case _bcmFieldInternalEndStructGroupQual: 9447 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_QUAL) { 9448 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 9449 "END MARKER CHECK FAILED : QUAL\n"))); 9450 rv = BCM_E_INTERNAL; 9451 goto cleanup; 9452 } 9453 break; 9454 default: 9455 break; 9456 } 9457 } 9458 if (qual_count != 0) { 9459 q_arr = &(qual_arr[entry_type][j]); 9460 for (idx = 0; idx < q_arr->size; idx++) { 9461 if (q_arr->qid_arr[idx] >= qual_count) { 9462 q_arr->qid_arr[idx] = (q_arr->qid_arr[idx] - qual_count) 9463 + bcmFieldQualifyCount; 9464 } 9465 } 9466 } 9467 TLV_INIT(tlv2); 9468 } 9469 9470 return BCM_E_NONE; 9471 9472 cleanup: 9473 TLV_INIT(tlv2); 9474 if (qual_arr[entry_type][j].qid_arr != NULL) { 9475 sal_free(qual_arr[entry_type][j].qid_arr); 9476 qual_arr[entry_type][j].qid_arr = NULL; 9477 } 9478 if (qual_arr[entry_type][j].offset_arr != NULL) { 9479 sal_free(qual_arr[entry_type][j].offset_arr); 9480 qual_arr[entry_type][j].offset_arr = NULL; 9481 } 9482 9483 return rv; 9484 9485 } 9486 9487 /* Function: 9488 * _field_ltinfo_recover 9489 * 9490 * Purpose: 9491 * recover _field_lt_config_t structure 9492 * 9493 * Paramaters: 9494 * unit - (IN) BCM device number 9495 * tlv - (IN) TLV structure for field 9496 * stage_fc - (OUT) Pointer to field stage structure 9497 * 9498 * Returns: 9499 * BCM_E_XXX 9500 */ 9501 9502 int 9503 _field_ltinfo_recover(int unit, _field_tlv_t *tlv) 9504 { 9505 int i = 0; /* local variable for loops */ 9506 int j = 0; 9507 uint32 *type; /* Elem type */ 9508 int num_types = 0; /* Number of types */ 9509 _field_tlv_t tlv2; /* TLV structure */ 9510 uint8 *scache_ptr; /* Scahce pointer */ 9511 uint32 *position; /* Scache position */ 9512 _field_control_t *fc; /* Field control structure.*/ 9513 int type_pos = 0; /* position of type */ 9514 int num_i_instances = 0; /* num_instances in 1st dimension */ 9515 int num_j_instances = 0; /* num_instances in 2nd dimension */ 9516 _field_lt_config_t *f_cfg = NULL; /* Field config for LT */ 9517 9518 tlv2.value = NULL; 9519 TLV_INIT(tlv2); 9520 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 9521 type = (uint32 *)tlv->value; 9522 num_i_instances = (tlv->length) & 0x000003ff; 9523 num_j_instances = ((tlv->length) & 0x003ffc00) >> 10; 9524 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 9525 _FP_WB_TLV_TYPE_SHIFT); 9526 9527 for (i = 0; i < num_i_instances; i++) { 9528 if (!(fc->pipe_map & (1 << i))) { 9529 continue; 9530 } 9531 for (j = 0; j < num_j_instances; j++) { 9532 9533 f_cfg = fc->lt_info[i][j]; 9534 type_pos = 0; 9535 9536 while ((tlv2.type != _bcmFieldInternalEndStructLtConfig) 9537 && (type_pos != num_types)) { 9538 TLV_INIT(tlv2); 9539 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 9540 tlv2.basic_type = ((type[type_pos] 9541 & _FP_WB_TLV_BASIC_TYPE_MASK) >> 9542 _FP_WB_TLV_BASIC_TYPE_SHIFT); 9543 BCM_IF_ERROR_RETURN( 9544 tlv_read(unit, &tlv2, scache_ptr, position)); 9545 switch (tlv2.type) { 9546 case _bcmFieldInternalLtConfigValid: 9547 f_cfg->valid = *(int *) tlv2.value; 9548 break; 9549 case _bcmFieldInternalLtConfigLtId: 9550 f_cfg->lt_id = *(int *) tlv2.value; 9551 break; 9552 case _bcmFieldInternalLtConfigLtPartPri: 9553 sal_memcpy(f_cfg->lt_part_pri, tlv2.value, 9554 ((tlv2.length) 9555 * (recovery_type_map[unit][tlv2.type].size))); 9556 break; 9557 case _bcmFieldInternalLtConfigLtPartMap: 9558 f_cfg->lt_part_map = *(uint32 *)tlv2.value; 9559 break; 9560 case _bcmFieldInternalLtConfigLtActionPri: 9561 f_cfg->lt_action_pri = *(int *) tlv2.value; 9562 break; 9563 case _bcmFieldInternalLtConfigPri: 9564 f_cfg->priority = *(int *) tlv2.value; 9565 break; 9566 case _bcmFieldInternalLtConfigFlags: 9567 f_cfg->flags = *(int *) tlv2.value; 9568 break; 9569 case _bcmFieldInternalLtConfigEntry: 9570 f_cfg->lt_entry = *(bcm_field_entry_t *) tlv2.value; 9571 break; 9572 case _bcmFieldInternalEndStructLtConfig: 9573 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_LTCONF) { 9574 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 9575 "END MARKER CHECK FAILED : LTCONF\n"))); 9576 TLV_INIT(tlv2); 9577 return BCM_E_INTERNAL; 9578 } 9579 break; 9580 default: 9581 break; 9582 } 9583 type_pos++; 9584 9585 } 9586 TLV_INIT(tlv2); 9587 } 9588 } 9589 9590 return BCM_E_NONE; 9591 } 9592 9593 /* Function: 9594 * _field_range_recover 9595 * 9596 * Purpose: 9597 * recover _field_range_t structure 9598 * 9599 * Paramaters: 9600 * unit - (IN) BCM device number 9601 * tlv - (IN) TLV structure for field 9602 * stage_fc - (OUT) Pointer to field stage structure 9603 * 9604 * Returns: 9605 * BCM_E_XXX 9606 */ 9607 9608 int 9609 _field_range_recover(int unit, _field_tlv_t *tlv, _field_stage_t *stage_fc) 9610 { 9611 int i = 0; /* local variable for loops */ 9612 int num_instances = 0; /* number of instances */ 9613 uint32 *type; /* Elem type */ 9614 int num_types = 0; /* Number of types */ 9615 _field_tlv_t tlv2; /* TLV structure */ 9616 uint8 *scache_ptr; /* Scahce pointer */ 9617 uint32 *position; /* Scache position */ 9618 _field_control_t *fc; /* Field control structure.*/ 9619 _field_range_t *new_fr = NULL; /* New field range structure */ 9620 _field_range_t *prev_fr = NULL; /* Prev field range structure */ 9621 int type_pos = 0; /* Positon of type */ 9622 int rv = 0; /* Return variable */ 9623 9624 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 9625 tlv2.value = NULL; 9626 TLV_INIT(tlv2); 9627 type = (uint32 *)tlv->value; 9628 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 9629 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 9630 _FP_WB_TLV_TYPE_SHIFT); 9631 9632 for (i = 0; i < num_instances; i++) { 9633 _FP_XGS3_ALLOC(new_fr, sizeof(_field_range_t), "FP Range"); 9634 if (NULL == new_fr) { 9635 rv = BCM_E_MEMORY; 9636 goto cleanup; 9637 } 9638 type_pos = 0; 9639 while ((tlv2.type != _bcmFieldInternalEndStructRanges) 9640 && (type_pos != num_types)) { 9641 TLV_INIT(tlv2); 9642 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 9643 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 9644 _FP_WB_TLV_BASIC_TYPE_SHIFT); 9645 rv = tlv_read(unit, &tlv2, scache_ptr, position); 9646 BCM_IF_ERROR_CLEANUP(rv); 9647 switch (tlv2.type) { 9648 case _bcmFieldInternalRangeFlags: 9649 new_fr->flags = *(uint32 *)tlv2.value; 9650 break; 9651 case _bcmFieldInternalRangeRid: 9652 new_fr->rid = *(bcm_field_range_t *)tlv2.value; 9653 break; 9654 case _bcmFieldInternalRangeMin: 9655 new_fr->min = *(bcm_l4_port_t *)tlv2.value; 9656 break; 9657 case _bcmFieldInternalRangeMax: 9658 new_fr->max = *(bcm_l4_port_t *)tlv2.value; 9659 break; 9660 case _bcmFieldInternalRangeHwIndex: 9661 new_fr->hw_index = *(int *)tlv2.value; 9662 break; 9663 case _bcmFieldInternalRangeStyle: 9664 new_fr->style = *(uint8 *)tlv2.value; 9665 break; 9666 case _bcmFieldInternalEndStructRanges: 9667 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_RANGE) { 9668 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 9669 "END MARKER CHECK FAILED : RANGE\n"))); 9670 rv = BCM_E_INTERNAL; 9671 goto cleanup; 9672 } 9673 break; 9674 default: 9675 break; 9676 } 9677 type_pos++; 9678 9679 } 9680 new_fr->next = prev_fr; 9681 prev_fr = new_fr; 9682 new_fr = NULL; 9683 TLV_INIT(tlv2); 9684 9685 } 9686 9687 cleanup: 9688 TLV_INIT(tlv2); 9689 stage_fc->ranges = prev_fr; 9690 9691 if (new_fr != NULL) { 9692 sal_free(new_fr); 9693 new_fr = NULL; 9694 } 9695 return rv; 9696 } 9697 9698 /* Function: 9699 * _field_datacontroldataqualifier_recover 9700 * 9701 * Purpose: 9702 * recover _field_data_qualifier_t structure 9703 * 9704 * Paramaters: 9705 * unit - (IN) BCM device number 9706 * tlv - (IN) TLV structure for field 9707 * fd - (IN) Field data control structure 9708 * Returns: 9709 * BCM_E_XXX 9710 */ 9711 9712 int 9713 _field_datacontroldataqualifier_recover(int unit, _field_tlv_t *tlv, 9714 _field_data_control_t *fd) 9715 { 9716 int i = 0; /* local variable for loops */ 9717 int num_instances = 0; /* number of instances */ 9718 _field_tlv_t tlv2; /* TLV structure */ 9719 uint8 *scache_ptr; /* Scahce pointer */ 9720 uint32 *position; /* Scache position */ 9721 _field_control_t *fc; /* Field control structure.*/ 9722 _field_data_qualifier_p new_f_dq = NULL; /* New qualifier */ 9723 _field_data_qualifier_p prev_f_dq = NULL; /* Prev qualifier */ 9724 int rv = 0; /* Return variable */ 9725 9726 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 9727 tlv2.value = NULL; 9728 TLV_INIT(tlv2); 9729 num_instances = (tlv->length); 9730 9731 for (i = 0; i < num_instances; i++) { 9732 9733 _FP_XGS3_ALLOC(new_f_dq, sizeof(_field_data_qualifier_t), 9734 "FP data qualifier"); 9735 if (NULL == new_f_dq) { 9736 rv = BCM_E_MEMORY; 9737 goto cleanup; 9738 } 9739 9740 _FP_XGS3_ALLOC(new_f_dq->spec, sizeof(bcm_field_udf_spec_t), 9741 " FP data qualifier spec "); 9742 if (NULL == new_f_dq->spec) { 9743 rv = BCM_E_MEMORY; 9744 goto cleanup; 9745 } 9746 9747 9748 while (tlv2.type != _bcmFieldInternalDataControlEndStructDataQual) { 9749 TLV_INIT(tlv2); 9750 /* coverity[no_write_call : FALSE] */ 9751 rv = tlv_read(unit, &tlv2, scache_ptr, position); 9752 if (rv < 0 ) { 9753 goto cleanup; 9754 } 9755 9756 switch (tlv2.type) { 9757 case _bcmFieldInternalDataControlDataQualQid: 9758 new_f_dq->qid = *(int *)tlv2.value; 9759 break; 9760 case _bcmFieldInternalDataControlDataQualUdfSpec: 9761 sal_memcpy(new_f_dq->spec->offset,tlv2.value,tlv2.length); 9762 break; 9763 case _bcmFieldInternalDataControlDataQualOffsetBase: 9764 new_f_dq->offset_base = * (bcm_field_data_offset_base_t *) 9765 tlv2.value; 9766 break; 9767 case _bcmFieldInternalDataControlDataQualOffset: 9768 new_f_dq->offset = * (int *)tlv2.value; 9769 break; 9770 case _bcmFieldInternalDataControlDataQualByteOffset: 9771 new_f_dq->byte_offset = * (uint8 *)tlv2.value; 9772 break; 9773 case _bcmFieldInternalDataControlDataQualHwBmp: 9774 new_f_dq->hw_bmap = * (uint32 *)tlv2.value; 9775 break; 9776 case _bcmFieldInternalDataControlDataQualFlags: 9777 new_f_dq->flags = * (uint32 *)tlv2.value; 9778 break; 9779 case _bcmFieldInternalDataControlDataQualElemCount: 9780 new_f_dq->elem_count = * (uint32 *)tlv2.value; 9781 break; 9782 case _bcmFieldInternalDataControlDataQualLength: 9783 new_f_dq->length = * (int *)tlv2.value; 9784 break; 9785 case _bcmFieldInternalDataControlEndStructDataQual: 9786 if (*(int *)tlv2.value != _FIELD_WB_EM_DATAQUAL) { 9787 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 9788 "END MARKER CHECK FAILED : DATAQUAL\n"))); 9789 rv = BCM_E_INTERNAL; 9790 goto cleanup; 9791 } 9792 break; 9793 default: 9794 break; 9795 } 9796 } 9797 new_f_dq->next = prev_f_dq; 9798 prev_f_dq = new_f_dq; 9799 new_f_dq = NULL; 9800 TLV_INIT(tlv2); 9801 9802 } 9803 9804 cleanup: 9805 TLV_INIT(tlv2); 9806 fd->data_qual = prev_f_dq; 9807 9808 if (new_f_dq != NULL) { 9809 if (new_f_dq->spec != NULL) { 9810 sal_free(new_f_dq->spec); 9811 new_f_dq->spec = NULL; 9812 } 9813 sal_free(new_f_dq); 9814 new_f_dq = NULL; 9815 } 9816 return rv; 9817 9818 } 9819 9820 /* Function: 9821 * _field_datacontrolprot_recover 9822 * 9823 * Purpose: 9824 * recover _field_data_protocol_t structure 9825 * 9826 * Paramaters: 9827 * unit - (IN) BCM device number 9828 * tlv - (IN) TLV structure for field 9829 * fd - (IN) Field data control structure 9830 * Returns: 9831 * BCM_E_XXX 9832 */ 9833 9834 int 9835 _field_datacontrolprot_recover(int unit, _field_tlv_t *tlv, 9836 _field_data_control_t *fd) 9837 { 9838 int i = 0; /* local variable for loops */ 9839 int num_instances = 0; /* number of instances */ 9840 uint32 *type; /* Elem type */ 9841 int num_types = 0; /* Number of types */ 9842 _field_tlv_t tlv2; /* TLV structure */ 9843 uint8 *scache_ptr; /* Scahce pointer */ 9844 uint32 *position; /* Scache position */ 9845 _field_control_t *fc; /* Field control structure.*/ 9846 int type_pos = 0; /* Positon of type */ 9847 9848 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 9849 tlv2.value = NULL; 9850 TLV_INIT(tlv2); 9851 type = (uint32 *)tlv->value; 9852 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 9853 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 9854 _FP_WB_TLV_TYPE_SHIFT); 9855 9856 for (i = 0; i < num_instances; i++) { 9857 type_pos = 0; 9858 while ((tlv2.type != _bcmFieldInternalDataControlEndStructProt) 9859 && (type_pos != num_types)) { 9860 TLV_INIT(tlv2); 9861 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 9862 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 9863 _FP_WB_TLV_BASIC_TYPE_SHIFT); 9864 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, scache_ptr, position)); 9865 switch (tlv2.type) { 9866 case _bcmFieldInternalDataControlProtIp4RefCount: 9867 fd->ip[i].ip4_ref_count = *(int *)tlv2.value; 9868 break; 9869 case _bcmFieldInternalDataControlProtIp6RefCount: 9870 fd->ip[i].ip6_ref_count = *(int *)tlv2.value; 9871 break; 9872 case _bcmFieldInternalDataControlProtFlags: 9873 fd->ip[i].flags = *(uint32 *)tlv2.value; 9874 break; 9875 case _bcmFieldInternalDataControlProtIp: 9876 fd->ip[i].ip = *(uint8 *)tlv2.value; 9877 break; 9878 case _bcmFieldInternalDataControlProtL2: 9879 fd->ip[i].l2 = *(uint16 *)tlv2.value; 9880 break; 9881 case _bcmFieldInternalDataControlProtVlanTag: 9882 fd->ip[i].vlan_tag = *(uint16 *)tlv2.value; 9883 break; 9884 case _bcmFieldInternalDataControlProtRelOffset: 9885 fd->ip[i].relative_offset = *(int *)tlv2.value; 9886 break; 9887 case _bcmFieldInternalDataControlEndStructProt: 9888 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_DATAPROT) { 9889 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 9890 "END MARKER CHECK FAILED : DATAPROT\n"))); 9891 TLV_INIT(tlv2); 9892 return BCM_E_INTERNAL; 9893 } 9894 break; 9895 default: 9896 break; 9897 } 9898 type_pos++; 9899 9900 } 9901 TLV_INIT(tlv2); 9902 } 9903 return BCM_E_NONE; 9904 } 9905 9906 9907 /* Function: 9908 * _field_datacontrolethertype_recover 9909 * 9910 * Purpose: 9911 * recover _field_data_ethertype_t structure 9912 * 9913 * Paramaters: 9914 * unit - (IN) BCM device number 9915 * tlv - (IN) TLV structure for field 9916 * fd - (IN) Field data control structure 9917 * Returns: 9918 * BCM_E_XXX 9919 */ 9920 9921 int 9922 _field_datacontrolethertype_recover(int unit, _field_tlv_t *tlv, 9923 _field_data_control_t *fd) 9924 { 9925 int i = 0; /* local variable for loops */ 9926 int num_instances = 0; /* number of instances */ 9927 uint32 *type; /* Elem type */ 9928 int num_types = 0; /* Number of types */ 9929 _field_tlv_t tlv2; /* TLV structure */ 9930 uint8 *scache_ptr; /* Scahce pointer */ 9931 uint32 *position; /* Scache position */ 9932 _field_control_t *fc; /* Field control structure.*/ 9933 int type_pos = 0; /* Positon of type */ 9934 9935 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 9936 tlv2.value = NULL; 9937 TLV_INIT(tlv2); 9938 type = (uint32 *)tlv->value; 9939 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 9940 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 9941 _FP_WB_TLV_TYPE_SHIFT); 9942 9943 for (i = 0; i < num_instances; i++) { 9944 type_pos = 0; 9945 while ((tlv2.type != _bcmFieldInternalDataControlEndStructEtype) 9946 && (type_pos != num_types)) { 9947 TLV_INIT(tlv2); 9948 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 9949 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 9950 _FP_WB_TLV_BASIC_TYPE_SHIFT); 9951 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, scache_ptr, position)); 9952 switch (tlv2.type) { 9953 case _bcmFieldInternalDataControlEthertypeRefCount: 9954 fd->etype[i].ref_count = * (int *)tlv2.value; 9955 break; 9956 9957 case _bcmFieldInternalDataControlEthertypeL2: 9958 fd->etype[i].l2 = * (uint16 *)tlv2.value; 9959 break; 9960 9961 case _bcmFieldInternalDataControlEthertypeVlanTag: 9962 fd->etype[i].vlan_tag = * (uint16 *)tlv2.value; 9963 break; 9964 9965 case _bcmFieldInternalDataControlEthertypePortEt: 9966 fd->etype[i].ethertype = * (bcm_port_ethertype_t *) 9967 tlv2.value; 9968 break; 9969 9970 case _bcmFieldInternalDataControlEthertypeRelOffset: 9971 fd->etype[i].relative_offset = * (int *)tlv2.value; 9972 break; 9973 9974 case _bcmFieldInternalDataControlEndStructEtype: 9975 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_DATAETYPE) { 9976 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 9977 "END MARKER CHECK FAILED : DATATYPE\n"))); 9978 TLV_INIT(tlv2); 9979 return BCM_E_INTERNAL; 9980 } 9981 break; 9982 default: 9983 break; 9984 } 9985 type_pos++; 9986 9987 } 9988 TLV_INIT(tlv2); 9989 } 9990 return BCM_E_NONE; 9991 } 9992 9993 /* Function: 9994 * _field_datacontroltcamentry_recover 9995 * 9996 * Purpose: 9997 * recover _field_data_tcam_entry_t structure 9998 * 9999 * Paramaters: 10000 * unit - (IN) BCM device number 10001 * tlv - (IN) TLV structure for field 10002 * fd - (IN) Field data control structure 10003 * Returns: 10004 * BCM_E_XXX 10005 */ 10006 10007 int 10008 _field_datacontroltcamentry_recover(int unit, _field_tlv_t *tlv, 10009 _field_data_control_t *fd) 10010 { 10011 int i = 0; /* local variable for loops */ 10012 int num_instances = 0; /* number of instances */ 10013 uint32 *type; /* Elem type */ 10014 _field_tlv_t tlv2; /* TLV structure */ 10015 uint8 *scache_ptr; /* Scahce pointer */ 10016 uint32 *position; /* Scache position */ 10017 _field_control_t *fc; /* Field control structure.*/ 10018 _field_data_tcam_entry_t *fent = NULL; /* Field tcam entry */ 10019 int type_pos = 0; /* Positon of type */ 10020 int num_types = 0; /* Number of types */ 10021 10022 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 10023 tlv2.value = NULL; 10024 TLV_INIT(tlv2); 10025 type = (uint32 *)tlv->value; 10026 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 10027 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 10028 _FP_WB_TLV_TYPE_SHIFT); 10029 10030 fent = fd->tcam_entry_arr; 10031 if (fent == NULL) { 10032 /* data control not initilaized */ 10033 return BCM_E_INIT; 10034 } 10035 10036 for (i = 0; i < num_instances; i++) { 10037 type_pos = 0; 10038 while ((tlv2.type != _bcmFieldInternalDataControlEndStructTcam) 10039 && (type_pos != num_types)) { 10040 TLV_INIT(tlv2); 10041 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 10042 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 10043 _FP_WB_TLV_BASIC_TYPE_SHIFT); 10044 10045 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, scache_ptr, position)); 10046 switch (tlv2.type) { 10047 case _bcmFieldInternalDataControlTcamRefCount: 10048 fent->ref_count = * (uint8 *)tlv2.value; 10049 break; 10050 case _bcmFieldInternalDataControlTcamPriority: 10051 fent->priority = * (uint8 *)tlv2.value; 10052 break; 10053 case _bcmFieldInternalDataControlEndStructTcam: 10054 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_DATATCAM) { 10055 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 10056 "END MARKER CHECK FAILED : DATATCAM\n"))); 10057 TLV_INIT(tlv2); 10058 return BCM_E_INTERNAL; 10059 } 10060 break; 10061 default: 10062 break; 10063 } 10064 type_pos++; 10065 } 10066 fent++; 10067 TLV_INIT(tlv2); 10068 } 10069 return BCM_E_NONE; 10070 } 10071 10072 10073 /* Function: 10074 * _field_data_control_recover 10075 * 10076 * Purpose: 10077 * recover _field_data_control_t structure 10078 * 10079 * Paramaters: 10080 * unit - (IN) BCM device number 10081 * tlv - (IN) TLV structure for field 10082 * stage_fc - (OUT) Pointer to field stage structure 10083 * 10084 * Returns: 10085 * BCM_E_XXX 10086 */ 10087 10088 int 10089 _field_data_control_recover(int unit, _field_tlv_t *tlv, 10090 _field_stage_t *stage_fc) 10091 { 10092 _field_tlv_t tlv2; /* Field TLV structure */ 10093 uint8 *scache_ptr = NULL; /* Pointer to Scache */ 10094 uint32 *position = NULL; /* Position in Scache */ 10095 _field_control_t *fc; /* Field control structure.*/ 10096 _field_data_control_t *fd = NULL;/* Field Data control structure */ 10097 10098 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 10099 tlv2.value = NULL; /* Initialize value */ 10100 TLV_INIT(tlv2); 10101 fd = stage_fc->data_ctrl; 10102 10103 10104 while (tlv2.type != _bcmFieldInternalEndStructDataControl) { 10105 TLV_INIT(tlv2); 10106 /* coverity[no_write_call : FALSE] */ 10107 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, scache_ptr, position)); 10108 10109 switch (tlv2.type) 10110 { 10111 case _bcmFieldInternalDataControlUsageBmp: 10112 fd->usage_bmap = * (uint32 *)tlv2.value; 10113 break; 10114 case _bcmFieldInternalDataControlDataQualStruct: 10115 BCM_IF_ERROR_RETURN( 10116 _field_datacontroldataqualifier_recover(unit, 10117 &tlv2, 10118 fd)); 10119 break; 10120 case _bcmFieldInternalDataControlElemSize: 10121 fd->elem_size = *(int *)tlv2.value; 10122 break; 10123 case _bcmFieldInternalDataControlNumElem: 10124 fd->num_elems = *(int *)tlv2.value; 10125 break; 10126 case _bcmFieldInternalDataControlEthertypeStruct: 10127 BCM_IF_ERROR_RETURN(_field_datacontrolethertype_recover(unit, 10128 &tlv2, 10129 fd)); 10130 break; 10131 case _bcmFieldInternalDataControlProtStart: 10132 BCM_IF_ERROR_RETURN(_field_datacontrolprot_recover(unit, 10133 &tlv2, 10134 fd)); 10135 break; 10136 case _bcmFieldInternalDataControlTcamStruct: 10137 BCM_IF_ERROR_RETURN(_field_datacontroltcamentry_recover(unit, 10138 &tlv2, 10139 fd)); 10140 10141 break; 10142 case _bcmFieldInternalEndStructDataControl: 10143 if (*(uint32 *)tlv2.value != _FIELD_WB_EM_DATACONTROL) { 10144 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 10145 "END MARKER CHECK FAILED : DATACONTROL\n"))); 10146 TLV_INIT(tlv2); 10147 return BCM_E_INTERNAL; 10148 } 10149 break; 10150 default: 10151 break; 10152 } 10153 } 10154 TLV_INIT(tlv2); 10155 10156 return BCM_E_NONE; 10157 } 10158 10159 10160 /* Function: 10161 * _field_stage_recover 10162 * 10163 * Purpose: 10164 * recover _field_stage_t structure 10165 * 10166 * Paramaters: 10167 * unit - (IN) BCM device number 10168 * stage_fc - (IN) Pointer to device stage structure 10169 * 10170 * Returns: 10171 * BCM_E_XXX 10172 */ 10173 10174 int 10175 _field_stage_recover(int unit, _field_stage_t **stage_fc) 10176 { 10177 _field_tlv_t tlv; /* Field TLV structure */ 10178 uint8 *scache_ptr = NULL; /* Pointer to Scache */ 10179 uint32 *position = NULL; /* Position in Scache */ 10180 _field_control_t *fc; /* Field control structure.*/ 10181 10182 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 10183 tlv.value = NULL; /* Initialize value */ 10184 TLV_INIT(tlv); 10185 10186 10187 while (tlv.type != _bcmFieldInternalEndStructStage) { 10188 TLV_INIT(tlv); 10189 /* coverity[no_write_call : FALSE] */ 10190 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv, scache_ptr, position)); 10191 10192 switch (tlv.type) 10193 { 10194 case _bcmFieldInternalStageStageid: 10195 (*stage_fc)->stage_id = *(_field_stage_id_t *)tlv.value; 10196 break; 10197 case _bcmFieldInternalStageFlags: 10198 (*stage_fc)->flags = *(int *)tlv.value; 10199 break; 10200 case _bcmFieldInternalStageTcamSz: 10201 (*stage_fc)->tcam_sz = *(int *)tlv.value; 10202 break; 10203 case _bcmFieldInternalStageTcamSlices: 10204 (*stage_fc)->tcam_slices = *(int *)tlv.value; 10205 break; 10206 case _bcmFieldInternalStageNumInstances: 10207 (*stage_fc)->num_instances = *(int *)tlv.value; 10208 break; 10209 case _bcmFieldInternalStageNumPipes: 10210 (*stage_fc)->num_pipes = *(int *)tlv.value; 10211 break; 10212 case _bcmFieldInternalStageRangeId: 10213 (*stage_fc)->range_id = *(uint32 *)tlv.value; 10214 break; 10215 case _bcmFieldInternalStageNumMeterPools: 10216 (*stage_fc)->num_meter_pools = *(int *)tlv.value; 10217 break; 10218 case _bcmFieldInternalStageNumCntrPools: 10219 (*stage_fc)->num_cntr_pools = *(unsigned *)tlv.value; 10220 break; 10221 case _bcmFieldInternalStageLtTcamSz: 10222 (*stage_fc)->lt_tcam_sz = *(int *)tlv.value; 10223 break; 10224 case _bcmFieldInternalStageNumLogicalTables: 10225 (*stage_fc)->num_logical_tables = *(int *)tlv.value; 10226 break; 10227 case _bcmFieldInternalStageExtLevels: 10228 (*stage_fc)->num_ext_levels = *(int *)tlv.value; 10229 break; 10230 case _bcmFieldInternalStageOperMode: 10231 if ((*(bcm_field_group_oper_mode_t *)tlv.value) 10232 == bcmFieldGroupOperModePipeLocal) { 10233 BCM_IF_ERROR_RETURN(_bcm_field_wb_group_oper_mode_set(unit, 10234 bcmFieldQualifyStageIngress, 10235 stage_fc, 10236 bcmFieldGroupOperModePipeLocal)); 10237 } 10238 break; 10239 case _bcmFieldInternalStageRanges: 10240 BCM_IF_ERROR_RETURN(_field_range_recover(unit, 10241 &tlv, (*stage_fc))); 10242 break; 10243 case _bcmFieldInternalStageMeterPool: 10244 BCM_IF_ERROR_RETURN(_field_meterpool_recover(unit, 10245 &tlv, (*stage_fc))); 10246 break; 10247 case _bcmFieldInternalStageCntrPools: 10248 BCM_IF_ERROR_RETURN(_field_cntrpool_recover(unit, 10249 &tlv, (*stage_fc))); 10250 break; 10251 case _bcmFieldInternalStageLtInfo: 10252 BCM_IF_ERROR_RETURN(_field_ltinfo_recover(unit, 10253 &tlv)); 10254 break; 10255 case _bcmFieldInternalDataControlStart: 10256 BCM_IF_ERROR_RETURN(_field_data_control_recover(unit, 10257 &tlv, 10258 (*stage_fc))); 10259 break; 10260 case _bcmFieldInternalStageLtActionPri: 10261 (*stage_fc)->lt_action_pri = *(int *)tlv.value; 10262 break; 10263 case _bcmFieldInternalStageGrpRunningPrio: 10264 (*stage_fc)->group_running_prio = *(int *)tlv.value; 10265 break; 10266 case _bcmFieldInternalStagePreselQset: 10267 if (downgrade[unit] ==TRUE) { 10268 sal_memcpy(&((*stage_fc)->presel_qset.w), tlv.value, 10269 (recovery_type_map[unit][tlv.type].size * 10270 _SHR_BITDCLSIZE(BCM_FIELD_QUALIFY_MAX))); 10271 } else { 10272 sal_memcpy(&((*stage_fc)->presel_qset.w), tlv.value, 10273 (recovery_type_map[unit][tlv.type].size * tlv.length)); 10274 } 10275 break; 10276 #if defined BCM_TRIDENT3_SUPPORT 10277 case _bcmFieldInternalStageAuxTagIBusContStatus: 10278 BCM_IF_ERROR_RETURN(_field_auxtag_ibus_cont_recover(unit, 10279 &tlv, (*stage_fc))); 10280 break; 10281 #endif 10282 case _bcmFieldInternalEndStructStage: 10283 if (*(uint32 *)tlv.value != _FIELD_WB_EM_STAGE) { 10284 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 10285 "END MARKER CHECK FAILED : STAGE\n"))); 10286 TLV_INIT(tlv); 10287 return BCM_E_INTERNAL; 10288 } 10289 break; 10290 default: 10291 break; 10292 } 10293 } 10294 TLV_INIT(tlv); 10295 10296 return BCM_E_NONE; 10297 } 10298 10299 /* Function: 10300 * _field_slice_recover 10301 * 10302 * Purpose: 10303 * recover _field_slice_t structure 10304 * 10305 * Paramaters: 10306 * unit - (IN) BCM device number 10307 * pipe_id - (IN) Pipe to which this slice belongs 10308 * slice - (IN) Pointer to device slice structure 10309 * 10310 * Returns: 10311 * BCM_E_XXX 10312 */ 10313 10314 int 10315 _field_slice_recover(int unit, int pipe_id, _field_slice_t *slice) 10316 { 10317 _field_tlv_t tlv; /* tlv structure */ 10318 _field_control_t *fc = NULL; /* Field control structure */ 10319 _field_stage_t *stage_fc = NULL; /* Field stage structure */ 10320 uint8 *scache_ptr; /* Pointer to scache_ptr */ 10321 uint8 temp_id; /* temp variable to store next 10322 * or prev slice id's 10323 */ 10324 uint32 *position; /* pointer to scache_pos */ 10325 uint8 slice_flags8 = 0; /* LSB 8-bit slice flags */ 10326 uint32 slice_flags24 = 0; /* MSB 24-bit slice flags */ 10327 10328 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 10329 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, _BCM_FIELD_STAGE_INGRESS, 10330 &stage_fc)); 10331 tlv.value = NULL; 10332 TLV_INIT(tlv); 10333 10334 while (tlv.type != _bcmFieldInternalEndStructSlice) { 10335 TLV_INIT(tlv); 10336 /* coverity[no_write_call : FALSE] */ 10337 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv, scache_ptr, position)); 10338 10339 switch (tlv.type) { 10340 10341 case _bcmFieldInternalSliceNumber: 10342 slice->slice_number = *(uint8 *)tlv.value; 10343 break; 10344 case _bcmFieldInternalSliceStartTcamIdx: 10345 slice->start_tcam_idx = *(int *)tlv.value; 10346 break; 10347 case _bcmFieldInternalSliceEntryCount: 10348 slice->entry_count = *(int *)tlv.value; 10349 break; 10350 case _bcmFieldInternalSliceFreeCount: 10351 slice->free_count = *(int *)tlv.value; 10352 break; 10353 case _bcmFieldInternalSliceCountersCount: 10354 slice->counters_count = *(int *)tlv.value; 10355 break; 10356 case _bcmFieldInternalSliceMetersCount: 10357 slice->meters_count = *(int *)tlv.value; 10358 break; 10359 case _bcmFieldInternalSliceInstalledEntriesCount: 10360 /* slice->hw_ent_count = *(int *)tlv.value; */ 10361 slice->hw_ent_count = 0; 10362 /* Since calculcation was wrong in older releases, 10363 * resetting this field to 0 and then doing manual 10364 * calculation during entry recover 10365 */ 10366 break; 10367 case _bcmFieldInternalSliceCounterBmp: 10368 sal_memcpy(&(slice->counter_bmp), tlv.value, 10369 tlv.length); 10370 break; 10371 case _bcmFieldInternalSliceMeterBmp: 10372 sal_memcpy(&(slice->meter_bmp), tlv.value, 10373 tlv.length); 10374 break; 10375 case _bcmFieldInternalSliceStageId: 10376 slice->stage_id = *(_field_stage_id_t *)tlv.value; 10377 break; 10378 case _bcmFieldInternalSlicePortPbmp: 10379 sal_memcpy(&(slice->pbmp), tlv.value, 10380 (recovery_type_map[unit][tlv.type].size * tlv.length)); 10381 10382 break; 10383 case _bcmFieldInternalSliceNextSlice: 10384 temp_id = *(uint8 *)tlv.value; 10385 if (slice->slice_number > temp_id) { 10386 slice->next = 10387 &SLICE_STRUCT(stage_fc, slices, pipe_id, temp_id); 10388 SLICE_STRUCT(stage_fc, slices, pipe_id, temp_id).prev 10389 = slice; 10390 } 10391 break; 10392 10393 case _bcmFieldInternalSlicePrevSlice: 10394 temp_id = *(uint8 *)tlv.value; 10395 if (slice->slice_number > temp_id) { 10396 slice->prev = 10397 &SLICE_STRUCT(stage_fc, slices, pipe_id, temp_id); 10398 SLICE_STRUCT(stage_fc,slices, 10399 pipe_id, temp_id).next = slice; 10400 } 10401 break; 10402 10403 case _bcmFieldInternalSliceFlags: 10404 slice_flags8 = *(uint8 *)tlv.value; 10405 slice->slice_flags |= slice_flags8 & 0xFF; 10406 break; 10407 case _bcmFieldInternalSliceFlagsMsb24: 10408 slice_flags24 = *(uint32 *)tlv.value; 10409 slice->slice_flags |= (slice_flags24 << 8); 10410 break; 10411 case _bcmFieldInternalSliceGroupFlags: 10412 slice->group_flags = *(uint8 *)tlv.value; 10413 break; 10414 case _bcmFieldInternalSliceLtMap: 10415 slice->lt_map = *(uint32 *)tlv.value; 10416 break; 10417 case _bcmFieldInternalSliceLtPartitionPri: 10418 slice->lt_partition_pri = *(uint8 *)tlv.value; 10419 break; 10420 case _bcmFieldInternalExtractor: 10421 BCM_IF_ERROR_RETURN(_field_extractor_recover(unit, scache_ptr, 10422 position, &tlv, slice->ext_sel)); 10423 break; 10424 case _bcmFieldInternalEndStructSlice: 10425 if (*(uint32 *)tlv.value != _FIELD_WB_EM_SLICE) { 10426 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 10427 "END MARKER CHECK FAILED : SLICE\n"))); 10428 TLV_INIT(tlv); 10429 return BCM_E_INTERNAL; 10430 } 10431 break; 10432 default: 10433 break; 10434 } 10435 } 10436 TLV_INIT(tlv); 10437 return BCM_E_NONE; 10438 } 10439 10440 10441 /* Function: 10442 * _field_lt_slice_recover 10443 * 10444 * Purpose: 10445 * recover _field_lt_slice_t structure 10446 * 10447 * Paramaters: 10448 * unit - (IN) BCM device number 10449 * pipe_id - (IN) Pipe to which this lt_slice belongs. 10450 * lt_slice - (IN) Pointer to device lt_slice structure 10451 * 10452 * Returns: 10453 * BCM_E_XXX 10454 */ 10455 10456 int 10457 _field_lt_slice_recover(int unit, int pipe_id, _field_lt_slice_t *lt_slice) 10458 { 10459 _field_tlv_t tlv; /* tlv structure */ 10460 _field_control_t *fc = NULL; /* field control structure */ 10461 _field_stage_t *stage_fc = NULL; /* field stage structure */ 10462 uint8 *scache_ptr; /*pointer to scache_ptr */ 10463 uint8 temp_id; /* temp var to store next 10464 * and prev slice id's 10465 */ 10466 uint32 *position; /* pointer to scache_pos */ 10467 10468 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 10469 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 10470 _BCM_FIELD_STAGE_INGRESS, &stage_fc)); 10471 tlv.value = NULL; 10472 TLV_INIT(tlv); 10473 10474 while (tlv.type != _bcmFieldInternalEndStructSlice) { 10475 TLV_INIT(tlv); 10476 /* coverity[no_write_call : FALSE] */ 10477 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv, scache_ptr, position)); 10478 10479 switch (tlv.type) { 10480 10481 case _bcmFieldInternalLtSliceSliceNum: 10482 lt_slice->slice_number = *(uint8 *)tlv.value; 10483 break; 10484 case _bcmFieldInternalLtSliceStartTcamIdx: 10485 lt_slice->start_tcam_idx = *(int *)tlv.value; 10486 break; 10487 case _bcmFieldInternalLtSliceEntryCount: 10488 lt_slice->entry_count = *(int *)tlv.value; 10489 break; 10490 case _bcmFieldInternalLtSliceFreeCount: 10491 lt_slice->free_count = *(int *)tlv.value; 10492 break; 10493 case _bcmFieldInternalLtSliceStageid: 10494 lt_slice->stage_id = *(_field_stage_id_t *)tlv.value; 10495 break; 10496 case _bcmFieldInternalLtSliceNextSlice: 10497 temp_id = *(uint8 *)tlv.value; 10498 if (lt_slice->slice_number > temp_id) { 10499 lt_slice->next = 10500 &SLICE_STRUCT(stage_fc, lt_slices, pipe_id, temp_id); 10501 SLICE_STRUCT(stage_fc,lt_slices, pipe_id, temp_id).prev 10502 = lt_slice; 10503 } 10504 break; 10505 case _bcmFieldInternalLtSlicePrevSlice: 10506 temp_id = *(uint8 *)tlv.value; 10507 if (lt_slice->slice_number > temp_id) { 10508 lt_slice->prev = 10509 &SLICE_STRUCT(stage_fc, lt_slices, pipe_id, temp_id); 10510 SLICE_STRUCT(stage_fc,lt_slices, pipe_id,temp_id).next 10511 = lt_slice; 10512 } 10513 break; 10514 case _bcmFieldInternalLtSliceFlags: 10515 lt_slice->slice_flags = *(uint16 *)tlv.value; 10516 break; 10517 case _bcmFieldInternalLtSliceGroupFlags: 10518 lt_slice->group_flags = *(uint16 *)tlv.value; 10519 break; 10520 case _bcmFieldInternalEndStructSlice: 10521 if (*(uint32 *)tlv.value != _FIELD_WB_EM_LTSLICE) { 10522 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 10523 "END MARKER CHECK FAILED : LT SLICE\n"))); 10524 TLV_INIT(tlv); 10525 return BCM_E_INTERNAL; 10526 } 10527 break; 10528 default: 10529 break; 10530 } 10531 } 10532 TLV_INIT(tlv); 10533 return BCM_E_NONE; 10534 10535 } 10536 #define _FIELD_ENTRY_WB_ACTION_INSERT(_ptr_, action) \ 10537 do { \ 10538 if (action != NULL) { \ 10539 action->next = _ptr_; \ 10540 _ptr_ = action; \ 10541 } \ 10542 action = NULL; \ 10543 } while (0); \ 10544 10545 /* Function: 10546 * _field_action_profile_set1_recover 10547 * 10548 * Purpose: 10549 * recover profile set 1 actions 10550 * 10551 * Paramaters: 10552 * unit - (IN) BCM device number 10553 * f_ent - (IN) Field Entry Structure 10554 * e_buf - (IN) FP Policy Entry data 10555 * act - (OUT) Pointer to action structure 10556 * 10557 * 10558 * Returns: 10559 * BCM_E_XXX 10560 */ 10561 int 10562 _field_action_profile_set1_recover(int unit, _field_entry_t *f_ent, 10563 uint32* e_buf, _field_action_t *act) 10564 { 10565 _bcm_field_action_offset_t a_offset; /* Action offsets */ 10566 10567 if (NULL == f_ent || NULL == act || NULL == e_buf) { 10568 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META("Invalid Parameters\n"))); 10569 return BCM_E_PARAM; 10570 } 10571 sal_memset(&a_offset, 0 , sizeof(a_offset)); 10572 ACTION_GET(unit, f_ent, e_buf, act->action, 0, &a_offset); 10573 10574 switch (act ->action) { 10575 10576 case bcmFieldActionGpPrioIntCopy: 10577 case bcmFieldActionYpPrioIntCopy: 10578 case bcmFieldActionRpPrioIntCopy: 10579 case bcmFieldActionPrioIntCopy: 10580 case bcmFieldActionPrioIntTos: 10581 case bcmFieldActionGpPrioIntTos: 10582 case bcmFieldActionYpPrioIntTos: 10583 case bcmFieldActionRpPrioIntTos: 10584 case bcmFieldActionPrioIntCancel: 10585 case bcmFieldActionGpPrioIntCancel: 10586 case bcmFieldActionYpPrioIntCancel: 10587 case bcmFieldActionRpPrioIntCancel: 10588 /* No Params */ 10589 break; 10590 10591 case bcmFieldActionGpPrioIntNew: 10592 case bcmFieldActionYpPrioIntNew: 10593 case bcmFieldActionRpPrioIntNew: 10594 case bcmFieldActionGpDropPrecedence: 10595 case bcmFieldActionYpDropPrecedence: 10596 case bcmFieldActionRpDropPrecedence: 10597 case bcmFieldActionGpIntCongestionNotificationNew: 10598 case bcmFieldActionYpIntCongestionNotificationNew: 10599 case bcmFieldActionRpIntCongestionNotificationNew: 10600 case bcmFieldActionPfcClassNew: 10601 case bcmFieldActionUntaggedPacketPriorityNew: 10602 act->param[0] = a_offset.value[0]; 10603 break; 10604 case bcmFieldActionGpCosMapNew: 10605 case bcmFieldActionYpCosMapNew: 10606 case bcmFieldActionRpCosMapNew: 10607 _BCM_COSQ_CLASSIFIER_FIELD_SET(act->param[0], a_offset.value[0]); 10608 break; 10609 case bcmFieldActionPrioIntNew: 10610 ACTION_GET(unit, f_ent, e_buf, bcmFieldActionGpPrioIntNew, 10611 0, &a_offset); 10612 act->param[0] = a_offset.value[0]; 10613 break; 10614 10615 case bcmFieldActionDropPrecedence: 10616 ACTION_GET(unit, f_ent, e_buf, bcmFieldActionGpDropPrecedence, 10617 0, &a_offset); 10618 act->param[0] = a_offset.value[0]; 10619 break; 10620 case bcmFieldActionCosMapNew: 10621 ACTION_GET(unit, f_ent, e_buf, bcmFieldActionGpCosMapNew, 10622 0, &a_offset); 10623 _BCM_COSQ_CLASSIFIER_FIELD_SET(act->param[0], a_offset.value[0]); 10624 break; 10625 default: 10626 return BCM_E_INTERNAL; 10627 10628 10629 } 10630 10631 return BCM_E_NONE; 10632 } 10633 10634 10635 /* Function: 10636 * _field_action_profile_set2_recover 10637 * 10638 * Purpose: 10639 * recover profile set 2 actions 10640 * 10641 * Paramaters: 10642 * unit - (IN) BCM device number 10643 * f_ent - (IN) Field Entry Structure 10644 * e_buf - (IN) FP Policy Entry data 10645 * act - (OUT) Pointer to action structure 10646 * 10647 * 10648 * Returns: 10649 * BCM_E_XXX 10650 */ 10651 int 10652 _field_action_profile_set2_recover(int unit, _field_entry_t *f_ent, 10653 uint32* e_buf, _field_action_t *act) 10654 { 10655 _bcm_field_action_offset_t a_offset; /* Action offsets */ 10656 10657 if (NULL == f_ent || NULL == act || NULL == e_buf) { 10658 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META("Invalid Parameters\n"))); 10659 return BCM_E_PARAM; 10660 } 10661 sal_memset(&a_offset, 0 , sizeof(a_offset)); 10662 ACTION_GET(unit, f_ent, e_buf, act->action, 0, &a_offset); 10663 10664 switch (act ->action) { 10665 10666 case bcmFieldActionGpEcnNew: 10667 case bcmFieldActionYpEcnNew: 10668 case bcmFieldActionRpEcnNew: 10669 case bcmFieldActionGpPrioPktNew: 10670 case bcmFieldActionYpPrioPktNew: 10671 case bcmFieldActionRpPrioPktNew: 10672 case bcmFieldActionRpDscpNew: 10673 case bcmFieldActionYpDscpNew: 10674 case bcmFieldActionGpDscpNew: 10675 case bcmFieldActionGpTosPrecedenceNew: 10676 act->param[0] = a_offset.value[0]; 10677 break; 10678 10679 case bcmFieldActionEcnNew: 10680 ACTION_GET(unit, f_ent, e_buf, bcmFieldActionGpEcnNew, 10681 0, &a_offset); 10682 act->param[0] = a_offset.value[0]; 10683 break; 10684 case bcmFieldActionPrioPktNew: 10685 ACTION_GET(unit, f_ent, e_buf, bcmFieldActionGpPrioPktNew, 10686 0, &a_offset); 10687 act->param[0] = a_offset.value[0]; 10688 break; 10689 case bcmFieldActionDscpNew: 10690 ACTION_GET(unit, f_ent, e_buf, bcmFieldActionGpDscpNew, 10691 0, &a_offset); 10692 act->param[0] = a_offset.value[0]; 10693 break; 10694 10695 case bcmFieldActionGpPrioPktCopy: 10696 case bcmFieldActionGpPrioPktTos: 10697 case bcmFieldActionGpPrioPktCancel: 10698 case bcmFieldActionYpPrioPktCopy: 10699 case bcmFieldActionYpPrioPktTos: 10700 case bcmFieldActionYpPrioPktCancel: 10701 case bcmFieldActionRpPrioPktCopy: 10702 case bcmFieldActionRpPrioPktTos: 10703 case bcmFieldActionRpPrioPktCancel: 10704 case bcmFieldActionGpDscpCancel: 10705 case bcmFieldActionYpDscpCancel: 10706 case bcmFieldActionRpDscpCancel: 10707 case bcmFieldActionPrioPktCopy: 10708 case bcmFieldActionPrioPktTos: 10709 case bcmFieldActionDscpCancel: 10710 case bcmFieldActionPrioPktCancel: 10711 case bcmFieldActionGpTosPrecedenceCopy: 10712 case bcmFieldActionDot1pPreserve: 10713 case bcmFieldActionGpDot1pPreserve: 10714 case bcmFieldActionYpDot1pPreserve: 10715 case bcmFieldActionRpDot1pPreserve: 10716 case bcmFieldActionDscpPreserve: 10717 case bcmFieldActionGpDscpPreserve: 10718 case bcmFieldActionYpDscpPreserve: 10719 case bcmFieldActionRpDscpPreserve: 10720 /* No Params */ 10721 break; 10722 default: 10723 return BCM_E_INTERNAL; 10724 10725 } 10726 10727 return BCM_E_NONE; 10728 10729 } 10730 10731 10732 /* Function: 10733 * _field_action_l3swl2_recover 10734 * 10735 * Purpose: 10736 * recover L3_SWITCH_L2 set actions 10737 * 10738 * Paramaters: 10739 * unit - (IN) BCM device number 10740 * f_ent - (IN) Field Entry Structure 10741 * e_buf - (IN) FP Policy Entry data 10742 * act - (OUT) Pointer to action structure 10743 * 10744 * 10745 * Returns: 10746 * BCM_E_XXX 10747 */ 10748 int 10749 _field_action_l3swl2_recover(int unit, _field_entry_t *f_ent, 10750 uint32* e_buf, _field_action_t *act) 10751 { 10752 _bcm_field_action_offset_t a_offset; /* action offsets */ 10753 10754 if (NULL == f_ent || NULL == act || NULL == e_buf) { 10755 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META("Invalid Parameters\n"))); 10756 return BCM_E_PARAM; 10757 } 10758 sal_memset(&a_offset, 0 , sizeof(a_offset)); 10759 ACTION_GET(unit, f_ent, e_buf, act->action, 0, &a_offset); 10760 10761 switch (act ->action) { 10762 10763 case bcmFieldActionNewClassId: 10764 case bcmFieldActionAddClassTag: 10765 case bcmFieldActionMultipathHash: 10766 case bcmFieldActionBFDSessionIdNew: 10767 act->param[0] = a_offset.value[0]; 10768 break; 10769 #ifdef INCLUDE_L3 10770 case bcmFieldActionChangeL2Fields: 10771 act->param[0] = BCM_XGS3_EGRESS_IDX_MIN(unit) + a_offset.value[0]; 10772 break; 10773 #endif 10774 case bcmFieldActionL3SwitchCancel: 10775 case bcmFieldActionChangeL2FieldsCancel: 10776 /* No Params */ 10777 break; 10778 default: 10779 return BCM_E_INTERNAL; 10780 10781 } 10782 10783 return BCM_E_NONE; 10784 10785 } 10786 10787 /* Function: 10788 * _field_dlb_ecmp_actions_recover 10789 * 10790 * Purpose: 10791 * recover bcmFieldActionDlbEcmpMonitorEnable action. 10792 * 10793 * Paramaters: 10794 * unit - (IN) BCM device number 10795 * f_ent - (IN) Field Entry Structure 10796 * e_buf - (IN) FP Policy Entry data 10797 * act - (OUT) Pointer to action structure 10798 * 10799 * 10800 * Returns: 10801 * BCM_E_XXX 10802 */ 10803 int 10804 _field_dlb_ecmp_actions_recover(int unit, _field_entry_t *f_ent, 10805 uint32* e_buf, _field_action_t *act) 10806 { 10807 _bcm_field_action_offset_t a_offset; /* action offsets */ 10808 10809 if (NULL == f_ent || NULL == act || NULL == e_buf) { 10810 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META("Invalid Parameters\n"))); 10811 return BCM_E_PARAM; 10812 } 10813 10814 sal_memset(&a_offset, 0 , sizeof(a_offset)); 10815 ACTION_GET(unit, f_ent, e_buf, act->action, 0, &a_offset); 10816 act->param[0] = a_offset.value[0]; 10817 return BCM_E_NONE; 10818 10819 } 10820 10821 /* Function: 10822 * _field_action_delayed_recover 10823 * 10824 * Purpose: 10825 * recover bcmFieldActionFabricEHAddOrUpdate action. 10826 * 10827 * Paramaters: 10828 * unit - (IN) BCM device number 10829 * f_ent - (IN) Field Entry Structure 10830 * e_buf - (IN) FP Policy Entry data 10831 * act - (OUT) Pointer to action structure 10832 * 10833 * 10834 * Returns: 10835 * BCM_E_XXX 10836 */ 10837 int 10838 _field_action_delayed_recover(int unit, _field_entry_t *f_ent, 10839 uint32* e_buf, _field_action_t *act) 10840 { 10841 _field_stage_t *stage_fc = NULL; /* Field Stage Control Structure. */ 10842 _bcm_field_action_offset_t a_offset; /* Field action offset information. */ 10843 soc_profile_mem_t *profile = NULL; 10844 void *entry_ptr = NULL; 10845 ifp_egress_port_check_for_drop_entry_t ddrop_entry; 10846 ifp_egress_port_check_for_redirect_entry_t dredirect_entry; 10847 soc_mem_t mem = INVALIDm; 10848 int rv = 0; 10849 bcm_pbmp_t pbmp; 10850 10851 /* NULL Parameters Check */ 10852 if (NULL == f_ent || NULL == act || NULL == e_buf) { 10853 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META("Invalid Parameters\n"))); 10854 return BCM_E_PARAM; 10855 } 10856 10857 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 10858 _BCM_FIELD_STAGE_INGRESS, &stage_fc)); 10859 10860 /* Fetch the action offset information. */ 10861 sal_memset(&a_offset, 0 , sizeof(a_offset)); 10862 ACTION_GET(unit, f_ent, e_buf, act->action, 0, &a_offset); 10863 10864 switch (act ->action) { 10865 case bcmFieldActionMatchPbmpRedirect: 10866 act->param[0] = a_offset.value[1]; 10867 BCM_IF_ERROR_RETURN 10868 (_bcm_field_dredirect_profile_get(unit, &profile)); 10869 mem = IFP_EGRESS_PORT_CHECK_FOR_REDIRECTm; 10870 /* Reset redirection profile entry. */ 10871 sal_memset(&dredirect_entry, 0, 10872 sizeof(ifp_egress_port_check_for_redirect_entry_t)); 10873 entry_ptr = &dredirect_entry; 10874 break; 10875 case bcmFieldActionMatchPbmpDrop: 10876 BCM_IF_ERROR_RETURN 10877 (_bcm_field_ddrop_profile_get(unit, &profile)); 10878 mem = IFP_EGRESS_PORT_CHECK_FOR_DROPm; 10879 /* Reset redirection profile entry. */ 10880 sal_memset(&ddrop_entry, 0, 10881 sizeof(ifp_egress_port_check_for_drop_entry_t)); 10882 entry_ptr = &ddrop_entry; 10883 break; 10884 default: 10885 return BCM_E_INTERNAL; 10886 } 10887 10888 act->hw_index = a_offset.value[0]; 10889 10890 rv = soc_mem_read(unit, mem, 10891 MEM_BLOCK_ANY, act->hw_index, entry_ptr); 10892 if (!SOC_SUCCESS(rv)) { 10893 sal_free(act->egress_pbmp); 10894 return rv; 10895 } 10896 10897 BCM_PBMP_CLEAR(pbmp); 10898 soc_mem_pbmp_field_get(unit, mem, 10899 (uint32 *)entry_ptr, PORT_BITMAPf, &pbmp); 10900 10901 if (BCM_PBMP_NOT_NULL(pbmp)) { 10902 _FP_XGS3_ALLOC(act->egress_pbmp, sizeof(bcm_pbmp_t), 10903 "Field Action Pbmp Allocation "); 10904 if (NULL == act->egress_pbmp) { 10905 return (BCM_E_MEMORY); 10906 } 10907 10908 BCM_PBMP_ASSIGN(*(act->egress_pbmp), pbmp); 10909 } 10910 act->elephant_pkts_only = soc_mem_field32_get(unit, mem, 10911 (uint32 *)entry_ptr, ELEPHANT_PKT_ONLYf); 10912 10913 /* Increment the reference count for profile entry. */ 10914 SOC_PROFILE_MEM_REFERENCE(unit, profile, act->hw_index, 1); 10915 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, profile, 10916 act->hw_index, 1); 10917 10918 return BCM_E_NONE; 10919 } 10920 10921 10922 /* Function: 10923 * _field_action_mirror_zero_recover 10924 * 10925 * Purpose: 10926 * recover bcmFieldActionMirrorZeroingEnable action. 10927 * 10928 * Paramaters: 10929 * unit - (IN) BCM device number 10930 * f_ent - (IN) Field Entry Structure 10931 * e_buf - (IN) FP Policy Entry data 10932 * act - (OUT) Pointer to action structure 10933 * 10934 * 10935 * Returns: 10936 * BCM_E_XXX 10937 */ 10938 int 10939 _field_action_mirror_zero_recover(int unit, _field_entry_t *f_ent, 10940 uint32* e_buf, _field_action_t *act) 10941 { 10942 _bcm_field_action_offset_t a_offset; /* Field action offset information. */ 10943 10944 /* Fetch the action offset information. */ 10945 sal_memset(&a_offset, 0 , sizeof(a_offset)); 10946 ACTION_GET(unit, f_ent, e_buf, act->action, 0, &a_offset); 10947 act->param[0] = a_offset.value[0]; 10948 return BCM_E_NONE; 10949 } 10950 10951 /* Function: 10952 * _field_action_misc_recover 10953 * 10954 * Purpose: 10955 * recover misc actions 10956 * 10957 * Paramaters: 10958 * unit - (IN) BCM device number 10959 * f_ent - (IN) Field Entry Structure 10960 * e_buf - (IN) FP Policy Entry data 10961 * act - (OUT) Pointer to action structure 10962 * 10963 * 10964 * Returns: 10965 * BCM_E_XXX 10966 */ 10967 int 10968 _field_action_misc_recover(int unit, _field_entry_t *f_ent, 10969 uint32* e_buf, _field_action_t *act) 10970 { 10971 _bcm_field_action_offset_t a_offset; 10972 10973 if (NULL == f_ent || NULL == act || NULL == e_buf) { 10974 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META("Invalid Parameters\n"))); 10975 return BCM_E_PARAM; 10976 } 10977 sal_memset(&a_offset, 0 , sizeof(a_offset)); 10978 ACTION_GET(unit, f_ent, e_buf, act->action, 0, &a_offset); 10979 10980 switch (act ->action) { 10981 case bcmFieldActionHgTrunkRandomRoundRobinHashCancel: 10982 case bcmFieldActionTrunkRandomRoundRobinHashCancel: 10983 case bcmFieldActionEcmpRandomRoundRobinHashCancel: 10984 case bcmFieldActionNatCancel: 10985 case bcmFieldActionDoNotCutThrough: 10986 case bcmFieldActionDoNotCheckUrpf: 10987 case bcmFieldActionDoNotChangeTtl: 10988 case bcmFieldActionMirrorOverride: 10989 case bcmFieldActionIngSampleEnable: 10990 case bcmFieldActionCopyToCpuCancel: 10991 case bcmFieldActionSwitchToCpuCancel: 10992 case bcmFieldActionSwitchToCpuReinstate: 10993 case bcmFieldActionDrop: 10994 case bcmFieldActionDropCancel: 10995 case bcmFieldActionGpCopyToCpuCancel: 10996 case bcmFieldActionGpSwitchToCpuCancel: 10997 case bcmFieldActionGpSwitchToCpuReinstate: 10998 case bcmFieldActionYpCopyToCpuCancel: 10999 case bcmFieldActionYpSwitchToCpuCancel: 11000 case bcmFieldActionYpSwitchToCpuReinstate: 11001 case bcmFieldActionRpCopyToCpuCancel: 11002 case bcmFieldActionRpSwitchToCpuCancel: 11003 case bcmFieldActionRpSwitchToCpuReinstate: 11004 case bcmFieldActionGpDrop: 11005 case bcmFieldActionGpDropCancel: 11006 case bcmFieldActionYpDrop: 11007 case bcmFieldActionYpDropCancel: 11008 case bcmFieldActionRpDrop: 11009 case bcmFieldActionRpDropCancel: 11010 case bcmFieldActionPacketTraceEnable: 11011 case bcmFieldActionNat: 11012 #if defined(BCM_TOMAHAWK2_SUPPORT) 11013 case bcmFieldActionEgressTimeStampInsert: 11014 case bcmFieldActionIngressTimeStampInsert: 11015 case bcmFieldActionIngressTimeStampInsertCancel: 11016 case bcmFieldActionEgressTimeStampInsertCancel: 11017 case bcmFieldActionDynamicTrunkEnable: 11018 case bcmFieldActionDynamicTrunkCancel: 11019 case bcmFieldActionDynamicHgTrunkEnable: 11020 case bcmFieldActionDynamicHgTrunkCancel: 11021 #if defined(INCLUDE_L3) 11022 case bcmFieldActionDynamicEcmpEnable: 11023 case bcmFieldActionDynamicEcmpCancel: 11024 case bcmFieldActionRecoverableDropCancel: 11025 #endif /*INCLUDE_L3*/ 11026 #endif /*BCM_TOMAHAWK2_SUPPORT*/ 11027 case bcmFieldActionIntEncapEnable: 11028 case bcmFieldActionIntEncapDisable: 11029 case bcmFieldActionElephantColorEnable: 11030 case bcmFieldActionElephantColorDisable: 11031 case bcmFieldActionElephantQueueEnable: 11032 case bcmFieldActionElephantQueueDisable: 11033 case bcmFieldActionElephantLookupEnable: 11034 case bcmFieldActionElephantLookupDisable: 11035 /* No params */ 11036 break; 11037 case bcmFieldActionColorIndependent: 11038 case bcmFieldActionServicePoolIdNew: 11039 case bcmFieldActionCosQCpuNew: 11040 act->param[0] = a_offset.value[0]; 11041 break; 11042 case bcmFieldActionServicePoolIdPrecedenceNew: 11043 act->param[0] = a_offset.value[0]; 11044 /* SPAP is 2b'00 for BCM_FIELD_COLOR_GREEN 11045 2b'01 for BCM_FIELD_COLOR_RED 11046 2b'11 for BCM_FIELD_COLOR_YELLOW 11047 */ 11048 act->param[1] = ((0 == a_offset.value[1]) ? BCM_FIELD_COLOR_GREEN : \ 11049 ((3 == a_offset.value[1])? BCM_FIELD_COLOR_YELLOW : BCM_FIELD_COLOR_RED)); 11050 break; 11051 #ifdef INCLUDE_L3 11052 case bcmFieldActionNatEgressOverride: 11053 act->param[0] = 11054 ((a_offset.value[0] << 1) | (a_offset.value[1])); 11055 break; 11056 #if defined(BCM_TOMAHAWK2_SUPPORT) 11057 case bcmFieldActionDgm: 11058 break; 11059 case bcmFieldActionDgmThreshold: 11060 case bcmFieldActionDgmBias: 11061 case bcmFieldActionDgmCost: 11062 act->param[0] = a_offset.value[0]; 11063 break; 11064 #endif /*BCM_TOMAHAWK2_SUPPORT*/ 11065 #endif /*INCLUDE_L3*/ 11066 11067 default: 11068 return BCM_E_INTERNAL; 11069 } 11070 return BCM_E_NONE; 11071 11072 } 11073 /* Function: 11074 * _field_action_eh_recover 11075 * 11076 * Purpose: 11077 * recover bcmFieldActionFabricEHAddOrUpdate action. 11078 * 11079 * Paramaters: 11080 * unit - (IN) BCM device number 11081 * f_ent - (IN) Field Entry Structure 11082 * e_buf - (IN) FP Policy Entry data 11083 * act - (OUT) Pointer to action structure 11084 * 11085 * 11086 * Returns: 11087 * BCM_E_XXX 11088 */ 11089 int 11090 _field_action_eh_recover(int unit, _field_entry_t *f_ent, 11091 uint32* e_buf, _field_action_t *act) 11092 { 11093 uint32 eh_mask = 0; /* HiGiG2 extended header mask */ 11094 int hw_index = 0; /* h/w index to EH_MASK_PROFILE table entry. */ 11095 soc_profile_mem_t *eh_mask_profile = NULL; /* Profile pointer for EH_MASK_PROFILE table. */ 11096 eh_mask_profile_entry_t *eh_mask_entry = NULL; /* pointer to EH_MASK_PROFILE table entry. */ 11097 _bcm_field_action_offset_t a_offset; /* Field action offset information. */ 11098 int rv = 0; 11099 _field_control_t *fc = NULL; /* Field Control Structure */ 11100 11101 /* NULL Parameters Check */ 11102 if (NULL == f_ent || NULL == act || NULL == e_buf) { 11103 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META("Invalid Parameters\n"))); 11104 return BCM_E_PARAM; 11105 } 11106 11107 /* Get field control structure. */ 11108 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 11109 11110 /* Fetch the action offset information. */ 11111 sal_memset(&a_offset, 0 , sizeof(a_offset)); 11112 ACTION_GET(unit, f_ent, e_buf, act->action, 0, &a_offset); 11113 switch (act ->action) { 11114 case bcmFieldActionFabricEHAddOrUpdate: 11115 _FP_XGS3_ALLOC(eh_mask_entry, sizeof(eh_mask_profile_entry_t), 11116 "wb HiGiG2 extended header mask profile entry"); 11117 if (eh_mask_entry == NULL) { 11118 return BCM_E_MEMORY; 11119 } 11120 eh_mask_profile = &fc->eh_mask_profile; 11121 if ((a_offset.value[3] == 6)) { 11122 /* First parameter is New extended header. */ 11123 act->param[0] = a_offset.value[0]; 11124 /* Second parameter is extended header mask. */ 11125 /* coverity[check_return : FALSE] */ 11126 hw_index = a_offset.value[1]; 11127 rv = soc_mem_read(unit, EH_MASK_PROFILEm, 11128 MEM_BLOCK_ANY, hw_index, eh_mask_entry); 11129 if (!SOC_SUCCESS(rv)) { 11130 sal_free(eh_mask_entry); 11131 return rv; 11132 } 11133 soc_mem_field_get(unit, EH_MASK_PROFILEm, 11134 (uint32 *)eh_mask_entry, EH_MASKf, &eh_mask); 11135 act->param[1] = eh_mask; 11136 11137 /* Increment the reference count for profile entry. */ 11138 SOC_PROFILE_MEM_REFERENCE(unit, eh_mask_profile, hw_index, 1); 11139 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, eh_mask_profile, 11140 hw_index, 1); 11141 } 11142 sal_free(eh_mask_entry); 11143 break; 11144 default: 11145 return BCM_E_INTERNAL; 11146 } 11147 11148 return BCM_E_NONE; 11149 } 11150 /* Function: 11151 * _field_action_sofware_recover 11152 * 11153 * Purpose: 11154 * recover cached actions 11155 * 11156 * Paramaters: 11157 * unit - (IN) BCM device number 11158 * f_ent - (IN) Field Entry Structure 11159 * e_buf - (IN) FP Policy Entry data 11160 * act - (OUT) Pointer to action structure 11161 * val_array - (OUT) Action value array 11162 * pos - (OUT) reference to position. 11163 * Returns: 11164 * BCM_E_XXX 11165 */ 11166 int 11167 _field_action_software_recover(int unit, _field_entry_t *f_ent, uint32 *e_buf, 11168 _field_action_t *act, 11169 _field_wb_entry_t *wb_entry, int *pos, 11170 uint8 action_param_type) 11171 { 11172 int param_id = 0; /* Loop variable */ 11173 int position = 0; /* pointer to position in the 11174 * array of values 11175 */ 11176 _field_action_t *new_action = NULL; /* Used to hold multiple 11177 * actions structures in case 11178 * an action is repeated 11179 */ 11180 _field_action_t *fa = act; /* pointer to array of actions */ 11181 int *val_array = wb_entry->val_array; 11182 int *val_array0 = wb_entry->val_array0; 11183 11184 position = *pos; 11185 switch (fa->action) { 11186 case bcmFieldActionCosQNew: 11187 case bcmFieldActionGpCosQNew: 11188 case bcmFieldActionYpCosQNew: 11189 case bcmFieldActionRpCosQNew: 11190 case bcmFieldActionUcastCosQNew: 11191 case bcmFieldActionGpUcastCosQNew: 11192 case bcmFieldActionYpUcastCosQNew: 11193 case bcmFieldActionRpUcastCosQNew: 11194 case bcmFieldActionMcastCosQNew: 11195 case bcmFieldActionGpMcastCosQNew: 11196 case bcmFieldActionYpMcastCosQNew: 11197 case bcmFieldActionRpMcastCosQNew: 11198 case bcmFieldActionEgressClassSelect: 11199 case bcmFieldActionHiGigClassSelect: 11200 case bcmFieldActionFabricQueue: 11201 case bcmFieldActionL3Switch: 11202 case bcmFieldActionRedirectMcast: 11203 case bcmFieldActionRedirectEgrNextHop: 11204 case bcmFieldActionRedirectIpmc: 11205 case bcmFieldActionRedirectCancel: 11206 case bcmFieldActionOuterVlanNew: 11207 for (param_id = 0; param_id < 1; param_id++) { 11208 act->param[param_id] = val_array[position++]; 11209 } 11210 break; 11211 case bcmFieldActionCopyToCpu: 11212 case bcmFieldActionTimeStampToCpu: 11213 case bcmFieldActionRpCopyToCpu: 11214 case bcmFieldActionRpTimeStampToCpu: 11215 case bcmFieldActionYpCopyToCpu: 11216 case bcmFieldActionYpTimeStampToCpu: 11217 case bcmFieldActionGpCopyToCpu: 11218 case bcmFieldActionGpTimeStampToCpu: 11219 if (action_param_type == 1) { 11220 for (param_id = 0; param_id < 2; param_id++) { 11221 act->param[param_id] = val_array[position++]; 11222 } 11223 } 11224 break; 11225 case bcmFieldActionDstMacNew: 11226 case bcmFieldActionSrcMacNew: 11227 case bcmFieldActionUnmodifiedPacketRedirectPort: 11228 case bcmFieldActionRedirect: 11229 case bcmFieldActionEtagNew: 11230 case bcmFieldActionVnTagNew: 11231 case bcmFieldActionRedirectTrunk: 11232 for (param_id = 0; param_id < 2; param_id++) { 11233 act->param[param_id] = val_array[position++]; 11234 } 11235 break; 11236 case bcmFieldActionRedirectPbmp: 11237 case bcmFieldActionEgressMask: 11238 case bcmFieldActionEgressPortsAdd: 11239 case bcmFieldActionRedirectBcastPbmp: 11240 for (param_id = 0; param_id < 4; param_id++) { 11241 act->param[param_id] = val_array[position++]; 11242 } 11243 if ((NULL != val_array0) && (val_array[1] != val_array0[1])) { 11244 act->param[4] = val_array0[0]; 11245 } 11246 break; 11247 case bcmFieldActionMirrorIngress: 11248 case bcmFieldActionMirrorEgress: 11249 fa = act; 11250 /* fetch all mirror params, if param is != -1, 11251 * action is valid, hence alloc new action 11252 */ 11253 for (param_id = 0; param_id < BCM_MIRROR_MTP_COUNT; 11254 param_id++) { 11255 if ((val_array[position] != -1) 11256 && (val_array[position + 1] != -1)) { 11257 if (param_id != 0) { 11258 if(!soc_feature(unit, soc_feature_ifp_action_profiling)) { 11259 new_action = NULL; 11260 _FP_XGS3_ALLOC(new_action, 11261 sizeof(_field_action_t), "actions"); 11262 act->next = new_action; 11263 new_action->action = fa->action; 11264 new_action->hw_index = -1; 11265 new_action->old_index = -1; 11266 new_action->flags |= _FP_ACTION_VALID ; 11267 } 11268 act = act->next; 11269 } 11270 if (act->action == fa->action) { 11271 act->param[0] = val_array[position]; 11272 act->param[1] = val_array[position + 1]; 11273 } 11274 act->action = fa->action; 11275 act->param[0] = val_array[position]; 11276 act->param[1] = val_array[position + 1]; 11277 if ((SOC_INFO(unit).th_ctc_replace_enabled) && 11278 (fa->action == bcmFieldActionMirrorEgress)) { 11279 _bcm_field_action_offset_t a_offset; 11280 11281 sal_memset(&a_offset, 0 , sizeof(a_offset)); 11282 if (!soc_feature(unit, soc_feature_ifp_action_profiling)) { 11283 ACTION_GET(unit, f_ent, e_buf, bcmFieldActionFabricQueue, 11284 0, &a_offset); 11285 } else { 11286 /*loop over f_ent structure and get the fabricqueue param 1*/ 11287 } 11288 if (a_offset.value[1]) { 11289 act->param[2] = 1; 11290 act->param[3] = a_offset.value[1]; 11291 act->flags |= _BCM_FIELD_ACTION_CTC_MANIPULATE_FLAG; 11292 } 11293 } 11294 } 11295 position = position + 2; 11296 } 11297 break; 11298 11299 case bcmFieldActionRedirectVlan: 11300 case bcmFieldActionVnTagDelete: 11301 case bcmFieldActionEtagDelete: 11302 11303 default: 11304 break; 11305 } 11306 *pos = position; 11307 return BCM_E_NONE; 11308 } 11309 /* Function: 11310 * _field_compression_actions_recover 11311 * 11312 * Purpose: 11313 * recover parameters for compression actions 11314 * 11315 * Paramaters: 11316 * unit - (IN) BCM device number 11317 * f_ent - (IN) Field Entry Structure 11318 * fa - (OUT) Pointer to action structure 11319 * 11320 * 11321 * Returns: 11322 * BCM_E_XXX 11323 */ 11324 int 11325 _field_compression_actions_recover(int unit, _field_entry_t *f_ent, 11326 _field_action_t *fa) { 11327 uint32 cdata; /* compression entry data */ 11328 uint32 *cdata_ptr; /* pointer to the same data */ 11329 _field_class_type_t ctype; /* type of compression */ 11330 soc_reg_t reg; /* SOC Register */ 11331 soc_mem_t mem; /* SOC Memory */ 11332 int rv = BCM_E_NONE; /* return value */ 11333 uint64 value; /* to store 64 bit class_ids */ 11334 int tcamsz = 0; 11335 /* Retreive Class Type from entry qset */ 11336 rv = _bcm_field_th_class_type_qset_get(unit, 11337 &f_ent->group->qset, &ctype); 11338 if (BCM_FAILURE(rv)) { 11339 sal_free(fa); 11340 return (rv); 11341 } 11342 11343 rv = _bcm_field_th_class_size_get(unit, ctype, &tcamsz); 11344 11345 /* Assign class data buffer */ 11346 if (f_ent->tcam.key == NULL) { 11347 if ((f_ent->flags & _FP_ENTRY_INSTALLED) && 11348 (f_ent->slice_idx != -1)) { 11349 /* Allocate memory for class data */ 11350 _FP_XGS3_ALLOC(f_ent->tcam.key, 11351 tcamsz, "field class data buf"); 11352 f_ent->tcam.key_size = tcamsz; 11353 if (f_ent->tcam.key == NULL) { 11354 sal_free(fa); 11355 return (BCM_E_MEMORY); 11356 } 11357 /* Entry is in hardware , read it from hardware */ 11358 rv = _bcm_field_th_class_entry_hwread(unit, f_ent, 11359 ctype, f_ent->tcam.key); 11360 if (BCM_FAILURE(rv)) { 11361 sal_free(f_ent->tcam.key); 11362 sal_free(fa); 11363 return (rv); 11364 } 11365 } else { 11366 sal_free(fa); 11367 return (BCM_E_INTERNAL); 11368 } 11369 } 11370 cdata = *(f_ent->tcam.key); 11371 cdata_ptr = f_ent->tcam.key; 11372 switch(ctype) { 11373 case _FieldClassEtherType: 11374 reg = ETHERTYPE_MAPr; 11375 fa->param[0] = soc_reg_field_get(unit, reg, cdata, C_ETHERTYPEf); 11376 break; 11377 case _FieldClassTtl: 11378 mem = TTL_FNm; 11379 if (fa->action == bcmFieldActionClassZero) { 11380 soc_mem_field_get(unit, mem, cdata_ptr, 11381 FN0f, &fa->param[0]); 11382 } else { 11383 soc_mem_field_get(unit, mem, cdata_ptr, 11384 FN1f, &fa->param[0]); 11385 } 11386 break; 11387 case _FieldClassToS: 11388 mem = TOS_FNm; 11389 if (fa->action == bcmFieldActionClassZero) { 11390 soc_mem_field_get(unit, mem, cdata_ptr, 11391 FN0f, &fa->param[0]); 11392 } else { 11393 soc_mem_field_get(unit, mem, cdata_ptr, 11394 FN1f, &fa->param[0]); 11395 } 11396 break; 11397 case _FieldClassIpProto: 11398 mem = IP_PROTO_MAPm; 11399 soc_mem_field_get(unit, mem, cdata_ptr, 11400 C_IP_PROTOCOLf, &fa->param[0]); 11401 break; 11402 case _FieldClassL4SrcPort: 11403 reg = L4_SRC_PORT_MAPr; 11404 fa->param[0] = soc_reg_field_get(unit, reg, cdata, C_L4_SRC_PORTf); 11405 break; 11406 case _FieldClassL4DstPort: 11407 reg = L4_DST_PORT_MAPr; 11408 fa->param[0] = soc_reg_field_get(unit, reg, cdata, C_L4_DST_PORTf); 11409 break; 11410 case _FieldClassTcp: 11411 mem = TCP_FNm; 11412 if (fa->action == bcmFieldActionClassZero) { 11413 soc_mem_field_get(unit, mem, cdata_ptr, 11414 FN0f, &fa->param[0]); 11415 } else { 11416 soc_mem_field_get(unit, mem, cdata_ptr, 11417 FN1f, &fa->param[0]); 11418 } 11419 break; 11420 case _FieldClassSrcCompression: 11421 mem = SRC_COMPRESSIONm; 11422 soc_mem_field64_get(unit, mem, cdata_ptr, 11423 C_SRCf, &value); 11424 COMPILER_64_TO_32_LO(fa->param[0], value); 11425 COMPILER_64_TO_32_HI(fa->param[1], value); 11426 break; 11427 case _FieldClassDstCompression: 11428 mem = DST_COMPRESSIONm; 11429 soc_mem_field64_get(unit, mem, cdata_ptr, 11430 C_DSTf, &value); 11431 COMPILER_64_TO_32_LO(fa->param[0], value); 11432 COMPILER_64_TO_32_HI(fa->param[1], value); 11433 break; 11434 case _FieldClassIpTunnelTtl: 11435 mem = ALT_TTL_FNm; 11436 if (fa->action == bcmFieldActionClassZero) { 11437 soc_mem_field_get(unit, mem, cdata_ptr, 11438 FN0f, &fa->param[0]); 11439 } else { 11440 rv = BCM_E_PARAM; 11441 } 11442 break; 11443 default: 11444 rv = BCM_E_PARAM; 11445 } 11446 11447 return rv; 11448 } 11449 /* Function: 11450 * field_wb_td3_ifp_actions_recover 11451 * 11452 * Purpose: 11453 * recover _field_action_t structure for TD3 IFP 11454 * 11455 * Paramaters: 11456 * unit - (IN) BCM device number 11457 * entry - (IN) Field Entry Structure 11458 * e_buf - (IN) Policy memory data 11459 * val_array - (IN) Array of parameters 11460 * hw_idx_array - (IN) Array of hardware indices 11461 * 11462 * Returns: 11463 * BCM_E_XXX 11464 */ 11465 int field_wb_td3_ifp_actions_recover(int unit, uint32 *e_buf, 11466 _field_entry_t *entry, 11467 _field_wb_entry_t *wb_entry) 11468 { 11469 _field_action_t *curr_action = NULL; /* current action */ 11470 _field_action_t *fa = NULL; /* pointer to actions array */ 11471 bcm_field_action_t action_id; /* action id - used in loop */ 11472 int rv = BCM_E_NONE; /* Return value */ 11473 int pos = 0; /* postion in the array of values 11474 * -val_array 11475 */ 11476 int mtp_recovered = 0; 11477 int hw_count = 0; /* position in the array 11478 * of hw_indices 11479 */ 11480 /* Validate input params , hw_index and val_array can be null in case there 11481 * are actions that doesnt have params or hw_index 11482 */ 11483 if (entry == NULL) { 11484 rv = BCM_E_INTERNAL; 11485 BCM_IF_ERROR_CLEANUP(rv); 11486 } 11487 11488 if (NULL == wb_entry->act_bmp.w) { 11489 rv = BCM_E_NONE; 11490 goto cleanup; 11491 } 11492 11493 for (action_id = 0; action_id < wb_entry->action_count; action_id++) { 11494 if (0 == _FP_ACTION_BMP_TEST(wb_entry->act_bmp, action_id)) { 11495 continue; 11496 } 11497 /* Search for action_id in the recovered entry's actions */ 11498 for (fa = entry->actions; 11499 (NULL != fa) && (_FP_ACTION_VALID & fa->flags) && (action_id != fa->action); 11500 fa = fa->next); 11501 if (NULL == fa) { 11502 continue; 11503 } 11504 curr_action = fa; 11505 switch (fa->action) { 11506 case bcmFieldActionCopyToCpu: 11507 case bcmFieldActionTimeStampToCpu: 11508 case bcmFieldActionRpCopyToCpu: 11509 case bcmFieldActionRpTimeStampToCpu: 11510 case bcmFieldActionYpCopyToCpu: 11511 case bcmFieldActionYpTimeStampToCpu: 11512 case bcmFieldActionGpCopyToCpu: 11513 case bcmFieldActionGpTimeStampToCpu: 11514 case bcmFieldActionCosQNew: 11515 case bcmFieldActionGpCosQNew: 11516 case bcmFieldActionYpCosQNew: 11517 case bcmFieldActionRpCosQNew: 11518 case bcmFieldActionUcastCosQNew: 11519 case bcmFieldActionGpUcastCosQNew: 11520 case bcmFieldActionYpUcastCosQNew: 11521 case bcmFieldActionRpUcastCosQNew: 11522 case bcmFieldActionMcastCosQNew: 11523 case bcmFieldActionGpMcastCosQNew: 11524 case bcmFieldActionYpMcastCosQNew: 11525 case bcmFieldActionRpMcastCosQNew: 11526 case bcmFieldActionEgressClassSelect: 11527 case bcmFieldActionHiGigClassSelect: 11528 case bcmFieldActionFabricQueue: 11529 #ifdef INCLUDE_L3 11530 case bcmFieldActionL3Switch: 11531 #endif 11532 case bcmFieldActionRedirect: 11533 case bcmFieldActionRedirectTrunk: 11534 case bcmFieldActionUnmodifiedPacketRedirectPort: 11535 case bcmFieldActionRedirectMcast: 11536 #ifdef INCLUDE_L3 11537 case bcmFieldActionRedirectEgrNextHop: 11538 case bcmFieldActionRedirectIpmc: 11539 #endif 11540 case bcmFieldActionRedirectCancel: 11541 case bcmFieldActionRedirectVlan: 11542 case bcmFieldActionRedirectBcastPbmp: 11543 case bcmFieldActionEgressMask: 11544 case bcmFieldActionEgressPortsAdd: 11545 rv = _field_action_software_recover(unit, entry, e_buf, 11546 curr_action, wb_entry, &pos, 11547 wb_entry->action_param_type); 11548 BCM_IF_ERROR_CLEANUP(rv); 11549 break; 11550 case bcmFieldActionMirrorIngress: 11551 /* 11552 * _field_action_software_recover recovers all MirrorIngress 11553 * actions params of an entry at once. No need to recover again. 11554 */ 11555 if (mtp_recovered & 0x1) { 11556 break; 11557 } 11558 rv = _field_action_software_recover(unit, entry, e_buf, 11559 curr_action, wb_entry, &pos, 11560 wb_entry->action_param_type); 11561 BCM_IF_ERROR_CLEANUP(rv); 11562 /* Set MirrorIngress action params recovered flag */ 11563 mtp_recovered |= 0x1; 11564 break; 11565 case bcmFieldActionMirrorEgress: 11566 /* 11567 * _field_action_software_recover recovers all MirrorEgress 11568 * actions params of an entry at once. No need to recover again. 11569 */ 11570 if (mtp_recovered & 0x2) { 11571 break; 11572 } 11573 rv = _field_action_software_recover(unit, entry, e_buf, 11574 curr_action, wb_entry, &pos, 11575 wb_entry->action_param_type); 11576 BCM_IF_ERROR_CLEANUP(rv); 11577 /* Set MirrorEgress action params recovered flag */ 11578 mtp_recovered |= 0x2; 11579 break; 11580 default: 11581 /* 11582 * Nothing to do for this action. 11583 * Recover other actions. 11584 */ 11585 continue; 11586 } 11587 11588 switch (fa->action) { 11589 case bcmFieldActionRedirectPbmp: 11590 case bcmFieldActionEgressMask: 11591 case bcmFieldActionEgressPortsAdd: 11592 case bcmFieldActionRedirectBcastPbmp: 11593 case bcmFieldActionRedirectEgrNextHop: 11594 case bcmFieldActionL3Switch: 11595 fa->hw_index = wb_entry->hw_idx_array[hw_count++]; 11596 break; 11597 default : 11598 break; 11599 } 11600 } 11601 11602 cleanup: 11603 return rv; 11604 } 11605 11606 /* Function: 11607 * _field_action_installed_check 11608 * 11609 * Purpose: 11610 * Check if an action exists in policy table 11611 * 11612 * Paramaters: 11613 * unit - (IN) BCM device number 11614 * entry - (IN) Field Entry Structure 11615 * e_buf - (IN) Policy memory data 11616 * action_id - (IN) bcmFieldActionXXX 11617 * exist - (OUT) Number of Action 11618 * 11619 * 11620 * Returns: 11621 * BCM_E_XXX 11622 */ 11623 STATIC int _field_action_installed_check(int unit, _field_entry_t *entry, 11624 uint32 *e_buf, bcm_field_action_t action_id, 11625 int *exist) 11626 { 11627 int rv = BCM_E_NONE; 11628 int v_drop = 1; /* encoding for DROP */ 11629 int v_ndrop = 2; /* encoding for DONOTDROP */ 11630 _bcm_field_action_offset_t a_offset; 11631 11632 if ((exist != NULL) && (entry != NULL) && (e_buf != NULL)) { 11633 *exist = 1; 11634 } else { 11635 return BCM_E_INTERNAL; 11636 } 11637 11638 sal_memset(&a_offset, 0 , sizeof(a_offset)); 11639 switch (action_id) { 11640 case bcmFieldActionDrop: 11641 ACTION_GET(unit, entry, e_buf, bcmFieldActionGpDrop, 0, &a_offset); 11642 if (a_offset.value[0] != v_drop) { 11643 *exist = 0; 11644 return rv; 11645 } 11646 ACTION_GET(unit, entry, e_buf, bcmFieldActionYpDrop, 0, &a_offset); 11647 if (a_offset.value[0] != v_drop) { 11648 *exist = 0; 11649 return rv; 11650 } 11651 ACTION_GET(unit, entry, e_buf, bcmFieldActionRpDrop, 0, &a_offset); 11652 if (a_offset.value[0] != v_drop) { 11653 *exist = 0; 11654 return rv; 11655 } 11656 break; 11657 case bcmFieldActionDropCancel: 11658 ACTION_GET(unit, entry, e_buf, bcmFieldActionGpDropCancel, 0, &a_offset); 11659 if (a_offset.value[0] != v_ndrop) { 11660 *exist = 0; 11661 return rv; 11662 } 11663 ACTION_GET(unit, entry, e_buf, bcmFieldActionYpDropCancel, 0, &a_offset); 11664 if (a_offset.value[0] != v_ndrop) { 11665 *exist = 0; 11666 return rv; 11667 } 11668 ACTION_GET(unit, entry, e_buf, bcmFieldActionRpDropCancel, 0, &a_offset); 11669 if (a_offset.value[0] != v_ndrop) { 11670 *exist = 0; 11671 return rv; 11672 } 11673 break; 11674 default: 11675 break; 11676 } 11677 11678 return rv; 11679 } 11680 11681 /* Function: 11682 * _field_action_recover 11683 * 11684 * Purpose: 11685 * recover _field_action_t structure 11686 * 11687 * Paramaters: 11688 * unit - (IN) BCM device number 11689 * entry - (IN) Field Entry Structure 11690 * act_bmp - (IN) Action Bitmap 11691 * e_buf - (IN) Policy memory data 11692 * val_array - (IN) Array of parameters 11693 * hw_idx_array - (IN) Array of hardware indices 11694 * action_count - (OUT) Number of Action 11695 * 11696 * 11697 * Returns: 11698 * BCM_E_XXX 11699 */ 11700 11701 int 11702 _field_actions_recover(int unit, uint32 *e_buf, 11703 _field_entry_t *entry, 11704 _field_wb_entry_t *wb_entry) 11705 { 11706 bcm_field_action_t action_id; /* action id - used in loop */ 11707 _field_action_t *curr_action = NULL; /* current action */ 11708 _field_action_t *fa = NULL; /* pointer to actions array */ 11709 int rv = 0, mirror_id = 0; /* return value, loop variable */ 11710 soc_profile_mem_t *redirect_profile; /* pointer to redirect profile mem */ 11711 int pos = 0; /* postion in the array of values 11712 * -val_array 11713 */ 11714 int hw_count = 0; /* position in the array 11715 * of hw_indices 11716 */ 11717 int append = 1; /* action installed in hw */ 11718 /* Validate input params , hw_index and val_array can be null in case there 11719 * are actions that doesnt have params or hw_index 11720 */ 11721 if (entry == NULL) { 11722 rv = BCM_E_INTERNAL; 11723 BCM_IF_ERROR_CLEANUP(rv); 11724 } 11725 11726 if (wb_entry->act_bmp.w == NULL) { 11727 return BCM_E_NONE; 11728 } 11729 11730 for (action_id = 0; action_id < wb_entry->action_count; action_id++) { 11731 if (_FP_ACTION_BMP_TEST(wb_entry->act_bmp, action_id)) { 11732 _FP_XGS3_ALLOC(curr_action, sizeof(_field_action_t), "actions"); 11733 if (curr_action == NULL) { 11734 rv = BCM_E_MEMORY; 11735 goto cleanup; 11736 } 11737 curr_action->action = action_id; 11738 curr_action->hw_index = -1; 11739 curr_action->old_index = -1; 11740 curr_action->flags = _FP_ACTION_VALID; 11741 append = 1; 11742 switch (action_id) { 11743 case bcmFieldActionGpPrioIntCopy: 11744 case bcmFieldActionGpPrioIntNew: 11745 case bcmFieldActionGpPrioIntTos: 11746 case bcmFieldActionGpPrioIntCancel: 11747 case bcmFieldActionYpPrioIntCopy: 11748 case bcmFieldActionYpPrioIntNew: 11749 case bcmFieldActionYpPrioIntTos: 11750 case bcmFieldActionYpPrioIntCancel: 11751 case bcmFieldActionRpPrioIntCopy: 11752 case bcmFieldActionRpPrioIntNew: 11753 case bcmFieldActionRpPrioIntTos: 11754 case bcmFieldActionRpPrioIntCancel: 11755 case bcmFieldActionGpDropPrecedence: 11756 case bcmFieldActionYpDropPrecedence: 11757 case bcmFieldActionRpDropPrecedence: 11758 case bcmFieldActionPrioIntCopy: 11759 case bcmFieldActionPrioIntNew: 11760 case bcmFieldActionPrioIntTos: 11761 case bcmFieldActionPrioIntCancel: 11762 case bcmFieldActionDropPrecedence: 11763 case bcmFieldActionGpIntCongestionNotificationNew: 11764 case bcmFieldActionYpIntCongestionNotificationNew: 11765 case bcmFieldActionRpIntCongestionNotificationNew: 11766 case bcmFieldActionPfcClassNew: 11767 case bcmFieldActionCosMapNew: 11768 case bcmFieldActionGpCosMapNew: 11769 case bcmFieldActionYpCosMapNew: 11770 case bcmFieldActionRpCosMapNew: 11771 case bcmFieldActionUntaggedPacketPriorityNew: 11772 rv = _field_action_profile_set1_recover(unit, entry, 11773 e_buf, curr_action); 11774 BCM_IF_ERROR_CLEANUP(rv); 11775 break; 11776 case bcmFieldActionGpEcnNew: 11777 case bcmFieldActionYpEcnNew: 11778 case bcmFieldActionRpEcnNew: 11779 case bcmFieldActionGpPrioPktCopy: 11780 case bcmFieldActionGpPrioPktNew: 11781 case bcmFieldActionGpPrioPktTos: 11782 case bcmFieldActionGpPrioPktCancel: 11783 case bcmFieldActionYpPrioPktCopy: 11784 case bcmFieldActionYpPrioPktNew: 11785 case bcmFieldActionYpPrioPktTos: 11786 case bcmFieldActionYpPrioPktCancel: 11787 case bcmFieldActionRpPrioPktCopy: 11788 case bcmFieldActionRpPrioPktNew: 11789 case bcmFieldActionRpPrioPktTos: 11790 case bcmFieldActionRpPrioPktCancel: 11791 case bcmFieldActionGpTosPrecedenceNew: 11792 case bcmFieldActionGpTosPrecedenceCopy: 11793 case bcmFieldActionGpDscpNew: 11794 case bcmFieldActionGpDscpCancel: 11795 case bcmFieldActionYpDscpNew: 11796 case bcmFieldActionYpDscpCancel: 11797 case bcmFieldActionRpDscpNew: 11798 case bcmFieldActionRpDscpCancel: 11799 case bcmFieldActionEcnNew: 11800 case bcmFieldActionPrioPktCopy: 11801 case bcmFieldActionPrioPktNew: 11802 case bcmFieldActionPrioPktTos: 11803 case bcmFieldActionPrioPktCancel: 11804 case bcmFieldActionDscpNew: 11805 case bcmFieldActionDscpCancel: 11806 case bcmFieldActionDot1pPreserve: 11807 case bcmFieldActionGpDot1pPreserve: 11808 case bcmFieldActionYpDot1pPreserve: 11809 case bcmFieldActionRpDot1pPreserve: 11810 case bcmFieldActionDscpPreserve: 11811 case bcmFieldActionGpDscpPreserve: 11812 case bcmFieldActionYpDscpPreserve: 11813 case bcmFieldActionRpDscpPreserve: 11814 rv = _field_action_profile_set2_recover(unit, entry, 11815 e_buf, curr_action); 11816 BCM_IF_ERROR_CLEANUP(rv); 11817 break; 11818 case bcmFieldActionNewClassId: 11819 case bcmFieldActionAddClassTag: 11820 case bcmFieldActionMultipathHash: 11821 case bcmFieldActionL3SwitchCancel: 11822 #ifdef INCLUDE_L3 11823 case bcmFieldActionChangeL2Fields: 11824 #endif 11825 case bcmFieldActionChangeL2FieldsCancel: 11826 case bcmFieldActionBFDSessionIdNew: 11827 rv = _field_action_l3swl2_recover(unit, entry, 11828 e_buf, curr_action); 11829 BCM_IF_ERROR_CLEANUP(rv); 11830 break; 11831 case bcmFieldActionHgTrunkRandomRoundRobinHashCancel: 11832 case bcmFieldActionTrunkRandomRoundRobinHashCancel: 11833 case bcmFieldActionEcmpRandomRoundRobinHashCancel: 11834 case bcmFieldActionNatCancel: 11835 case bcmFieldActionDoNotCutThrough: 11836 case bcmFieldActionDoNotCheckUrpf: 11837 case bcmFieldActionDoNotChangeTtl: 11838 case bcmFieldActionMirrorOverride: 11839 case bcmFieldActionIngSampleEnable: 11840 case bcmFieldActionCopyToCpuCancel: 11841 case bcmFieldActionSwitchToCpuCancel: 11842 case bcmFieldActionSwitchToCpuReinstate: 11843 case bcmFieldActionDrop: 11844 case bcmFieldActionDropCancel: 11845 case bcmFieldActionGpCopyToCpuCancel: 11846 case bcmFieldActionGpSwitchToCpuCancel: 11847 case bcmFieldActionGpSwitchToCpuReinstate: 11848 case bcmFieldActionYpCopyToCpuCancel: 11849 case bcmFieldActionYpSwitchToCpuCancel: 11850 case bcmFieldActionYpSwitchToCpuReinstate: 11851 case bcmFieldActionRpCopyToCpuCancel: 11852 case bcmFieldActionRpSwitchToCpuCancel: 11853 case bcmFieldActionRpSwitchToCpuReinstate: 11854 case bcmFieldActionGpDrop: 11855 case bcmFieldActionGpDropCancel: 11856 case bcmFieldActionYpDrop: 11857 case bcmFieldActionYpDropCancel: 11858 case bcmFieldActionRpDrop: 11859 case bcmFieldActionRpDropCancel: 11860 case bcmFieldActionNat: 11861 #ifdef INCLUDE_L3 11862 case bcmFieldActionNatEgressOverride: 11863 #endif 11864 case bcmFieldActionColorIndependent: 11865 case bcmFieldActionServicePoolIdNew: 11866 case bcmFieldActionServicePoolIdPrecedenceNew: 11867 case bcmFieldActionCosQCpuNew: 11868 case bcmFieldActionPacketTraceEnable: 11869 #if defined(BCM_TOMAHAWK2_SUPPORT) 11870 case bcmFieldActionEgressTimeStampInsert: 11871 case bcmFieldActionIngressTimeStampInsert: 11872 case bcmFieldActionIngressTimeStampInsertCancel: 11873 case bcmFieldActionEgressTimeStampInsertCancel: 11874 case bcmFieldActionDynamicTrunkEnable: 11875 case bcmFieldActionDynamicTrunkCancel: 11876 case bcmFieldActionDynamicHgTrunkEnable: 11877 case bcmFieldActionDynamicHgTrunkCancel: 11878 #if defined(INCLUDE_L3) 11879 case bcmFieldActionDynamicEcmpEnable: 11880 case bcmFieldActionDynamicEcmpCancel: 11881 case bcmFieldActionDgm: 11882 case bcmFieldActionDgmThreshold: 11883 case bcmFieldActionDgmBias: 11884 case bcmFieldActionDgmCost: 11885 case bcmFieldActionRecoverableDropCancel: 11886 #endif /*INCLUDE_L3*/ 11887 #endif /*BCM_TOMAHAWK2_SUPPORT*/ 11888 case bcmFieldActionIntEncapEnable: 11889 case bcmFieldActionIntEncapDisable: 11890 case bcmFieldActionElephantColorEnable: 11891 case bcmFieldActionElephantColorDisable: 11892 case bcmFieldActionElephantQueueEnable: 11893 case bcmFieldActionElephantQueueDisable: 11894 case bcmFieldActionElephantLookupEnable: 11895 case bcmFieldActionElephantLookupDisable: 11896 if (SOC_IS_TOMAHAWKX(unit)) { 11897 rv = _field_action_installed_check(unit, entry, e_buf, 11898 action_id, &append); 11899 BCM_IF_ERROR_CLEANUP(rv); 11900 } 11901 rv = _field_action_misc_recover(unit, entry, 11902 e_buf, curr_action); 11903 BCM_IF_ERROR_CLEANUP(rv); 11904 break; 11905 case bcmFieldActionCopyToCpu: 11906 case bcmFieldActionTimeStampToCpu: 11907 case bcmFieldActionRpCopyToCpu: 11908 case bcmFieldActionRpTimeStampToCpu: 11909 case bcmFieldActionYpCopyToCpu: 11910 case bcmFieldActionYpTimeStampToCpu: 11911 case bcmFieldActionGpCopyToCpu: 11912 case bcmFieldActionGpTimeStampToCpu: 11913 case bcmFieldActionCosQNew: 11914 case bcmFieldActionGpCosQNew: 11915 case bcmFieldActionYpCosQNew: 11916 case bcmFieldActionRpCosQNew: 11917 case bcmFieldActionUcastCosQNew: 11918 case bcmFieldActionGpUcastCosQNew: 11919 case bcmFieldActionYpUcastCosQNew: 11920 case bcmFieldActionRpUcastCosQNew: 11921 case bcmFieldActionMcastCosQNew: 11922 case bcmFieldActionGpMcastCosQNew: 11923 case bcmFieldActionYpMcastCosQNew: 11924 case bcmFieldActionRpMcastCosQNew: 11925 case bcmFieldActionEgressClassSelect: 11926 case bcmFieldActionHiGigClassSelect: 11927 case bcmFieldActionFabricQueue: 11928 #ifdef INCLUDE_L3 11929 case bcmFieldActionL3Switch: 11930 #endif 11931 case bcmFieldActionRedirect: 11932 case bcmFieldActionRedirectTrunk: 11933 case bcmFieldActionUnmodifiedPacketRedirectPort: 11934 case bcmFieldActionRedirectMcast: 11935 #ifdef INCLUDE_L3 11936 case bcmFieldActionRedirectEgrNextHop: 11937 case bcmFieldActionRedirectIpmc: 11938 #endif 11939 case bcmFieldActionRedirectCancel: 11940 case bcmFieldActionRedirectPbmp: 11941 case bcmFieldActionRedirectVlan: 11942 case bcmFieldActionRedirectBcastPbmp: 11943 case bcmFieldActionEgressMask: 11944 case bcmFieldActionEgressPortsAdd: 11945 case bcmFieldActionMirrorIngress: 11946 case bcmFieldActionMirrorEgress: 11947 case bcmFieldActionDstMacNew: 11948 case bcmFieldActionSrcMacNew: 11949 case bcmFieldActionOuterVlanNew: 11950 case bcmFieldActionVnTagNew: 11951 case bcmFieldActionVnTagDelete: 11952 case bcmFieldActionEtagNew: 11953 case bcmFieldActionEtagDelete: 11954 rv = _field_action_software_recover(unit, entry, e_buf, 11955 curr_action, wb_entry, &pos, 11956 wb_entry->action_param_type); 11957 BCM_IF_ERROR_CLEANUP(rv); 11958 break; 11959 case bcmFieldActionFabricEHAddOrUpdate: 11960 rv = _field_action_eh_recover(unit, entry, 11961 e_buf, curr_action); 11962 BCM_IF_ERROR_CLEANUP(rv); 11963 break; 11964 case bcmFieldActionClassOne: 11965 case bcmFieldActionClassZero: 11966 rv = _field_compression_actions_recover(unit, entry, 11967 curr_action); 11968 break; 11969 case bcmFieldActionDlbEcmpMonitorEnable: 11970 rv = _field_dlb_ecmp_actions_recover(unit, entry, 11971 e_buf, 11972 curr_action); 11973 break; 11974 case bcmFieldActionMatchPbmpRedirect: 11975 case bcmFieldActionMatchPbmpDrop: 11976 rv = _field_action_delayed_recover(unit, entry, 11977 e_buf, 11978 curr_action); 11979 break; 11980 case bcmFieldActionMirrorZeroingEnable: 11981 rv = _field_action_mirror_zero_recover(unit, entry, 11982 e_buf, 11983 curr_action); 11984 break; 11985 default: 11986 rv = BCM_E_INTERNAL; 11987 goto cleanup; 11988 } 11989 11990 switch (curr_action->action) { 11991 case bcmFieldActionDstMacNew: 11992 case bcmFieldActionSrcMacNew: 11993 case bcmFieldActionOuterVlanNew: 11994 case bcmFieldActionVnTagNew: 11995 case bcmFieldActionVnTagDelete: 11996 case bcmFieldActionEtagNew: 11997 case bcmFieldActionEtagDelete: 11998 case bcmFieldActionRedirectPbmp: 11999 case bcmFieldActionEgressMask: 12000 case bcmFieldActionEgressPortsAdd: 12001 case bcmFieldActionRedirectBcastPbmp: 12002 case bcmFieldActionRedirectEgrNextHop: 12003 case bcmFieldActionL3Switch: 12004 if (wb_entry->hw_idx_array != NULL) { 12005 curr_action->hw_index = 12006 wb_entry->hw_idx_array[hw_count++]; 12007 } 12008 break; 12009 case bcmFieldActionMirrorIngress: 12010 case bcmFieldActionMirrorEgress: 12011 fa = curr_action; 12012 for (mirror_id = 0; mirror_id < BCM_MIRROR_MTP_COUNT; 12013 mirror_id++) { 12014 if (wb_entry->hw_idx_array[hw_count] != -1) { 12015 fa->hw_index = wb_entry->hw_idx_array[hw_count]; 12016 if (fa ->next != NULL) { 12017 fa = fa->next; 12018 } 12019 } 12020 hw_count++; 12021 } 12022 break; 12023 default : 12024 break; 12025 } 12026 12027 12028 /* Update profile memeory for redirect action's reference count*/ 12029 if ((curr_action->action == bcmFieldActionRedirectBcastPbmp) || 12030 (curr_action->action == bcmFieldActionRedirectPbmp) || 12031 (curr_action->action == bcmFieldActionEgressMask) || 12032 (curr_action->action == bcmFieldActionEgressPortsAdd)) { 12033 #if defined (BCM_TOMAHAWK3_SUPPORT) 12034 if ((curr_action->action == bcmFieldActionEgressMask) && 12035 (soc_feature(unit, soc_feature_th3_style_fp))) { 12036 BCM_IF_ERROR_RETURN(_bcm_field_th3_redirect_profile_get(unit, 12037 &redirect_profile)); 12038 12039 } else 12040 #endif 12041 { 12042 BCM_IF_ERROR_RETURN(_field_trx_redirect_profile_get(unit, 12043 &redirect_profile)); 12044 } 12045 SOC_PROFILE_MEM_REFERENCE(unit, redirect_profile, 12046 curr_action->hw_index, 1); 12047 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, redirect_profile, 12048 curr_action->hw_index, 1); 12049 } 12050 if ((curr_action->action == bcmFieldActionMirrorIngress) || 12051 (curr_action->action == bcmFieldActionMirrorEgress)) { 12052 fa ->next = entry->actions; 12053 /* 12054 * COVERITY 12055 * 12056 * fa may include multiple actions, and it points to tail now. 12057 * Not intend to use: entry->actions = fa. 12058 */ 12059 /* coverity[copy_paste_error : FALSE] */ 12060 entry->actions = curr_action; 12061 } else if (append != 0) { 12062 curr_action->next = entry->actions; 12063 entry->actions = curr_action; 12064 } else { 12065 sal_free(curr_action); 12066 } 12067 curr_action = NULL; 12068 12069 } 12070 } 12071 12072 cleanup: 12073 return rv; 12074 } 12075 12076 /* Function: 12077 * _field_lt_entry_info_recover 12078 * 12079 * Purpose: 12080 * recover _field_lt_entry_t structure 12081 * 12082 * Paramaters: 12083 * unit - (IN) BCM device number 12084 * f_lt_ent - (IN/OUT) _field_lt_entry_t structure with memory allocated. 12085 * fc - (IN) _field_control_t structure. 12086 * flags - (IN/OUT) Array of uint32, to fill in the flags for each part. 12087 * Returns: 12088 * BCM_E_XXX 12089 */ 12090 int 12091 _field_lt_entry_info_recover(int unit, _field_lt_entry_t *f_lt_ent, 12092 uint32 flags[], _field_group_t **new_fg) 12093 { 12094 _field_tlv_t tlv; /* tlv structure */ 12095 uint8 *scache_ptr; /* pointer to scache_ptr (base) */ 12096 uint32 *position; /* pointer to scache_pos (offset) */ 12097 _field_control_t *fc = NULL; /* pointer to field control structure */ 12098 _field_stage_t *stage_fc = NULL;/* Field stage Structure */ 12099 int temp; /* Temporary variable */ 12100 int rv = 0; /* return Variable */ 12101 _field_action_t *action = NULL; /* Lt entry action */ 12102 12103 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 12104 stage_fc = curr_stage_fc; 12105 tlv.value = NULL; 12106 TLV_INIT(tlv); 12107 12108 while (tlv.type != _bcmFieldInternalEndStructEntry) { 12109 TLV_INIT(tlv); 12110 /* coverity[no_write_call : FALSE] */ 12111 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv, scache_ptr, position)); 12112 switch (tlv.type) { 12113 12114 case _bcmFieldInternalEntryFlagsPart1: 12115 f_lt_ent->flags = *(uint32 *)tlv.value; 12116 break; 12117 12118 case _bcmFieldInternalEntryFlagsPart2: 12119 flags[1] = *(uint32 *)tlv.value; 12120 break; 12121 12122 case _bcmFieldInternalEntryFlagsPart3: 12123 flags[2] = *(uint32 *)tlv.value; 12124 break; 12125 12126 12127 case _bcmFieldInternalEntryEid: 12128 f_lt_ent->eid = *(bcm_field_entry_t *)tlv.value; 12129 break; 12130 12131 12132 case _bcmFieldInternalEntrySliceId: 12133 f_lt_ent->index = *(uint32 *)tlv.value; 12134 break; 12135 12136 case _bcmFieldInternalEntryPrio: 12137 f_lt_ent->prio = *(int *)tlv.value; 12138 break; 12139 12140 12141 case _bcmFieldInternalEntrySlice: 12142 temp = *(int *)tlv.value; 12143 f_lt_ent->lt_fs = 12144 &stage_fc->lt_slices[f_lt_ent->group->instance][temp]; 12145 break; 12146 12147 case _bcmFieldInternalGroupClassAct: 12148 _FP_XGS3_ALLOC(action, sizeof(_field_action_t), "actions"); 12149 if (action == NULL) { 12150 rv = BCM_E_MEMORY; 12151 goto cleanup; 12152 } 12153 action->action = bcmFieldActionGroupClassSet; 12154 action->param[0] = *(uint32 *)tlv.value; 12155 f_lt_ent->actions = action; 12156 break; 12157 12158 case _bcmFieldInternalEntryGroup: 12159 temp = *(int *)tlv.value; 12160 if (new_fg != NULL) { 12161 while ((*new_fg) != NULL) { 12162 if((*new_fg)->gid == temp) { 12163 break; 12164 } 12165 *new_fg = (*new_fg)->next; 12166 } 12167 if ((*new_fg) == NULL) { 12168 rv = BCM_E_INTERNAL; 12169 goto cleanup; 12170 } 12171 12172 f_lt_ent->group = *new_fg; 12173 } 12174 break; 12175 12176 case _bcmFieldInternalEndStructEntry: 12177 if (*(uint32 *)tlv.value != _FIELD_WB_EM_LTENTRY) { 12178 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 12179 "END MARKER CHECK FAILED : LTENTRY\n"))); 12180 rv = BCM_E_INTERNAL; 12181 goto cleanup; 12182 } 12183 break; 12184 12185 default: 12186 break; 12187 } 12188 } 12189 12190 cleanup: 12191 TLV_INIT(tlv); 12192 return rv; 12193 } 12194 12195 /* Function: 12196 * _field_entry_policer_recover 12197 * 12198 * Purpose: 12199 * recover field policers in _field_entry_t structure 12200 * 12201 * Paramaters: 12202 * unit - (IN) BCM device number 12203 * tlv - (IN) tlv structure containing encoded types 12204 * f_ent - (IN/OUT) _field_entry_t structure with memory allocated. 12205 * Returns: 12206 * BCM_E_XXX 12207 */ 12208 int 12209 _field_entry_policer_recover(int unit, _field_tlv_t *tlv, _field_entry_t *f_ent) 12210 { 12211 12212 int type_pos = 0; /* position of type */ 12213 int i = 0; /* local variable for loops */ 12214 int num_instances = 0; /* number of instances */ 12215 int num_types = 0; /* Number of types */ 12216 _field_tlv_t tlv2; /* TLV structure */ 12217 uint32 *type; /* Elem type */ 12218 uint8 *scache_ptr; /* Scahce pointer */ 12219 uint32 *position; /* Scache position */ 12220 _field_control_t *fc = NULL; /* Field control structure. */ 12221 12222 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 12223 tlv2.value = NULL; 12224 TLV_INIT(tlv2); 12225 type = (uint32 *)tlv->value; 12226 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 12227 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 12228 _FP_WB_TLV_TYPE_SHIFT); 12229 12230 for (i = 0; i < num_instances; i++) { 12231 12232 type_pos = 0; 12233 while ((tlv2.type != _bcmFieldInternalEndStructEntPolicer) 12234 && (type_pos != num_types)) { 12235 TLV_INIT(tlv2); 12236 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 12237 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 12238 _FP_WB_TLV_BASIC_TYPE_SHIFT); 12239 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, scache_ptr, position)); 12240 12241 switch (tlv2.type) { 12242 12243 case _bcmFieldInternalEntryPolicerPid: 12244 f_ent->policer[i].pid = *(bcm_policer_t *)tlv2.value; 12245 break; 12246 case _bcmFieldInternalEntryPolicerFlags: 12247 f_ent->policer[i].flags = *(uint8 *)tlv2.value; 12248 break; 12249 case _bcmFieldInternalEndStructEntPolicer: 12250 TLV_INIT(tlv2); 12251 break; 12252 default: 12253 break; 12254 } 12255 type_pos++; 12256 } 12257 } 12258 return BCM_E_NONE; 12259 } 12260 12261 /* Function: 12262 * _field_entry_info_recover 12263 * 12264 * Purpose: 12265 * recover _field_entry_t structure 12266 * 12267 * Paramaters: 12268 * unit - (IN) BCM device number 12269 * f_ent - (IN/OUT) _field_entry_t structure with memory allocated. 12270 * flags - (IN/OUT) Array of uint32, to fill in the flags for each part. 12271 * parts_count - (IN) number of parts of Field Entry. 12272 * new_fg - (IN) Array of Groups 12273 * act_bmp - (OUT) Pbmp of Actions 12274 * val_array - (OUT) Array of parameters 12275 * hw_idx_array - (OUT) Array of hardware indices 12276 * action_count - (OUT) Number of Action 12277 * 12278 * Returns: 12279 * BCM_E_XXX 12280 */ 12281 12282 int 12283 _field_entry_info_recover(int unit, _field_entry_t *f_ent, 12284 int parts_count, _field_group_t **new_fg, 12285 _field_wb_entry_t *wb_entry) 12286 12287 { 12288 _field_tlv_t tlv; /* tlv structure */ 12289 uint8 *scache_ptr; /* pointer to scache_ptr (base) */ 12290 uint32 *position; /* Pointer to scache_pos (offset) */ 12291 /* uint32 flag_cpy[_FP_TH_MAX_ENTRY_WIDTH] = {0}; */ 12292 /* array to flags of each entry part, 12293 * entries parts of the same 12294 * entry differ only in flags 12295 */ 12296 _field_control_t *fc = NULL; /* pointer to field control structure */ 12297 _field_stage_t *stage_fc = NULL; /* Field stage structure */ 12298 int temp = 0; /* Temporary variable */ 12299 int rv = 0; /* Return Variable */ 12300 12301 tlv.value = NULL; 12302 TLV_INIT(tlv); 12303 12304 wb_entry->act_bmp.w = NULL; 12305 12306 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 12307 stage_fc = curr_stage_fc; 12308 12309 while (tlv.type != _bcmFieldInternalEndStructEntry) { 12310 TLV_INIT(tlv); 12311 /* coverity[no_write_call : FALSE] */ 12312 rv = tlv_read(unit, &tlv, scache_ptr, position); 12313 BCM_IF_ERROR_CLEANUP(rv); 12314 switch (tlv.type) 12315 { 12316 12317 case _bcmFieldInternalEntryEid: 12318 f_ent->eid = *(bcm_field_entry_t *)tlv.value; 12319 break; 12320 case _bcmFieldInternalEntryPrio: 12321 f_ent->prio = *(int *)tlv.value; 12322 break; 12323 12324 case _bcmFieldInternalEntrySliceId: 12325 f_ent->slice_idx = *(uint32 *)tlv.value; 12326 break; 12327 12328 case _bcmFieldInternalEntryFlagsPart1: 12329 f_ent->flags = *(uint32 *)tlv.value; 12330 break; 12331 12332 case _bcmFieldInternalEntryFlagsPart2: 12333 wb_entry->flags[1] = *(uint32 *)tlv.value; 12334 break; 12335 12336 case _bcmFieldInternalEntryFlagsPart3: 12337 wb_entry->flags[2] = *(uint32 *)tlv.value; 12338 break; 12339 12340 case _bcmFieldInternalEntryPbmpData: 12341 f_ent->pbmp.data = *(bcm_pbmp_t *)tlv.value; 12342 break; 12343 12344 case _bcmFieldInternalEntryPbmpMask: 12345 f_ent->pbmp.mask = *(bcm_pbmp_t *)tlv.value; 12346 break; 12347 12348 case _bcmFieldInternalEntryPbmpFullData: 12349 sal_memcpy(f_ent->pbmp.data.pbits, tlv.value, 12350 (tlv.length * recovery_type_map[unit][tlv.type].size)); 12351 break; 12352 12353 case _bcmFieldInternalEntryPbmpFullMask: 12354 sal_memcpy(f_ent->pbmp.mask.pbits, tlv.value, 12355 (tlv.length * recovery_type_map[unit][tlv.type].size)); 12356 break; 12357 12358 case _bcmFieldInternalEntrySlice: 12359 temp = *(int *)tlv.value; 12360 f_ent->fs = &stage_fc->slices[f_ent->group->instance][temp]; 12361 break; 12362 12363 case _bcmFieldInternalEntryGroup: 12364 temp = *(int *)tlv.value; 12365 while ((*new_fg) != NULL) { 12366 if((*new_fg)->gid == temp) { 12367 break; 12368 } 12369 *new_fg = (*new_fg)->next; 12370 } 12371 12372 if ((*new_fg) == NULL) { 12373 rv = BCM_E_INTERNAL; 12374 goto cleanup; 12375 } 12376 f_ent->group = *new_fg; 12377 break; 12378 12379 case _bcmFieldInternalEntryActionsPbmp: 12380 _FP_XGS3_ALLOC(wb_entry->act_bmp.w, 12381 (tlv.length * recovery_type_map[unit][tlv.type].size), 12382 "action_bmp"); 12383 if (wb_entry->act_bmp.w == NULL) { 12384 rv = BCM_E_MEMORY; 12385 goto cleanup; 12386 } 12387 wb_entry->action_count = (tlv.length 12388 * recovery_type_map[unit][tlv.type].size * 8); 12389 sal_memcpy(wb_entry->act_bmp.w, tlv.value, 12390 (tlv.length * recovery_type_map[unit][tlv.type].size)); 12391 break; 12392 12393 case _bcmFieldInternalActionParam: 12394 wb_entry->val_array0 = (int *)tlv.value; 12395 wb_entry->action_param_type = 0; 12396 tlv.value = NULL; 12397 break; 12398 12399 case _bcmFieldInternalActionParam1: 12400 wb_entry->val_array = (int *)tlv.value; 12401 wb_entry->action_param_type = 1; 12402 tlv.value = NULL; 12403 break; 12404 12405 case _bcmFieldInternalActionHwIdx: 12406 wb_entry->hw_idx_array = (int *)tlv.value; 12407 tlv.value = NULL; 12408 break; 12409 12410 case _bcmFieldInternalEntryStatSid: 12411 f_ent->statistic.sid = *(int *)tlv.value; 12412 break; 12413 12414 case _bcmFieldInternalEntryStatExtendedSid: 12415 f_ent->statistic.extended_sid = *(int *)(tlv.value); 12416 break; 12417 case _bcmFieldInternalEntryStatFlags: 12418 f_ent->statistic.flags = *(uint16 *)tlv.value; 12419 break; 12420 case _bcmFieldInternalEntryStatAction: 12421 f_ent->statistic.stat_action = 12422 *(bcm_field_stat_action_t *)tlv.value; 12423 break; 12424 12425 case _bcmFieldInternalEntryPolicer: 12426 _field_entry_policer_recover(unit, &tlv, f_ent); 12427 break; 12428 12429 case _bcmFieldInternalGlobalEntryPolicerPid: 12430 f_ent->global_meter_policer.pid = *(bcm_policer_t *) tlv.value; 12431 break; 12432 12433 case _bcmFieldInternalGlobalEntryPolicerFlags: 12434 f_ent->global_meter_policer.flags = *(uint8 *)tlv.value; 12435 break; 12436 12437 case _bcmFieldInternalEntryIngMtp: 12438 f_ent->ing_mtp_slot_map = *(uint8 *)tlv.value; 12439 break; 12440 12441 case _bcmFieldInternalEntryEgrMtp: 12442 f_ent->egr_mtp_slot_map = *(uint8 *)tlv.value; 12443 break; 12444 12445 case _bcmFieldInternalEntryDvp: 12446 f_ent->dvp_type = *(uint8 *)tlv.value; 12447 break; 12448 case _bcmFieldInternalEntrySvpType: 12449 f_ent->svp_type = *(uint8 *)tlv.value; 12450 break; 12451 case _bcmFieldInternalEntryTcamIptype: 12452 f_ent->tcam.ip_type = *(uint8 *)tlv.value; 12453 break; 12454 case _bcmFieldInternalEntryCopy: 12455 /* 12456 _FP_XGS3_ALLOC(f_ent->ent_copy, 12457 parts_count* sizeof(_field_entry_t), "field entry copy"); 12458 _field_entry_info_recover(unit, f_ent->ent_copy, flag_cpy, 12459 parts_count, new_fg, policy_mem, 12460 policy_buf); 12461 if (parts_count > 1) { 12462 for (j=1; j < parts_count; j++) { 12463 sal_memcpy((f_ent->ent_copy)+j, (f_ent->ent_copy), 12464 sizeof(_field_entry_t)); 12465 ((f_ent->ent_copy)+j)->flags = flag_cpy[j]; 12466 } 12467 } 12468 */ 12469 break; 12470 12471 case _bcmFieldInternalEndStructEntry: 12472 if (*(uint32 *)tlv.value != _FIELD_WB_EM_ENTRY) { 12473 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 12474 "END MARKER CHECK FAILED : ENTRY\n"))); 12475 rv = BCM_E_INTERNAL; 12476 goto cleanup; 12477 } 12478 break; 12479 12480 default: 12481 break; 12482 } 12483 } 12484 TLV_INIT(tlv); 12485 return BCM_E_NONE; 12486 cleanup: 12487 TLV_INIT(tlv); 12488 if (f_ent->actions != NULL) { 12489 sal_free(f_ent->actions); 12490 f_ent->actions = NULL; 12491 } 12492 if (f_ent->ent_copy != NULL) { 12493 sal_free(f_ent->ent_copy); 12494 f_ent->ent_copy = NULL; 12495 } 12496 return rv; 12497 } 12498 12499 /* Function: 12500 * _field_entry_recover_policer_actual_hw_rates 12501 * 12502 * Purpose: 12503 * Recover actual hardware rates for policers already 12504 * installed in coldboot. 12505 * 12506 * Paramaters: 12507 * unit - (IN) BCM device number 12508 * f_ent - (IN) Field entry structure 12509 * 12510 * Returns: 12511 * BCM_E_XXX 12512 */ 12513 12514 int _field_entry_recover_policer_actual_hw_rates(int unit, _field_entry_t *f_ent) 12515 { 12516 _field_policer_t *f_pl; /*Internal policer descriptor. */ 12517 _field_entry_policer_t *f_ent_pl; /*Field entry policer structure.*/ 12518 _field_stage_t *stage_fc; /*Field stage control structure.*/ 12519 soc_mem_t policer_mem = INVALIDm; /*Meter table name. */ 12520 int idx; /*Policers levels iterator. */ 12521 int rv = BCM_E_NONE;/*Operation return status. */ 12522 12523 for (idx = 0; idx < _FP_POLICER_LEVEL_COUNT; idx++) { 12524 f_ent_pl = f_ent->policer + idx; 12525 12526 rv = _bcm_field_policer_get(unit, f_ent_pl->pid, &f_pl); 12527 12528 if (BCM_SUCCESS(rv)) { 12529 if(!(f_ent->policer[idx].flags & _FP_POLICER_INSTALLED)) { 12530 continue; 12531 } 12532 rv = _field_stage_control_get (unit, f_ent->fs->stage_id, &stage_fc); 12533 BCM_IF_ERROR_RETURN(rv); 12534 12535 /* Resolve meter table name. */ 12536 rv = _bcm_field_th_policer_mem_get(unit, stage_fc, f_ent->group->instance, 12537 &policer_mem); 12538 BCM_IF_ERROR_RETURN(rv); 12539 12540 rv = _field_entry_policer_update_actual_hw_rates(unit, policer_mem, 12541 f_ent->group->instance, 12542 f_ent, f_pl); 12543 BCM_IF_ERROR_RETURN(rv); 12544 } 12545 } 12546 return BCM_E_NONE; 12547 } 12548 12549 /* Function: 12550 * _field_entry_recover 12551 * 12552 * Purpose: 12553 * recover _field_entry_t and _field_lt_entry_t structures 12554 * For each group, 12555 * Get partscount and number of entries, call entry recover for each entry 12556 * Using the same parts count, and get number of lt_entries, call 12557 * lt_entry_recover for each lt_entry. 12558 * Proceed to next group. 12559 * when _bcmFieldInternalEndStructEntryDetails is reached, that means all 12560 * entries in all groups are recovered. 12561 * 12562 * Paramaters: 12563 * unit - (IN) BCM device number 12564 * 12565 * Returns: 12566 * BCM_E_XXX 12567 */ 12568 int 12569 _field_entry_recover(int unit, _field_group_t *new_fg) 12570 { 12571 _field_tlv_t tlv; /* tlv structure */ 12572 uint8 *scache_ptr; /* pointer to scache_pointer (base) */ 12573 uint32 *position; /* pointer to scache_pos */ 12574 uint32 flags[_FP_TH_MAX_ENTRY_WIDTH] = {0}; 12575 /* Flags array to store flags 12576 * for each entry part 12577 */ 12578 _field_control_t *fc = NULL; /* pointer to field control structure */ 12579 _field_entry_t *f_ent = NULL; /* pointer to entry structure */ 12580 _field_lt_entry_t *f_lt_ent = NULL; /* pointer to lt_entry structure */ 12581 12582 int i,j, parts_count = 0; /* i,j - loop variables 12583 * parts_count -> 12584 * Number of parts in entry 12585 */ 12586 int entry_count = 0, rv = 0; /* entry_count -> number of entries 12587 * rv -> return value 12588 */ 12589 _field_stage_t *stage_fc = NULL; /* Field Stage structure */ 12590 int pri_tcam_idx = -1; /* Primary tcam index */ 12591 int policy_tcam_idx = -1; /* Policy memory index */ 12592 int slice_number = 0; /* Slice where entry belongs */ 12593 int part_index = 0; /* To loop through parts */ 12594 char *fp_policy_buf[_FP_MAX_NUM_PIPES] = {0}; 12595 /* Buffer to read the FP_POLICY table */ 12596 char *fp_policy_buf_wide[_FP_MAX_NUM_PIPES] = {0}; 12597 /* Buffer to read the FP_POLICY wide table */ 12598 12599 char *ifp_act_profile_buf[_FP_MAX_NUM_PIPES] = {0}; 12600 /* Buffer to read the action profile table */ 12601 char *lt_policy_buf[_FP_MAX_NUM_PIPES] = {0}; 12602 /* Buffer to read the FP_POLICY table */ 12603 int index_min = -1, index_max = -1; /* Min and max index in Policy memory */ 12604 int pipe = 0; /* Pipe variable */ 12605 uint32 *e_buf = NULL; /* Buffer holding corresponding entry */ 12606 _field_stat_t *f_st = NULL; /* Field Stat structure */ 12607 bcm_stat_group_mode_t stat_mode; /* Stat type bcmStatGroupModeXXX. */ 12608 bcm_stat_object_t stat_obj; /* Stat object type. */ 12609 bcm_stat_flex_mode_t offset_mode; /* Counter mode. */ 12610 int fp_stat_mode_max; /* Max stat modes. */ 12611 uint8 idx; /* Index to carry loop count. */ 12612 uint32 pool_num; /* Flex Stat Hw Pool No. */ 12613 uint32 base_index; /* Flex Stat counter base index. */ 12614 uint32 num_hw_cntrs; /* Number of counters allocated. */ 12615 uint32 req_bmap = 0; /* Requested statistics bitmap. */ 12616 uint32 hw_bmap; /* HW supported statistics bitmap. */ 12617 int act_idx = -1; /* Action profile index */ 12618 uint32 act_data[12] = {0}; /* Action data */ 12619 uint32 *action_prof_buf = NULL; /* Action profile buffer */ 12620 _field_wb_entry_t wb_entry; /* Set of WB entry info */ 12621 _field_action_bmp_t action_bitmap; /* Entry action bitmap */ 12622 _field_group_t *entry_fg = new_fg; /* Pointer to ingress groups*/ 12623 _field_group_t *lt_entry_fg = new_fg; /* Pointer to ingress groups for lt*/ 12624 int entry_pos = 0; /* No of entries in a group */ 12625 soc_mem_t lt_policy_mem = INVALIDm; /* LT Policy memory */ 12626 soc_mem_t fp_policy_mem_wide = INVALIDm; /* IFP Policy memory wide */ 12627 soc_mem_t fp_policy_mem = INVALIDm; /* IFP Policy memeory */ 12628 soc_mem_t fp_action_profile_mem = INVALIDm;/* IFP action profile memeory */ 12629 12630 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 12631 _BCM_FIELD_STAGE_INGRESS, &stage_fc)); 12632 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 12633 tlv.value = NULL; 12634 TLV_INIT(tlv); 12635 12636 12637 wb_entry.action_count = -1; 12638 wb_entry.action_param_type = -1; 12639 wb_entry.hw_idx_array = NULL; 12640 wb_entry.val_array = NULL; 12641 wb_entry.val_array0 = NULL; 12642 12643 for (pipe = 0; pipe < stage_fc->num_pipes; pipe++) { 12644 if (!(fc->pipe_map & (1 << pipe))) { 12645 continue; 12646 } 12647 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 12648 fp_policy_mem = IFP_POLICY_TABLEm; 12649 lt_policy_mem = IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm; 12650 if (soc_feature(unit, soc_feature_ifp_action_profiling)) { 12651 fp_policy_mem_wide = IFP_POLICY_TABLE_WIDEm; 12652 fp_action_profile_mem = IFP_POLICY_ACTION_PROFILEm; 12653 } 12654 } else { 12655 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 12656 IFP_POLICY_TABLEm, 12657 pipe, &fp_policy_mem)); 12658 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 12659 IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm, 12660 pipe, <_policy_mem)); 12661 if (soc_feature(unit, soc_feature_ifp_action_profiling)) { 12662 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 12663 IFP_POLICY_TABLE_WIDEm, 12664 pipe, &fp_policy_mem_wide)); 12665 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 12666 IFP_POLICY_ACTION_PROFILEm, 12667 pipe, &fp_action_profile_mem)); 12668 } 12669 } 12670 12671 fp_policy_buf[pipe] = soc_cm_salloc(unit, 12672 SOC_MEM_TABLE_BYTES(unit, fp_policy_mem), 12673 "FP POLICY TABLE buffer"); 12674 lt_policy_buf[pipe] = soc_cm_salloc(unit, 12675 SOC_MEM_TABLE_BYTES(unit, lt_policy_mem), 12676 "FP POLICY TABLE buffer"); 12677 /* starting from TD3, we have IFP_POLICY_TABLE_WIDE hw tables 12678 action profile tables.*/ 12679 if (soc_feature(unit, soc_feature_ifp_action_profiling)) { 12680 fp_policy_buf_wide[pipe] = soc_cm_salloc(unit, 12681 SOC_MEM_TABLE_BYTES(unit, fp_policy_mem_wide), 12682 "FP POLICY TABLE WIDE buffer"); 12683 ifp_act_profile_buf[pipe] = soc_cm_salloc(unit, 12684 SOC_MEM_TABLE_BYTES(unit, fp_action_profile_mem), 12685 "act Profile table buffer"); 12686 if ((NULL == fp_policy_buf_wide[pipe]) || 12687 (NULL == ifp_act_profile_buf[pipe])) { 12688 rv = BCM_E_MEMORY; 12689 goto cleanup; 12690 } 12691 } 12692 if ((NULL == fp_policy_buf[pipe]) || (NULL == lt_policy_buf[pipe])) { 12693 rv = BCM_E_MEMORY; 12694 goto cleanup; 12695 } 12696 /* starting from TD3, we have IFP_POLICY_TABLE_WIDE hw tables 12697 action profile tables.read and keep the entries for these table too*/ 12698 if (soc_feature(unit, soc_feature_ifp_action_profiling)) { 12699 index_min = soc_mem_index_min(unit, fp_policy_mem_wide); 12700 index_max = soc_mem_index_max(unit, fp_policy_mem_wide); 12701 rv = soc_mem_read_range(unit, fp_policy_mem_wide, MEM_BLOCK_ALL, 12702 index_min, index_max, fp_policy_buf_wide[pipe]); 12703 BCM_IF_ERROR_CLEANUP(rv); 12704 index_min = soc_mem_index_min(unit, fp_action_profile_mem); 12705 index_max = soc_mem_index_max(unit, fp_action_profile_mem); 12706 rv = soc_mem_read_range(unit, fp_action_profile_mem, MEM_BLOCK_ALL, 12707 index_min, index_max, ifp_act_profile_buf[pipe]); 12708 BCM_IF_ERROR_CLEANUP(rv); 12709 } 12710 index_min = soc_mem_index_min(unit, fp_policy_mem); 12711 index_max = soc_mem_index_max(unit, fp_policy_mem); 12712 rv = soc_mem_read_range(unit, fp_policy_mem, MEM_BLOCK_ALL, 12713 index_min, index_max, fp_policy_buf[pipe]); 12714 BCM_IF_ERROR_CLEANUP(rv); 12715 12716 index_min = soc_mem_index_min(unit, lt_policy_mem); 12717 index_max = soc_mem_index_max(unit, lt_policy_mem); 12718 rv = soc_mem_read_range(unit, lt_policy_mem, MEM_BLOCK_ALL, 12719 index_min, index_max, lt_policy_buf[pipe]); 12720 BCM_IF_ERROR_CLEANUP(rv); 12721 } 12722 12723 while (tlv.type != _bcmFieldInternalEndStructEntryDetails) { 12724 TLV_INIT(tlv); 12725 /* coverity[no_write_call : FALSE] */ 12726 rv = tlv_read(unit, &tlv, scache_ptr, position); 12727 BCM_IF_ERROR_CLEANUP(rv); 12728 switch (tlv.type) { 12729 case _bcmFieldInternalGroupPartCount: 12730 parts_count = *(int *)tlv.value; 12731 break; 12732 12733 case _bcmFieldInternalGroupEntry: 12734 entry_count = *(int *)tlv.value; 12735 entry_pos = 0; 12736 for (i = 0; i < entry_count; i++) { 12737 _FP_XGS3_ALLOC(f_ent, parts_count* sizeof(_field_entry_t), 12738 "field entry"); 12739 if (f_ent == NULL) { 12740 rv = BCM_E_MEMORY; 12741 goto cleanup; 12742 } 12743 12744 sal_memset(wb_entry.flags, 0, sizeof(wb_entry.flags)); 12745 12746 /* Recover entry */ 12747 rv = _field_entry_info_recover(unit, f_ent, 12748 parts_count, &entry_fg, 12749 &wb_entry); 12750 BCM_IF_ERROR_CLEANUP(rv); 12751 12752 action_bitmap = wb_entry.act_bmp; 12753 /* Increment Stat reference counts */ 12754 f_st = NULL; 12755 if ((!soc_feature(unit, soc_feature_ifp_action_profiling)) || 12756 (0 == (f_ent->flags & _FP_ENTRY_INSTALLED))) { 12757 rv = _bcm_field_stat_get(unit, f_ent->statistic.sid, 12758 &f_st); 12759 if ((BCM_SUCCESS(rv)) && (f_st->flex_mode != 0)) { 12760 offset_mode = pool_num = base_index = num_hw_cntrs = -1; 12761 12762 /* Get flex counter hardware details stored in flex stat ID.*/ 12763 _bcm_esw_stat_get_counter_id_info(unit, f_st->flex_mode, 12764 &stat_mode, 12765 &stat_obj, 12766 &offset_mode, 12767 &pool_num, 12768 &base_index); 12769 12770 if ((bcmStatObjectIngFieldStageIngress == stat_obj) || 12771 (bcmStatObjectIngExactMatch == stat_obj)){ 12772 /* Get application requested bitmap. */ 12773 rv = (_bcm_field_stat_array_to_bmap(unit, f_st, 12774 &req_bmap)); 12775 BCM_IF_ERROR_CLEANUP(rv); 12776 12777 fp_stat_mode_max = th_ingress_cntr_hw_mode_tbl_size; 12778 12779 for (idx = 0; idx < fp_stat_mode_max; idx++) { 12780 hw_bmap = th_ingress_cntr_hw_mode_tbl[idx].hw_bmap; 12781 num_hw_cntrs = th_ingress_cntr_hw_mode_tbl[idx].hw_entry_count; 12782 12783 if (0 == ((req_bmap | hw_bmap) & ~(hw_bmap))) { 12784 /* 12785 * For maximizing utilization of hardware counters, this should 12786 * select the hw_mode both supports the requested stats 12787 * AND minimizes the number of required hardware counters. 12788 */ 12789 break; 12790 } 12791 } 12792 } else { 12793 num_hw_cntrs = 1; 12794 } 12795 12796 /* Store flex stat hardware details in stat data structure. */ 12797 f_st->pool_index = pool_num; 12798 f_st->hw_index = base_index; 12799 f_st->hw_mode = offset_mode; 12800 f_st->hw_entry_count = num_hw_cntrs; 12801 f_st->hw_stat = req_bmap; 12802 f_st->sw_ref_count = f_st->sw_ref_count + 1; 12803 12804 if(_FP_ENTRY_INSTALLED & f_ent->flags) { 12805 f_st->hw_ref_count = f_st->hw_ref_count + 1; 12806 } 12807 12808 f_st->gid = f_ent->group->gid; 12809 } 12810 } 12811 12812 /* Get tcam index for entry */ 12813 pipe = f_ent->group->instance; 12814 rv = _bcm_field_slice_offset_to_tcam_idx (unit, stage_fc, 12815 pipe, 12816 f_ent->fs->slice_number, 12817 f_ent->slice_idx, 12818 &pri_tcam_idx); 12819 policy_tcam_idx = pri_tcam_idx; 12820 /* for TD3/TH3, irrespective of group mode, tcam idx =policy idx 12821 so the below check and computation is only valid for 12822 non TD3/TH3 devices */ 12823 if ((!soc_feature(unit, soc_feature_td3_style_fp)) 12824 && (!soc_feature(unit, soc_feature_th3_style_fp)) 12825 && (!(f_ent->group->flags 12826 & _FP_GROUP_SPAN_SINGLE_SLICE) 12827 || (f_ent->group->flags 12828 & _FP_GROUP_INTRASLICE_DOUBLEWIDE))) { 12829 policy_tcam_idx = pri_tcam_idx 12830 + (f_ent->fs->slice_number * 256); 12831 } 12832 12833 BCM_IF_ERROR_CLEANUP(rv); 12834 12835 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 12836 fp_policy_mem = IFP_POLICY_TABLEm; 12837 lt_policy_mem = IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm; 12838 if (soc_feature(unit, soc_feature_ifp_action_profiling)) { 12839 fp_policy_mem_wide = IFP_POLICY_TABLE_WIDEm; 12840 fp_action_profile_mem = IFP_POLICY_ACTION_PROFILEm; 12841 } 12842 } else { 12843 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 12844 IFP_POLICY_TABLEm, 12845 pipe, &fp_policy_mem)); 12846 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 12847 IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm, 12848 pipe, <_policy_mem)); 12849 if (soc_feature(unit, soc_feature_ifp_action_profiling)) { 12850 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 12851 IFP_POLICY_TABLE_WIDEm, 12852 pipe, &fp_policy_mem_wide)); 12853 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 12854 IFP_POLICY_ACTION_PROFILEm, 12855 pipe, &fp_action_profile_mem)); 12856 } 12857 } 12858 12859 if (soc_feature(unit, 12860 soc_feature_fp_nw_tcam_prio_order_war)) { 12861 rv = soc_mem_field_nw_tcam_prio_order_index_get(unit, 12862 fp_policy_mem, 12863 &policy_tcam_idx); 12864 BCM_IF_ERROR_CLEANUP(rv); 12865 } 12866 /* Get memory for tcam index */ 12867 e_buf = soc_mem_table_idx_to_pointer( 12868 unit, 12869 fp_policy_mem, 12870 uint32 *, 12871 fp_policy_buf[pipe], 12872 policy_tcam_idx); 12873 /* for wider mode groups, policy table in TD3 12874 will be IFP_POLICY_TABLE_WIDE. so we have to use 12875 the corresponding wide bufs */ 12876 if (soc_feature(unit, soc_feature_ifp_action_profiling)) { 12877 if (!(f_ent->group->flags 12878 & _FP_GROUP_SPAN_SINGLE_SLICE) 12879 || (f_ent->group->flags 12880 & _FP_GROUP_INTRASLICE_DOUBLEWIDE)) { 12881 e_buf = soc_mem_table_idx_to_pointer( 12882 unit, 12883 fp_policy_mem_wide, 12884 uint32 *, 12885 fp_policy_buf_wide[pipe], 12886 policy_tcam_idx); 12887 soc_mem_field_get(unit, fp_policy_mem_wide, 12888 e_buf, POLICY_DATAf, act_data); 12889 } else { 12890 soc_mem_field_get(unit, fp_policy_mem, e_buf, 12891 POLICY_DATAf, act_data); 12892 } 12893 } 12894 12895 if (f_ent->flags & _FP_ENTRY_INSTALLED) { 12896 /* Actions recover for entry for non TD3 devices*/ 12897 if (!soc_feature(unit, soc_feature_ifp_action_profiling)) { 12898 rv = _field_actions_recover(unit, e_buf, 12899 f_ent, &wb_entry); 12900 BCM_IF_ERROR_CLEANUP(rv); 12901 } else { 12902 /* 12903 * For TD3, need to parse the action profile to get 12904 * the s/w structures updated for actions 12905 */ 12906 act_idx = f_ent->group->action_profile_idx[0]; 12907 if (act_idx != -1) { 12908 action_prof_buf = soc_mem_table_idx_to_pointer(unit, 12909 fp_action_profile_mem, 12910 uint32 *, ifp_act_profile_buf[pipe], 12911 act_idx); 12912 rv = _field_wb_action_profile_parse(unit, f_ent, 12913 action_prof_buf, act_data, 12914 &action_bitmap); 12915 BCM_IF_ERROR_CLEANUP(rv); 12916 rv = field_wb_td3_ifp_actions_recover(unit, 12917 e_buf, f_ent, &wb_entry); 12918 BCM_IF_ERROR_CLEANUP(rv); 12919 } 12920 } 12921 /* Update Slice hw entry count */ 12922 f_ent->fs->hw_ent_count +=1; 12923 12924 } else { 12925 if (NULL != wb_entry.val_array) { 12926 sal_free(wb_entry.val_array); 12927 } 12928 if (NULL != wb_entry.hw_idx_array) { 12929 sal_free(wb_entry.hw_idx_array); 12930 } 12931 wb_entry.val_array = NULL; 12932 wb_entry.hw_idx_array = NULL; 12933 } 12934 12935 rv = _field_entry_recover_policer_actual_hw_rates(unit, f_ent); 12936 BCM_IF_ERROR_CLEANUP(rv); 12937 12938 /* Recover remaining entry parts */ 12939 if (parts_count > 1) { 12940 for (j=1; j < parts_count; j++) { 12941 sal_memcpy(f_ent+j, f_ent, sizeof(_field_entry_t)); 12942 (f_ent+j)->flags = wb_entry.flags[j]; 12943 (f_ent+j)->actions = NULL; 12944 /* Given primary entry tcam index calculate entry 12945 part tcam index. */ 12946 rv = _bcm_field_entry_part_tcam_idx_get(unit, f_ent, 12947 pri_tcam_idx, j, &part_index); 12948 BCM_IF_ERROR_CLEANUP(rv); 12949 /* recover the actions from remaining entry parts */ 12950 if (soc_feature(unit, soc_feature_ifp_action_profiling)) { 12951 act_idx = f_ent->group->action_profile_idx[j]; 12952 if (act_idx != -1) { 12953 e_buf = soc_mem_table_idx_to_pointer( 12954 unit, 12955 fp_policy_mem_wide, 12956 uint32 *, 12957 fp_policy_buf_wide[pipe], 12958 part_index); 12959 /* retrieve action data */ 12960 soc_mem_field_get(unit, fp_policy_mem_wide, 12961 e_buf, POLICY_DATAf, act_data); 12962 /* retrieve action profile */ 12963 action_prof_buf = soc_mem_table_idx_to_pointer(unit, 12964 fp_action_profile_mem, 12965 uint32 *, ifp_act_profile_buf[pipe], 12966 act_idx); 12967 /* parse and update the f_ent->actions */ 12968 rv = _field_wb_action_profile_parse(unit, f_ent, 12969 action_prof_buf, act_data, 12970 &action_bitmap); 12971 BCM_IF_ERROR_CLEANUP(rv); 12972 rv = field_wb_td3_ifp_actions_recover(unit, 12973 e_buf, f_ent, &wb_entry); 12974 BCM_IF_ERROR_CLEANUP(rv); 12975 } 12976 } 12977 rv = _bcm_field_th_tcam_idx_to_slice_offset(unit, 12978 stage_fc, f_ent, part_index, 12979 &slice_number, 12980 (int *)&f_ent[j].slice_idx); 12981 BCM_IF_ERROR_CLEANUP(rv); 12982 f_ent[j].fs = 12983 stage_fc->slices[f_ent->group->instance] 12984 + slice_number; 12985 12986 /* Update Slice hw entry count */ 12987 if (f_ent->flags & _FP_ENTRY_INSTALLED) { 12988 f_ent[j].fs->hw_ent_count +=1; 12989 } 12990 12991 } 12992 12993 } 12994 12995 if (f_ent->flags & _FP_ENTRY_INSTALLED) { 12996 if (NULL != wb_entry.val_array) { 12997 sal_free(wb_entry.val_array); 12998 } 12999 if (NULL != wb_entry.hw_idx_array) { 13000 sal_free(wb_entry.hw_idx_array); 13001 } 13002 } 13003 13004 /* We free memory in actions recover for installed actions*/ 13005 wb_entry.val_array = NULL; 13006 wb_entry.hw_idx_array = NULL; 13007 13008 entry_fg->entry_arr[entry_pos] = f_ent; 13009 entry_pos++; 13010 for (part_index = 0; part_index < parts_count; 13011 part_index ++) { 13012 f_ent[part_index].fs->entries[ 13013 f_ent[part_index].slice_idx] = f_ent + part_index; 13014 13015 } 13016 f_ent = NULL; 13017 } 13018 break; 13019 13020 case _bcmFieldInternalGroupLtEntry: 13021 entry_count = *(int *)tlv.value; 13022 entry_pos= 0; 13023 for (i = 0; i < entry_count; i++) { 13024 _FP_XGS3_ALLOC(f_lt_ent, 13025 parts_count*sizeof(_field_lt_entry_t), "field entry"); 13026 if (f_lt_ent == NULL) { 13027 rv = BCM_E_MEMORY; 13028 goto cleanup; 13029 } 13030 sal_memset(flags, 0, sizeof(flags)); 13031 13032 /* Recover entry */ 13033 rv =_field_lt_entry_info_recover(unit, f_lt_ent, 13034 flags, <_entry_fg); 13035 13036 /* Get tcam index for entry */ 13037 rv = _bcm_field_th_lt_slice_offset_to_tcam_index(unit, 13038 stage_fc, f_lt_ent->group->instance, 13039 f_lt_ent->lt_fs->slice_number, 13040 f_lt_ent->index, &pri_tcam_idx); 13041 BCM_IF_ERROR_CLEANUP(rv); 13042 13043 /* Recover remaining entry parts */ 13044 if (parts_count > 1) { 13045 for (j = 1; j < parts_count; j++) { 13046 sal_memcpy(f_lt_ent+j, f_lt_ent, 13047 sizeof(_field_lt_entry_t)); 13048 (f_lt_ent+j)->flags = flags[j]; 13049 13050 rv = _bcm_field_th_lt_entry_part_tcam_idx_get(unit, 13051 f_lt_ent->group, pri_tcam_idx, 13052 j, &part_index); 13053 BCM_IF_ERROR_CLEANUP(rv); 13054 rv = _bcm_field_th_lt_tcam_idx_to_slice_offset(unit, 13055 stage_fc, f_lt_ent->group->instance, 13056 part_index, 13057 &slice_number,(int *)&f_lt_ent->index); 13058 BCM_IF_ERROR_CLEANUP(rv); 13059 13060 f_lt_ent[j].lt_fs = 13061 stage_fc->lt_slices[f_lt_ent->group->instance] 13062 + slice_number; 13063 } 13064 } 13065 13066 /* Recover tcam details */ 13067 for (j = 0; j < parts_count; j++) { 13068 rv = _bcm_field_th_lt_tcam_entry_get(unit, 13069 f_lt_ent->group, 13070 f_lt_ent+j); 13071 BCM_IF_ERROR_CLEANUP(rv); 13072 f_lt_ent[j].lt_fs->entries[ 13073 f_lt_ent[j].index] = f_lt_ent; 13074 } 13075 lt_entry_fg->lt_entry_arr[entry_pos] = f_lt_ent; 13076 entry_pos++; 13077 f_lt_ent = NULL; 13078 } 13079 break; 13080 13081 case _bcmFieldInternalEndStructEntryDetails: 13082 break; 13083 default: 13084 break; 13085 } 13086 } 13087 13088 TLV_INIT(tlv); 13089 return BCM_E_NONE; 13090 13091 cleanup: 13092 TLV_INIT(tlv); 13093 if (f_lt_ent != NULL) { 13094 sal_free(f_lt_ent); 13095 f_lt_ent = NULL; 13096 } 13097 if (f_ent != NULL) { 13098 sal_free(f_ent); 13099 f_ent = NULL; 13100 } 13101 13102 for (pipe = 0; pipe < stage_fc->num_pipes; pipe++) { 13103 if (!(fc->pipe_map & (1 << pipe))) { 13104 continue; 13105 } 13106 if (fp_policy_buf[pipe] != NULL) { 13107 soc_cm_sfree(unit, fp_policy_buf[pipe]); 13108 } 13109 if (lt_policy_buf[pipe] != NULL) { 13110 soc_cm_sfree(unit, lt_policy_buf[pipe]); 13111 } 13112 if (soc_feature(unit, soc_feature_ifp_action_profiling)) { 13113 if (fp_policy_buf_wide[pipe] != NULL) { 13114 soc_cm_sfree(unit, fp_policy_buf_wide[pipe]); 13115 } 13116 if (ifp_act_profile_buf[pipe] != NULL) { 13117 soc_cm_sfree(unit, ifp_act_profile_buf[pipe]); 13118 } 13119 13120 } 13121 } 13122 return rv; 13123 13124 } 13125 13126 13127 /* Function: 13128 * _field_group_recover 13129 * 13130 * Purpose: 13131 * recover _field_group_t structure 13132 * 13133 * Paramaters: 13134 * unit - (IN) BCM device number 13135 * fg - (IN) Pointer to device group structure 13136 * total _qual_count - (OUT) qual_count recovered 13137 * 13138 * Returns: 13139 * BCM_E_XXX 13140 */ 13141 13142 int 13143 _field_group_recover(int unit, _field_group_t *fg, int *total_qual_count) 13144 { 13145 _field_tlv_t tlv; /* Field TLV structure */ 13146 uint32 *position = NULL; /* Position in Scache */ 13147 uint8 *scache_ptr = NULL; /* Pointer to Scache */ 13148 _field_control_t *fc; /* Field control structure.*/ 13149 int mem_sz = 0; /* memeory to be allocated to entry_arr */ 13150 _field_stage_t *stage_fc = NULL; /* Field Stage structure */ 13151 soc_profile_mem_t *keygen_profile;/* Key gen program profile memory */ 13152 int part_count = 0; /* Parts for Field entry in group */ 13153 int i = 0; /* Local variable */ 13154 SHR_BITDCL udf_map[_SHR_BITDCLSIZE(BCM_FIELD_USER_NUM_UDFS)] = {0}; 13155 /* Map of UDF qualifiers */ 13156 uint32 qual_count = -1; /* Qualifier Count */ 13157 int total_qualify_count = -1; /* Qualifier Count including UDF EM */ 13158 int idx = 0; /* Loop index variable*/ 13159 bcm_field_qset_t qset_copy; /* Qset For Group */ 13160 SHR_BITDCL *group_qset = NULL; /* Group Qset */ 13161 int rv = 0; /* Return Variable */ 13162 soc_profile_mem_t *action_profile;/* action profile memory */ 13163 uint16 grp_flags16 = 0; /* 16-bit group flags */ 13164 13165 *total_qual_count = -1; 13166 stage_fc = curr_stage_fc; 13167 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 13168 tlv.value = NULL; 13169 TLV_INIT(tlv); 13170 13171 for (idx=0; idx < MAX_ACT_PROF_ENTRIES_PER_GROUP; idx++) { 13172 fg->action_profile_idx[idx] = -1; 13173 } 13174 13175 if (fc->wb_recovered_version <= BCM_FIELD_WB_VERSION_1_18) { 13176 static_type_map[_bcmFieldInternalQsetW].size = 8; 13177 static_type_map[_bcmFieldInternalQsetUdfMap].size = 8; 13178 } 13179 13180 while (tlv.type != _bcmFieldInternalEndStructGroup) { 13181 TLV_INIT(tlv); 13182 /* coverity[no_write_call : FALSE] */ 13183 BCM_IF_ERROR_CLEANUP(tlv_read(unit, &tlv, scache_ptr, position)); 13184 13185 switch (tlv.type) 13186 { 13187 case _bcmFieldInternalGroupId: 13188 fg->gid = *(bcm_field_group_t *)tlv.value; 13189 break; 13190 case _bcmFieldInternalGroupPri: 13191 fg->priority = *(int *)tlv.value; 13192 break; 13193 case _bcmFieldInternalQualifyCount: 13194 qual_count = *(uint32 *)tlv.value; 13195 *total_qual_count = qual_count; 13196 break; 13197 case _bcmFieldInternalQsetW: 13198 if (downgrade[unit] == TRUE) { 13199 _FP_XGS3_ALLOC(group_qset, 13200 (tlv.length * (recovery_type_map[unit][tlv.type].size)), 13201 "Qset for Group"); 13202 } else { 13203 if (fc->wb_recovered_version <= BCM_FIELD_WB_VERSION_1_18) { 13204 _FP_XGS3_ALLOC(group_qset, 13205 (_SHR_BITDCLSIZE(BCM_FIELD_QUALIFY_MAX) 13206 * (recovery_type_map[unit][tlv.type].size)), "Qset for Group"); 13207 } else { 13208 _FP_XGS3_ALLOC(group_qset, 13209 (_SHR_BITDCLSIZE(_bcmFieldQualifyCount) 13210 * (recovery_type_map[unit][tlv.type].size)), "Qset for Group"); 13211 } 13212 } 13213 if (group_qset == NULL) { 13214 rv = BCM_E_MEMORY; 13215 goto cleanup; 13216 } 13217 13218 if (fc->wb_recovered_version <= BCM_FIELD_WB_VERSION_1_18) { 13219 static_type_map[_bcmFieldInternalQsetW].size = 4; 13220 } 13221 13222 sal_memcpy(group_qset, tlv.value, 13223 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13224 13225 break; 13226 case _bcmFieldInternalQsetQual: 13227 if (downgrade[unit] == TRUE) { 13228 _FP_XGS3_ALLOC(group_qset, 13229 (tlv.length * (recovery_type_map[unit][tlv.type].size)), 13230 "Qset for Group"); 13231 } else { 13232 if (fc->wb_recovered_version <= BCM_FIELD_WB_VERSION_1_18) { 13233 _FP_XGS3_ALLOC(group_qset, 13234 (_SHR_BITDCLSIZE(BCM_FIELD_QUALIFY_MAX) 13235 * (recovery_type_map[unit][tlv.type].size)), "Qset for Group"); 13236 } else { 13237 _FP_XGS3_ALLOC(group_qset, 13238 (_SHR_BITDCLSIZE(_bcmFieldQualifyCount) 13239 * (recovery_type_map[unit][tlv.type].size)), "Qset for Group"); 13240 } 13241 } 13242 if (group_qset == NULL) { 13243 rv = BCM_E_MEMORY; 13244 goto cleanup; 13245 } 13246 13247 sal_memcpy(group_qset, tlv.value, 13248 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13249 13250 break; 13251 case _bcmFieldInternalQsetUdf: 13252 sal_memcpy(udf_map, tlv.value, 13253 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13254 13255 for (idx = 0; idx < ((recovery_type_map[unit][tlv.type].size) 13256 * tlv.length); idx++) { 13257 if (SHR_BITGET(udf_map, idx)) { 13258 BCM_FIELD_QSET_ADD_INTERNAL(fg->qset, 13259 bcmFieldQualifyCount + idx); 13260 } 13261 } 13262 break; 13263 case _bcmFieldInternalQsetUdfMap: 13264 if (fc->wb_recovered_version <= BCM_FIELD_WB_VERSION_1_18) { 13265 static_type_map[_bcmFieldInternalQsetUdfMap].size = 4; 13266 } 13267 13268 sal_memcpy(fg->qset.udf_map, tlv.value, 13269 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13270 break; 13271 case _bcmFieldInternalGroupFlags: 13272 grp_flags16 = *(uint16 *)tlv.value; 13273 fg->flags |= (grp_flags16 & 0xFFFFFFFF); 13274 break; 13275 case _bcmFieldInternalGroupFlagsMsb16: 13276 grp_flags16 = *(uint16 *)tlv.value; 13277 fg->flags |= (grp_flags16 << 16); 13278 break; 13279 case _bcmFieldInternalGroupPbmp: 13280 sal_memcpy(&fg->pbmp, tlv.value, 13281 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13282 break; 13283 case _bcmFieldInternalGroupSlice: 13284 fg->slices = 13285 &(stage_fc->slices[fg->instance][*(int *)tlv.value]); 13286 if (fc->wb_recovered_version <= BCM_FIELD_WB_VERSION_1_18) { 13287 fg->flags = fg->slices->group_flags; 13288 fg->flags |= _FP_GROUP_LOOKUP_ENABLED; 13289 fg->flags |= _FP_GROUP_SELECT_AUTO_EXPANSION; 13290 } 13291 break; 13292 case _bcmFieldInternalGroupQual: 13293 BCM_IF_ERROR_CLEANUP(_field_groupqual_recover(unit, 13294 &tlv, fg, 13295 (fg->qual_arr), 13296 qual_count)); 13297 break; 13298 case _bcmFieldInternalGroupPreselQual: 13299 BCM_IF_ERROR_CLEANUP(_field_groupqual_recover(unit, 13300 &tlv, fg, 13301 (fg->presel_qual_arr), 13302 qual_count)); 13303 break; 13304 case _bcmFieldInternalGroupStage: 13305 fg->stage_id = *(_field_stage_id_t *)tlv.value; 13306 break; 13307 case _bcmFieldInternalGroupEntry: 13308 break; 13309 case _bcmFieldInternalGroupBlockCount: 13310 fg->ent_block_count = *(uint16 *)tlv.value; 13311 break; 13312 case _bcmFieldInternalGroupGroupStatus: 13313 sal_memcpy(&(fg->group_status), tlv.value, 13314 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13315 break; 13316 case _bcmFieldInternalGroupGroupAset: 13317 if (downgrade[unit] == TRUE) { 13318 sal_memcpy(&(fg->aset.w), tlv.value, 13319 ((recovery_type_map[unit][tlv.type].size) * 13320 _SHR_BITDCLSIZE(bcmFieldActionCount))); 13321 } else { 13322 sal_memcpy(&(fg->aset.w), tlv.value, 13323 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13324 } 13325 break; 13326 case _bcmFieldInternalGroupCounterBmp: 13327 sal_memcpy(fg->counter_pool_bmp.w, tlv.value, 13328 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13329 break; 13330 case _bcmFieldInternalGroupInstance: 13331 fg->instance = *(int *)tlv.value; 13332 break; 13333 case _bcmFieldInternalExtractor: 13334 BCM_IF_ERROR_CLEANUP(_field_extractor_recover(unit, 13335 scache_ptr, position, &tlv, fg->ext_codes)); 13336 break; 13337 case _bcmFieldInternalGroupLtSlice: 13338 fg->lt_slices = 13339 &(stage_fc->lt_slices[fg->instance][*(int *)tlv.value]); 13340 break; 13341 case _bcmFieldInternalGroupLtConfig: 13342 fg->lt_id = *(int *)tlv.value; 13343 break; 13344 case _bcmFieldInternalGroupLtEntry: 13345 /* backlink function will handle */ 13346 break; 13347 case _bcmFieldInternalGroupLtEntrySize: 13348 fg->lt_ent_blk_cnt = *(uint16 *)tlv.value; 13349 break; 13350 case _bcmFieldInternalLtStatusEntriesFree: 13351 fg->lt_grp_status.entries_free = *(int *)tlv.value; 13352 break; 13353 case _bcmFieldInternalLtStatusEntriesTotal: 13354 fg->lt_grp_status.entries_total = *(int *)tlv.value; 13355 break; 13356 case _bcmFieldInternalLtStatusEntriesCnt: 13357 fg->lt_grp_status.entry_count = *(int *)tlv.value; 13358 break; 13359 case _bcmFieldInternalGroupQsetSize: 13360 fg->qset_size = *(int *)tlv.value; 13361 break; 13362 case _bcmFieldInternalGroupHintId: 13363 fg->hintid = *(bcm_field_hintid_t *)tlv.value; 13364 break; 13365 case _bcmFieldInternalGroupMaxSize: 13366 fg->max_group_size = *(uint32 *)tlv.value; 13367 break; 13368 case _bcmFieldInternalEMGroupMode: 13369 fg->em_mode = *(_field_em_mode_t *)tlv.value; 13370 break; 13371 case _bcmFieldInternalEMGroupAset: 13372 /*length value was not saved in this case. Hence added a new 13373 enum */ 13374 if (downgrade[unit] == TRUE) { 13375 sal_memcpy(&(fg->aset.w), tlv.value, 13376 ((recovery_type_map[unit][tlv.type].size) * 13377 _SHR_BITDCLSIZE(bcmFieldActionCount))); 13378 } else { 13379 sal_memcpy(&(fg->aset.w), tlv.value, 13380 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13381 } 13382 break; 13383 case _bcmFieldInternalEMGroupAset2: 13384 if (downgrade[unit] == TRUE) { 13385 sal_memcpy(&(fg->aset.w), tlv.value, 13386 ((recovery_type_map[unit][tlv.type].size) * 13387 _SHR_BITDCLSIZE(bcmFieldActionCount))); 13388 } else { 13389 sal_memcpy(&(fg->aset.w), tlv.value, 13390 ((recovery_type_map[unit][tlv.type].size) * tlv.length)); 13391 } 13392 break; 13393 case _bcmFieldInternalGroupActionProfIdx: 13394 sal_memcpy(fg->action_profile_idx, tlv.value, 13395 ((static_type_map[tlv.type].size) * tlv.length)); 13396 break; 13397 case _bcmFieldInternalEndStructGroup: 13398 if (*(uint32 *)tlv.value != _FIELD_WB_EM_GROUP) { 13399 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 13400 "END MARKER CHECK FAILED : GROUP\n"))); 13401 TLV_INIT(tlv); 13402 rv = BCM_E_INTERNAL; 13403 goto cleanup; 13404 } 13405 break; 13406 13407 default: 13408 break; 13409 } 13410 } 13411 13412 /* 13413 * If the group's priority is BCM_FIELD_GROUP_PRIO_ANY, 13414 * update group running priority 13415 */ 13416 if ((stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) && 13417 (fg->priority == BCM_FIELD_GROUP_PRIO_ANY)) { 13418 stage_fc->group_running_prio += 1; 13419 fg->priority = stage_fc->group_running_prio; 13420 } 13421 13422 if (fc->wb_recovered_version <= BCM_FIELD_WB_VERSION_1_18) { 13423 static_type_map[_bcmFieldInternalQsetW].size = 4; 13424 static_type_map[_bcmFieldInternalQsetUdfMap].size = 4; 13425 } 13426 13427 fg->action_res_id = -1; 13428 13429 /* Key gen program profile memory is set with correct reference count */ 13430 keygen_profile = &stage_fc->keygen_profile[fg->instance].profile; 13431 /* Action profile memory is set with correct reference count */ 13432 action_profile = &stage_fc->action_profile[fg->instance]; 13433 if (fg->flags & _FP_GROUP_SPAN_TRIPLE_SLICE) { 13434 part_count = 3; 13435 } else if ((fg->flags & _FP_GROUP_SPAN_DOUBLE_SLICE) || 13436 (fg->flags & _FP_GROUP_DW_DEPTH_EXPANDED)) { 13437 part_count = 2; 13438 } else { 13439 part_count = 1; 13440 } 13441 13442 /* Allocate memory for entries in group */ 13443 mem_sz = _FP_GROUP_ENTRY_ARR_BLOCK * (fg->ent_block_count) * 13444 sizeof(_field_entry_t *); 13445 _FP_XGS3_ALLOC(fg->entry_arr, mem_sz, "entry block for fp group"); 13446 if (fg->entry_arr == NULL) { 13447 rv = BCM_E_MEMORY; 13448 goto cleanup; 13449 } 13450 13451 /* Clear copy of qset. */ 13452 BCM_FIELD_QSET_INIT(qset_copy); 13453 13454 /* Update Qualifier Ids for qualifiers after bcmFieldqualifyCount */ 13455 13456 if (qual_count != 0) { 13457 /* Downgrade case */ 13458 if (qual_count > bcmFieldQualifyCount) { 13459 total_qualify_count = ((_bcmFieldQualifyCount) + 13460 (qual_count - bcmFieldQualifyCount)); 13461 } else { 13462 total_qualify_count = ((_bcmFieldQualifyCount) - 13463 (bcmFieldQualifyCount - qual_count)); 13464 } 13465 13466 /* Cleanup new qualifiers which are not present in downgrade */ 13467 if (downgrade[unit] == TRUE) { 13468 for (idx = bcmFieldQualifyCount; idx < qual_count; idx ++) { 13469 SHR_BITCLR(group_qset, idx); 13470 } 13471 } 13472 13473 for (idx = qual_count; idx < total_qualify_count; idx ++) { 13474 if (SHR_BITGET((group_qset), (idx))) { 13475 SHR_BITCLR(group_qset, idx); 13476 SHR_BITSET(qset_copy.w, ( (idx - qual_count) 13477 + bcmFieldQualifyCount)); 13478 } 13479 } 13480 13481 for (idx = bcmFieldQualifyCount; idx < _bcmFieldQualifyCount; 13482 idx++) { 13483 if (BCM_FIELD_QSET_TEST(qset_copy, idx)) { 13484 SHR_BITSET(group_qset, idx); 13485 } 13486 } 13487 13488 for (idx = 0; idx < _bcmFieldQualifyCount; idx++) { 13489 if (SHR_BITGET((group_qset), (idx))) { 13490 SHR_BITSET(fg->qset.w, idx); 13491 } 13492 } 13493 13494 BCM_FIELD_QSET_INIT(qset_copy); 13495 } 13496 13497 13498 if ((stage_fc->stage_id == _BCM_FIELD_STAGE_CLASS) || 13499 (stage_fc->stage_id == _BCM_FIELD_STAGE_FLOWTRACKER)) { 13500 rv = BCM_E_NONE; 13501 goto cleanup; 13502 } 13503 13504 /* For WB version prior to 23, the extractors are recovered 13505 * at the end of recovery and hence below code is not 13506 * required for WB version < 24. 13507 */ 13508 if ((fc->wb_recovered_version) >= BCM_FIELD_WB_VERSION_1_24) { 13509 for (i = 0; i < part_count; i++) { 13510 soc_profile_mem_reference(unit, keygen_profile, 13511 fg->ext_codes[i].keygen_index, 1); 13512 } 13513 } 13514 if (stage_fc->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 13515 for (i =0; i < MAX_ACT_PROF_ENTRIES_PER_GROUP; i++) { 13516 if (-1 != fg->action_profile_idx[i]) { 13517 SOC_PROFILE_MEM_REFERENCE(unit, action_profile, 13518 fg->action_profile_idx[i], 1); 13519 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, action_profile, 13520 fg->action_profile_idx[i], 1); 13521 } 13522 } 13523 } 13524 mem_sz = _FP_GROUP_ENTRY_ARR_BLOCK * (fg->lt_ent_blk_cnt + 1) 13525 * sizeof(_field_lt_entry_t *); 13526 _FP_XGS3_ALLOC(fg->lt_entry_arr, mem_sz, "entry block for fp group"); 13527 if (fg->lt_entry_arr == NULL) { 13528 rv = BCM_E_MEMORY; 13529 } 13530 13531 cleanup: 13532 TLV_INIT(tlv); 13533 if (group_qset != NULL) { 13534 sal_free(group_qset); 13535 } 13536 return rv; 13537 13538 } 13539 13540 /* Function: 13541 * _field_class_info_recover 13542 * 13543 * Purpose: 13544 * Recover function for _field_class_info_t structure 13545 * 13546 * Parameters: 13547 * unit - (IN) unit number 13548 * class_info_arr - (IN) pointer to array of pointers to structures 13549 * tlv - (IN) tlv structure holding the number of types and count of array 13550 * Returns: 13551 * BCM_E_XXX 13552 */ 13553 int 13554 _field_class_info_recover(int unit, _field_class_info_t **class_info_arr, 13555 _field_tlv_t *tlv) 13556 { 13557 int type_pos = 0; /* position of type */ 13558 int i = 0; /* local variable for loops */ 13559 int num_instances = 0; /* number of instances */ 13560 int num_types = 0; /* Number of types */ 13561 _field_tlv_t tlv2; /* TLV structure */ 13562 uint32 *type; /* Elem type */ 13563 uint8 *scache_ptr; /* Scache pointer */ 13564 uint32 *position; /* Scache position */ 13565 _field_control_t *fc; /* Field control structure. */ 13566 _field_class_type_t ctype; /* Ctype supported */ 13567 13568 WB_FIELD_CONTROL_GET(fc, scache_ptr, position); 13569 tlv2.value = NULL; 13570 TLV_INIT(tlv2); 13571 type = (uint32 *)tlv->value; 13572 num_instances = (tlv->length) & _FP_WB_TLV_LENGTH_MASK; 13573 num_types = ((tlv->length & _FP_WB_TLV_TYPES_MASK) >> 13574 _FP_WB_TLV_TYPE_SHIFT); 13575 13576 if (class_info_arr == NULL) { 13577 return BCM_E_INTERNAL; 13578 } 13579 13580 ctype = 0; 13581 i = 0; 13582 while(i < num_instances) { 13583 if (_bcm_field_th_class_ctype_supported(unit, ctype) == BCM_E_NONE) { 13584 type_pos = 0; 13585 while ((tlv2.type != _bcmFieldInternalEndStructClass) 13586 && (type_pos != num_types)) { 13587 TLV_INIT(tlv2); 13588 tlv2.type = (type[type_pos] & _FP_WB_TLV_ELEM_TYPE_MASK); 13589 tlv2.basic_type = ((type[type_pos] & _FP_WB_TLV_BASIC_TYPE_MASK) >> 13590 _FP_WB_TLV_BASIC_TYPE_SHIFT); 13591 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv2, scache_ptr, position)); 13592 13593 switch(tlv2.type) { 13594 case _bcmFieldInternalClassFlags: 13595 class_info_arr[ctype]->flags = *(uint32 *)tlv2.value; 13596 break; 13597 case _bcmFieldInternalClassEntUsed: 13598 class_info_arr[ctype]->total_entries_used 13599 = *(uint32 *)tlv2.value; 13600 break; 13601 case _bcmFieldInternalClassBmp: 13602 sal_memcpy(class_info_arr[ctype]->class_bmp.w, 13603 tlv2.value, tlv2.length); 13604 /* 13605 * Prior to 1_26 version class_bmp sync was not proper. 13606 * it will be reconstructed during entry recovery for 13607 * WB versions prior to 1_26. 13608 */ 13609 if ((fc->wb_recovered_version) < BCM_FIELD_WB_VERSION_1_26) { 13610 int max_entries = 0,size = 0; 13611 BCM_IF_ERROR_RETURN(_field_th_class_max_entries(unit, 0, 13612 ctype, &max_entries)); 13613 size = SHR_BITALLOCSIZE(max_entries << 1); 13614 sal_memset(class_info_arr[ctype]->class_bmp.w, 13615 0, sizeof(size)); 13616 } 13617 break; 13618 case _bcmFieldInternalEndStructClass: 13619 break; 13620 default: 13621 break; 13622 } 13623 type_pos++; 13624 } 13625 TLV_INIT(tlv2); 13626 i++; 13627 } 13628 ctype++; 13629 } 13630 return BCM_E_NONE; 13631 } 13632 13633 int 13634 _field_class_recover(int unit, _field_control_t *fc, 13635 _field_stage_t *stage_fc) 13636 { 13637 _field_tlv_t tlv; /* Field TLV structure */ 13638 uint8 *ptr = NULL; /* pointer to scache_ptr in fc */ 13639 uint32 *pos = NULL; /* pointer to position in fc */ 13640 int rv = 0; 13641 int pipe = 0; 13642 13643 tlv.value = NULL; 13644 TLV_INIT(tlv); 13645 if ((fc == NULL) || (stage_fc == NULL)) { 13646 return BCM_E_PARAM; 13647 } 13648 13649 13650 WB_FIELD_CONTROL_GET(fc, ptr, pos); 13651 for (pipe = 0; pipe < stage_fc->num_instances; pipe++) { 13652 if (!(fc->pipe_map & (1 << pipe))) { 13653 continue; 13654 } 13655 TLV_INIT(tlv); 13656 /* coverity[no_write_call : FALSE] */ 13657 BCM_IF_ERROR_CLEANUP(tlv_read(unit, &tlv, ptr, pos)); 13658 13659 switch (tlv.type) { 13660 case _bcmFieldInternalStageClass: 13661 BCM_IF_ERROR_CLEANUP( 13662 _field_class_info_recover(unit, 13663 stage_fc->class_info_arr[pipe], &tlv)); 13664 break; 13665 default: 13666 break; 13667 } 13668 } 13669 13670 cleanup: 13671 TLV_INIT(tlv); 13672 return rv; 13673 13674 } 13675 13676 int 13677 _bcm_field_th_stage_class_reinit(int unit, _field_control_t *fc, 13678 _field_stage_t *stage_fc) 13679 { 13680 _field_tlv_t tlv; /* Field TLV structure */ 13681 _field_entry_t *f_ent = NULL; /* pointer to entry structure */ 13682 uint8 *ptr = NULL; /* pointer to scache_ptr in fc */ 13683 uint32 *pos = NULL; /* pointer to position in fc */ 13684 /* Used to build a linked list of groups in stage */ 13685 _field_group_t *curr_fg = NULL, *prev_fg = NULL; 13686 /* pointer to array of group pointers */ 13687 _field_group_t *new_fg = NULL, *fg = NULL; 13688 int group_count = 0, rv = 0; /* Number of groups, return value */ 13689 int idx = 0, entry_count; /* loop variable, no. of entries in group */ 13690 int pipe = 0; /* loop var,perpipe mode or global */ 13691 int group_id = 0; /* group id in this stage */ 13692 _field_class_type_t ctype; 13693 _field_class_info_t **class_status_arr = NULL; 13694 /* Field Per Pipe Class Status Array */ 13695 _field_class_info_t *class_status_info = NULL; 13696 /* Field Per Compression table status */ 13697 int tcamsz = 0; 13698 int total_qual_count = -1; 13699 _field_wb_entry_t wb_entry; /* Set of WB entry info */ 13700 int ent_pos; /* No of entries in ent_arr */ 13701 13702 tlv.value = NULL; 13703 TLV_INIT(tlv); 13704 if ((fc == NULL) || (stage_fc == NULL)) { 13705 return BCM_E_PARAM; 13706 } 13707 13708 wb_entry.action_count = -1; 13709 wb_entry.action_param_type = -1; 13710 wb_entry.hw_idx_array = NULL; 13711 wb_entry.val_array = NULL; 13712 wb_entry.val_array0 = NULL; 13713 13714 WB_FIELD_CONTROL_GET_WITH_LOCK(fc, ptr, pos); 13715 BCM_IF_ERROR_CLEANUP(_field_scache_stage_hdr_chk(fc, 13716 _FIELD_CLASS_DATA_START)); 13717 while (tlv.type != _bcmFieldInternalEndStageClass) { 13718 TLV_INIT(tlv); 13719 /* coverity[no_write_call : FALSE] */ 13720 BCM_IF_ERROR_CLEANUP(tlv_read(unit, &tlv, ptr, pos)); 13721 13722 switch (tlv.type) { 13723 13724 case _bcmFieldInternalClassOperMode: 13725 if (*(bcm_field_group_oper_mode_t *)tlv.value) { 13726 BCM_IF_ERROR_CLEANUP(_bcm_field_wb_group_oper_mode_set(unit, 13727 bcmFieldQualifyStageClass, 13728 &stage_fc, 13729 bcmFieldGroupOperModePipeLocal)); 13730 stage_fc = fc->stages; 13731 while (stage_fc->stage_id != _BCM_FIELD_STAGE_CLASS) { 13732 stage_fc = stage_fc->next; 13733 } 13734 } 13735 curr_stage_fc = stage_fc; 13736 break; 13737 case _bcmFieldInternalStageClass: 13738 BCM_IF_ERROR_CLEANUP( 13739 _field_class_info_recover(unit, 13740 stage_fc->class_info_arr[pipe], &tlv)); 13741 pipe++; 13742 break; 13743 case _bcmFieldInternalGroupCount: 13744 group_count = *(int *)tlv.value; 13745 for (group_id =0 ;group_id < group_count; group_id ++) { 13746 curr_fg = NULL; 13747 _FP_XGS3_ALLOC(curr_fg, sizeof(_field_group_t), 13748 "current field grp"); 13749 if (curr_fg == NULL) { 13750 rv = BCM_E_MEMORY; 13751 goto cleanup; 13752 } 13753 rv = _field_group_recover(unit, curr_fg, &total_qual_count); 13754 BCM_IF_ERROR_CLEANUP(rv); 13755 13756 if (fc->groups == NULL) { 13757 prev_fg = curr_fg; 13758 fc->groups = curr_fg; 13759 new_fg = fc->groups; 13760 continue; 13761 } 13762 13763 if (prev_fg == NULL) { 13764 prev_fg = fc->groups; 13765 while (prev_fg->next != NULL) { 13766 prev_fg = prev_fg->next; 13767 } 13768 prev_fg->next = curr_fg; 13769 new_fg = prev_fg->next; 13770 prev_fg = prev_fg->next; 13771 } else { 13772 prev_fg->next = curr_fg; 13773 prev_fg = curr_fg; 13774 } 13775 } 13776 curr_fg = NULL; 13777 break; 13778 case _bcmFieldInternalGroupEntry: 13779 entry_count = *(int *)tlv.value; 13780 ent_pos = 0; 13781 for (idx = 0; idx < entry_count; idx++) { 13782 _FP_XGS3_ALLOC(f_ent, sizeof(_field_entry_t), "field entry"); 13783 /* coverity[forward_null : FALSE] */ 13784 /* coverity[var_deref_model] */ 13785 if (f_ent == NULL) { 13786 rv = BCM_E_MEMORY; 13787 goto cleanup; 13788 } 13789 sal_memset(wb_entry.flags, 0, sizeof(wb_entry.flags)); 13790 13791 _field_entry_info_recover(unit, f_ent, 13792 1, &new_fg, 13793 &wb_entry); 13794 /* Actions recover for entry */ 13795 if (f_ent->flags & _FP_ENTRY_INSTALLED) { 13796 rv = _field_actions_recover(unit, NULL, 13797 f_ent, &wb_entry); 13798 } else { 13799 rv = _bcm_field_th_class_type_qset_get(unit, 13800 &f_ent->group->qset, &ctype); 13801 BCM_IF_ERROR_CLEANUP(rv); 13802 rv = _bcm_field_th_class_size_get(unit, ctype, &tcamsz); 13803 _FP_XGS3_ALLOC(f_ent->tcam.key, 13804 tcamsz, "field class data buf"); 13805 if (f_ent->tcam.key == NULL) { 13806 rv = BCM_E_MEMORY; 13807 goto cleanup; 13808 } 13809 f_ent->tcam.key_size = tcamsz; 13810 13811 } 13812 BCM_IF_ERROR_CLEANUP(rv); 13813 13814 /* 13815 * Prior to 1_26 class_bmp sync was not proper. 13816 * Reconstruct class_bmp for releases prior to 13817 * Wb versions 1_26. 13818 */ 13819 if ((fc->wb_recovered_version) < BCM_FIELD_WB_VERSION_1_26) { 13820 /* Update Class Status Info Structure */ 13821 rv = _bcm_field_th_class_type_qset_get(unit, 13822 &f_ent->group->qset, &ctype); 13823 class_status_arr = stage_fc->class_info_arr[new_fg->instance]; 13824 if (class_status_arr == NULL) { 13825 rv = (BCM_E_INTERNAL); 13826 goto cleanup; 13827 } 13828 class_status_info = class_status_arr[ctype]; 13829 if (class_status_info == NULL) { 13830 rv = (BCM_E_INTERNAL); 13831 goto cleanup; 13832 } 13833 _FP_CLASS_TABLE_BMP_ADD(class_status_info->class_bmp, f_ent->slice_idx); 13834 } 13835 13836 fg = new_fg; 13837 fg->entry_arr[ent_pos] = f_ent; 13838 ent_pos++; 13839 f_ent = NULL; 13840 } 13841 break; 13842 case _bcmFieldInternalStageClassInfo: 13843 BCM_IF_ERROR_CLEANUP( 13844 _field_class_recover(unit, fc, 13845 stage_fc)); 13846 pipe++; 13847 break; 13848 case _bcmFieldInternalEndStageClass: 13849 if (*(uint32 *)tlv.value != _FIELD_WB_EM_CLASS) { 13850 rv = BCM_E_INTERNAL; 13851 goto cleanup; 13852 } 13853 break; 13854 13855 default: 13856 break; 13857 } 13858 } 13859 13860 BCM_IF_ERROR_CLEANUP(_field_scache_stage_hdr_chk(fc, _FIELD_CLASS_DATA_END)); 13861 cleanup: 13862 TLV_INIT(tlv); 13863 13864 if (curr_fg != NULL) { 13865 sal_free(curr_fg); 13866 curr_fg = NULL; 13867 } 13868 13869 if (f_ent != NULL) { 13870 sal_free(f_ent); 13871 f_ent = NULL; 13872 } 13873 FP_UNLOCK(unit); 13874 return rv; 13875 } 13876 /* 13877 * Function: 13878 * _field_qos_actions_recover 13879 * Purpose: 13880 * Recover actions that belong to IFP_PROFILE_SET1 and SET2. 13881 * 13882 * Parameters: 13883 * unit - (IN) StrataSwitch unit #. 13884 * f_ent - (IN) pointer to entry structure which refers 13885 * this action profile. 13886 * ebuf - (IN) qos profile table entry 13887 * Returns: 13888 * BCM_E_XXX 13889 */ 13890 int 13891 _field_qos_actions_recover(int unit, _field_entry_t *f_ent, uint32 *ebuf) 13892 { 13893 _bcm_field_action_offset_t a_offset; 13894 _field_action_t *f_act = NULL; 13895 bcm_field_action_t action_id; 13896 int param[6] = {0}; 13897 int hw_index = 0, i = 0, valid = 0; 13898 int supported = 0; 13899 13900 for (action_id = 0; action_id < bcmFieldActionCount; action_id++) { 13901 valid = 0; 13902 _bcm_field_th_action_support_check(unit, f_ent, action_id, &supported); 13903 if (!supported) { 13904 continue; 13905 } 13906 ACTION_GET(unit, f_ent, ebuf, action_id, 0, &a_offset); 13907 switch (action_id) { 13908 13909 case bcmFieldActionGpPrioIntCopy: 13910 case bcmFieldActionYpPrioIntCopy: 13911 case bcmFieldActionRpPrioIntCopy: 13912 if (a_offset.value[0] == 4) { 13913 valid = 1; 13914 } 13915 break; 13916 /* case bcmFieldActionPrioIntCopy: 13917 case bcmFieldActionPrioIntTos: */ 13918 case bcmFieldActionGpPrioIntTos: 13919 case bcmFieldActionYpPrioIntTos: 13920 case bcmFieldActionRpPrioIntTos: 13921 if (a_offset.value[0] == 6) { 13922 valid = 1; 13923 } 13924 break; 13925 /* case bcmFieldActionPrioIntCancel: */ 13926 case bcmFieldActionGpPrioIntCancel: 13927 case bcmFieldActionYpPrioIntCancel: 13928 case bcmFieldActionRpPrioIntCancel: 13929 if (a_offset.value[0] == 7) { 13930 valid = 1; 13931 } 13932 break; 13933 case bcmFieldActionGpPrioIntNew: 13934 case bcmFieldActionYpPrioIntNew: 13935 case bcmFieldActionRpPrioIntNew: 13936 if (a_offset.value[1] == 5) { 13937 valid = 1; 13938 param[0] = a_offset.value[0]; 13939 } 13940 break; 13941 case bcmFieldActionGpDropPrecedence: 13942 case bcmFieldActionYpDropPrecedence: 13943 case bcmFieldActionRpDropPrecedence: 13944 if (a_offset.value[0] != 0) { 13945 valid = 1; 13946 param[0] = a_offset.value[0]; 13947 } 13948 break; 13949 case bcmFieldActionGpEcnNew: 13950 case bcmFieldActionYpEcnNew: 13951 case bcmFieldActionRpEcnNew: 13952 if (a_offset.value[1] == 1) { 13953 valid = 1; 13954 param[0] = a_offset.value[0]; 13955 } 13956 break; 13957 case bcmFieldActionGpPrioPktNew: 13958 case bcmFieldActionYpPrioPktNew: 13959 case bcmFieldActionRpPrioPktNew: 13960 if (a_offset.value[1] == 5) { 13961 valid = 1; 13962 param[0] = a_offset.value[0]; 13963 } 13964 break; 13965 case bcmFieldActionRpDscpNew: 13966 case bcmFieldActionYpDscpNew: 13967 case bcmFieldActionGpTosPrecedenceNew: 13968 if (a_offset.value[1] == 1) { 13969 valid = 1; 13970 param[0] = a_offset.value[0]; 13971 } 13972 break; 13973 case bcmFieldActionGpDscpNew: 13974 if (a_offset.value[1] == 3) { 13975 valid = 1; 13976 param[0] = a_offset.value[0]; 13977 } 13978 break; 13979 case bcmFieldActionGpPrioPktCopy: 13980 case bcmFieldActionYpPrioPktCopy: 13981 case bcmFieldActionRpPrioPktCopy: 13982 if (a_offset.value[0] == 4) { 13983 valid = 1; 13984 } 13985 break; 13986 case bcmFieldActionGpPrioPktTos: 13987 case bcmFieldActionYpPrioPktTos: 13988 case bcmFieldActionRpPrioPktTos: 13989 if (a_offset.value[0] == 6) { 13990 valid = 1; 13991 } 13992 break; 13993 case bcmFieldActionGpPrioPktCancel: 13994 case bcmFieldActionYpPrioPktCancel: 13995 case bcmFieldActionRpPrioPktCancel: 13996 if (a_offset.value[0] == 7) { 13997 valid = 1; 13998 } 13999 break; 14000 case bcmFieldActionGpDscpCancel: 14001 case bcmFieldActionYpDscpCancel: 14002 case bcmFieldActionRpDscpCancel: 14003 if (a_offset.value[0] == 4) { 14004 valid = 1; 14005 } 14006 break; 14007 case bcmFieldActionGpTosPrecedenceCopy: 14008 if (a_offset.value[0] == 2) { 14009 valid = 1; 14010 } 14011 break; 14012 case bcmFieldActionGpDot1pPreserve: 14013 case bcmFieldActionYpDot1pPreserve: 14014 case bcmFieldActionRpDot1pPreserve: 14015 if (a_offset.value[0] == 3) { 14016 valid = 1; 14017 } 14018 break; 14019 case bcmFieldActionGpDscpPreserve: 14020 if (a_offset.value[0] == 5) { 14021 valid = 1; 14022 } 14023 break; 14024 case bcmFieldActionYpDscpPreserve: 14025 case bcmFieldActionRpDscpPreserve: 14026 if (a_offset.value[0] == 3) { 14027 valid = 1; 14028 } 14029 break; 14030 case bcmFieldActionGpIntCongestionNotificationNew: 14031 case bcmFieldActionYpIntCongestionNotificationNew: 14032 case bcmFieldActionRpIntCongestionNotificationNew: 14033 if (a_offset.value[1] == 1) { 14034 valid = 1; 14035 } 14036 break; 14037 case bcmFieldActionPfcClassNew: 14038 if (a_offset.value[1] == 1) { 14039 valid = 1; 14040 } 14041 break; 14042 case bcmFieldActionGpCosMapNew: 14043 case bcmFieldActionYpCosMapNew: 14044 case bcmFieldActionRpCosMapNew: 14045 if (a_offset.value[1] == 2) { 14046 valid = 1; 14047 } 14048 break; 14049 case bcmFieldActionGpCosQNew: 14050 case bcmFieldActionYpCosQNew: 14051 case bcmFieldActionRpCosQNew: 14052 if (a_offset.value[1] == 1) { 14053 valid = 1; 14054 param[0] = a_offset.value[0]; 14055 } 14056 break; 14057 case bcmFieldActionGpUcastCosQNew: 14058 case bcmFieldActionYpUcastCosQNew: 14059 case bcmFieldActionRpUcastCosQNew: 14060 if (a_offset.value[1] == 8) { 14061 valid = 1; 14062 param[0] = a_offset.value[0]; 14063 } 14064 break; 14065 case bcmFieldActionGpMcastCosQNew: 14066 case bcmFieldActionYpMcastCosQNew: 14067 case bcmFieldActionRpMcastCosQNew: 14068 if (a_offset.value[1] == 9) { 14069 valid = 1; 14070 param[0] = a_offset.value[0]; 14071 } 14072 break; 14073 case bcmFieldActionUntaggedPacketPriorityNew: 14074 if (a_offset.value[1] == 1) { 14075 valid = 1; 14076 param[0] = a_offset.value[0]; 14077 } 14078 break; 14079 default: 14080 break; 14081 14082 } 14083 if (valid) { 14084 f_act = NULL; 14085 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP em actions qos"); 14086 if (f_act == NULL) { 14087 return BCM_E_MEMORY; 14088 } 14089 f_act->action = action_id; 14090 for (i=0; i < 6; i++) { 14091 f_act->param[i] = param[i]; 14092 } 14093 f_act->hw_index = hw_index; 14094 f_act->old_index = -1; 14095 f_act->flags = _FP_ACTION_VALID; 14096 f_act->next = f_ent->actions; 14097 f_ent->actions = f_act; 14098 } 14099 } 14100 return BCM_E_NONE; 14101 } 14102 static char *qos_profile_buf[BCM_MAX_NUM_UNITS][_FP_MAX_NUM_PIPES] = {{0}}; 14103 int 14104 _field_wb_qos_buffer_free(int unit) { 14105 _field_stage_t *stage_fc = NULL; 14106 int pipe = 0, num_pipes = 0; 14107 _field_control_t *fc; /* Field control structure. */ 14108 14109 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 14110 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 14111 14112 /* Get field control structure. */ 14113 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 14114 14115 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 14116 num_pipes = 1; 14117 } else { 14118 num_pipes = stage_fc->num_pipes; 14119 } 14120 for (pipe = 0; pipe < num_pipes; pipe++) { 14121 if (!(fc->pipe_map & (1 << pipe))) { 14122 continue; 14123 } 14124 if (qos_profile_buf[unit][pipe]) { 14125 soc_cm_sfree(unit, qos_profile_buf[unit][pipe]); 14126 qos_profile_buf[unit][pipe] = NULL; 14127 } 14128 } 14129 return BCM_E_NONE; 14130 } 14131 /* 14132 * Function: 14133 * _field_wb_qos_actions_recover 14134 * Purpose: 14135 * Recover all QOS Related actions for a particular entry. 14136 * This profile may be pointed to, by many entries. so, we 14137 * DMA the entire table and store the pointers in statically 14138 * declared buffer. Corresponding free function is called 14139 * at the end of em reinit. 14140 * 14141 * Parameters: 14142 * unit - (IN) StrataSwitch unit #. 14143 * f_ent - (IN) pointer to entry structure which refers 14144 * this qos profile. 14145 * qos_idx - (IN) qos index (obtained from QOS_PROFILE_IDf from 14146 * exact match tables) 14147 * Returns: 14148 * BCM_E_XXX 14149 */ 14150 int 14151 _field_wb_qos_actions_recover(int unit, _field_entry_t *f_ent, int qos_idx) 14152 { 14153 static soc_mem_t mem = INVALIDm; 14154 int pipe = 0; 14155 _field_stage_t *stage_fc = NULL; 14156 uint32 *e_buf = NULL; 14157 int index_min = 0, index_max = 0; 14158 int rv = 0; 14159 soc_profile_mem_t *qos_act_prof = NULL; 14160 int inst = -1; 14161 _field_control_t *fc; /* Field control structure. */ 14162 14163 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 14164 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 14165 inst = f_ent->group->instance; 14166 qos_act_prof = &stage_fc->qos_action_profile[inst]; 14167 14168 /* Get field control structure. */ 14169 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 14170 14171 if (qos_profile_buf[unit][0] == NULL) { 14172 14173 for (pipe = 0; pipe < stage_fc->num_pipes; pipe++) { 14174 if (!(fc->pipe_map & (1 << pipe))) { 14175 continue; 14176 } 14177 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 14178 mem = EXACT_MATCH_QOS_ACTIONS_PROFILEm; 14179 } else { 14180 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 14181 EXACT_MATCH_QOS_ACTIONS_PROFILEm, 14182 pipe, &mem)); 14183 } 14184 qos_profile_buf[unit][pipe] = soc_cm_salloc(unit, 14185 SOC_MEM_TABLE_BYTES(unit, mem), 14186 "QOS Profile table buffer"); 14187 14188 index_min = soc_mem_index_min(unit, mem); 14189 index_max = soc_mem_index_max(unit, mem); 14190 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 14191 index_min, index_max, qos_profile_buf[unit][pipe]); 14192 BCM_IF_ERROR_RETURN(rv); 14193 14194 } 14195 } 14196 pipe = f_ent->group->instance; 14197 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 14198 mem = EXACT_MATCH_QOS_ACTIONS_PROFILEm; 14199 } else { 14200 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 14201 EXACT_MATCH_QOS_ACTIONS_PROFILEm, 14202 pipe, &mem)); 14203 } 14204 14205 e_buf = soc_mem_table_idx_to_pointer(unit, mem, 14206 uint32 *, qos_profile_buf[unit][pipe], qos_idx); 14207 _field_qos_actions_recover(unit, f_ent, e_buf); 14208 SOC_PROFILE_MEM_REFERENCE(unit, qos_act_prof, qos_idx, 1); 14209 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, qos_act_prof, qos_idx, 1); 14210 14211 return BCM_E_NONE; 14212 } 14213 14214 static char *act_profile_buf[_FP_MAX_NUM_PIPES] = {0}; 14215 int 14216 _field_wb_em_act_buffer_free(int unit) { 14217 _field_stage_t *stage_fc = NULL; 14218 int pipe = 0, num_pipes = 0; 14219 _field_control_t *fc; /* Field control structure. */ 14220 14221 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 14222 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 14223 14224 /* Get field control structure. */ 14225 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 14226 14227 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 14228 num_pipes = 1; 14229 } else { 14230 num_pipes = stage_fc->num_pipes; 14231 } 14232 for (pipe = 0; pipe < num_pipes; pipe++) { 14233 14234 if (!(fc->pipe_map & (1 << pipe))) { 14235 continue; 14236 } 14237 if (act_profile_buf[pipe]) { 14238 soc_cm_sfree(unit, act_profile_buf[pipe]); 14239 act_profile_buf[pipe] = NULL; 14240 } 14241 } 14242 return BCM_E_NONE; 14243 } 14244 #define ACTION_DATA_SHIFT(act_data, shift) \ 14245 umask = ((1 << shift) - 1); \ 14246 act_data[0] = (act_data[0] >> shift); \ 14247 act_data[0] |= ((act_data[1] & umask) << (32-shift)); \ 14248 act_data[1] = (act_data[1] >> shift); \ 14249 /* 14250 * Function: 14251 * _field_wb_change_cpu_cos_set_recover 14252 * Purpose: 14253 * Recover actions that belong to cpu cos set 14254 * 14255 * Parameters: 14256 * unit - (IN) StrataSwitch unit #. 14257 * f_ent - (IN) pointer to entry structure which refers 14258 * this action profile. 14259 * act_data - (IN) action data in the entry obtained from 14260 * exact match tables 14261 * Returns: 14262 * BCM_E_XXX 14263 */ 14264 int 14265 _field_wb_change_cpu_cos_set_recover(int unit, _field_entry_t *f_ent, 14266 uint32 *ebuf, _field_action_bmp_t *act_bmp) 14267 { 14268 _bcm_field_action_offset_t a_offset; 14269 _field_action_t *f_act = NULL, *prev_act = NULL; 14270 bcm_field_action_t action_idx; 14271 int param[6] = {0}; 14272 int hw_index = 0, i = 0, valid = 0; 14273 int rv = BCM_E_NONE; 14274 bcm_field_action_t action_arr[] = { 14275 bcmFieldActionCosQCpuNew, 14276 bcmFieldActionServicePoolIdNew, 14277 bcmFieldActionServicePoolIdPrecedenceNew 14278 }; 14279 14280 14281 if (f_ent->actions != NULL) { 14282 prev_act = f_ent->actions; 14283 while (prev_act->next != NULL) { 14284 prev_act = prev_act->next; 14285 } 14286 } 14287 14288 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 14289 valid = 0; 14290 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 14291 /* If action is not supported on this device, go for next action */ 14292 if (BCM_E_UNAVAIL == rv) { 14293 continue; 14294 } 14295 BCM_IF_ERROR_RETURN(rv); 14296 14297 switch (action_arr[action_idx]) { 14298 case bcmFieldActionCosQCpuNew: 14299 if (a_offset.value[1] == 1) { 14300 valid = 1; 14301 param[0] = a_offset.value[0]; 14302 } 14303 break; 14304 case bcmFieldActionServicePoolIdNew: 14305 if ((a_offset.value[1] == 2) && (a_offset.value[2] == 2)){ 14306 valid = 1; 14307 param[0] = a_offset.value[0]; 14308 } 14309 break; 14310 case bcmFieldActionServicePoolIdPrecedenceNew: 14311 if ((a_offset.value[2] == 3) && (a_offset.value[3] == 2)){ 14312 valid = 1; 14313 param[0] = a_offset.value[0]; 14314 /* SPAP is 2b'00 for BCM_FIELD_COLOR_GREEN 14315 2b'01 for BCM_FIELD_COLOR_RED 14316 2b'11 for BCM_FIELD_COLOR_YELLOW 14317 */ 14318 param[1] = ((0 == a_offset.value[1]) ? BCM_FIELD_COLOR_GREEN : \ 14319 ((3 == a_offset.value[1])? BCM_FIELD_COLOR_YELLOW : BCM_FIELD_COLOR_RED)); 14320 } 14321 break; 14322 default: 14323 break; 14324 14325 } 14326 if (valid) { 14327 f_act = NULL; 14328 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP em actions qos"); 14329 if (f_act == NULL) { 14330 return BCM_E_MEMORY; 14331 } 14332 f_act->action = action_arr[action_idx]; 14333 for (i=0; i < 6; i++) { 14334 f_act->param[i] = param[i]; 14335 } 14336 f_act->hw_index = hw_index; 14337 f_act->old_index = -1; 14338 f_act->flags = _FP_ACTION_VALID; 14339 if (prev_act == NULL) { 14340 prev_act = f_act; 14341 f_ent->actions = prev_act; 14342 } else { 14343 prev_act->next = f_act; 14344 prev_act = prev_act->next; 14345 } 14346 } 14347 } 14348 return BCM_E_NONE; 14349 14350 } 14351 14352 _bcm_field_mirror_actions_recover_t *em_mirror_actions = NULL; 14353 14354 int 14355 _field_mirror_actions_recover_callback(int unit,_bcm_mirror_config_p _bcm_mirror_config) 14356 { 14357 int idx = 0; 14358 _bcm_field_mirror_actions_recover_t *mirror_cb = NULL; 14359 _bcm_mirror_dest_config_p mdest;/* Mirror destination description. */ 14360 _field_action_t *f_act = NULL; 14361 14362 if (NULL == em_mirror_actions) { 14363 return BCM_E_NONE; 14364 } 14365 mirror_cb = em_mirror_actions; 14366 while (NULL != mirror_cb) { 14367 for (idx = 0; idx < _bcm_mirror_config->dest_count; idx++) { 14368 mdest = _bcm_mirror_config->dest_arr + idx; 14369 /* Skip unused entries. */ 14370 if (0 == mdest->ref_count) { 14371 continue; 14372 } 14373 14374 if (mdest->mirror_dest.gport == mirror_cb->mtp_gport) { 14375 /* Matching mirror destination found. */ 14376 for (f_act = mirror_cb->f_ent->actions; NULL!= f_act; f_act = f_act->next) { 14377 if ((mirror_cb->action == f_act->action) && 14378 (f_act->param[1] == mirror_cb->mtp_gport)) { 14379 f_act->param[1]= mdest->mirror_dest.mirror_dest_id; 14380 break; 14381 } 14382 } 14383 } 14384 } 14385 em_mirror_actions = mirror_cb->next; 14386 sal_free(mirror_cb); 14387 mirror_cb = em_mirror_actions; 14388 } 14389 14390 return BCM_E_NONE; 14391 } 14392 14393 /* 14394 * Function: 14395 * _field_wb_mirror_set_recover 14396 * Purpose: 14397 * Recover actions that belong to mirror set 14398 * For any entry, 4 Mirror actions can be attached, 14399 * Ingress and egress together. Mirror_select register 14400 * indicates whether the actions or ingress or egress 14401 * corresponding bit -> 0 - ingress 1 - egress 14402 * 14403 * Parameters: 14404 * unit - (IN) StrataSwitch unit #. 14405 * f_ent - (IN) pointer to entry structure which refers 14406 * this action profile. 14407 * act_data - (IN) action data in the entry obtained from 14408 * exact match tables 14409 * Returns: 14410 * BCM_E_XXX 14411 */ 14412 int 14413 _field_wb_mirror_set_recover(int unit, _field_entry_t *f_ent, 14414 uint32 *ebuf, _field_action_bmp_t *act_bmp) 14415 { 14416 _bcm_field_action_offset_t a_offset; 14417 _bcm_field_mirror_actions_recover_t *mirror_recover = NULL; 14418 _field_action_t *f_act = NULL, *prev_act = NULL; 14419 bcm_field_action_t action_idx = 0; 14420 int param[6] = {0}; 14421 int hw_index = 0, i = 0, valid = 0; 14422 uint32 reg_value = 0; 14423 int rv = BCM_E_NONE; 14424 bcm_field_action_t action_arr[] = { 14425 bcmFieldActionMirrorIngress, 14426 bcmFieldActionMirrorIngress, 14427 bcmFieldActionMirrorIngress, 14428 bcmFieldActionMirrorIngress, 14429 bcmFieldActionMirrorEgress, 14430 bcmFieldActionMirrorEgress, 14431 bcmFieldActionMirrorEgress, 14432 bcmFieldActionMirrorEgress 14433 }; 14434 14435 14436 BCM_IF_ERROR_RETURN(READ_MIRROR_SELECTr(unit, ®_value)); 14437 if (f_ent->actions != NULL) { 14438 prev_act = f_ent->actions; 14439 while (prev_act->next != NULL) { 14440 prev_act = prev_act->next; 14441 } 14442 } 14443 14444 ACTION_GET(unit, f_ent, ebuf, action_arr[0], 0, &a_offset); 14445 14446 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 14447 valid = 0; 14448 if (act_bmp != NULL) { 14449 if (act_bmp->w == NULL) { 14450 continue; 14451 } else { 14452 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 14453 continue; 14454 } 14455 } 14456 } 14457 if (action_idx == 4) { 14458 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 14459 /* If action is not supported on this device, go for next action */ 14460 if (BCM_E_UNAVAIL == rv) { 14461 continue; 14462 } 14463 BCM_IF_ERROR_RETURN(rv); 14464 } 14465 switch (action_arr[action_idx]) { 14466 case bcmFieldActionMirrorIngress: 14467 if ((a_offset.value[0] & 0x1) && !(reg_value & 0x1)) { 14468 hw_index = a_offset.value[1] & 0x3; 14469 _bcm_esw_mirror_mtp_to_modport(unit, hw_index, TRUE, 14470 BCM_MIRROR_PORT_INGRESS, ¶m[0], ¶m[1]); 14471 a_offset.value[0] &= 0xfffffffe; 14472 valid = 1; 14473 break; 14474 14475 } 14476 if ((a_offset.value[0] & 0x2) && !(reg_value & 0x2)) { 14477 hw_index = (a_offset.value[1] & 0xc) >> 2; 14478 _bcm_esw_mirror_mtp_to_modport(unit, hw_index, TRUE, 14479 BCM_MIRROR_PORT_INGRESS, ¶m[0], ¶m[1]); 14480 a_offset.value[0] &= 0xfffffffc; 14481 valid = 1; 14482 break; 14483 } 14484 if ((a_offset.value[0] & 0x4) && !(reg_value & 0x4)) { 14485 hw_index = (a_offset.value[1] & 0x30) >> 4; 14486 _bcm_esw_mirror_mtp_to_modport(unit, hw_index, TRUE, 14487 BCM_MIRROR_PORT_INGRESS, ¶m[0], ¶m[1]); 14488 a_offset.value[0] &= 0xfffffff8; 14489 valid = 1; 14490 break; 14491 } 14492 if ((a_offset.value[0] & 0x8) && !(reg_value & 0x8)) { 14493 hw_index = (a_offset.value[1] & 0xc0) >> 6; 14494 _bcm_esw_mirror_mtp_to_modport(unit, hw_index, TRUE, 14495 BCM_MIRROR_PORT_INGRESS, ¶m[0], ¶m[1]); 14496 a_offset.value[0] &= 0xfffffff0; 14497 valid = 1; 14498 break; 14499 } 14500 break; 14501 break; 14502 case bcmFieldActionMirrorEgress: 14503 if ((a_offset.value[0] & 0x1) && (reg_value & 0x1)){ 14504 hw_index = a_offset.value[1] & 0x3; 14505 _bcm_esw_mirror_mtp_to_modport(unit, hw_index, TRUE, 14506 BCM_MIRROR_PORT_EGRESS, ¶m[0], ¶m[1]); 14507 14508 a_offset.value[0] &= 0xfffffffe; 14509 valid = 1; 14510 break; 14511 14512 } 14513 if ((a_offset.value[0] & 0x2) && (reg_value & 0x2)) { 14514 hw_index = (a_offset.value[1] & 0xc) >> 2; 14515 _bcm_esw_mirror_mtp_to_modport(unit, hw_index, TRUE, 14516 BCM_MIRROR_PORT_EGRESS, ¶m[0], ¶m[1]); 14517 a_offset.value[0] &= 0xfffffffc; 14518 valid = 1; 14519 break; 14520 } 14521 if ((a_offset.value[0] & 0x4) && (reg_value & 0x4)) { 14522 hw_index = (a_offset.value[1] & 0x30) >> 4; 14523 _bcm_esw_mirror_mtp_to_modport(unit, hw_index, TRUE, 14524 BCM_MIRROR_PORT_EGRESS, ¶m[0], ¶m[1]); 14525 a_offset.value[0] &= 0xfffffff8; 14526 valid = 1; 14527 break; 14528 } 14529 if ((a_offset.value[0] & 0x8) && (reg_value & 0x8)) { 14530 hw_index = (a_offset.value[1] & 0xc0) >> 6; 14531 _bcm_esw_mirror_mtp_to_modport(unit, hw_index, TRUE, 14532 BCM_MIRROR_PORT_EGRESS, ¶m[0], ¶m[1]); 14533 a_offset.value[0] &= 0xfffffff0; 14534 valid = 1; 14535 break; 14536 } 14537 14538 break; 14539 default: 14540 break; 14541 14542 } 14543 if (valid) { 14544 f_act = NULL; 14545 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP em actions qos"); 14546 if (f_act == NULL) { 14547 return BCM_E_MEMORY; 14548 } 14549 mirror_recover = NULL; 14550 _FP_XGS3_ALLOC(mirror_recover, sizeof(_bcm_field_mirror_actions_recover_t), 14551 "Field Mirror Actions Recover Alloc."); 14552 if (mirror_recover == NULL) { 14553 sal_free(f_act); 14554 return BCM_E_MEMORY; 14555 } 14556 14557 mirror_recover->f_ent = f_ent; 14558 f_act->action = action_arr[action_idx]; 14559 mirror_recover->action = f_act->action; 14560 mirror_recover->mtp_gport = param[1]; 14561 mirror_recover->next = em_mirror_actions; 14562 em_mirror_actions = mirror_recover; 14563 14564 for (i=0; i < 6; i++) { 14565 f_act->param[i] = param[i]; 14566 } 14567 f_act->hw_index = hw_index; 14568 f_act->old_index = -1; 14569 f_act->flags = _FP_ACTION_VALID; 14570 if (prev_act == NULL) { 14571 prev_act = f_act; 14572 f_ent->actions = prev_act; 14573 } else { 14574 prev_act->next = f_act; 14575 prev_act = prev_act->next; 14576 } 14577 } 14578 } 14579 return BCM_E_NONE; 14580 } 14581 /* 14582 * Function: 14583 * _field_wb_l3swl2_set_recover 14584 * Purpose: 14585 * Recover actions that belong to l3swl2 set 14586 * 14587 * Parameters: 14588 * unit - (IN) StrataSwitch unit #. 14589 * f_ent - (IN) pointer to entry structure which refers 14590 * this action profile. 14591 * act_data - (IN) action data in the entry obtained from 14592 * exact match tables 14593 * Returns: 14594 * BCM_E_XXX 14595 */ 14596 int 14597 _field_wb_l3swl2_set_recover(int unit, _field_entry_t *f_ent, uint32 *ebuf, 14598 _field_action_bmp_t *act_bmp) 14599 { 14600 _bcm_field_action_offset_t a_offset; 14601 _field_action_t *f_act = NULL, *prev_act = NULL; 14602 int action_idx = 0; 14603 int param[6] = {0}; 14604 int sa_disable = 0, da_disable = 0, vn_action = 0; 14605 int hw_index = 0, i = 0, valid = 0, ov_new = 0; 14606 egr_l3_next_hop_entry_t entry; 14607 bcm_mac_t mac; 14608 uint32 *temp; 14609 int rv = BCM_E_NONE; 14610 bcm_field_action_t action_arr[] = { 14611 bcmFieldActionEgressClassSelect, 14612 bcmFieldActionHiGigClassSelect, 14613 bcmFieldActionNewClassId, 14614 bcmFieldActionDstMacNew, 14615 bcmFieldActionSrcMacNew, 14616 bcmFieldActionOuterVlanNew, 14617 bcmFieldActionVnTagNew, 14618 bcmFieldActionVnTagDelete, 14619 bcmFieldActionEtagNew, 14620 bcmFieldActionEtagDelete, 14621 bcmFieldActionFabricQueue, 14622 bcmFieldActionAddClassTag, 14623 bcmFieldActionL3Switch, 14624 bcmFieldActionMultipathHash, 14625 bcmFieldActionL3SwitchCancel, 14626 bcmFieldActionChangeL2FieldsCancel, 14627 bcmFieldActionChangeL2Fields, 14628 bcmFieldActionBFDSessionIdNew, 14629 }; 14630 14631 14632 temp = (uint32 *) &mac; 14633 if (f_ent->actions != NULL) { 14634 prev_act = f_ent->actions; 14635 while (prev_act->next != NULL) { 14636 prev_act = prev_act->next; 14637 } 14638 } 14639 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 14640 valid = 0; 14641 if (act_bmp != NULL) { 14642 if (act_bmp->w == NULL) { 14643 continue; 14644 } else { 14645 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 14646 continue; 14647 } 14648 } 14649 } 14650 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 14651 /* If action is not supported on this device, go for next action */ 14652 if (BCM_E_UNAVAIL == rv) { 14653 continue; 14654 } 14655 BCM_IF_ERROR_RETURN(rv); 14656 14657 switch (action_arr[action_idx]) { 14658 case bcmFieldActionEgressClassSelect: 14659 if ((a_offset.value[1] == 8) && (a_offset.value[0] != 0)) { 14660 if (a_offset.value[0] == 0xf) { 14661 param[0] = 0xb; 14662 } else { 14663 param[0] = a_offset.value[0]; 14664 } 14665 valid = 1; 14666 } 14667 break; 14668 case bcmFieldActionHiGigClassSelect: 14669 if ((a_offset.value[1] == 8) && (a_offset.value[0] != 0)) { 14670 param[0] = a_offset.value[0]; 14671 valid = 1; 14672 } 14673 break; 14674 case bcmFieldActionNewClassId: 14675 if ((a_offset.value[1] == 8) && (a_offset.offset[0] == 7)){ 14676 param[0] = a_offset.value[0]; 14677 valid = 1; 14678 } 14679 break; 14680 14681 case bcmFieldActionSrcMacNew: 14682 if ((a_offset.offset[1]==19) && (a_offset.width[1]==4) 14683 && (a_offset.value[1]==1)) { 14684 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, 14685 MEM_BLOCK_ANY, a_offset.value[0], &entry)); 14686 sa_disable = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14687 &entry, IFP_ACTIONS__L3_UC_SA_DISABLEf); 14688 da_disable = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14689 &entry, IFP_ACTIONS__L3_UC_DA_DISABLEf); 14690 /* ov_new = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &entry, IFP_ACTIONS__L3_UC_VLAN_DISABLEf); 14691 vn_action = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &entry, IFP_ACTIONS__VNTAG_ACTIONf); */ 14692 } 14693 if (sa_disable == 1) { 14694 valid = 1; 14695 hw_index = a_offset.value[0]; 14696 soc_mem_field_get(unit, EGR_L3_NEXT_HOPm, (uint32 *)&entry, 14697 IFP_ACTIONS__MAC_ADDRESSf, temp); 14698 for (i=0; i < 6; i++) { 14699 param[i] = mac[i]; 14700 } 14701 } 14702 break; 14703 case bcmFieldActionOuterVlanNew: 14704 if ((a_offset.offset[1]==19) && (a_offset.width[1]==4) 14705 && (a_offset.value[1]==1)) { 14706 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, 14707 MEM_BLOCK_ANY, a_offset.value[0], &entry)); 14708 ov_new = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &entry, 14709 IFP_ACTIONS__L3_UC_VLAN_DISABLEf); 14710 if (ov_new == 1) { 14711 valid = 1; 14712 param[0] = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14713 &entry, IFP_ACTIONS__INTF_NUMf); 14714 } 14715 } 14716 break; 14717 case bcmFieldActionDstMacNew: 14718 if ((a_offset.offset[1]==19) && (a_offset.width[1]==4) 14719 && (a_offset.value[1]==1)) { 14720 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, 14721 MEM_BLOCK_ANY, a_offset.value[0], &entry)); 14722 sa_disable = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14723 &entry, IFP_ACTIONS__L3_UC_SA_DISABLEf); 14724 da_disable = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14725 &entry, IFP_ACTIONS__L3_UC_DA_DISABLEf); 14726 /* ov_new = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &entry, IFP_ACTIONS__L3_UC_VLAN_DISABLEf); 14727 vn_action = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, &entry, IFP_ACTIONS__VNTAG_ACTIONf); */ 14728 } 14729 if (da_disable == 1) { 14730 valid = 1; 14731 hw_index = a_offset.value[0]; 14732 soc_mem_field_get(unit, EGR_L3_NEXT_HOPm, (uint32 *)&entry, 14733 IFP_ACTIONS__MAC_ADDRESSf, temp); 14734 for (i=0; i < 6; i++) { 14735 param[i] = mac[i]; 14736 } 14737 } 14738 break; 14739 case bcmFieldActionVnTagDelete: 14740 if ((a_offset.offset[1]==19) && (a_offset.width[1]==4) 14741 && (a_offset.value[1]==1)) { 14742 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, 14743 MEM_BLOCK_ANY, a_offset.value[0], &entry)); 14744 vn_action = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14745 &entry, IFP_ACTIONS__VNTAG_ACTIONf); 14746 if (vn_action == 0x3) { 14747 valid = 1; 14748 hw_index = a_offset.value[0]; 14749 } 14750 } 14751 break; 14752 case bcmFieldActionEtagNew: 14753 if ((a_offset.offset[1]==19) && (a_offset.width[1]==4) 14754 && (a_offset.value[1]==1)) { 14755 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, 14756 MEM_BLOCK_ANY, a_offset.value[0], &entry)); 14757 vn_action = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14758 &entry, IFP_ACTIONS__VNTAG_ACTIONf); 14759 if (vn_action == 0x2) { 14760 valid = 1; 14761 hw_index = a_offset.value[0]; 14762 param[0] = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14763 &entry, IFP_ACTIONS__VNTAGf); 14764 } 14765 } 14766 break; 14767 case bcmFieldActionVnTagNew: 14768 if ((a_offset.offset[1]==19) && (a_offset.width[1]==4) 14769 && (a_offset.value[1]==1)) { 14770 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_L3_NEXT_HOPm, 14771 MEM_BLOCK_ANY, a_offset.value[0], &entry)); 14772 vn_action = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14773 &entry, IFP_ACTIONS__VNTAG_ACTIONf); 14774 if (vn_action == 0x1) { 14775 valid = 1; 14776 hw_index = a_offset.value[0]; 14777 param[0] = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 14778 &entry, IFP_ACTIONS__VNTAGf); 14779 } 14780 } 14781 break; 14782 case bcmFieldActionFabricQueue: 14783 if (a_offset.value[2] == 3) { 14784 param[0] = a_offset.value[0]; 14785 param[1] = a_offset.value[1]; 14786 } 14787 break; 14788 case bcmFieldActionAddClassTag: 14789 if (a_offset.value[1] == 4) { 14790 param[0] = a_offset.value[0]; 14791 } 14792 break; 14793 14794 case bcmFieldActionL3Switch: 14795 #ifdef INCLUDE_L3 14796 if ((a_offset.value[2] == 6) && (a_offset.value[1] == 1)) { 14797 param[0] = a_offset.value[0] + BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit); 14798 valid = 1; 14799 } 14800 if ((a_offset.value[2] == 6) && (a_offset.value[1] == 0)) { 14801 param[0] = a_offset.value[1] + BCM_XGS3_EGRESS_IDX_MIN(unit); 14802 valid = 1; 14803 } 14804 #endif 14805 break; 14806 case bcmFieldActionMultipathHash: 14807 if ((a_offset.value[1] == 6) && (a_offset.width[0] == 3)) { 14808 param[0] = a_offset.value[0]; 14809 valid = 1; 14810 } 14811 break; 14812 case bcmFieldActionL3SwitchCancel: 14813 if (a_offset.value[0] == 7) { 14814 valid = 1; 14815 } 14816 break; 14817 case bcmFieldActionChangeL2FieldsCancel: 14818 if (a_offset.value[0] == 2) { 14819 valid = 1; 14820 } 14821 break; 14822 #ifdef INCLUDE_L3 14823 case bcmFieldActionChangeL2Fields: 14824 if (a_offset.value[1] == 1) { 14825 param[0] = BCM_XGS3_EGRESS_IDX_MIN(unit) + a_offset.value[0]; 14826 valid = 1; 14827 } 14828 break; 14829 #endif 14830 case bcmFieldActionBFDSessionIdNew: 14831 if (a_offset.value[1] == 9) { 14832 param[0] = a_offset.value[0]; 14833 valid = 1; 14834 } 14835 break; 14836 default: 14837 break; 14838 14839 } 14840 if (valid) { 14841 f_act = NULL; 14842 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP em actions qos"); 14843 if (f_act == NULL) { 14844 return BCM_E_MEMORY; 14845 } 14846 14847 f_act->action = action_arr[action_idx]; 14848 for (i=0; i < 6; i++) { 14849 f_act->param[i] = param[i]; 14850 param[i] = 0; 14851 } 14852 f_act->hw_index = hw_index; 14853 hw_index = 0; 14854 f_act->old_index = -1; 14855 f_act->flags = _FP_ACTION_VALID; 14856 if (prev_act == NULL) { 14857 prev_act = f_act; 14858 f_ent->actions = prev_act; 14859 } else { 14860 prev_act->next = f_act; 14861 prev_act = prev_act->next; 14862 } 14863 } 14864 } 14865 return BCM_E_NONE; 14866 } 14867 /* 14868 * Function: 14869 * _field_wb_emredirect_set_recover 14870 * Purpose: 14871 * Recover actions that belong to redirect set 14872 * 14873 * Parameters: 14874 * unit - (IN) StrataSwitch unit #. 14875 * f_ent - (IN) pointer to entry structure which refers 14876 * this action profile. 14877 * act_data - (IN) action data in the entry obtained from 14878 * exact match tables 14879 * Returns: 14880 * BCM_E_XXX 14881 */ 14882 int 14883 _field_wb_emredirect_set_recover(int unit, _field_entry_t *f_ent, 14884 uint32 *ebuf, _field_action_bmp_t *act_bmp) 14885 { 14886 _bcm_field_action_offset_t a_offset; 14887 _field_action_t *f_act = NULL, *prev_act = NULL; 14888 bcm_field_action_t action_idx; 14889 int param[6] = {0}; 14890 int hw_index = 0, i = 0, valid = 0; 14891 _field_stage_t *stage_fc = NULL; 14892 bcm_field_action_t action_arr[] = { 14893 bcmFieldActionRedirectTrunk, 14894 bcmFieldActionRedirect, 14895 bcmFieldActionUnmodifiedPacketRedirectPort, 14896 bcmFieldActionRedirectEgrNextHop, 14897 bcmFieldActionRedirectCancel, 14898 bcmFieldActionRedirectPbmp, 14899 bcmFieldActionRedirectVlan, 14900 bcmFieldActionRedirectBcastPbmp, 14901 bcmFieldActionRedirectMcast, 14902 bcmFieldActionRedirectIpmc, 14903 bcmFieldActionEgressMask, 14904 bcmFieldActionEgressPortsAdd, 14905 bcmFieldActionFabricEHAddOrUpdate 14906 }; 14907 soc_profile_mem_t *redirect_profile; 14908 ifp_redirection_profile_entry_t *entry = NULL; 14909 bcm_pbmp_t pbmp; 14910 int rv = BCM_E_NONE; 14911 #ifdef INCLUDE_L3 14912 int vp = 0; 14913 #endif 14914 14915 if (f_ent->actions != NULL) { 14916 prev_act = f_ent->actions; 14917 while (prev_act->next != NULL) { 14918 prev_act = prev_act->next; 14919 } 14920 } 14921 14922 entry = sal_alloc(sizeof(ifp_redirection_profile_entry_t), "em wb redirect entry"); 14923 BCM_IF_ERROR_CLEANUP(_field_stage_control_get(unit,f_ent->fs->stage_id, &stage_fc)); 14924 BCM_IF_ERROR_CLEANUP(_field_trx_redirect_profile_get(unit, &redirect_profile)); 14925 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 14926 valid = 0; 14927 if (act_bmp != NULL) { 14928 if (act_bmp->w == NULL) { 14929 continue; 14930 } else { 14931 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 14932 continue; 14933 } 14934 } 14935 } 14936 rv = (_bcm_field_action_val_get(unit, f_ent, 14937 ebuf, action_arr[action_idx], 0, &a_offset)); 14938 /* If action is not supported on this device, go for next action */ 14939 if (BCM_E_UNAVAIL == rv) { 14940 continue; 14941 } 14942 BCM_IF_ERROR_CLEANUP(rv); 14943 14944 switch (action_arr[action_idx]) { 14945 case bcmFieldActionRedirect: 14946 BCM_IF_ERROR_CLEANUP(_bcm_field_action_val_get(unit, f_ent, 14947 ebuf, bcmFieldActionRedirect, 14948 _BCM_FIELD_ACTION_REDIRECT_DGLP, &a_offset)); 14949 if ((a_offset.value[3] == 1) && (a_offset.value[2] == 0) 14950 && (a_offset.value[1] == 0)) { 14951 valid = 1; 14952 param[0] = (a_offset.value[0] >> 8) & 0xff; 14953 param[1] = (a_offset.value[0]) & 0xff; 14954 break; 14955 } 14956 if (!(soc_feature(unit, soc_feature_fp_no_dvp_support))) { 14957 BCM_IF_ERROR_CLEANUP(_bcm_field_action_val_get(unit, f_ent, 14958 ebuf, bcmFieldActionRedirect, 14959 _BCM_FIELD_ACTION_REDIRECT_DVP, &a_offset)); 14960 if ((a_offset.value[2] == 1) && (a_offset.value[1] == 6)) { 14961 #ifdef INCLUDE_L3 14962 valid = 1; 14963 vp = a_offset.value[0]; 14964 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 14965 BCM_GPORT_MPLS_PORT_ID_SET(param[1], vp); 14966 } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 14967 BCM_GPORT_MIM_PORT_ID_SET(param[1], vp); 14968 } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 14969 BCM_GPORT_VXLAN_PORT_ID_SET(param[1], vp); 14970 } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeFlow)) { 14971 BCM_GPORT_FLOW_PORT_ID_SET(param[1], vp); 14972 } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeTrill)) { 14973 BCM_GPORT_TRILL_PORT_ID_SET(param[1], vp); 14974 } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 14975 BCM_GPORT_L2GRE_PORT_ID_SET(param[1], vp); 14976 } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) { 14977 BCM_GPORT_NIV_PORT_ID_SET(param[1], vp); 14978 } 14979 break; 14980 #endif 14981 } 14982 } 14983 BCM_IF_ERROR_CLEANUP(_bcm_field_action_val_get(unit, f_ent, 14984 ebuf, bcmFieldActionRedirect, 14985 _BCM_FIELD_ACTION_REDIRECT_TRUNK, &a_offset)); 14986 if ((a_offset.value[3] == 1) && (a_offset.value[2] == 0) 14987 && (a_offset.value[1] == 1)) { 14988 valid = 1; 14989 param[0] = a_offset.value[0]; 14990 } 14991 break; 14992 case bcmFieldActionRedirectTrunk: 14993 if ((a_offset.value[3] == 1) && (a_offset.value[2] == 0) 14994 && (a_offset.value[1] == 1)) { 14995 valid = 1; 14996 param[0] = a_offset.value[0]; 14997 } 14998 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 14999 else { 15000 if (!(soc_feature(unit, soc_feature_fp_no_dvp_support))) { 15001 int vp_id_min = -1; 15002 BCM_IF_ERROR_CLEANUP(_bcm_field_action_val_get(unit, f_ent, 15003 ebuf, action_arr[action_idx], 15004 _BCM_FIELD_ACTION_REDIRECT_DVP, &a_offset)); 15005 if ((a_offset.value[2] == 1) && (a_offset.value[1] == 6)) { 15006 BCM_IF_ERROR_CLEANUP( 15007 _bcm_esw_trunk_chip_info_vp_resource_get(unit, 15008 &vp_id_min, 15009 NULL, NULL)); 15010 valid = 1; 15011 param[0] = a_offset.value[0] + vp_id_min; 15012 } 15013 } 15014 } 15015 #endif 15016 break; 15017 case bcmFieldActionUnmodifiedPacketRedirectPort: 15018 if ((a_offset.value[3] == 1) && (a_offset.value[2] == 1) 15019 && (a_offset.value[1] == 0)) { 15020 valid = 1; 15021 param[0] = a_offset.value[0]; 15022 } 15023 break; 15024 #ifdef INCLUDE_L3 15025 case bcmFieldActionRedirectEgrNextHop: 15026 if ((a_offset.value[2] == 1) && (a_offset.value[1] == 2)) { 15027 valid = 1; 15028 param[0] = (a_offset.value[0] & 0x7fff) 15029 + BCM_XGS3_EGRESS_IDX_MIN(unit); 15030 } 15031 if ((a_offset.value[2] == 1) && (a_offset.value[1] == 3)) { 15032 valid = 1; 15033 param[0] = (a_offset.value[0] & 0x7ff) 15034 + BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit); 15035 } 15036 break; 15037 #endif 15038 case bcmFieldActionRedirectCancel: 15039 if (a_offset.value[0] == 2) { 15040 valid = 1; 15041 } 15042 break; 15043 case bcmFieldActionRedirectVlan: 15044 if ((a_offset.value[2] == 3) && (a_offset.value[1] == 1)) { 15045 valid = 1; 15046 param[0] = a_offset.value[0]; 15047 } 15048 break; 15049 case bcmFieldActionRedirectMcast: 15050 if ((a_offset.value[2] == 3) && (a_offset.value[1] == 2)) { 15051 valid = 1; 15052 param[0] = a_offset.value[0]; 15053 } 15054 break; 15055 #ifdef INCLUDE_L3 15056 case bcmFieldActionRedirectIpmc: 15057 if ((a_offset.value[2]== 3) && (a_offset.value[1] == 3)) { 15058 valid = 1; 15059 param[0] = a_offset.value[0]; 15060 } 15061 break; 15062 #endif 15063 case bcmFieldActionEgressMask: 15064 if (a_offset.value[1] == 4) { 15065 hw_index = a_offset.value[0]; 15066 SOC_IF_ERROR_RETURN(soc_mem_read(unit, 15067 IFP_REDIRECTION_PROFILEm, MEM_BLOCK_ANY, 15068 hw_index, entry)); 15069 sal_memset(&pbmp, 0, sizeof(pbmp)); 15070 soc_mem_field_get(unit, IFP_REDIRECTION_PROFILEm, 15071 (uint32 *)entry, BITMAPf, pbmp.pbits); 15072 for (i=0; i < 4; i++) { 15073 param[i] = SOC_PBMP_WORD_GET(pbmp, i); 15074 } 15075 valid = 1; 15076 } 15077 break; 15078 case bcmFieldActionEgressPortsAdd: 15079 if (a_offset.value[1] == 5) { 15080 hw_index = a_offset.value[0]; 15081 SOC_IF_ERROR_RETURN(soc_mem_read(unit, 15082 IFP_REDIRECTION_PROFILEm, 15083 MEM_BLOCK_ANY, hw_index, entry)); 15084 sal_memset(&pbmp, 0, sizeof(pbmp)); 15085 soc_mem_field_get(unit, IFP_REDIRECTION_PROFILEm, 15086 (uint32 *)entry, BITMAPf, pbmp.pbits); 15087 for (i=0; i < 4; i++) { 15088 param[i] = SOC_PBMP_WORD_GET(pbmp, i); 15089 } 15090 valid = 1; 15091 } 15092 break; 15093 case bcmFieldActionRedirectBcastPbmp: 15094 if ((a_offset.value[3] == 3) && (a_offset.value[2] == 1) 15095 && (a_offset.value[1] == 1)) { 15096 hw_index = a_offset.value[0]; 15097 SOC_IF_ERROR_RETURN(soc_mem_read(unit, 15098 IFP_REDIRECTION_PROFILEm, MEM_BLOCK_ANY, 15099 hw_index, entry)); 15100 sal_memset(&pbmp, 0, sizeof(pbmp)); 15101 soc_mem_field_get(unit, IFP_REDIRECTION_PROFILEm,( 15102 uint32 *) entry, BITMAPf,pbmp.pbits); 15103 for (i=0; i < 4; i++) { 15104 param[i] = SOC_PBMP_WORD_GET(pbmp, i); 15105 } 15106 valid = 1; 15107 } 15108 break; 15109 case bcmFieldActionRedirectPbmp: 15110 if ((a_offset.value[2] == 3) && (a_offset.value[1] == 0)) { 15111 hw_index = a_offset.value[0]; 15112 SOC_IF_ERROR_RETURN(soc_mem_read(unit, 15113 IFP_REDIRECTION_PROFILEm, 15114 MEM_BLOCK_ANY, hw_index, entry)); 15115 sal_memset(&pbmp, 0, sizeof(pbmp)); 15116 soc_mem_field_get(unit, IFP_REDIRECTION_PROFILEm, 15117 (uint32 *)entry, BITMAPf, pbmp.pbits); 15118 for (i=0; i < 4; i++) { 15119 param[i] = SOC_PBMP_WORD_GET(pbmp, i); 15120 } 15121 valid = 1; 15122 } 15123 break; 15124 case bcmFieldActionFabricEHAddOrUpdate: 15125 if (stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 15126 valid =1; 15127 } 15128 break; 15129 default: 15130 break; 15131 15132 } 15133 if (valid) { 15134 f_act = NULL; 15135 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP em actions qos"); 15136 if (f_act == NULL) { 15137 rv = BCM_E_MEMORY; 15138 goto cleanup; 15139 } 15140 15141 f_act->action = action_arr[action_idx]; 15142 for (i=0; i < 6; i++) { 15143 f_act->param[i] = param[i]; 15144 param[i] = 0; 15145 } 15146 f_act->hw_index = hw_index; 15147 hw_index = 0; 15148 f_act->old_index = -1; 15149 f_act->flags = _FP_ACTION_VALID; 15150 if (prev_act == NULL) { 15151 prev_act = f_act; 15152 f_ent->actions = prev_act; 15153 } else { 15154 prev_act->next = f_act; 15155 prev_act = prev_act->next; 15156 } 15157 if ((f_act->action == bcmFieldActionRedirectBcastPbmp) || 15158 (f_act->action == bcmFieldActionRedirectPbmp) || 15159 (f_act->action == bcmFieldActionEgressMask) || 15160 (f_act->action == bcmFieldActionEgressPortsAdd)) { 15161 #if defined (BCM_TOMAHAWK3_SUPPORT) 15162 if ((f_act->action == bcmFieldActionEgressMask) && 15163 (soc_feature(unit, soc_feature_th3_style_fp))) { 15164 BCM_IF_ERROR_RETURN(_bcm_field_th3_redirect_profile_get(unit, 15165 &redirect_profile)); 15166 } 15167 #endif 15168 SOC_PROFILE_MEM_REFERENCE(unit, redirect_profile, hw_index, 1); 15169 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, 15170 redirect_profile, hw_index, 1); 15171 } 15172 if (f_act->action == bcmFieldActionFabricEHAddOrUpdate) { 15173 rv = _field_action_eh_recover(unit, f_ent, 15174 ebuf, f_act); 15175 BCM_IF_ERROR_CLEANUP(rv); 15176 } 15177 } 15178 15179 } 15180 cleanup: 15181 if (entry != NULL) { 15182 sal_free(entry); 15183 } 15184 return rv; 15185 } 15186 /* 15187 * Function: 15188 * _field_wb_counter_set_recover 15189 * Purpose: 15190 * Recover actions that belong to counter set 15191 * 15192 * Parameters: 15193 * unit - (IN) StrataSwitch unit #. 15194 * f_ent - (IN) pointer to entry structure which refers 15195 * this action profile. 15196 * act_data - (IN) action data in the entry obtained from 15197 * exact match tables 15198 * Returns: 15199 * BCM_E_XXX 15200 */ 15201 int 15202 _field_wb_counter_set_recover(int unit, _field_entry_t *f_ent, 15203 uint32 *ebuf, _field_action_bmp_t *act_bmp) { 15204 uint32 hw_offset_mode = 0; 15205 _field_stat_t *f_st = NULL; 15206 int rv = 0; 15207 bcm_stat_object_t stat_obj; /* Stat object type. */ 15208 bcm_stat_flex_mode_t offset_mode; /* Counter mode. */ 15209 bcm_stat_group_mode_t stat_mode; /* Stat type bcmStatGroupModeXXX. */ 15210 int fp_stat_mode_max; /* Max stat modes. */ 15211 uint8 idx; /* Index to carry loop count. */ 15212 uint32 pool_num; /* Flex Stat Hw Pool No. */ 15213 uint32 base_index; /* Flex Stat counter base index. */ 15214 uint32 num_hw_cntrs; /* Number of counters allocated. */ 15215 uint32 req_bmap = 0; /* Requested statistics bitmap. */ 15216 uint32 hw_bmap; /* HW supported statistics bitmap. */ 15217 15218 if (soc_feature(unit, soc_feature_th3_style_fp)) { 15219 hw_offset_mode = (*ebuf & 0x3000) >> 12; 15220 pool_num = (*ebuf & 0x7c000) >> 14; 15221 base_index = (*ebuf & 0xfff); 15222 } else { 15223 hw_offset_mode = (*ebuf & 0x1800) >> 11; 15224 pool_num = (*ebuf & 0x7c0) >> 6; 15225 base_index = (*ebuf & 0x1ff7000) >> 13; 15226 if (soc_feature(unit, soc_feature_td3_style_fp)) { 15227 base_index = (*ebuf & 0x3ffe000) >> 13; 15228 } 15229 } 15230 15231 _bcm_esw_stat_flex_check_ingress_em_table_entry(unit, 15232 f_ent->group->instance, f_ent->group->stage_id, 15233 hw_offset_mode, pool_num, base_index); 15234 15235 rv = _bcm_field_stat_get(unit, f_ent->statistic.sid, 15236 &f_st); 15237 if ((BCM_SUCCESS(rv)) && (f_st->flex_mode != 0)) { 15238 offset_mode = pool_num = base_index = num_hw_cntrs = -1; 15239 /* Get flex counter hardware details stored in flex stat ID.*/ 15240 _bcm_esw_stat_get_counter_id_info(unit, f_st->flex_mode, &stat_mode, 15241 &stat_obj, &offset_mode, &pool_num, 15242 &base_index); 15243 15244 if ((bcmStatObjectIngFieldStageIngress == stat_obj) || 15245 (bcmStatObjectIngExactMatch == stat_obj)) { 15246 /* Get application requested bitmap. */ 15247 BCM_IF_ERROR_RETURN(_bcm_field_stat_array_to_bmap(unit, f_st, 15248 &req_bmap)); 15249 fp_stat_mode_max = th_ingress_cntr_hw_mode_tbl_size; 15250 for (idx = 0; idx < fp_stat_mode_max; idx++) { 15251 hw_bmap = th_ingress_cntr_hw_mode_tbl[idx].hw_bmap; 15252 num_hw_cntrs = th_ingress_cntr_hw_mode_tbl[idx].hw_entry_count; 15253 if (0 == ((req_bmap | hw_bmap) & ~(hw_bmap))) { 15254 /* 15255 * For maximizing utilization of hardware counters, this should 15256 * select the hw_mode both supports the requested stats 15257 * AND minimizes the number of required hardware counters. 15258 */ 15259 break; 15260 } 15261 } 15262 } else { 15263 num_hw_cntrs = 1; 15264 } 15265 15266 /* Store flex stat hardware details in stat data structure. */ 15267 f_st->pool_index = pool_num; 15268 f_st->hw_index = base_index; 15269 f_st->hw_mode = offset_mode; 15270 f_st->hw_entry_count = num_hw_cntrs; 15271 f_st->hw_stat = req_bmap; 15272 f_st->sw_ref_count = f_st->sw_ref_count + 1; 15273 if(_FP_ENTRY_INSTALLED & f_ent->flags) { 15274 f_st->hw_ref_count = f_st->hw_ref_count + 1; 15275 } 15276 f_st->gid = f_ent->group->gid; 15277 f_st->stage_id = f_ent->group->stage_id; 15278 } 15279 return BCM_E_NONE; 15280 15281 } 15282 /* 15283 * Function: 15284 * _field_wb_change_ecn_set_recover 15285 * Purpose: 15286 * Recover actions that belong to ecn set 15287 * 15288 * Parameters: 15289 * unit - (IN) StrataSwitch unit #. 15290 * f_ent - (IN) pointer to entry structure which refers 15291 * this action profile. 15292 * act_data - (IN) action data in the entry obtained from 15293 * exact match tables 15294 * Returns: 15295 * BCM_E_XXX 15296 */ 15297 int 15298 _field_wb_change_ecn_set_recover(int unit, _field_entry_t *f_ent, 15299 uint32 *ebuf, _field_action_bmp_t *act_bmp) { 15300 _bcm_field_action_offset_t a_offset; 15301 _field_action_t *f_act = NULL, *prev_act = NULL; 15302 bcm_field_action_t action_idx; 15303 int param[6] = {0}; 15304 int hw_index = 0, i = 0, valid = 0; 15305 _field_stage_t *stage_fc = NULL; 15306 int rv = BCM_E_NONE; 15307 bcm_field_action_t action_arr[] = { 15308 bcmFieldActionRpEcnNew, 15309 bcmFieldActionYpEcnNew, 15310 bcmFieldActionGpEcnNew, 15311 bcmFieldActionEcnNew 15312 }; 15313 15314 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,f_ent->fs->stage_id, &stage_fc)); 15315 if (f_ent->actions != NULL) { 15316 prev_act = f_ent->actions; 15317 while (prev_act->next != NULL) { 15318 prev_act = prev_act->next; 15319 } 15320 } 15321 15322 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 15323 valid = 0; 15324 if (act_bmp != NULL) { 15325 if (act_bmp->w == NULL) { 15326 continue; 15327 } else { 15328 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 15329 continue; 15330 } 15331 } 15332 } 15333 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 15334 /* If action is not supported on this device, go for next action */ 15335 if (BCM_E_UNAVAIL == rv) { 15336 continue; 15337 } 15338 BCM_IF_ERROR_RETURN(rv); 15339 15340 switch (action_arr[action_idx]) { 15341 case bcmFieldActionRpEcnNew: 15342 case bcmFieldActionYpEcnNew: 15343 case bcmFieldActionGpEcnNew: 15344 valid = 1; 15345 param[0] = a_offset.value[0]; 15346 break; 15347 case bcmFieldActionEcnNew: 15348 if (stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 15349 valid = 1; 15350 param[0] = a_offset.value[0]; 15351 } 15352 break; 15353 default: 15354 break; 15355 15356 } 15357 if (valid) { 15358 f_act = NULL; 15359 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP em actions qos"); 15360 f_act->action = action_arr[action_idx]; 15361 for (i=0; i < 6; i++) { 15362 f_act->param[i] = param[i]; 15363 } 15364 f_act->hw_index = hw_index; 15365 f_act->old_index = -1; 15366 f_act->flags = _FP_ACTION_VALID; 15367 if (prev_act == NULL) { 15368 prev_act = f_act; 15369 f_ent->actions = prev_act; 15370 } else { 15371 prev_act->next = f_act; 15372 prev_act = prev_act->next; 15373 } 15374 } 15375 } 15376 15377 15378 return BCM_E_NONE; 15379 } 15380 15381 /* 15382 * Function: 15383 * _field_wb_pkt_pri_set_recover 15384 * Purpose: 15385 * Recover actions that belong to pkt pri set 15386 * 15387 * Parameters: 15388 * unit - (IN) StrataSwitch unit #. 15389 * f_ent - (IN) pointer to entry structure which refers 15390 * this action profile. 15391 * act_data - (IN) action data in the entry obtained from 15392 * exact match tables 15393 * Returns: 15394 * BCM_E_XXX 15395 */ 15396 int 15397 _field_wb_pkt_pri_set_recover(int unit, _field_entry_t *f_ent, 15398 uint32 *ebuf, _field_action_bmp_t *act_bmp) { 15399 15400 _bcm_field_action_offset_t a_offset; 15401 _field_action_t *f_act = NULL, *prev_act = NULL; 15402 bcm_field_action_t action_idx; 15403 int param[6] = {0}; 15404 int hw_index = 0, i = 0, valid = 0; 15405 int rv = BCM_E_NONE; 15406 bcm_field_action_t action_arr[] = { 15407 bcmFieldActionPrioPktCopy, 15408 bcmFieldActionPrioPktNew, 15409 bcmFieldActionPrioPktCancel, 15410 bcmFieldActionPrioPktTos, 15411 bcmFieldActionDot1pPreserve, 15412 bcmFieldActionGpPrioPktCopy, 15413 bcmFieldActionGpPrioPktNew, 15414 bcmFieldActionGpPrioPktCancel, 15415 bcmFieldActionGpPrioPktTos, 15416 bcmFieldActionGpDot1pPreserve, 15417 bcmFieldActionRpPrioPktCopy, 15418 bcmFieldActionRpPrioPktNew, 15419 bcmFieldActionRpPrioPktCancel, 15420 bcmFieldActionRpPrioPktTos, 15421 bcmFieldActionRpDot1pPreserve, 15422 bcmFieldActionYpPrioPktCopy, 15423 bcmFieldActionYpPrioPktNew, 15424 bcmFieldActionYpPrioPktCancel, 15425 bcmFieldActionYpPrioPktTos, 15426 bcmFieldActionYpDot1pPreserve 15427 }; 15428 15429 15430 if (f_ent->actions != NULL) { 15431 prev_act = f_ent->actions; 15432 while (prev_act->next != NULL) { 15433 prev_act = prev_act->next; 15434 } 15435 } 15436 15437 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 15438 valid = 0; 15439 if (act_bmp != NULL) { 15440 if (act_bmp->w == NULL) { 15441 continue; 15442 } else { 15443 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 15444 continue; 15445 } 15446 } 15447 } 15448 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 15449 /* If action is not supported on this device, go for next action */ 15450 if (BCM_E_UNAVAIL == rv) { 15451 continue; 15452 } 15453 BCM_IF_ERROR_RETURN(rv); 15454 15455 switch (action_arr[action_idx]) { 15456 case bcmFieldActionPrioPktCopy: 15457 case bcmFieldActionPrioPktTos: 15458 case bcmFieldActionPrioPktCancel: 15459 case bcmFieldActionDot1pPreserve: 15460 case bcmFieldActionGpPrioPktCopy: 15461 case bcmFieldActionGpPrioPktTos: 15462 case bcmFieldActionGpPrioPktCancel: 15463 case bcmFieldActionYpPrioPktCopy: 15464 case bcmFieldActionYpPrioPktTos: 15465 case bcmFieldActionYpPrioPktCancel: 15466 case bcmFieldActionRpPrioPktCopy: 15467 case bcmFieldActionRpPrioPktTos: 15468 case bcmFieldActionRpPrioPktCancel: 15469 case bcmFieldActionGpDot1pPreserve: 15470 case bcmFieldActionYpDot1pPreserve: 15471 case bcmFieldActionRpDot1pPreserve: 15472 valid = 1; 15473 break; 15474 case bcmFieldActionPrioPktNew: 15475 valid = 1; 15476 param[0] = a_offset.value[0]; 15477 break; 15478 case bcmFieldActionGpPrioPktNew: 15479 case bcmFieldActionRpPrioPktNew: 15480 case bcmFieldActionYpPrioPktNew: 15481 valid = 1; 15482 param[0] = a_offset.value[0]; 15483 break; 15484 default: 15485 break; 15486 15487 } 15488 if (valid) { 15489 f_act = NULL; 15490 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP em actions qos"); 15491 f_act->action = action_arr[action_idx]; 15492 for (i=0; i < 6; i++) { 15493 f_act->param[i] = param[i]; 15494 } 15495 f_act->hw_index = hw_index; 15496 f_act->old_index = -1; 15497 f_act->flags = _FP_ACTION_VALID; 15498 if (prev_act == NULL) { 15499 prev_act = f_act; 15500 f_ent->actions = prev_act; 15501 } else { 15502 prev_act->next = f_act; 15503 prev_act = prev_act->next; 15504 } 15505 } 15506 } 15507 return BCM_E_NONE; 15508 } 15509 15510 15511 15512 int 15513 _field_em_entry_bmp_to_action_get(int unit, 15514 _field_entry_t *f_ent, 15515 bcm_field_action_t action, 15516 int *valid) 15517 { 15518 int rv = BCM_E_NONE; 15519 int count = 0; 15520 int hw_index = 0; 15521 _field_wb_em_act_ent_bmp_t *f_ent_bmp = NULL; 15522 _field_group_t *fg = NULL; 15523 _field_stage_t *stage_fc = NULL; 15524 15525 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 15526 f_ent->group->stage_id, &stage_fc)); 15527 fg = f_ent->group; 15528 f_ent_bmp = tlv_em_act[unit]; 15529 BCM_IF_ERROR_CLEANUP(_bcm_field_th_em_entry_tcam_idx_get(unit, f_ent, &hw_index)); 15530 for (count = 0 ; 15531 (count < _FP_EM_NUM_WB_SUPPORTED_ACTIONS); 15532 count++) { 15533 if (bcmFieldActionCount == f_ent_bmp[count].action) { 15534 break; 15535 } 15536 if (action != f_ent_bmp[count].action) { 15537 continue; 15538 } 15539 if (SHR_BITGET(f_ent_bmp[count].ent_bmp.w, hw_index)) { 15540 if (stage_fc->oper_mode == bcmFieldGroupOperModePipeLocal) { 15541 if (!SHR_BITGET(f_ent_bmp[count].ent_bmp.w, stage_fc->tcam_sz + fg->instance)) { 15542 continue; 15543 } 15544 } 15545 *valid = 1; 15546 break; 15547 } 15548 } 15549 cleanup: 15550 return rv; 15551 } 15552 15553 /* Recover Extraction Ctrl ID Set */ 15554 int 15555 _field_wb_extraction_ctrl_id_set_recover(int unit, _field_entry_t *f_ent, 15556 uint32 *ebuf, 15557 _field_action_bmp_t *act_bmp) 15558 { 15559 int rv1 = BCM_E_NONE, rv2 = BCM_E_NONE; 15560 int act_val = 0; 15561 int ext_ctrl_id = 0; 15562 int hw_index = 0, valid = 0, param0 = 0; 15563 bcm_field_action_t action = bcmFieldActionCount; 15564 bcm_field_action_t action_idx = bcmFieldActionCount; 15565 _bcm_field_action_offset_t a_offset; 15566 soc_cancun_ceh_field_info_t ceh_info1; 15567 soc_cancun_ceh_field_info_t ceh_info2; 15568 _field_action_t *f_act = NULL, *prev_act = NULL, *fa = NULL; 15569 int rv = BCM_E_NONE; 15570 bcm_field_action_t action_arr[] = { 15571 _bcmFieldActionExtractionCtrlId, 15572 bcmFieldActionAssignExtractionCtrlId, 15573 }; 15574 15575 15576 if (f_ent->actions != NULL) { 15577 prev_act = f_ent->actions; 15578 while (prev_act->next != NULL) { 15579 prev_act = prev_act->next; 15580 } 15581 } 15582 15583 15584 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 15585 valid = 0; 15586 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 15587 /* If action is not supported on this device, go for next action */ 15588 if (BCM_E_UNAVAIL == rv) { 15589 continue; 15590 } 15591 BCM_IF_ERROR_RETURN(rv); 15592 15593 15594 if (valid == 0) { 15595 ext_ctrl_id = a_offset.value[0]; 15596 15597 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15598 "SPID_SI_LOOKUP_ENABLE", &ceh_info1); 15599 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15600 "SPID_SI_LOOKUP_ENABLE_MASK", &ceh_info2); 15601 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15602 act_val = ceh_info1.value; 15603 act_val |= ((ceh_info2.value) << ceh_info2.offset); 15604 15605 if (act_val == ext_ctrl_id) { 15606 action = bcmFieldActionNshEncapEnable; 15607 valid = 1; 15608 } 15609 } 15610 } 15611 15612 if (valid == 0) { 15613 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "INT_ENABLE", 15614 &ceh_info1); 15615 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "INT_ENABLE_MASK", 15616 &ceh_info2); 15617 15618 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15619 act_val = ceh_info1.value; 15620 act_val |= ((ceh_info2.value) << ceh_info2.offset); 15621 } 15622 15623 if (act_val == ext_ctrl_id) { 15624 action = bcmFieldActionIntEncapUpdate; 15625 valid = 1; 15626 } 15627 } 15628 15629 if (valid == 0) { 15630 ext_ctrl_id = (a_offset.value[0] & 0xff); /* Ignore Mask (msb 16 bits) */ 15631 switch (ext_ctrl_id) { 15632 case _BCM_FIELD_EXTR_CTRL_ID_ERSPAN3_VLAN_PKT_COPY: 15633 action = bcmFieldActionErspan3HdrVlanCosPktCopy; 15634 valid = 1; 15635 break; 15636 default: 15637 break; 15638 } 15639 } 15640 15641 if (valid == 0) { 15642 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "GBP_PRESENT_IN_PKT", 15643 &ceh_info1); 15644 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "GBP_PRESENT_IN_PKT_MASK", 15645 &ceh_info2); 15646 15647 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15648 act_val = ceh_info1.value; 15649 act_val |= ((ceh_info2.value) << ceh_info2.offset); 15650 } 15651 15652 if (act_val == ext_ctrl_id) { 15653 action = bcmFieldActionGbpClassifierAdd; 15654 valid = 1; 15655 } 15656 } 15657 if (valid == 0) { 15658 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "GBP_SID_DID_CHECK", 15659 &ceh_info1); 15660 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "GBP_SID_DID_CHECK_MASK", 15661 &ceh_info2); 15662 15663 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15664 act_val = ceh_info1.value; 15665 act_val |= ((ceh_info2.value) << ceh_info2.offset); 15666 } 15667 15668 if (act_val == ext_ctrl_id) { 15669 action = bcmFieldActionGbpSrcMacMcastBitSet; 15670 valid = 1; 15671 } 15672 } 15673 15674 if (0 == valid) { 15675 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "REDIRECT_TO_DEST", 15676 &ceh_info1); 15677 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "REDIRECT_TO_DEST_MASK", 15678 &ceh_info2); 15679 15680 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15681 act_val = ceh_info1.value; 15682 act_val |= ((ceh_info2.value) << ceh_info2.offset); 15683 } 15684 15685 if (act_val == ext_ctrl_id) { 15686 action = bcmFieldActionEgressFlowControlEnable; 15687 param0 = bcmFieldEgressFlowControlLoopbackRedirect; 15688 valid = 1; 15689 } 15690 } 15691 15692 if (0 == valid) { 15693 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "PRESERVE_INCOMING_OTAG", 15694 &ceh_info1); 15695 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "PRESERVE_INCOMING_OTAG_MASK", 15696 &ceh_info2); 15697 15698 if ((BCM_E_NOT_FOUND == rv1) && (BCM_E_NOT_FOUND == rv2)) { 15699 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15700 "ADD_ING_OTAG_TO_EGR_OTAG", 15701 &ceh_info1); 15702 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15703 "ADD_ING_OTAG_TO_EGR_OTAG_MASK", 15704 &ceh_info2); 15705 } 15706 15707 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15708 act_val = ceh_info1.value; 15709 act_val |= ((ceh_info2.value) << ceh_info2.offset); 15710 } 15711 15712 if (act_val == ext_ctrl_id) { 15713 if (_BCM_FIELD_STAGE_INGRESS == f_ent->group->stage_id) { 15714 if ((NULL != act_bmp) && (NULL != act_bmp->w)) { 15715 if (SHR_BITGET(act_bmp->w, bcmFieldEgressFlowControlAppendIncomingOuterVlan)) { 15716 action = bcmFieldActionEgressFlowControlEnable; 15717 param0 = bcmFieldEgressFlowControlAppendIncomingOuterVlan; 15718 valid = 1; 15719 } else { 15720 action = bcmFieldActionAddIngOuterVlanToEgrOuterVlan; 15721 valid = 1; 15722 } 15723 } 15724 } else { 15725 rv1 = _field_em_entry_bmp_to_action_get(unit, f_ent, 15726 bcmFieldActionEgressFlowControlEnable, 15727 &valid); 15728 if (BCM_SUCCESS(rv1)) { 15729 if (valid) { 15730 action = bcmFieldActionEgressFlowControlEnable; 15731 param0 = bcmFieldEgressFlowControlAppendIncomingOuterVlan; 15732 } else { 15733 action = bcmFieldActionAddIngOuterVlanToEgrOuterVlan; 15734 valid = 1; 15735 } 15736 } 15737 } 15738 } 15739 } 15740 15741 if (0 == valid) { 15742 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "ASSIGN_PRESERVE_OTAG", 15743 &ceh_info1); 15744 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "ASSIGN_PRESERVE_OTAG_MASK", 15745 &ceh_info2); 15746 15747 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15748 act_val = ceh_info1.value; 15749 } 15750 15751 if (act_val == ext_ctrl_id) { 15752 action = bcmFieldActionEgressFlowControlEnable; 15753 param0 = bcmFieldEgressFlowControlAppendOuterVlanNew; 15754 valid = 1; 15755 } 15756 } 15757 15758 if (0 == valid) { 15759 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "SIP_ONLY_TRANSLATE", 15760 &ceh_info1); 15761 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "SIP_ONLY_TRANSLATE_MASK", 15762 &ceh_info2); 15763 15764 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15765 act_val = ceh_info1.value; 15766 } 15767 15768 if (act_val == ext_ctrl_id) { 15769 action = bcmFieldActionEgressFlowControlEnable; 15770 param0 = bcmFieldEgressFlowControlTranslateSnatSrcIpOnly; 15771 valid = 1; 15772 } 15773 } 15774 15775 if (0 == valid) { 15776 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "SIP_DIP_TRANSLATE", 15777 &ceh_info1); 15778 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "SIP_DIP_TRANSLATE_MASK", 15779 &ceh_info2); 15780 15781 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15782 act_val = ceh_info1.value; 15783 } 15784 15785 if (act_val == ext_ctrl_id) { 15786 action = bcmFieldActionEgressFlowControlEnable; 15787 param0 = bcmFieldEgressFlowControlTranslateDnatSrcIpDstIp; 15788 valid = 1; 15789 } 15790 } 15791 15792 if (0 == valid) { 15793 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "SIP_DIP_TRANSLATE_SNAT", 15794 &ceh_info1); 15795 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "SIP_DIP_TRANSLATE_SNAT_MASK", 15796 &ceh_info2); 15797 15798 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15799 act_val = ceh_info1.value; 15800 } 15801 15802 if (act_val == ext_ctrl_id) { 15803 action = bcmFieldActionEgressFlowControlEnable; 15804 param0 = bcmFieldEgressFlowControlTranslateSnatSrcIpDstIp; 15805 valid = 1; 15806 } 15807 } 15808 15809 if (0 == valid) { 15810 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "SIP_L4SRC_PORT_TRANSLATE", 15811 &ceh_info1); 15812 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", "SIP_L4SRC_PORT_TRANSLATE_MASK", 15813 &ceh_info2); 15814 15815 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15816 act_val = ceh_info1.value; 15817 } 15818 15819 if (act_val == ext_ctrl_id) { 15820 action = bcmFieldActionEgressFlowControlEnable; 15821 param0 = bcmFieldEgressFlowControlTranslateSnaptSrcIpL4SrcPort; 15822 valid = 1; 15823 } 15824 } 15825 15826 if (0 == valid) { 15827 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15828 "SIP_L4SRC_PORT_DIP_L4DST_PORT_TRANSLATE_SNAT", 15829 &ceh_info1); 15830 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15831 "SIP_L4SRC_PORT_DIP_L4DST_PORT_TRANSLATE_SNAT_MASK", 15832 &ceh_info2); 15833 15834 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15835 act_val = ceh_info1.value; 15836 } 15837 15838 if (act_val == ext_ctrl_id) { 15839 action = bcmFieldActionEgressFlowControlEnable; 15840 param0 = bcmFieldEgressFlowControlTranslateSnaptSrcIpDstIpL4SrcPortL4DstPort; 15841 valid = 1; 15842 } 15843 } 15844 15845 if (0 == valid) { 15846 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15847 "SIP_L4SRC_PORT_DIP_L4DST_PORT_TRANSLATE", 15848 &ceh_info1); 15849 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15850 "SIP_L4SRC_PORT_DIP_L4DST_PORT_TRANSLATE_MASK", 15851 &ceh_info2); 15852 15853 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15854 act_val = ceh_info1.value; 15855 } 15856 15857 if (act_val == ext_ctrl_id) { 15858 action = bcmFieldActionEgressFlowControlEnable; 15859 param0 = bcmFieldEgressFlowControlTranslateDnaptSrcIpDstIpL4SrcPortL4DstPort; 15860 valid = 1; 15861 } 15862 } 15863 15864 if (0 == valid) { 15865 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15866 "DIP_ONLY_TRANSLATE", 15867 &ceh_info1); 15868 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15869 "DIP_ONLY_TRANSLATE_MASK", 15870 &ceh_info2); 15871 15872 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15873 act_val = ceh_info1.value; 15874 } 15875 15876 if (act_val == ext_ctrl_id) { 15877 action = bcmFieldActionEgressFlowControlEnable; 15878 param0 = bcmFieldEgressFlowControlTranslateDnatDstIpOnly; 15879 valid = 1; 15880 } 15881 } 15882 15883 if (0 == valid) { 15884 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15885 "DIP_L4DST_PORT_TRANSLATE", 15886 &ceh_info1); 15887 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15888 "DIP_L4DST_PORT_TRANSLATE_MASK", 15889 &ceh_info2); 15890 15891 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15892 act_val = ceh_info1.value; 15893 } 15894 15895 if (act_val == ext_ctrl_id) { 15896 action = bcmFieldActionEgressFlowControlEnable; 15897 param0 = bcmFieldEgressFlowControlTranslateDnaptDstIpL4DstPort; 15898 valid = 1; 15899 } 15900 } 15901 15902 if (0 == valid) { 15903 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15904 "IPMC_TRANSLATE", 15905 &ceh_info1); 15906 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15907 "IPMC_TRANSLATE_MASK", 15908 &ceh_info2); 15909 15910 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15911 act_val = ceh_info1.value; 15912 } 15913 15914 if (act_val == ext_ctrl_id) { 15915 action = bcmFieldActionEgressFlowControlEnable; 15916 param0 = bcmFieldEgressFlowControlTranslateIpmc; 15917 valid = 1; 15918 } 15919 } 15920 15921 if (0 == valid) { 15922 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15923 "CHANGE_L2_FIELDS_DA_SA_VLAN", 15924 &ceh_info1); 15925 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15926 "CHANGE_L2_FIELDS_DA_SA_VLAN_MASK", 15927 &ceh_info2); 15928 15929 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15930 act_val = ceh_info1.value; 15931 } 15932 15933 if (act_val == ext_ctrl_id) { 15934 action = bcmFieldActionEgressFlowControlEnable; 15935 param0 = bcmFieldEgressFlowControlSrcMacDstMacVlanNew; 15936 valid = 1; 15937 } 15938 } 15939 15940 if (0 == valid) { 15941 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15942 "CHANGE_L2_FIELDS_DA_VLAN", 15943 &ceh_info1); 15944 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15945 "CHANGE_L2_FIELDS_DA_VLAN_MASK", 15946 &ceh_info2); 15947 15948 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15949 act_val = ceh_info1.value; 15950 } 15951 15952 if (act_val == ext_ctrl_id) { 15953 action = bcmFieldActionEgressFlowControlEnable; 15954 param0 = bcmFieldEgressFlowControlDstMacVlanNew; 15955 valid = 1; 15956 } 15957 } 15958 15959 if (0 == valid) { 15960 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15961 "CHANGE_L2_FIELDS_SA_VLAN", 15962 &ceh_info1); 15963 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15964 "CHANGE_L2_FIELDS_SA_VLAN_MASK", 15965 &ceh_info2); 15966 15967 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15968 act_val = ceh_info1.value; 15969 } 15970 15971 if (act_val == ext_ctrl_id) { 15972 action = bcmFieldActionEgressFlowControlEnable; 15973 param0 = bcmFieldEgressFlowControlSrcMacVlanNew; 15974 valid = 1; 15975 } 15976 } 15977 15978 if (0 == valid) { 15979 rv1 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15980 "CHANGE_L2_FIELDS_VLAN", 15981 &ceh_info1); 15982 rv2 = soc_cancun_ceh_obj_field_get(unit, "EXTRACTION_CTRL_ID", 15983 "CHANGE_L2_FIELDS_VLAN_MASK", 15984 &ceh_info2); 15985 15986 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 15987 act_val = ceh_info1.value; 15988 } 15989 15990 if (act_val == ext_ctrl_id) { 15991 action = bcmFieldActionEgressFlowControlEnable; 15992 param0 = bcmFieldEgressFlowControlVlanNew; 15993 valid = 1; 15994 } 15995 } 15996 15997 if (0 == valid) { 15998 action = bcmFieldActionAssignExtractionCtrlId; 15999 param0 = ext_ctrl_id; 16000 valid = 1; 16001 } 16002 16003 if (valid) { 16004 int found = 0; 16005 int int_action = -1; 16006 #if 0 16007 bcm_field_action_t int_action, nsh_action, remove_action; 16008 #endif 16009 16010 fa = f_ent->actions; 16011 while (fa != NULL) { 16012 if (fa->action == action) { 16013 f_act = fa; 16014 found = 1; 16015 } 16016 #if 0 16017 if (fa->action == bcmFieldActionNshEncapEnable) { 16018 nsh_action = fa->action; 16019 } 16020 #endif 16021 if (fa->action == bcmFieldActionIntEncapEnable) { 16022 int_action = fa->action; 16023 } 16024 fa = fa->next; 16025 } 16026 16027 if ((action == bcmFieldActionIntEncapUpdate) && 16028 (int_action == bcmFieldActionIntEncapEnable)) { 16029 /* 16030 * The Action "IntEncapEnable" is already attached to the entry 16031 * in the EDIT Ctrl Recovery, need not process here. 16032 */ 16033 break; 16034 } 16035 16036 if (action == bcmFieldActionNshEncapEnable) { 16037 if (found == 0) { 16038 continue; 16039 } 16040 } 16041 #if 0 16042 if ((action != bcmFieldActionNshEncapEnable) && 16043 (nsh_action == bcmFieldActionNshEncapEnable)) { 16044 /* remove NshEncapEnable action */ 16045 remove_action = nsh_action; 16046 16047 } 16048 16049 if ((action != bcmFieldActionIntEncapUpdate) && 16050 (int_action == bcmFieldActionIntEncapEnable)) { 16051 /* remove NshEncapEnable action */ 16052 remove_action = int_action; 16053 } 16054 #endif 16055 16056 if (f_act == NULL) { 16057 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16058 if (f_act == NULL) { 16059 return BCM_E_MEMORY; 16060 } 16061 } 16062 f_act->action = action; 16063 f_act->param[0] = param0; 16064 f_act->hw_index = hw_index; 16065 f_act->old_index = -1; 16066 f_act->flags = _FP_ACTION_VALID; 16067 if (found == 0) { 16068 if (prev_act == NULL) { 16069 prev_act = f_act; 16070 f_ent->actions = prev_act; 16071 } else { 16072 prev_act->next = f_act; 16073 prev_act = prev_act->next; 16074 } 16075 } 16076 break; 16077 } 16078 } 16079 return BCM_E_NONE; 16080 } 16081 16082 /* Recover Edit Ctrl ID Set */ 16083 int 16084 _field_wb_edit_ctrl_id_set_recover(int unit, _field_entry_t *f_ent, 16085 uint32 *ebuf, 16086 _field_action_bmp_t *act_bmp) 16087 { 16088 int rv1, rv2; 16089 int act_val = 0; 16090 int param0 = 0; 16091 int edit_ctrl_id = 0; 16092 int hw_index = 0, valid = 0; 16093 bcm_field_action_t action; 16094 bcm_field_action_t action_idx; 16095 _bcm_field_action_offset_t a_offset; 16096 soc_cancun_ceh_field_info_t ceh_info1; 16097 soc_cancun_ceh_field_info_t ceh_info2; 16098 _field_action_t *f_act = NULL, *prev_act = NULL; 16099 int rv = BCM_E_NONE; 16100 bcm_field_action_t action_arr[] = { 16101 bcmFieldActionAssignEditCtrlId, 16102 _bcmFieldActionEditCtrlId, 16103 }; 16104 16105 16106 if (f_ent->actions != NULL) { 16107 prev_act = f_ent->actions; 16108 while (prev_act->next != NULL) { 16109 prev_act = prev_act->next; 16110 } 16111 } 16112 16113 16114 sal_memset(&a_offset, 0, sizeof(a_offset)); 16115 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 16116 valid = 0; 16117 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16118 /* If action is not supported on this device, go for next action */ 16119 if (BCM_E_UNAVAIL == rv) { 16120 continue; 16121 } 16122 BCM_IF_ERROR_RETURN(rv); 16123 16124 if (action_arr[action_idx] == bcmFieldActionAssignEditCtrlId) { 16125 if (act_bmp != NULL) { 16126 if (act_bmp->w == NULL) { 16127 continue; 16128 } else { 16129 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 16130 continue; 16131 } 16132 } 16133 } 16134 } 16135 16136 if (valid == 0) { 16137 edit_ctrl_id = a_offset.value[0]; 16138 16139 rv1 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", "INT_TURNAROUND", 16140 &ceh_info1); 16141 rv2 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", "INT_TURNAROUND_MASK", 16142 &ceh_info2); 16143 if (SOC_SUCCESS(rv1) && SOC_SUCCESS(rv2)) { 16144 act_val = ceh_info1.value; 16145 act_val |= ((ceh_info2.value) << ceh_info2.offset); 16146 16147 if (act_val == edit_ctrl_id) { 16148 action = bcmFieldActionIntTurnAround; 16149 valid = 1; 16150 } 16151 } 16152 } 16153 16154 if (valid == 0) { 16155 rv1 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", "ADD_NSH", 16156 &ceh_info1); 16157 rv2 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", "ADD_NSH_MASK", 16158 &ceh_info2); 16159 if (SOC_SUCCESS(rv1) && (SOC_SUCCESS(rv2))) { 16160 act_val = ceh_info1.value; 16161 act_val |= ((ceh_info2.value) << ceh_info2.offset); 16162 if (act_val == edit_ctrl_id) { 16163 action = bcmFieldActionNshEncapEnable; 16164 valid = 1; 16165 } 16166 } 16167 } 16168 16169 if (valid == 0) { 16170 rv1 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", 16171 "INT_ENABLE", &ceh_info1); 16172 rv2 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", 16173 "INT_ENABLE_MASK", &ceh_info2); 16174 if (SOC_SUCCESS(rv1) && (SOC_SUCCESS(rv2))) { 16175 act_val = ceh_info1.value; 16176 act_val |= ((ceh_info2.value) << ceh_info2.offset); 16177 if (act_val == edit_ctrl_id) { 16178 action = bcmFieldActionIntEncapEnable; 16179 valid = 1; 16180 } 16181 } 16182 } 16183 16184 if (valid == 0) { 16185 rv1 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", 16186 "PRESERVE_INCOMING_OTAG", &ceh_info1); 16187 rv2 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", 16188 "PRESERVE_INCOMING_OTAG_MASK", &ceh_info2); 16189 if (SOC_SUCCESS(rv1) && (SOC_SUCCESS(rv2))) { 16190 act_val = ceh_info1.value; 16191 act_val |= ((ceh_info2.value) << ceh_info2.offset); 16192 if (act_val == edit_ctrl_id) { 16193 action = bcmFieldActionEgressFlowEncapEnable; 16194 param0 = bcmFieldEgressFlowEncapAppendIncomingOuterVlan; 16195 valid = 1; 16196 } 16197 } 16198 } 16199 16200 if (valid == 0) { 16201 rv1 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", 16202 "PRESERVE_INCOMING_OTAG", &ceh_info1); 16203 rv2 = soc_cancun_ceh_obj_field_get(unit, "EDIT_CTRL_ID", 16204 "PRESERVE_INCOMING_OTAG_MASK", &ceh_info2); 16205 if (SOC_SUCCESS(rv1) && (SOC_SUCCESS(rv2))) { 16206 act_val = ceh_info1.value; 16207 act_val |= ((ceh_info2.value) << ceh_info2.offset); 16208 if (act_val == edit_ctrl_id) { 16209 action = bcmFieldActionEgressFlowEncapEnable; 16210 param0 = bcmFieldEgressFlowEncapTwampOwampTxTimestamp; 16211 valid = 1; 16212 } 16213 } 16214 } 16215 16216 if (valid == 0) { 16217 action = bcmFieldActionAssignEditCtrlId; 16218 param0 = a_offset.value[0]; 16219 valid = 1; 16220 } 16221 16222 if (valid) { 16223 f_act = NULL; 16224 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16225 if (f_act == NULL) { 16226 return BCM_E_MEMORY; 16227 } 16228 f_act->action = action; 16229 f_act->param[0] = param0; 16230 f_act->hw_index = hw_index; 16231 f_act->old_index = -1; 16232 f_act->flags = _FP_ACTION_VALID; 16233 if (prev_act == NULL) { 16234 prev_act = f_act; 16235 f_ent->actions = prev_act; 16236 } else { 16237 prev_act->next = f_act; 16238 prev_act = prev_act->next; 16239 } 16240 break; 16241 } 16242 } 16243 return BCM_E_NONE; 16244 } 16245 16246 /* Recover Opaque1 Set */ 16247 int 16248 _field_wb_opaque1_set_recover(int unit, _field_entry_t *f_ent, 16249 uint32 *ebuf, 16250 _field_action_bmp_t *act_bmp) 16251 { 16252 _bcm_field_action_offset_t a_offset; 16253 _field_action_t *f_act = NULL, *prev_act = NULL; 16254 bcm_field_action_t action_idx; 16255 int valid = 0; 16256 bcm_field_action_t action; 16257 int rv = BCM_E_NONE; 16258 bcm_field_action_t action_arr[] = { 16259 bcmFieldActionAssignOpaqueObject1, 16260 bcmFieldActionGbpSrcIdNew, 16261 bcmFieldActionAssignNatClassId, 16262 bcmFieldActionNshServicePathId, /* Always last. Default action to be recovered. */ 16263 }; 16264 _field_stage_t *stage_fc = NULL; 16265 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 16266 f_ent->group->stage_id, &stage_fc)); 16267 16268 if (f_ent->actions != NULL) { 16269 prev_act = f_ent->actions; 16270 while (prev_act->next != NULL) { 16271 prev_act = prev_act->next; 16272 } 16273 } 16274 16275 if (_BCM_FIELD_STAGE_EXACTMATCH == f_ent->group->stage_id) { 16276 valid = 0; 16277 for (action_idx = 0; (0 == valid) && action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 16278 if (bcmFieldActionNshServicePathId == action_arr[action_idx]) { 16279 sal_memset(&a_offset, 0x0, sizeof(a_offset)); 16280 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16281 /* If action is not supported on this device, go for next action */ 16282 if (BCM_E_UNAVAIL == rv) { 16283 continue; 16284 } 16285 BCM_IF_ERROR_RETURN(rv); 16286 16287 f_act = NULL; 16288 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16289 if (f_act == NULL) { 16290 return BCM_E_MEMORY; 16291 } 16292 valid = 1; 16293 f_act->action = bcmFieldActionNshServicePathId; 16294 f_act->param[0] |= a_offset.value[0]; 16295 f_act->old_index = -1; 16296 f_act->flags = _FP_ACTION_VALID; 16297 if (prev_act == NULL) { 16298 prev_act = f_act; 16299 f_ent->actions = prev_act; 16300 } else { 16301 prev_act->next = f_act; 16302 prev_act = prev_act->next; 16303 } 16304 } else { 16305 BCM_IF_ERROR_CLEANUP(_field_em_entry_bmp_to_action_get(unit, f_ent, 16306 action_arr[action_idx], 16307 &valid)); 16308 if (!valid) { 16309 continue; 16310 } 16311 sal_memset(&a_offset, 0x0, sizeof(a_offset)); 16312 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16313 /* If action is not supported on this device, go for next action */ 16314 if (BCM_E_UNAVAIL == rv) { 16315 continue; 16316 } 16317 BCM_IF_ERROR_RETURN(rv); 16318 16319 f_act = NULL; 16320 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16321 if (f_act == NULL) { 16322 return BCM_E_MEMORY; 16323 } 16324 f_act->action = action_arr[action_idx]; 16325 f_act->param[0] = a_offset.value[0]; 16326 f_act->old_index = -1; 16327 f_act->flags = _FP_ACTION_VALID; 16328 if (prev_act == NULL) { 16329 prev_act = f_act; 16330 f_ent->actions = prev_act; 16331 } else { 16332 prev_act->next = f_act; 16333 prev_act = prev_act->next; 16334 } 16335 } 16336 } 16337 } else { 16338 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 16339 valid = 0; 16340 16341 if (act_bmp != NULL) { 16342 if (act_bmp->w == NULL) { 16343 continue; 16344 } else { 16345 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 16346 continue; 16347 } 16348 } 16349 } 16350 sal_memset(&a_offset, 0x0, sizeof(a_offset)); 16351 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16352 /* If action is not supported on this device, go for next action */ 16353 if (BCM_E_UNAVAIL == rv) { 16354 continue; 16355 } 16356 BCM_IF_ERROR_RETURN(rv); 16357 16358 16359 action = action_arr[action_idx]; 16360 valid = 1; 16361 16362 if (valid) { 16363 int found = 0; 16364 f_act = f_ent->actions; 16365 while (f_act != NULL) { 16366 if (f_act->action == action) { 16367 found = 1; 16368 break; 16369 } 16370 f_act = f_act->next; 16371 } 16372 16373 if (f_act == NULL) { 16374 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16375 if (f_act == NULL) { 16376 return BCM_E_MEMORY; 16377 } 16378 16379 f_act->action = action; 16380 f_act->old_index = -1; 16381 } 16382 f_act->param[0] |= a_offset.value[0]; 16383 f_act->flags = _FP_ACTION_VALID; 16384 if (found == 0) { 16385 if (prev_act == NULL) { 16386 prev_act = f_act; 16387 f_ent->actions = prev_act; 16388 } else { 16389 prev_act->next = f_act; 16390 prev_act = prev_act->next; 16391 } 16392 } 16393 } 16394 } 16395 } 16396 16397 cleanup: 16398 return BCM_E_NONE; 16399 } 16400 16401 /* Recover Opaque2 Set */ 16402 int 16403 _field_wb_opaque2_set_recover(int unit, _field_entry_t *f_ent, 16404 uint32 *ebuf, 16405 _field_action_bmp_t *act_bmp) 16406 { 16407 _bcm_field_action_offset_t a_offset, a_offset1; 16408 _field_action_t *f_act = NULL, *prev_act = NULL; 16409 bcm_field_action_t action_idx; 16410 uint8 found = 0; 16411 int valid = 0, ct = 0; 16412 int valid_actions = 0; 16413 uint32 val[2] = {0}; 16414 int rv = BCM_E_NONE; 16415 bcm_field_action_t action[2]; 16416 bcm_field_action_t action_arr[] = { 16417 bcmFieldActionAssignOpaqueObject2, 16418 bcmFieldActionGbpDstIdNew, 16419 bcmFieldActionNshServiceIndex, /* Always last. Default action to be recovered. */ 16420 }; 16421 _field_stage_t *stage_fc = NULL; 16422 16423 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 16424 f_ent->group->stage_id, &stage_fc)); 16425 16426 sal_memset(&a_offset, 0x0, sizeof(a_offset)); 16427 sal_memset(&a_offset1, 0x0, sizeof(a_offset1)); 16428 16429 if (f_ent->actions != NULL) { 16430 prev_act = f_ent->actions; 16431 while (prev_act->next != NULL) { 16432 prev_act = prev_act->next; 16433 } 16434 } 16435 16436 if (_BCM_FIELD_STAGE_EXACTMATCH == f_ent->group->stage_id) { 16437 valid = 0; 16438 for (action_idx = 0; (0 == valid) && action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 16439 if (bcmFieldActionNshServiceIndex == action_arr[action_idx]) { 16440 action[0] = bcmFieldActionNshServiceIndex; 16441 ACTION_OFFSET_GET(unit, stage_fc, action[0], &a_offset1, 0); 16442 val[0] = ((1 << a_offset1.width[0]) - 1) & a_offset.value[0]; 16443 16444 action[1] = bcmFieldActionNshServicePathId; 16445 ACTION_OFFSET_GET(unit, stage_fc, action[1], &a_offset1, 0); 16446 val[1] = a_offset.value[0] >> a_offset1.offset[0]; 16447 valid_actions = 2; 16448 for (ct = 0; ct < valid_actions; ct++) { 16449 if (val[ct] != 0) { 16450 found = 0; 16451 f_act = f_ent->actions; 16452 while (f_act != NULL) { 16453 if (f_act->action == action[ct]) { 16454 if (f_act->action == bcmFieldActionNshServicePathId) { 16455 val[ct] |= f_act->param[0]; 16456 } 16457 found = 1; 16458 break; 16459 } 16460 f_act = f_act->next; 16461 } 16462 16463 if (f_act == NULL) { 16464 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16465 if (f_act == NULL) { 16466 return BCM_E_MEMORY; 16467 } 16468 } 16469 16470 valid = 1; 16471 f_act->action = action[ct]; 16472 f_act->old_index = -1; 16473 f_act->param[0] = val[ct]; 16474 f_act->flags = _FP_ACTION_VALID; 16475 if (found == 0) { 16476 if (prev_act == NULL) { 16477 prev_act = f_act; 16478 f_ent->actions = prev_act; 16479 } else { 16480 prev_act->next = f_act; 16481 prev_act = prev_act->next; 16482 } 16483 } 16484 } 16485 } 16486 } else { 16487 BCM_IF_ERROR_CLEANUP(_field_em_entry_bmp_to_action_get(unit, f_ent, 16488 action_arr[action_idx], 16489 &valid)); 16490 if (!valid) { 16491 continue; 16492 } 16493 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16494 /* If action is not supported on this device, go for next action */ 16495 if (BCM_E_UNAVAIL == rv) { 16496 continue; 16497 } 16498 BCM_IF_ERROR_RETURN(rv); 16499 16500 f_act = NULL; 16501 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16502 if (f_act == NULL) { 16503 return BCM_E_MEMORY; 16504 } 16505 f_act->action = action_arr[action_idx]; 16506 f_act->param[0] = a_offset.value[0]; 16507 f_act->old_index = -1; 16508 f_act->flags = _FP_ACTION_VALID; 16509 if (prev_act == NULL) { 16510 prev_act = f_act; 16511 f_ent->actions = prev_act; 16512 } else { 16513 prev_act->next = f_act; 16514 prev_act = prev_act->next; 16515 } 16516 } 16517 } 16518 } else { 16519 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 16520 valid = 0; 16521 if (act_bmp != NULL) { 16522 if (act_bmp->w == NULL) { 16523 continue; 16524 } else { 16525 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 16526 continue; 16527 } 16528 } 16529 } 16530 16531 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16532 /* If action is not supported on this device, go for next action */ 16533 if (BCM_E_UNAVAIL == rv) { 16534 continue; 16535 } 16536 BCM_IF_ERROR_RETURN(rv); 16537 16538 if (bcmFieldActionNshServiceIndex == action_arr[action_idx]) { 16539 action[0] = bcmFieldActionNshServiceIndex; 16540 ACTION_OFFSET_GET(unit, stage_fc, action[0], &a_offset1, 0); 16541 val[0] = ((1 << a_offset1.width[0]) - 1) & a_offset.value[0]; 16542 16543 action[1] = bcmFieldActionNshServicePathId; 16544 ACTION_OFFSET_GET(unit, stage_fc, action[1], &a_offset1, 0); 16545 val[1] = a_offset.value[0] >> a_offset1.offset[0]; 16546 valid_actions = 2; 16547 } else { 16548 action[0] = action_arr[action_idx]; 16549 val[0] = a_offset.value[0]; 16550 valid_actions = 1; 16551 } 16552 valid = 1; 16553 16554 if (valid) { 16555 for (ct = 0; ct < valid_actions; ct++) { 16556 if (val[ct] != 0) { 16557 found = 0; 16558 f_act = f_ent->actions; 16559 while (f_act != NULL) { 16560 if (f_act->action == action[ct]) { 16561 if (f_act->action == bcmFieldActionNshServicePathId) { 16562 val[ct] |= f_act->param[0]; 16563 } 16564 found = 1; 16565 break; 16566 } 16567 f_act = f_act->next; 16568 } 16569 16570 if (f_act == NULL) { 16571 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16572 if (f_act == NULL) { 16573 return BCM_E_MEMORY; 16574 } 16575 } 16576 16577 f_act->action = action[ct]; 16578 f_act->old_index = -1; 16579 f_act->param[0] = val[ct]; 16580 f_act->flags = _FP_ACTION_VALID; 16581 if (found == 0) { 16582 if (prev_act == NULL) { 16583 prev_act = f_act; 16584 f_ent->actions = prev_act; 16585 } else { 16586 prev_act->next = f_act; 16587 prev_act = prev_act->next; 16588 } 16589 } 16590 } 16591 } 16592 } 16593 } 16594 } 16595 cleanup: 16596 return BCM_E_NONE; 16597 } 16598 16599 /* Recover Opaque3 Set */ 16600 int 16601 _field_wb_opaque3_set_recover(int unit, _field_entry_t *f_ent, 16602 uint32 *ebuf, 16603 _field_action_bmp_t *act_bmp) 16604 { 16605 _bcm_field_action_offset_t a_offset; 16606 _field_action_t *f_act = NULL, *prev_act = NULL; 16607 bcm_field_action_t action_idx; 16608 int valid = 0; 16609 bcm_field_action_t action; 16610 int rv = BCM_E_NONE; 16611 bcm_field_action_t action_arr[] = { 16612 bcmFieldActionAssignChangeL2FieldsClassId, 16613 bcmFieldActionAssignOpaqueObject3, 16614 bcmFieldActionLoopbackSubtype, /* Always last. Default action to be recovered. */ 16615 }; 16616 _field_stage_t *stage_fc = NULL; 16617 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 16618 f_ent->group->stage_id, &stage_fc)); 16619 16620 if (f_ent->actions != NULL) { 16621 prev_act = f_ent->actions; 16622 while (prev_act->next != NULL) { 16623 prev_act = prev_act->next; 16624 } 16625 } 16626 16627 if (_BCM_FIELD_STAGE_EXACTMATCH == f_ent->group->stage_id) { 16628 valid = 0; 16629 for (action_idx = 0; (0 == valid) && action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 16630 if (bcmFieldActionLoopbackSubtype == action_arr[action_idx]) { 16631 sal_memset(&a_offset, 0x0, sizeof(a_offset)); 16632 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16633 /* If action is not supported on this device, go for next action */ 16634 if (BCM_E_UNAVAIL == rv) { 16635 continue; 16636 } 16637 BCM_IF_ERROR_RETURN(rv); 16638 16639 f_act = NULL; 16640 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16641 if (f_act == NULL) { 16642 return BCM_E_MEMORY; 16643 } 16644 valid = 1; 16645 f_act->action = bcmFieldActionLoopbackSubtype; 16646 f_act->param[0] = bcmFieldLoopbackSubtypeIfa; 16647 f_act->old_index = -1; 16648 f_act->flags = _FP_ACTION_VALID; 16649 if (prev_act == NULL) { 16650 prev_act = f_act; 16651 f_ent->actions = prev_act; 16652 } else { 16653 prev_act->next = f_act; 16654 prev_act = prev_act->next; 16655 } 16656 } else { 16657 BCM_IF_ERROR_CLEANUP(_field_em_entry_bmp_to_action_get(unit, f_ent, 16658 action_arr[action_idx], 16659 &valid)); 16660 if (!valid) { 16661 continue; 16662 } 16663 sal_memset(&a_offset, 0x0, sizeof(a_offset)); 16664 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16665 /* If action is not supported on this device, go for next action */ 16666 if (BCM_E_UNAVAIL == rv) { 16667 continue; 16668 } 16669 BCM_IF_ERROR_RETURN(rv); 16670 16671 f_act = NULL; 16672 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16673 if (f_act == NULL) { 16674 return BCM_E_MEMORY; 16675 } 16676 f_act->action = action_arr[action_idx]; 16677 f_act->param[0] = a_offset.value[0]; 16678 f_act->old_index = -1; 16679 f_act->flags = _FP_ACTION_VALID; 16680 if (prev_act == NULL) { 16681 prev_act = f_act; 16682 f_ent->actions = prev_act; 16683 } else { 16684 prev_act->next = f_act; 16685 prev_act = prev_act->next; 16686 } 16687 } 16688 } 16689 } else { 16690 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 16691 valid = 0; 16692 16693 if (act_bmp != NULL) { 16694 if (act_bmp->w == NULL) { 16695 continue; 16696 } else { 16697 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 16698 continue; 16699 } 16700 } 16701 } 16702 sal_memset(&a_offset, 0x0, sizeof(a_offset)); 16703 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16704 /* If action is not supported on this device, go for next action */ 16705 if (BCM_E_UNAVAIL == rv) { 16706 continue; 16707 } 16708 BCM_IF_ERROR_RETURN(rv); 16709 16710 action = action_arr[action_idx]; 16711 valid = 1; 16712 16713 if (valid) { 16714 int found = 0; 16715 f_act = f_ent->actions; 16716 while (f_act != NULL) { 16717 if (f_act->action == action) { 16718 found = 1; 16719 break; 16720 } 16721 f_act = f_act->next; 16722 } 16723 16724 if (f_act == NULL) { 16725 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16726 if (f_act == NULL) { 16727 return BCM_E_MEMORY; 16728 } 16729 16730 f_act->action = action; 16731 f_act->old_index = -1; 16732 } 16733 if (bcmFieldActionLoopbackSubtype == f_act->action) { 16734 f_act->param[0] = bcmFieldLoopbackSubtypeIfa; 16735 } else { 16736 f_act->param[0] |= a_offset.value[0]; 16737 } 16738 f_act->flags = _FP_ACTION_VALID; 16739 if (found == 0) { 16740 if (prev_act == NULL) { 16741 prev_act = f_act; 16742 f_ent->actions = prev_act; 16743 } else { 16744 prev_act->next = f_act; 16745 prev_act = prev_act->next; 16746 } 16747 } 16748 } 16749 } 16750 } 16751 16752 cleanup: 16753 return BCM_E_NONE; 16754 } 16755 16756 /* Recover Opaque4 Set */ 16757 int 16758 _field_wb_opaque4_set_recover(int unit, _field_entry_t *f_ent, 16759 uint32 *ebuf, 16760 _field_action_bmp_t *act_bmp) 16761 { 16762 _bcm_field_action_offset_t a_offset; 16763 _field_action_t *f_act = NULL, *prev_act = NULL; 16764 bcm_field_action_t action_idx; 16765 int hw_index = 0; 16766 int rv = BCM_E_NONE; 16767 bcm_field_action_t action_arr[] = { 16768 bcmFieldActionAssignOpaqueObject4, 16769 _bcmFieldActionOpaque4, 16770 }; 16771 16772 16773 if (f_ent->actions != NULL) { 16774 prev_act = f_ent->actions; 16775 while (prev_act->next != NULL) { 16776 prev_act = prev_act->next; 16777 } 16778 } 16779 16780 16781 for (action_idx = 0; action_idx < (sizeof(action_arr)/sizeof(int)); action_idx++) { 16782 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 16783 /* If action is not supported on this device, go for next action */ 16784 if (BCM_E_UNAVAIL == rv) { 16785 continue; 16786 } 16787 BCM_IF_ERROR_RETURN(rv); 16788 16789 if (bcmFieldActionAssignOpaqueObject4 == action_arr[action_idx]) { 16790 if (act_bmp != NULL) { 16791 if (act_bmp->w == NULL) { 16792 continue; 16793 } else { 16794 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 16795 continue; 16796 } 16797 } 16798 } 16799 16800 f_act = NULL; 16801 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP WB PDD Alloc"); 16802 if (f_act == NULL) { 16803 return BCM_E_MEMORY; 16804 } 16805 f_act->action = action_arr[action_idx]; 16806 f_act->param[0] = a_offset.value[0]; 16807 f_act->hw_index = hw_index; 16808 f_act->old_index = -1; 16809 f_act->flags = _FP_ACTION_VALID; 16810 if (prev_act == NULL) { 16811 prev_act = f_act; 16812 f_ent->actions = prev_act; 16813 } else { 16814 prev_act->next = f_act; 16815 prev_act = prev_act->next; 16816 } 16817 16818 return BCM_E_NONE; 16819 } 16820 } 16821 return BCM_E_NONE; 16822 } 16823 16824 16825 /* 16826 * Function: 16827 * _field_wb_em_actions_recover 16828 * Purpose: 16829 * Recover all non-qos actions for a particular entry. 16830 * This profile may be pointed to, by many entries. so, we 16831 * DMA the entire table and store the pointers in statically 16832 * declared buffer. Corresponding free function is called 16833 * at the end of em reinit. 16834 * 16835 * Parameters: 16836 * unit - (IN) StrataSwitch unit #. 16837 * f_ent - (IN) pointer to entry structure which refers 16838 * this qos profile. 16839 * act_idx - (IN) action profile index (obtained from ACTION_PROFILE_IDf 16840 * from exact match tables) 16841 * Returns: 16842 * BCM_E_XXX 16843 */ 16844 int 16845 _field_wb_em_actions_recover(int unit, _field_entry_t *f_ent, int act_idx, 16846 uint32 *act_data) 16847 { 16848 static soc_mem_t mem = INVALIDm; 16849 int pipe = 0; 16850 _field_stage_t *stage_fc = NULL; 16851 uint32 *e_buf = NULL; 16852 int index_min = 0, index_max = 0; 16853 int rv = 0; 16854 _field_control_t *fc; /* Field control structure. */ 16855 16856 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 16857 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 16858 16859 /* Get field control structure. */ 16860 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 16861 16862 if (act_profile_buf[0] == NULL) { 16863 16864 for (pipe = 0; pipe < stage_fc->num_pipes; pipe++) { 16865 if (!(fc->pipe_map & (1 << pipe))) { 16866 continue; 16867 } 16868 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 16869 mem = EXACT_MATCH_ACTION_PROFILEm; 16870 } else { 16871 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 16872 EXACT_MATCH_ACTION_PROFILEm, 16873 pipe, &mem)); 16874 } 16875 act_profile_buf[pipe] = soc_cm_salloc(unit, 16876 SOC_MEM_TABLE_BYTES(unit, mem), 16877 "act Profile table buffer"); 16878 16879 index_min = soc_mem_index_min(unit, mem); 16880 index_max = soc_mem_index_max(unit, mem); 16881 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 16882 index_min, index_max, act_profile_buf[pipe]); 16883 BCM_IF_ERROR_RETURN(rv); 16884 16885 } 16886 } 16887 pipe = f_ent->group->instance; 16888 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 16889 mem = EXACT_MATCH_ACTION_PROFILEm; 16890 } else { 16891 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 16892 EXACT_MATCH_ACTION_PROFILEm, 16893 pipe, &mem)); 16894 } 16895 16896 e_buf = soc_mem_table_idx_to_pointer(unit, mem, 16897 uint32 *, act_profile_buf[pipe], act_idx); 16898 _field_wb_action_profile_parse(unit, f_ent, e_buf, act_data, NULL); 16899 16900 return BCM_E_NONE; 16901 } 16902 16903 int 16904 _field_em_class_action_add(int unit, _field_entry_t *f_ent, int class_id) { 16905 _field_action_t *f_act = NULL; 16906 16907 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "class id action"); 16908 if (f_act == NULL) { 16909 return BCM_E_MEMORY; 16910 } 16911 16912 f_act->action = bcmFieldActionExactMatchClassId; 16913 f_act->flags = _FP_ACTION_VALID; 16914 f_act->param[0] = class_id; 16915 f_act->next = f_ent->actions; 16916 f_ent->actions = f_act; 16917 16918 return BCM_E_NONE; 16919 } 16920 int 16921 _field_wb_em_defentry_recover(int unit, _field_entry_t *f_ent, soc_mem_t mem) { 16922 int idx = 0; 16923 uint32 *bufp; 16924 uint32 act_data[2] = {0}; 16925 int qos_idx = 0, act_idx = 0, class_id = 0; 16926 exact_match_default_policy_entry_t ebuf; 16927 _field_group_t *fg = NULL; 16928 _field_stage_t *stage_fc = NULL; 16929 soc_profile_mem_t *action_profile; 16930 16931 idx = f_ent->group->ext_codes[0].keygen_index; 16932 bufp = (uint32 *)&ebuf; 16933 sal_memcpy(bufp, soc_mem_entry_null(unit, mem), 16934 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 16935 16936 16937 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx, bufp)); 16938 16939 16940 soc_mem_field_get(unit, mem, bufp, 16941 (soc_feature(unit, soc_feature_td3_style_fp)) ? POLICY_DATAf : 16942 ACTION_DATAf, act_data); 16943 qos_idx = soc_mem_field32_get(unit, mem, bufp, QOS_PROFILE_IDf); 16944 act_idx = soc_mem_field32_get(unit, mem, bufp, 16945 soc_feature(unit, soc_feature_td3_style_fp) ? DATA_TYPEf : 16946 ACTION_PROFILE_IDf); 16947 class_id = soc_mem_field32_get(unit, mem, bufp, EXACT_MATCH_CLASS_IDf); 16948 16949 _field_wb_qos_actions_recover(unit, f_ent, qos_idx); 16950 _field_wb_em_actions_recover(unit, f_ent, act_idx, act_data); 16951 16952 16953 if (class_id) { 16954 _field_em_class_action_add(unit, f_ent, class_id); 16955 } 16956 fg = f_ent->group; 16957 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 16958 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 16959 action_profile = &stage_fc->action_profile[fg->instance]; 16960 SOC_PROFILE_MEM_REFERENCE(unit, action_profile, 16961 act_idx, 1); 16962 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, action_profile, 16963 act_idx, 1); 16964 return BCM_E_NONE; 16965 } 16966 /* 16967 * Function: 16968 * _field_em_group_entries_recover 16969 * Purpose: 16970 * Recover all entries for a given exactmatch match group 16971 * For each entry, entry_id, flags, (flags for 2nd part in 16972 * case of double wide group), hw_index are stored in order 16973 * Read EXACT_MATCH_2 or EXACT_MATCH_4 based on group mode, 16974 * parse the entry, and populate entry structe, link it to 16975 * group slices. IN case of double wide, as there are no real 16976 * slices(same memory is used in different views), both are 16977 * linked to the same slice. Read action profile and qos_action 16978 * profile pointer and call corresponding functions to retrive 16979 * action data. 16980 * 16981 * Parameters: 16982 * unit - (IN) StrataSwitch unit #. 16983 * fg - (IN) pointer to group structure whose entries 16984 * have to be recovered. 16985 * Returns: 16986 * BCM_E_XXX 16987 */ 16988 int 16989 _field_em_group_entries_recover(int unit, _field_group_t *fg) 16990 { 16991 _field_tlv_t tlv; 16992 int i = 0; 16993 _field_control_t *fc = NULL; 16994 uint8 *ptr = NULL; 16995 uint32 *pos = NULL; 16996 uint32 *value = NULL; 16997 _field_entry_t *f_ent = NULL, *f_ent_part = NULL; 16998 int hw_index = -1, idx = 0; 16999 soc_mem_t mem = INVALIDm; /* Memory Identifier. */ 17000 soc_mem_t def_policy_mem = INVALIDm; /* Memory Identifier. */ 17001 _field_stage_t *stage_fc = NULL; 17002 uint32 tbuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 17003 /* Temp Buffer One. */ 17004 uint32 tbuftemp[SOC_MAX_MEM_FIELD_WORDS] = {0}; 17005 /* Temp Buffer Two. */ 17006 uint32 tbuftemp2[5] = {0}; /* Temp Buffer Three. */ 17007 uint32 *bufp = NULL; /* Hardware Buffer Ptr. */ 17008 exact_match_2_entry_t ebuf_nar; /* Narrow Entry Buffer. */ 17009 exact_match_4_entry_t ebuf_wide; /* Wide Entry Buffer. */ 17010 soc_profile_mem_t *action_profile;/* action profile memory */ 17011 int rv = 0, parts_count = 0; 17012 int qos_idx = 0; 17013 int act_idx = 0, class_id = 0; 17014 uint32 act_data[2] = {0}; 17015 char *em_buffer = NULL; 17016 17017 soc_field_t policy_data_128 = INVALIDf, policy_data_160=INVALIDf, policy_data_320=INVALIDf; 17018 soc_field_t act_prof_id_128=INVALIDf, act_prof_id_160=INVALIDf, act_prof_id_320=INVALIDf; 17019 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 17020 if ((soc_feature(unit, soc_feature_td3_style_fp)) 17021 || (soc_feature(unit, soc_feature_th3_style_fp))) { 17022 policy_data_128 = MODE128__POLICY_DATAf; 17023 policy_data_160 = MODE160__POLICY_DATAf; 17024 policy_data_320 = MODE320__POLICY_DATAf; 17025 act_prof_id_128 = MODE128__DATA_TYPEf; 17026 act_prof_id_160 = MODE160__DATA_TYPEf; 17027 act_prof_id_320 = MODE320__DATA_TYPEf; 17028 } else 17029 #endif 17030 { 17031 policy_data_128 = MODE128__ACTION_DATAf; 17032 policy_data_160 = MODE160__ACTION_DATAf; 17033 policy_data_320 = MODE320__ACTION_DATAf; 17034 act_prof_id_128 = MODE128__ACTION_PROFILE_IDf; 17035 act_prof_id_160 = MODE160__ACTION_PROFILE_IDf; 17036 act_prof_id_320 = MODE320__ACTION_PROFILE_IDf; 17037 } 17038 17039 tlv.value = NULL; 17040 TLV_INIT(tlv); 17041 WB_FIELD_CONTROL_GET(fc, ptr, pos); 17042 if (fg->group_status.entry_count == 0) { 17043 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 17044 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 17045 action_profile = &stage_fc->action_profile[fg->instance]; 17046 for (i =0; i < MAX_ACT_PROF_ENTRIES_PER_GROUP; i++) { 17047 if (-1 != fg->action_profile_idx[i]) { 17048 SOC_PROFILE_MEM_REFERENCE(unit, action_profile, 17049 fg->action_profile_idx[i], 1); 17050 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, action_profile, 17051 fg->action_profile_idx[i], 1); 17052 } 17053 } 17054 return BCM_E_NONE; 17055 } 17056 /* coverity[no_write_call : FALSE] */ 17057 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv, ptr, pos)); 17058 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 17059 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 17060 17061 17062 if (tlv.type != _bcmFieldInternalEMEntryarr) { 17063 sal_free(tlv.value); 17064 return BCM_E_INTERNAL; 17065 } 17066 /* Get Hardware Buffer Pointer and memory identifier. */ 17067 if ((fg->em_mode == _FieldExactMatchMode128) || 17068 (fg->em_mode == _FieldExactMatchMode160)) { 17069 bufp = (uint32 *)&ebuf_nar; 17070 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 17071 mem = EXACT_MATCH_2m; 17072 def_policy_mem = EXACT_MATCH_DEFAULT_POLICYm; 17073 } else { 17074 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 17075 EXACT_MATCH_2m, 17076 fg->instance, &mem)); 17077 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 17078 EXACT_MATCH_DEFAULT_POLICYm, 17079 fg->instance, &def_policy_mem)); 17080 } 17081 } else { 17082 bufp = (uint32 *)&ebuf_wide; 17083 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 17084 mem = EXACT_MATCH_4m; 17085 def_policy_mem = EXACT_MATCH_DEFAULT_POLICYm; 17086 } else { 17087 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 17088 EXACT_MATCH_4m, 17089 fg->instance, &mem)); 17090 BCM_IF_ERROR_CLEANUP(_bcm_field_mem_instance_get(unit, 17091 EXACT_MATCH_DEFAULT_POLICYm, 17092 fg->instance, &def_policy_mem)); 17093 } 17094 } 17095 em_buffer = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), 17096 "em table buffer"); 17097 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 17098 soc_mem_index_min(unit, mem), 17099 soc_mem_index_max(unit, mem), 17100 em_buffer); 17101 BCM_IF_ERROR_RETURN(rv); 17102 17103 rv = _bcm_field_entry_tcam_parts_count(unit, fg->stage_id, 17104 fg->flags, &parts_count); 17105 BCM_IF_ERROR_RETURN(rv); 17106 17107 17108 value = tlv.value; 17109 while (i < tlv.length) { 17110 if (fg->em_mode == _FieldExactMatchMode320) { 17111 f_ent = NULL; 17112 f_ent_part = NULL; 17113 _FP_XGS3_ALLOC(f_ent, 2 * sizeof(_field_entry_t), "em entry"); 17114 if (f_ent == NULL) { 17115 rv = BCM_E_MEMORY; 17116 goto cleanup; 17117 } 17118 17119 17120 f_ent_part = f_ent+1; 17121 f_ent->eid = value[i++]; 17122 f_ent_part->eid = f_ent->eid; 17123 /* _bcm_field_th_qual_tcam_key_mask_get allocates memory for 17124 tcam.key and tcam.mask, also populates tcam.key_size. 17125 This function also checks for group, and if installed flag 17126 is set, tries to read hw. so flags should be populated later. 17127 we save tcam.key, tcam.mask, and tcam.key_hw for each em entry. 17128 tcam.key may change in software but tcam.key_hw changes only 17129 when entry is written to hardware. */ 17130 f_ent->group = fg; 17131 f_ent->fs = fg->slices; 17132 f_ent->slice_idx = -1; 17133 f_ent_part->group = fg; 17134 f_ent_part->fs = fg->slices; 17135 f_ent_part->slice_idx = -1; 17136 fg->entry_arr[idx++] = f_ent; 17137 _bcm_field_th_qual_tcam_key_mask_get(unit, f_ent, &f_ent->tcam); 17138 _bcm_field_th_qual_tcam_key_mask_get(unit, f_ent_part, 17139 &f_ent_part->tcam); 17140 17141 f_ent->flags = value[i++]; 17142 f_ent_part->flags = value[i++]; 17143 _FP_XGS3_ALLOC(f_ent->tcam.key_hw, f_ent->tcam.key_size, 17144 "em entry key"); 17145 if (f_ent->tcam.key_hw == NULL) { 17146 rv = BCM_E_MEMORY; 17147 goto cleanup; 17148 } 17149 17150 _FP_XGS3_ALLOC(f_ent_part->tcam.key_hw, f_ent->tcam.key_size, 17151 "em entry key"); 17152 if (f_ent_part->tcam.key_hw == NULL) { 17153 rv = BCM_E_MEMORY; 17154 goto cleanup; 17155 } 17156 17157 if (value[i] != -1) { 17158 f_ent->statistic.sid = value[i]; 17159 f_ent->statistic.flags |= _FP_ENTRY_STAT_VALID; 17160 } 17161 i += 1; 17162 if (value[i] != -1) { 17163 f_ent->policer[0].pid = value[i]; 17164 f_ent->policer[0].flags |= 17165 _FP_POLICER_INSTALLED | _FP_POLICER_VALID; 17166 } 17167 17168 rv = _field_entry_recover_policer_actual_hw_rates(unit, f_ent); 17169 BCM_IF_ERROR_CLEANUP(rv); 17170 17171 i += 1; 17172 hw_index = value[i++]; 17173 if (f_ent->flags & _FP_ENTRY_EXACT_MATCH_GROUP_DEFAULT) { 17174 _field_wb_em_defentry_recover(unit, f_ent, def_policy_mem); 17175 continue; 17176 } 17177 if (hw_index != -1) { 17178 bufp = soc_mem_table_idx_to_pointer(unit, mem, uint32 *, 17179 em_buffer, hw_index); 17180 if (SOC_IS_TOMAHAWKX(unit)) { 17181 if (soc_feature(unit, soc_feature_th3_style_fp)) { 17182 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_0_ONLYf, tbuf); 17183 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_1_ONLYf, 17184 tbuftemp); 17185 rv = _bcm_field_qual_partial_data_get(tbuftemp, 0, 17186 (EM_ENTRY_PART0_KEYSIZE - 17187 TH3_EM_MODE320_KEY_PART0_SIZE), 17188 tbuftemp2); 17189 BCM_IF_ERROR_CLEANUP(rv); 17190 rv = _bcm_field_th_val_set(tbuf, tbuftemp2, TH3_EM_MODE320_KEY_PART0_SIZE, 17191 (EM_ENTRY_PART0_KEYSIZE - 17192 TH3_EM_MODE320_KEY_PART0_SIZE)); 17193 BCM_IF_ERROR_CLEANUP(rv); 17194 sal_memcpy(f_ent->tcam.key_hw, tbuf, f_ent->tcam.key_size); 17195 sal_memcpy(f_ent->tcam.key, tbuf, f_ent->tcam.key_size); 17196 rv = _bcm_field_th_val_get(tbuftemp, f_ent_part->tcam.key_hw, 17197 (EM_ENTRY_PART0_KEYSIZE - 17198 TH3_EM_MODE320_KEY_PART0_SIZE), 17199 (TH3_EM_MODE320_KEY_PART1_SIZE - 17200 (EM_ENTRY_PART0_KEYSIZE - 17201 TH3_EM_MODE320_KEY_PART0_SIZE))); 17202 BCM_IF_ERROR_CLEANUP(rv); 17203 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_2_ONLYf, tbuf); 17204 rv = _bcm_field_th_val_set(f_ent_part->tcam.key_hw, tbuf, 17205 (TH3_EM_MODE320_KEY_PART1_SIZE - 17206 (EM_ENTRY_PART0_KEYSIZE - 17207 TH3_EM_MODE320_KEY_PART0_SIZE)), 17208 TH3_EM_MODE320_KEY_PART2_SIZE); 17209 BCM_IF_ERROR_CLEANUP(rv); 17210 sal_memcpy(f_ent_part->tcam.key, f_ent_part->tcam.key_hw, 17211 f_ent->tcam.key_size); 17212 17213 } else { 17214 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_0_ONLYf, tbuf); 17215 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_1_ONLYf, 17216 tbuftemp); 17217 /* using tbuftemp2 to copy the first 59 bits of tbuftemp to 17218 tbuf. directly copying the data from tbuftemp to tbuf is 17219 failing as th_val_set function will return E_PARAM error 17220 if input buffer has valid bits after the 59th bit in it */ 17221 rv = _bcm_field_qual_partial_data_get(tbuftemp, 0, 17222 (EM_ENTRY_PART0_KEYSIZE - 17223 EM_MODE320_KEY_PART0_SIZE), 17224 tbuftemp2); 17225 BCM_IF_ERROR_CLEANUP(rv); 17226 rv = _bcm_field_th_val_set(tbuf, tbuftemp2, EM_MODE320_KEY_PART0_SIZE, 17227 (EM_ENTRY_PART0_KEYSIZE - 17228 EM_MODE320_KEY_PART0_SIZE)); 17229 BCM_IF_ERROR_CLEANUP(rv); 17230 sal_memcpy(f_ent->tcam.key_hw, tbuf, f_ent->tcam.key_size); 17231 sal_memcpy(f_ent->tcam.key, tbuf, f_ent->tcam.key_size); 17232 rv = _bcm_field_th_val_get(tbuftemp, f_ent_part->tcam.key_hw, 17233 (EM_ENTRY_PART0_KEYSIZE - 17234 EM_MODE320_KEY_PART0_SIZE), 17235 (EM_MODE320_KEY_PART1_SIZE - 17236 (EM_ENTRY_PART0_KEYSIZE - 17237 EM_MODE320_KEY_PART0_SIZE))); 17238 BCM_IF_ERROR_CLEANUP(rv); 17239 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_2_ONLYf, tbuf); 17240 rv = _bcm_field_th_val_set(f_ent_part->tcam.key_hw, tbuf, 17241 (EM_MODE320_KEY_PART1_SIZE - 17242 (EM_ENTRY_PART0_KEYSIZE - 17243 EM_MODE320_KEY_PART0_SIZE)), 17244 EM_MODE320_KEY_PART2_SIZE); 17245 BCM_IF_ERROR_CLEANUP(rv); 17246 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_3_ONLYf, tbuf); 17247 rv = _bcm_field_th_val_set(f_ent_part->tcam.key_hw, tbuf, 17248 EM_MODE320_KEY_PART2_SIZE + 17249 (EM_MODE320_KEY_PART1_SIZE - 17250 (EM_ENTRY_PART0_KEYSIZE - 17251 EM_MODE320_KEY_PART0_SIZE)), 17252 EM_MODE320_KEY_PART3_SIZE); 17253 BCM_IF_ERROR_CLEANUP(rv); 17254 sal_memcpy(f_ent_part->tcam.key, f_ent_part->tcam.key_hw, 17255 f_ent->tcam.key_size); 17256 } 17257 } else { 17258 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_0_ONLYf, tbuf); 17259 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_1_ONLYf, 17260 tbuftemp); 17261 rv = _bcm_field_qual_partial_data_get(tbuftemp, 0, 17262 (EM_ENTRY_PART0_KEYSIZE - 17263 TD3_EM_MODE320_KEY_PART0_SIZE), 17264 tbuftemp2); 17265 BCM_IF_ERROR_CLEANUP(rv); 17266 rv = _bcm_field_th_val_set(tbuf, tbuftemp2, TD3_EM_MODE320_KEY_PART0_SIZE, 17267 (EM_ENTRY_PART0_KEYSIZE - 17268 TD3_EM_MODE320_KEY_PART0_SIZE)); 17269 BCM_IF_ERROR_CLEANUP(rv); 17270 sal_memcpy(f_ent->tcam.key_hw, tbuf, f_ent->tcam.key_size); 17271 sal_memcpy(f_ent->tcam.key, tbuf, f_ent->tcam.key_size); 17272 rv = _bcm_field_th_val_get(tbuftemp, f_ent_part->tcam.key_hw, 17273 (EM_ENTRY_PART0_KEYSIZE - 17274 TD3_EM_MODE320_KEY_PART0_SIZE), 17275 (TD3_EM_MODE320_KEY_PART1_SIZE - 17276 (EM_ENTRY_PART0_KEYSIZE - 17277 TD3_EM_MODE320_KEY_PART0_SIZE))); 17278 BCM_IF_ERROR_CLEANUP(rv); 17279 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_2_ONLYf, tbuf); 17280 rv = _bcm_field_th_val_set(f_ent_part->tcam.key_hw, tbuf, 17281 (TD3_EM_MODE320_KEY_PART1_SIZE - 17282 (EM_ENTRY_PART0_KEYSIZE - 17283 TD3_EM_MODE320_KEY_PART0_SIZE)), 17284 TD3_EM_MODE320_KEY_PART2_SIZE); 17285 BCM_IF_ERROR_CLEANUP(rv); 17286 soc_mem_field_get(unit, mem, bufp, MODE320__KEY_3_ONLYf, tbuf); 17287 rv = _bcm_field_th_val_set(f_ent_part->tcam.key_hw, tbuf, 17288 TD3_EM_MODE320_KEY_PART2_SIZE + 17289 (TD3_EM_MODE320_KEY_PART1_SIZE - 17290 (EM_ENTRY_PART0_KEYSIZE - 17291 TD3_EM_MODE320_KEY_PART0_SIZE)), 17292 TD3_EM_MODE320_KEY_PART3_SIZE); 17293 BCM_IF_ERROR_CLEANUP(rv); 17294 sal_memcpy(f_ent_part->tcam.key, f_ent_part->tcam.key_hw, 17295 f_ent->tcam.key_size); 17296 } 17297 soc_mem_field_get(unit, mem, bufp, policy_data_320, 17298 act_data); 17299 qos_idx = soc_mem_field32_get(unit, mem, bufp, 17300 MODE320__QOS_PROFILE_IDf); 17301 act_idx = soc_mem_field32_get(unit, mem, bufp, 17302 act_prof_id_320); 17303 class_id = soc_mem_field32_get(unit, mem, bufp, 17304 MODE320__EXACT_MATCH_CLASS_IDf); 17305 fg->action_profile_idx[0] = act_idx; 17306 if (class_id) { 17307 _field_em_class_action_add(unit, f_ent, class_id); 17308 } 17309 } else { 17310 continue; 17311 } 17312 /* EM match doesnot support bit masking */ 17313 sal_memset(f_ent->tcam.mask, 0xff, f_ent->tcam.key_size); 17314 sal_memset(f_ent_part->tcam.mask, 0xff, f_ent->tcam.key_size); 17315 _field_wb_qos_actions_recover(unit, f_ent, qos_idx); 17316 _field_wb_em_actions_recover(unit, f_ent, act_idx, act_data); 17317 continue; 17318 } 17319 f_ent = NULL; 17320 _FP_XGS3_ALLOC(f_ent, sizeof(_field_entry_t), "em entry"); 17321 if (f_ent == NULL) { 17322 rv = BCM_E_MEMORY; 17323 goto cleanup; 17324 } 17325 17326 f_ent->eid = value[i++]; 17327 /* similar order is followed. Check groupmode320 for details */ 17328 f_ent->group = fg; 17329 f_ent->fs = fg->slices; 17330 f_ent->slice_idx = -1; 17331 fg->entry_arr[idx++] = f_ent; 17332 _bcm_field_th_qual_tcam_key_mask_get(unit, f_ent, &f_ent->tcam); 17333 f_ent->flags = value[i++]; 17334 if (value[i] != -1) { 17335 f_ent->statistic.sid = value[i]; 17336 f_ent->statistic.flags |= _FP_ENTRY_STAT_VALID; 17337 } 17338 i += 1; 17339 if (value[i] != -1) { 17340 f_ent->policer[0].pid = value[i]; 17341 f_ent->policer[0].flags |= 17342 _FP_POLICER_INSTALLED | _FP_POLICER_VALID; 17343 } 17344 17345 rv = _field_entry_recover_policer_actual_hw_rates(unit, f_ent); 17346 BCM_IF_ERROR_CLEANUP(rv); 17347 17348 i += 1; 17349 hw_index = value[i++]; 17350 if (f_ent->flags & _FP_ENTRY_EXACT_MATCH_GROUP_DEFAULT) { 17351 _field_wb_em_defentry_recover(unit, f_ent, def_policy_mem); 17352 continue; 17353 } 17354 if (hw_index != -1) { 17355 bufp = soc_mem_table_idx_to_pointer(unit, mem, uint32 *, 17356 em_buffer, hw_index); 17357 if (fg->em_mode == _FieldExactMatchMode128) { 17358 soc_mem_field_get(unit, mem, bufp, MODE128__KEY_0_ONLYf, tbuf); 17359 soc_mem_field_get(unit, mem, bufp, MODE128__KEY_1_ONLYf, tbuftemp); 17360 if (SOC_IS_TOMAHAWKX(unit)) { 17361 if (soc_feature(unit, soc_feature_th3_style_fp)) { 17362 rv = _bcm_field_th_val_set(tbuf, tbuftemp, TH3_EM_MODE128_KEY_PART0_SIZE, 17363 TH3_EM_MODE128_KEY_PART1_SIZE); 17364 } else { 17365 rv = _bcm_field_th_val_set(tbuf, tbuftemp, EM_MODE128_KEY_PART0_SIZE, 17366 EM_MODE128_KEY_PART1_SIZE); 17367 } 17368 } else { 17369 rv = _bcm_field_th_val_set(tbuf, tbuftemp, TD3_EM_MODE128_KEY_PART0_SIZE, 17370 TD3_EM_MODE128_KEY_PART1_SIZE); 17371 } 17372 BCM_IF_ERROR_CLEANUP(rv); 17373 soc_mem_field_get(unit, mem, bufp, policy_data_128, act_data); 17374 qos_idx = soc_mem_field32_get(unit, mem, bufp, 17375 MODE128__QOS_PROFILE_IDf); 17376 act_idx = soc_mem_field32_get(unit, mem, bufp, 17377 act_prof_id_128); 17378 class_id = soc_mem_field32_get(unit, mem, bufp, 17379 MODE128__EXACT_MATCH_CLASS_IDf); 17380 fg->action_profile_idx[0] = act_idx; 17381 } else if (fg->em_mode == _FieldExactMatchMode160) { 17382 soc_mem_field_get(unit, mem, bufp, MODE160__KEY_0_ONLYf, tbuf); 17383 soc_mem_field_get(unit, mem, bufp, MODE160__KEY_1_ONLYf, tbuftemp); 17384 if (SOC_IS_TOMAHAWKX(unit)) { 17385 if (soc_feature(unit, soc_feature_th3_style_fp)) { 17386 rv = _bcm_field_th_val_set(tbuf, tbuftemp, TH3_EM_MODE160_KEY_PART0_SIZE, 17387 TH3_EM_MODE160_KEY_PART1_SIZE); 17388 } else { 17389 rv = _bcm_field_th_val_set(tbuf, tbuftemp, EM_MODE160_KEY_PART0_SIZE, 17390 EM_MODE160_KEY_PART1_SIZE); 17391 } 17392 } else { 17393 rv = _bcm_field_th_val_set(tbuf, tbuftemp, TD3_EM_MODE160_KEY_PART0_SIZE, 17394 TD3_EM_MODE160_KEY_PART1_SIZE); 17395 } 17396 BCM_IF_ERROR_CLEANUP(rv); 17397 soc_mem_field_get(unit, mem, bufp, policy_data_160, 17398 act_data); 17399 qos_idx = soc_mem_field32_get(unit, mem, bufp, 17400 MODE160__QOS_PROFILE_IDf); 17401 act_idx = soc_mem_field32_get(unit, mem, bufp, 17402 act_prof_id_160); 17403 class_id = soc_mem_field32_get(unit, mem, bufp, 17404 MODE160__EXACT_MATCH_CLASS_IDf); 17405 fg->action_profile_idx[0] = act_idx; 17406 } 17407 } else { 17408 continue; 17409 } 17410 if (class_id) { 17411 _field_em_class_action_add(unit, f_ent, class_id); 17412 } 17413 _FP_XGS3_ALLOC(f_ent->tcam.key_hw, 17414 f_ent->tcam.key_size, "em entry key"); 17415 17416 if (f_ent->tcam.key_hw == NULL) { 17417 rv = BCM_E_MEMORY; 17418 goto cleanup; 17419 } 17420 17421 sal_memcpy(f_ent->tcam.key_hw, tbuf, f_ent->tcam.key_size); 17422 sal_memcpy(f_ent->tcam.key, tbuf, f_ent->tcam.key_size); 17423 sal_memset(f_ent->tcam.mask, 0xff, f_ent->tcam.key_size); 17424 _field_wb_qos_actions_recover(unit, f_ent, qos_idx); 17425 _field_wb_em_actions_recover(unit, f_ent, act_idx, act_data); 17426 17427 17428 } 17429 17430 action_profile = &stage_fc->action_profile[fg->instance]; 17431 for (i =0; i < MAX_ACT_PROF_ENTRIES_PER_GROUP; i++) { 17432 if (-1 != fg->action_profile_idx[i]) { 17433 SOC_PROFILE_MEM_REFERENCE(unit, action_profile, 17434 fg->action_profile_idx[i], 1); 17435 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, action_profile, 17436 fg->action_profile_idx[i], 1); 17437 } 17438 } 17439 17440 soc_cm_sfree(unit, em_buffer); 17441 return BCM_E_NONE; 17442 17443 cleanup: 17444 TLV_INIT(tlv); 17445 17446 if (f_ent != NULL) { 17447 if (f_ent->tcam.key_hw != NULL) { 17448 sal_free(f_ent->tcam.key_hw); 17449 f_ent->tcam.key_hw = NULL; 17450 } 17451 if ((f_ent+1)->tcam.key_hw != NULL) { 17452 sal_free((f_ent+1)->tcam.key_hw); 17453 (f_ent+1)->tcam.key_hw = NULL; 17454 } 17455 sal_free(f_ent); 17456 f_ent = NULL; 17457 } 17458 return rv; 17459 } 17460 17461 /* 17462 * Function: 17463 * _bcm_field_th_stage_mixed_src_class_mode_recover 17464 * Purpose: 17465 * Recover Mixed Src Class mode for Ingress and exact match stage 17466 * 17467 * Parameters: 17468 * unit - (IN) StrataSwitch unit #. 17469 * stage_fc - (IN) pointer to stage structure 17470 * Returns: 17471 * BCM_E_XXX 17472 */ 17473 int _bcm_field_th_stage_mixed_src_class_mode_recover(int unit, 17474 _field_stage_t *stage_fc) 17475 { 17476 soc_reg_t lt_select_config; 17477 uint32 mixed_src_class_mode; 17478 uint8 pipe_idx = 0; 17479 _field_control_t *fc; /* Field control structure. */ 17480 17481 /* Get field control structure. */ 17482 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 17483 17484 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 17485 if (stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 17486 lt_select_config = IFP_LOGICAL_TABLE_SELECT_CONFIGr; 17487 } else if (stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 17488 lt_select_config = EXACT_MATCH_LOGICAL_TABLE_SELECT_CONFIGr; 17489 } else { /* stage_fc->stage_id == _BCM_FIELD_STAGE_FLOWTRACKER */ 17490 lt_select_config = BROADSCAN_LOGICAL_TABLE_SELECT_CONFIGr; 17491 } 17492 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, lt_select_config, 17493 REG_PORT_ANY, 0, &mixed_src_class_mode)); 17494 stage_fc->field_src_class_mode[pipe_idx] = soc_reg_field_get(unit, 17495 lt_select_config, 17496 mixed_src_class_mode, 17497 SOURCE_CLASS_MODEf); 17498 } else { 17499 for (pipe_idx = 0; pipe_idx < stage_fc->num_pipes ; pipe_idx++) { 17500 if (!(fc->pipe_map & (1 << pipe_idx))) { 17501 continue; 17502 } 17503 if (stage_fc->stage_id == _BCM_FIELD_STAGE_INGRESS) { 17504 BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit, 17505 IFP_LOGICAL_TABLE_SELECT_CONFIGr, 17506 pipe_idx, 17507 <_select_config)); 17508 } 17509 else { 17510 BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit, 17511 EXACT_MATCH_LOGICAL_TABLE_SELECT_CONFIGr, 17512 pipe_idx, 17513 <_select_config)); 17514 } 17515 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, lt_select_config, 17516 REG_PORT_ANY, 0, &mixed_src_class_mode)); 17517 stage_fc->field_src_class_mode[pipe_idx] = soc_reg_field_get(unit, 17518 lt_select_config, 17519 mixed_src_class_mode, 17520 SOURCE_CLASS_MODEf); 17521 } 17522 } 17523 return BCM_E_NONE; 17524 } 17525 17526 int 17527 _field_em_actions_tlv_retrieve(int unit, _field_control_t *fc, 17528 _field_tlv_t *tlv, 17529 bcm_field_action_t action) 17530 { 17531 bcm_error_t rv = BCM_E_NONE; 17532 int count = 0; 17533 _field_wb_em_act_ent_bmp_t *f_ent_bmp = NULL; 17534 17535 f_ent_bmp = tlv_em_act[unit]; 17536 for (count = 0 ; 17537 (count < _FP_EM_NUM_WB_SUPPORTED_ACTIONS); 17538 count++) { 17539 if (bcmFieldActionCount != f_ent_bmp[count].action) { 17540 continue; 17541 } 17542 f_ent_bmp[count].action = action; 17543 _FP_XGS3_ALLOC(f_ent_bmp[count].ent_bmp.w, 17544 (tlv->length * static_type_map[tlv->type].size), 17545 "Em Entry PBMP"); 17546 if (NULL == f_ent_bmp[count].ent_bmp.w) { 17547 rv = BCM_E_MEMORY; 17548 goto cleanup; 17549 } 17550 17551 sal_memcpy(f_ent_bmp[count].ent_bmp.w, tlv->value, 17552 tlv->length * static_type_map[tlv->type].size); 17553 break; 17554 } 17555 17556 cleanup: 17557 return rv; 17558 } 17559 17560 /* 17561 * Function: 17562 * _bcm_field_th_stage_em_reinit 17563 * Purpose: 17564 * Main reinit function for exact match stage 17565 * 17566 * Parameters: 17567 * unit - (IN) StrataSwitch unit #. 17568 * fc - (IN) _field_control_t structure 17569 * stage_fc - (IN) pointer to stage structure 17570 * Returns: 17571 * BCM_E_XXX 17572 */ 17573 int 17574 _bcm_field_th_stage_em_reinit(int unit, _field_control_t *fc, 17575 _field_stage_t *stage_fc) 17576 { 17577 _field_tlv_t tlv; 17578 uint8 *ptr = NULL; 17579 uint32 *pos = NULL; 17580 int rv = BCM_E_NONE; 17581 int pipe_id = 0, num_pipes = 0; 17582 _field_slice_t *curr_slice = NULL; 17583 _field_lt_slice_t *curr_ltslice = NULL; 17584 int slice_id = 0, lt_id = 0, i = 0; 17585 int group_count = 0, group_id = 0; 17586 _field_group_t *curr_fg = NULL; 17587 _field_group_t *new_fg = NULL; 17588 _field_lt_entry_t *f_lt_ent = NULL, *f_lt_ent_part = NULL; 17589 uint32 flags[3]; 17590 int part_index = 0, pri_tcam_idx = 0, slice_number = 0; 17591 int meter_pairs_per_pool = 0; 17592 int size = 0; 17593 int count = 0; 17594 _field_stage_t *stage_ifp = NULL; 17595 _field_wb_em_act_ent_bmp_t *f_ent_bmp = NULL; 17596 int pipe = -1, pool = -1; 17597 int total_qual_count = -1; 17598 17599 tlv.value = NULL; 17600 if ((fc == NULL) || (stage_fc == NULL)) { 17601 return BCM_E_PARAM; 17602 } 17603 TLV_INIT(tlv); 17604 17605 WB_FIELD_CONTROL_GET_WITH_LOCK(fc, ptr, pos); 17606 BCM_IF_ERROR_CLEANUP(_field_scache_stage_hdr_chk(fc, _FIELD_EM_DATA_START)); 17607 17608 _FP_XGS3_ALLOC(tlv_em_act[unit], 17609 _FP_EM_NUM_WB_SUPPORTED_ACTIONS * sizeof(_field_wb_em_act_ent_bmp_t), 17610 "EM entry BMP"); 17611 if (NULL == tlv_em_act[unit]) { 17612 rv = BCM_E_MEMORY; 17613 BCM_IF_ERROR_CLEANUP(rv); 17614 } 17615 17616 f_ent_bmp = tlv_em_act[unit]; 17617 for (count = 0 ; count < _FP_EM_NUM_WB_SUPPORTED_ACTIONS; count++) { 17618 f_ent_bmp[count].action = bcmFieldActionCount; 17619 f_ent_bmp[count].ent_bmp.w = NULL; 17620 } 17621 17622 while (tlv.type != _bcmFieldInternalEndStageEM) { 17623 TLV_INIT(tlv); 17624 /* coverity[no_write_call : FALSE] */ 17625 BCM_IF_ERROR_CLEANUP(tlv_read(unit, &tlv, ptr, pos)); 17626 17627 switch (tlv.type) { 17628 17629 case _bcmFieldInternalEMOperMode: 17630 if (*(bcm_field_group_oper_mode_t *)tlv.value) { 17631 BCM_IF_ERROR_CLEANUP(_bcm_field_wb_group_oper_mode_set(unit, 17632 bcmFieldQualifyStageIngressExactMatch, 17633 &stage_fc, 17634 bcmFieldGroupOperModePipeLocal)); 17635 BCM_IF_ERROR_CLEANUP(_field_stage_control_get(unit, 17636 _BCM_FIELD_STAGE_EXACTMATCH, 17637 &stage_fc)); 17638 num_pipes = stage_fc->num_pipes; 17639 } else { 17640 num_pipes = 1; 17641 } 17642 curr_stage_fc = stage_fc; 17643 break; 17644 case _bcmFieldInternalSlice: 17645 /* _field_slice_t and _field_lt_slice_t */ 17646 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"EM:: FP(unit %d):" 17647 "_bcm_field_th_stage" 17648 "_em_reinit -" 17649 "recovering _field_slice_t," 17650 "_field_lt_slice_t " 17651 "from pos = %d\r\n"), 17652 unit,fc->scache_pos)); 17653 17654 for (pipe_id = 0; pipe_id < num_pipes; pipe_id++) { 17655 if (!(fc->pipe_map & (1 << pipe_id))) { 17656 continue; 17657 } 17658 curr_slice = stage_fc->slices[pipe_id]; 17659 curr_ltslice = stage_fc->lt_slices[pipe_id]; 17660 17661 if (curr_slice != NULL) { 17662 for (slice_id= 0; slice_id < stage_fc->tcam_slices; 17663 slice_id ++) { 17664 17665 rv = _field_slice_recover(unit, pipe_id, 17666 (curr_slice + slice_id)); 17667 BCM_IF_ERROR_CLEANUP(rv); 17668 } 17669 } else { 17670 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 17671 "Memory not allocated for slice\n"))); 17672 } 17673 17674 if (curr_ltslice != NULL) { 17675 for (lt_id = 0; lt_id < stage_fc->tcam_slices; lt_id++) { 17676 rv = _field_lt_slice_recover(unit, pipe_id, 17677 (curr_ltslice 17678 + lt_id)); 17679 BCM_IF_ERROR_CLEANUP(rv); 17680 } 17681 } else { 17682 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 17683 "Memory not allocated for LT slice\n"))); 17684 } 17685 17686 } 17687 break; 17688 case _bcmFieldInternalGroupCount: 17689 group_count = *(int *)tlv.value; 17690 for (group_id =0 ;group_id < group_count; group_id ++) { 17691 curr_fg = NULL; 17692 _FP_XGS3_ALLOC(curr_fg, sizeof(_field_group_t), 17693 "current field grp"); 17694 if (curr_fg== NULL) { 17695 rv = BCM_E_MEMORY; 17696 goto cleanup; 17697 } 17698 rv = _field_group_recover(unit, curr_fg, &total_qual_count); 17699 BCM_IF_ERROR_CLEANUP(rv); 17700 rv = _field_em_group_entries_recover(unit, curr_fg); 17701 BCM_IF_ERROR_CLEANUP(rv); 17702 for (i=0; i < curr_fg->lt_grp_status.entry_count; i++) { 17703 f_lt_ent = NULL; 17704 if (curr_fg->em_mode == _FieldExactMatchMode320) { 17705 _FP_XGS3_ALLOC(f_lt_ent, 2 *sizeof(_field_lt_entry_t), 17706 "em ltentry"); 17707 } else { 17708 _FP_XGS3_ALLOC(f_lt_ent, sizeof(_field_lt_entry_t), 17709 "em ltentry"); 17710 } 17711 17712 if (f_lt_ent == NULL) { 17713 rv = BCM_E_MEMORY; 17714 goto cleanup; 17715 } 17716 curr_fg->lt_entry_arr[i] = f_lt_ent; 17717 f_lt_ent->group = curr_fg; 17718 f_lt_ent_part = f_lt_ent + 1; 17719 /* Recover entry */ 17720 rv =_field_lt_entry_info_recover(unit, f_lt_ent, 17721 flags, NULL); 17722 BCM_IF_ERROR_CLEANUP(rv); 17723 if (curr_fg->em_mode == _FieldExactMatchMode320) { 17724 sal_memcpy((f_lt_ent_part), f_lt_ent, sizeof(_field_lt_entry_t)); 17725 (f_lt_ent_part)->flags = flags[1]; 17726 rv = _bcm_field_th_lt_slice_offset_to_tcam_index(unit, 17727 stage_fc, f_lt_ent->group->instance, 17728 f_lt_ent->lt_fs->slice_number, 17729 f_lt_ent->index, &pri_tcam_idx); 17730 BCM_IF_ERROR_CLEANUP(rv); 17731 17732 rv = _bcm_field_th_lt_entry_part_tcam_idx_get(unit, 17733 f_lt_ent->group, pri_tcam_idx, 17734 1, &part_index); 17735 BCM_IF_ERROR_CLEANUP(rv); 17736 rv = _bcm_field_th_lt_tcam_idx_to_slice_offset(unit, 17737 stage_fc, f_lt_ent->group->instance, 17738 part_index, 17739 &slice_number,(int *)&f_lt_ent->index); 17740 BCM_IF_ERROR_CLEANUP(rv); 17741 f_lt_ent_part->lt_fs = 17742 stage_fc->lt_slices[f_lt_ent->group->instance] 17743 + slice_number; 17744 17745 } 17746 17747 17748 } 17749 curr_fg->next = fc->groups; 17750 fc->groups = curr_fg; 17751 17752 } 17753 17754 f_lt_ent = NULL; 17755 17756 new_fg = NULL; 17757 curr_fg = NULL; 17758 break; 17759 case _bcmFieldInternalControlPreselInfo: 17760 /* _field_presel_entry_t */ 17761 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 17762 "_bcm_field_th_stage" 17763 "_em_reinit -" 17764 "recovering _field_presel_" 17765 "entry_t from pos = %d\r\n"), 17766 unit, 17767 fc->scache_pos)); 17768 /* coverity[var_deref_model] */ 17769 new_fg = fc->groups; 17770 rv = _field_presel_entry_recover(unit, &tlv, new_fg, 17771 total_qual_count); 17772 BCM_IF_ERROR_CLEANUP(rv); 17773 break; 17774 17775 case _bcmFieldInternalEMActionPbmAssignChangeL2FieldsClassId: 17776 rv = _field_em_actions_tlv_retrieve(unit, fc, &tlv, bcmFieldActionAssignChangeL2FieldsClassId); 17777 BCM_IF_ERROR_CLEANUP(rv); 17778 break; 17779 case _bcmFieldInternalEMActionPbmAssignNatClassId: 17780 rv = _field_em_actions_tlv_retrieve(unit, fc, &tlv, bcmFieldActionAssignNatClassId); 17781 BCM_IF_ERROR_CLEANUP(rv); 17782 break; 17783 case _bcmFieldInternalEMActionPbmOpaqueObject3: 17784 rv = _field_em_actions_tlv_retrieve(unit, fc, &tlv, bcmFieldActionAssignOpaqueObject3); 17785 BCM_IF_ERROR_CLEANUP(rv); 17786 break; 17787 case _bcmFieldInternalEMActionPbmOpaqueObject1: 17788 rv = _field_em_actions_tlv_retrieve(unit, fc, &tlv, bcmFieldActionAssignOpaqueObject1); 17789 BCM_IF_ERROR_CLEANUP(rv); 17790 break; 17791 case _bcmFieldInternalEMActionPbmGbpSrcIdNew: 17792 rv = _field_em_actions_tlv_retrieve(unit, fc, &tlv, bcmFieldActionGbpSrcIdNew); 17793 BCM_IF_ERROR_CLEANUP(rv); 17794 break; 17795 case _bcmFieldInternalEMActionPbmGbpDstIdNew: 17796 rv = _field_em_actions_tlv_retrieve(unit, fc, &tlv, bcmFieldActionGbpDstIdNew); 17797 BCM_IF_ERROR_CLEANUP(rv); 17798 break; 17799 case _bcmFieldInternalEMActionPbmOpaqueObject2: 17800 rv = _field_em_actions_tlv_retrieve(unit, fc, &tlv, bcmFieldActionAssignOpaqueObject2); 17801 BCM_IF_ERROR_CLEANUP(rv); 17802 break; 17803 case _bcmFieldInternalEMActionPbmEgressFlowControlEnable: 17804 rv = _field_em_actions_tlv_retrieve(unit, fc, &tlv, bcmFieldActionEgressFlowControlEnable); 17805 BCM_IF_ERROR_CLEANUP(rv); 17806 break; 17807 case _bcmFieldInternalEndStageEM: 17808 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 17809 "_bcm_field_th_stage_em_reinit -" 17810 "at pos = %d\r\n"),unit, fc->scache_pos)); 17811 break; 17812 default : 17813 break; 17814 } 17815 17816 } 17817 17818 _field_wb_qos_buffer_free(unit); 17819 _field_wb_em_act_buffer_free(unit); 17820 rv = _field_scache_stage_hdr_chk(fc, _FIELD_EM_DATA_END); 17821 BCM_IF_ERROR_CLEANUP(rv); 17822 /* Sync of extractor codes for wide mode groups was missing post 17823 * post WB version 23 and is fixed in the sync code when WB version is 24. 17824 * But,for WB upgrade from version < 24,it has to be fixed in the recovery 17825 * code.Hence the below fix is required only if wb version is < 24 17826 */ 17827 if ((fc->wb_recovered_version) < BCM_FIELD_WB_VERSION_1_24) { 17828 if (SOC_SUCCESS(rv)) { 17829 rv = _field_recover_multi_part_extractor_codes(unit); 17830 BCM_IF_ERROR_CLEANUP(rv); 17831 } 17832 } 17833 rv = _bcm_field_th_stage_mixed_src_class_mode_recover(unit, stage_fc); 17834 17835 if (group_count != 0) { 17836 if (soc_feature(unit, soc_feature_td3_style_fp)) { 17837 meter_pairs_per_pool = BCM_FIELD_INGRESS_TD3_NUM_METER_PAIRS_PER_POOL; 17838 } else { 17839 meter_pairs_per_pool = BCM_FIELD_INGRESS_TH_NUM_METER_PAIRS_PER_POOL; 17840 } 17841 /* Initialize number of meter per pool.*/ 17842 size = SHR_BITALLOCSIZE(meter_pairs_per_pool << 1); 17843 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 17844 _BCM_FIELD_STAGE_INGRESS , &stage_ifp)); 17845 for (pipe = 0; pipe < _FP_MAX_NUM_PIPES; pipe++) { 17846 for (pool = 0; pool < _FIELD_MAX_METER_POOLS; pool++) { 17847 if (!(fc->pipe_map & (1 << pipe))) { 17848 continue; 17849 } 17850 if (fc->ifp_em_meter_in_use[pipe][pool] != 17851 BCM_FIELD_METER_POOL_USED_BY_NONE) { 17852 sal_memcpy(stage_fc->meter_pool[pipe][pool]->meter_bmp.w, 17853 stage_ifp->meter_pool[pipe][pool]->meter_bmp.w, 17854 size); 17855 stage_fc->meter_pool[pipe][pool]->level = 17856 stage_ifp->meter_pool[pipe][pool]->level; 17857 stage_fc->meter_pool[pipe][pool]->slice_id = 17858 stage_ifp->meter_pool[pipe][pool]->slice_id; 17859 stage_fc->meter_pool[pipe][pool]->size = 17860 stage_ifp->meter_pool[pipe][pool]->size; 17861 stage_fc->meter_pool[pipe][pool]->pool_size = 17862 stage_ifp->meter_pool[pipe][pool]->pool_size; 17863 stage_fc->meter_pool[pipe][pool]->free_meters = 17864 stage_ifp->meter_pool[pipe][pool]->free_meters; 17865 stage_fc->meter_pool[pipe][pool]->num_meter_pairs = 17866 stage_ifp->meter_pool[pipe][pool]->num_meter_pairs; 17867 } 17868 } 17869 } 17870 } 17871 cleanup: 17872 TLV_INIT(tlv); 17873 17874 for (count = 0 ; count < _FP_EM_NUM_WB_SUPPORTED_ACTIONS; count++) { 17875 if ((NULL != f_ent_bmp) && (NULL != f_ent_bmp[count].ent_bmp.w)) { 17876 _FP_ACTION_BMP_FREE(f_ent_bmp[count].ent_bmp); 17877 f_ent_bmp[count].ent_bmp.w = NULL; 17878 f_ent_bmp[count].action = bcmFieldActionCount; 17879 } 17880 } 17881 17882 if (NULL != tlv_em_act[unit]) { 17883 sal_free(tlv_em_act[unit]); 17884 } 17885 17886 if (f_lt_ent != NULL) { 17887 sal_free(f_lt_ent); 17888 } 17889 17890 if (curr_fg != NULL) { 17891 sal_free(curr_fg); 17892 } 17893 17894 FP_UNLOCK(unit); 17895 return rv; 17896 17897 } 17898 17899 17900 void 17901 _bcm_field_th_tlv_recovery_map_free(int unit) { 17902 if (downgrade[unit] == TRUE) { 17903 if (recovery_type_map[unit] != NULL) { 17904 sal_free(recovery_type_map[unit]); 17905 } 17906 } 17907 downgrade[unit] = FALSE; 17908 } 17909 17910 int 17911 _bcm_field_th_tlv_recovery_map_alloc(int unit, uint32 enum_total_count) { 17912 downgrade[unit] = TRUE; 17913 _FP_XGS3_ALLOC(recovery_type_map[unit], (sizeof (_field_type_map_t) 17914 * enum_total_count), 17915 "enum type map"); 17916 if (recovery_type_map[unit] == NULL) { 17917 return BCM_E_MEMORY; 17918 } 17919 return BCM_E_NONE; 17920 } 17921 /* 17922 * Function: 17923 * _bcm_field_th_stage_ingress_reinit 17924 * Description: 17925 * Service routine used to retain the software sate of 17926 * IFP(Ingress Field Processor) configuration . 17927 * Parameters: 17928 * unit - (IN) BCM device number. 17929 * fc - (IN) Field control structure. 17930 * stage_fc - (IN/OUT) Stage field control structure. 17931 * Returns: 17932 * BCM_E_XXX 17933 * Notes: 17934 * None. 17935 */ 17936 17937 int 17938 _bcm_field_th_stage_ingress_reinit(int unit, 17939 _field_control_t *fc, 17940 _field_stage_t *stage_fc) 17941 { 17942 int rv = BCM_E_NONE; /* Operation return value */ 17943 uint8 *scache_ptr; /* Pointer to 1st scache part*/ 17944 uint32 temp; /* Temporary variable */ 17945 _field_group_t *new_fg,*curr_fg, *prev_fg; 17946 /* For Group LL */ 17947 uint32 slice_id,pipe_id,lt_id,group_id; /* Iterator varaiables */ 17948 struct _field_slice_s *curr_slice; /* Slice information */ 17949 struct _field_lt_slice_s *curr_ltslice; /* LT slice information */ 17950 _field_tlv_t tlv; /* TLV data */ 17951 int num_pipes = 0; /* Number of pipes */ 17952 int group_count = 0; 17953 uint32 enum_properties_type = 0; 17954 /* Type for Enum Properties */ 17955 uint32 enum_total_count = 0; 17956 /* Count of Enums */ 17957 uint32 *enum_properties = NULL; 17958 /* Enum properties */ 17959 uint32 prop_pos = 0; /* To index Enum Properties array */ 17960 uint32 enum_count = 0; /* Enum index Variable */ 17961 int total_qual_count = -1; 17962 17963 tlv.value = NULL; 17964 new_fg = NULL; 17965 prev_fg = curr_fg = NULL; 17966 17967 17968 FP_LOCK(unit); 17969 TLV_INIT(tlv); 17970 scache_ptr = fc->scache_ptr[_FIELD_SCACHE_PART_0]; 17971 17972 fc->scache_pos = 0; 17973 fc->scache_pos += SOC_WB_SCACHE_CONTROL_SIZE; 17974 17975 sal_memcpy(&enum_properties_type, &scache_ptr[fc->scache_pos], 17976 sizeof(uint32)); 17977 fc->scache_pos += sizeof(uint32); 17978 17979 17980 if (enum_properties_type == BCM_FIELD_TYPE_ENUM_PROPERTIES) { 17981 _field_type_map_t temp_type_map; 17982 17983 sal_memcpy(&enum_total_count, &scache_ptr[fc->scache_pos], sizeof(uint32)); 17984 fc->scache_pos+= sizeof(uint32); 17985 17986 _FP_XGS3_ALLOC(enum_properties, (sizeof(uint32) * 3 * 17987 enum_total_count), 17988 "enum properties"); 17989 if (enum_properties == NULL) { 17990 rv = BCM_E_MEMORY; 17991 goto cleanup; 17992 } 17993 17994 rv = _bcm_field_th_tlv_recovery_map_alloc(unit, enum_total_count); 17995 if (BCM_FAILURE(rv)) { 17996 goto cleanup; 17997 } 17998 17999 sal_memcpy(enum_properties, &scache_ptr[fc->scache_pos], 18000 ((3 * sizeof(uint32)) * enum_total_count)); 18001 fc->scache_pos += ((3 * sizeof(uint32)) * enum_total_count); 18002 18003 prop_pos = 0; 18004 for (enum_count = 0; enum_count < enum_total_count; enum_count++) { 18005 sal_memset(&temp_type_map, 0x0, sizeof(_field_type_map_t)); 18006 temp_type_map.element = enum_properties[prop_pos++]; 18007 temp_type_map.size = enum_properties[prop_pos++]; 18008 temp_type_map.flags = enum_properties[prop_pos++]; 18009 sal_memcpy(&recovery_type_map[unit][enum_count], &temp_type_map, 18010 sizeof(_field_type_map_t)); 18011 } 18012 } else { 18013 recovery_type_map[unit] = (_field_type_map_t *)&static_type_map; 18014 fc->scache_pos -= sizeof(uint32); 18015 } 18016 18017 while (tlv.type != _bcmFieldInternalEndStructIFP) { 18018 TLV_INIT(tlv); 18019 /* coverity[no_write_call : FALSE] */ 18020 BCM_IF_ERROR_CLEANUP(tlv_read(unit, &tlv, scache_ptr, 18021 &(fc->scache_pos))); 18022 18023 18024 switch (tlv.type) { 18025 case _bcmFieldInternalControl: 18026 /* _field_control_t */ 18027 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 18028 "_bcm_field_th_stage" 18029 "_ingress_reinit" 18030 " recovering _field_control_t " 18031 " from pos = %d\r\n"),unit, 18032 fc->scache_pos)); 18033 rv = _field_control_recover(unit,fc); 18034 BCM_IF_ERROR_CLEANUP(rv); 18035 break; 18036 case _bcmFieldInternalStage: 18037 /*_field_stage_t */ 18038 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 18039 "_bcm_field_th_stage" 18040 "_ingress_reinit" 18041 " recovering _field_stage_t " 18042 " from pos = %d\r\n"),unit, 18043 fc->scache_pos)); 18044 rv = _field_stage_recover(unit,&stage_fc); 18045 BCM_IF_ERROR_CLEANUP(rv); 18046 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 18047 num_pipes = 1; 18048 } else if (stage_fc->oper_mode == bcmFieldGroupOperModePipeLocal) { 18049 num_pipes = stage_fc->num_pipes; 18050 } 18051 curr_stage_fc = stage_fc; 18052 break; 18053 case _bcmFieldInternalSlice: 18054 /* _field_slice_t and _field_lt_slice_t */ 18055 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 18056 "_bcm_field_th_stage" 18057 "_ingress_reinit -" 18058 "recovering _field_slice_t," 18059 "_field_lt_slice_t " 18060 "from pos = %d\r\n"), 18061 unit,fc->scache_pos)); 18062 18063 for (pipe_id = 0; pipe_id < num_pipes; pipe_id++) { 18064 if (!(fc->pipe_map & (1 << pipe_id))) { 18065 continue; 18066 } 18067 curr_slice = stage_fc->slices[pipe_id]; 18068 curr_ltslice = stage_fc->lt_slices[pipe_id]; 18069 18070 if (curr_slice != NULL) { 18071 for (slice_id= 0; slice_id < stage_fc->tcam_slices; 18072 slice_id ++) { 18073 18074 rv = _field_slice_recover(unit, pipe_id, 18075 (curr_slice + slice_id)); 18076 BCM_IF_ERROR_CLEANUP(rv); 18077 } 18078 } else { 18079 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 18080 "Memory not allocated for slice\n"))); 18081 } 18082 18083 18084 18085 18086 if (curr_ltslice != NULL) { 18087 for (lt_id = 0; lt_id < stage_fc->tcam_slices; lt_id++) { 18088 rv = _field_lt_slice_recover(unit, pipe_id, 18089 (curr_ltslice 18090 + lt_id)); 18091 BCM_IF_ERROR_CLEANUP(rv); 18092 } 18093 }else { 18094 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 18095 "Memory not allocated for LT slice\n"))); 18096 } 18097 18098 } 18099 break; 18100 case _bcmFieldInternalGroupCount: 18101 /* _field_group_t */ 18102 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 18103 "_bcm_field_th_stage" 18104 "_ingress_reinit -" 18105 "recovering _field_group_t " 18106 "from pos = %d\r\n"),unit, 18107 fc->scache_pos)); 18108 group_count = *(int *)tlv.value; 18109 18110 /* Iterate over the groups */ 18111 for (group_id =0 ;group_id < group_count; group_id ++) { 18112 curr_fg = NULL; 18113 _FP_XGS3_ALLOC(curr_fg, sizeof(_field_group_t), 18114 "current field grp"); 18115 if (curr_fg == NULL) { 18116 rv = BCM_E_MEMORY; 18117 goto cleanup; 18118 } 18119 18120 rv = _field_group_recover(unit, curr_fg, &total_qual_count); 18121 BCM_IF_ERROR_CLEANUP(rv); 18122 18123 if (prev_fg == NULL) { 18124 prev_fg = curr_fg; 18125 fc->groups = prev_fg; 18126 } else { 18127 prev_fg->next = curr_fg; 18128 prev_fg = curr_fg; 18129 } 18130 } 18131 curr_fg = NULL; 18132 /* _field_entry_t and _field_lt_entry_t */ 18133 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 18134 "_bcm_field_th_stage_ingress_reinit -" 18135 "recovering _field_entry_t," 18136 "_field_lt_entry_t from pos = %d\r\n"), 18137 unit,fc->scache_pos)); 18138 18139 new_fg = fc->groups; 18140 rv = _field_entry_recover(unit, new_fg); 18141 BCM_IF_ERROR_CLEANUP(rv); 18142 break; 18143 18144 case _bcmFieldInternalControlPreselInfo: 18145 /* _field_presel_entry_t */ 18146 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 18147 "_bcm_field_th_stage" 18148 "_ingress_reinit -" 18149 "recovering _field_presel_" 18150 "entry_t from pos = %d\r\n"), 18151 unit, 18152 fc->scache_pos)); 18153 /* coverity[var_deref_model] */ 18154 new_fg = fc->groups; 18155 rv = _field_presel_entry_recover(unit, &tlv, new_fg, 18156 total_qual_count); 18157 BCM_IF_ERROR_CLEANUP(rv); 18158 break; 18159 18160 case _bcmFieldInternalEndStructIFP: 18161 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 18162 "_bcm_field_th_stage_ingress_reinit -" 18163 "End of structures recover " 18164 "at pos = %d\r\n"),unit, fc->scache_pos)); 18165 break; 18166 default: 18167 break; 18168 } 18169 } 18170 18171 18172 temp = 0; 18173 temp |= scache_ptr[fc->scache_pos]; 18174 fc->scache_pos++; 18175 temp |= scache_ptr[fc->scache_pos] << 8; 18176 fc->scache_pos++; 18177 temp |= scache_ptr[fc->scache_pos] << 16; 18178 fc->scache_pos++; 18179 temp |= scache_ptr[fc->scache_pos] << 24; 18180 fc->scache_pos++; 18181 if (temp != _FIELD_IFP_DATA_END) { 18182 fc->l2warm = 0; 18183 rv = BCM_E_INTERNAL; 18184 } 18185 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 18186 "_bcm_field_th_stage_ingress_reinit -" 18187 "End of IFP Section " 18188 "at pos = %d\r\n"),unit, 18189 fc->scache_pos)); 18190 BCM_IF_ERROR_CLEANUP(rv); 18191 rv = _bcm_field_th_stage_mixed_src_class_mode_recover(unit, stage_fc); 18192 BCM_IF_ERROR_CLEANUP(rv); 18193 18194 cleanup: 18195 TLV_INIT(tlv); 18196 FP_UNLOCK(unit); 18197 if (curr_fg != NULL) { 18198 sal_free(curr_fg); 18199 } 18200 if (enum_properties != NULL) { 18201 sal_free(enum_properties); 18202 } 18203 18204 return rv; 18205 } 18206 18207 int 18208 _field_wb_action_alloc(int unit, _field_entry_t *f_ent, 18209 bcm_field_action_t action, 18210 _field_action_t **prev_act, 18211 int *param, int hw_index) 18212 { 18213 _field_action_t *f_act = NULL; 18214 int i; 18215 if (NULL == prev_act) { 18216 return BCM_E_PARAM; 18217 } 18218 18219 f_act = NULL; 18220 _FP_XGS3_ALLOC(f_act, sizeof(_field_action_t), "FP actions alloc"); 18221 if (f_act == NULL) { 18222 return BCM_E_MEMORY; 18223 } 18224 18225 f_act->action = action; 18226 for (i = 0; i < _FP_ACTION_PARAM_SZ; i++) { 18227 f_act->param[i] = param[i]; 18228 } 18229 f_act->hw_index = hw_index; 18230 f_act->old_index = -1; 18231 f_act->flags = _FP_ACTION_VALID; 18232 if (NULL == *prev_act) { 18233 *prev_act = f_act; 18234 f_ent->actions = *prev_act; 18235 } else { 18236 (*prev_act)->next = f_act; 18237 *prev_act = (*prev_act)->next; 18238 } 18239 18240 return BCM_E_NONE; 18241 } 18242 18243 int 18244 _field_wb_aset_actions_recover(int unit, _field_entry_t *f_ent, 18245 uint32 *ebuf, _field_action_bmp_t *act_bmp, 18246 int idx) 18247 { 18248 int i = 0; 18249 int bmp[1]; 18250 uint32 num_sw_enc = 0, num_hw_enc = 0; 18251 _bcm_field_action_offset_t a_offset; 18252 _bcm_field_action_offset_t a_enc; 18253 _field_action_t *prev_act = NULL; 18254 bcm_field_action_t action_idx; 18255 int param[_FP_ACTION_PARAM_SZ] = {0}; 18256 int rv = BCM_E_NONE; 18257 int hw_index = 0, valid = 0; 18258 _field_stage_t *stage_fc = NULL; 18259 int *action_arr = _field_aset_actions_array[idx]; 18260 18261 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,f_ent->fs->stage_id, &stage_fc)); 18262 if (f_ent->actions != NULL) { 18263 prev_act = f_ent->actions; 18264 while (prev_act->next != NULL) { 18265 prev_act = prev_act->next; 18266 } 18267 } 18268 18269 for (action_idx = 0; bcmFieldActionCount != action_arr[action_idx]; action_idx++) { 18270 valid = 0; 18271 if (act_bmp != NULL) { 18272 if (act_bmp->w == NULL) { 18273 continue; 18274 } else { 18275 if (!SHR_BITGET(act_bmp->w, action_arr[action_idx])) { 18276 continue; 18277 } 18278 } 18279 } 18280 18281 /* Get action offsets and action encodings programmed during action init */ 18282 rv = _bcm_field_action_offset_get(unit, stage_fc, action_arr[action_idx], &a_enc, 0); 18283 if (BCM_E_UNAVAIL == rv) { 18284 continue; 18285 } 18286 BCM_IF_ERROR_RETURN(rv); 18287 18288 /* Get the H/W values based on the action offsets */ 18289 rv = _bcm_field_action_val_get(unit, f_ent, ebuf, action_arr[action_idx], 0, &a_offset); 18290 /* If action is not supported on this device, go for next action */ 18291 if (BCM_E_UNAVAIL == rv) { 18292 continue; 18293 } 18294 BCM_IF_ERROR_RETURN(rv); 18295 18296 18297 num_sw_enc = 0; 18298 num_hw_enc = 0; 18299 for (i = 0; i < _FP_ACTION_MAX_PARAM_ENC; i++) { 18300 if (SHR_BITGET(&a_enc.encode_bmp, i)) { 18301 num_sw_enc++; 18302 if (a_offset.value[i] == a_enc.value[i]) { 18303 num_hw_enc++; 18304 } 18305 } 18306 } 18307 18308 if (num_sw_enc == num_hw_enc) { 18309 for (i = 0; i < _FP_ACTION_MAX_PARAM_ENC; i++) { 18310 /* Single index array added to prevent ARRAY_VS_SINGLETON coverity warning */ 18311 bmp[0] = a_enc.param_bmp; 18312 if (SHR_BITGET(bmp, i)) { 18313 switch (action_arr[action_idx]) { 18314 case bcmFieldActionGpCosMapNew: 18315 case bcmFieldActionYpCosMapNew: 18316 case bcmFieldActionRpCosMapNew: 18317 case bcmFieldActionCosMapNew: 18318 _BCM_COSQ_CLASSIFIER_FIELD_SET(param[0], a_offset.value[0]); 18319 break; 18320 case bcmFieldActionLoopbackType: 18321 if (5 == a_offset.value[0]) { 18322 param[0] = bcmFieldLoopbackTypeMasquerade; 18323 } 18324 break; 18325 case bcmFieldActionNatEgressOverride: 18326 param[0] = (a_offset.value[0] << 1) | (a_offset.value[1]); 18327 break; 18328 default: 18329 param[i] = a_offset.value[i]; 18330 break; 18331 } 18332 } 18333 } 18334 valid = 1; 18335 } 18336 18337 if (valid) { 18338 BCM_IF_ERROR_RETURN(_field_wb_action_alloc(unit, f_ent, action_arr[action_idx], 18339 &prev_act, param, hw_index)); 18340 } 18341 } 18342 18343 return BCM_E_NONE; 18344 } 18345 18346 /* 18347 * Function: 18348 * _field_wb_action_profile_parse 18349 * Purpose: 18350 * Parse the entry read from action profile table and figure out 18351 * which action sets are enabled. Update the f_ent structure 18352 * with data in hardware. It is a common function for TH EM, 18353 * TD3 IFP and TD3 EM. 18354 * Parameters: 18355 * unit - (IN) StrataSwitch unit #. 18356 * f_ent - (IN) entry which points to this action profile 18357 * ebuf - (IN) action profile table entry 18358 * act_data - (IN) action data part in the entry 18359 * Returns: 18360 * BCM_E_XXX 18361 */ 18362 int 18363 _field_wb_action_profile_parse(int unit, _field_entry_t *f_ent, 18364 uint32 *action_set_bitmap, uint32 *act_data, 18365 _field_action_bmp_t *act_bmp) 18366 { 18367 int idx; 18368 _field_stage_t *stage_fc = NULL; 18369 /* pointer to stage structure */ 18370 uint32 act_valid =0; 18371 /* Action valid flag */ 18372 _bcm_field_action_set_t *action_set_ptr; 18373 /* action set pointer */ 18374 uint8 *hw_bitmap; 18375 /* hw bitmap as per Action profile table */ 18376 uint8 hw_bitmap_entries = 0; 18377 /* number of entries in hw bitmap */ 18378 uint32 tbuf[2] = {0}; 18379 uint32 offset = 0; 18380 18381 /* Function pointer to call the recovery function for each 18382 action set */ 18383 int (*aset_recovery_func_ptr)(int unit, _field_entry_t *f_ent, 18384 uint32 *act_data, _field_action_bmp_t *act_bmp); 18385 18386 /* stage control gey */ 18387 BCM_IF_ERROR_RETURN(_field_stage_control_get (unit, 18388 f_ent->fs->stage_id, &stage_fc)); 18389 18390 /*Action_set bitmap*/ 18391 /*Retrieve action set pointer from stage structure */ 18392 action_set_ptr = stage_fc->action_set_ptr; 18393 /* depending on the stage, get the hw bitmap and 18394 number of entries in action profile bitmap */ 18395 if (f_ent->group->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 18396 /* Assign Exact Match Action Profile Memory */ 18397 if (SOC_IS_TOMAHAWK(unit)) { 18398 hw_bitmap = em_action_profile_bitmap; 18399 hw_bitmap_entries = 18400 sizeof(em_action_profile_bitmap)/sizeof(uint8); 18401 } else if (SOC_IS_TOMAHAWK2(unit)) { 18402 hw_bitmap = em_th2_action_profile_bitmap; 18403 hw_bitmap_entries = 18404 sizeof(em_th2_action_profile_bitmap)/sizeof(uint8); 18405 } else if (SOC_IS_TOMAHAWK3(unit)){ 18406 hw_bitmap = em_th3_action_profile_bitmap; 18407 hw_bitmap_entries = 18408 sizeof(em_th3_action_profile_bitmap)/sizeof(uint8); 18409 } else if (soc_feature(unit, soc_feature_td3_style_fp)) { 18410 hw_bitmap = em_td3_action_profile_bitmap; 18411 hw_bitmap_entries = 18412 sizeof(em_td3_action_profile_bitmap)/sizeof(uint8); 18413 if (f_ent->flags & _FP_ENTRY_EXACT_MATCH_GROUP_DEFAULT) { 18414 offset = EM_DEFAULT_POLICY_ACTION_DATA_SIZE; 18415 } else if (_FieldExactMatchMode128 == f_ent->group->em_mode) { 18416 offset = EM_MODE128_ACTION_DATA_SIZE; 18417 } else if(_FieldExactMatchMode160 == f_ent->group->em_mode) { 18418 offset = EM_MODE160_ACTION_DATA_SIZE; 18419 } else if(_FieldExactMatchMode320 == f_ent->group->em_mode) { 18420 offset = EM_MODE320_ACTION_DATA_SIZE; 18421 } 18422 18423 } else { 18424 return BCM_E_INTERNAL; 18425 } 18426 } else { 18427 hw_bitmap = ifp_td3_action_profile_bitmap; 18428 hw_bitmap_entries = 18429 sizeof(ifp_td3_action_profile_bitmap)/sizeof(uint8); 18430 if (!(f_ent->group->flags & _FP_GROUP_SPAN_SINGLE_SLICE) 18431 || (f_ent->group->flags & _FP_GROUP_INTRASLICE_DOUBLEWIDE)) { 18432 offset = _FP_ASET_DATA_SIZE_FOR_POLICY_WIDE; 18433 } else { 18434 offset = _FP_ASET_DATA_SIZE_FOR_POLICY_NARROW; 18435 } 18436 } 18437 /* Starting from bit0 to bitn (n = number of entries in bitmap) 18438 1) check whether the bit is 1. 18439 2) if the bit is 1, get the corresponing Action set from hw_bitmap array. 18440 3) get the size of the action set say width from action set pointer. 18441 4) get the action set data, size equal to width from the policy data. 18442 5) if the Action set data is non Zero value, call the corresponding 18443 action set's recovery function. 18444 6) shift the policy data index to width. 18445 7) repeat steps from 1 to 6 for all entries in hw bitmap. 18446 */ 18447 #if defined(BCM_TRIDENT3_SUPPORT) 18448 if(soc_feature(unit, soc_feature_ifp_action_profiling)) { 18449 for (idx = hw_bitmap_entries - 1; idx >= 0; idx--) { 18450 BCM_IF_ERROR_RETURN(_bcm_field_th_val_get(action_set_bitmap, 18451 &act_valid, idx, 1)); 18452 if (act_valid == 1) { 18453 /*idx Bit is set in the action profile */ 18454 tbuf[0] = 0; 18455 tbuf[1] = 0; 18456 BCM_IF_ERROR_RETURN(_bcm_field_th_val_get(act_data, tbuf, 18457 offset - action_set_ptr[hw_bitmap[idx]].size, 18458 action_set_ptr[hw_bitmap[idx]].size)); 18459 if ((0 != tbuf[0]) || (0 != tbuf[1])) { 18460 if (NULL != _field_wb_action_recovery_func_ptr[hw_bitmap[idx]]) { 18461 aset_recovery_func_ptr = 18462 (_field_wb_action_recovery_func_ptr[hw_bitmap[idx]]); 18463 BCM_IF_ERROR_RETURN((*aset_recovery_func_ptr) 18464 (unit, f_ent, tbuf, act_bmp)); 18465 } else if (NULL != _field_aset_actions_array[hw_bitmap[idx]]) { 18466 BCM_IF_ERROR_RETURN(_field_wb_aset_actions_recover 18467 (unit, f_ent, tbuf, act_bmp, hw_bitmap[idx])); 18468 } 18469 } 18470 offset -= action_set_ptr[hw_bitmap[idx]].size; 18471 } 18472 } 18473 } else 18474 #endif 18475 { 18476 for (idx=0; idx < hw_bitmap_entries;idx++) 18477 { 18478 BCM_IF_ERROR_RETURN(_bcm_field_th_val_get(action_set_bitmap, 18479 &act_valid, idx, 1)); 18480 if (act_valid == 1) { 18481 /*idx Bit is set in the action profile */ 18482 tbuf[0] = 0; 18483 tbuf[1] = 0; 18484 18485 BCM_IF_ERROR_RETURN(_bcm_field_th_val_get(act_data, tbuf, 18486 offset, 18487 action_set_ptr[hw_bitmap[idx]].size)); 18488 if ((0 != tbuf[0]) || (0 != tbuf[1])) { 18489 if (NULL != _field_wb_action_recovery_func_ptr[hw_bitmap[idx]]) { 18490 aset_recovery_func_ptr = 18491 (_field_wb_action_recovery_func_ptr[hw_bitmap[idx]]); 18492 BCM_IF_ERROR_RETURN((*aset_recovery_func_ptr) 18493 (unit, f_ent, tbuf, act_bmp)); 18494 } else if (NULL != _field_aset_actions_array[hw_bitmap[idx]]) { 18495 BCM_IF_ERROR_RETURN(_field_wb_aset_actions_recover 18496 (unit, f_ent, tbuf, act_bmp, hw_bitmap[idx])); 18497 } 18498 } 18499 offset += action_set_ptr[hw_bitmap[idx]].size; 18500 } 18501 } 18502 } 18503 return BCM_E_NONE; 18504 } 18505 18506 #ifdef BCM_HELIX5_SUPPORT 18507 /* 18508 * Function: 18509 * _field_wb_ft_actions_sync 18510 * Purpose: 18511 * Sync field actions for a given entry ina form of array 18512 * for flowtracker stage. 18513 * For each entry, entry_id, flags, (flags for 2nd part in 18514 * case of double wide group), slice_idx are stored in order. 18515 * 18516 * Parameters: 18517 * unit - (IN) StrataSwitch unit #. 18518 * f_ent - (IN) pointer to entry structure whose actions 18519 * to be synced. 18520 * array - (IN) array 18521 * count - (IN/OUT) Start of offsets in array. It is also 18522 * incremented by the indices written. 18523 * Returns: 18524 * BCM_E_XXX 18525 */ 18526 int 18527 _field_wb_ft_actions_sync(int unit, _field_entry_t *f_ent, 18528 uint32 *array, int *count) 18529 { 18530 int idx = 0; 18531 int offset = 0; 18532 _field_action_t *fa = NULL; 18533 int actions_list[] = { 18534 bcmFieldActionFlowtrackerGroupId, 18535 bcmFieldActionFlowtrackerEnable, 18536 bcmFieldActionFlowtrackerNewLearnEnable 18537 }; 18538 18539 offset = *count; 18540 /* Set Action offsets */ 18541 array[offset++] = COUNTOF(actions_list) * 2; 18542 for (idx = 0; idx < COUNTOF(actions_list) * 2; idx++) { 18543 array[offset+idx] = -1; 18544 } 18545 18546 /* Loop through */ 18547 for (fa = f_ent->actions; fa != NULL; fa = fa->next) { 18548 if (!(fa->flags & _FP_ACTION_VALID)) { 18549 continue; 18550 } 18551 if (fa->flags & _BCM_FIELD_ACTION_REF_STALE) { 18552 continue; 18553 } 18554 for (idx = 0; idx < COUNTOF(actions_list); idx++) { 18555 if (fa->action == actions_list[idx]) { 18556 break; 18557 } 18558 } 18559 array[offset+(2*idx)] = fa->param[0]; 18560 array[offset+(2*idx)+1] = fa->hw_index; 18561 } 18562 18563 *count = offset + 2 * COUNTOF(actions_list); 18564 18565 return BCM_E_NONE; 18566 } 18567 18568 /* 18569 * Function: 18570 * _field_ft_group_entries_sync 18571 * Purpose: 18572 * sync necessary information for each entry in a group 18573 * save entry id, flags (part 2 flags in case of double wide), 18574 * and slice Idx. 18575 * 18576 * Parameters: 18577 * unit - (IN) StrataSwitch unit #. 18578 * fg - (IN) pointer to group structure whose entries 18579 * have to be synced. 18580 * Returns: 18581 * BCM_E_XXX 18582 */ 18583 int 18584 _field_ft_group_entries_sync(int unit, _field_group_t *fg) 18585 { 18586 18587 _field_tlv_t *tlv = NULL; /* tlv pointer */ 18588 _field_entry_t *f_ent = NULL; /* pointers to entry structures */ 18589 uint8 *ptr = NULL; /* pointer to scache_ptr */ 18590 uint32 *pos = NULL; /* pointer to scache_pos */ 18591 _field_control_t *fc = NULL; /* pointer to field control struc */ 18592 _field_stage_t *stage_fc = NULL; /* pointer to stage structure */ 18593 int count = 0; /* to hold the current postion in array */ 18594 uint32 *array = NULL; /* to hold the values that are to be syced */ 18595 int ent_count = 0; /* entry count, hw index */ 18596 int rv = 0, parts_count = 0; /* rv, number of parts */ 18597 int num_attr = 0; /* Number of attributes stored per entry */ 18598 18599 ent_count = fg->group_status.entry_count; 18600 WB_FIELD_CONTROL_GET(fc, ptr, pos); 18601 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 18602 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc)); 18603 18604 rv = _bcm_field_entry_tcam_parts_count(unit, fg->stage_id, 18605 fg->flags, &parts_count); 18606 BCM_IF_ERROR_CLEANUP(rv); 18607 if (parts_count == 2) { 18608 /* Field to be saved are :- 18609 * eid, prio, flags (2 for DW), slice Idx, 18610 * action_count, 2 * field actions */ 18611 num_attr = 12; 18612 } else { 18613 /* Field to be saved are :- 18614 * eid, prio, flags (1 for SW), slice Idx, 18615 * action_count, 2 * field actions */ 18616 num_attr = 11; 18617 } 18618 18619 _FP_XGS3_ALLOC(array, num_attr * ent_count * sizeof(int), 18620 "ft entires array"); 18621 if (array == NULL) { 18622 rv = BCM_E_MEMORY; 18623 goto cleanup; 18624 } 18625 18626 while (count != (num_attr * ent_count)) { 18627 f_ent = fg->entry_arr[count/num_attr]; 18628 array[count++] = f_ent->eid; 18629 array[count++] = f_ent->flags; 18630 array[count++] = f_ent->prio; 18631 if (parts_count == 2) { 18632 array[count++] = (f_ent + 1)->flags; 18633 } 18634 array[count++] = f_ent->slice_idx; 18635 18636 rv = _field_wb_ft_actions_sync(unit, f_ent, array, &count); 18637 if (BCM_FAILURE(rv)) { 18638 goto cleanup; 18639 } 18640 } 18641 18642 TLV_CREATE_IF_ERR_CLEANUP(_bcmFieldInternalFTEntryArr, 18643 _bcmFieldInternalArray, 18644 num_attr * ent_count, &tlv); 18645 tlv->value = array; 18646 TLV_WRITE_IF_ERR_CLEANUP(unit, tlv, ptr, pos); 18647 18648 cleanup: 18649 if (array != NULL) { 18650 sal_free(array); 18651 } 18652 return rv; 18653 } 18654 18655 /* 18656 * Function: 18657 * _bcm_field_stage_ft_sync 18658 * Purpose: 18659 * Main sync for flowtracker stage 18660 * Parameters: 18661 * unit - (IN) StrataSwitch unit #. 18662 * fc - (IN) _field_control_t structure 18663 * stage_fc - (IN) Pointer tflowtracker stage structure 18664 * Returns: 18665 * BCM_E_XXX 18666 */ 18667 int 18668 _bcm_field_stage_ft_sync(int unit, _field_control_t *fc, 18669 _field_stage_t *stage_fc) 18670 { 18671 int rv = BCM_E_NONE; /* return value */ 18672 _field_tlv_t *tlv = NULL; /* pointer to tlv structure */ 18673 uint8 *scache_ptr = NULL; /* pointer to scache */ 18674 uint32 *pos = NULL; /* pointer to sacache_pos */ 18675 int num_pipes = 0; /* Number of pipes */ 18676 int pipe_id = 0; /* Pipe iterator */ 18677 int slice_id = 0; /* Slice iterator */ 18678 int lt_slice_id = 0; /* lt slice iterator */ 18679 _field_slice_t *curr_fs = NULL; /* Pointer to curr slice */ 18680 _field_lt_slice_t *curr_lt_fs = NULL; /* pointer to curr lt slice */ 18681 _field_group_t *fg = NULL; /* pointer to Field group */ 18682 int group_count = 0; /* Number of groups */ 18683 18684 WB_FIELD_CONTROL_GET_WITH_LOCK(fc, scache_ptr, pos); 18685 18686 /* Set static curr_stage_fc */ 18687 curr_stage_fc = stage_fc; 18688 18689 if (stage_fc->oper_mode == 0) { 18690 num_pipes = 1; 18691 } 18692 18693 fg = fc->groups; 18694 while (fg != NULL) { 18695 if (fg->stage_id == _BCM_FIELD_STAGE_FLOWTRACKER) { 18696 group_count++ ; 18697 } 18698 fg = fg->next; 18699 } 18700 /* Oper mode */ 18701 TLV_CREATE(_bcmFieldInternalFTOperMode, 18702 _bcmFieldInternalVariable, 0, &tlv); 18703 tlv->value = &stage_fc->oper_mode; 18704 TLV_WRITE(unit, tlv, scache_ptr, pos); 18705 18706 if (group_count > 0) { 18707 TLV_CREATE(_bcmFieldInternalSlice, 18708 _bcmFieldInternalVariable, 0, &tlv); 18709 TLV_WRITE(unit, tlv, scache_ptr, pos); 18710 18711 for (pipe_id = 0; pipe_id < num_pipes; pipe_id++) { 18712 curr_fs = stage_fc->slices[pipe_id]; 18713 curr_lt_fs = stage_fc->lt_slices[pipe_id]; 18714 18715 if (curr_fs != NULL) { 18716 for (slice_id = 0; slice_id < stage_fc->tcam_slices; 18717 slice_id ++) { 18718 rv = _field_slice_sync(unit, (curr_fs + slice_id)); 18719 BCM_IF_ERROR_CLEANUP(rv); 18720 } 18721 } else { 18722 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 18723 "No slices to sync\n"))); 18724 } 18725 if (curr_lt_fs != NULL) { 18726 for (lt_slice_id = 0; lt_slice_id < stage_fc->tcam_slices; 18727 lt_slice_id++) { 18728 rv = _field_lt_slice_sync(unit, (curr_lt_fs + lt_slice_id)); 18729 BCM_IF_ERROR_CLEANUP(rv); 18730 } 18731 } else { 18732 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 18733 "No LT slices to sync\n"))); 18734 } 18735 } 18736 18737 TLV_CREATE(_bcmFieldInternalGroupCount, 18738 _bcmFieldInternalVariable, 0, &tlv); 18739 tlv->value = &group_count; 18740 TLV_WRITE(unit, tlv, scache_ptr, pos); 18741 18742 fg = fc->groups; 18743 while (fg != NULL) { 18744 if (fg->stage_id == _BCM_FIELD_STAGE_FLOWTRACKER) { 18745 rv = _field_group_sync(unit,fg); 18746 18747 BCM_IF_ERROR_CLEANUP(rv); 18748 if (fg->group_status.entry_count > 0) { 18749 rv = _field_ft_group_entries_sync(unit, fg); 18750 BCM_IF_ERROR_CLEANUP(rv); 18751 } 18752 } 18753 fg = fg->next; 18754 } 18755 rv = _field_presel_entry_sync(unit); 18756 BCM_IF_ERROR_CLEANUP(rv); 18757 } 18758 TLV_CREATE(_bcmFieldInternalEndStageFT, _bcmFieldInternalVariable, 0, &tlv); 18759 TLV_WRITE(unit, tlv, scache_ptr, pos); 18760 18761 cleanup: 18762 FP_UNLOCK(unit); 18763 sal_free(tlv); 18764 return rv; 18765 } 18766 18767 /* 18768 * Function: 18769 * _field_wb_ft_actions_recover 18770 * Purpose: 18771 * Recover field actions for a given entry from synced array 18772 * for flowtracker stage. 18773 * For each entry, entry_id, flags, (flags for 2nd part in 18774 * case of double wide group), slice_idx are stored in order. 18775 * 18776 * Parameters: 18777 * unit - (IN) StrataSwitch unit #. 18778 * f_ent - (IN) pointer to entry structure whose actions 18779 * to be recovered. 18780 * array - (IN) array synced 18781 * count - (IN/OUT) Start of offsets in array. It is also 18782 * incremented by the indices read. 18783 * Returns: 18784 * BCM_E_XXX 18785 */ 18786 int 18787 _field_wb_ft_actions_recover(int unit, _field_entry_t *f_ent, 18788 uint32 *array, int *count) 18789 { 18790 int idx = 0; 18791 int offset = 0; 18792 int num_offsets; 18793 _field_action_t *fa = NULL; 18794 int actions_list[] = { 18795 bcmFieldActionFlowtrackerGroupId, 18796 bcmFieldActionFlowtrackerEnable, 18797 bcmFieldActionFlowtrackerNewLearnEnable 18798 }; 18799 18800 num_offsets = array[*count]; 18801 offset = *count + 1; 18802 18803 for (idx = 0; idx < num_offsets/2; idx++) { 18804 if (array[offset + (2 *idx)] == -1) { 18805 continue; 18806 } 18807 18808 fa = NULL; 18809 _FP_XGS3_ALLOC(fa, sizeof(_field_action_t), "field action"); 18810 if (fa == NULL) { 18811 return BCM_E_MEMORY; 18812 } 18813 fa->next = f_ent->actions; 18814 f_ent->actions = fa; 18815 18816 fa->action = actions_list[idx]; 18817 fa->param[0] = array[offset+(2*idx)]; 18818 fa->hw_index = array[offset+(2*idx)+1]; 18819 fa->old_index = _FP_INVALID_INDEX; 18820 fa->flags |= _FP_ACTION_VALID; 18821 } 18822 18823 *count = offset + num_offsets; 18824 18825 return BCM_E_NONE; 18826 } 18827 18828 /* 18829 * Function: 18830 * _field_ft_group_entries_recover 18831 * Purpose: 18832 * Recover all entries for a given exactmatch match group 18833 * For each entry, entry_id, flags, (flags for 2nd part in 18834 * case of double wide group), slice_idx are stored in order. 18835 * 18836 * Parameters: 18837 * unit - (IN) StrataSwitch unit #. 18838 * fg - (IN) pointer to group structure whose entries 18839 * have to be recovered. 18840 * Returns: 18841 * BCM_E_XXX 18842 */ 18843 int 18844 _field_ft_group_entries_recover(int unit, _field_group_t *fg) 18845 { 18846 _field_tlv_t tlv; 18847 int i = 0; 18848 _field_control_t *fc = NULL; 18849 uint8 *ptr = NULL; 18850 uint32 *pos = NULL; 18851 uint32 *value = NULL; 18852 _field_entry_t *f_ent = NULL, *f_ent_part = NULL; 18853 int idx = 0; 18854 _field_stage_t *stage_fc = NULL; 18855 int rv = 0, parts_count = 0; 18856 18857 tlv.value = NULL; 18858 TLV_INIT(tlv); 18859 WB_FIELD_CONTROL_GET(fc, ptr, pos); 18860 if (fg->group_status.entry_count == 0) { 18861 return BCM_E_NONE; 18862 } 18863 /* coverity[no_write_call : FALSE] */ 18864 BCM_IF_ERROR_RETURN(tlv_read(unit, &tlv, ptr, pos)); 18865 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 18866 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc)); 18867 18868 18869 if (tlv.type != _bcmFieldInternalFTEntryArr) { 18870 sal_free(tlv.value); 18871 return BCM_E_INTERNAL; 18872 } 18873 18874 rv = _bcm_field_entry_tcam_parts_count(unit, fg->stage_id, 18875 fg->flags, &parts_count); 18876 BCM_IF_ERROR_RETURN(rv); 18877 18878 value = tlv.value; 18879 while (i < tlv.length) { 18880 if (parts_count == 2) { 18881 f_ent = NULL; 18882 f_ent_part = NULL; 18883 _FP_XGS3_ALLOC(f_ent, 2 * sizeof(_field_entry_t), "ft entry"); 18884 if (f_ent == NULL) { 18885 rv = BCM_E_MEMORY; 18886 goto cleanup; 18887 } 18888 f_ent_part = f_ent + 1; 18889 f_ent->eid = value[i++]; 18890 f_ent_part->eid = f_ent->eid; 18891 f_ent->flags = value[i++]; 18892 f_ent->prio = value[i++]; 18893 f_ent_part->prio = f_ent->prio; 18894 f_ent_part->flags = value[i++]; 18895 f_ent->group = fg; 18896 f_ent_part->group = fg; 18897 f_ent->fs = fg->slices; 18898 f_ent_part->fs = fg->slices; 18899 f_ent->slice_idx = value[i++]; 18900 f_ent_part->slice_idx = (f_ent->slice_idx != -1) ? (f_ent->slice_idx + 1):(-1); 18901 fg->entry_arr[idx++] = f_ent; 18902 if (f_ent->flags & _FP_ENTRY_INSTALLED) { 18903 f_ent->fs->hw_ent_count += 2; 18904 } 18905 } else { 18906 f_ent = NULL; 18907 _FP_XGS3_ALLOC(f_ent, sizeof(_field_entry_t), "em entry"); 18908 if (f_ent == NULL) { 18909 rv = BCM_E_MEMORY; 18910 goto cleanup; 18911 } 18912 18913 f_ent->eid = value[i++]; 18914 f_ent->group = fg; 18915 f_ent->fs = fg->slices; 18916 f_ent->flags = value[i++]; 18917 f_ent->prio = value[i++]; 18918 f_ent->slice_idx = value[i++]; 18919 fg->entry_arr[idx++] = f_ent; 18920 if (f_ent->flags & _FP_ENTRY_INSTALLED) { 18921 f_ent->fs->hw_ent_count += 1; 18922 } 18923 } 18924 _field_wb_ft_actions_recover(unit, f_ent, value, &i); 18925 } 18926 18927 return BCM_E_NONE; 18928 18929 cleanup: 18930 TLV_INIT(tlv); 18931 18932 return rv; 18933 } 18934 18935 /* 18936 * Function: 18937 * _bcm_field_stage_ft_reinit 18938 * Purpose: 18939 * re-initialize flowtracker stage after warmboot 18940 * Parameters: 18941 * unit - (IN) StrataSwitch unit #. 18942 * fc - (IN) Field control structure. 18943 * stage_fc-(IN) pointer to stage structure 18944 * Returns: 18945 * BCM_E_XXX 18946 */ 18947 int 18948 _bcm_field_stage_ft_reinit(int unit, 18949 _field_control_t *fc, 18950 _field_stage_t *stage_fc) 18951 { 18952 int rv = BCM_E_NONE; /* Error code. */ 18953 int idx = 0; /* Iterator */ 18954 _field_tlv_t tlv; /* TLV structure. */ 18955 uint8 *scache_ptr = NULL; /* Scache pointer. */ 18956 uint32 *pos = NULL; /* Position in scache. */ 18957 _field_slice_t *curr_fs = NULL; /* Pointer to current Slice. */ 18958 _field_lt_slice_t *curr_lt_fs = NULL; /* Pointer to current LT slice. */ 18959 int pipe_id = 0; /* Pipe number. */ 18960 int num_pipes = 1; /* Number of pipes. */ 18961 int slice_id = 0; /* Slice Number. */ 18962 int lt_slice_id = 0; /* Lt Slice Number. */ 18963 int group_count = 0; /* Group counter. */ 18964 int group_id = 0; /* Group Identifier. */ 18965 _field_group_t *curr_fg = NULL; /* Current Field Group. */ 18966 int total_qual_count = -1; 18967 18968 /* Validate Input params. */ 18969 if ((fc == NULL) || (stage_fc == NULL)) { 18970 return BCM_E_PARAM; 18971 } 18972 tlv.value = NULL; 18973 TLV_INIT(tlv); 18974 18975 WB_FIELD_CONTROL_GET_WITH_LOCK(fc, scache_ptr, pos); 18976 BCM_IF_ERROR_CLEANUP(_field_scache_stage_hdr_chk(fc, _FIELD_FT_DATA_START)); 18977 18978 curr_stage_fc = stage_fc; 18979 18980 while (tlv.type != _bcmFieldInternalEndStageFT) { 18981 TLV_INIT(tlv); 18982 /* coverity[no_write_call : FALSE] */ 18983 BCM_IF_ERROR_CLEANUP(tlv_read(unit, &tlv, scache_ptr, pos)); 18984 18985 switch (tlv.type) { 18986 case _bcmFieldInternalFTOperMode: 18987 stage_fc->oper_mode = *(bcm_field_group_oper_mode_t *)tlv.value; 18988 num_pipes = 1; 18989 break; 18990 case _bcmFieldInternalSlice: 18991 /* recover _field_slice_t and _field_lt_slice_t */ 18992 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FT:: FP(unit %d):" 18993 "_bcm_field_hx5_stage_ft_reinit -" 18994 "recovering _field_slice_t, _field_lt_slice_t " 18995 "from pos = %d\r\n"), unit,fc->scache_pos)); 18996 18997 for (pipe_id = 0; pipe_id < num_pipes; pipe_id++) { 18998 curr_fs = stage_fc->slices[pipe_id]; 18999 curr_lt_fs = stage_fc->lt_slices[pipe_id]; 19000 19001 if (curr_fs != NULL) { 19002 for (slice_id= 0; slice_id < stage_fc->tcam_slices; 19003 slice_id ++) { 19004 19005 rv = _field_slice_recover(unit, pipe_id, 19006 (curr_fs + slice_id)); 19007 BCM_IF_ERROR_CLEANUP(rv); 19008 } 19009 } else { 19010 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 19011 "Memory not allocated for slice\n"))); 19012 } 19013 19014 if (curr_lt_fs != NULL) { 19015 for (lt_slice_id = 0; lt_slice_id < stage_fc->tcam_slices; 19016 lt_slice_id++) { 19017 rv = _field_lt_slice_recover(unit, pipe_id, 19018 (curr_lt_fs + lt_slice_id)); 19019 BCM_IF_ERROR_CLEANUP(rv); 19020 } 19021 } else { 19022 LOG_ERROR(BSL_LS_BCM_FP,(BSL_META_U(unit, 19023 "Memory not allocated for LT slice\n"))); 19024 } 19025 } 19026 break; 19027 case _bcmFieldInternalGroupCount: 19028 group_count = *(int *)tlv.value; 19029 for (group_id = 0; group_id < group_count; group_id ++) { 19030 curr_fg = NULL; 19031 _FP_XGS3_ALLOC(curr_fg, sizeof(_field_group_t), 19032 "current field grp"); 19033 if (curr_fg == NULL) { 19034 rv = BCM_E_MEMORY; 19035 goto cleanup; 19036 } 19037 /* Clear the group's select codes. */ 19038 for (idx = 0; idx < _FP_MAX_ENTRY_WIDTH; idx++) { 19039 _FIELD_SELCODE_CLEAR(curr_fg->sel_codes[idx]); 19040 } 19041 rv = _field_group_recover(unit, curr_fg, &total_qual_count); 19042 BCM_IF_ERROR_CLEANUP(rv); 19043 19044 rv = _field_ft_group_entries_recover(unit, curr_fg); 19045 BCM_IF_ERROR_CLEANUP(rv); 19046 19047 curr_fg->next = fc->groups; 19048 fc->groups = curr_fg; 19049 } 19050 curr_fg = NULL; 19051 break; 19052 case _bcmFieldInternalControlPreselInfo: 19053 /* Recover _field_presel_entry_t */ 19054 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FT:: FP(unit %d):" 19055 "_bcm_field_hx5_stage_ft_reinit -" 19056 "recovering _field_presel_entry_t " 19057 "from pos = %d\r\n"), unit,fc->scache_pos)); 19058 19059 rv = _field_presel_entry_recover(unit, &tlv, fc->groups, 19060 total_qual_count); 19061 BCM_IF_ERROR_CLEANUP(rv); 19062 break; 19063 19064 case _bcmFieldInternalEndStageFT: 19065 LOG_DEBUG(BSL_LS_BCM_FP,(BSL_META_U(unit,"FP(unit %d):" 19066 "_bcm_field_hx5_stage_ft_reinit -" 19067 "at pos = %d\r\n"),unit, fc->scache_pos)); 19068 break; 19069 default : 19070 break; 19071 } 19072 } 19073 19074 rv = _field_scache_stage_hdr_chk(fc, _FIELD_FT_DATA_END); 19075 BCM_IF_ERROR_CLEANUP(rv); 19076 19077 /* Recover ft ext codes for field groups from hw. */ 19078 rv = _bcm_field_ft_group_ext_codes_recover(unit); 19079 BCM_IF_ERROR_CLEANUP(rv); 19080 19081 /* Recover mixed source class mode. */ 19082 rv = _bcm_field_th_stage_mixed_src_class_mode_recover(unit, stage_fc); 19083 19084 cleanup: 19085 TLV_INIT(tlv); 19086 19087 if (curr_fg != NULL) { 19088 sal_free(curr_fg); 19089 } 19090 19091 FP_UNLOCK(unit); 19092 19093 return rv; 19094 } 19095 19096 #endif /* BCM_HELIX5_SUPPORT */ 19097 19098 #endif /* BCM_TOMAHAWK_SUPPORT */ 19099 #endif /* BCM_WARM_BOOT_SUPPORT */