openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 = &empty;
   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, &lt_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, &lt_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, &lt_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, &lt_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, &reg_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, &param[0], &param[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, &param[0], &param[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, &param[0], &param[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, &param[0], &param[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, &param[0], &param[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, &param[0], &param[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, &param[0], &param[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, &param[0], &param[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                             &lt_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                             &lt_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 */