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

udf.c (104534B)


      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  * All Rights Reserved.$
      7  *
      8  * File:       udf.c
      9  * Purpose:    BCM56870 Field Processor functions.
     10  */
     11 
     12 #include <soc/defs.h>
     13 #if defined(BCM_TRIDENT3_SUPPORT)
     14 #include <shared/bsl.h>
     15 #include <soc/mem.h>
     16 #include <soc/drv.h>
     17 #include <soc/tomahawk.h>
     18 #include <soc/field.h>
     19 #include <soc/format.h>
     20 #include <soc/scache.h>
     21 #include <soc/error.h>
     22 #include <shared/bitop.h>
     23 #include "include/soc/esw/cancun.h"
     24 #include <include/soc/mcm/formatacc.h>
     25 #include <bcm/error.h>
     26 #include <bcm/module.h>
     27 
     28 #include <bcm/udf.h>
     29 #include <bcm_int/esw/udf.h>
     30 
     31 #if defined (BCM_WARM_BOOT_SUPPORT)
     32 /* Warmboot Versions */
     33 #define BCM_WB_VERSION_1_0     SOC_SCACHE_VERSION(1, 0)
     34 #define BCM_WB_VERSION_2_0     SOC_SCACHE_VERSION(2, 0)
     35 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_2_0
     36 #endif /* BCM_WARM_BOOT_SUPPORT */
     37 
     38 /* Maximum number of UDF objects - (Max Chunks * number of pkt abstracts) */
     39 #define _BCM_UDF_TD3_MAX_OBJECTS(_u_)   \
     40      (_BCM_UDF_CTRL_MAX_UDF_CHUNKS(_u_) * bcmUdfAbstractPktFormatLastCount)
     41 
     42 /* UDF Object Min and Max Values. */
     43 #define _BCM_UDF_TD3_OBJ_MIN_ID 0x1
     44 #define _BCM_UDF_TD3_OBJ_MAX_ID 0xfffe
     45 
     46 /* UDF Parse limit supported by SRC_PKT_OFFSET in CMD_POLICY_DATA */
     47 #define _BCM_UDF_TD3_MAX_PARSE_LIMIT 128
     48 
     49 /* Number of commands dedicated to UDF in CMD_POLICY_DATAf */
     50 #define _BCM_UDF_MAX_POLICY_CMDS 8
     51 
     52 /* Device Parser level from which UDF is extracted */
     53 #define _BCM_UDF_PARSER0 3
     54 #define _BCM_UDF_PARSER1 1
     55 #define _BCM_UDF_PARSER2 2
     56 
     57 /* Global UDF control structure pointers */
     58 _bcm_udf_td3_ctrl_t *udf_td3_control[BCM_MAX_NUM_UNITS];
     59 
     60 #define UDF_TD3_CTRL(_u_) udf_td3_control[_u_]
     61 
     62 /*
     63  *  UDF Container Chunks (2 bytes each) to Destination container ID mapping.
     64  *
     65  *  UDF Chunks  Container ID
     66  *  ==========  ============
     67  *  UDF1_0      CONT_20
     68  *  UDF1_1      CONT_19
     69  *  UDF1_2      CONT_18
     70  *  UDF1_3      CONT_17
     71  *  UDF1_4      CONT_16
     72  *  UDF1_5      CONT_15
     73  *  UDF1_6      CONT_14
     74  *  UDF1_7      CONT_13
     75  *  UDF2_0      CONT_28
     76  *  UDF2_1      CONT_27
     77  *  UDF2_2      CONT_26
     78  *  UDF2_3      CONT_25
     79  *  UDF2_4      CONT_24
     80  *  UDF2_5      CONT_23
     81  *  UDF2_6      CONT_22
     82  *  UDF2_7      CONT_21
     83  */
     84 STATIC
     85 uint8 _bcm_udf_chunk_to_dest_cont_id_mapping[16] =
     86       {20, 19, 18, 17, 16, 15, 14, 13, 28, 27, 26, 25, 24, 23, 22, 21};
     87 
     88 /* Opaque to UDF chunks */
     89 STATIC
     90 uint8 _bcm_udf_opaque_cont_to_chunk_mapping[16] =
     91       {7, 6, 5 ,4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8};
     92 
     93 /* Range Check supported UDF Chunk - UDF1_CHUNK2 */
     94 #define _BCM_UDF_TD3_RANGE_CHUNK_BMAP 0x4
     95 
     96 /* Maximum number of Chunks Supported. */
     97 #define _BCM_UDF_TD3_MAX_CHUNKS     16
     98 
     99 /* Maximum Chunk Bitmap. */
    100 #define _BCM_UDF_TD3_MAX_CHUNK_BMAP 0xffff
    101 
    102 /*
    103  * Global Variable to hold Abstract
    104  * Packet format HW information.
    105  */
    106 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *abstr_pkt_fmt_hw_info[BCM_MAX_NUM_UNITS][bcmUdfAbstractPktFormatLastCount];
    107 
    108 /*
    109  * Macro to retrieve pointer to _bcm_udf_td3_abstr_pkt_fmt_hw_info_t
    110  * structure for a given abstr pkt format.
    111  */
    112 #define _UDF_ABSTR_PKT_FMT_HW_INFO_GET(_u_, _pkt_fmt_)   \
    113                  abstr_pkt_fmt_hw_info[_u_][_pkt_fmt_]
    114 
    115 
    116 /* UDF Byte to Chunk Conversion */
    117 #define _BCM_UDF_BYTE_TO_CHUNK(_val_) (_val_/2)
    118 
    119 /* UDF Chunk to Byte Conversion */
    120 #define _BCM_UDF_CHUNK_TO_BYTE(_val_) (_val_ * 2)
    121 
    122 /* Validate Abstract Packet format */
    123 #define _BCM_UDF_ABSTR_PKT_FORMAT_VALIDATE(_u_, _pkt_fmt_)       \
    124     do {                                                         \
    125        if ((_pkt_fmt_ < bcmUdfAbstractPktFormatLlc) ||           \
    126            (_pkt_fmt_ >= bcmUdfAbstractPktFormatLastCount)) {    \
    127            return BCM_E_PARAM;                                   \
    128        }                                                         \
    129        if (abstr_pkt_fmt_hw_info[_u_][_pkt_fmt_]->max_extract_bytes == 0) {      \
    130            return BCM_E_UNAVAIL;                                 \
    131        }                                                         \
    132     } while (0)
    133 
    134 /* Validate Extraction bytes for a given packet format */
    135 #define _BCM_UDF_EXTRACTION_BYTES_VALIDATE(_u_, _pkt_format_, _bytes_)       \
    136     do {                                                                     \
    137        _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *_pkt_format_hw_info_ = NULL;    \
    138                                                                              \
    139        _pkt_format_hw_info_ = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(_u_, _pkt_format_);  \
    140        if (_pkt_format_hw_info_ == NULL)  {                                  \
    141           return BCM_E_INTERNAL;                                             \
    142        }                                                                     \
    143        if (_bytes_ > (_pkt_format_hw_info_->max_extract_bytes -              \
    144                       _pkt_format_hw_info_->extracted_bytes)) {              \
    145           return BCM_E_CONFIG;                                               \
    146        }                                                                     \
    147     } while(0)
    148 
    149 /* Validate chunk */
    150 #define _BCM_UDF_CHUNK_VALIDATE(_u_, _chunk_bmap_, _pkt_fmt_)                      \
    151     do {                                                                           \
    152        uint32 _unavail_cbmap;                                                      \
    153        if ((_chunk_bmap_ == 0x0) ||                                                \
    154            (_chunk_bmap_ > _BCM_UDF_TD3_MAX_CHUNK_BMAP)) {                         \
    155             return BCM_E_PARAM;                                                    \
    156        }                                                                           \
    157        _unavail_cbmap = abstr_pkt_fmt_hw_info[_u_][_pkt_fmt_]->unavail_chunk_bmap; \
    158        if (_unavail_cbmap & _chunk_bmap_) {                                        \
    159            LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,                             \
    160              "The chunks in the given chunk bitmap are reserved/unavailable: 0x%x\n\r"), \
    161               _unavail_cbmap & _chunk_bmap_));                                     \
    162            return BCM_E_CONFIG;                                                    \
    163        }                                                                           \
    164     } while(0)
    165 
    166 /* Validate Chunk bitmap */
    167 #define _BCM_UDF_OBJECT_CHUNK_IN_USE_VALIDATE(_u_, _pkt_format_, _chunk_bmap_)   \
    168     do {                                                                         \
    169        _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *_pkt_format_hw_info_ = NULL;        \
    170                                                                                  \
    171        _pkt_format_hw_info_ = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(_u_, _pkt_format_); \
    172        if (_pkt_format_hw_info_ == NULL)  {                                      \
    173           return BCM_E_INTERNAL;                                                 \
    174        }                                                                         \
    175        if (_pkt_format_hw_info_->chunk_bmap_used & _chunk_bmap_) {               \
    176           return BCM_E_CONFIG;                                                   \
    177        }                                                                         \
    178     } while(0)
    179 
    180 /*
    181  * Typedef:
    182  *    _BCM_UDF_ABSTRACT_PKT_FORMAT_MAPPING_DECL
    183  */
    184 #define _BCM_UDF_ABSTRACT_PKT_FORMAT_MAPPING_DECL    \
    185     int _rv_;                                        \
    186     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t _pkt_fmt_hw_cfg_;
    187 
    188 /*
    189  * Typedef:
    190  *    _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT
    191  * Purpose:
    192  *    Insert UDF abstract packet format configuration.
    193  */
    194 #define _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(_unit_, _pkt_format_, _parser_)  \
    195       do {                                                                     \
    196             uint8 _stg_;                                                       \
    197             sal_memset(&_pkt_fmt_hw_cfg_, 0x0,                                 \
    198                            sizeof(_bcm_udf_td3_abstr_pkt_fmt_hw_info_t));      \
    199             (_pkt_fmt_hw_cfg_).parser = (_parser_);                            \
    200             (_pkt_fmt_hw_cfg_).base_offset = 0x0;                              \
    201             (_pkt_fmt_hw_cfg_).max_extract_bytes = 0x0;                        \
    202             for (_stg_ = 0; _stg_ < _BCM_UDF_MAX_PARSER_STAGES; _stg_++) {     \
    203                 (_pkt_fmt_hw_cfg_).stage_policy_mem[_stg_] = INVALIDm;         \
    204                 (_pkt_fmt_hw_cfg_).hfe_prof_ptr_arr_len[_stg_] = 0;            \
    205                 (_pkt_fmt_hw_cfg_).hfe_profile_ptr[_stg_]  = NULL;             \
    206             }                                                                  \
    207             _rv_ = _bcm_udf_td3_abstr_pkt_fmt_hw_info_insert((_unit_),         \
    208                                   (_pkt_format_), &(_pkt_fmt_hw_cfg_));        \
    209             BCM_IF_ERROR_RETURN(_rv_);                                         \
    210       } while(0)
    211 
    212 
    213 /*
    214  * Macros to manage (add, delete, get) the Object Node
    215  */
    216 #define _BCM_UDF_OBJ_NODE_ADD(_u_, _new_, _head_)             \
    217         _UDF_DLL_NODE_ADD(_u_, _new_, _head_)
    218 
    219 #define _BCM_UDF_OBJ_NODE_DEL(_u_, _del_, _head_)             \
    220     do {                                                      \
    221         _bcm_udf_td3_obj_info_t *_temp_;                      \
    222         _UDF_DLL_NODE_DEL(_u_, _del_, _head_, _temp_);        \
    223     } while (0)
    224 
    225 #define _BCM_UDF_OBJ_NODE_GET(_u_, _id_, _head_, _node_)      \
    226     do {                                                      \
    227         _bcm_udf_td3_obj_info_t *_temp_;                      \
    228         _UDF_DLL_NODE_GET(_u_, _id_, _head_, _temp_, _node_); \
    229     } while (0)
    230 
    231 #define _BCM_UDF_OBJ_NODE_DEL_ALL(_u_, _head_)                        \
    232     do {                                                              \
    233          _bcm_udf_td3_obj_info_t *_temp_;                             \
    234          while(_head_ != NULL) {                                      \
    235              _temp_ = _head_;                                         \
    236              _BCM_UDF_OBJ_NODE_DEL(_u_, _temp_, _head_);              \
    237              _BCM_UDF_FREE(_temp_);                                   \
    238          }                                                            \
    239     } while (0)
    240 
    241 #define _BCM_UDF_OBJ_NODE_NEXT(_node_)                   \
    242         _node_ = _node_->prev;
    243 
    244 
    245 soc_field_t src_pkt_offset_p0_cmds[8] = {
    246                                         INVALIDf,
    247                                         INVALIDf,
    248                                         INVALIDf,
    249                                         INVALIDf,
    250                                         INVALIDf,
    251                                         INVALIDf,
    252                                         CMD_A_8_SRC_PKT_OFFSETf,
    253                                         CMD_A_9_SRC_PKT_OFFSETf
    254                                      };
    255 soc_field_t valid_p0_cmds[8] = {
    256                                INVALIDf,
    257                                INVALIDf,
    258                                INVALIDf,
    259                                INVALIDf,
    260                                INVALIDf,
    261                                INVALIDf,
    262                                CMD_A_8_VALIDf,
    263                                CMD_A_9_VALIDf,
    264                             };
    265 
    266 soc_field_t src_pkt_offset_cmds[8] = {
    267                                         CMD_C_4_SRC_PKT_OFFSETf,
    268                                         CMD_C_5_SRC_PKT_OFFSETf,
    269                                         CMD_C_6_SRC_PKT_OFFSETf,
    270                                         CMD_C_7_SRC_PKT_OFFSETf,
    271                                         CMD_C_8_SRC_PKT_OFFSETf,
    272                                         CMD_C_9_SRC_PKT_OFFSETf,
    273                                         CMD_C_10_SRC_PKT_OFFSETf,
    274                                         CMD_C_11_SRC_PKT_OFFSETf
    275                                      };
    276 soc_field_t dest_cont_id_cmds[8] = {
    277                                       CMD_C_4_DEST_CONT_IDf,
    278                                       CMD_C_5_DEST_CONT_IDf,
    279                                       CMD_C_6_DEST_CONT_IDf,
    280                                       CMD_C_7_DEST_CONT_IDf,
    281                                       CMD_C_8_DEST_CONT_IDf,
    282                                       CMD_C_9_DEST_CONT_IDf,
    283                                       CMD_C_10_DEST_CONT_IDf,
    284                                       CMD_C_11_DEST_CONT_IDf
    285                                    };
    286 soc_field_t valid_cmds[8] = {
    287                                CMD_C_4_VALIDf,
    288                                CMD_C_5_VALIDf,
    289                                CMD_C_6_VALIDf,
    290                                CMD_C_7_VALIDf,
    291                                CMD_C_8_VALIDf,
    292                                CMD_C_9_VALIDf,
    293                                CMD_C_10_VALIDf,
    294                                CMD_C_11_VALIDf
    295                             };
    296 
    297 #define _UDF_TD3_GET_HFE_CMD_FORMAT(_parser_, _fmt_) \
    298       do {                                                  \
    299             if (_parser_ == _BCM_UDF_PARSER1) {             \
    300                _fmt_ = IP_PARSER1_HFE_CMD_POLICY_DATAfmt;   \
    301             } else if (_parser_ == _BCM_UDF_PARSER2) {      \
    302                _fmt_ = IP_PARSER2_HFE_CMD_POLICY_DATAfmt;   \
    303             } else if (_parser_ == _BCM_UDF_PARSER0) {      \
    304                _fmt_ = IP_PARSER0_HFE_CMD_POLICY_DATAfmt;   \
    305             } else {                                        \
    306                _fmt_ = INVALIDfmt;                          \
    307             }                                               \
    308          } while(0)
    309 
    310 
    311 /* Local Structure to hold chunk information assigned to UDF object. */
    312 typedef struct _udf_obj_pkt_fmt_hw_cfg_s {
    313    uint8   num_chunks;                           /* Number of chunks. */
    314    uint8   chunk_arr[_BCM_UDF_TD3_MAX_CHUNKS];   /* Chunk array. */
    315    uint16  cmd_bmap[_BCM_UDF_MAX_PARSER_STAGES]; /* CMD Bitmap for each stage */
    316 } _udf_obj_pkt_fmt_hw_cfg_t;
    317 
    318 /* Function Declarations */
    319 #if defined (BCM_WARM_BOOT_SUPPORT)
    320 STATIC int
    321 _bcm_udf_td3_reinit(int unit);
    322 
    323 STATIC int
    324 _bcm_udf_td3_wb_alloc(int unit);
    325 #endif /* BCM_WARM_BOOT_SUPPORT */
    326 STATIC int
    327 _bcm_udf_td3_abstr_pkt_fmt_hw_info_insert(int unit, bcm_udf_abstract_pkt_format_t format,
    328                                    _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_format_info);
    329 
    330 extern int
    331 _bcm_field_td3_qset_udf_chunk_validate(int unit,
    332                                        bcm_udf_chunk_info_t *udf_info,
    333                                        bcm_udf_alloc_hints_t *hints);
    334 
    335 soc_mem_t _udf_hfe_to_hme_mem_conv[11][2] = {
    336                {IP_PARSER0_HME_STAGE_TCAM_DATA_ONLY_0m, IP_PARSER0_HFE_POLICY_TABLE_0m},
    337                {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_0m, IP_PARSER1_HFE_POLICY_TABLE_0m},
    338                {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_1m, IP_PARSER1_HFE_POLICY_TABLE_1m},
    339                {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_2m, IP_PARSER1_HFE_POLICY_TABLE_2m},
    340                {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_3m, IP_PARSER1_HFE_POLICY_TABLE_3m},
    341                {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_4m, IP_PARSER1_HFE_POLICY_TABLE_4m},
    342                {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_0m, IP_PARSER2_HFE_POLICY_TABLE_0m},
    343                {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_1m, IP_PARSER2_HFE_POLICY_TABLE_1m},
    344                {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_2m, IP_PARSER2_HFE_POLICY_TABLE_2m},
    345                {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_3m, IP_PARSER2_HFE_POLICY_TABLE_3m},
    346                {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_4m, IP_PARSER2_HFE_POLICY_TABLE_4m}};
    347 
    348 
    349 STATIC int
    350  _udf_td3_hme_to_hfe_mem_get(soc_mem_t hme_mem, soc_mem_t  *hfe_mem) {
    351      int ct;
    352 
    353      for (ct = 0; ct < 11; ct++) {
    354         if (_udf_hfe_to_hme_mem_conv[ct][0] == hme_mem) {
    355            *hfe_mem = _udf_hfe_to_hme_mem_conv[ct][1];
    356            break;
    357         }
    358      }
    359 
    360      if (ct >= 11) {
    361         return BCM_E_CONFIG;
    362      }
    363 
    364      return BCM_E_NONE;
    365 }
    366 
    367 STATIC int
    368 _udf_td3_opaque_cont_to_chunk_bmap(uint32 opq_cont_bmap, uint32 *chunk_bmap)
    369 {
    370     int id;
    371 
    372     for (id = 0; id < _BCM_UDF_TD3_MAX_CHUNKS; id++) {
    373         if (opq_cont_bmap & (1 << id)) {
    374            *chunk_bmap |= (1 << _bcm_udf_opaque_cont_to_chunk_mapping[id]);
    375         }
    376     }
    377 
    378     return BCM_E_NONE;
    379 }
    380 
    381 STATIC char *
    382 _udf_abstr_pkt_fmt_name(bcm_udf_abstract_pkt_format_t abstr_pkt_fmt)
    383 {
    384     static char *text[] = BCM_UDF_ABSTRACT_PKT_FORMAT;
    385 
    386     if (abstr_pkt_fmt >= COUNTOF(text)) {
    387         return "??";
    388     }
    389     return text[abstr_pkt_fmt];
    390 }
    391 
    392 
    393 /*
    394  * Free UDF device control structure.
    395  */
    396 int _bcm_udf_td3_ctrl_free(int unit, _bcm_udf_td3_ctrl_t *udf_ctrl)
    397 {
    398    if (udf_ctrl == NULL) {
    399       return BCM_E_NONE;
    400    }
    401 
    402    if (udf_ctrl->udf_obj_head != NULL) {
    403       _BCM_UDF_OBJ_NODE_DEL_ALL(_u_, udf_ctrl->udf_obj_head);
    404       udf_ctrl->udf_obj_head = NULL;
    405    }
    406 
    407    _BCM_UDF_FREE(udf_ctrl);
    408    return BCM_E_NONE;
    409 }
    410 
    411 /*
    412  * Function:
    413  *      _bcm_udf_td3_detach
    414  * Purpose:
    415  *      Detaches udf module and cleans software state.
    416  * Parameters:
    417  *      unit            - (IN)      Unit number.
    418  * Returns:
    419  *      BCM_E_XXX
    420  * Notes:
    421  */
    422 int
    423 _bcm_udf_td3_detach(int unit)
    424 {
    425     uint8 stage;
    426     bcm_udf_abstract_pkt_format_t pkt_fmt;
    427     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info;
    428 
    429     /* Free resources related to UDF module */
    430     BCM_IF_ERROR_RETURN(_bcm_udf_td3_ctrl_free(unit, UDF_TD3_CTRL(unit)));
    431 
    432     UDF_TD3_CTRL(unit) = NULL;
    433 
    434     /* Free Abstract Packet Format HW Info. */
    435     for (pkt_fmt = 0; pkt_fmt < bcmUdfAbstractPktFormatLastCount; pkt_fmt++) {
    436         pkt_fmt_hw_info = abstr_pkt_fmt_hw_info[unit][pkt_fmt];
    437         if (pkt_fmt_hw_info != NULL) {
    438            for (stage = 0; stage < _BCM_UDF_MAX_PARSER_STAGES; stage++) {
    439               if (pkt_fmt_hw_info->hfe_profile_ptr[stage] != NULL) {
    440                   _BCM_UDF_FREE(pkt_fmt_hw_info->hfe_profile_ptr[stage]);
    441               }
    442 
    443               if (pkt_fmt_hw_info->cmd_policy_data[stage] != NULL) {
    444                  _BCM_UDF_FREE(pkt_fmt_hw_info->cmd_policy_data[stage]);
    445               }
    446            }
    447 
    448            _BCM_UDF_FREE(abstr_pkt_fmt_hw_info[unit][pkt_fmt]);
    449         }
    450     }
    451 
    452     return BCM_E_NONE;
    453 }
    454 
    455 /*
    456  * Function:
    457  *      _bcm_udf_td3_ctrl_init
    458  * Purpose:
    459  *      Initialize UDF control and internal data structures.
    460  * Parameters:
    461  *      unit           - (IN) bcm device.
    462  *
    463  * Returns:
    464  *      BCM_E_XXX
    465  */
    466 STATIC int
    467 _bcm_udf_td3_ctrl_init(int unit)
    468 {
    469     int alloc_sz;
    470     _bcm_udf_td3_ctrl_t *udf_ctrl = NULL;
    471 
    472     /* Detach module if already installed */
    473     if (UDF_TD3_CTRL(unit) != NULL) {
    474        _bcm_udf_td3_detach(unit);
    475     }
    476 
    477     /* Allocating memory of UDF control structure */
    478     alloc_sz = sizeof(_bcm_udf_td3_ctrl_t);
    479     _BCM_UDF_ALLOC(udf_ctrl, alloc_sz, "UDF td3 control");
    480     if (udf_ctrl == NULL) {
    481         return BCM_E_MEMORY;
    482     }
    483 
    484     UDF_TD3_CTRL(unit) = udf_ctrl;
    485 
    486     /* UDF Range Checker support */
    487     udf_ctrl->flags |= _BCM_UDF_TD3_CTRL_RANGE_CHECK;
    488 
    489     /*
    490      * Update UDF Common control fields.
    491      */
    492     UDF_CONTROL(unit)->gran = _BCM_UDF_OFFSET_GRAN2;
    493     UDF_CONTROL(unit)->num_chunks = _BCM_UDF_OFFSET_CHUNKS16;
    494     UDF_CONTROL(unit)->min_obj_id = _BCM_UDF_TD3_OBJ_MIN_ID;
    495     UDF_CONTROL(unit)->max_obj_id = _BCM_UDF_TD3_OBJ_MAX_ID;
    496     UDF_CONTROL(unit)->parse_limit = _BCM_UDF_TD3_MAX_PARSE_LIMIT;
    497     UDF_CONTROL(unit)->max_udfs = _BCM_UDF_TD3_MAX_OBJECTS(unit);
    498     return BCM_E_NONE;
    499 }
    500 
    501 
    502 int
    503 _bcm_udf_abstr_pkt_fmt_flex_init(int unit)
    504 {
    505     int rv;
    506     uint32 stg, num_stage;
    507     uint32 *hfe_prof_ptr_arr[_BCM_UDF_MAX_PARSER_STAGES];
    508     uint32 hfe_prof_ptr_arr_len[_BCM_UDF_MAX_PARSER_STAGES] = {0};
    509     bcm_udf_abstract_pkt_format_t pkt_fmt;
    510     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info;
    511     soc_cancun_udf_stage_info_t udf_ccinfo_arr[_BCM_UDF_MAX_PARSER_STAGES];
    512 
    513     for (pkt_fmt = 0; pkt_fmt < bcmUdfAbstractPktFormatLastCount; pkt_fmt++) {
    514         pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt);
    515         if (pkt_fmt_hw_info == NULL) {
    516            LOG_DEBUG(BSL_LS_BCM_UDF, (BSL_META_U(unit,
    517                           "UDF Abstract pkt fmt '%s' not found in flex db.\n\r"),
    518                           _udf_abstr_pkt_fmt_name(pkt_fmt)));
    519            continue;
    520         }
    521 
    522         num_stage = 0;
    523         sal_memset(udf_ccinfo_arr, 0x0,
    524                    sizeof(soc_cancun_udf_stage_info_t) * _BCM_UDF_MAX_PARSER_STAGES);
    525         rv = soc_cancun_udf_abstr_type_info_get(unit, pkt_fmt,
    526                                                 pkt_fmt_hw_info->parser,
    527                                                 0, NULL, NULL,
    528                                                 &num_stage,
    529                                                 hfe_prof_ptr_arr_len);
    530         if (SOC_SUCCESS(rv)) {
    531            if (hfe_prof_ptr_arr_len[0] == 0) {
    532               LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
    533                           "UDF Abstract pkt fmt '%s' has null hfe_prof_ptr.\n\r"),
    534                           _udf_abstr_pkt_fmt_name(pkt_fmt)));
    535               continue;
    536            }
    537 
    538            for (stg = 0; stg < num_stage; stg++) {
    539                hfe_prof_ptr_arr[stg] = NULL;
    540                _BCM_UDF_ALLOC(hfe_prof_ptr_arr[stg],
    541                               sizeof(uint32) * hfe_prof_ptr_arr_len[stg],
    542                               "UDF Hfe Prof Ptr Alloc.");
    543            }
    544 
    545            rv = soc_cancun_udf_abstr_type_info_get(unit, pkt_fmt,
    546                                                 pkt_fmt_hw_info->parser,
    547                                                 num_stage, hfe_prof_ptr_arr,
    548                                                 udf_ccinfo_arr,
    549                                                 NULL, NULL);
    550         }
    551 
    552         if (SOC_FAILURE(rv)) {
    553            if (rv == SOC_E_NOT_FOUND) {
    554               LOG_DEBUG(BSL_LS_BCM_UDF, (BSL_META_U(unit,
    555                           "UDF Abstract pkt fmt '%s' not found in flex db.\n\r"),
    556                           _udf_abstr_pkt_fmt_name(pkt_fmt)));
    557 
    558               continue;
    559            }
    560            LOG_DEBUG(BSL_LS_BCM_UDF, (BSL_META_U(unit,
    561                      "UDF Flex DB Error for Abstract pkt fmt '%s'.\n\r"),
    562                      _udf_abstr_pkt_fmt_name(pkt_fmt)));
    563            continue;
    564         }
    565 
    566         pkt_fmt_hw_info->num_stages = num_stage;
    567         for (stg = 0; stg < num_stage; stg++) {
    568             pkt_fmt_hw_info->base_offset = udf_ccinfo_arr[stg].start_pos;
    569             rv = _udf_td3_hme_to_hfe_mem_get(udf_ccinfo_arr[stg].policy_mem,
    570                                      &pkt_fmt_hw_info->stage_policy_mem[stg]);
    571             if (BCM_FAILURE(rv)) {
    572                 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
    573                           "Unknown Policy Mem from flex db:%d for abstr_type:[%s]\n\r"),
    574                           pkt_fmt_hw_info->stage_policy_mem[stg], _udf_abstr_pkt_fmt_name(pkt_fmt)));
    575                 return rv;
    576             }
    577 
    578             pkt_fmt_hw_info->hfe_prof_ptr_arr_len[stg] = udf_ccinfo_arr[stg].hfe_prof_ptr_arr_len;
    579             pkt_fmt_hw_info->hfe_profile_ptr[stg] = udf_ccinfo_arr[stg].hfe_profile_ptr;
    580             pkt_fmt_hw_info->num_cmds[stg] = (udf_ccinfo_arr[stg].size)/2;
    581             pkt_fmt_hw_info->max_extract_bytes += (pkt_fmt_hw_info->num_cmds[stg] * 2);
    582             rv = _udf_td3_opaque_cont_to_chunk_bmap(udf_ccinfo_arr[stg].unavail_contbmap,
    583                                                     &pkt_fmt_hw_info->unavail_chunk_bmap);
    584             if (BCM_FAILURE(rv)) {
    585                 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
    586                           "Unknown Unavail Opaque container from flex db:0x%x for abstr_type:[%s]\n\r"),
    587                           udf_ccinfo_arr[stg].unavail_contbmap, _udf_abstr_pkt_fmt_name(pkt_fmt)));
    588                 return rv;
    589             }
    590 
    591             LOG_DEBUG(BSL_LS_BCM_UDF, (BSL_META_U(unit,
    592                "UDF Abstract pkt fmt %d-'%s': max_extract_bytes:%d"
    593                  " hfe_profile_ptr:%d mem:%d unavail_chunk_bmap:0x%x.\n\r"), pkt_fmt,
    594                  _udf_abstr_pkt_fmt_name(pkt_fmt), pkt_fmt_hw_info->max_extract_bytes,
    595                  pkt_fmt_hw_info->hfe_profile_ptr[stg][0], pkt_fmt_hw_info->stage_policy_mem[stg],
    596                  pkt_fmt_hw_info->unavail_chunk_bmap));
    597         }
    598     }
    599 
    600     return BCM_E_NONE;
    601 }
    602 
    603 /*
    604  * Initialize Abstract Packet Formats with offset and default values.
    605  */
    606 int
    607 _bcm_udf_abstr_pkt_format_info_init(int unit)
    608 {
    609     bcm_udf_abstract_pkt_format_t pkt_fmt;
    610     _BCM_UDF_ABSTRACT_PKT_FORMAT_MAPPING_DECL
    611     /* Validate whether UDF module is attached */
    612     if (UDF_TD3_CTRL(unit) == NULL) {
    613         return BCM_E_INIT;
    614     }
    615 
    616     for (pkt_fmt = 0; pkt_fmt < bcmUdfAbstractPktFormatLastCount; pkt_fmt++) {
    617         if (abstr_pkt_fmt_hw_info[unit][pkt_fmt] != NULL) {
    618            sal_free(abstr_pkt_fmt_hw_info[unit][pkt_fmt]);
    619            abstr_pkt_fmt_hw_info[unit][pkt_fmt] = NULL;
    620         }
    621 
    622         _BCM_UDF_ALLOC(abstr_pkt_fmt_hw_info[unit][pkt_fmt],
    623                    sizeof(_bcm_udf_td3_abstr_pkt_fmt_hw_info_t),
    624                    "UDF Abstract Pkt Format INIT");
    625         if (abstr_pkt_fmt_hw_info[unit][pkt_fmt] == NULL) {
    626            return BCM_E_MEMORY;
    627         }
    628     }
    629 
    630     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatLlc, 1);
    631     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerLlc, 2);
    632     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3, 1);
    633     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3, 2);
    634     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownNonIp, 1);
    635     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerKnownNonIp, 2);
    636     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3Mim, 1);
    637     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3FcoeStdEncap, 1);
    638     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3FcoeVftIfr, 1);
    639     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsOneLabel, 1);
    640     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsTwoLabel, 1);
    641     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsThreeLabel, 1);
    642     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsFourLabel, 1);
    643     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsMoreThanFourLabel, 1);
    644     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL4, 1);
    645     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL4, 2);
    646     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpUnknownL5, 1);
    647     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUdpUnknownL5, 2);
    648     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpGpeGeneve, 1);
    649     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpBfd, 1);
    650     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUdpBfd, 2);
    651     /* _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpBfdUnknown, 1); */
    652     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpVxlan, 1);
    653     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdp1588, 1);
    654     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatTcpUnknownL5, 1);
    655     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerTcpUnknownL5, 2);
    656     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatSctpUnknownL5, 1);
    657     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerSctpUnknownL5, 2);
    658     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGreWithoutKey, 1);
    659     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGreWithKey, 1);
    660     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGreWithoutChecksumRouting, 1);
    661     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2GreWithoutChecksumRouting, 1);
    662     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2GreWithoutRouting, 1);
    663     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatAchNonIp, 2);
    664     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpINT, 1);
    665     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatTcpUnknownL5WithIpExtnHdr, 1);
    666     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3GreUnknownPayload, 1);
    667     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGreWithKeyRouting, 1);
    668     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2GreWithKeyRouting, 1);
    669     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUdp1588, 2);
    670     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatTcpINT, 1);
    671     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3FcoeUnknownRctl, 1);
    672     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd0, 3);
    673     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd0EHType0, 3);
    674     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd0EHType1, 3);
    675     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd0EHType2, 3);
    676     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd2, 3);
    677     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd2EHType0, 3);
    678     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd2EHType1, 3);
    679     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd2EHType2, 3);
    680     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGpeIOAM, 1);
    681     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownMplsMcast, 1);
    682     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatLoopbackHdrType0, 3);
    683     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatLoopbackHdrType1, 3);
    684     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv4Fragmented, 1);
    685     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv4FragmentedWithOptions, 1);
    686     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv4WithoutOptions, 1);
    687     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv4WithOptions, 1);
    688     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv6, 1);
    689     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2, 3);
    690     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2Untagged, 1);
    691     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2OuterVlanTag, 1);
    692     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2InnerVlanTag, 1);
    693     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2DoubleVlanTag, 1);
    694     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2GbpTag, 1);
    695     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2OuterVlanWithGbpTag, 1);
    696     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2InnerVlanWithGbpTag, 1);
    697     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2DoubleVlanWithGbpTag, 1);
    698     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2Vntag, 1);
    699     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2OuterVlanWithVntag, 1);
    700     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2InnerVlanWithVntag, 1);
    701     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2DoubleVlanWithVntag, 1);
    702     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2Etag, 1);
    703     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2OuterVlanEtag, 1);
    704     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2InnerVlanEtag, 1);
    705     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2DoubleVlanEtag, 1);
    706     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL3Ipv4, 2);
    707     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL3Ipv4Fragmented, 2);
    708     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL3Ipv6, 2);
    709     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2Untagged, 2);
    710     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2OuterVlanTag, 2);
    711     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2InnerVlanTag, 2);
    712     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2DoubleVlanTag, 2);
    713     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2GbpTag, 2);
    714     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2OuterVlanWithGbpTag, 2);
    715     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2InnerVlanWithGbpTag, 2);
    716     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2DoubleVlanWithGbpTag, 2);
    717     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomEtherType1, 1);
    718     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomEtherType2, 1);
    719     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomIpProtocol1, 1);
    720     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomIpProtocol2, 1);
    721     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomUdpDstPort1, 1);
    722     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomUdpDstPort2, 1);
    723     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomEtherType1, 2);
    724     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomEtherType2, 2);
    725     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomIpProtocol1, 2);
    726     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomIpProtocol2, 2);
    727     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomUdpDstPort1, 2);
    728     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomUdpDstPort2, 2);
    729     _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpProbeBasedINT, 1);
    730 
    731     return _bcm_udf_abstr_pkt_fmt_flex_init(unit);
    732 }
    733 
    734 
    735 /*
    736  * Reset HFE Profile indices for all abstract pkt formats.
    737  */
    738 STATIC int
    739 _bcm_udf_td3_hfe_profile_hw_init(int unit)
    740 {
    741     int rv;
    742     int len;
    743     uint8 stage;
    744     soc_format_t fmt;
    745     soc_mem_t policy_mem;
    746     uint8 buf[100];
    747     uint32 hfe_profile_ptr;
    748     uint8 *cmd_pol_data_buf = NULL;
    749     bcm_udf_abstract_pkt_format_t pkt_fmt;
    750     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info;
    751 
    752     for (pkt_fmt = bcmUdfAbstractPktFormatLlc;
    753          pkt_fmt < bcmUdfAbstractPktFormatLastCount;
    754          pkt_fmt++) {
    755         pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt);
    756         if (pkt_fmt_hw_info == NULL) {
    757            continue;
    758         }
    759 
    760         for (stage = 0; stage < pkt_fmt_hw_info->num_stages; stage++) {
    761             policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage];
    762             hfe_profile_ptr = pkt_fmt_hw_info->hfe_profile_ptr[stage][0];
    763 
    764             if (policy_mem == INVALIDm) {
    765                LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
    766                           "Invalid Policy mem for Abstract pkt fmt '%s', stage:%d.\n\r"),
    767                           _udf_abstr_pkt_fmt_name(pkt_fmt), stage));
    768                return BCM_E_INTERNAL;
    769             }
    770 
    771             _UDF_TD3_GET_HFE_CMD_FORMAT(pkt_fmt_hw_info->parser, fmt);
    772             if (fmt == INVALIDfmt) {
    773                return BCM_E_INTERNAL;
    774             }
    775 
    776             sal_memset(buf, 0x0, sizeof(buf));
    777             rv = soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY,
    778                               hfe_profile_ptr, (uint32 *) buf);
    779             BCM_IF_ERROR_RETURN(rv);
    780 
    781             len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf);
    782             cmd_pol_data_buf = NULL;
    783             _BCM_UDF_ALLOC(cmd_pol_data_buf, len, "UDF default CMD Policy data");
    784             if (cmd_pol_data_buf == NULL) {
    785                return BCM_E_MEMORY;
    786             }
    787 
    788             soc_mem_field_get(unit, policy_mem, (uint32 *)buf,
    789                           CMD_POLICY_DATAf, (uint32 *)cmd_pol_data_buf);
    790 
    791             pkt_fmt_hw_info->cmd_policy_data[stage] = cmd_pol_data_buf;
    792 
    793 #if 0
    794             for (i = 0; i < _BCM_UDF_MAX_POLICY_CMDS; i++) {
    795                 soc_format_field32_set(unit, fmt, (uint32 *)f_buf,
    796                                                 valid_cmds[i], 0);
    797             }
    798 
    799             soc_mem_field_set(unit, policy_mem, (uint32 *)buf,
    800                               CMD_POLICY_DATAf, (uint32 *)f_buf);
    801 
    802             rv = soc_mem_write(unit, policy_mem, MEM_BLOCK_ANY,
    803                                hfe_profile_ptr, (uint32 *)buf);
    804             BCM_IF_ERROR_RETURN(rv);
    805 #endif
    806 
    807         }
    808     }
    809 
    810     return BCM_E_NONE;
    811 }
    812 
    813 /*
    814  * Function:
    815  *      _bcm_udf_td3_init
    816  * Purpose:
    817  *      initializes/ReInitializes the UDF module.
    818  * Parameters:
    819  *      unit  - (IN) Unit number.
    820  * Returns:
    821  *      BCM_E_XXX
    822  * Notes:
    823  */
    824 int
    825 _bcm_udf_td3_init(int unit)
    826 {
    827     int rv;
    828 
    829     /* Init control structures */
    830     rv = _bcm_udf_td3_ctrl_init(unit);
    831     BCM_IF_ERROR_GOTO_CLEANUP(rv);
    832 
    833     /*
    834      * Initialize Abstract Packet Formats with offset
    835      * and default values.
    836      */
    837     rv = _bcm_udf_abstr_pkt_format_info_init(unit);
    838     BCM_IF_ERROR_GOTO_CLEANUP(rv);
    839 
    840     /* Initialize hardware HFE Profile Indices with default values */
    841     rv = _bcm_udf_td3_hfe_profile_hw_init(unit);
    842     BCM_IF_ERROR_GOTO_CLEANUP(rv);
    843 #if defined (BCM_WARM_BOOT_SUPPORT)
    844     if (SOC_WARM_BOOT(unit)) {
    845         rv = _bcm_udf_td3_reinit(unit);
    846         BCM_IF_ERROR_GOTO_CLEANUP(rv);
    847     } else
    848 #endif /* BCM_WARM_BOOT_SUPPORT */
    849     {
    850 #if defined (BCM_WARM_BOOT_SUPPORT)
    851         rv = _bcm_udf_td3_wb_alloc(unit);
    852         BCM_IF_ERROR_GOTO_CLEANUP(rv);
    853 #endif /* BCM_WARM_BOOT_SUPPORT */
    854     }
    855 
    856     return BCM_E_NONE;
    857 
    858 cleanup:
    859     (void) _bcm_udf_td3_detach(unit);
    860     return rv;
    861 }
    862 
    863 STATIC int
    864 _bcm_udf_td3_abstr_pkt_fmt_hw_info_insert(int unit, bcm_udf_abstract_pkt_format_t abstr_pkt_fmt,
    865                                           _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_format_info)
    866 {
    867     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info = NULL;
    868 
    869     if (pkt_format_info == NULL) {
    870        return BCM_E_INTERNAL;
    871     }
    872 
    873     pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, abstr_pkt_fmt);
    874     if (pkt_fmt_hw_info == NULL) {
    875        return BCM_E_INTERNAL;
    876     }
    877 
    878     sal_memcpy(pkt_fmt_hw_info, pkt_format_info,
    879                sizeof(_bcm_udf_td3_abstr_pkt_fmt_hw_info_t));
    880 
    881     return BCM_E_NONE;
    882 }
    883 
    884 /* Routine to retrieve chunks from the bitmap. */
    885 int
    886 _udf_chunk_bmap_to_chunks(uint32 chunk_bmap, uint8 *num_chunks, uint8 *chunk_arr)
    887 {
    888     uint8 bit, i;
    889     uint8 num = 0;
    890 
    891     for (i = 0; i < _BCM_UDF_TD3_MAX_CHUNKS; i++) {
    892         bit = (chunk_bmap >> i) & 1;
    893         if (bit) {
    894            if (chunk_arr != NULL) {
    895               chunk_arr[num] = i;
    896            }
    897            num++;
    898         }
    899     }
    900 
    901     *num_chunks = num;
    902 
    903     return BCM_E_NONE;
    904 }
    905 
    906 /* To sanitize udf_info/pkt_format_info input structures */
    907 STATIC int
    908 _udf_td3_sanitize_inputs(int unit, bcm_udf_chunk_info_t *udf_info,
    909                          bcm_udf_alloc_hints_t *hints,
    910                          bcm_udf_id_t *udf_id)
    911 {
    912     uint8 num_chunks = 0;
    913 
    914     /* NULL check */
    915     BCM_IF_NULL_RETURN_PARAM(udf_id);
    916     BCM_IF_NULL_RETURN_PARAM(udf_info);
    917 
    918     /* start and width should be at byte boundary */
    919     if (((udf_info->offset % 8) != 0) || ((udf_info->width % 8) != 0)) {
    920        return BCM_E_PARAM;
    921     }
    922 
    923     /* start and width should be less than max byte selection */
    924     if (BITS2BYTES(udf_info->offset + udf_info->width) >
    925                    UDF_CONTROL(unit)->parse_limit) {
    926        return BCM_E_PARAM;
    927     }
    928 
    929     /* check if pkt format is in valid range */
    930     _BCM_UDF_ABSTR_PKT_FORMAT_VALIDATE(unit, udf_info->abstract_pkt_format);
    931 
    932     /* Extraction bytes (width) Validate */
    933     _BCM_UDF_EXTRACTION_BYTES_VALIDATE(unit, udf_info->abstract_pkt_format,
    934                                        BITS2BYTES(udf_info->width));
    935 
    936     if (hints != NULL) {
    937         /* Replace flag is not supported. */
    938         if (hints->flags & BCM_UDF_CREATE_O_REPLACE) {
    939             return BCM_E_PARAM;
    940         }
    941 
    942         /* Validate UDF ID */
    943         if (hints->flags & BCM_UDF_CREATE_O_WITHID) {
    944            _BCM_UDF_ID_VALIDATE(unit, *udf_id);
    945         }
    946 
    947         /* check if chip supports Range Check */
    948         if (hints->flags & BCM_UDF_CREATE_O_RANGE_CHECK) {
    949            /* Check if device supports Range Check. */
    950            if (!(UDF_TD3_CTRL(unit)->flags & _BCM_UDF_TD3_CTRL_RANGE_CHECK)) {
    951               return BCM_E_PARAM;
    952            }
    953 
    954            /*
    955             * If RANGE_CHECK Flag is set, chunk bitmap should be
    956             * as per the device supported chunks.
    957             */
    958            if (udf_info->chunk_bmap != _BCM_UDF_TD3_RANGE_CHUNK_BMAP) {
    959               return BCM_E_PARAM;
    960            }
    961         }
    962     }
    963 
    964     /* Chunk Validate */
    965     /* Validate whether the given chunk bmap is part of reserved chunk bitmap */
    966     _BCM_UDF_CHUNK_VALIDATE(unit, udf_info->chunk_bmap, udf_info->abstract_pkt_format);
    967 
    968     /* Validate given chunk_bmap matches with width */
    969     _udf_chunk_bmap_to_chunks(udf_info->chunk_bmap, &num_chunks, NULL);
    970     if (BITS2BYTES(udf_info->width) != _BCM_UDF_CHUNK_TO_BYTE(num_chunks)) {
    971        return BCM_E_PARAM;
    972     }
    973 
    974     if (hints != NULL) {
    975         /* Validate whether given chunk bmap used by qualifiers in given qset */
    976         SOC_IF_ERROR_RETURN(_bcm_field_td3_qset_udf_chunk_validate(unit, udf_info, hints));
    977     }
    978 
    979     /* Check whether chunks given in the bitmap are already in use */
    980     _BCM_UDF_OBJECT_CHUNK_IN_USE_VALIDATE(unit, udf_info->abstract_pkt_format,
    981                                           udf_info->chunk_bmap);
    982 
    983     return BCM_E_NONE;
    984 }
    985 
    986 /*
    987  * Function:
    988  *      _bcm_udf_td3_object_info_add
    989  * Purpose:
    990  *      To convert the UDF info to object info and add to the linked list.
    991  * Parameters:
    992  *      unit            - (IN)      Unit number.
    993  *      udf_info        - (IN)      UDF info to be added to linked list.
    994  *      object_info     - (INOUT)   Reference to allocated object info.
    995  * Returns:
    996  *      BCM_E_XXX
    997  * Notes:
    998  */
    999 STATIC int
   1000 _bcm_udf_td3_object_info_add(int unit, bcm_udf_chunk_info_t *udf_info,
   1001                              _bcm_udf_td3_obj_info_t **obj_info)
   1002 {
   1003     /* Allocate memory for UDF object info. */
   1004     _BCM_UDF_ALLOC(*obj_info, sizeof(_bcm_udf_td3_obj_info_t),
   1005                    "UDF object info.");
   1006     if (*obj_info == NULL) {
   1007        return BCM_E_MEMORY;
   1008     }
   1009 
   1010     /* Insert user inputs into the object_info struct */
   1011     (*obj_info)->width = BITS2BYTES(udf_info->width);
   1012     (*obj_info)->offset = BITS2BYTES(udf_info->offset);
   1013     (*obj_info)->chunk_bmap = udf_info->chunk_bmap;
   1014     (*obj_info)->abstr_pkt_fmt = udf_info->abstract_pkt_format;
   1015     (*obj_info)->next = NULL;
   1016     (*obj_info)->prev = NULL;
   1017 
   1018     /* Add obj_info item to the linked list */
   1019     _BCM_UDF_OBJ_NODE_ADD(unit, (*obj_info),
   1020                           UDF_TD3_CTRL(unit)->udf_obj_head);
   1021     return BCM_E_NONE;
   1022 }
   1023 
   1024 /*
   1025  * Function:
   1026  *      _bcm_udf_td3_object_info_delete
   1027  * Purpose:
   1028  *      Remove the UDF object info from the database for a given object.
   1029  * Parameters:
   1030  *      unit         - (IN)  Unit number.
   1031  *      obj_info     - (IN)  Reference to allocated object info.
   1032  * Returns:
   1033  *      BCM_E_XXX
   1034  * Notes:
   1035  */
   1036 STATIC int
   1037 _bcm_udf_td3_object_info_delete(int unit, _bcm_udf_td3_obj_info_t *obj_info)
   1038 {
   1039     if (obj_info == NULL) {
   1040        return BCM_E_PARAM;
   1041     }
   1042 
   1043     /* Delete obj_info from the linked list */
   1044     _BCM_UDF_OBJ_NODE_DEL(unit, obj_info, UDF_TD3_CTRL(unit)->udf_obj_head);
   1045     _BCM_UDF_FREE(obj_info);
   1046     return BCM_E_NONE;
   1047 }
   1048 
   1049 /*
   1050  * Function:
   1051  *      _bcm_udf_td3_object_info_get
   1052  * Purpose:
   1053  *      Retrieves UDF object info for the given udf id.
   1054  * Parameters:
   1055  *      unit         - (IN)      Unit number.
   1056  *      udf_id       - (IN)      UDF Id.
   1057  *      obj_info     - (INOUT)   Retrieve udf object info.
   1058  * Returns:
   1059  *      BCM_E_XXX
   1060  * Notes:
   1061  */
   1062 int
   1063 _bcm_udf_td3_object_info_get(
   1064     int unit,
   1065     bcm_udf_id_t udf_id,
   1066     _bcm_udf_td3_obj_info_t **obj_info)
   1067 {
   1068     _BCM_UDF_OBJ_NODE_GET(unit, udf_id,
   1069                           UDF_TD3_CTRL(unit)->udf_obj_head,
   1070                           *obj_info);
   1071 
   1072     if (*obj_info == NULL) {
   1073        return BCM_E_NOT_FOUND;
   1074     }
   1075 
   1076     return BCM_E_NONE;
   1077 }
   1078 
   1079 /*
   1080  * To allocate running id for UDF IDs.
   1081  */
   1082 static int
   1083 _bcm_udf_td3_object_running_id_alloc(int unit, bcm_udf_id_t *udf_id)
   1084 {
   1085     int rv;
   1086     int id;
   1087     int min_id, max_id;
   1088     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   1089 
   1090     min_id = UDF_CONTROL(unit)->min_obj_id;
   1091     max_id = UDF_CONTROL(unit)->max_obj_id;
   1092 
   1093     id = _BCM_UDF_OBJ_ID_RUNNING(unit);
   1094 
   1095     if (id > max_id) {
   1096         for (id = min_id; id <= max_id; id++) {
   1097             rv = _bcm_udf_td3_object_info_get(unit, id, &obj_info);
   1098             if (BCM_E_NOT_FOUND == rv) {
   1099                break;
   1100             }
   1101 
   1102             if (BCM_FAILURE(rv)) {
   1103                return BCM_E_INTERNAL;
   1104             }
   1105         }
   1106 
   1107         /* All the udf ids are used up */
   1108         if (id > max_id) {
   1109            return BCM_E_FULL;
   1110         }
   1111     }
   1112 
   1113     *udf_id = id;
   1114 
   1115     return BCM_E_NONE;
   1116 }
   1117 
   1118 static int _udf_parser0_chunk_to_cmd_get(int unit, uint32 chunk_bmap,
   1119                                          uint16 *cmd_bmap)
   1120 {
   1121     uint8 chunk;
   1122 
   1123     chunk = _bcm_udf_opaque_cont_to_chunk_mapping[2];
   1124     if (chunk_bmap & (1 << chunk)) {
   1125         *cmd_bmap |= (1 << 6);
   1126     }
   1127 
   1128     chunk = _bcm_udf_opaque_cont_to_chunk_mapping[0];
   1129     if (chunk_bmap & (1 << chunk)) {
   1130         *cmd_bmap |= (1 << 7);
   1131     }
   1132 
   1133     return BCM_E_NONE;
   1134 }
   1135 
   1136 static int
   1137 _udf_td3_hw_policy_cmd_alloc(
   1138     int unit,
   1139     _bcm_udf_td3_obj_info_t *obj_info,
   1140     _udf_obj_pkt_fmt_hw_cfg_t *cfg_data)
   1141 {
   1142    int i;
   1143    uint8 stage;
   1144    uint8 start_cmd;
   1145    uint8 num_cmds_required;
   1146    bcm_udf_abstract_pkt_format_t pkt_fmt;
   1147    _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *hw_info = NULL;
   1148 
   1149    pkt_fmt = obj_info->abstr_pkt_fmt;
   1150    hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt);
   1151    if (hw_info == NULL) {
   1152       return BCM_E_INTERNAL;
   1153    }
   1154 
   1155    if (hw_info->chunk_bmap_used & obj_info->chunk_bmap) {
   1156       return BCM_E_PARAM;
   1157    }
   1158 
   1159    BCM_IF_ERROR_RETURN(_udf_chunk_bmap_to_chunks(obj_info->chunk_bmap,
   1160                                                  &cfg_data->num_chunks,
   1161 						 cfg_data->chunk_arr));
   1162 
   1163    num_cmds_required = (hw_info->parser == _BCM_UDF_PARSER0) ?
   1164                                         0 : obj_info->width/2;
   1165 
   1166    for (stage = 0; stage < hw_info->num_stages; stage++) {
   1167       if (hw_info->stage_policy_mem[stage] != INVALIDm) {
   1168           if (hw_info->parser == _BCM_UDF_PARSER0) {
   1169               BCM_IF_ERROR_RETURN(_udf_parser0_chunk_to_cmd_get(unit,
   1170                                       obj_info->chunk_bmap,
   1171                                       &cfg_data->cmd_bmap[stage]));
   1172               hw_info->valid_cmd_bmap[stage] |= cfg_data->cmd_bmap[stage];
   1173               continue;
   1174           }
   1175 
   1176           start_cmd = _BCM_UDF_MAX_POLICY_CMDS - hw_info->num_cmds[stage];
   1177           for (i = start_cmd; i < _BCM_UDF_MAX_POLICY_CMDS; i++) {
   1178              if (num_cmds_required == 0) {
   1179                 break;
   1180              }
   1181 
   1182              /* Allocate CMD if the bit is not set */
   1183              if ((hw_info->valid_cmd_bmap[stage] & (1 << i)) == 0) {
   1184                 cfg_data->cmd_bmap[stage] |= (1 << i);
   1185                 num_cmds_required--;
   1186              }
   1187           }
   1188           hw_info->valid_cmd_bmap[stage] |= cfg_data->cmd_bmap[stage];
   1189       }
   1190    }
   1191 
   1192    if (num_cmds_required != 0) {
   1193       return BCM_E_INTERNAL;
   1194    }
   1195 
   1196    return BCM_E_NONE;
   1197 }
   1198 
   1199 /*
   1200  * Install HW Policy Commands for given UDF object.
   1201  */
   1202 static int
   1203 _udf_td3_hw_policy_cmd_install(
   1204     int unit,
   1205     _bcm_udf_td3_obj_info_t *obj_info,
   1206     _udf_obj_pkt_fmt_hw_cfg_t *cfg_data)
   1207 {
   1208    int rv;
   1209    uint8 i;
   1210    uint8 gran = 2;
   1211    uint8 chunk;
   1212    uint8 stage;
   1213    uint8 chunk_ct = 0;
   1214    uint8 curr_chunk = 0;
   1215    uint8 hfe_ct;
   1216    uint8 start_cmd;
   1217    uint32 offset = 0;
   1218    uint32 curr_offset = 0;
   1219    uint32 dest_cont_id;
   1220    soc_format_t fmt;
   1221    uint32 cancun_ver;
   1222    uint8 skip_hw_change = 0;
   1223    bcm_udf_abstract_pkt_format_t pkt_fmt;
   1224    uint8 f_buf[_BCM_UDF_MAX_PARSER_STAGES][50];
   1225    uint8 buf[_BCM_UDF_MAX_PARSER_STAGES][100];
   1226    uint16 cmd_bmap[_BCM_UDF_MAX_PARSER_STAGES];
   1227    uint8 null_update[_BCM_UDF_MAX_PARSER_STAGES] = {0};
   1228    soc_mem_t policy_mem[_BCM_UDF_MAX_PARSER_STAGES];
   1229    uint32 hfe_profile_ptr[_BCM_UDF_MAX_PARSER_STAGES];
   1230    _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *hw_info = NULL;
   1231 
   1232    pkt_fmt = obj_info->abstr_pkt_fmt;
   1233    hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt);
   1234 
   1235    offset = obj_info->offset;
   1236 
   1237    sal_memset(f_buf, 0x0, sizeof(f_buf));
   1238    sal_memset(buf, 0x0, sizeof(buf));
   1239 
   1240    BCM_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver));
   1241    if (SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) {
   1242        if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) ||
   1243            (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) {
   1244            skip_hw_change = 1;
   1245        }
   1246    }
   1247 
   1248    for (stage = 0; stage < hw_info->num_stages; stage++) {
   1249        cmd_bmap[stage] = cfg_data->cmd_bmap[stage];
   1250        policy_mem[stage] = hw_info->stage_policy_mem[stage];
   1251 
   1252        start_cmd = _BCM_UDF_MAX_POLICY_CMDS - hw_info->num_cmds[stage];
   1253        if (policy_mem[stage] == INVALIDm) {
   1254           LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
   1255                    "Invalid Policy mem for Abstract pkt fmt '%s', stage:%d.\n\r"),
   1256                    _udf_abstr_pkt_fmt_name(pkt_fmt), stage));
   1257           return BCM_E_INTERNAL;
   1258        }
   1259 
   1260        if (skip_hw_change == 1) {
   1261           continue;
   1262        }
   1263 
   1264        _UDF_TD3_GET_HFE_CMD_FORMAT(hw_info->parser, fmt);
   1265        if (fmt == INVALIDfmt) {
   1266           return BCM_E_INTERNAL;
   1267        }
   1268 
   1269        null_update[stage] = 0;
   1270        curr_chunk = chunk_ct;
   1271        curr_offset = offset;
   1272        for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stage]; hfe_ct++) {
   1273            hfe_profile_ptr[stage] = hw_info->hfe_profile_ptr[stage][hfe_ct];;
   1274 
   1275            rv = soc_mem_read(unit, policy_mem[stage], MEM_BLOCK_ANY,
   1276                              hfe_profile_ptr[stage], (uint32 *) buf[stage]);
   1277            BCM_IF_ERROR_RETURN(rv);
   1278 
   1279            soc_mem_field_get(unit, policy_mem[stage], (uint32 *)buf[stage],
   1280                              CMD_POLICY_DATAf, (uint32 *)f_buf[stage]);
   1281 
   1282            for (i = start_cmd; i < _BCM_UDF_MAX_POLICY_CMDS; i++) {
   1283                if (cmd_bmap[stage] & (1 << i)) {
   1284                   if (hw_info->parser == _BCM_UDF_PARSER0) {
   1285                       soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1286                                         src_pkt_offset_p0_cmds[i], offset * 8);
   1287                       soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1288                                                           valid_p0_cmds[i], 1);
   1289                   } else {
   1290                       soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1291                                                src_pkt_offset_cmds[i], offset);
   1292                       soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1293                                                              valid_cmds[i], 1);
   1294                       if (chunk_ct <= cfg_data->num_chunks) {
   1295                          chunk = cfg_data->chunk_arr[chunk_ct];
   1296                          dest_cont_id = _bcm_udf_chunk_to_dest_cont_id_mapping[chunk];
   1297                          soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1298                                                dest_cont_id_cmds[i], dest_cont_id);
   1299                          chunk_ct++;
   1300                       } else {
   1301                          return BCM_E_INTERNAL;
   1302                       }
   1303                   }
   1304                   offset += gran;
   1305                } else if (hw_info->chunk_bmap_used == 0) {
   1306                   if (hw_info->parser == _BCM_UDF_PARSER0) {
   1307                       soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1308                                                           valid_p0_cmds[i], 0);
   1309                   } else {
   1310                       soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1311                                                              valid_cmds[i], 0);
   1312                   }
   1313                   null_update[stage] = 1;
   1314                }
   1315            }
   1316 
   1317            if (cmd_bmap[stage] || (null_update[stage])) {
   1318               soc_mem_field_set(unit, policy_mem[stage], (uint32 *)buf[stage],
   1319                              CMD_POLICY_DATAf, (uint32 *)f_buf[stage]);
   1320            }
   1321 
   1322            if ((hfe_ct + 1) < hw_info->hfe_prof_ptr_arr_len[stage]) {
   1323                chunk_ct = curr_chunk;
   1324                offset = curr_offset;
   1325            }
   1326        }
   1327    }
   1328 
   1329    if (skip_hw_change == 0) {
   1330       for (stage = 0; stage < hw_info->num_stages; stage++) {
   1331           for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stage]; hfe_ct++) {
   1332               hfe_profile_ptr[stage] = hw_info->hfe_profile_ptr[stage][hfe_ct];;
   1333               if (cmd_bmap[stage] || (null_update[stage])) {
   1334                  rv = soc_mem_write(unit, policy_mem[stage], MEM_BLOCK_ANY,
   1335                          hfe_profile_ptr[stage], (uint32 *)buf[stage]);
   1336                  BCM_IF_ERROR_RETURN(rv);
   1337               }
   1338           }
   1339       }
   1340    }
   1341 
   1342    for (stage = 0; stage < hw_info->num_stages; stage++) {
   1343        obj_info->hw_cmd_bmap[stage] = cfg_data->cmd_bmap[stage];
   1344    }
   1345    hw_info->extracted_bytes += _BCM_UDF_CHUNK_TO_BYTE(cfg_data->num_chunks);
   1346    hw_info->chunk_bmap_used |= obj_info->chunk_bmap;
   1347    return BCM_E_NONE;
   1348 }
   1349 
   1350 /*
   1351  * Un-install HW Policy Commands for given UDF object.
   1352  */
   1353 STATIC
   1354 int _udf_td3_hw_policy_cmd_uninstall(int unit, _bcm_udf_td3_obj_info_t *obj_info)
   1355 {
   1356    int rv;
   1357    uint8 stage, i, hfe_ct;
   1358    uint8 num_chunks = 0;
   1359    uint8 start_cmd;
   1360    uint8 skip_hw_init = 0;
   1361    soc_format_t fmt;
   1362    uint32 cancun_ver;
   1363    uint8 *cmd_policy_data = NULL;
   1364    bcm_udf_abstract_pkt_format_t pkt_fmt;
   1365    uint8 f_buf[_BCM_UDF_MAX_PARSER_STAGES][50];
   1366    uint8 buf[_BCM_UDF_MAX_PARSER_STAGES][100];
   1367    uint16 cmd_bmap[_BCM_UDF_MAX_PARSER_STAGES];
   1368    soc_mem_t policy_mem[_BCM_UDF_MAX_PARSER_STAGES];
   1369    uint32 hfe_profile_ptr[_BCM_UDF_MAX_PARSER_STAGES];
   1370    uint8 null_update[_BCM_UDF_MAX_PARSER_STAGES] = {0};
   1371    _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *hw_info = NULL;
   1372 
   1373    pkt_fmt = obj_info->abstr_pkt_fmt;
   1374    hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt);
   1375 
   1376    BCM_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver));
   1377    if (SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) {
   1378        if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) ||
   1379            (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) {
   1380            skip_hw_init = 1;
   1381        }
   1382    }
   1383 
   1384    if (skip_hw_init == 0) {
   1385       sal_memset(f_buf, 0x0, sizeof(f_buf));
   1386       sal_memset(buf, 0x0, sizeof(buf));
   1387 
   1388       for (stage = 0; stage < hw_info->num_stages; stage++) {
   1389           cmd_bmap[stage] = obj_info->hw_cmd_bmap[stage];
   1390           policy_mem[stage] = hw_info->stage_policy_mem[stage];
   1391           cmd_policy_data = hw_info->cmd_policy_data[stage];
   1392 
   1393           if (policy_mem[stage] == INVALIDm) {
   1394              continue;
   1395           }
   1396 
   1397           _UDF_TD3_GET_HFE_CMD_FORMAT(hw_info->parser, fmt);
   1398           if (fmt == INVALIDfmt) {
   1399              return BCM_E_INTERNAL;
   1400           }
   1401 
   1402           if (cmd_policy_data == NULL) {
   1403              return BCM_E_INTERNAL;
   1404           }
   1405 
   1406           for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stage]; hfe_ct++) {
   1407               hfe_profile_ptr[stage] = hw_info->hfe_profile_ptr[stage][hfe_ct];;
   1408               rv = soc_mem_read(unit, policy_mem[stage], MEM_BLOCK_ANY,
   1409                                 hfe_profile_ptr[stage], (uint32 *) buf[stage]);
   1410               BCM_IF_ERROR_RETURN(rv);
   1411               soc_mem_field_get(unit, policy_mem[stage], (uint32 *)buf[stage],
   1412                                 CMD_POLICY_DATAf, (uint32 *)f_buf[stage]);
   1413 
   1414               start_cmd = _BCM_UDF_MAX_POLICY_CMDS - hw_info->num_cmds[stage];
   1415               for (i = start_cmd; i < _BCM_UDF_MAX_POLICY_CMDS; i++) {
   1416                  if (cmd_bmap[stage] & (1 << i)) {
   1417                     if (hw_info->parser == _BCM_UDF_PARSER0) {
   1418                         soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1419                                                             valid_p0_cmds[i], 0);
   1420                         soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1421                                                    src_pkt_offset_p0_cmds[i], 0);
   1422                     } else {
   1423                         soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1424                                                                valid_cmds[i], 0);
   1425                         soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1426                                                         dest_cont_id_cmds[i], 0);
   1427                         soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage],
   1428                                                       src_pkt_offset_cmds[i], 0);
   1429                     }
   1430                  }
   1431               }
   1432 
   1433               if (cmd_bmap[stage]) {
   1434                  soc_mem_field_set(unit, policy_mem[stage], (uint32 *)buf[stage],
   1435                                 CMD_POLICY_DATAf, (uint32 *)f_buf[stage]);
   1436               }
   1437 
   1438               if (!(hw_info->chunk_bmap_used & ~(obj_info->hw_cmd_bmap[stage]))) {
   1439                   soc_mem_field_set(unit, policy_mem[stage], (uint32 *)buf[stage],
   1440                                 CMD_POLICY_DATAf, (uint32 *)cmd_policy_data);
   1441                   null_update[stage] = 1;
   1442               }
   1443           }
   1444       }
   1445 
   1446       for (stage = 0; stage < hw_info->num_stages; stage++) {
   1447           for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stage]; hfe_ct++) {
   1448               hfe_profile_ptr[stage] = hw_info->hfe_profile_ptr[stage][hfe_ct];;
   1449               if ((cmd_bmap[stage]) || (null_update[stage] == 1)) {
   1450                  rv = soc_mem_write(unit, policy_mem[stage], MEM_BLOCK_ANY,
   1451                              hfe_profile_ptr[stage], (uint32 *)buf[stage]);
   1452                  BCM_IF_ERROR_RETURN(rv);
   1453               }
   1454           }
   1455       }
   1456    }
   1457 
   1458    (void)_udf_chunk_bmap_to_chunks(obj_info->chunk_bmap,
   1459                                    &num_chunks, NULL);
   1460 
   1461    /* Update Abstr Pkt Format HW variables. */
   1462    for (stage = 0; stage < hw_info->num_stages; stage++) {
   1463       hw_info->valid_cmd_bmap[stage] &= ~(obj_info->hw_cmd_bmap[stage]);
   1464       obj_info->hw_cmd_bmap[stage] = 0x0;
   1465    }
   1466    hw_info->extracted_bytes -= _BCM_UDF_CHUNK_TO_BYTE(num_chunks);
   1467    hw_info->chunk_bmap_used &= ~(obj_info->chunk_bmap);
   1468 
   1469    return BCM_E_NONE;
   1470 }
   1471 
   1472 
   1473 /*
   1474  * Function:
   1475  *      _bcm_udf_td3_chunk_create
   1476  * Purpose:
   1477  *      Creates a UDF object
   1478  * Parameters:
   1479  *      unit - (IN) Unit number.
   1480  *      hints - (IN) Hints to UDF allocator
   1481  *      udf_info - (IN) UDF Chunk Info structure
   1482  *      udf_id - (IN/OUT) UDF ID
   1483  * Returns:
   1484  *      BCM_E_NONE          UDF created successfully.
   1485  *      BCM_E_EXISTS        Entry already exists.
   1486  *      BCM_E_FULL          UDF table full.
   1487  *      BCM_E_UNIT          Invalid BCM Unit number.
   1488  *      BCM_E_INIT          UDF module not initialized.
   1489  *      BCM_E_UNAVAIL       Feature not supported.
   1490  *      BCM_E_XXX           Standard error code.
   1491  * Notes:
   1492  */
   1493 int
   1494 _bcm_udf_td3_chunk_create(
   1495     int unit,
   1496     bcm_udf_alloc_hints_t *hints,
   1497     bcm_udf_chunk_info_t  *udf_info,
   1498     bcm_udf_id_t *udf_id)
   1499 {
   1500     int id_running_allocated = 0;
   1501     int rv = BCM_E_NONE;
   1502     _udf_obj_pkt_fmt_hw_cfg_t cfg_data;
   1503     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   1504 
   1505     /* UDF Device Module Init check */
   1506     if (UDF_TD3_CTRL(unit) == NULL) {
   1507         return BCM_E_INIT;
   1508     }
   1509 
   1510     /* Sanitize input parameters */
   1511     rv = _udf_td3_sanitize_inputs(unit, udf_info, hints, udf_id);
   1512     BCM_IF_ERROR_RETURN(rv);
   1513 
   1514     /* Check if similar entry already existing */
   1515     if ((hints != NULL) && (hints->flags & BCM_UDF_CREATE_O_WITHID)) {
   1516         /* Retrieve UDF object info; get should be successful */
   1517         rv = _bcm_udf_td3_object_info_get(unit, *udf_id, &obj_info);
   1518         if (BCM_SUCCESS(rv)) {
   1519            return BCM_E_EXISTS;
   1520         }
   1521     } else {
   1522         /* Allocate new udf id */
   1523         rv = _bcm_udf_td3_object_running_id_alloc(unit, udf_id);
   1524         if (BCM_FAILURE(rv)) {
   1525             return rv;
   1526         } else {
   1527             id_running_allocated = 1;
   1528         }
   1529     }
   1530 
   1531     /* Add udf info structure to linked list */
   1532     rv = _bcm_udf_td3_object_info_add(unit, udf_info, &obj_info);
   1533     if ((BCM_FAILURE(rv)) || (obj_info == NULL)) {
   1534         return rv;
   1535     }
   1536 
   1537     sal_memset(&cfg_data, 0x0, sizeof(cfg_data));
   1538     /* Allocate udf chunks */
   1539     rv = _udf_td3_hw_policy_cmd_alloc(unit, obj_info, &cfg_data);
   1540     BCM_IF_ERROR_GOTO_CLEANUP(rv);
   1541 
   1542     /* Install UDF object */
   1543     rv = _udf_td3_hw_policy_cmd_install(unit, obj_info, &cfg_data);
   1544     BCM_IF_ERROR_GOTO_CLEANUP(rv);
   1545 
   1546     /* update udf_id in the offset_info */
   1547     obj_info->udf_id = *udf_id;
   1548 
   1549     if (hints != NULL) {
   1550         
   1551         if (hints->flags & BCM_UDF_CREATE_O_FIELD_INGRESS) {
   1552             obj_info->flags |= _BCM_UDF_TD3_OBJ_IFP;
   1553         }
   1554         if (hints->flags & BCM_UDF_CREATE_O_FIELD_LOOKUP) {
   1555             obj_info->flags |= _BCM_UDF_TD3_OBJ_VFP;
   1556         }
   1557         if (hints->flags & BCM_UDF_CREATE_O_RANGE_CHECK) {
   1558             obj_info->flags |= _BCM_UDF_TD3_OBJ_RANGE_CHECK;
   1559         }
   1560     }
   1561 
   1562 cleanup:
   1563     if (BCM_FAILURE(rv)) {
   1564         if ((id_running_allocated == 1) &&
   1565             (UDF_CONTROL(unit)->udf_id_running != _BCM_UDF_TD3_OBJ_MAX_ID)) {
   1566             /* Decrement the running udf id */
   1567             UDF_CONTROL(unit)->udf_id_running -= 1;
   1568         }
   1569 
   1570         /* Delete the object node */
   1571         if (obj_info != NULL) {
   1572             _BCM_UDF_OBJ_NODE_DEL(unit, obj_info,
   1573                                   UDF_TD3_CTRL(unit)->udf_obj_head);
   1574             _BCM_UDF_FREE(obj_info);
   1575         }
   1576     }
   1577 
   1578     return rv;
   1579 }
   1580 int
   1581 _bcm_udf_td3_destroy(int unit, bcm_udf_id_t udf_id)
   1582 {
   1583     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   1584 
   1585     BCM_IF_ERROR_RETURN(_bcm_udf_td3_object_info_get(unit, udf_id, &obj_info));
   1586 
   1587     /* De-allocate HW Resource */
   1588     BCM_IF_ERROR_RETURN(_udf_td3_hw_policy_cmd_uninstall(unit, obj_info));
   1589     /* Detach UDF object info from its database. */
   1590     BCM_IF_ERROR_RETURN(_bcm_udf_td3_object_info_delete(unit, obj_info));
   1591 
   1592     return BCM_E_NONE;
   1593 }
   1594 
   1595 int
   1596 _bcm_udf_td3_chunk_info_get(
   1597     int unit,
   1598     bcm_udf_id_t udf_id,
   1599     bcm_udf_chunk_info_t *udf_chunk_info)
   1600 {
   1601     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   1602 
   1603     if (udf_chunk_info == NULL) {
   1604        return BCM_E_PARAM;
   1605     }
   1606 
   1607     BCM_IF_ERROR_RETURN(_bcm_udf_td3_object_info_get(unit, udf_id, &obj_info));
   1608 
   1609     udf_chunk_info->offset = obj_info->offset;
   1610     udf_chunk_info->width = obj_info->width;
   1611     udf_chunk_info->abstract_pkt_format = obj_info->abstr_pkt_fmt;
   1612     udf_chunk_info->chunk_bmap = obj_info->chunk_bmap;
   1613     return BCM_E_NONE;
   1614 }
   1615 
   1616 int
   1617 _bcm_udf_td3_abstr_pkt_format_obj_list_get(
   1618     int unit,
   1619     bcm_udf_abstract_pkt_format_t abstract_pkt_format,
   1620     int max,
   1621     bcm_udf_id_t *udf_id_list,
   1622     int *actual)
   1623 {
   1624     int ct = 0;
   1625     bcm_udf_id_t id_list[32] = {0};
   1626     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   1627 
   1628     /* Validate input params */
   1629     if ((udf_id_list == NULL) || (actual == NULL)) {
   1630        return BCM_E_PARAM;
   1631     }
   1632 
   1633     /* check if pkt format is in valid range */
   1634     _BCM_UDF_ABSTR_PKT_FORMAT_VALIDATE(unit, abstract_pkt_format);
   1635 
   1636     obj_info = UDF_TD3_CTRL(unit)->udf_obj_head;
   1637 
   1638     while (obj_info != NULL) {
   1639         if (obj_info->abstr_pkt_fmt == abstract_pkt_format) {
   1640            id_list[ct++] = obj_info->udf_id;
   1641         }
   1642         _BCM_UDF_OBJ_NODE_NEXT(obj_info);
   1643     }
   1644 
   1645     if (ct > max) {
   1646        return BCM_E_PARAM;
   1647     }
   1648 
   1649     sal_memcpy(udf_id_list, id_list, sizeof(bcm_udf_id_t) * ct);
   1650     *actual = ct;
   1651     return BCM_E_NONE;
   1652 }
   1653 
   1654 STATIC
   1655 int _bcm_udf_td3_abstr_pkt_format_info_get(
   1656     int unit,
   1657     bcm_udf_abstract_pkt_format_t abstract_pkt_format,
   1658     bcm_udf_abstract_pkt_format_info_t *pkt_format_info)
   1659 {
   1660     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info;
   1661 
   1662     if (pkt_format_info == NULL) {
   1663        return BCM_E_PARAM;
   1664     }
   1665 
   1666     /* Validate whether UDF module is attached */
   1667     if (UDF_TD3_CTRL(unit) == NULL) {
   1668         return BCM_E_INIT;
   1669     }
   1670 
   1671     /* check if pkt format is in valid range */
   1672     _BCM_UDF_ABSTR_PKT_FORMAT_VALIDATE(unit, abstract_pkt_format);
   1673 
   1674     pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, abstract_pkt_format);
   1675     if (pkt_fmt_hw_info == NULL) {
   1676        return BCM_E_INTERNAL;
   1677     }
   1678 
   1679     pkt_format_info->base_offset = pkt_fmt_hw_info->base_offset;
   1680     pkt_format_info->num_chunks_max =
   1681                          _BCM_UDF_BYTE_TO_CHUNK(pkt_fmt_hw_info->max_extract_bytes);
   1682     pkt_format_info->chunk_bmap_used = pkt_fmt_hw_info->chunk_bmap_used;
   1683     pkt_format_info->unavail_chunk_bmap = pkt_fmt_hw_info->unavail_chunk_bmap;
   1684 
   1685     return BCM_E_NONE;
   1686 }
   1687 
   1688 /* ceh field string */
   1689 typedef struct _flex_ceh_field_str_s {
   1690     char  field_str[40];
   1691 } _flex_ceh_field_str_t;
   1692 
   1693 /* Tunnel term type to CEH string mapping */
   1694 STATIC
   1695 _flex_ceh_field_str_t flex_tunnel_term_type_arr[bcmUdfTunnelTermFlowTypeLastCount] = {
   1696             {"MIM_TERM_PYLD_TYPE_IP"},
   1697             {"MIM_TERM_PYLD_TYPE_NON_IP"},
   1698             {"L2_MPLS_TERM_PYLD_TYPE_IP"},
   1699             {"L2_MPLS_TERM_PYLD_TYPE_NON_IP"},
   1700             {"L2GRE_TERM_PYLD_TYPE_IP"},
   1701             {"L2GRE_TERM_PYLD_TYPE_NON_IP"},
   1702             {"VXLAN_TERM_PYLD_TYPE_IP"},
   1703             {"VXLAN_TERM_PYLD_TYPE_NON_IP"},
   1704             {"L3_MPLS_TERM"},
   1705             {"L3_TUN_TERM"},
   1706 };
   1707 
   1708 STATIC
   1709 _flex_ceh_field_str_t _udf_chunk_ceh_str[_BCM_UDF_TD3_MAX_CHUNKS] = {
   1710             {"UDF_1_CHUNK_0"}, {"UDF_1_CHUNK_1"},
   1711             {"UDF_1_CHUNK_2"}, {"UDF_1_CHUNK_3"},
   1712             {"UDF_1_CHUNK_4"}, {"UDF_1_CHUNK_5"},
   1713             {"UDF_1_CHUNK_6"}, {"UDF_1_CHUNK_7"},
   1714             {"UDF_2_CHUNK_0"}, {"UDF_2_CHUNK_1"},
   1715             {"UDF_2_CHUNK_2"}, {"UDF_2_CHUNK_3"},
   1716             {"UDF_2_CHUNK_4"}, {"UDF_2_CHUNK_5"},
   1717             {"UDF_2_CHUNK_6"}, {"UDF_2_CHUNK_7"},
   1718 };
   1719 
   1720 /*
   1721  * Get API to retrieve chunk bitmap.
   1722  */
   1723 STATIC int
   1724 _bcm_udf_td3_field_bus_merge_profile_get(int unit,
   1725                                          bcm_udf_tunnel_term_flow_type_t flow_type,
   1726                                          uint32 *chunk_bmap)
   1727 {
   1728     int rv;
   1729     uint32 fmt_buf = 0;
   1730     uint32 val;
   1731     uint8 chunk, f;
   1732     uint32 buf[100]={0};
   1733     uint32 profile_idx;
   1734     soc_field_t assign_ctrl_field;
   1735     soc_cancun_ceh_field_info_t ceh_info;
   1736     soc_format_t fmt = FLEX_ASSIGNMENT_CTRL_FORMATfmt;
   1737     soc_mem_t mem = FIELD_BUS_MERGE_PROFILEm;
   1738     soc_mem_info_t  *meminfo;
   1739 
   1740     meminfo = &SOC_MEM_INFO(unit, mem);
   1741 
   1742     /* Retrieve flow index from CEH flex db */
   1743     rv = soc_cancun_ceh_obj_field_get(unit,
   1744                                       "FIELD_BUS_MERGE_PROFILE_INDEX",
   1745                                       flex_tunnel_term_type_arr[flow_type].field_str,
   1746                                       &ceh_info);
   1747     if (SOC_FAILURE(rv)) {
   1748         LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
   1749                  "Flow type %d not found in CEH DB.\n\r"), flow_type));
   1750         return rv;
   1751     }
   1752 
   1753     profile_idx = ceh_info.value;
   1754     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, profile_idx, buf);
   1755     BCM_IF_ERROR_RETURN(rv);
   1756 
   1757     for (chunk = 0; chunk < _BCM_UDF_TD3_MAX_CHUNKS; chunk++) {
   1758         rv = soc_cancun_ceh_obj_field_get(unit,
   1759                                           "FIELD_BUS_MERGE_PROFILE_UDF_CONTAINERS",
   1760                                           _udf_chunk_ceh_str[chunk].field_str,
   1761                                           &ceh_info);
   1762         if (SOC_FAILURE(rv)) {
   1763             LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
   1764                  "Chunk[%d : %s] Assignment control offset not found in CEH DB.\n\r"),
   1765                  chunk, _udf_chunk_ceh_str[chunk].field_str));
   1766             return rv;
   1767         }
   1768 
   1769         assign_ctrl_field = INVALIDf;
   1770         for (f = 0; f < meminfo->nFields; f++) {
   1771             if (ceh_info.offset == meminfo->fields[f].bp) {
   1772                 assign_ctrl_field = meminfo->fields[f].field;
   1773                 break;
   1774             }
   1775         }
   1776 
   1777         if (assign_ctrl_field == INVALIDf) {
   1778             return BCM_E_INTERNAL;
   1779         }
   1780  
   1781         soc_mem_field_get(unit, mem, buf, assign_ctrl_field, &fmt_buf);
   1782         /* coverity[address_of : FALSE] */
   1783         /* coverity[callee_ptr_arith : FALSE] */
   1784         soc_format_field_get(unit, fmt, &fmt_buf, SELECTf, &val);
   1785         if (val == 0) {
   1786             *chunk_bmap |= 1 << chunk;
   1787         }
   1788     }
   1789 
   1790     return rv;
   1791 }
   1792 
   1793 /*
   1794  * SET field bus merge profile for given UDF chunk bitmap
   1795  */
   1796 STATIC int
   1797 _bcm_udf_td3_field_bus_merge_profile_set(int unit,
   1798                                          bcm_udf_tunnel_term_flow_type_t flow_type,
   1799                                          uint32 chunk_bmap)
   1800 {
   1801     int rv;
   1802     uint32 fmt_buf = 0;
   1803     uint32 val;
   1804     uint8 chunk, f;
   1805     uint32 buf[100]={0};
   1806     uint32 profile_idx;
   1807     soc_field_t assign_ctrl_field;
   1808     soc_cancun_ceh_field_info_t ceh_info;
   1809     soc_format_t fmt = FLEX_ASSIGNMENT_CTRL_FORMATfmt;
   1810     soc_mem_t mem = FIELD_BUS_MERGE_PROFILEm;
   1811     soc_mem_info_t  *meminfo;
   1812 
   1813     meminfo = &SOC_MEM_INFO(unit, mem);
   1814     /* Retrieve flow index from CEH flex db */
   1815     rv = soc_cancun_ceh_obj_field_get(unit,
   1816                                       "FIELD_BUS_MERGE_PROFILE_INDEX",
   1817                                       flex_tunnel_term_type_arr[flow_type].field_str,
   1818                                       &ceh_info);
   1819     if (SOC_FAILURE(rv)) {
   1820         LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
   1821                  "Flow type %d not found in CEH DB.\n\r"), flow_type));
   1822         return rv;
   1823     }
   1824 
   1825     profile_idx = ceh_info.value;
   1826     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, profile_idx, buf);
   1827     BCM_IF_ERROR_RETURN(rv);
   1828 
   1829     for (chunk = 0; chunk < _BCM_UDF_TD3_MAX_CHUNKS; chunk++) {
   1830         rv = soc_cancun_ceh_obj_field_get(unit,
   1831                                           "FIELD_BUS_MERGE_PROFILE_UDF_CONTAINERS",
   1832                                           _udf_chunk_ceh_str[chunk].field_str,
   1833                                           &ceh_info);
   1834         if (SOC_FAILURE(rv)) {
   1835             LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
   1836                  "Chunk[%d : %s] Assignment control offset not found in CEH DB.\n\r"),
   1837                  chunk, _udf_chunk_ceh_str[chunk].field_str));
   1838             return rv;
   1839         }
   1840 
   1841         assign_ctrl_field = INVALIDf;
   1842         for (f = 0; f < meminfo->nFields; f++) {
   1843             if (ceh_info.offset == meminfo->fields[f].bp) {
   1844                 assign_ctrl_field = meminfo->fields[f].field;
   1845                 break;
   1846             }
   1847         }
   1848 
   1849         if (assign_ctrl_field == INVALIDf) {
   1850             return BCM_E_INTERNAL;
   1851         }
   1852         fmt_buf = 0x0;
   1853         val = (chunk_bmap & (1 << chunk)) ? 0 : 1;
   1854         soc_format_field32_set(unit, fmt, &fmt_buf, SELECTf, val);
   1855         soc_mem_field_set(unit, mem, (uint32 *)buf,
   1856                            assign_ctrl_field, &fmt_buf);
   1857 
   1858     }
   1859 
   1860     rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY,
   1861                        profile_idx, buf);
   1862 
   1863     return rv;
   1864 }
   1865 
   1866 STATIC
   1867 int _bcm_udf_flow_based_chunk_arrange_set(
   1868         int unit,
   1869         bcm_udf_tunnel_term_flow_type_t flow_type,
   1870         uint32 chunk_bmap)
   1871 {
   1872     if (flow_type >= bcmUdfTunnelTermFlowTypeLastCount) {
   1873         return BCM_E_PARAM;
   1874     }
   1875 
   1876     if (chunk_bmap & ~((1 << _BCM_UDF_TD3_MAX_CHUNKS) - 1)) {
   1877         return BCM_E_PARAM;
   1878     }
   1879 
   1880     return _bcm_udf_td3_field_bus_merge_profile_set(unit,
   1881                                   flow_type, chunk_bmap);
   1882 }
   1883 
   1884 STATIC
   1885 int _bcm_udf_flow_based_chunk_arrange_get(
   1886         int unit,
   1887         bcm_udf_tunnel_term_flow_type_t flow_type,
   1888         uint32 *chunk_bmap)
   1889 {
   1890     if (chunk_bmap == NULL) {
   1891         return BCM_E_PARAM;
   1892     }
   1893 
   1894     return _bcm_udf_td3_field_bus_merge_profile_get(unit,
   1895                                   flow_type, chunk_bmap);
   1896 }
   1897 
   1898 STATIC int
   1899 _bcm_udf_td3_format_field_dump(int unit, soc_mem_t mem, uint32 index)
   1900 {
   1901    uint32 buf[100]={0};
   1902    uint32 f_buf[50]={0};
   1903    soc_format_t fmt;
   1904    uint32 id = 0, valid, dst_cont_id, src_offset;
   1905    int rv;
   1906 
   1907    if (!((mem == IP_PARSER0_HFE_POLICY_TABLE_0m) ||
   1908          (mem == IP_PARSER1_HFE_POLICY_TABLE_0m) ||
   1909          (mem == IP_PARSER1_HFE_POLICY_TABLE_1m) ||
   1910          (mem == IP_PARSER1_HFE_POLICY_TABLE_2m) ||
   1911          (mem == IP_PARSER1_HFE_POLICY_TABLE_3m) ||
   1912          (mem == IP_PARSER1_HFE_POLICY_TABLE_4m) ||
   1913          (mem == IP_PARSER2_HFE_POLICY_TABLE_0m) ||
   1914          (mem == IP_PARSER2_HFE_POLICY_TABLE_1m) ||
   1915          (mem == IP_PARSER2_HFE_POLICY_TABLE_2m) ||
   1916          (mem == IP_PARSER2_HFE_POLICY_TABLE_3m) ||
   1917          (mem == IP_PARSER2_HFE_POLICY_TABLE_4m))) {
   1918        return BCM_E_NONE;
   1919    }
   1920 
   1921    rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, (uint32 *)buf);
   1922    BCM_IF_ERROR_RETURN(rv);
   1923 
   1924    soc_mem_field_get(unit, mem, (uint32 *)buf, CMD_POLICY_DATAf, (uint32 *)f_buf);
   1925 
   1926    if (mem == IP_PARSER0_HFE_POLICY_TABLE_0m) {
   1927        soc_format_t fmt = IP_PARSER0_HFE_CMD_POLICY_DATAfmt;
   1928  
   1929        LOG_CLI(("CMD VALID SRC_PKT_OFFSET\n\r"));
   1930        LOG_CLI(("=== ===== ==============\n\r"));
   1931        id = 8;
   1932        valid = soc_format_field32_get(unit, fmt, f_buf, CMD_A_8_VALIDf);
   1933        src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_A_8_SRC_PKT_OFFSETf);
   1934        LOG_CLI(("%2d %5d %10d\n\r", id, valid, src_offset));
   1935 
   1936        valid = soc_format_field32_get(unit, fmt, f_buf, CMD_A_9_VALIDf);
   1937        src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_A_9_SRC_PKT_OFFSETf);
   1938        id++; LOG_CLI(("%2d %5d %10d\n\r", id, valid, src_offset));
   1939        return BCM_E_NONE;
   1940    }
   1941 
   1942    if ((mem == IP_PARSER1_HFE_POLICY_TABLE_0m) ||
   1943        (mem == IP_PARSER1_HFE_POLICY_TABLE_1m) ||
   1944        (mem == IP_PARSER1_HFE_POLICY_TABLE_2m) ||
   1945        (mem == IP_PARSER1_HFE_POLICY_TABLE_3m) ||
   1946        (mem == IP_PARSER1_HFE_POLICY_TABLE_4m)) {
   1947        fmt = IP_PARSER1_HFE_CMD_POLICY_DATAfmt;
   1948    } else {
   1949        fmt = IP_PARSER2_HFE_CMD_POLICY_DATAfmt;
   1950    }
   1951 
   1952    LOG_CLI(("ID VALID DEST_CONT_ID SRC_PKT_OFFSET\n\r"));
   1953    LOG_CLI(("== ===== ============ ==============\n\r"));
   1954    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_0_VALIDf);
   1955    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_0_DEST_CONT_IDf);
   1956    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_0_SRC_PKT_OFFSETf);
   1957    LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   1958 
   1959    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_1_VALIDf);
   1960    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_1_DEST_CONT_IDf);
   1961    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_1_SRC_PKT_OFFSETf);
   1962    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   1963 
   1964 
   1965    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_2_VALIDf);
   1966    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_2_DEST_CONT_IDf);
   1967    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_2_SRC_PKT_OFFSETf);
   1968    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   1969 
   1970    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_3_VALIDf);
   1971    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_3_DEST_CONT_IDf);
   1972    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_3_SRC_PKT_OFFSETf);
   1973    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   1974 
   1975    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_4_VALIDf);
   1976    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_4_DEST_CONT_IDf);
   1977    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_4_SRC_PKT_OFFSETf);
   1978    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   1979 
   1980    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_5_VALIDf);
   1981    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_5_DEST_CONT_IDf);
   1982    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_5_SRC_PKT_OFFSETf);
   1983    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   1984 
   1985    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_6_VALIDf);
   1986    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_6_DEST_CONT_IDf);
   1987    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_6_SRC_PKT_OFFSETf);
   1988    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   1989 
   1990    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_7_VALIDf);
   1991    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_7_DEST_CONT_IDf);
   1992    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_7_SRC_PKT_OFFSETf);
   1993    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   1994 
   1995    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_8_VALIDf);
   1996    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_8_DEST_CONT_IDf);
   1997    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_8_SRC_PKT_OFFSETf);
   1998    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   1999 
   2000    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_9_VALIDf);
   2001    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_9_DEST_CONT_IDf);
   2002    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_9_SRC_PKT_OFFSETf);
   2003    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   2004 
   2005    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_10_VALIDf);
   2006    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_10_DEST_CONT_IDf);
   2007    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_10_SRC_PKT_OFFSETf);
   2008    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   2009 
   2010    valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_11_VALIDf);
   2011    dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_11_DEST_CONT_IDf);
   2012    src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_11_SRC_PKT_OFFSETf);
   2013    id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset));
   2014 
   2015    return BCM_E_NONE;
   2016 }
   2017 
   2018 STATIC
   2019 void _udf_print_in_bin(uint16 n)
   2020 {
   2021     int ct = 0;
   2022 
   2023     while (n) {
   2024        LOG_CLI(("%d", (n & 1)));
   2025        n >>= 1;
   2026 
   2027        ct++;
   2028        if (ct == 4) {
   2029           LOG_CLI((" "));
   2030           ct = 0;
   2031        }
   2032     }
   2033 }
   2034 
   2035 int
   2036 _bcm_udf_object_hw_info_dump(int unit, bcm_udf_id_t udf_id)
   2037 {
   2038     uint8 stg, hfe_ct;
   2039     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   2040    _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *hw_info = NULL;
   2041 
   2042     BCM_IF_ERROR_RETURN(_bcm_udf_td3_object_info_get(unit, udf_id, &obj_info));
   2043 
   2044     LOG_CLI(("UDF Object ID [%d] Information:\n\r", udf_id));
   2045     LOG_CLI(("Offset..................%d\n\r", obj_info->offset));
   2046     LOG_CLI(("Width...................%d\n\r", obj_info->width));
   2047     LOG_CLI(("Abstr Pkt Fmt...........%s\n\r", _udf_abstr_pkt_fmt_name(obj_info->abstr_pkt_fmt)));
   2048     LOG_CLI(("Chunk Bitmap............0x%x\n\r", obj_info->chunk_bmap));
   2049     for (stg = 0; stg < _BCM_UDF_MAX_PARSER_STAGES; stg++) {
   2050        LOG_CLI(("HW CMD Bitmap%d..........0x%x\n\r", stg, obj_info->hw_cmd_bmap[stg]));
   2051     }
   2052 
   2053     hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, obj_info->abstr_pkt_fmt);
   2054     if (hw_info == NULL) {
   2055        return BCM_E_INTERNAL;
   2056     }
   2057 
   2058     LOG_CLI(("Abstr Packet Format Information:\n\r"));
   2059     LOG_CLI(("Parser............................%d\n\r", hw_info->parser));
   2060     LOG_CLI(("Num stages supported..............%d\n\r", hw_info->num_stages));
   2061     for (stg = 0; stg < hw_info->num_stages; stg++) {
   2062        if (hw_info->stage_policy_mem[stg] != INVALIDm) {
   2063           LOG_CLI(("Stage[%d] Policy Mem........................%s\n\r", stg,
   2064                SOC_MEM_NAME(unit, hw_info->stage_policy_mem[stg])));
   2065        }
   2066        LOG_CLI(("Stage[%d] HFE Profile Ptr....................{", stg));
   2067        for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stg]; hfe_ct++) {
   2068             if (hfe_ct == (hw_info->hfe_prof_ptr_arr_len[stg] - 1)) {
   2069                 LOG_CLI(("%d}\n\r", hw_info->hfe_profile_ptr[stg][hfe_ct]));
   2070             } else {
   2071                 LOG_CLI(("%d, ", hw_info->hfe_profile_ptr[stg][hfe_ct]));
   2072             }
   2073        }
   2074        LOG_CLI(("Stage[%d] Number of CMDs supported...........%d\n\r", stg,
   2075                hw_info->num_cmds[stg]));
   2076     }
   2077     LOG_CLI(("Maximum Extr Bytes................%d\n\r", hw_info->max_extract_bytes));
   2078     LOG_CLI(("Used Extr Bytes...................%d\n\r", hw_info->extracted_bytes));
   2079     LOG_CLI(("Chunk Bitmap Used (bits)..........0x%x (", hw_info->chunk_bmap_used));
   2080     _udf_print_in_bin((uint16)hw_info->chunk_bmap_used);
   2081     LOG_CLI((")\n\r"));
   2082     LOG_CLI(("Unavailable Chunk Bitmap (bits)...0x%x (", hw_info->unavail_chunk_bmap));
   2083     _udf_print_in_bin((uint16)hw_info->chunk_bmap_used);
   2084     LOG_CLI((")\n\r"));
   2085     for (stg = 0; stg < hw_info->num_stages; stg++) {
   2086         LOG_CLI(("CMD Bitmap%d (bits)................0x%x (", stg, hw_info->valid_cmd_bmap[stg]));
   2087            _udf_print_in_bin(hw_info->valid_cmd_bmap[stg]);
   2088         LOG_CLI((")\n\r"));
   2089     }
   2090 
   2091     for (stg = 0; stg < hw_info->num_stages; stg++) {
   2092        if (hw_info->stage_policy_mem[stg] != INVALIDm) {
   2093           for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stg]; hfe_ct++) {
   2094               _bcm_udf_td3_format_field_dump(unit, hw_info->stage_policy_mem[stg],
   2095                                          hw_info->hfe_profile_ptr[stg][hfe_ct]);
   2096           }
   2097        }
   2098     }
   2099 
   2100     return BCM_E_NONE;
   2101 }
   2102 
   2103 /*
   2104  * Routine to dump all the configured UDF objects info.
   2105  */
   2106 STATIC void
   2107 _bcm_udf_td3_sw_dump(int unit)
   2108 {
   2109     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   2110 
   2111     if (UDF_TD3_CTRL(unit)->udf_obj_head == NULL) {
   2112        return;
   2113     }
   2114 
   2115     obj_info = UDF_TD3_CTRL(unit)->udf_obj_head;
   2116 
   2117     while (obj_info != NULL) {
   2118         _bcm_udf_object_hw_info_dump(unit, obj_info->udf_id);
   2119         _BCM_UDF_OBJ_NODE_NEXT(obj_info);
   2120     }
   2121 }
   2122 
   2123 
   2124 /*
   2125  * Routine to retrieve number of UDF objects associated
   2126  * to the given UDF Chunk Bitmap
   2127  */
   2128 int
   2129 _bcm_udf_td3_chunk_id_multi_get(
   2130     int unit,
   2131     uint32 udf_chunk_bmap,
   2132     int max,
   2133     int *objects_list,
   2134     int *actual)
   2135 {
   2136     int idx = 0;
   2137     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   2138 
   2139     obj_info = UDF_TD3_CTRL(unit)->udf_obj_head;
   2140     while (obj_info != NULL) {
   2141         if (obj_info->chunk_bmap & udf_chunk_bmap) {
   2142            if (idx >= max) {
   2143               return BCM_E_PARAM;
   2144            }
   2145            objects_list[idx++] = obj_info->udf_id;
   2146         }
   2147         _BCM_UDF_OBJ_NODE_NEXT(obj_info);
   2148     }
   2149     *actual = idx;
   2150 
   2151     return BCM_E_NONE;
   2152 }
   2153 
   2154 /*
   2155  * Routine to return UDF chunk dedicated to Range Checker.
   2156  */
   2157 int
   2158 _bcm_udf_td3_range_checker_chunk_info_get(
   2159     int unit,
   2160     uint8 *num_chunks,
   2161     uint32 *chunk_bmap)
   2162 {
   2163     if ((num_chunks == NULL) || (chunk_bmap == NULL)) {
   2164        return BCM_E_PARAM;
   2165     }
   2166 
   2167     *num_chunks = 1;
   2168     *chunk_bmap = _BCM_UDF_TD3_RANGE_CHUNK_BMAP;
   2169     return BCM_E_NONE;
   2170 }
   2171 
   2172 #if defined (BCM_WARM_BOOT_SUPPORT)
   2173  
   2174 STATIC int
   2175 _udf_td3_wb_abstr_pkt_fmt_recover(int unit, _bcm_udf_td3_obj_info_t *obj_info)
   2176 {
   2177     uint8 stg;
   2178     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info;
   2179 
   2180     pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, obj_info->abstr_pkt_fmt);
   2181     if (pkt_fmt_hw_info == NULL) {
   2182        return BCM_E_INTERNAL;
   2183     }
   2184 
   2185     pkt_fmt_hw_info->extracted_bytes += obj_info->width;
   2186     pkt_fmt_hw_info->chunk_bmap_used |= obj_info->chunk_bmap;
   2187     for (stg = 0; stg < pkt_fmt_hw_info->num_stages; stg++) {
   2188         pkt_fmt_hw_info->valid_cmd_bmap[stg] |= obj_info->hw_cmd_bmap[stg];
   2189     }
   2190 
   2191     return BCM_E_NONE;
   2192 }
   2193 
   2194 /*
   2195  * Routine to Recover UDF Object information during WarmBoot.
   2196  */
   2197 STATIC int
   2198 _bcm_udf_td3_wb_obj_info_recover_1_0(int unit, uint8 **scache_ptr)
   2199 {
   2200     _bcm_udf_td3_wb_obj_info_t *scache_obj_ptr;
   2201     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   2202     int ct;
   2203     uint16 num_udfs = 0;
   2204     uint8 num_chunks = 0;
   2205 
   2206     /* Retrieve number of UDFs */
   2207     sal_memcpy(&num_udfs, *scache_ptr, sizeof(num_udfs));
   2208     *scache_ptr += sizeof(num_udfs);
   2209 
   2210     /* Retrieve the UDF objects */
   2211     scache_obj_ptr = (_bcm_udf_td3_wb_obj_info_t *)(*scache_ptr);
   2212     for (ct = 0; ct < num_udfs; ct++) {
   2213         /* Allocate memory for UDF object info. */
   2214         obj_info = NULL;
   2215         _BCM_UDF_ALLOC(obj_info, sizeof(_bcm_udf_td3_obj_info_t),
   2216                        "UDF object info.");
   2217         if (obj_info == NULL) {
   2218            return BCM_E_MEMORY;
   2219         }
   2220 
   2221         obj_info->udf_id = scache_obj_ptr->udf_id;
   2222         obj_info->offset = scache_obj_ptr->offset;
   2223         obj_info->chunk_bmap = scache_obj_ptr->chunk_bmap;
   2224 
   2225         (void)_udf_chunk_bmap_to_chunks(obj_info->chunk_bmap,
   2226                                         &num_chunks, NULL);
   2227         obj_info->width = _BCM_UDF_CHUNK_TO_BYTE(num_chunks);
   2228         obj_info->hw_cmd_bmap[0] = scache_obj_ptr->hw_cmd_bmap1;
   2229         obj_info->hw_cmd_bmap[1] = scache_obj_ptr->hw_cmd_bmap2;
   2230         obj_info->abstr_pkt_fmt = scache_obj_ptr->abstr_pkt_fmt;
   2231 
   2232         BCM_IF_ERROR_RETURN(_udf_td3_wb_abstr_pkt_fmt_recover(unit, obj_info));
   2233 
   2234         /* Add obj_info item to the linked list */
   2235         _BCM_UDF_OBJ_NODE_ADD(unit, (obj_info),
   2236                               UDF_TD3_CTRL(unit)->udf_obj_head);
   2237         scache_obj_ptr++;
   2238     }
   2239 
   2240     *scache_ptr = (uint8 *)scache_obj_ptr;
   2241     return BCM_E_NONE;
   2242 }
   2243 
   2244 /*
   2245  * Routine to recover UDF Abstract Pkt Fmt default cmd_policy_data.
   2246  */
   2247 STATIC int
   2248 _bcm_udf_td3_wb_abstr_pkt_fmt_info_recover_1_0(int unit, uint8 **scache_ptr)
   2249 {
   2250     uint8 stage, len;
   2251     soc_mem_t policy_mem;
   2252     uint8 buf[100];
   2253     uint32 hfe_profile_ptr;
   2254     uint8 *cmd_pol_data_buf = NULL;
   2255     bcm_udf_abstract_pkt_format_t pkt_fmt;
   2256     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info;
   2257 
   2258     for (pkt_fmt = bcmUdfAbstractPktFormatLlc;
   2259          pkt_fmt < bcmUdfAbstractPktFormatLastCount;
   2260          pkt_fmt++) {
   2261         pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt);
   2262         if (pkt_fmt_hw_info == NULL) {
   2263            continue;
   2264         }
   2265 
   2266         /*
   2267          * INT containers are fixed, need not sync the containers.
   2268          */
   2269         if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) ||
   2270             (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) {
   2271            continue;
   2272         }
   2273 
   2274         for (stage = 0; stage < _BCM_UDF_MAX_PARSER_STAGES; stage++) {
   2275             policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage];
   2276             hfe_profile_ptr = pkt_fmt_hw_info->hfe_profile_ptr[stage][0];
   2277 
   2278             if (policy_mem == INVALIDm || policy_mem == 0) {
   2279                continue;
   2280             }
   2281 
   2282             len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf);
   2283 
   2284             cmd_pol_data_buf = NULL;
   2285             if (pkt_fmt_hw_info->chunk_bmap_used) {
   2286                 _BCM_UDF_ALLOC(cmd_pol_data_buf, len, "UDF WB CMD_POLICY_DATA alloc");
   2287                 if (cmd_pol_data_buf == NULL) {
   2288                    return BCM_E_MEMORY;
   2289                 }
   2290 
   2291                 sal_memcpy(cmd_pol_data_buf, *scache_ptr, len);
   2292                 *scache_ptr += len;
   2293             } else {
   2294                 sal_memset(buf, 0x0, sizeof(buf));
   2295 
   2296                 BCM_IF_ERROR_RETURN(soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY,
   2297                                     hfe_profile_ptr, (uint32 *) buf));
   2298 
   2299                 _BCM_UDF_ALLOC(cmd_pol_data_buf, len, "UDF default CMD Policy data");
   2300                 if (cmd_pol_data_buf == NULL) {
   2301                    return BCM_E_MEMORY;
   2302                 }
   2303 
   2304                 soc_mem_field_get(unit, policy_mem, (uint32 *)buf,
   2305                              CMD_POLICY_DATAf, (uint32 *)cmd_pol_data_buf);
   2306             }
   2307 
   2308             pkt_fmt_hw_info->cmd_policy_data[stage] = cmd_pol_data_buf;
   2309         }
   2310     }
   2311 
   2312     return BCM_E_NONE;
   2313 }
   2314 
   2315 
   2316 /*
   2317  * Routine to Recover UDF Object information during WarmBoot.
   2318  */
   2319 STATIC int
   2320 _bcm_udf_td3_wb_obj_info_recover_2_0(int unit, uint16 recovered_version, uint8 **scache_ptr)
   2321 {
   2322     int ct;
   2323     uint8 stg;
   2324     uint8 num_chunks = 0;
   2325     uint16 num_udfs = 0;
   2326     uint8 num_stages = 0;
   2327     _bcm_udf_td3_wb_obj_info_2_t *scache_obj_ptr;
   2328     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   2329 
   2330     /* Retrieve number of UDFs */
   2331     sal_memcpy(&num_udfs, *scache_ptr, sizeof(num_udfs));
   2332     *scache_ptr += sizeof(num_udfs);
   2333 
   2334     /* Retrieve the UDF objects */
   2335     scache_obj_ptr = (_bcm_udf_td3_wb_obj_info_2_t *)(*scache_ptr);
   2336     for (ct = 0; ct < num_udfs; ct++) {
   2337         /* Allocate memory for UDF object info. */
   2338         obj_info = NULL;
   2339         _BCM_UDF_ALLOC(obj_info, sizeof(_bcm_udf_td3_obj_info_t),
   2340                        "UDF object info.");
   2341         if (obj_info == NULL) {
   2342            return BCM_E_MEMORY;
   2343         }
   2344 
   2345         obj_info->udf_id = scache_obj_ptr->udf_id;
   2346         obj_info->offset = scache_obj_ptr->offset;
   2347         obj_info->chunk_bmap = scache_obj_ptr->chunk_bmap;
   2348 
   2349         (void)_udf_chunk_bmap_to_chunks(obj_info->chunk_bmap,
   2350                                         &num_chunks, NULL);
   2351         obj_info->width = _BCM_UDF_CHUNK_TO_BYTE(num_chunks);
   2352         if (recovered_version > BCM_WB_VERSION_1_0) {
   2353            num_stages = scache_obj_ptr->num_stages;
   2354         } else {
   2355            num_stages = 2;
   2356         }
   2357 
   2358         for (stg = 0; stg < num_stages; stg++) {
   2359            obj_info->hw_cmd_bmap[stg] = scache_obj_ptr->hw_cmd_bmap[stg];
   2360         }
   2361         obj_info->abstr_pkt_fmt = scache_obj_ptr->abstr_pkt_fmt;
   2362 
   2363         BCM_IF_ERROR_RETURN(_udf_td3_wb_abstr_pkt_fmt_recover(unit, obj_info));
   2364 
   2365         /* Add obj_info item to the linked list */
   2366         _BCM_UDF_OBJ_NODE_ADD(unit, (obj_info),
   2367                               UDF_TD3_CTRL(unit)->udf_obj_head);
   2368         scache_obj_ptr++;
   2369     }
   2370 
   2371     *scache_ptr = (uint8 *)scache_obj_ptr;
   2372     return BCM_E_NONE;
   2373 }
   2374 
   2375 /*
   2376  * Routine to recover UDF Abstract Pkt Fmt default cmd_policy_data.
   2377  */
   2378 STATIC int
   2379 _bcm_udf_td3_wb_abstr_pkt_fmt_info_recover_2_0(int unit, uint16 recovered_version, uint8 **scache_ptr)
   2380 {
   2381     uint8 stage, len;
   2382     soc_mem_t policy_mem;
   2383     uint8 num_stages = 0;
   2384     uint8 *cmd_pol_data_buf = NULL;
   2385     bcm_udf_abstract_pkt_format_t pkt_fmt;
   2386     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info;
   2387 
   2388     for (pkt_fmt = bcmUdfAbstractPktFormatLlc;
   2389          pkt_fmt < bcmUdfAbstractPktFormatLastCount;
   2390          pkt_fmt++) {
   2391         pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt);
   2392         if (pkt_fmt_hw_info == NULL) {
   2393            continue;
   2394         }
   2395 
   2396         if (recovered_version == BCM_WB_VERSION_1_0) {
   2397            if (pkt_fmt >= bcmUdfAbstractPktFormatL3GreUnknownPayload) {
   2398               continue;
   2399            }
   2400            num_stages = 2;
   2401         } else {
   2402            num_stages = pkt_fmt_hw_info->num_stages;
   2403         }
   2404 
   2405         for (stage = 0; stage < num_stages; stage++) {
   2406             policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage];
   2407 
   2408             if (policy_mem == INVALIDm) {
   2409                LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
   2410                           "Invalid Policy mem for Abstract pkt fmt '%s', stage:%d.\n\r"),
   2411                           _udf_abstr_pkt_fmt_name(pkt_fmt), stage));
   2412                continue;
   2413             }
   2414 
   2415             len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf);
   2416 
   2417             if (pkt_fmt_hw_info->chunk_bmap_used) {
   2418                 cmd_pol_data_buf = pkt_fmt_hw_info->cmd_policy_data[stage];
   2419                 sal_memcpy(cmd_pol_data_buf, *scache_ptr, len);
   2420                 *scache_ptr += len;
   2421                 pkt_fmt_hw_info->cmd_policy_data[stage] = cmd_pol_data_buf;
   2422             }
   2423         }
   2424     }
   2425 
   2426     return BCM_E_NONE;
   2427 }
   2428 
   2429 
   2430 
   2431 /*
   2432  * Routine to Sync UDF Object information for WarmBoot.
   2433  */
   2434 STATIC int
   2435 _bcm_udf_td3_wb_obj_info_sync_1_0(int unit, uint8 **scache_ptr)
   2436 {
   2437     _bcm_udf_td3_wb_obj_info_t *scache_obj_ptr;
   2438     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   2439     uint16 *scache_num_udf_ptr = NULL;
   2440     uint16 num_udfs = 0;
   2441 
   2442     scache_num_udf_ptr = (uint16 *)(*scache_ptr);
   2443     *scache_ptr += sizeof(num_udfs);
   2444 
   2445     scache_obj_ptr = (_bcm_udf_td3_wb_obj_info_t *)(*scache_ptr);
   2446 
   2447     obj_info = UDF_TD3_CTRL(unit)->udf_obj_head;
   2448     while (obj_info != NULL) {
   2449          scache_obj_ptr->udf_id = obj_info->udf_id;
   2450          scache_obj_ptr->offset = obj_info->offset;
   2451          scache_obj_ptr->chunk_bmap = obj_info->chunk_bmap;
   2452          scache_obj_ptr->abstr_pkt_fmt = obj_info->abstr_pkt_fmt;
   2453          scache_obj_ptr->hw_cmd_bmap1 = obj_info->hw_cmd_bmap[0];
   2454          scache_obj_ptr->hw_cmd_bmap2 = obj_info->hw_cmd_bmap[1];
   2455 
   2456          scache_obj_ptr++;
   2457          num_udfs++;
   2458          _BCM_UDF_OBJ_NODE_NEXT(obj_info);
   2459     }
   2460     sal_memcpy(scache_num_udf_ptr, &num_udfs, sizeof(num_udfs));
   2461 
   2462     *scache_ptr = (uint8 *)scache_obj_ptr;
   2463     return BCM_E_NONE;
   2464 }
   2465 /*
   2466  * Routine to Sync UDF Object information for WarmBoot.
   2467  */
   2468 STATIC int
   2469 _bcm_udf_td3_wb_obj_info_sync_2_0(int unit, uint8 **scache_ptr)
   2470 {
   2471     uint8 stg;
   2472     _bcm_udf_td3_wb_obj_info_2_t *scache_obj_ptr;
   2473     _bcm_udf_td3_obj_info_t *obj_info = NULL;
   2474     uint16 *scache_num_udf_ptr = NULL;
   2475     uint16 num_udfs = 0;
   2476 
   2477     scache_num_udf_ptr = (uint16 *)(*scache_ptr);
   2478     *scache_ptr += sizeof(num_udfs);
   2479 
   2480     scache_obj_ptr = (_bcm_udf_td3_wb_obj_info_2_t *)(*scache_ptr);
   2481 
   2482     obj_info = UDF_TD3_CTRL(unit)->udf_obj_head;
   2483     while (obj_info != NULL) {
   2484          scache_obj_ptr->udf_id = obj_info->udf_id;
   2485          scache_obj_ptr->offset = obj_info->offset;
   2486          scache_obj_ptr->chunk_bmap = obj_info->chunk_bmap;
   2487          scache_obj_ptr->abstr_pkt_fmt = obj_info->abstr_pkt_fmt;
   2488          scache_obj_ptr->num_stages = _BCM_UDF_MAX_PARSER_STAGES;
   2489          for (stg = 0; stg < _BCM_UDF_MAX_PARSER_STAGES; stg++) {
   2490             scache_obj_ptr->hw_cmd_bmap[stg] = obj_info->hw_cmd_bmap[stg];
   2491          }
   2492 
   2493          scache_obj_ptr++;
   2494          num_udfs++;
   2495          _BCM_UDF_OBJ_NODE_NEXT(obj_info);
   2496     }
   2497     sal_memcpy(scache_num_udf_ptr, &num_udfs, sizeof(num_udfs));
   2498 
   2499     *scache_ptr = (uint8 *)scache_obj_ptr;
   2500     return BCM_E_NONE;
   2501 }
   2502 
   2503 /*
   2504  * Routine to sync UDF Abstract Pkt Fmt default cmd_policy_data.
   2505  */
   2506 STATIC int
   2507 _bcm_udf_td3_wb_abstr_pkt_fmt_info_sync_1_0(int unit, uint8 **scache_ptr)
   2508 {
   2509     uint8 stage, len;
   2510     soc_mem_t policy_mem;
   2511     uint8 *cmd_policy_data = NULL;
   2512     bcm_udf_abstract_pkt_format_t pkt_fmt;
   2513     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info;
   2514 
   2515     for (pkt_fmt = bcmUdfAbstractPktFormatLlc;
   2516          pkt_fmt < bcmUdfAbstractPktFormatLastCount;
   2517          pkt_fmt++) {
   2518         pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt);
   2519         if (pkt_fmt_hw_info == NULL) {
   2520            continue;
   2521         }
   2522 
   2523         /*
   2524          * INT containers are fixed, need not sync the containers.
   2525          */
   2526         if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) ||
   2527             (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) {
   2528            continue;
   2529         }
   2530 
   2531         if (pkt_fmt_hw_info->chunk_bmap_used) {
   2532             for (stage = 0; stage < _BCM_UDF_MAX_PARSER_STAGES; stage++) {
   2533                 policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage];
   2534                 cmd_policy_data = pkt_fmt_hw_info->cmd_policy_data[stage];
   2535 
   2536                 if (policy_mem == INVALIDm || policy_mem == 0) {
   2537                    continue;
   2538                 }
   2539 
   2540                 len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf);
   2541                 sal_memcpy(*scache_ptr, cmd_policy_data, len);
   2542                 *scache_ptr += len;
   2543             }
   2544         }
   2545     }
   2546 
   2547     return BCM_E_NONE;
   2548 }
   2549 
   2550 
   2551 /*
   2552  * Routine to sync UDF Abstract Pkt Fmt default cmd_policy_data.
   2553  */
   2554 STATIC int
   2555 _bcm_udf_td3_wb_abstr_pkt_fmt_info_sync_2_0(int unit, uint8 **scache_ptr)
   2556 {
   2557     uint8 stage, len;
   2558     soc_mem_t policy_mem;
   2559     uint32 cancun_ver;
   2560     uint8 *cmd_policy_data = NULL;
   2561     bcm_udf_abstract_pkt_format_t pkt_fmt;
   2562     _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info;
   2563 
   2564     for (pkt_fmt = bcmUdfAbstractPktFormatLlc;
   2565          pkt_fmt < bcmUdfAbstractPktFormatLastCount;
   2566          pkt_fmt++) {
   2567         pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt);
   2568         if (pkt_fmt_hw_info == NULL) {
   2569            continue;
   2570         }
   2571 
   2572        /*
   2573         * INT containers are fixed, need not sync the containers.
   2574         */
   2575         BCM_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver));
   2576         if (SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) {
   2577             if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) ||
   2578                 (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) {
   2579                 continue;
   2580             }
   2581         }
   2582 
   2583         if (pkt_fmt_hw_info->chunk_bmap_used) {
   2584             for (stage = 0; stage < pkt_fmt_hw_info->num_stages; stage++) {
   2585                 policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage];
   2586                 cmd_policy_data = pkt_fmt_hw_info->cmd_policy_data[stage];
   2587 
   2588                 if (policy_mem == INVALIDm || policy_mem == 0) {
   2589                    LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit,
   2590                           "Invalid Policy mem for Abstract pkt fmt '%s', stage:%d.\n\r"),
   2591                           _udf_abstr_pkt_fmt_name(pkt_fmt), stage));
   2592                    return BCM_E_INTERNAL;
   2593                 }
   2594 
   2595                 len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf);
   2596                 sal_memcpy(*scache_ptr, cmd_policy_data, len);
   2597                 *scache_ptr += len;
   2598             }
   2599         }
   2600     }
   2601 
   2602     return BCM_E_NONE;
   2603 }
   2604 
   2605 
   2606 /*
   2607  * Function:
   2608  *      _bcm_udf_td3_udf_wb_sync
   2609  * Purpose:
   2610  *      Syncs UDF warmboot state to scache
   2611  * Parameters:
   2612  *      unit   - (IN)  Unit number.
   2613  * Returns:
   2614  *      BCM_E_XXX
   2615  * Notes:
   2616  */
   2617 STATIC int
   2618 _bcm_udf_td3_wb_sync(int unit)
   2619 {
   2620     uint8   *scache_ptr;
   2621     soc_scache_handle_t scache_handle;
   2622 
   2623     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_UDF, 0);
   2624 
   2625     BCM_IF_ERROR_RETURN
   2626         (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
   2627                                  0, &scache_ptr,
   2628                                  BCM_WB_DEFAULT_VERSION, NULL));
   2629     if (UDF_CONTROL(unit) != NULL) {
   2630        if (BCM_WB_DEFAULT_VERSION == BCM_WB_VERSION_1_0) {
   2631           BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_obj_info_sync_1_0(unit, &scache_ptr));
   2632           BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_abstr_pkt_fmt_info_sync_1_0(unit, &scache_ptr));
   2633        } else {
   2634           BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_obj_info_sync_2_0(unit, &scache_ptr));
   2635           BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_abstr_pkt_fmt_info_sync_2_0(unit, &scache_ptr));
   2636        }
   2637     }
   2638     return BCM_E_NONE;
   2639 }
   2640 
   2641 /* Returns required scache size in bytes for version = 1_0 */
   2642 STATIC int
   2643 _bcm_udf_td3_wb_scache_size_get_1_0(int unit, int *req_scache_size)
   2644 {
   2645     int len;
   2646     int alloc_size = 0;
   2647 
   2648     /* Number of UDFs */
   2649     alloc_size += sizeof(uint16);
   2650 
   2651     /* Max UDF Object Nodes. */
   2652     alloc_size += (UDF_CONTROL(unit)->max_udfs *
   2653                    sizeof(_bcm_udf_td3_wb_obj_info_t));
   2654 
   2655     /* Max UDF Abstract Type CMD_POLICY_DATA. */
   2656     len = soc_mem_field_length(unit, IP_PARSER1_HFE_POLICY_TABLE_3m, CMD_POLICY_DATAf);
   2657     alloc_size += ((bcmUdfAbstractPktFormatLastCount - 1) * len);
   2658 
   2659     *req_scache_size = alloc_size;
   2660 
   2661     return BCM_E_NONE;
   2662 }
   2663 
   2664 /* Returns required scache size in bytes for version = 2_0 */
   2665 STATIC int
   2666 _bcm_udf_td3_wb_scache_size_get_2_0(int unit, int *req_scache_size)
   2667 {
   2668     int len;
   2669     int alloc_size = 0;
   2670 
   2671     /* Number of UDFs */
   2672     alloc_size += sizeof(uint16);
   2673 
   2674     /* Max UDF Object Nodes. */
   2675     alloc_size += (UDF_CONTROL(unit)->max_udfs *
   2676                    sizeof(_bcm_udf_td3_wb_obj_info_2_t));
   2677 
   2678     /* Max UDF Abstract Type CMD_POLICY_DATA. */
   2679     len = soc_mem_field_length(unit, IP_PARSER1_HFE_POLICY_TABLE_3m, CMD_POLICY_DATAf);
   2680     alloc_size += ((bcmUdfAbstractPktFormatLastCount - 1) * len);
   2681 
   2682     *req_scache_size = alloc_size;
   2683 
   2684     return BCM_E_NONE;
   2685 }
   2686 
   2687 
   2688 /* Returns required scache size for UDF module */
   2689 STATIC int
   2690 _bcm_udf_td3_wb_scache_size_get(int unit, int *req_scache_size)
   2691 {
   2692     if (BCM_WB_DEFAULT_VERSION > BCM_WB_VERSION_1_0) {
   2693        BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_scache_size_get_2_0(unit,
   2694                                                    req_scache_size));
   2695     } else {
   2696        BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_scache_size_get_1_0(unit,
   2697                                                   req_scache_size));
   2698     }
   2699     return BCM_E_NONE;
   2700 }
   2701 
   2702 /* Allocates required scache size for the UDF module recovery */
   2703 STATIC int
   2704 _bcm_udf_td3_wb_alloc(int unit)
   2705 {
   2706     int     rv;
   2707     int     req_scache_size;
   2708     uint8   *scache_ptr;
   2709     soc_scache_handle_t scache_handle;
   2710     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_UDF, 0);
   2711 
   2712     rv = _bcm_udf_td3_wb_scache_size_get(unit, &req_scache_size);
   2713     BCM_IF_ERROR_RETURN(rv);
   2714 
   2715     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE,
   2716                                  req_scache_size, &scache_ptr,
   2717                                  BCM_WB_DEFAULT_VERSION, NULL);
   2718 
   2719     if (BCM_E_NOT_FOUND == rv) {
   2720         /* Proceed with Level 1 Warm Boot */
   2721         rv = BCM_E_NONE;
   2722     }
   2723 
   2724     return rv;
   2725 }
   2726 
   2727 
   2728 /*
   2729  * Function:
   2730  *      _bcm_udf_td3_reinit
   2731  * Purpose:
   2732  *      Recovers UDF warmboot state from scache
   2733  * Parameters:
   2734  *      unit  - (IN)  Unit number.
   2735  * Returns:
   2736  *      BCM_E_XXX
   2737  * Notes:
   2738  */
   2739 STATIC int
   2740 _bcm_udf_td3_reinit(int unit)
   2741 {
   2742     int     rv = BCM_E_INTERNAL;
   2743     uint8   *scache_ptr;
   2744     uint16  recovered_ver = 0;
   2745     soc_scache_handle_t scache_handle;
   2746     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_UDF, 0);
   2747 
   2748     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
   2749                                  0, &scache_ptr,
   2750                                  BCM_WB_DEFAULT_VERSION, &recovered_ver);
   2751     if (BCM_E_NOT_FOUND == rv) {
   2752         /* Proceed with Level 1 Warm Boot */
   2753         rv = BCM_E_NONE;
   2754     }
   2755 
   2756     BCM_IF_ERROR_RETURN(rv);
   2757 
   2758     if (recovered_ver > BCM_WB_VERSION_1_0) {
   2759        rv = _bcm_udf_td3_wb_obj_info_recover_2_0(unit, recovered_ver, &scache_ptr);
   2760        BCM_IF_ERROR_RETURN(rv);
   2761 
   2762        rv = _bcm_udf_td3_wb_abstr_pkt_fmt_info_recover_2_0(unit, recovered_ver, &scache_ptr);
   2763        BCM_IF_ERROR_RETURN(rv);
   2764     } else if (recovered_ver == BCM_WB_VERSION_1_0) {
   2765        rv = _bcm_udf_td3_wb_obj_info_recover_1_0(unit, &scache_ptr);
   2766        BCM_IF_ERROR_RETURN(rv);
   2767 
   2768        rv = _bcm_udf_td3_wb_abstr_pkt_fmt_info_recover_1_0(unit, &scache_ptr);
   2769        BCM_IF_ERROR_RETURN(rv);
   2770     }
   2771 
   2772     if (BCM_SUCCESS(rv) &&
   2773        (recovered_ver < BCM_WB_DEFAULT_VERSION)) {
   2774         /*
   2775          * This will handle the below cases
   2776          * 1. When warboot from release which didn't had UDF module in SCACHE or
   2777          * 2. The current release SCACHE size required is more than previous version or
   2778          * 3. Level 1 warmboot in this case memory will not be allocated.
   2779          */
   2780         BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_alloc(unit));
   2781     }
   2782     return rv;
   2783 }
   2784 
   2785 #endif /* BCM_WARM_BOOT_SUPPORT */
   2786 /*
   2787  * Routine to dump UDF mem info.
   2788  */
   2789 STATIC void
   2790 _bcm_udf_td3_sw_mem_dump(int unit, soc_mem_t mem, int idx)
   2791 {
   2792     _bcm_udf_td3_format_field_dump(unit, mem, idx);
   2793 }
   2794 
   2795 
   2796 /*
   2797  * Function:
   2798  *    _bcm_udf_td3_functions_init
   2799  *
   2800  * Purpose:
   2801  *    Set up functions pointers
   2802  *
   2803  * Parameters:
   2804  *    functions - (IN/OUT) Pointer to device specific UDF module utility
   2805  *                         routines.
   2806  *
   2807  * Returns:
   2808  *     Nothing
   2809  */
   2810 void
   2811 _bcm_udf_td3_functions_init(_bcm_udf_funct_t *functions)
   2812 {
   2813     functions->udf_init                = _bcm_udf_td3_init;
   2814     functions->udf_detach              = _bcm_udf_td3_detach;
   2815     functions->udf_chunk_create        = _bcm_udf_td3_chunk_create;
   2816     functions->udf_destroy             = _bcm_udf_td3_destroy;
   2817     functions->udf_chunk_info_get      = _bcm_udf_td3_chunk_info_get;
   2818     functions->udf_flow_based_chunk_arrange_set =
   2819                                          _bcm_udf_flow_based_chunk_arrange_set;
   2820     functions->udf_flow_based_chunk_arrange_get =
   2821                                          _bcm_udf_flow_based_chunk_arrange_get;
   2822     functions->udf_abstr_pkt_format_obj_list_get =
   2823                                          _bcm_udf_td3_abstr_pkt_format_obj_list_get;
   2824     functions->udf_abstr_pkt_format_info_get =
   2825                                          _bcm_udf_td3_abstr_pkt_format_info_get;
   2826 #ifdef BCM_WARM_BOOT_SUPPORT
   2827     functions->udf_wb_sync = _bcm_udf_td3_wb_sync;
   2828 #endif /* BCM_WARM_BOOT_SUPPORT */
   2829     functions->udf_range_checker_chunk_info_get =
   2830                                          _bcm_udf_td3_range_checker_chunk_info_get;
   2831     functions->udf_sw_dump             = _bcm_udf_td3_sw_dump;
   2832     functions->udf_sw_mem_dump         = _bcm_udf_td3_sw_mem_dump;
   2833 }
   2834 #endif /* (BCM_TRIDENT3_SUPPORT) */