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

shr_template.c (109682B)


      1 /*
      2  * 
      3  * 
      4  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      5  * 
      6  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      7  *
      8  * Global template management
      9  */
     10 
     11 #include <shared/bsl.h>
     12 
     13 #include <sal/core/sync.h>
     14 #include <shared/shr_template.h>
     15 #include <shared/error.h>
     16 
     17 #if defined(BCM_PETRA_SUPPORT)
     18 #include <soc/cm.h>
     19 #include <soc/dpp/SAND/Utils/sand_os_interface.h>
     20 #include <soc/dpp/SAND/Utils/sand_multi_set.h>
     21 #include <bcm_int/dpp/error.h>
     22 #include <shared/swstate/access/sw_state_access.h>
     23 
     24 /*****************************************************************************/
     25 /*
     26  *  Internal implementation
     27  */
     28 
     29 /* Sw state access macro. */
     30 #define TEMPLATE_ACCESS sw_state_access[unit].dpp.shr.template_info
     31 
     32 
     33 #define SHR_TEMPLATE_MAX_BUFFER_SIZE_FOR_PRINT  2048
     34 
     35 /* A handle for a non-unit-based template manager instance */
     36 typedef struct _shr_template_unit_desc_s *shr_mtemplate_handle_t;
     37 
     38 
     39 /*
     40  *  Various function prototypes per method for the alloc managers.
     41  */
     42 typedef int (*_shr_template_manage_create)(int unit,
     43                                            int pool_id,
     44                                          int template_low_id,
     45                                          int template_count,
     46                                          int max_entities,
     47                                          uint32 global_max,
     48                                          size_t data_size,
     49                                          const void *extras,
     50                                          const char *name);
     51 typedef int (*_shr_template_manage_destroy)(int unit, int pool_id);
     52 typedef int (*_shr_template_manage_alloc)(int unit, 
     53                                           int pool_id,
     54                                         uint32 flags,
     55                                         const void* data,
     56                                         int *is_allocated,
     57                                         int *template);
     58 typedef int (*_shr_template_manage_alloc_group)(int unit, 
     59                                                 int pool_id,
     60                                                 uint32 flags,
     61                                                 const void* data,
     62                                                 int nof_additions,
     63                                                 int *is_allocated,
     64                                                 int *template);
     65 typedef int (*_shr_template_manage_exchange)(int unit, 
     66                                              int pool_id,
     67                                             uint32 flags,
     68                                             const void *data,
     69                                             int old_template,
     70                                             int *is_last,
     71                                             int *template,
     72                                             int *is_allocated); 
     73 typedef int (*_shr_template_manage_exchange_test)(int unit, 
     74                                                   int pool_id,
     75                                                 uint32 flags,
     76                                                 const void *data,
     77                                                 int old_template,
     78                                                 int *is_last,
     79                                                 int *template,
     80                                                 int *is_allocated);                       
     81 typedef int (*_shr_template_manage_free)(int unit, 
     82                                          int pool_id,                                  
     83                                         int template,
     84                                         int *is_free);
     85 typedef int (*_shr_template_manage_free_group)(int unit, 
     86                                                int pool_id,                                  
     87                                                 int template,
     88                                                 int nof_deductions,
     89                                                 int *is_free);
     90 typedef int (*_shr_template_manage_data_get)(int unit, 
     91                                              int pool_id,
     92                                             int template,
     93                                             void *data);
     94 typedef int (*_shr_template_manage_index_get)(int unit, 
     95                                               int pool_id,
     96                                             const void *data, 
     97                                             int *template);
     98 typedef int (*_shr_template_manage_ref_count_get)(int unit, 
     99                                                   int pool_id,
    100                                                 int template,
    101                                                 uint32 *ref_count);
    102 typedef int (*_shr_template_manage_clear)(int unit, int pool_id);
    103 
    104 /*
    105  *  This structure describes a single allocator mechanism, specifically by
    106  *  providing a set pointers to functions that are used to manipulate it.
    107  */
    108 typedef struct _shr_template_managements_s {
    109     _shr_template_manage_create create;
    110     _shr_template_manage_destroy destroy;
    111     _shr_template_manage_alloc alloc;
    112     _shr_template_manage_alloc_group alloc_group;
    113     _shr_template_manage_exchange exchange;
    114     _shr_template_manage_exchange_test exchange_test;
    115     _shr_template_manage_free free;
    116     _shr_template_manage_free_group free_group;
    117     _shr_template_manage_data_get data_get;
    118     _shr_template_manage_ref_count_get ref_count_get;
    119     _shr_template_manage_clear clear;
    120     _shr_template_manage_index_get index_get;
    121     char *name;
    122 } _shr_template_managements_t;
    123 
    124 /*
    125  *  These prototypes are for the global const structure below that points to
    126  *  all of the various implementations.
    127  */
    128 static int _shr_template_hash_create(int unit, 
    129                                      int pool_id,
    130                                      int template_low_id,
    131                                      int template_count,
    132                                      int max_entities,
    133                                      uint32 global_max,
    134                                      size_t data_size,
    135                                      const void *extras,
    136                                      const char *name);
    137 static int _shr_template_hash_destroy(int unit, int pool_id);
    138 static int _shr_template_hash_alloc(int unit, 
    139                                     int pool_id,
    140                                      uint32 flags,
    141                                      const void* data,
    142                                      int *is_allocated,
    143                                      int *template);
    144 static int _shr_template_hash_alloc_group(int unit, 
    145                                           int pool_id,
    146                                          uint32 flags,
    147                                          const void* data,
    148                                          int nof_additions,
    149                                          int *is_allocated,
    150                                          int *template);
    151 static int _shr_template_hash_free(int unit, 
    152                                    int pool_id,
    153                                     int template,
    154                                     int *is_last);
    155 static int _shr_template_hash_free_group(int unit, 
    156                                          int pool_id,
    157                                         int template,
    158                                         int nof_deductions,
    159                                         int *is_last);
    160 static int _shr_template_hash_exchange(int unit, 
    161                                        int pool_id,
    162                                         uint32 flags,
    163                                         const void *data,
    164                                         int old_template,
    165                                         int *is_last,
    166                                         int *template,
    167                                         int *is_allocated);
    168 static int _shr_template_hash_exchange_test(int unit, 
    169                                             int pool_id,
    170                                             uint32 flags,
    171                                             const void *data,
    172                                             int old_template,
    173                                             int *is_last,
    174                                             int *template,
    175                                             int *is_allocated);
    176 static int _shr_template_hash_data_get(int unit, 
    177                                        int pool_id,
    178                                         int template,
    179                                         void *data);
    180 static int _shr_template_hash_ref_count_get(int unit, 
    181                                             int pool_id,
    182                                             int template,
    183                                             uint32 *ref_count);
    184 static int _shr_template_hash_clear(int unit, int pool_id);
    185 static int _shr_template_hash_index_get(int unit, 
    186                                         int pool_id,
    187                                         const void *data,
    188                                         int* template);
    189 /*
    190  *  Global const structure describing the various allocator mechanisms.
    191  */
    192 static const _shr_template_managements_t _shr_template_managements_mgrs[SHR_TEMPLATE_MANAGE_COUNT] =
    193     {
    194         {
    195             _shr_template_hash_create,
    196             _shr_template_hash_destroy,
    197             _shr_template_hash_alloc,
    198             _shr_template_hash_alloc_group,
    199             _shr_template_hash_exchange,
    200             _shr_template_hash_exchange_test,
    201             _shr_template_hash_free,
    202             _shr_template_hash_free_group,
    203             _shr_template_hash_data_get,
    204             _shr_template_hash_ref_count_get,
    205             _shr_template_hash_clear,
    206             _shr_template_hash_index_get,
    207             "SHR_TEMPLATE_MANAGE_HASH"
    208         } /* hash */
    209     };
    210 
    211 /*
    212  * Global array holding the callbacks to the to_stream and from_stream functions. 
    213  * Should be filled when template manager is started. 
    214  */
    215 static shr_template_to_stream_t     *hash_compare_to_stream_cb[BCM_MAX_NUM_UNITS];
    216 static shr_template_from_stream_t   *hash_compare_from_stream_cb[BCM_MAX_NUM_UNITS];
    217 
    218 
    219 /*
    220  *  Basic checks performed for many functions
    221  */
    222 #define SW_STATE_ACCESS_ERROR_CHECK(rv) \
    223     if (rv != _SHR_E_NONE) {             \
    224         LOG_ERROR(BSL_LS_SOC_COMMON,    \
    225                   (BSL_META("Error in sw state access\n")));    \
    226         return _SHR_E_INTERNAL;  \
    227     }
    228 
    229 
    230 #define SW_STATE_ACCESS_ERROR_CHECK_NO_RET(rv) \
    231     if (rv != _SHR_E_NONE) {             \
    232         LOG_ERROR(BSL_LS_SOC_COMMON,    \
    233                   (BSL_META("Error in sw state access\n")));    \
    234         rv = _SHR_E_INTERNAL;  \
    235         goto err;   \
    236     }
    237 
    238 #define TEMPLATE_UNIT_CHECK(_unit) \
    239     {\
    240         uint8 _exists;\
    241         if ((0 > (_unit)) || (BCM_LOCAL_UNITS_MAX <= (_unit))) { \
    242             LOG_ERROR(BSL_LS_SOC_COMMON, \
    243             (BSL_META_U(_unit, \
    244                         "invalid unit number %d\n"), \
    245                        _unit)); \
    246             return BCM_E_PARAM; \
    247         } \
    248         SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.is_allocated(_unit, &_exists)); \
    249         if (!_exists) { \
    250             LOG_ERROR(BSL_LS_SOC_COMMON, \
    251             (BSL_META_U(_unit, \
    252                         "unit %d is not initialised\n"), \
    253                        _unit)); \
    254             return BCM_E_INIT; \
    255         } \
    256     }
    257     
    258 #define TEMPLATE_POOL_VALID_CHECK(_unit, _pool) \
    259     {\
    260         uint16 _templatePoolCount;\
    261         SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.templatePoolCount.get(_unit, &_templatePoolCount)); \
    262         if ((0 > (_pool)) || (_templatePoolCount <= (_pool))) { \
    263             LOG_ERROR(BSL_LS_SOC_COMMON, \
    264                       (BSL_META("unit %d pool %d does not exist\n"), \
    265                        _unit, _pool)); \
    266             return BCM_E_PARAM; \
    267         }\
    268     }
    269 #define TEMPLATE_POOL_EXIST_CHECK(_unit, _pool) \
    270     {\
    271         uint8 _exists;\
    272         SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.pool.is_allocated(_unit, _pool, &_exists)); \
    273         if (!_exists) { \
    274             LOG_ERROR(BSL_LS_SOC_COMMON, \
    275                       (BSL_META("unit %d pool %d is not configured\n"), \
    276                        _unit, _pool)); \
    277             return BCM_E_CONFIG; \
    278         }\
    279     }
    280 #define TEMPLATE_TYPE_VALID_CHECK(_unit, _type) \
    281     {\
    282         uint16 _templateTypeCount;\
    283         SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.templateTypeCount.get(_unit, &_templateTypeCount)); \
    284         if ((0 > (_type)) || (_templateTypeCount <= (_type))) { \
    285             LOG_ERROR(BSL_LS_SOC_COMMON, \
    286                       (BSL_META("unit %d template %d does not exist\n"), \
    287                        _unit, _type)); \
    288             return BCM_E_PARAM; \
    289         }\
    290     }
    291 #define TEMPLATE_TYPE_EXIST_CHECK(_unit, _type) \
    292     {\
    293         uint8 _exists;\
    294         SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.template_param.is_allocated(_unit, _type, &_exists)); \
    295         if (!_exists) { \
    296             LOG_ERROR(BSL_LS_SOC_COMMON, \
    297                       (BSL_META("unit %d template %d is not configured\n"), \
    298                        _unit, _type)); \
    299             return BCM_E_CONFIG; \
    300         }\
    301     }
    302 #define TEMPLATE_PARAM_NULL_CHECK(_unit, _param) \
    303     if ((_param) == NULL) { \
    304         LOG_ERROR(BSL_LS_SOC_COMMON, \
    305                   (BSL_META("unit %d template with obligatory argument is NULL\n"), \
    306                    _unit)); \
    307         return BCM_E_PARAM;  \
    308     }
    309 #define TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(_unit,_thisPool,_template) \
    310     {\
    311         int _template_low_id, _template_count; \
    312         SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.pool.template_low_id.get(_unit, _thisPool, &_template_low_id)); \
    313         SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.pool.template_count.get(_unit, _thisPool, &_template_count)); \
    314         if (!(_template >= _template_low_id && _template <= (_template_low_id + _template_count-1))) { \
    315             LOG_ERROR(BSL_LS_SOC_COMMON, \
    316                       (BSL_META("_template id %d is not in correct range. Should be between thisPool.template_low_id %d template_count %d\n") \
    317                        , _template, _template_low_id, (_template_low_id + _template_count-1))); \
    318             return BCM_E_PARAM;  \
    319         }\
    320     }
    321 
    322     
    323 /* Mtemplate_* prototypes */
    324 static int
    325 shr_mtemplate_alloc(int unit, 
    326                int template_type,
    327                uint32 flags,
    328                const void *data,
    329                int *is_allocated,
    330                int *template);
    331 static int
    332 shr_mtemplate_alloc_group(int unit, 
    333                int template_type,
    334                uint32 flags,
    335                const void *data,
    336                int nof_additions,
    337                int *is_allocated,
    338                int *template);
    339 static int
    340 shr_mtemplate_free(int unit, 
    341                int template_type,
    342                int template,
    343                int *is_last);
    344 static int
    345 shr_mtemplate_free_group(int unit, 
    346                int template_type,
    347                int template,
    348                int nof_deductions,
    349                int *is_last);
    350 static int
    351 shr_mtemplate_exchange(int unit, 
    352                       int template_type,
    353                       uint32 flags,
    354                       const void *data,
    355                       int old_template,
    356                       int *is_last,
    357                       int *template,
    358                       int *is_allocated);
    359 static int
    360 shr_mtemplate_exchange_test(int unit, 
    361                           int template_type,
    362                           uint32 flags,
    363                           const void *data,
    364                           int old_template,
    365                           int *is_last,
    366                           int *template,
    367                           int *is_allocated);
    368 static int
    369 shr_mtemplate_data_get(int unit, 
    370                       int template_type,
    371                       int template,
    372                       void *data);
    373 static int
    374 shr_mtemplate_index_get(int unit,
    375                       int template_type,
    376                       const void *data, 
    377                       int *template);
    378 static int
    379 shr_mtemplate_ref_count_get(int unit,
    380                       int template_type,
    381                       int template,
    382                       uint32 *ref_count);
    383 static int
    384 shr_mtemplate_create(int unit,
    385                 int num_template_types,
    386                 int num_template_pools,
    387                 shr_template_to_stream_t *to_stream_cb_arr,
    388                 shr_template_from_stream_t *from_stream_cb_arr,
    389                 int cb_arr_length);
    390 static int
    391 shr_mtemplate_get(int unit,
    392                  int *num_template_types,
    393                  int *num_template_pools);
    394 static int
    395 shr_mtemplate_pool_set(int unit,
    396                  int pool_id,
    397                  shr_template_manage_t manager,
    398                  int template_low_id,
    399                  int template_count,
    400                  int max_entities,
    401                  uint32 global_max,
    402                  size_t data_size,
    403                  const void *extras,
    404                  const char *name);
    405 static int
    406 shr_mtemplate_pool_get(int unit,
    407                       int pool_id,
    408                       shr_template_manage_t *manager,
    409                       int *template_low_id,
    410                       int *template_count,
    411                       int *max_entities,
    412                       size_t *data_size,
    413                       shr_template_manage_hash_compare_extras_t *extras,
    414                       sw_state_template_name_t *name);
    415 static int
    416 shr_mtemplate_pool_unset(int unit,
    417                     int pool_id);
    418 static int
    419 shr_mtemplate_type_set(int unit,
    420                       int template_type,
    421                       int pool_id,
    422                       const char *name);
    423 static int
    424 shr_mtemplate_type_get(int unit,
    425                   int template_type,
    426                   int *pool_id,
    427                   sw_state_template_name_t *name);
    428 static int
    429 shr_mtemplate_type_unset(int unit,
    430                     int template_id);
    431 static int
    432 _shr_mtemplate_destroy_data(int unit);
    433 static int 
    434 shr_mtemplate_dump(int unit, int template_type);
    435 static int 
    436 shr_mtemplate_clear(int unit, int template_type);
    437 
    438 /*****************************************************************************/
    439 /*
    440  *  Exposed API implementation (unit based)
    441  */
    442 
    443 /*
    444  *      Initialize the tamplate manager for the unit
    445  */
    446 int
    447 shr_template_init(int unit,
    448                   int num_template_types,
    449                   int num_template_pools,
    450                   shr_template_to_stream_t *to_stream_cb_arr,
    451                   shr_template_from_stream_t *from_stream_cb_arr,
    452                   int cb_arr_length)
    453 {
    454     int result = BCM_E_NONE;
    455     uint8 exists;
    456 
    457     LOG_DEBUG(BSL_LS_SOC_COMMON,
    458               (BSL_META_U(unit,
    459                           "(%d, %d, %d) enter\n"),
    460                unit,
    461                num_template_types,
    462                num_template_pools));
    463 
    464     /* a little parameter checking */
    465     if ((0 > unit) || (BCM_LOCAL_UNITS_MAX <= unit)) {
    466         LOG_ERROR(BSL_LS_SOC_COMMON,
    467                   (BSL_META_U(unit,
    468                               "invalid unit number %d\n"),
    469                    unit));
    470         return BCM_E_PARAM;
    471     }
    472 
    473     /* get this unit's current information, mark it as destroyed */
    474     result = TEMPLATE_ACCESS.is_allocated(unit, &exists);
    475     SW_STATE_ACCESS_ERROR_CHECK(result); 
    476 
    477     if (exists) {
    478         /* this unit has already been initialised; tear it down */
    479         result = _shr_mtemplate_destroy_data(unit);
    480     } /* if (exists) */
    481 
    482 
    483     if (BCM_E_NONE == result) {
    484         result = shr_mtemplate_create(unit,
    485                                  num_template_types,
    486                                  num_template_pools,
    487                                  to_stream_cb_arr,
    488                                  from_stream_cb_arr,
    489                                  cb_arr_length);
    490     } /* if (BCM_E_NONE == result) */
    491 
    492     /* return the result */
    493     LOG_DEBUG(BSL_LS_SOC_COMMON,
    494               (BSL_META_U(unit,
    495                           "(%d, %d, %d) return %d (%s)\n"),
    496                unit,
    497                num_template_types,
    498                num_template_pools,
    499                result,
    500                _SHR_ERRMSG(result)));
    501     return result;
    502 }
    503 
    504 /*
    505  *      Get number of template pools and types configured for a unit
    506  */
    507 int
    508 shr_template_get(int unit,
    509                  int *num_template_types,
    510                  int *num_template_pools)
    511 {
    512     /* a little parameter checking */
    513     TEMPLATE_UNIT_CHECK(unit);
    514 
    515     /* perform the fetch */
    516     return shr_mtemplate_get(unit, num_template_types, num_template_pools);
    517 }
    518 
    519 /*
    520  *      Configure a template pool for the unit
    521  */
    522 int
    523 shr_template_pool_set(int unit,
    524                  int pool_id,
    525                  shr_template_manage_t manager,
    526                  int template_low_id,
    527                  int template_count,
    528                  int max_entities,
    529                  uint32 global_max,
    530                  size_t data_size,
    531                  const void *extras,
    532                  const char *name)
    533 {
    534     /* a little parameter checking */
    535     TEMPLATE_UNIT_CHECK(unit);
    536 
    537     /* perform the action */
    538     return shr_mtemplate_pool_set(unit,
    539                              pool_id,
    540                              manager,
    541                              template_low_id,
    542                              template_count,
    543                              max_entities,
    544                              global_max,
    545                              data_size,
    546                              extras,
    547                              name);
    548 }
    549 
    550 /*
    551  *      Get configuration for a resource pool on a particular unit
    552  */
    553 int
    554 shr_template_pool_get(int unit,
    555                       int pool_id,
    556                       shr_template_manage_t *manager,
    557                       int *template_low_id,
    558                       int *template_count,
    559                       int *max_entities,
    560                       size_t *data_size,
    561                       shr_template_manage_hash_compare_extras_t *extras,
    562                       sw_state_template_name_t *name)
    563 {
    564     /* a little parameter checking */
    565     TEMPLATE_UNIT_CHECK(unit);
    566 
    567     /* perform the action */
    568     return shr_mtemplate_pool_get(unit,
    569                                  pool_id,
    570                                  manager,
    571                                  template_low_id,
    572                                  template_count,
    573                                  max_entities,
    574                                  data_size,
    575                                  extras,
    576                                  name);
    577 }
    578 
    579 /*
    580  *  Destroy a template pool on a unit
    581  */
    582 int
    583 shr_template_pool_unset(int unit,
    584                    int pool_id)
    585 {
    586     /* a little parameter checking */
    587     TEMPLATE_UNIT_CHECK(unit);
    588 
    589     /* perform the action */
    590     return shr_mtemplate_pool_unset(unit, pool_id);
    591 }
    592 
    593 /*
    594  *      Configure a template type
    595  */
    596 int
    597 shr_template_type_set(int unit,
    598                       int template_type,
    599                       int pool_id,
    600                       const char *name)
    601 {
    602     /* a little parameter checking */
    603     TEMPLATE_UNIT_CHECK(unit);
    604 
    605     /* perform the action */
    606     return shr_mtemplate_type_set(unit, template_type, pool_id, name);
    607 }
    608 
    609 /*
    610  *      Get information about a template type
    611  */
    612 extern int
    613 shr_template_type_get(int unit,
    614                       int template_type,
    615                       int *pool_id,
    616                       sw_state_template_name_t *name)
    617 {
    618     /* a little parameter checking */
    619     TEMPLATE_UNIT_CHECK(unit);
    620 
    621     /* perform the action */
    622     return shr_mtemplate_type_get(unit, template_type, pool_id, name);
    623 }
    624 
    625 
    626 /*
    627  *  Destroy a template type on a unit
    628  */
    629 int
    630 shr_template_type_unset(int unit,
    631                    int template_id)
    632 {
    633     /* a little parameter checking */
    634     TEMPLATE_UNIT_CHECK(unit);
    635 
    636     /* perform the action */
    637     return shr_mtemplate_type_unset(unit, template_id);
    638 }
    639 
    640 /*
    641  *      Remove all template management for a unit
    642  */
    643 int
    644 shr_template_detach(int unit)
    645 {
    646     int result = BCM_E_NONE;
    647     uint8 exists;
    648 
    649 
    650     LOG_DEBUG(BSL_LS_SOC_COMMON,
    651               (BSL_META_U(unit,
    652                           "(%d) enter\n"),
    653                unit));
    654 
    655     /* get this unit's current information, mark it as destroyed */
    656     result = TEMPLATE_ACCESS.is_allocated(unit, &exists);
    657     SW_STATE_ACCESS_ERROR_CHECK(result); 
    658 
    659     if (exists) {
    660         /* this unit has already been initialised; tear it down */
    661         result = _shr_mtemplate_destroy_data(unit);
    662     } /* if (exists) */
    663     /* else would be not inited, again, easy to detach in that case - NOP */
    664 
    665     /* return the result */
    666     LOG_DEBUG(BSL_LS_SOC_COMMON,
    667               (BSL_META_U(unit,
    668                           "(%d) return %d (%s)\n"),
    669                unit,
    670                result,
    671                _SHR_ERRMSG(result)));
    672     return result;
    673 }
    674 
    675 /*
    676  *      Find a template to assign to the requested data.
    677  */
    678 int
    679 shr_template_allocate(int unit,
    680                       int template_type,
    681                       uint32 flags,
    682                       const void *data,
    683                       int *is_allocated,
    684                       int *template)
    685 {
    686     /* a little parameter checking */
    687     TEMPLATE_UNIT_CHECK(unit);
    688 
    689     /* perform the action */
    690     return shr_mtemplate_alloc(unit, template_type, flags, data, is_allocated, template);
    691 }
    692 
    693 /*
    694  *      Find a template to assign to the requested data for a group of elements.
    695  */
    696 int
    697 shr_template_allocate_group(int unit,
    698                       int template_type,
    699                       uint32 flags,
    700                       const void *data,
    701                       int nof_additions,
    702                       int *is_allocated,
    703                       int *template)
    704 {
    705     /* a little parameter checking */
    706     TEMPLATE_UNIT_CHECK(unit);
    707 
    708     /* perform the action */
    709     return shr_mtemplate_alloc_group(unit, template_type, flags, data, nof_additions, is_allocated, template);
    710 }
    711 
    712 /*
    713  *      Release a template (referrer no longer points to it)
    714  */
    715 extern int
    716 shr_template_free(int unit,
    717                   int template_type,
    718                   int template,
    719                   int *is_last)
    720 {
    721     /* a little parameter checking */
    722     TEMPLATE_UNIT_CHECK(unit);
    723 
    724     /* perform the action */
    725     return shr_mtemplate_free(unit, template_type, template, is_last);
    726 }
    727 
    728 /*
    729  *      Release several template referers (referrer no longer points to it)
    730  */
    731 extern int
    732 shr_template_free_group(int unit,
    733                   int template_type,
    734                   int template,
    735                   int nof_deductions,
    736                   int *is_last)
    737 {
    738     /* a little parameter checking */
    739     TEMPLATE_UNIT_CHECK(unit);
    740 
    741     /* perform the action */
    742     return shr_mtemplate_free_group(unit, template_type, template, nof_deductions, is_last);
    743 }
    744 
    745 /*
    746  *      Free a current template and allocate a new one for new data
    747  */
    748 int
    749 shr_template_exchange(int unit,
    750                       int template_type,
    751                       uint32 flags,
    752                       const void *data,
    753                       int old_template,
    754                       int *is_last,
    755                       int *template,
    756                       int *is_allocated)
    757 {
    758     /* a little parameter checking */
    759     TEMPLATE_UNIT_CHECK(unit);
    760 
    761     /* perform the action */
    762     return shr_mtemplate_exchange(unit, template_type, flags, data, old_template, is_last, template, is_allocated);
    763 }
    764 
    765 /*
    766  *      Tests if Free a current template and allocate a new one for new data is possible
    767  */
    768 int
    769 shr_template_exchange_test(int unit,
    770                       int template_type,
    771                       uint32 flags,
    772                       const void *data,
    773                       int old_template,
    774                       int *is_last,
    775                       int *template,
    776                       int *is_allocated)
    777 {
    778     /* a little parameter checking */
    779     TEMPLATE_UNIT_CHECK(unit);
    780 
    781     /* perform the action */
    782     return shr_mtemplate_exchange_test(unit, template_type, flags, data, old_template, is_last, template, is_allocated);
    783 }
    784 
    785 /*
    786  *   Function
    787  *      shr_template_data_get
    788  *   Purpose
    789  *      Get the data from a specific template
    790  *   Parameters
    791  *      (IN) unit          : unit number of the device
    792  *      (IN) template_type : which template type to use
    793  *      (IN) template      : which template to get
    794  *      (OUT) data         : where to put the template's data
    795  *   Returns
    796  *      BCM_E_NONE if successful
    797  *      BCM_E_* as appropriate otherwise
    798  *   Notes
    799  */
    800 int
    801 shr_template_data_get(int unit,
    802                       int template_type,
    803                       int template,
    804                       void *data)
    805 {
    806     /* a little parameter checking */
    807     TEMPLATE_UNIT_CHECK(unit);
    808 
    809     /* perform the action */
    810     return shr_mtemplate_data_get(unit, template_type, template, data);
    811 }
    812 
    813 /*
    814  *   Function
    815  *      shr_template_template_get
    816  *   Purpose
    817  *      Get the template from a specific data
    818  *   Parameters
    819  *      (IN) unit          : unit number of the device
    820  *      (IN) template_type : which template type to use
    821  *      (IN) data         : the template's data
    822  *      (OUT) template      : which template
    823  *   Returns
    824  *      BCM_E_NONE if successful
    825  *      BCM_E_* as appropriate otherwise
    826  *   Notes
    827  */
    828 int
    829 shr_template_template_get(int unit,
    830                       int template_type,
    831                       const void *data,
    832                       int *template)
    833 {
    834     /* a little parameter checking */
    835     TEMPLATE_UNIT_CHECK(unit);
    836 
    837     /* perform the action */
    838     return shr_mtemplate_index_get(unit, template_type, data, template);
    839 }
    840 
    841 
    842 /*
    843  *   Function
    844  *      shr_template_ref_count_get
    845  *   Purpose
    846  *      Get the reference counter from a specific template id
    847  *   Parameters
    848  *      (IN) unit          : unit number of the device
    849  *      (IN) template_type : which template type to use
    850  *      (IN) template      : which template to get the reference count
    851  *      (OUT) ref_count    : where to put the template's reference count
    852  *   Returns
    853  *      BCM_E_NONE if successful
    854  *      BCM_E_* as appropriate otherwise
    855  *   Notes
    856  */
    857 int
    858 shr_template_ref_count_get(int unit,
    859                       int template_type,
    860                       int template,
    861                       uint32 *ref_count)
    862 {
    863     /* a little parameter checking */
    864     TEMPLATE_UNIT_CHECK(unit);
    865 
    866     /* perform the action */
    867     return shr_mtemplate_ref_count_get(unit, template_type, template, ref_count);
    868 }
    869 
    870 /*
    871  *   Function
    872  *      shr_template_dump
    873  *   Purpose
    874  *      Diagnostic dump of a unit's resource management information
    875  *   Parameters
    876  *      (IN) unit      : unit number of the device
    877  *   Returns
    878  *      BCM_E_NONE if successful
    879  *      BCM_E_* as appropriate otherwise
    880  *   Notes
    881  *      This displays the information using bsl_printf.
    882  */
    883 int
    884 shr_template_dump(int unit, int template_type)
    885 {
    886     /* a little parameter checking */
    887     TEMPLATE_UNIT_CHECK(unit);
    888 
    889     /* perform the action */
    890     return shr_mtemplate_dump(unit, template_type);
    891 }
    892 
    893 /*
    894  *   Function
    895  *      shr_template_clear
    896  *   Purpose
    897  *      Free all templates located in this template_type
    898  *      (without free memory of the template resource)
    899  *   Parameters
    900  *      (IN) unit     	   : unit number of the device
    901  *      (IN) template_type : which template type to use
    902  *   Returns
    903  *      BCM_E_NONE if successful
    904  *      BCM_E_* as appropriate otherwise
    905  *   Notes
    906  */
    907 int
    908 shr_template_clear(int unit,
    909                    int template_type)
    910 {
    911     /* a little parameter checking */
    912     TEMPLATE_UNIT_CHECK(unit);
    913 
    914     /* perform the action */
    915     return shr_mtemplate_clear(unit,template_type);
    916 }
    917 
    918 
    919 static int
    920 shr_mtmemplate_type_change_count(int unit, int template_type, int count){
    921     int refCount;
    922     int result = _SHR_E_NONE;
    923     
    924     result = TEMPLATE_ACCESS.template_param.refCount.get(unit, template_type, &refCount);
    925     SW_STATE_ACCESS_ERROR_CHECK(result); 
    926 
    927     refCount += count;
    928     
    929     /*
    930      * A free operation on an empty template would not return any indication, but would still try to 
    931      * reduce the refCount. This could go below zero, which is meaningless, so pervent it.
    932      */
    933     if (refCount < 0){
    934         refCount = 0;
    935     }
    936 
    937     result = TEMPLATE_ACCESS.template_param.refCount.set(unit, template_type, refCount);
    938     SW_STATE_ACCESS_ERROR_CHECK(result); 
    939 
    940     return result;
    941 }
    942 
    943 /*
    944  *  Allocate template of a resource type
    945  */
    946 static int
    947 shr_mtemplate_alloc(int unit, 
    948                int template_type,
    949                uint32 flags,
    950                const void *data,
    951                int *is_allocated,
    952                int *template)               
    953 {
    954     int thisPool;
    955     int result = BCM_E_NONE;
    956     shr_template_manage_t mngr_type;
    957 
    958     LOG_DEBUG(BSL_LS_SOC_COMMON,
    959               (BSL_META("(%d, %d, %08X) enter\n"),
    960                unit,
    961                template_type,
    962                flags));
    963                
    964 
    965     /* a little parameter checking */
    966     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
    967     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
    968     
    969     TEMPLATE_PARAM_NULL_CHECK(unit,data);
    970     TEMPLATE_PARAM_NULL_CHECK(unit,is_allocated);
    971     TEMPLATE_PARAM_NULL_CHECK(unit,template);
    972 
    973     if (flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS)) {
    974         LOG_ERROR(BSL_LS_SOC_COMMON,
    975                   (BSL_META("invalid flags %08X\n"),
    976                    flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS)));
    977         return BCM_E_PARAM;
    978     }
    979     
    980     /* get the pool information */
    981     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
    982     SW_STATE_ACCESS_ERROR_CHECK(result); 
    983 
    984     if (flags & SHR_TEMPLATE_MANAGE_SINGLE_FLAGS) {
    985         /* verify template id from pool information */
    986         TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,*template);
    987     }
    988 
    989     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
    990     SW_STATE_ACCESS_ERROR_CHECK(result); 
    991 
    992     /* make the call */
    993     result = _shr_template_managements_mgrs[mngr_type].alloc(unit,
    994                                                              thisPool,
    995                                                              flags,
    996                                                              data,
    997                                                              is_allocated,
    998                                                              template);
    999 
   1000      if (BCM_E_NONE == result) {
   1001         /* account for successful allocation */
   1002         result = shr_mtmemplate_type_change_count(unit, template_type, 1);
   1003         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1004     }
   1005 
   1006      LOG_DEBUG(BSL_LS_SOC_COMMON,
   1007                (BSL_META("(%d, %d, %08X, %p, %d, %d) return %d (%s)\n"),
   1008                 unit,
   1009                 template_type,
   1010                 flags,
   1011                 data,
   1012                 *is_allocated,
   1013                 *template,
   1014                 result,
   1015                 _SHR_ERRMSG(result)));
   1016 
   1017     return result;
   1018 }
   1019 
   1020 /*
   1021  *  Allocate template of a resource type for a bunch of elements
   1022  */
   1023 static int
   1024 shr_mtemplate_alloc_group(int unit, 
   1025                int template_type,
   1026                uint32 flags,
   1027                const void *data,
   1028                int nof_additions,
   1029                int *is_allocated,
   1030                int *template)               
   1031 {
   1032     shr_template_manage_t mngr_type;
   1033     int thisPool;
   1034     int result = BCM_E_NONE;
   1035     
   1036 
   1037     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1038               (BSL_META("(%d, %d, %08X) enter\n"),
   1039                unit,
   1040                template_type,
   1041                flags));
   1042                
   1043 
   1044     /* a little parameter checking */
   1045     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   1046     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   1047     
   1048     TEMPLATE_PARAM_NULL_CHECK(unit,data);
   1049     TEMPLATE_PARAM_NULL_CHECK(unit,is_allocated);
   1050     TEMPLATE_PARAM_NULL_CHECK(unit,template);
   1051 
   1052     if (flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS)) {
   1053         LOG_ERROR(BSL_LS_SOC_COMMON,
   1054                   (BSL_META("invalid flags %08X\n"),
   1055                    flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS)));
   1056         return BCM_E_PARAM;
   1057     }
   1058 
   1059     
   1060     if ((flags & (SHR_TEMPLATE_MANAGE_SET_WITH_ID)) == 0) {
   1061         LOG_ERROR(BSL_LS_SOC_COMMON,
   1062                   (BSL_META("WITH_ID must be specify %08X\n"),
   1063                    flags));
   1064         return BCM_E_PARAM;
   1065     }
   1066     
   1067     /* get the pool information */
   1068     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
   1069     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1070 
   1071     if (flags & SHR_TEMPLATE_MANAGE_SINGLE_FLAGS) {
   1072         /* verify template id from pool information */
   1073         TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,*template);
   1074     }
   1075 
   1076     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
   1077     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1078     /* make the call */
   1079     result = _shr_template_managements_mgrs[mngr_type].alloc_group(unit,
   1080                                                                      thisPool,
   1081                                                                      flags,
   1082                                                                      data,
   1083                                                                      nof_additions,
   1084                                                                      is_allocated,
   1085                                                                      template);
   1086 
   1087      if (BCM_E_NONE == result) {
   1088         /* account for successful allocation */
   1089         result = shr_mtmemplate_type_change_count(unit, template_type, nof_additions);
   1090         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1091     }
   1092 
   1093      LOG_DEBUG(BSL_LS_SOC_COMMON,
   1094                (BSL_META("(%d, %d, %08X, %p, %d, %d, %d) return %d (%s)\n"),
   1095                 unit,
   1096                 template_type,
   1097                 flags,
   1098                 data,
   1099                 nof_additions,
   1100                 *is_allocated,
   1101                 *template,
   1102                 result,
   1103                 _SHR_ERRMSG(result)));
   1104 
   1105     return result;
   1106 }
   1107 
   1108 /* Free template (if needed) and decrement reference of the given resource */
   1109 static int
   1110 shr_mtemplate_free(int unit,
   1111                int template_type,
   1112                int template,
   1113                int *is_last)
   1114 {
   1115     shr_template_manage_t mngr_type;
   1116     int  thisPool;
   1117     int result = BCM_E_NONE;
   1118 
   1119     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1120               (BSL_META("(%d, %d, %d) enter\n"),
   1121                unit,
   1122                template_type,
   1123                template));
   1124                
   1125 
   1126     /* a little parameter checking */
   1127     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   1128     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   1129 
   1130     TEMPLATE_PARAM_NULL_CHECK(unit,is_last);
   1131     
   1132     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
   1133     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1134 
   1135     /* verify template id from pool information */
   1136     TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,template);
   1137 
   1138     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
   1139     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1140 
   1141     /* make the call */
   1142     result = _shr_template_managements_mgrs[mngr_type].free(unit,
   1143                                                             thisPool,
   1144                                                             template,
   1145                                                             is_last);
   1146 
   1147     if (BCM_E_NONE == result) {
   1148         /* account for successful deallocation */
   1149         result = shr_mtmemplate_type_change_count(unit, template_type, -1);
   1150         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1151     }
   1152 
   1153     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1154               (BSL_META("(%d, %d, %d, %d) return %d (%s)\n"),
   1155                unit,
   1156                template_type,
   1157                template,
   1158                *is_last,
   1159                result,
   1160                _SHR_ERRMSG(result)));
   1161     return result;
   1162 }
   1163 
   1164 
   1165 /* Free template (if needed) and decrement reference of the given resource */
   1166 static int
   1167 shr_mtemplate_free_group(int unit, 
   1168                int template_type,
   1169                int template,
   1170                int nof_deductions,
   1171                int *is_last)
   1172 {
   1173     shr_template_manage_t mngr_type;
   1174     int thisPool;
   1175     int result = BCM_E_NONE;
   1176 
   1177     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1178               (BSL_META("(%d, %d, %d) enter\n"),
   1179                unit,
   1180                template_type,
   1181                template));
   1182                
   1183 
   1184     /* a little parameter checking */
   1185     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   1186     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   1187 
   1188     TEMPLATE_PARAM_NULL_CHECK(unit,is_last);
   1189     
   1190     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
   1191     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1192 
   1193     /* verify template id from pool information */
   1194     TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,template);
   1195     
   1196     /* make the call */
   1197     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
   1198     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1199     result = _shr_template_managements_mgrs[mngr_type].free_group(unit,
   1200                                                                 thisPool,
   1201                                                                 template,
   1202                                                                 nof_deductions,
   1203                                                                 is_last);
   1204 
   1205     if (BCM_E_NONE == result) {
   1206         /* account for successful deallocation */
   1207         result = shr_mtmemplate_type_change_count(unit, template_type, -nof_deductions);
   1208         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1209     }
   1210 
   1211     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1212               (BSL_META("(%d, %d, %d, %d) return %d (%s)\n"),
   1213                unit,
   1214                template_type,
   1215                template,
   1216                *is_last,
   1217                result,
   1218                _SHR_ERRMSG(result)));
   1219     return result;
   1220 }
   1221 
   1222 static int
   1223 shr_mtemplate_exchange(int unit, 
   1224                       int template_type,
   1225                       uint32 flags,
   1226                       const void *data,
   1227                       int old_template,
   1228                       int *is_last,
   1229                       int *template,
   1230                       int *is_allocated)
   1231 {
   1232     shr_template_manage_t mngr_type;
   1233     int thisPool;
   1234     int result = BCM_E_NONE;
   1235     uint32 valid_flags = SHR_TEMPLATE_MANAGE_SINGLE_FLAGS | SHR_TEMPLATE_MANAGE_SET_WITH_ID | SHR_TEMPLATE_MANAGE_IGNORE_DATA;
   1236 
   1237     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1238               (BSL_META("(%d, %d, %08X, %d) enter\n"),
   1239                unit,
   1240                template_type,
   1241                flags,
   1242                old_template));
   1243                
   1244 
   1245     /* a little parameter checking */
   1246     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   1247     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   1248     
   1249     TEMPLATE_PARAM_NULL_CHECK(unit,data);
   1250     TEMPLATE_PARAM_NULL_CHECK(unit,is_last);
   1251     TEMPLATE_PARAM_NULL_CHECK(unit,is_allocated);
   1252     TEMPLATE_PARAM_NULL_CHECK(unit,template);
   1253 
   1254     if (flags & ~valid_flags) {
   1255         LOG_ERROR(BSL_LS_SOC_COMMON,
   1256                   (BSL_META("invalid flags %08X\n"),
   1257                    flags & ~valid_flags));
   1258         return BCM_E_PARAM;
   1259     }
   1260 
   1261     if ((flags & SHR_TEMPLATE_MANAGE_IGNORE_DATA) && !(flags & SHR_TEMPLATE_MANAGE_SET_WITH_ID)) {
   1262         LOG_ERROR(BSL_LS_SOC_COMMON,
   1263                   (BSL_META("SHR_TEMPLATE_MANAGE_IGNORE_DATA is only valid in combination with SHR_TEMPLATE_MANAGE_SET_WITH_ID\n")));
   1264         return BCM_E_PARAM;
   1265     }
   1266     
   1267     /* get the pool information */
   1268     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
   1269     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1270 
   1271 
   1272     /* verify template id from pool information */
   1273     TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,old_template);
   1274     /* make the call */
   1275     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
   1276     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1277     result = _shr_template_managements_mgrs[mngr_type].exchange(unit,
   1278                                                                 thisPool,
   1279                                                                  flags,
   1280                                                                  data,
   1281                                                                  old_template,
   1282                                                                  is_last,
   1283                                                                  template,
   1284                                                                  is_allocated);
   1285 
   1286     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1287               (BSL_META("(%d, %d, %08X, %d, %d) return %d (%s)\n"),
   1288                unit,
   1289                template_type,
   1290                flags,
   1291                old_template,
   1292                *is_last,
   1293                result,
   1294                _SHR_ERRMSG(result)));
   1295 
   1296     return result;
   1297 }
   1298 
   1299 static int
   1300 shr_mtemplate_exchange_test(int unit, 
   1301                       int template_type,
   1302                       uint32 flags,
   1303                       const void *data,
   1304                       int old_template,
   1305                       int *is_last,
   1306                       int *template,
   1307                       int *is_allocated)
   1308 {
   1309     shr_template_manage_t mngr_type;
   1310     int thisPool;
   1311     int result = BCM_E_NONE;
   1312 
   1313     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1314               (BSL_META("(%d, %d, %08X, %d) enter\n"),
   1315                unit,
   1316                template_type,
   1317                flags,
   1318                old_template));
   1319                
   1320 
   1321     /* a little parameter checking */
   1322     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   1323     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   1324     
   1325     TEMPLATE_PARAM_NULL_CHECK(unit,data);
   1326     TEMPLATE_PARAM_NULL_CHECK(unit,is_last);
   1327     TEMPLATE_PARAM_NULL_CHECK(unit,is_allocated);
   1328     TEMPLATE_PARAM_NULL_CHECK(unit,template);
   1329 
   1330     if (flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS)) {
   1331         LOG_ERROR(BSL_LS_SOC_COMMON,
   1332                   (BSL_META("invalid flags %08X\n"),
   1333                    flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS)));
   1334         return BCM_E_PARAM;
   1335     }
   1336     
   1337     /* get the pool information */
   1338     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
   1339     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1340 
   1341 
   1342     /* verify template id from pool information */
   1343     TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,old_template);
   1344     /* make the call */
   1345     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
   1346     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1347     result = _shr_template_managements_mgrs[mngr_type].exchange_test(unit,
   1348                                                                      thisPool,
   1349                                                                      flags,
   1350                                                                      data,
   1351                                                                      old_template,
   1352                                                                      is_last,
   1353                                                                      template,
   1354                                                                      is_allocated);
   1355 
   1356     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1357               (BSL_META("(%d, %d, %08X, %d, %d) return %d (%s)\n"),
   1358                unit,
   1359                template_type,
   1360                flags,
   1361                old_template,
   1362                *is_last,
   1363                result,
   1364                _SHR_ERRMSG(result)));
   1365 
   1366     return result;
   1367 }
   1368 
   1369 static int
   1370 shr_mtemplate_data_get(int unit, 
   1371                       int template_type,
   1372                       int template,
   1373                       void *data)
   1374 {
   1375     shr_template_manage_t mngr_type;
   1376     int thisPool;
   1377     int result = BCM_E_NONE;
   1378 
   1379     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1380               (BSL_META("(%d, %d, %d) enter\n"),
   1381                unit,
   1382                template_type,
   1383                template));
   1384                
   1385 
   1386     /* a little parameter checking */
   1387     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   1388     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   1389     
   1390     TEMPLATE_PARAM_NULL_CHECK(unit,data);
   1391     /* get the pool information */
   1392     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
   1393     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1394 
   1395 
   1396     /* verify template id from pool information */
   1397     TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,template);
   1398 
   1399     /* make the call */
   1400     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
   1401     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1402     result = _shr_template_managements_mgrs[mngr_type].data_get(unit,
   1403                                                                 thisPool,
   1404                                                                 template,
   1405                                                                 data);
   1406 
   1407     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1408               (BSL_META("(%d, %d, %d) return %d (%s)\n"),
   1409                unit,
   1410                template_type,
   1411                template,
   1412                result,
   1413                _SHR_ERRMSG(result)));
   1414 
   1415     return result;
   1416 }
   1417 
   1418 static int
   1419 shr_mtemplate_index_get(int unit, 
   1420                       int template_type,
   1421                       const void *data, 
   1422                       int *template)
   1423 {
   1424     shr_template_manage_t mngr_type;
   1425     int thisPool;
   1426     int result = BCM_E_NONE;
   1427 
   1428     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1429               (BSL_META("(%d, %d) enter\n"),
   1430                unit,
   1431                template_type));
   1432 
   1433 
   1434     /* a little parameter checking */
   1435     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   1436     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   1437 
   1438     TEMPLATE_PARAM_NULL_CHECK(unit,data);
   1439     /* get the pool information */
   1440     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
   1441     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1442 
   1443     /* make the call */
   1444     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
   1445     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1446     result = _shr_template_managements_mgrs[mngr_type].index_get(unit,
   1447                                                                  thisPool,
   1448                                                                  data,
   1449                                                                  template);
   1450 
   1451     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1452               (BSL_META("(%d, %d, %d) return %d (%s)\n"),
   1453                unit,
   1454                template_type,
   1455                *template,
   1456                result,
   1457                _SHR_ERRMSG(result)));
   1458 
   1459     return result;
   1460 }
   1461 
   1462 
   1463 static int
   1464 shr_mtemplate_ref_count_get(int unit, 
   1465                             int template_type,
   1466                             int template,
   1467                             uint32 *ref_count)
   1468 {
   1469     shr_template_manage_t mngr_type;
   1470     int thisPool;
   1471     int result = BCM_E_NONE;
   1472 
   1473     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1474               (BSL_META("(%d, %d, %d) enter\n"),
   1475                unit,
   1476                template_type,
   1477                template));
   1478                
   1479 
   1480     /* a little parameter checking */
   1481     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   1482     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   1483     
   1484     TEMPLATE_PARAM_NULL_CHECK(unit,ref_count);
   1485 
   1486     /* get the pool information */
   1487     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
   1488     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1489 
   1490     /* verify template id from pool information */
   1491     TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,template);
   1492     /* make the call */
   1493     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
   1494     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1495     result = _shr_template_managements_mgrs[mngr_type].ref_count_get(unit, 
   1496                                                                      thisPool,
   1497                                                                      template,
   1498                                                                      ref_count);
   1499 
   1500     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1501               (BSL_META("(%d, %d, %d) return %d (%s)\n"),
   1502                unit,
   1503                template_type,
   1504                template,
   1505                result,
   1506                _SHR_ERRMSG(result)));
   1507 
   1508     return result;
   1509 }
   1510 
   1511 static int
   1512 shr_mtemplate_create(int unit, 
   1513                 int num_template_types,
   1514                 int num_template_pools,
   1515                 shr_template_to_stream_t *to_stream_cb_arr,
   1516                 shr_template_from_stream_t *from_stream_cb_arr,
   1517                 int cb_arr_length)
   1518 {
   1519     int result = BCM_E_NONE;
   1520 
   1521     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1522               (BSL_META("(%d, %d, %d) enter\n"),
   1523                unit,
   1524                num_template_types,
   1525                num_template_pools));
   1526 
   1527     /* a little parameter checking */
   1528     if (1 > num_template_pools) {
   1529         LOG_ERROR(BSL_LS_SOC_COMMON,
   1530                   (BSL_META("resource pools %d; must be > 0\n"),
   1531                    num_template_pools));
   1532         result =  BCM_E_PARAM;
   1533     }
   1534     if (1 > num_template_types) {
   1535         LOG_ERROR(BSL_LS_SOC_COMMON,
   1536                   (BSL_META("resource types %d; must be > 0\n"),
   1537                    num_template_types));
   1538         result =  BCM_E_PARAM;
   1539     }
   1540     if (BCM_E_NONE != result) {
   1541         /* displayed diagnostics above */
   1542         return result;
   1543     }
   1544     /* set things up */
   1545 
   1546     if (cb_arr_length > 0) {
   1547         /*
   1548          * Allocate and copy the callback arrays. We can this on warmboot because callbacks are static and don't change between runs.
   1549          */
   1550         if (!hash_compare_to_stream_cb[unit]) {
   1551             hash_compare_to_stream_cb[unit] = to_stream_cb_arr;
   1552         }
   1553 
   1554         if (!hash_compare_from_stream_cb[unit]) {
   1555             hash_compare_from_stream_cb[unit] = from_stream_cb_arr;
   1556         }
   1557     }
   1558 
   1559 
   1560     if (!SOC_WARM_BOOT(unit)) {
   1561         result = TEMPLATE_ACCESS.alloc(unit);
   1562         SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 
   1563 
   1564         result = TEMPLATE_ACCESS.pool.ptr_alloc(unit, num_template_pools);
   1565         SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 
   1566 
   1567         result = TEMPLATE_ACCESS.template_param.ptr_alloc(unit, num_template_types);
   1568         SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 
   1569 
   1570         result = TEMPLATE_ACCESS.templateTypeCount.set(unit, num_template_types);
   1571         SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 
   1572 
   1573         result = TEMPLATE_ACCESS.templatePoolCount.set(unit, num_template_pools);
   1574         SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 
   1575     }
   1576 err:
   1577     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1578               (BSL_META("(%d, %d, %d) return %d (%s)\n"),
   1579                unit,
   1580                num_template_types,
   1581                num_template_pools,
   1582                result,
   1583                _SHR_ERRMSG(result)));
   1584     return result;
   1585 }
   1586 
   1587 
   1588 static int
   1589 shr_mtemplate_get(int unit, 
   1590                  int *num_template_types,
   1591                  int *num_template_pools)
   1592 {
   1593     uint16 tmp;
   1594     int result = BCM_E_NONE;
   1595 
   1596     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1597               (BSL_META("(%d, %p, %p) enter\n"),
   1598                unit,
   1599                num_template_types,
   1600                num_template_pools));
   1601 
   1602     /* a little parameter checking */
   1603     /* return the requested information */
   1604     if (num_template_pools) {
   1605         result = TEMPLATE_ACCESS.templatePoolCount.get(unit, &tmp);
   1606         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1607         *num_template_pools = tmp;
   1608     }
   1609     if (num_template_types) {
   1610         result = TEMPLATE_ACCESS.templateTypeCount.get(unit, &tmp);
   1611         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1612         *num_template_types = tmp;
   1613     }
   1614 
   1615     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1616               (BSL_META("(%d, &(%d), &(%d)) return %d (%s)\n"),
   1617                unit,
   1618                num_template_types?*num_template_types:-1,
   1619                num_template_pools?*num_template_pools:-1,
   1620                result,
   1621                _SHR_ERRMSG(result)));
   1622     return result;
   1623 }
   1624 
   1625 static int
   1626 shr_mtemplate_pool_set(int unit, 
   1627                  int pool_id,
   1628                  shr_template_manage_t manager,
   1629                  int template_low_id,
   1630                  int template_count,
   1631                  int max_entities,
   1632                  uint32 global_max,
   1633                  size_t data_size,
   1634                  const void *extras,
   1635                  const char *name)
   1636 {
   1637     int result = BCM_E_NONE;
   1638     uint8 exists;
   1639     const char *noname = "???";
   1640     sw_state_template_name_t name_handle;
   1641     int name_len;
   1642 
   1643     sal_memset(&name_handle, 0, sizeof(name_handle));
   1644 
   1645     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1646               (BSL_META("(%d, %d, %s, %d, %d, %d, %d, %p, \"%s\") enter\n"),
   1647                unit,
   1648                pool_id,
   1649                ((0 <= manager) && (SHR_TEMPLATE_MANAGE_COUNT > manager))?_shr_template_managements_mgrs[manager].name:"INVALID",
   1650                template_low_id,
   1651                template_count,
   1652                max_entities,
   1653                (int)data_size,
   1654                extras,
   1655                name?name:noname));
   1656 
   1657     /* a little parameter checking */
   1658     if (SOC_WARM_BOOT(unit)) {
   1659         LOG_ERROR(BSL_LS_SOC_COMMON,
   1660                   (BSL_META("Can't create templates during init\n")));
   1661         return _SHR_E_DISABLED;
   1662     }
   1663     TEMPLATE_POOL_VALID_CHECK(unit,pool_id);
   1664     if ((0 > manager) || (SHR_TEMPLATE_MANAGE_COUNT <= manager)) {
   1665         LOG_ERROR(BSL_LS_SOC_COMMON,
   1666                   (BSL_META("template manager type %d not supported\n"),
   1667                    manager));
   1668         return BCM_E_PARAM;
   1669     }
   1670     if (0 >= data_size) {
   1671         LOG_ERROR(BSL_LS_SOC_COMMON,
   1672                   (BSL_META("data size must be positive\n")));
   1673         return BCM_E_PARAM;
   1674     }
   1675     if (0 >= max_entities) {
   1676         LOG_ERROR(BSL_LS_SOC_COMMON,
   1677                   (BSL_META("maximum entities must be positive\n")));
   1678         return BCM_E_PARAM;
   1679     }
   1680     if (0 > template_low_id) {
   1681         LOG_ERROR(BSL_LS_SOC_COMMON,
   1682                   (BSL_META("template low id cant be negative \n")));
   1683         return BCM_E_PARAM;
   1684     }
   1685     if (0 >= template_count) {
   1686         LOG_ERROR(BSL_LS_SOC_COMMON,
   1687                   (BSL_META("template count must be positive \n")));
   1688         return BCM_E_PARAM;
   1689     }
   1690     name_len = name ? sal_strlen(name) : 0;
   1691     if (name_len>= SW_STATE_TEMPLATE_NAME_MAX_LENGTH) {
   1692         LOG_ERROR(BSL_LS_SOC_COMMON,
   1693                   (BSL_META("Name string \"%s\" too long. Must be shorter than %d "
   1694                             "(including terminal \\0)\n"),
   1695                    name,
   1696                    SW_STATE_RES_NAME_MAX_LENGTH));
   1697         return _SHR_E_PARAM;
   1698     }
   1699 
   1700 
   1701     TEMPLATE_PARAM_NULL_CHECK(unit,extras);
   1702 
   1703     result = TEMPLATE_ACCESS.pool.is_allocated(unit, pool_id, &exists);
   1704     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1705 
   1706     if (exists) {
   1707         LOG_ERROR(BSL_LS_SOC_COMMON,
   1708                   (BSL_META("%d pool %d already exists. "
   1709                             "Please free it before reallocating.\n"),
   1710                    unit,
   1711                    pool_id));
   1712         return BCM_E_CONFIG;
   1713     } else {
   1714         /* Allocate the pool. */
   1715         result = TEMPLATE_ACCESS.pool.alloc(unit, pool_id);
   1716         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1717     }
   1718     
   1719     /* create the new pool */
   1720     result = _shr_template_managements_mgrs[manager].create(unit,
   1721                                                          pool_id,
   1722                                                          template_low_id,
   1723                                                          template_count,
   1724                                                          max_entities,
   1725                                                          global_max,
   1726                                                          data_size,
   1727                                                          extras,
   1728                                                          name?name:noname);
   1729     if (BCM_E_NONE == result) {
   1730         /* New one created successfully. Fill the information.  */
   1731         result = TEMPLATE_ACCESS.pool.templateManagerType.set(unit, pool_id, manager);
   1732         SW_STATE_ACCESS_ERROR_CHECK(result);
   1733 
   1734         result = TEMPLATE_ACCESS.pool.template_low_id.set(unit, pool_id, template_low_id);
   1735         SW_STATE_ACCESS_ERROR_CHECK(result);
   1736 
   1737         result = TEMPLATE_ACCESS.pool.template_count.set(unit, pool_id, template_count);
   1738         SW_STATE_ACCESS_ERROR_CHECK(result);
   1739 
   1740         result = TEMPLATE_ACCESS.pool.max_entities.set(unit, pool_id, max_entities);
   1741         SW_STATE_ACCESS_ERROR_CHECK(result);
   1742 
   1743         result = TEMPLATE_ACCESS.pool.data_size.set(unit, pool_id, data_size);
   1744         SW_STATE_ACCESS_ERROR_CHECK(result);
   1745 
   1746         sal_memcpy(name_handle.name, name?name:noname, sal_strlen(name?name:noname) + 1);
   1747 
   1748         result = TEMPLATE_ACCESS.pool.name.set(unit, pool_id, &name_handle);
   1749         SW_STATE_ACCESS_ERROR_CHECK(result);
   1750 
   1751     } /* if (BCM_E_NONE == result) */
   1752 
   1753     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1754               (BSL_META("(%d, %d, %s, %d, %d, %d, %d, %p, \"%s\") return %d (%s)\n"),
   1755                unit,
   1756                pool_id,
   1757                _shr_template_managements_mgrs[manager].name,
   1758                template_low_id,
   1759                template_count,
   1760                max_entities,
   1761                (int)data_size,
   1762                extras,
   1763                name?name:noname,
   1764                result,
   1765                _SHR_ERRMSG(result)));
   1766 
   1767     return result;
   1768 }
   1769 
   1770 static int
   1771 shr_mtemplate_pool_get(int unit, 
   1772                       int pool_id,
   1773                       shr_template_manage_t *manager,
   1774                       int *template_low_id,
   1775                       int *template_count,
   1776                       int *max_entities,
   1777                       size_t *data_size,
   1778                       shr_template_manage_hash_compare_extras_t *extras,
   1779                       sw_state_template_name_t *name)
   1780 {
   1781     int result;
   1782 
   1783     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1784               (BSL_META("(%d, %d, %p, %p, %p, %p, %p, %p, %p) enter\n"),
   1785                unit,
   1786                pool_id,
   1787                manager,
   1788                template_low_id,
   1789                template_count,
   1790                max_entities,
   1791                data_size,
   1792                extras,
   1793                name));
   1794 
   1795     /* a little parameter checking */
   1796     TEMPLATE_POOL_VALID_CHECK(unit, pool_id);
   1797     TEMPLATE_POOL_EXIST_CHECK(unit, pool_id);
   1798     /* fill in the caller's request */
   1799     if (manager) {
   1800         result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, pool_id, manager);
   1801         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1802     }
   1803     if (template_low_id) {
   1804         result = TEMPLATE_ACCESS.pool.template_low_id.get(unit, pool_id, template_low_id);
   1805         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1806     }
   1807     if (template_count) {
   1808         result = TEMPLATE_ACCESS.pool.template_count.get(unit, pool_id, template_count);
   1809         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1810     }
   1811     if (max_entities) {
   1812         result = TEMPLATE_ACCESS.pool.max_entities.get(unit, pool_id, max_entities);
   1813         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1814     }
   1815     if (data_size) {
   1816         result = TEMPLATE_ACCESS.pool.data_size.get(unit, pool_id, data_size);
   1817         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1818     }
   1819     if (extras) {
   1820         result = TEMPLATE_ACCESS.pool.extras.get(unit, pool_id, extras);
   1821         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1822     }
   1823     if (name) {
   1824         result = TEMPLATE_ACCESS.pool.name.get(unit, pool_id, name);
   1825         SW_STATE_ACCESS_ERROR_CHECK(result); 
   1826     }
   1827 
   1828     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1829               (BSL_META("(%d, %d, &(%s), &(%d), &(%d), &(%d), &(%d), &(%p), &(\"%s\")) return %d (%s)\n"),
   1830                unit,
   1831                pool_id,
   1832                manager?_shr_template_managements_mgrs[*manager].name:"NULL",
   1833                template_low_id?*template_low_id:0,
   1834                template_count?*template_count:0,
   1835                max_entities?*max_entities:0,
   1836                data_size?(int)*data_size:0,
   1837                extras?extras:NULL,
   1838                name?name->name:"NULL",
   1839                BCM_E_NONE,
   1840                _SHR_ERRMSG(BCM_E_NONE)));
   1841     return BCM_E_NONE;
   1842 }
   1843 
   1844 /*
   1845  *  Destroy a resource pool on a unit
   1846  */
   1847 static int
   1848 shr_mtemplate_pool_unset(int unit,
   1849                     int pool_id)
   1850 {
   1851     _shr_template_pool_desc_t oldPool;
   1852     int result = _SHR_E_NONE;
   1853     uint8 exists;
   1854 
   1855     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1856               (BSL_META("(%d, %d) enter\n"),
   1857                unit, pool_id));
   1858 
   1859     /* a little parameter checking */
   1860     TEMPLATE_POOL_VALID_CHECK(unit, pool_id);
   1861 
   1862     result = TEMPLATE_ACCESS.pool.is_allocated(unit, pool_id, &exists);
   1863     SW_STATE_ACCESS_ERROR_CHECK(result);
   1864 
   1865     if (exists) {
   1866 
   1867         result = TEMPLATE_ACCESS.pool.get(unit, pool_id, &oldPool);
   1868         SW_STATE_ACCESS_ERROR_CHECK(result);
   1869 
   1870         if (oldPool.refCount) {
   1871             LOG_ERROR(BSL_LS_SOC_COMMON,
   1872                       (BSL_META("unit %d: pool %d (%s) can not be destroyed because"
   1873                        " it has %d types that use it\n"),
   1874                        unit,
   1875                        pool_id,
   1876                        oldPool.name.name,
   1877                        oldPool.refCount));
   1878             result = _SHR_E_CONFIG;
   1879         } else { /* if (oldPool->refCount) */
   1880             result = _shr_template_managements_mgrs[oldPool.templateManagerType].destroy(unit, pool_id);
   1881             if (_SHR_E_NONE != result) {
   1882                 LOG_ERROR(BSL_LS_SOC_COMMON,
   1883                           (BSL_META("unit %d: unable to destroy old pool %d (%s):"
   1884                            " %d (%s)\n"),
   1885                            unit,
   1886                            pool_id,
   1887                            oldPool.name.name,
   1888                            result,
   1889                            _SHR_ERRMSG(result)));
   1890             } else {
   1891                 result = TEMPLATE_ACCESS.pool.free(unit, pool_id);
   1892                 SW_STATE_ACCESS_ERROR_CHECK(result);
   1893             }/* if (_SHR_E_NONE != result) */
   1894         } /* if (oldPool.refCount) */
   1895     } /* if (exists) */
   1896 
   1897     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1898               (BSL_META("(%d, %d) return %d (%s)\n"),
   1899                unit,
   1900                pool_id,
   1901                result,
   1902                _SHR_ERRMSG(result)));
   1903     return result;
   1904 }
   1905 
   1906 
   1907 static int
   1908 shr_mtemplate_type_set(int unit, 
   1909                       int template_type,
   1910                       int pool_id,
   1911                       const char *name)
   1912 {
   1913     int result = BCM_E_NONE;
   1914     const char *noname = "???";
   1915     int len_name = 0;
   1916     uint8 exists;
   1917     sw_state_template_name_t name_handle;
   1918 
   1919     sal_memset(&name_handle, 0, sizeof(name_handle));
   1920 
   1921     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1922               (BSL_META("(%d, %d, %d, \"%s\") enter\n"),
   1923                unit,
   1924                template_type,
   1925                pool_id,
   1926                name?name:noname));
   1927     if (SOC_WARM_BOOT(unit)) {
   1928         LOG_ERROR(BSL_LS_SOC_COMMON,
   1929                   (BSL_META("Can't create templates during init\n")));
   1930         return _SHR_E_DISABLED;
   1931     }
   1932 
   1933     /* a little parameter checking */
   1934     TEMPLATE_POOL_VALID_CHECK(unit, pool_id);
   1935     TEMPLATE_POOL_EXIST_CHECK(unit, pool_id);
   1936     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   1937 
   1938 
   1939     result = TEMPLATE_ACCESS.template_param.is_allocated(unit, template_type, &exists);
   1940     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1941     if (exists) {
   1942         LOG_ERROR(BSL_LS_SOC_COMMON,
   1943                   (BSL_META("%d template type %d already exists."
   1944                             "Unset it before setting again.\n"),
   1945                    unit,
   1946                    template_type));
   1947         return BCM_E_CONFIG;
   1948     }
   1949     if (!name) {
   1950         /* force a non-NULL name pointer */
   1951         name = noname;
   1952     }
   1953 
   1954     len_name = sal_strlen(name);
   1955     if (len_name>= SW_STATE_TEMPLATE_NAME_MAX_LENGTH) {
   1956         LOG_ERROR(BSL_LS_SOC_COMMON,
   1957                   (BSL_META("Name string \"%s\" too long. Must be shorter than %d "
   1958                             "(including terminal \\0)\n"),
   1959                    name,
   1960                    SW_STATE_RES_NAME_MAX_LENGTH));
   1961         return _SHR_E_PARAM;
   1962     }
   1963 
   1964 
   1965     /* note base type includes one character, so don't need to add NUL here */
   1966     result = TEMPLATE_ACCESS.template_param.alloc(unit, template_type);
   1967     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1968 
   1969     result = TEMPLATE_ACCESS.template_param.templatePoolId.set(unit, template_type, pool_id);
   1970     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1971 
   1972     sal_strncpy(name_handle.name, name, len_name + 1);
   1973 
   1974     result = TEMPLATE_ACCESS.template_param.name.set(unit, template_type, &name_handle);
   1975     SW_STATE_ACCESS_ERROR_CHECK(result); 
   1976 
   1977 
   1978     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1979               (BSL_META("(%d, %d, %d, \"%s\") return %d (%s)\n"),
   1980                unit,
   1981                template_type,
   1982                pool_id,
   1983                name?name:noname,
   1984                result,
   1985                _SHR_ERRMSG(result)));
   1986     return result;
   1987 }
   1988 
   1989 static int
   1990 shr_mtemplate_type_get(int unit, 
   1991                   int template_type,
   1992                   int *pool_id,
   1993                   sw_state_template_name_t *name)
   1994 {
   1995     int result;
   1996 
   1997     LOG_DEBUG(BSL_LS_SOC_COMMON,
   1998               (BSL_META("(%d, %d, %p, %p) enter\n"),
   1999                unit,
   2000                template_type,
   2001                pool_id,
   2002                name));
   2003 
   2004     /* a little parameter checking */
   2005     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   2006     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   2007     /* fill in the caller's request */
   2008     if (pool_id) {
   2009         result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, pool_id);
   2010         SW_STATE_ACCESS_ERROR_CHECK(result); 
   2011     }
   2012     if (name) {
   2013         result = TEMPLATE_ACCESS.template_param.name.get(unit, template_type, name);
   2014         SW_STATE_ACCESS_ERROR_CHECK(result); 
   2015     }
   2016 
   2017     LOG_DEBUG(BSL_LS_SOC_COMMON,
   2018               (BSL_META("(%d, %d, &(%d), &(\"%s\")) return %d (%s)\n"),
   2019                unit,
   2020                template_type,
   2021                pool_id ? *pool_id : 0,
   2022                name ? name->name : "NULL",
   2023                BCM_E_NONE,
   2024                _SHR_ERRMSG(BCM_E_NONE)));
   2025     return BCM_E_NONE;
   2026 }
   2027 
   2028 
   2029 /*
   2030  *  Destroy a resource type on a unit
   2031  */
   2032 static int
   2033 shr_mtemplate_type_unset(int unit,
   2034                     int template_id)
   2035 {
   2036     _shr_template_type_desc_t oldType;
   2037     int result = _SHR_E_NONE;
   2038     uint8 exists;
   2039     int refCount;
   2040 
   2041     LOG_DEBUG(BSL_LS_SOC_COMMON,
   2042               (BSL_META("(%d, %d) enter\n"),
   2043                unit, template_id));
   2044 
   2045     /* a little parameter checking */
   2046     TEMPLATE_TYPE_VALID_CHECK(unit, template_id);
   2047     
   2048     result = TEMPLATE_ACCESS.template_param.is_allocated(unit, template_id, &exists);
   2049     SW_STATE_ACCESS_ERROR_CHECK(result);
   2050     if (exists) {
   2051         result = TEMPLATE_ACCESS.template_param.get(unit, template_id, &oldType);
   2052         SW_STATE_ACCESS_ERROR_CHECK(result);
   2053 
   2054         if (oldType.refCount) {
   2055             LOG_ERROR(BSL_LS_SOC_COMMON,
   2056                       (BSL_META("%d resource %d (%s) can not be destroyed"
   2057                        " because it has %d elements in use\n"),
   2058                        unit,
   2059                        template_id,
   2060                        oldType.name.name,
   2061                        oldType.refCount));
   2062             result = _SHR_E_CONFIG;
   2063         } else {
   2064             result = TEMPLATE_ACCESS.pool.refCount.get(unit, oldType.templatePoolId, &refCount);
   2065             SW_STATE_ACCESS_ERROR_CHECK(result);
   2066 
   2067             refCount--;
   2068 
   2069             result = TEMPLATE_ACCESS.pool.refCount.set(unit, oldType.templatePoolId, refCount);
   2070             SW_STATE_ACCESS_ERROR_CHECK(result);
   2071 
   2072             result = TEMPLATE_ACCESS.template_param.free(unit, template_id);
   2073             SW_STATE_ACCESS_ERROR_CHECK(result);
   2074         }
   2075     } /* if (oldType) */
   2076 
   2077     LOG_DEBUG(BSL_LS_SOC_COMMON,
   2078               (BSL_META("(%d, %d) return %d (%s)\n"),
   2079                unit,
   2080                template_id,
   2081                result,
   2082                _SHR_ERRMSG(result)));
   2083     return result;
   2084 }
   2085 
   2086 
   2087 /*
   2088  *  Destroys all of the resources and then pools for a unit.
   2089  */
   2090 static int
   2091 _shr_mtemplate_destroy_data(int unit)
   2092 {
   2093     int i;
   2094     int result = BCM_E_NONE;
   2095     uint16 templateTypeCount, templatePoolCount;
   2096     uint8 exists;
   2097     _shr_template_type_desc_t type;
   2098     _shr_template_pool_desc_t pool;
   2099     int refCount;
   2100 
   2101     if (!SOC_IS_DETACHING(unit) && !SOC_WARM_BOOT(unit)) {
   2102         result = TEMPLATE_ACCESS.templateTypeCount.get(unit, &templateTypeCount);
   2103         SW_STATE_ACCESS_ERROR_CHECK(result); 
   2104 
   2105         result = TEMPLATE_ACCESS.templatePoolCount.get(unit, &templatePoolCount);
   2106         SW_STATE_ACCESS_ERROR_CHECK(result); 
   2107 
   2108 
   2109         /* destroy resources */
   2110         for (i = 0; i < templateTypeCount; i++) {
   2111             result = TEMPLATE_ACCESS.template_param.is_allocated(unit, i, &exists);
   2112             SW_STATE_ACCESS_ERROR_CHECK(result);
   2113 
   2114             if (exists) {
   2115                 result = TEMPLATE_ACCESS.template_param.get(unit, i, &type);
   2116                 SW_STATE_ACCESS_ERROR_CHECK(result);
   2117                 if (type.refCount) {
   2118                     LOG_WARN(BSL_LS_SOC_COMMON,
   2119                              (BSL_META("unit %d: type %d (%s): still in use (%d)\n"),
   2120                               unit,
   2121                               i,
   2122                               (type.name.name),
   2123                               type.refCount));
   2124                 }
   2125 
   2126                 result = TEMPLATE_ACCESS.pool.refCount.get(unit, type.templatePoolId, &refCount);
   2127                 SW_STATE_ACCESS_ERROR_CHECK(result);
   2128                 
   2129                 refCount--;
   2130 
   2131                 result = TEMPLATE_ACCESS.pool.refCount.set(unit, type.templatePoolId, refCount);
   2132                 SW_STATE_ACCESS_ERROR_CHECK(result);
   2133 
   2134                 result = TEMPLATE_ACCESS.template_param.free(unit, i);
   2135                 SW_STATE_ACCESS_ERROR_CHECK(result);
   2136             }
   2137         } /* for (all resources this unit) */
   2138 
   2139         /* Fress the resources pointer array. */
   2140         result = TEMPLATE_ACCESS.template_param.ptr_free(unit);
   2141         SW_STATE_ACCESS_ERROR_CHECK(result);
   2142 
   2143 
   2144         /* destroy pools */
   2145         for (i = 0;
   2146              (i < templatePoolCount) && (BCM_E_NONE == result);
   2147              i++) {
   2148 
   2149             result = TEMPLATE_ACCESS.pool.is_allocated(unit, i, &exists);
   2150             SW_STATE_ACCESS_ERROR_CHECK(result);
   2151 
   2152             if (exists) {
   2153                 result = TEMPLATE_ACCESS.pool.get(unit, i, &pool);
   2154                 SW_STATE_ACCESS_ERROR_CHECK(result);
   2155 
   2156                 if (pool.refCount) {
   2157                     LOG_WARN(BSL_LS_SOC_COMMON,
   2158                              (BSL_META("unit %d: %d (%s): unexpectedly still"
   2159                               " in use (%d) - invalid condition???\n"),
   2160                               unit,
   2161                               i,
   2162                               (pool.name.name),
   2163                               pool.refCount));
   2164                 }
   2165                 result = _shr_template_managements_mgrs[pool.templateManagerType].destroy(unit, i);
   2166                 if (_SHR_E_NONE != result) {
   2167                     LOG_ERROR(BSL_LS_SOC_COMMON,
   2168                               (BSL_META("unit %d: pool %d (%s): unable to destroy:"
   2169                                " %d (%s)\n"),
   2170                                unit,
   2171                                i,
   2172                                (pool.name.name),
   2173                                result,
   2174                                _SHR_ERRMSG(result)));
   2175                 } /* if (_SHR_E_NONE != result) */
   2176 
   2177                 result = TEMPLATE_ACCESS.pool.free(unit, i);
   2178                 SW_STATE_ACCESS_ERROR_CHECK(result);
   2179 
   2180             } /* if (unitData->pool[i]) */
   2181         } /* for (all pools as long as no errors) */
   2182 
   2183         /* Free the pool resources array. */
   2184         result = TEMPLATE_ACCESS.pool.ptr_free(unit);
   2185         SW_STATE_ACCESS_ERROR_CHECK(result);
   2186     }
   2187     return result;
   2188 }
   2189 
   2190 static int 
   2191 shr_mtemplate_dump(int unit, int template_type)
   2192 {
   2193     _shr_template_pool_desc_t thisPool;
   2194     _shr_template_type_desc_t thisTemplate;
   2195     int index, template, start_index, last_index, buff_counter;
   2196     int result = BCM_E_NONE;
   2197     char buff[SHR_TEMPLATE_MAX_BUFFER_SIZE_FOR_PRINT];
   2198     uint32 ref_count;
   2199     uint16 templateTypeCount, templatePoolCount;
   2200     uint8 exists;
   2201     int template_id, pool_idx;
   2202     
   2203     /* a little parameter checking */
   2204 
   2205     result = TEMPLATE_ACCESS.templateTypeCount.get(unit, &templateTypeCount);
   2206     SW_STATE_ACCESS_ERROR_CHECK(result); 
   2207 
   2208     result = TEMPLATE_ACCESS.templatePoolCount.get(unit, &templatePoolCount);
   2209     SW_STATE_ACCESS_ERROR_CHECK(result); 
   2210 
   2211     if( template_type != -1)
   2212     {
   2213         if (template_type < 0 || template_type > templateTypeCount)
   2214         {
   2215             LOG_CLI((BSL_META("  templateType not exist (%d..%d)\n"), 0, templateTypeCount));
   2216             return BCM_E_PARAM;
   2217         }
   2218         start_index = template_type;
   2219         last_index = template_type + 1;
   2220     }
   2221     else
   2222     {
   2223         /* dump information about the handle */
   2224         LOG_CLI((BSL_META("  template manager (%d)\n"), unit));
   2225         LOG_CLI((BSL_META("  template type count = %d\n"), templateTypeCount));
   2226         LOG_CLI((BSL_META("  template pool count = %d\n"), templatePoolCount));
   2227         start_index = 0;
   2228         last_index = templateTypeCount;
   2229     }
   2230     
   2231     for (index = start_index; index < last_index; index++) {
   2232         result = TEMPLATE_ACCESS.template_param.is_allocated(unit, index, &exists);
   2233         SW_STATE_ACCESS_ERROR_CHECK(result); 
   2234 
   2235         if (exists) {
   2236             result = TEMPLATE_ACCESS.template_param.get(unit, index, &thisTemplate);
   2237             SW_STATE_ACCESS_ERROR_CHECK(result); 
   2238 
   2239             result = TEMPLATE_ACCESS.pool.get(unit, thisTemplate.templatePoolId, &thisPool);
   2240             SW_STATE_ACCESS_ERROR_CHECK(result); 
   2241 
   2242             bcm_dpp_am_pool_id_to_template_id_get(unit, index, &template_id, &pool_idx);
   2243 
   2244             LOG_CLI((BSL_META("  template type %d (%s) in core #%d\n"), index, thisTemplate.name.name, pool_idx));
   2245             LOG_CLI((BSL_META("  first template index = %d nof templates     = %d\n"), thisPool.template_low_id, thisPool.template_count));
   2246             LOG_CLI((BSL_META("  number of elements using this template type = %d\n"), thisTemplate.refCount));
   2247             LOG_CLI((BSL_META("  template data size %d \n"), (int)(thisPool.data_size)));
   2248 
   2249             if(template_type != -1) {
   2250                 for (template = thisPool.template_low_id; template < thisPool.template_low_id + thisPool.template_count; template++) {
   2251                     result = _shr_template_managements_mgrs[thisPool.templateManagerType].ref_count_get(unit, thisTemplate.templatePoolId, template, &ref_count);
   2252                     if (BCM_E_NONE != result) {
   2253                         LOG_CLI((BSL_META("  error retriving ref counter \n")));
   2254                         return BCM_E_FAIL;
   2255                     }
   2256 
   2257                     if (ref_count > 0 && SHR_TEMPLATE_MAX_BUFFER_SIZE_FOR_PRINT >= thisPool.data_size) {
   2258                         result = _shr_template_managements_mgrs[thisPool.templateManagerType].data_get(unit, thisTemplate.templatePoolId, template, buff);
   2259                         if (BCM_E_NONE != result) {
   2260                             LOG_CLI((BSL_META("  error geting data for template ID %d\n"), template));
   2261                         } else{
   2262                             LOG_CLI((BSL_META("  template id = %d ref counter = %d \n"), template, ref_count));
   2263                             if (_bcm_dpp_am_template_print_func[template_id] == NULL ) {
   2264                                 LOG_CLI((BSL_META("  template data (hex): ")));
   2265                                 for (buff_counter = 0; buff_counter < thisPool.data_size; buff_counter++) {
   2266                                     /* %02hhx means print an unsigned char with at least two numbers in hexa. */
   2267                                     LOG_CLI((BSL_META("%02hhx"), buff[buff_counter]));
   2268                                 }
   2269                                 LOG_CLI((BSL_META("\n\n")));
   2270                             } else {
   2271                                 (_bcm_dpp_am_template_print_func[template_id]) (unit, buff);
   2272                             }
   2273                         }
   2274                     }
   2275                 }
   2276             }
   2277         } else {
   2278             LOG_CLI((BSL_META("   template type %d is not in use\n"), index));
   2279         }
   2280         LOG_CLI((BSL_META("\n")));
   2281     }
   2282     return result;
   2283 }
   2284 
   2285 static int 
   2286 shr_mtemplate_clear(int unit, 
   2287                     int template_type)
   2288 {
   2289     shr_template_manage_t mngr_type;
   2290     int thisPool;
   2291     int result = BCM_E_NONE;
   2292 
   2293     LOG_DEBUG(BSL_LS_SOC_COMMON,
   2294               (BSL_META("(%d, %d) enter\n"),
   2295                unit,
   2296                template_type));
   2297                
   2298     /* a little parameter checking */
   2299     TEMPLATE_TYPE_VALID_CHECK(unit, template_type);
   2300     TEMPLATE_TYPE_EXIST_CHECK(unit, template_type);
   2301     
   2302     /* get the pool information */
   2303     result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool);
   2304     SW_STATE_ACCESS_ERROR_CHECK(result); 
   2305 
   2306     result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type);
   2307     SW_STATE_ACCESS_ERROR_CHECK(result); 
   2308 
   2309     /* make the call */
   2310     result = _shr_template_managements_mgrs[mngr_type].clear(unit, thisPool);
   2311 
   2312     LOG_DEBUG(BSL_LS_SOC_COMMON,
   2313               (BSL_META("(%d, %d) return %d (%s)\n"),
   2314                unit,
   2315                template_type,
   2316                result,
   2317                _SHR_ERRMSG(result)));
   2318 
   2319     return result;
   2320 }
   2321 /* ******************************************************************/
   2322 
   2323 /* Hash Utils functions } */
   2324 
   2325 static int _shr_template_hash_create(int unit, 
   2326                                      int pool_id,
   2327                                      int template_low_id,
   2328                                      int template_count,
   2329                                      int max_entities,
   2330                                      uint32 global_max,
   2331                                      size_t data_size,
   2332                                      const void *extras,
   2333                                      const char *name)
   2334 {
   2335     /* need the base descriptor */
   2336     int result = BCM_E_NONE;
   2337     const shr_template_manage_hash_compare_extras_t *info = extras;
   2338     uint32 soc_sand_rv = 0;
   2339     SOC_SAND_MULTI_SET_PTR multi_set_info;
   2340     SOC_SAND_MULTI_SET_INIT_INFO multi_set_init_info;
   2341 
   2342     /* Set the pool's extras. */
   2343     result = TEMPLATE_ACCESS.pool.extras.set(unit, pool_id, *info);
   2344     SW_STATE_ACCESS_ERROR_CHECK(result); 
   2345 
   2346     /* Clear structures */
   2347     
   2348     /* Init hash template */
   2349     soc_sand_os_memset(&multi_set_init_info, 0x0, sizeof(SOC_SAND_MULTI_SET_INIT_INFO));
   2350     multi_set_init_info.get_entry_fun = NULL;
   2351     multi_set_init_info.set_entry_fun = NULL;
   2352     multi_set_init_info.max_duplications = max_entities;
   2353     multi_set_init_info.member_size = data_size;
   2354     multi_set_init_info.nof_members = template_count;
   2355     multi_set_init_info.sec_handle = 0;
   2356     multi_set_init_info.prime_handle = 0;
   2357 
   2358     soc_sand_rv = soc_sand_multi_set_create(
   2359         unit,
   2360         &multi_set_info,
   2361         multi_set_init_info
   2362     );
   2363 
   2364     result = TEMPLATE_ACCESS.pool.templateHandle.set(unit, pool_id, multi_set_info);
   2365     SW_STATE_ACCESS_ERROR_CHECK(result); 
   2366 
   2367     if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2368         /* Init failed */
   2369         return BCM_E_MEMORY;
   2370     }
   2371     
   2372     /* all's well if we got here */
   2373     return result;
   2374 }
   2375 
   2376 static int _shr_template_hash_destroy(int unit, int pool_id)
   2377 {
   2378     int res = BCM_E_NONE;
   2379     uint32 soc_sand_rv;
   2380     SOC_SAND_MULTI_SET_PTR hash_handle;
   2381 
   2382     res = TEMPLATE_ACCESS.pool.templateHandle.get(unit, pool_id, &hash_handle);
   2383     SW_STATE_ACCESS_ERROR_CHECK(res); 
   2384 
   2385     soc_sand_rv = soc_sand_multi_set_destroy(unit, hash_handle);
   2386     SOC_SAND_IF_ERR_RETURN(soc_sand_rv);
   2387 
   2388     return res;
   2389 }
   2390 
   2391 static int _shr_template_hash_alloc(int unit, 
   2392                                     int pool_id,
   2393                                      uint32 flags,
   2394                                      const void* data,
   2395                                      int *is_allocated,
   2396                                      int *template)
   2397 {
   2398     _shr_template_pool_desc_t desc;
   2399     int res = BCM_E_NONE;   
   2400     SOC_SAND_MULTI_SET_KEY * val;
   2401     SOC_SAND_MULTI_SET_PTR hash_handle;
   2402     uint8 add_success;
   2403     shr_template_manage_hash_compare_extras_t extra;
   2404     uint32 soc_sand_rv = SOC_SAND_OK;
   2405     uint8 first_appear;
   2406     int template_alloc = 0;
   2407     shr_template_to_stream_t *hcts_cb = NULL;
   2408 
   2409     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   2410     SW_STATE_ACCESS_ERROR_CHECK(res); 
   2411 
   2412     hash_handle = desc.templateHandle;
   2413     extra = desc.extras;
   2414     
   2415     val = sal_alloc((desc.data_size),"Data buffer");
   2416 
   2417     if (!val) {
   2418         /* alloc failed */
   2419         LOG_ERROR(BSL_LS_SOC_COMMON,
   2420                   (BSL_META("unable to allocate %u bytes for info\n"),
   2421                    (unsigned int)
   2422                    ((desc.data_size))));
   2423         res = BCM_E_MEMORY;
   2424     } else {
   2425         sal_memset(val,0x0,(desc.data_size));
   2426 
   2427         /* move to buffer */
   2428         hcts_cb = hash_compare_to_stream_cb[unit];
   2429         res = hcts_cb[extra](data,val,desc.data_size);
   2430         if (res != BCM_E_NONE) {
   2431             goto exit;
   2432         }
   2433 
   2434         if (flags & SHR_TEMPLATE_MANAGE_SET_WITH_ID) {
   2435             template_alloc = *template - desc.template_low_id;
   2436             soc_sand_rv = soc_sand_multi_set_member_add_at_index(
   2437                         unit,
   2438                         hash_handle,
   2439                         val,
   2440                         template_alloc,
   2441                         &first_appear,
   2442                         &add_success);            
   2443         } else {
   2444            /* Add new data */
   2445             soc_sand_rv = soc_sand_multi_set_member_add(
   2446                         unit,
   2447                         hash_handle,
   2448                         val,
   2449                         (uint32 *)&template_alloc,
   2450                         &first_appear,                        
   2451                         &add_success);
   2452             *template = template_alloc + desc.template_low_id;
   2453         }
   2454    
   2455         *is_allocated = first_appear;
   2456 
   2457         if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2458             res = BCM_E_INTERNAL;
   2459             goto exit;
   2460         }
   2461 
   2462         if (!add_success) {
   2463             res = BCM_E_MEMORY;
   2464             goto exit;
   2465         }
   2466         
   2467     }
   2468 
   2469 exit:
   2470     if (val) {
   2471         sal_free(val);
   2472     }
   2473     
   2474     return res;
   2475 }
   2476 
   2477 static int _shr_template_hash_alloc_group(int unit, 
   2478                                           int pool_id,
   2479                                      uint32 flags,
   2480                                      const void* data,
   2481                                      int nof_additions,
   2482                                      int *is_allocated,
   2483                                      int *template)
   2484 {
   2485     _shr_template_pool_desc_t desc;
   2486     int res = BCM_E_NONE;   
   2487     SOC_SAND_MULTI_SET_KEY * val;
   2488     SOC_SAND_MULTI_SET_PTR hash_handle;
   2489     uint8 add_success;
   2490     shr_template_manage_hash_compare_extras_t extra;
   2491     uint32 soc_sand_rv = SOC_SAND_OK;
   2492     uint8 first_appear;
   2493     int template_alloc = 0;
   2494     shr_template_to_stream_t *hcts_cb = NULL;
   2495 
   2496     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   2497     SW_STATE_ACCESS_ERROR_CHECK(res); 
   2498 
   2499     hash_handle = desc.templateHandle;
   2500     extra = desc.extras;
   2501     
   2502     val = sal_alloc((desc.data_size),"Data buffer");
   2503 
   2504     if (!val) {
   2505         /* alloc failed */
   2506         LOG_ERROR(BSL_LS_SOC_COMMON,
   2507                   (BSL_META("unable to allocate %u bytes for info\n"),
   2508                    (unsigned int)
   2509                    ((desc.data_size))));
   2510         res = BCM_E_MEMORY;
   2511     } else {
   2512         sal_memset(val,0x0,(desc.data_size));
   2513 
   2514         /* move to buffer */
   2515         hcts_cb = hash_compare_to_stream_cb[unit];
   2516         res = hcts_cb[extra](data,val,desc.data_size);
   2517         if (res != BCM_E_NONE) {
   2518             goto exit;
   2519         }
   2520 
   2521         if (flags & SHR_TEMPLATE_MANAGE_SET_WITH_ID) {
   2522             template_alloc = *template - desc.template_low_id;
   2523             soc_sand_rv = soc_sand_multi_set_member_add_at_index_nof_additions(
   2524                         unit,
   2525                         hash_handle,
   2526                         val,
   2527                         template_alloc,
   2528                         nof_additions,
   2529                         &first_appear,
   2530                         &add_success);            
   2531         } else {
   2532              
   2533              res = BCM_E_INTERNAL;
   2534              goto exit;
   2535         }
   2536    
   2537         *is_allocated = first_appear;
   2538 
   2539         if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2540             res = BCM_E_INTERNAL;
   2541             goto exit;
   2542         }
   2543 
   2544         if (!add_success) {
   2545             res = BCM_E_MEMORY;
   2546             goto exit;
   2547         }
   2548         
   2549     }
   2550 
   2551 exit:
   2552     if (val) {
   2553         sal_free(val);
   2554     }
   2555     
   2556     return res;
   2557 }
   2558 
   2559 static int _shr_template_hash_free(int unit, 
   2560                                    int pool_id,
   2561                                     int template,
   2562                                     int *is_last)
   2563 {
   2564     _shr_template_pool_desc_t desc;
   2565     int res = BCM_E_NONE;   
   2566     SOC_SAND_MULTI_SET_PTR hash_handle;
   2567     uint8 last_appear = 0;
   2568     uint32 soc_sand_rv;
   2569     int template_alloc;
   2570 
   2571     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   2572     SW_STATE_ACCESS_ERROR_CHECK(res); 
   2573 
   2574     hash_handle = desc.templateHandle;
   2575     
   2576     /* Remove old template */
   2577     template_alloc = template - desc.template_low_id;
   2578     soc_sand_rv = soc_sand_multi_set_member_remove_by_index(
   2579               unit,
   2580               hash_handle,
   2581               template_alloc,
   2582               &last_appear);
   2583     
   2584     if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2585         res = BCM_E_INTERNAL;
   2586     } else {
   2587         if (last_appear) {
   2588             *is_last = 1;
   2589         } else {
   2590             *is_last = 0;
   2591         }
   2592     }
   2593 
   2594     return res;
   2595 }
   2596 
   2597 static int _shr_template_hash_free_group(int unit, 
   2598                                          int pool_id,
   2599                                         int template,
   2600                                         int nof_deductions,
   2601                                         int *is_last)
   2602 {
   2603     _shr_template_pool_desc_t desc;
   2604     int res = BCM_E_NONE;   
   2605     SOC_SAND_MULTI_SET_PTR hash_handle;
   2606     uint8 last_appear = 0;
   2607     uint32 soc_sand_rv;
   2608     int template_alloc;
   2609 
   2610     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   2611     SW_STATE_ACCESS_ERROR_CHECK(res); 
   2612 
   2613     hash_handle = desc.templateHandle;
   2614     
   2615     /* Remove old template */
   2616     template_alloc = template - desc.template_low_id;
   2617     soc_sand_rv = soc_sand_multi_set_member_remove_by_index_multiple(
   2618               unit,
   2619               hash_handle,
   2620               template_alloc,
   2621               nof_deductions,
   2622               &last_appear);
   2623     
   2624     if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2625         res = BCM_E_INTERNAL;
   2626     } else {
   2627         if (last_appear) {
   2628             *is_last = 1;
   2629         } else {
   2630             *is_last = 0;
   2631         }
   2632     }
   2633 
   2634     return res;
   2635 }
   2636 
   2637 static int _shr_template_hash_exchange(int unit, 
   2638                                        int pool_id,
   2639                                         uint32 flags,
   2640                                         const void *data,
   2641                                         int old_template,
   2642                                         int *is_last,
   2643                                         int *template,
   2644                                         int *is_allocated)
   2645 {
   2646     _shr_template_pool_desc_t desc;
   2647     int res = BCM_E_NONE;   
   2648     SOC_SAND_MULTI_SET_KEY * val;
   2649     SOC_SAND_MULTI_SET_KEY * old_val;
   2650     SOC_SAND_MULTI_SET_PTR hash_handle;
   2651     uint8 add_success;
   2652     uint8 first_appear = 0;
   2653     uint8 last_appear = 0;
   2654     int template_alloc = 0;
   2655     int old_template_alloc;
   2656 
   2657     shr_template_manage_hash_compare_extras_t extra;
   2658     uint32 soc_sand_rv;
   2659     uint32 ref_count_old;
   2660     shr_template_to_stream_t *hcts_cb = NULL;
   2661 
   2662     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   2663     SW_STATE_ACCESS_ERROR_CHECK(res); 
   2664 
   2665     hash_handle = desc.templateHandle;
   2666     extra = desc.extras;
   2667     
   2668     old_template_alloc = old_template - desc.template_low_id;
   2669     
   2670     val = sal_alloc((desc.data_size),"Data buffer");
   2671     old_val = sal_alloc((desc.data_size),"Data buffer old");
   2672     if (!val || !old_val) {
   2673         /* alloc failed */
   2674         LOG_ERROR(BSL_LS_SOC_COMMON,
   2675                   (BSL_META("unable to allocate %u bytes for info\n"),
   2676                    (unsigned int)
   2677                    ((desc.data_size))));
   2678         res = BCM_E_MEMORY;
   2679         goto exit;
   2680     } else {
   2681         sal_memset(val,0x0,(desc.data_size));
   2682 
   2683         /* move to buffer */
   2684         hcts_cb = hash_compare_to_stream_cb[unit];
   2685         res = hcts_cb[extra](data,val,(desc.data_size));
   2686         if (res != BCM_E_NONE) {
   2687             goto exit;
   2688         }
   2689 
   2690         /* Save old data in case of failure */
   2691         soc_sand_rv = soc_sand_multi_set_get_by_index(
   2692                       unit,
   2693                       hash_handle,
   2694                       old_template_alloc,
   2695                       old_val,
   2696                       &ref_count_old);
   2697         if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2698             /* Get old data failed */
   2699             res = BCM_E_INTERNAL;
   2700             goto exit;
   2701         }
   2702 
   2703         if (ref_count_old == 0 && !(flags & SHR_TEMPLATE_MANAGE_IGNORE_NOT_EXIST_OLD_TEMPLATE)) {
   2704             /* User gave old template that was empty */
   2705             res = BCM_E_PARAM;
   2706             goto exit;
   2707         }
   2708                       
   2709         if (ref_count_old != 0) {
   2710             /* Remove old template */
   2711             soc_sand_rv = soc_sand_multi_set_member_remove_by_index(
   2712                           unit,
   2713                           hash_handle,
   2714                           old_template_alloc,
   2715                           &last_appear);
   2716                           
   2717             *is_last = last_appear;
   2718             if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2719                 /* Remove failed */
   2720                 res = BCM_E_INTERNAL;
   2721                 goto exit;
   2722             }
   2723         }
   2724         
   2725         /* WITH_ID means that the user would like to exchange the current template for a specific new template */
   2726         /* (as opposed to changing the template to any new template containing the supplied data). */
   2727         /* If IGNORE_DATA is not specified, then the user would also like to change the value of the new template. */
   2728         if (flags & SHR_TEMPLATE_MANAGE_SET_WITH_ID) {
   2729             uint32 new_template = (uint32) *template - desc.template_low_id;
   2730             uint32 old_data_ref_count;
   2731 
   2732             if (!(flags & SHR_TEMPLATE_MANAGE_IGNORE_DATA)) {
   2733                 uint32 new_data_ref_count;
   2734                 uint32 old_template_of_new_data;
   2735 
   2736                 /* Make sure that the new data does not exist already for another index. */
   2737                 /* This check is actually made inside the insert by index as well. */
   2738                 /* However no distinguishable error is returned for it. */
   2739                 soc_sand_rv = soc_sand_multi_set_member_lookup(
   2740                               unit,
   2741                               hash_handle,
   2742                               val,
   2743                               &old_template_of_new_data,
   2744                               &new_data_ref_count);
   2745                 if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2746                     /* Get data failed */
   2747                     res = BCM_E_INTERNAL;
   2748                     goto exit;
   2749                 }
   2750 
   2751                 if ((old_template_of_new_data != new_template) && (new_data_ref_count > 0)) {
   2752                     res = BCM_E_EXISTS;
   2753                     goto exit;
   2754                 }
   2755 
   2756             }
   2757 
   2758             /* Get the current data at index (and the ref count to it) and put it into the buffer (val). */
   2759             soc_sand_rv = soc_sand_multi_set_get_by_index(
   2760                           unit,
   2761                           hash_handle,
   2762                           new_template,
   2763                           val,
   2764                           &old_data_ref_count);
   2765             if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2766                 /* Get data failed */
   2767                 res = BCM_E_INTERNAL;
   2768                 goto exit;
   2769             }
   2770 
   2771             if ((flags & SHR_TEMPLATE_MANAGE_IGNORE_DATA) && (old_data_ref_count == 0)) {
   2772                 /* WITH_ID and IGNORE_DATA are invalid if the template does not exist - because we don't know where to get */
   2773                 /* the new value from. */
   2774                 res = BCM_E_NOT_FOUND;
   2775                 goto exit;
   2776             }
   2777             
   2778             /* If we ignore the data or we have a new template, then we need not change the existing template value. */
   2779             if ((flags & SHR_TEMPLATE_MANAGE_IGNORE_DATA) || (old_data_ref_count == 0)) {
   2780                 /* Add data by index. */
   2781                 soc_sand_rv = soc_sand_multi_set_member_add_at_index(
   2782                         unit,
   2783                         hash_handle,
   2784                         val,
   2785                         new_template,
   2786                         &first_appear,
   2787                         &add_success
   2788                 );  
   2789             } else /* We need to change the current template value. */ {
   2790                 uint8 last_appear;
   2791 
   2792                 /* Free all members using the old data. */
   2793                 soc_sand_rv = soc_sand_multi_set_member_remove_by_index_multiple(
   2794                               unit,
   2795                               hash_handle,
   2796                               new_template,
   2797                               old_data_ref_count,
   2798                               &last_appear);
   2799                 if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2800                     /* Get data failed */
   2801                     res = BCM_E_INTERNAL;
   2802                     goto exit;
   2803                 }
   2804 
   2805                 /* VERIFY(data_template == new_template); */
   2806                 /* VERIFY(last_appear); */
   2807 
   2808                 /* Move the new data to the buffer. */
   2809                 hcts_cb = hash_compare_to_stream_cb[unit];
   2810                 res = hcts_cb[extra](data,val,(desc.data_size));
   2811                 if (res != BCM_E_NONE) {
   2812                     goto exit;
   2813                 }
   2814 
   2815                 /* Add ref_count + 1 members using the new data at the required index. */
   2816                 soc_sand_rv = soc_sand_multi_set_member_add_at_index_nof_additions(
   2817                           unit,
   2818                           hash_handle,
   2819                           val,
   2820                           new_template,
   2821                           old_data_ref_count + 1,
   2822                           &first_appear,
   2823                           &add_success
   2824                 );  
   2825 
   2826             }
   2827         } else /* if (!WITH_ID) */ {
   2828             /* Add new data. */
   2829             soc_sand_rv = soc_sand_multi_set_member_add(
   2830                     unit,
   2831                     hash_handle,
   2832                     val,
   2833                     (uint32 *)&template_alloc,
   2834                     &first_appear,
   2835                     &add_success
   2836             );
   2837 
   2838             *template = template_alloc + desc.template_low_id;
   2839         }
   2840 
   2841         *is_allocated = first_appear;
   2842    
   2843         if (SOC_SAND_FAILURE(soc_sand_rv) || !add_success) {
   2844             /* Add new failed, return old data */
   2845             if (!add_success) {
   2846                 res = BCM_E_MEMORY;
   2847             } else {
   2848                 /* General error */
   2849                 res = BCM_E_INTERNAL;
   2850             }
   2851             
   2852             if (ref_count_old != 0) {
   2853             
   2854                 soc_sand_rv = soc_sand_multi_set_member_add_at_index(
   2855                      unit,
   2856                      hash_handle,
   2857                      old_val,
   2858                      old_template_alloc,                 
   2859                      &first_appear,
   2860                      &add_success);
   2861                 
   2862                 if (SOC_SAND_FAILURE(soc_sand_rv) || !add_success) {
   2863                     /* Internal error */
   2864                     res = BCM_E_INTERNAL;
   2865                 }
   2866             }
   2867             
   2868             goto exit;
   2869         }
   2870 
   2871     }
   2872 
   2873 exit:
   2874     if (val) {
   2875         sal_free(val);
   2876     }
   2877     if (old_val) {
   2878         sal_free(old_val);
   2879     }
   2880     
   2881 
   2882     return res;
   2883 }
   2884 
   2885 static int _shr_template_hash_exchange_test(int unit, 
   2886                                             int pool_id,
   2887                                             uint32 flags,
   2888                                             const void *data,
   2889                                             int old_template,
   2890                                             int *is_last,
   2891                                             int *template,
   2892                                             int *is_allocated)
   2893 {
   2894     _shr_template_pool_desc_t desc;
   2895     int res = BCM_E_NONE;   
   2896     SOC_SAND_MULTI_SET_KEY * val;
   2897     SOC_SAND_MULTI_SET_KEY * old_val;
   2898     SOC_SAND_MULTI_SET_PTR hash_handle;
   2899     uint8 add_success;
   2900     uint8 first_appear = 0;
   2901     uint8 last_appear = 0;
   2902     int old_template_alloc = 0;
   2903     int new_template_alloc = 0;
   2904 
   2905     shr_template_manage_hash_compare_extras_t extra;
   2906     uint32 soc_sand_rv;
   2907     uint32 ref_count_old;
   2908     shr_template_to_stream_t *hcts_cb = NULL;
   2909 
   2910     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   2911     SW_STATE_ACCESS_ERROR_CHECK(res); 
   2912 
   2913     hash_handle = desc.templateHandle;
   2914     extra = desc.extras;
   2915 
   2916     old_template_alloc = old_template - desc.template_low_id;
   2917     
   2918     val = sal_alloc((desc.data_size),"Data buffer");
   2919     old_val = sal_alloc((desc.data_size),"Data buffer old");
   2920     if (!val || !old_val) {
   2921         /* alloc failed */
   2922         LOG_ERROR(BSL_LS_SOC_COMMON,
   2923                   (BSL_META("unable to allocate %u bytes for info\n"),
   2924                    (unsigned int)
   2925                    ((desc.data_size))));
   2926         res = BCM_E_MEMORY;
   2927         goto exit;
   2928     } else {
   2929         sal_memset(val,0x0,(desc.data_size));
   2930              
   2931         /* move to buffer */
   2932         hcts_cb = hash_compare_to_stream_cb[unit];
   2933         res = hcts_cb[extra](data,val,(desc.data_size));
   2934         if (res != BCM_E_NONE) {
   2935             goto exit;
   2936         }
   2937 
   2938         /* Save old data in case of failure */
   2939         soc_sand_rv = soc_sand_multi_set_get_by_index(
   2940                       unit,
   2941                       hash_handle,
   2942                       old_template_alloc,
   2943                       old_val,
   2944                       &ref_count_old);
   2945         if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2946             /* Get old data failed */
   2947             res = BCM_E_INTERNAL;
   2948             goto exit;
   2949         }
   2950 
   2951         if (ref_count_old == 0 && !(flags & SHR_TEMPLATE_MANAGE_IGNORE_NOT_EXIST_OLD_TEMPLATE)) {
   2952             /* User gave old template that was empty */
   2953             res = BCM_E_PARAM;
   2954             goto exit;
   2955         }
   2956                       
   2957         if (ref_count_old != 0) {    
   2958             soc_sand_rv = soc_sand_multi_set_member_remove_by_index(
   2959                           unit,
   2960                           hash_handle,
   2961                           old_template_alloc,
   2962                           &last_appear);
   2963 
   2964             *is_last = last_appear;
   2965             
   2966             if (SOC_SAND_FAILURE(soc_sand_rv)) {
   2967                 res = BCM_E_INTERNAL;
   2968                 goto exit;
   2969             }
   2970         }
   2971 
   2972         /* Add new data */
   2973         soc_sand_rv = soc_sand_multi_set_member_add(
   2974                 unit,
   2975                 hash_handle,
   2976                 val,
   2977                 (uint32 *)&new_template_alloc,
   2978                 &first_appear,
   2979                 &add_success
   2980         );
   2981         *template = new_template_alloc + desc.template_low_id;
   2982 
   2983         *is_allocated = first_appear;
   2984    
   2985         if (SOC_SAND_FAILURE(soc_sand_rv) || !add_success) {
   2986             if (!add_success) {
   2987                 res = BCM_E_MEMORY;
   2988             } else {
   2989                 /* General error */
   2990                 res = BCM_E_INTERNAL;
   2991             }
   2992         }
   2993         else {
   2994             /* Remove new data */
   2995             soc_sand_rv = soc_sand_multi_set_member_remove_by_index(
   2996                           unit,
   2997                           hash_handle,
   2998                           new_template_alloc,
   2999                           &last_appear);
   3000             if (SOC_SAND_FAILURE(soc_sand_rv)) {
   3001                 LOG_ERROR(BSL_LS_SOC_COMMON,
   3002                       (BSL_META("Failed to release new allocated data.\n")));
   3003                 res = BCM_E_INTERNAL;
   3004                 goto exit;                   
   3005             }        
   3006         }
   3007 
   3008         if (ref_count_old != 0) {
   3009             soc_sand_rv = soc_sand_multi_set_member_add_at_index(
   3010                  unit,
   3011                  hash_handle,
   3012                  old_val,
   3013                  old_template_alloc,
   3014                  &first_appear,
   3015                  &add_success);
   3016              
   3017             if (SOC_SAND_FAILURE(soc_sand_rv)) {
   3018                 res = BCM_E_INTERNAL;
   3019                 goto exit;                   
   3020             }        
   3021         }
   3022     }
   3023 
   3024 exit:
   3025     if (val) {
   3026         sal_free(val);
   3027     }
   3028     if (old_val) {
   3029         sal_free(old_val);
   3030     }
   3031     
   3032 
   3033     return res;
   3034 }
   3035 
   3036 static int _shr_template_hash_data_get(int unit, 
   3037                                        int pool_id,
   3038                                         int template,
   3039                                         void *data)
   3040 {
   3041     _shr_template_pool_desc_t desc;
   3042     int res = BCM_E_NONE;   
   3043     SOC_SAND_MULTI_SET_KEY * val;
   3044     SOC_SAND_MULTI_SET_PTR hash_handle;
   3045     uint32 ref_count;
   3046     shr_template_manage_hash_compare_extras_t extra;
   3047     uint32 soc_sand_rv;
   3048     int template_alloc;
   3049     shr_template_from_stream_t *hcfs_cb = NULL;
   3050 
   3051     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   3052     SW_STATE_ACCESS_ERROR_CHECK(res); 
   3053 
   3054     hash_handle = desc.templateHandle;
   3055     extra = desc.extras;
   3056         
   3057     template_alloc = template - desc.template_low_id;
   3058 
   3059     val = sal_alloc((desc.data_size),"Data buffer");
   3060 
   3061     if (!val) {
   3062         /* alloc failed */
   3063         LOG_ERROR(BSL_LS_SOC_COMMON,
   3064                   (BSL_META("unable to allocate %u bytes for info\n"),
   3065                    (unsigned int)
   3066                    ((desc.data_size))));
   3067         res = BCM_E_MEMORY;
   3068     } else {
   3069         sal_memset(val,0x0,(desc.data_size));
   3070 
   3071         soc_sand_rv = soc_sand_multi_set_get_by_index(
   3072                     unit,
   3073                     hash_handle,
   3074                     template_alloc,
   3075                     val,
   3076                     &ref_count);
   3077 
   3078    
   3079         if (!SOC_SAND_FAILURE(soc_sand_rv) && ref_count != 0) {
   3080             hcfs_cb = hash_compare_from_stream_cb[unit];
   3081             res = (hcfs_cb[extra](data,val,(desc.data_size)));
   3082             if (res != BCM_E_NONE) {
   3083                 /* Problem with from stream */
   3084                 res =  BCM_E_INTERNAL;
   3085             }
   3086         } else {
   3087             /* No data */
   3088             res = BCM_E_NOT_FOUND;
   3089         }
   3090     }
   3091 
   3092     if (val) {
   3093         sal_free(val);
   3094     }
   3095     return res;
   3096 }
   3097 
   3098 static int _shr_template_hash_index_get(int unit, 
   3099                                         int pool_id,
   3100                                         const void *data,
   3101                                         int* template)
   3102 {
   3103     _shr_template_pool_desc_t desc;
   3104     int res = BCM_E_NONE;
   3105     SOC_SAND_MULTI_SET_KEY * val;
   3106     SOC_SAND_MULTI_SET_PTR hash_handle;
   3107     uint32 ref_count;
   3108     shr_template_manage_hash_compare_extras_t extra;
   3109     uint32 soc_sand_rv;
   3110     uint32 template_alloc;
   3111     shr_template_to_stream_t *hcts_cb = NULL;
   3112 
   3113     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   3114     SW_STATE_ACCESS_ERROR_CHECK(res); 
   3115 
   3116     hash_handle = desc.templateHandle;
   3117     extra = desc.extras;
   3118 
   3119     val = sal_alloc((desc.data_size),"Data buffer");
   3120 
   3121     if (!val) {
   3122         /* alloc failed */
   3123         LOG_ERROR(BSL_LS_SOC_COMMON,
   3124                   (BSL_META("unable to allocate %u bytes for info\n"),
   3125                    (unsigned int)
   3126                    ((desc.data_size))));
   3127         res = BCM_E_MEMORY;
   3128     } else {
   3129         sal_memset(val,0x0,(desc.data_size));
   3130 
   3131         /* move to buffer */
   3132         hcts_cb = hash_compare_to_stream_cb[unit];
   3133         res = hcts_cb[extra](data,val,(desc.data_size));
   3134         if (res != BCM_E_NONE) {
   3135             goto exit;
   3136         }
   3137 
   3138         /* Make sure that the new data does not exist already for another index. */
   3139         /* This check is actually made inside the insert by index as well. */
   3140         /* However no distinguishable error is returned for it. */
   3141         soc_sand_rv = soc_sand_multi_set_member_lookup(
   3142                       unit,
   3143                       hash_handle,
   3144                       val,
   3145                       &template_alloc,
   3146                       &ref_count);
   3147         if (SOC_SAND_FAILURE(soc_sand_rv)) {
   3148             /* Get data failed */
   3149             res = BCM_E_INTERNAL;
   3150             goto exit;
   3151         }
   3152 
   3153         if (ref_count == 0) {
   3154             res = BCM_E_NOT_FOUND;
   3155         } else {
   3156             *template = template_alloc + desc.template_low_id;
   3157         }
   3158     }
   3159 
   3160 exit:
   3161     if (val) {
   3162         sal_free(val);
   3163     }
   3164     return res;
   3165 }
   3166 
   3167 
   3168 static int _shr_template_hash_ref_count_get(int unit, 
   3169                                             int pool_id,
   3170                                             int template,
   3171                                             uint32 *ref_count)
   3172 {
   3173     _shr_template_pool_desc_t desc;
   3174     int res = BCM_E_NONE;   
   3175     SOC_SAND_MULTI_SET_KEY * val;
   3176     SOC_SAND_MULTI_SET_PTR hash_handle;        
   3177     uint32 soc_sand_rv;
   3178     uint32 tmp_ref_count = 0;
   3179     int template_alloc;
   3180 
   3181     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   3182     SW_STATE_ACCESS_ERROR_CHECK(res); 
   3183 
   3184     hash_handle = desc.templateHandle;
   3185 
   3186     template_alloc = template - desc.template_low_id;
   3187         
   3188     val = sal_alloc((desc.data_size),"Data buffer");
   3189 
   3190     if (!val) {
   3191         /* alloc failed */
   3192         LOG_ERROR(BSL_LS_SOC_COMMON,
   3193                   (BSL_META("unable to allocate %u bytes for info\n"),
   3194                    (unsigned int)
   3195                    ((desc.data_size))));
   3196         res = BCM_E_MEMORY;
   3197     } else {
   3198         sal_memset(val,0x0,(desc.data_size));
   3199 
   3200         soc_sand_rv = soc_sand_multi_set_get_by_index(
   3201                     unit,
   3202                     hash_handle,
   3203                     template_alloc,
   3204                     val,
   3205                     &tmp_ref_count);
   3206 
   3207    
   3208         if (!SOC_SAND_FAILURE(soc_sand_rv)) {
   3209             /* Update reference count */
   3210             *ref_count = tmp_ref_count;
   3211         } else {
   3212             /* Got error */
   3213             res = BCM_E_INTERNAL;
   3214         }
   3215     }
   3216 
   3217     if (val) {
   3218         sal_free(val);
   3219     }
   3220     return res;
   3221 }
   3222 
   3223 static int _shr_template_hash_clear(int unit, int pool_id)
   3224 {
   3225     _shr_template_pool_desc_t desc;
   3226     int res = BCM_E_NONE;   
   3227     SOC_SAND_MULTI_SET_PTR hash_handle;
   3228     uint32 soc_sand_rv;
   3229 
   3230     res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc);
   3231     SW_STATE_ACCESS_ERROR_CHECK(res); 
   3232 
   3233     hash_handle = desc.templateHandle;
   3234     
   3235     soc_sand_rv = soc_sand_multi_set_clear(unit, hash_handle);
   3236     SOC_SAND_IF_ERR_RETURN(soc_sand_rv);    
   3237    
   3238     return res;
   3239 }
   3240 #endif /* BCM_PETRA_SUPPORT || BCM_DFE_SUPPORT */