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

collector.c (89505B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * Collector - Common collector infrastructure interface
      8  * Purpose: APIs to configure collector parameters
      9  *          which will be used by instrumentation applications.
     10  */
     11 
     12 #include <soc/defs.h>
     13 
     14 #if defined(BCM_COLLECTOR_SUPPORT)
     15 
     16 #include <shared/bsl.h>
     17 #include <soc/drv.h>
     18 #include <shared/alloc.h>
     19 
     20 #include <bcm/types.h>
     21 #include <bcm/error.h>
     22 #include <bcm/module.h>
     23 
     24 #include <bcm_int/esw/collector.h>
     25 #include <bcm_int/esw/xgs5.h>
     26 #include <bcm_int/esw/switch.h>
     27 #if defined(BCM_FLOWTRACKER_SUPPORT)
     28 #include <bcm_int/esw/flowtracker/ft_export.h>
     29 #endif /* BCM_FLOWTRACKER_SUPPORT */
     30 
     31 
     32 /* Collector global information */
     33 _bcm_collector_global_info_t *collector_global_info[BCM_MAX_NUM_UNITS] = {0};
     34 
     35 /* List of collector export profiles info */
     36 _bcm_collector_export_profile_info_t
     37                       *export_profiles_info_list[BCM_MAX_NUM_UNITS] = {0};
     38 /* List of collectors info*/
     39 _bcm_collector_info_t *collectors_info_list[BCM_MAX_NUM_UNITS] = {0};
     40 
     41 #define BCM_COLLECTOR_INVALID_INDEX -1
     42 
     43 /******************************************************
     44 *                                                     *
     45 *                 UTILITY FUNCTIONS                   *
     46  */
     47 
     48 /*
     49  * Functions:
     50  *      _bcm_xgs5_collector_<header>_get
     51  * Purpose:
     52  *      The following set of _get() functions builds a given header for
     53  *      a given collector.
     54  * Parameters:
     55  *      collector_info -  (IN) Pointer to Collector information structure.
     56  *      <... other IN args ...>
     57  *      <header>  - (OUT) Returns header.
     58  * Returns:
     59  *      BCM_E_XXX
     60  * Notes:
     61  */
     62 int
     63 _bcm_xgs5_collector_udp_header_get(int unit,
     64                 bcm_collector_info_t *collector_info,
     65                 shr_udp_header_t *udp)
     66 {
     67     /* Set UDP */
     68     sal_memset(udp, 0, sizeof(*udp));
     69     udp->src = collector_info->udp.src_port;
     70     udp->dst = collector_info->udp.dst_port;
     71     /* Do not set UDP length since this will be filled by
     72      * EAPP.
     73      */
     74     udp->length = 0;
     75     udp->sum = 0;    /* Calculated later */
     76 
     77     return BCM_E_NONE;
     78 }
     79 
     80 int
     81 _bcm_xgs5_collector_ipv4_header_get(int unit, uint8 protocol,
     82                               uint8 tos, uint8 ttl,
     83                               bcm_ip_t src_ip_addr, bcm_ip_t dst_ip_addr,
     84                               shr_ipv4_header_t *ip)
     85 {
     86     uint8 buffer[SHR_IPV4_HEADER_LENGTH];
     87 
     88     sal_memset(ip, 0, sizeof(*ip));
     89 
     90     ip->version  = SHR_IPV4_VERSION;
     91     ip->h_length = SHR_IPV4_HEADER_LENGTH_WORDS;
     92     ip->dscp     = tos;
     93     ip->ecn      = 0;
     94     /* Dont fill in length since length will be calculated by
     95      * EAPP.
     96      */
     97     ip->length   = 0;
     98     ip->id       = 0;
     99     ip->flags    = 0;
    100     ip->f_offset = 0;
    101     ip->ttl      = ttl;
    102     ip->protocol = protocol;
    103     ip->sum      = 0;
    104     ip->src      = src_ip_addr;
    105     ip->dst      = dst_ip_addr;
    106 
    107     /* Calculate IP header checksum */
    108     shr_ipv4_header_pack(buffer, ip);
    109     ip->sum = 0;
    110 
    111     return BCM_E_NONE;
    112 }
    113 
    114 int
    115 _bcm_xgs5_collector_ip_headers_get(int unit,
    116                              bcm_collector_info_t *collector_info,
    117                              uint16 *etype,
    118                              shr_ipv4_header_t *ipv4)
    119 {
    120     int ip_protocol;
    121 
    122     ip_protocol = SHR_IP_PROTOCOL_UDP;
    123 
    124 
    125     *etype = SHR_L2_ETYPE_IPV4;
    126 
    127     BCM_IF_ERROR_RETURN
    128         (_bcm_xgs5_collector_ipv4_header_get(unit, ip_protocol,
    129                                        collector_info->ipv4.dscp,
    130                                        collector_info->ipv4.ttl,
    131                                        collector_info->ipv4.src_ip,
    132                                        collector_info->ipv4.dst_ip,
    133                                        ipv4));
    134 
    135     return BCM_E_NONE;
    136 }
    137 
    138 int
    139 _bcm_xgs5_collector_l2_header_get(int unit,
    140                            bcm_collector_info_t *collector_info,
    141                            uint16 etype, shr_l2_header_t *l2)
    142 {
    143     sal_memset(l2, 0, sizeof(*l2));
    144 
    145     /* Destination and Source MAC */
    146     sal_memcpy(l2->dst_mac, collector_info->eth.dst_mac, SHR_MAC_ADDR_LENGTH);
    147     sal_memcpy(l2->src_mac, collector_info->eth.src_mac, SHR_MAC_ADDR_LENGTH);
    148 
    149     /*
    150      * VLAN Tag(s)
    151      */
    152     if (collector_info->eth.vlan_tag_structure == 
    153         BCM_COLLECTOR_ETH_HDR_UNTAGGED) { 
    154         /* Set to 0 to indicate untagged */
    155         l2->outer_vlan_tag.tpid = 0;
    156         l2->inner_vlan_tag.tpid = 0;
    157     } else {
    158         /* Fill outer vlan */
    159         if ((collector_info->eth.vlan_tag_structure ==
    160              BCM_COLLECTOR_ETH_HDR_SINGLE_TAGGED) ||
    161             (collector_info->eth.vlan_tag_structure ==
    162              BCM_COLLECTOR_ETH_HDR_DOUBLE_TAGGED))
    163         {
    164             l2->outer_vlan_tag.tpid     = collector_info->eth.outer_tpid;
    165             l2->outer_vlan_tag.tci.prio =
    166                      BCM_VLAN_CTRL_PRIO(collector_info->eth.outer_vlan_tag);
    167             l2->outer_vlan_tag.tci.cfi  =
    168                      BCM_VLAN_CTRL_CFI(collector_info->eth.outer_vlan_tag);
    169             l2->outer_vlan_tag.tci.vid  =
    170                      BCM_VLAN_CTRL_ID(collector_info->eth.outer_vlan_tag);
    171         } else {
    172             return BCM_E_PARAM;
    173         }
    174         /* Fill inner vlan if double tagged */
    175         if (collector_info->eth.vlan_tag_structure ==
    176             BCM_COLLECTOR_ETH_HDR_DOUBLE_TAGGED) {
    177             l2->inner_vlan_tag.tpid     = collector_info->eth.inner_tpid;
    178             l2->inner_vlan_tag.tci.prio =
    179                      BCM_VLAN_CTRL_PRIO(collector_info->eth.inner_vlan_tag);
    180             l2->inner_vlan_tag.tci.cfi  =
    181                      BCM_VLAN_CTRL_CFI(collector_info->eth.inner_vlan_tag);
    182             l2->inner_vlan_tag.tci.vid  =
    183                      BCM_VLAN_CTRL_ID(collector_info->eth.inner_vlan_tag);
    184         } else {
    185             /* Set to 0 to indicate not inner tagged */
    186             l2->inner_vlan_tag.tpid = 0;
    187         }
    188     }
    189 
    190     /* Ether Type */
    191     l2->etype = etype;
    192 
    193     return BCM_E_NONE;
    194 }
    195 
    196 /***********************************************************
    197 *                                                          *
    198 *     COLLECTOR EXPORT PROFILE LIST MANAGEMENT FUNCTIONS   *
    199  */
    200 
    201 /*
    202  * Function:
    203  *     _bcm_xgs5_export_profile_list_export_profile_add
    204  * Purpose:
    205  *     Adds an export profile to the export profiles list.
    206  * Parameters:
    207  *     unit          - (IN) BCM device number
    208  *     export_profile_id   - (IN) Export profile ID
    209  *     export_profile_info - (IN) Export profile informatin.
    210  * Returns:
    211  *     BCM_E_XXX
    212  */
    213 int
    214 _bcm_xgs5_export_profile_list_export_profile_add(int unit,
    215                            int export_profile_id,
    216                            bcm_collector_export_profile_t *export_profile_info)
    217 {
    218     _bcm_collector_export_profile_info_t *export_profiles_info_list_node =
    219         &(export_profiles_info_list[unit][export_profile_id]);
    220 
    221     if (export_profiles_info_list_node->export_profile_id !=
    222         BCM_COLLECTOR_INVALID_INDEX) {
    223         return BCM_E_EXISTS;
    224     }
    225     export_profiles_info_list_node->export_profile_id = export_profile_id;
    226 
    227     sal_memcpy(&(export_profiles_info_list_node->export_profile_info),
    228                export_profile_info,
    229                sizeof(bcm_collector_export_profile_t));
    230 
    231     LOG_DEBUG(BSL_LS_BCM_COLLECTOR,
    232             (BSL_META_U(unit,
    233                         "COLLECTOR(unit %d) Info: %s" 
    234                         " (export_profile_id=0x%x).\n"), unit, __FUNCTION__,
    235                          export_profile_id));
    236     return (BCM_E_NONE);
    237 }
    238 
    239 /*
    240  * Function:
    241  *     _bcm_xgs5_export_profile_list_export_profile_delete
    242  * Purpose:
    243  *     Deletes a collector export profile from the export profiles list.
    244  * Parameters:
    245  *     unit          - (IN) BCM device number
    246  *     export_profile_id   - (IN) Export profile ID
    247  * Returns:
    248  *     BCM_E_XXX
    249  */
    250 int
    251 _bcm_xgs5_export_profile_list_export_profile_delete (int unit,
    252                               int export_profile_id)
    253 {
    254     _bcm_collector_export_profile_info_t *export_profiles_info_list_node =
    255         &(export_profiles_info_list[unit][export_profile_id]);
    256 
    257     if (export_profiles_info_list_node->export_profile_id !=
    258                               export_profile_id) {
    259         LOG_DEBUG(BSL_LS_BCM_COLLECTOR,
    260                   (BSL_META_U(unit,
    261                   "COLLECTOR(unit %d) Info: export profile ID "
    262                   "does not exist"), unit));
    263         return (BCM_E_NOT_FOUND);
    264     }
    265 
    266     sal_memset(export_profiles_info_list_node, 0,
    267                                  sizeof(_bcm_collector_export_profile_info_t));
    268 
    269     export_profiles_info_list_node->export_profile_id =
    270             BCM_COLLECTOR_INVALID_INDEX;
    271     return (BCM_E_NONE);
    272 }
    273 
    274 /*
    275  * Function:
    276  *     _bcm_xgs5_export_profile_list_export_profile_modify
    277  * Purpose:
    278  *     Modfiy a collector in the collector list.
    279  * Parameters:
    280  *     unit          - (IN) BCM device number
    281  *     export_profile_id   - (IN) Export profile ID
    282  *     export_profile_info - (IN) Export profile informatin.
    283  * Returns:
    284  *     BCM_E_XXX
    285  */
    286 int
    287 _bcm_xgs5_export_profile_list_export_profile_modify(int unit,
    288                            int export_profile_id,
    289                            bcm_collector_export_profile_t *export_profile_info)
    290 {
    291     _bcm_collector_export_profile_info_t *export_profiles_info_list_node =
    292         &(export_profiles_info_list[unit][export_profile_id]);
    293 
    294     if (export_profiles_info_list_node->export_profile_id !=
    295                                         export_profile_id) {
    296         LOG_DEBUG(BSL_LS_BCM_COLLECTOR,
    297                   (BSL_META_U(unit,
    298                   "COLLECTOR(unit %d) Info: export profile ID "
    299                   "does not exist"), unit));
    300         return (BCM_E_NOT_FOUND);
    301     }
    302 
    303     sal_memcpy(&(export_profiles_info_list_node->export_profile_info),
    304                export_profile_info,
    305                sizeof(bcm_collector_export_profile_t));
    306 
    307     return BCM_E_NONE;
    308 }
    309 
    310 /*
    311  * Function:
    312  *     _bcm_xgs5_export_profile_list_export_profile_get
    313  * Purpose:
    314  *     Get a collector from the collector list.
    315  * Parameters:
    316  *     unit          - (IN) BCM device number
    317  *     export_profile_id   - (IN) The export profile ID
    318  *     export_profile_info - (OUT) collector export profile information
    319  * Returns:
    320  *     BCM_E_XXX
    321  */
    322 int
    323 _bcm_xgs5_export_profile_list_export_profile_get (int unit,
    324                            int export_profile_id,
    325                            bcm_collector_export_profile_t *export_profile_info)
    326 {
    327     _bcm_collector_export_profile_info_t *export_profiles_info_list_node =
    328         &(export_profiles_info_list[unit][export_profile_id]);
    329 
    330     if (export_profiles_info_list_node->export_profile_id !=
    331                                         export_profile_id) {
    332         LOG_DEBUG(BSL_LS_BCM_COLLECTOR,
    333                   (BSL_META_U(unit,
    334                   "COLLECTOR(unit %d) Info: export profile ID "
    335                   "does not exist"), unit));
    336         return (BCM_E_NOT_FOUND);
    337     }
    338 
    339     sal_memcpy(export_profile_info,
    340                &(export_profiles_info_list_node->export_profile_info), 
    341                 sizeof(bcm_collector_export_profile_t));
    342 
    343 
    344     return BCM_E_NONE;
    345 }
    346 
    347 /*
    348  * Function:
    349  *      _bcm_xgs5_collector_export_profile_create
    350  * Purpose:
    351  *      Creates a collector export profile with given export profile info.
    352  * Parameters:
    353  *      unit            - (IN)  BCM device number
    354  *      options         - (IN)  Collector export profile create options
    355  *      id              - (INOUT)  Collector Id
    356  *      export_profile_info  - (IN)  Collector export profile info
    357  * Returns:
    358  *      BCM_E_XXX   - BCM error code.
    359  */
    360 int _bcm_xgs5_collector_export_profile_create(int unit,
    361                           uint32 options,
    362                           int *id,
    363                           bcm_collector_export_profile_t *export_profile_info)
    364 {
    365     int rv = BCM_E_NONE, export_profile_id = 0;
    366     bcm_collector_export_profile_t old_export_profile_info;
    367     _bcm_collector_global_info_t *collector_per_unit_global_info =
    368                                     COLLECTOR_GLOBAL_INFO_GET(unit);
    369 
    370     if (collector_per_unit_global_info == NULL) {
    371         LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    372                 (BSL_META_U(unit,
    373                             "COLLECTOR(unit %d) Error: collector"
    374                             " module is not initialized"), unit));
    375         return BCM_E_INIT;
    376     }
    377 
    378     if (export_profile_info == NULL) {
    379         LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    380                 (BSL_META_U(unit,
    381                             "COLLECTOR(unit %d) Error: NULL export profile"
    382                             " passed"), unit));
    383         return BCM_E_PARAM;
    384     }
    385 
    386     /* 1. IF replace, WITH_ID is mandatory. If not provided, return
    387      * BCM_E_PARAM.
    388      *
    389      * 2. Also verify that a collector export profile with such an ID
    390      * exists, else return BCM_E_NOT_FOUND
    391      */
    392     if ((options & BCM_COLLECTOR_EXPORT_PROFILE_REPLACE) &&
    393        !(options & BCM_COLLECTOR_EXPORT_PROFILE_WITH_ID)) {
    394         return BCM_E_PARAM;
    395     }
    396 
    397     /* Check collector wire format is valid or not */
    398     if ((export_profile_info->wire_format < bcmCollectorWireFormatIpfix) ||
    399         (export_profile_info->wire_format >= bcmCollectorWireFormatCount)) {
    400         return BCM_E_PARAM;
    401     }
    402 
    403     if ((options & BCM_COLLECTOR_EXPORT_PROFILE_WITH_ID) &&
    404         (options & BCM_COLLECTOR_EXPORT_PROFILE_REPLACE)) {
    405         sal_memset(&old_export_profile_info, 0,
    406                    sizeof(old_export_profile_info));
    407         rv = _bcm_xgs5_export_profile_list_export_profile_get(unit, *id,
    408                                                      &old_export_profile_info);
    409         if (BCM_FAILURE(rv)) {
    410             return rv;
    411         }
    412     }
    413 
    414     /* WITH_ID */
    415     if (options & BCM_COLLECTOR_EXPORT_PROFILE_WITH_ID) {
    416         if (!(options & BCM_COLLECTOR_EXPORT_PROFILE_REPLACE)) {
    417             /* If WITH_ID and not replace, reserve the ID */
    418             rv = shr_idxres_list_reserve(
    419                             collector_per_unit_global_info->export_profile_pool,
    420                                          *id, *id);
    421             if (BCM_FAILURE(rv)) {
    422                 return ((rv == BCM_E_RESOURCE) ? BCM_E_EXISTS : rv);
    423             }
    424         }
    425     } else {
    426         /* Else allocate the ID */
    427         rv = shr_idxres_list_alloc(
    428                             collector_per_unit_global_info->export_profile_pool,
    429                             (shr_idxres_element_t *)(&export_profile_id));
    430         if (BCM_FAILURE(rv)) {
    431             if (rv == BCM_E_RESOURCE) {
    432                 LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    433                   (BSL_META_U(unit,
    434                   "COLLECTOR(unit %d) Info: Cannot create more than"
    435                   " %d collector export profiles"), unit,
    436                   BCM_INT_COLLECTOR_MAX_EXPORT_PROFILES));
    437             }
    438             return rv;
    439         }
    440         *id = export_profile_id;
    441     }
    442 
    443     /* WITH_ID and replace. */
    444     if ((options & BCM_COLLECTOR_EXPORT_PROFILE_WITH_ID)  &&
    445         (options & BCM_COLLECTOR_EXPORT_PROFILE_REPLACE)) {
    446         /* Modify the collector info in the list with ID. */
    447         rv = _bcm_xgs5_export_profile_list_export_profile_modify(unit, *id,
    448                                                           export_profile_info);
    449     }
    450     else {
    451         /* Add it to the list of collectors */
    452         rv = _bcm_xgs5_export_profile_list_export_profile_add(unit, *id,
    453                                                     export_profile_info);
    454     }
    455     if (BCM_FAILURE(rv)) {
    456         /* Free up the collector id allocated */
    457         if (!(options & BCM_COLLECTOR_EXPORT_PROFILE_REPLACE)) {
    458             BCM_IF_ERROR_RETURN(
    459                shr_idxres_list_free(
    460                             collector_per_unit_global_info->export_profile_pool,
    461                             *id));
    462         }
    463         return rv;
    464     }
    465 
    466     return BCM_E_NONE;
    467 }
    468 
    469 /*
    470  * Function:
    471  *      _bcm_xgs5_collector_export_profile_get
    472  * Purpose:
    473  *      Gets a collector information
    474  * Parameters:
    475  *      unit            - (IN)  BCM device number
    476  *      id              - (IN)  Collector Id
    477  *      export_profile_info  - (OUT) Collector export profile info
    478  * Returns:
    479  *      BCM_E_XXX   - BCM error code.
    480  */
    481 int _bcm_xgs5_collector_export_profile_get(int unit,
    482                            int id,
    483                            bcm_collector_export_profile_t *export_profile_info)
    484 {
    485     int rv = BCM_E_NONE;
    486 
    487     if (export_profiles_info_list[unit] == NULL) {
    488         return BCM_E_INIT;
    489     }
    490 
    491     /* Ensure export_profile_info is not NULL */
    492     if (export_profile_info == NULL) {
    493         return BCM_E_PARAM;
    494     }
    495 
    496     /* Get the collector export profile info from the list
    497      * using ID.
    498      */
    499     rv = _bcm_xgs5_export_profile_list_export_profile_get(unit, id,
    500                                                    export_profile_info);
    501 
    502     /* If not found, return BCM_E_NOT_FOUND */
    503     if (BCM_FAILURE(rv)) {
    504         return rv;
    505     }
    506 
    507     return BCM_E_NONE;
    508 }
    509 
    510 /*
    511  * Function:
    512  *      _bcm_xgs5_collector_export_profile_ids_get_all
    513  * Purpose:
    514  *      Get the ID list of all collectors configured.
    515  * Parameters:
    516  *      unit                 - (IN)  BCM device number
    517  *      max_size             - (IN)  Size of the collector list array
    518  *      collector_list       - (OUT) Collector id list
    519  *      list_szie            - (OUT) NUmber of elements in the list
    520  * Returns:
    521  *      BCM_E_XXX   - BCM error code.
    522  */
    523 int _bcm_xgs5_collector_export_profile_ids_get_all(
    524                            int unit,
    525                            int max_size,
    526                            int *collector_list,
    527                            int *list_size)
    528 {
    529     int i;
    530     int num_export_profiles;
    531 
    532     if (export_profiles_info_list[unit] == NULL) {
    533         return BCM_E_INIT;
    534     }
    535 
    536     /* If the max_size is non zero and list == NULL, return
    537      * BCM_E_PARAM.
    538      */
    539     if (max_size != 0 && collector_list == NULL) {
    540         return BCM_E_PARAM;
    541     }
    542 
    543     num_export_profiles = 0;
    544     *list_size = 0;
    545     for (i = BCM_INT_COLLECTOR_EXPORT_PROFILE_START_ID;
    546          i <= BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID; i++) {
    547         if (export_profiles_info_list[unit][i].export_profile_id == i) {
    548             /* Collector export profile exists */
    549             num_export_profiles++;
    550             if (*list_size < max_size) {
    551                 collector_list[*list_size] = i;
    552                 (*list_size)++;
    553             }
    554         }
    555     }
    556 
    557     /* If the max_size is 0 then return the number of collector export profiles
    558      *  configured in list_size
    559      */
    560     if (max_size == 0) {
    561         *list_size = num_export_profiles;
    562         return BCM_E_NONE;
    563     }
    564 
    565     return BCM_E_NONE;
    566 }
    567 
    568 /*
    569  * Function:
    570  *      _bcm_xgs5_collector_export_profile_destroy
    571  * Purpose:
    572  *      Destroys a collector
    573  * Parameters:
    574  *      unit           - (IN)  BCM device number
    575  *      id             - (IN) Collector expor profile Id
    576  * Returns:
    577  *      BCM_E_XXX   - BCM error code.
    578  */
    579 int _bcm_xgs5_collector_export_profile_destroy(int unit,
    580                                  int id)
    581 {
    582     int rv = BCM_E_NONE;
    583      _bcm_collector_global_info_t *collector_per_unit_global_info =
    584                             COLLECTOR_GLOBAL_INFO_GET(unit);
    585 
    586     if (collector_per_unit_global_info == NULL) {
    587         LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    588                 (BSL_META_U(unit,
    589                             "COLLECTOR(unit %d) Error: collector"
    590                             " module is not initialized"), unit));
    591         return BCM_E_INIT;
    592     }
    593 
    594     if (export_profiles_info_list[unit] == NULL) {
    595         return BCM_E_INIT;
    596     }
    597 
    598     if (id > BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID) {
    599         return BCM_E_PARAM;
    600     }
    601 
    602     if (export_profiles_info_list[unit][id].ref_count != 0) {
    603         LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    604                   (BSL_META_U(unit,
    605                               "COLLECTOR(unit %d) Error: Export profile in use\n"),
    606                    unit));
    607         return BCM_E_EXISTS;
    608     }
    609 
    610     /* Delete the collector expor profile from the expor profile list with
    611      * given ID.
    612      */
    613     rv = _bcm_xgs5_export_profile_list_export_profile_delete(unit, id);
    614     /* If not found in the list, return BCM_E_NOT_FOUND */
    615     if (BCM_FAILURE(rv)) {
    616         return rv;
    617     }
    618 
    619     /* Free up the ID from the pool */
    620     BCM_IF_ERROR_RETURN(
    621         shr_idxres_list_free(
    622                    collector_per_unit_global_info->export_profile_pool, id));
    623 
    624     return BCM_E_NONE;
    625 }
    626 
    627 /*
    628  * Function:
    629  *     _bcm_xgs5_collector_export_profile_list_destroy
    630  * Purpose:
    631  *     Destroy the collector export profile list.
    632  * Parameters:
    633  *     unit          - (IN) BCM device number
    634  * Returns:
    635  *     BCM_E_XXX
    636  */
    637 int
    638 _bcm_xgs5_collector_export_profile_list_destroy (int unit)
    639 {
    640     if (export_profiles_info_list[unit] != NULL) {
    641         sal_free(export_profiles_info_list[unit]);
    642     }
    643 
    644     export_profiles_info_list[unit] = NULL;
    645     return BCM_E_NONE;
    646 }
    647 
    648 /*
    649  * Function:
    650  *     _bcm_xgs5_collector_export_profile_list_create
    651  * Purpose:
    652  *     Create the collector export profile list.
    653  * Parameters:
    654  *     unit          - (IN) BCM device number
    655  * Returns:
    656  *     BCM_E_XXX
    657  */
    658 int
    659 _bcm_xgs5_collector_export_profile_list_create (int unit)
    660 {
    661     int i = 0;
    662     _bcm_collector_export_profile_info_t *export_profiles_node = NULL;
    663 
    664     if (export_profiles_info_list[unit] == NULL) {
    665         _BCM_COLLECTOR_ALLOC(export_profiles_info_list[unit],
    666                              _bcm_collector_export_profile_info_t,
    667                       sizeof(_bcm_collector_export_profile_info_t) *
    668                 (BCM_INT_COLLECTOR_MAX_EXPORT_PROFILES +
    669                  BCM_INT_COLLECTOR_EXPORT_PROFILE_START_ID),
    670                 "collector export profile list");
    671 
    672     }
    673 
    674     if (export_profiles_info_list[unit] == NULL) {
    675         return BCM_E_MEMORY;
    676     }
    677 
    678     for (i= BCM_INT_COLLECTOR_EXPORT_PROFILE_START_ID;
    679          i<= BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID; i++) {
    680         export_profiles_node = &(export_profiles_info_list[unit][i]);
    681         export_profiles_node->export_profile_id =
    682                       BCM_COLLECTOR_INVALID_INDEX;
    683     }
    684     return BCM_E_NONE;
    685 }
    686 
    687 /*
    688  * Function:
    689  *     _bcm_xgs5_collector_export_profile_ref_count_update
    690  * Purpose:
    691  *     Increment/Decrement reference count for an export profile
    692  * Parameters:
    693  *     unit          - (IN) BCM device number
    694  *     id            - (IN) Export profile Id
    695  *     update        - (IN) Reference count update (+/-)
    696  * Returns:
    697  *     BCM_E_XXX
    698  */
    699 int
    700 _bcm_xgs5_collector_export_profile_ref_count_update(int unit, int id, int update)
    701 {
    702     if (id > BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID) {
    703         return BCM_E_PARAM;
    704     }
    705 
    706     if ((export_profiles_info_list[unit][id].ref_count + update) < 0) {
    707         return BCM_E_PARAM;
    708     }
    709     export_profiles_info_list[unit][id].ref_count += update;
    710 
    711     return BCM_E_NONE;
    712 }
    713 
    714 /******************************************************
    715 *                                                     *
    716 *        COLLECTOR LIST MANAGEMENT FUNCTIONS          *
    717  */
    718 
    719 /*
    720  * Function:
    721  *     _bcm_xgs5_collector_list_collector_add
    722  * Purpose:
    723  *     Add a collector to the collector list.
    724  * Parameters:
    725  *     unit          - (IN) BCM device number
    726  *     collector_id   - (IN) The collector ID
    727  *     collector_info - (IN) Collector informatin.
    728  * Returns:
    729  *     BCM_E_XXX
    730  */
    731 int
    732 _bcm_xgs5_collector_list_collector_add(int unit,
    733                            bcm_collector_t collector_id,
    734                            bcm_collector_info_t *collector_info)
    735 {
    736     _bcm_collector_info_t *collectors_info_list_node =
    737         &(collectors_info_list[unit][collector_id]);
    738 
    739     if (collectors_info_list_node->collector_id !=
    740         BCM_COLLECTOR_INVALID_INDEX) {
    741         return BCM_E_EXISTS;
    742     }
    743     collectors_info_list_node->collector_id = collector_id;
    744 
    745     sal_memcpy(&(collectors_info_list_node->collector_info), collector_info,
    746                sizeof(bcm_collector_info_t));
    747 
    748     LOG_DEBUG(BSL_LS_BCM_COLLECTOR,
    749             (BSL_META_U(unit,
    750                         "COLLECTOR(unit %d) Info: %s" 
    751                         " (Collector=0x%x).\n"), unit, __FUNCTION__,
    752                          collector_id));
    753     return (BCM_E_NONE);
    754 }
    755 
    756 /*
    757  * Function:
    758  *     _bcm_xgs5_collector_list_collector_delete
    759  * Purpose:
    760  *     Delete a collector from the collector list.
    761  * Parameters:
    762  *     unit          - (IN) BCM device number
    763  *     collector_id   - (IN) The collector ID
    764  * Returns:
    765  *     BCM_E_XXX
    766  */
    767 int
    768 _bcm_xgs5_collector_list_collector_delete (int unit,
    769                               bcm_collector_t collector_id)
    770 {
    771     _bcm_collector_info_t *collectors_info_list_node =
    772         &(collectors_info_list[unit][collector_id]);
    773 
    774     if (collectors_info_list_node->collector_id != collector_id) {
    775         LOG_DEBUG(BSL_LS_BCM_COLLECTOR,
    776                   (BSL_META_U(unit,
    777                   "COLLECTOR(unit %d) Info: collector ID"
    778                   " does not exist"), unit));
    779         return (BCM_E_NOT_FOUND);
    780     }
    781 
    782     sal_memset(collectors_info_list_node, 0,
    783                                  sizeof(_bcm_collector_info_t));
    784     collectors_info_list_node->collector_id = BCM_COLLECTOR_INVALID_INDEX;
    785     collectors_info_list_node->user         = _BCM_COLLECTOR_EXPORT_APP_NONE;
    786     return (BCM_E_NONE);
    787 }
    788 
    789 /*
    790  * Function:
    791  *     _bcm_xgs5_collector_list_collector_modify
    792  * Purpose:
    793  *     Modfiy a collector in the collector list.
    794  * Parameters:
    795  *     unit          - (IN) BCM device number
    796  *     collector_id   - (IN) The collector ID
    797  *     collector_info - (IN) Collector informatin.
    798  * Returns:
    799  *     BCM_E_XXX
    800  */
    801 int
    802 _bcm_xgs5_collector_list_collector_modify(int unit,
    803                            bcm_collector_t collector_id,
    804                            bcm_collector_info_t *collector_info)
    805 {
    806     _bcm_collector_info_t *list_node =
    807         &(collectors_info_list[unit][collector_id]);
    808 
    809     if (list_node->collector_id != collector_id) {
    810         LOG_DEBUG(BSL_LS_BCM_COLLECTOR,
    811                   (BSL_META_U(unit,
    812                   "COLLECTOR(unit %d) Info: collector ID"
    813                   " does not exist"), unit));
    814         return (BCM_E_NOT_FOUND);
    815     }
    816 
    817     sal_memcpy(&(list_node->collector_info), collector_info,
    818                sizeof(bcm_collector_info_t));
    819 
    820     return BCM_E_NONE;
    821 }
    822 
    823 /*
    824  * Function:
    825  *     _bcm_xgs5_collector_list_collector_get
    826  * Purpose:
    827  *     Get a collector from the collector list.
    828  * Parameters:
    829  *     unit          - (IN) BCM device number
    830  *     collector_id   - (IN) The collector ID
    831  *     collector_info - (OUT) collector information
    832  * Returns:
    833  *     BCM_E_XXX
    834  */
    835 int
    836 _bcm_xgs5_collector_list_collector_get (int unit,
    837                               bcm_collector_t collector_id,
    838                               bcm_collector_info_t *collector_info)
    839 {
    840     _bcm_collector_info_t *list_node =
    841         &(collectors_info_list[unit][collector_id]);
    842 
    843     if (list_node->collector_id != collector_id) {
    844         LOG_DEBUG(BSL_LS_BCM_COLLECTOR,
    845                   (BSL_META_U(unit,
    846                   "COLLECTOR(unit %d) Info: collector ID"
    847                   " does not exist"), unit));
    848         return (BCM_E_NOT_FOUND);
    849     }
    850 
    851     sal_memcpy(collector_info, &(list_node->collector_info), 
    852                 sizeof(bcm_collector_info_t));
    853 
    854 
    855     return BCM_E_NONE;
    856 }
    857 
    858 /*
    859  * Function:
    860  *     _bcm_xgs5_collector_list_destroy
    861  * Purpose:
    862  *     Destroy the collector list.
    863  * Parameters:
    864  *     unit          - (IN) BCM device number
    865  * Returns:
    866  *     BCM_E_XXX
    867  */
    868 int
    869 _bcm_xgs5_collector_list_destroy (int unit)
    870 {
    871     if (collectors_info_list[unit] != NULL) {
    872         sal_free(collectors_info_list[unit]);
    873     }
    874 
    875     collectors_info_list[unit] = NULL;
    876     return BCM_E_NONE;
    877 }
    878 
    879 /*
    880  * Function:
    881  *     _bcm_xgs5_collector_list_create
    882  * Purpose:
    883  *     Create the collector list.
    884  * Parameters:
    885  *     unit          - (IN) BCM device number
    886  * Returns:
    887  *     BCM_E_XXX
    888  */
    889 int
    890 _bcm_xgs5_collector_list_create (int unit)
    891 {
    892     int i = 0;
    893     _bcm_collector_info_t *collector_node = NULL;
    894 
    895     if (collectors_info_list[unit] == NULL) {
    896         _BCM_COLLECTOR_ALLOC(collectors_info_list[unit], _bcm_collector_info_t,
    897                       sizeof(_bcm_collector_info_t) *
    898                 (BCM_INT_COLLECTOR_MAX_COLLECTORS +
    899                  BCM_INT_COLLECTOR_COLLECTOR_START_ID),
    900                 "collector list");
    901     }
    902 
    903     if (collectors_info_list[unit] == NULL) {
    904         return BCM_E_MEMORY;
    905     }
    906 
    907     for (i= BCM_INT_COLLECTOR_COLLECTOR_START_ID;
    908          i<= BCM_INT_COLLECTOR_COLLECTOR_END_ID; i++) {
    909         collector_node = &(collectors_info_list[unit][i]);
    910         collector_node->collector_id =
    911                       BCM_COLLECTOR_INVALID_INDEX;
    912         collector_node->user = _BCM_COLLECTOR_EXPORT_APP_NONE;
    913     }
    914     return BCM_E_NONE;
    915 }
    916 
    917 /*
    918  * Function:
    919  *      _bcm_xgs5_collector_create
    920  * Purpose:
    921  *      Createa a collector with given collector info.
    922  * Parameters:
    923  *      unit            - (IN)  BCM device number
    924  *      options         - (IN)  Collector create options
    925  *      id              - (INOUT)  Collector Id
    926  *      collector_info  - (IN)  Collector info
    927  * Returns:
    928  *      BCM_E_XXX   - BCM error code.
    929  */
    930 int _bcm_xgs5_collector_create(int unit,
    931                                 uint32 options,
    932                                 bcm_collector_t *id,
    933                                 bcm_collector_info_t *collector_info)
    934 {
    935     int rv = BCM_E_NONE, collector_id = 0;
    936     bcm_collector_info_t old_collector_info;
    937     _bcm_collector_global_info_t *collector_per_unit_global_info =
    938                                     COLLECTOR_GLOBAL_INFO_GET(unit);
    939 
    940     if (collector_per_unit_global_info == NULL) {
    941         LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    942                 (BSL_META_U(unit,
    943                             "COLLECTOR(unit %d) Error: collector"
    944                             " module is not initialized"), unit));
    945         return BCM_E_INIT;
    946     }
    947 
    948     if (collector_info == NULL) {
    949         LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    950                 (BSL_META_U(unit,
    951                             "COLLECTOR(unit %d) Error: NULL collector info"
    952                             " passed"), unit));
    953         return BCM_E_PARAM;
    954     }
    955 
    956     /* 1. IF replace, WITH_ID is mandatory. If not provided, return
    957      * BCM_E_PARAM.
    958      *
    959      * 2. Also verify that a collector with such an ID
    960      * exists, else return BCM_E_NOT_FOUND
    961      */
    962     if ((options & BCM_COLLECTOR_REPLACE) &&
    963        !(options & BCM_COLLECTOR_WITH_ID)) {
    964         return BCM_E_PARAM;
    965     }
    966 
    967     /* Validate ETH header */
    968     switch (collector_info->eth.vlan_tag_structure) {
    969         case BCM_COLLECTOR_ETH_HDR_UNTAGGED:
    970             /* Nothing to validate */
    971             break;
    972 
    973         case BCM_COLLECTOR_ETH_HDR_SINGLE_TAGGED:
    974             if (collector_info->eth.outer_vlan_tag > BCM_VLAN_MAX) {
    975                 LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    976                           (BSL_META_U(unit,
    977                                       "COLLECTOR(unit %d) Error: Invalid outer_vlan_tag=%d\n"),
    978                            unit, collector_info->eth.outer_vlan_tag));
    979                 return BCM_E_PARAM;
    980             }
    981             break;
    982 
    983         case BCM_COLLECTOR_ETH_HDR_DOUBLE_TAGGED:
    984             if ((collector_info->eth.outer_vlan_tag > BCM_VLAN_MAX) ||
    985                 (collector_info->eth.inner_vlan_tag > BCM_VLAN_MAX)) {
    986                 LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    987                           (BSL_META_U(unit,
    988                                       "COLLECTOR(unit %d) Error: Invalid outer_vlan_tag(%d)"
    989                                       " or inner_vlan_tag(%d) \n"),
    990                            unit, collector_info->eth.outer_vlan_tag,
    991                            collector_info->eth.inner_vlan_tag));
    992                 return BCM_E_PARAM;
    993             }
    994             break;
    995 
    996         default:
    997             LOG_ERROR(BSL_LS_BCM_COLLECTOR,
    998                       (BSL_META_U(unit,
    999                                   "COLLECTOR(unit %d) Error: Invalid vlan_tag_structure=%d\n"),
   1000                        unit, collector_info->eth.vlan_tag_structure));
   1001             return BCM_E_PARAM;
   1002     }
   1003 
   1004     /* Check collector transport type is valid or not */
   1005     if ((collector_info->transport_type < bcmCollectorTransportTypeIpv4Udp) ||
   1006         (collector_info->transport_type >= bcmCollectorTransportTypeCount)) {
   1007         return BCM_E_PARAM;
   1008     }
   1009 
   1010     if ((options & BCM_COLLECTOR_WITH_ID) &&
   1011         (options & BCM_COLLECTOR_REPLACE)) {
   1012         sal_memset(&old_collector_info, 0, sizeof(old_collector_info));
   1013         rv = _bcm_xgs5_collector_list_collector_get(unit, *id,
   1014                                                        &old_collector_info);
   1015         if (BCM_FAILURE(rv)) {
   1016             return rv;
   1017         }
   1018     }
   1019 
   1020     if (collector_info->transport_type == bcmCollectorTransportTypeIpv4Udp) {
   1021         if((collector_info->ipv4.src_ip == 0) ||
   1022            (collector_info->ipv4.dst_ip == 0))
   1023         {
   1024             LOG_ERROR(BSL_LS_BCM_COLLECTOR,
   1025                   (BSL_META_U(unit,
   1026                   "COLLECTOR(unit %d) Error: Invalid IP configuration"), unit));
   1027             return BCM_E_PARAM;
   1028         }
   1029         if((collector_info->udp.src_port == 0) ||
   1030            (collector_info->udp.dst_port == 0))
   1031         {
   1032             LOG_ERROR(BSL_LS_BCM_COLLECTOR,
   1033                  (BSL_META_U(unit,
   1034                  "COLLECTOR(unit %d) Error: Invalid UDP configuration"), unit));
   1035             return BCM_E_PARAM;
   1036         }
   1037     }
   1038     /* WITH_ID */
   1039     if (options & BCM_COLLECTOR_WITH_ID) {
   1040         if (!(options & BCM_COLLECTOR_REPLACE)) {
   1041             /* If WITH_ID and not replace, reserve the ID */
   1042             rv = shr_idxres_list_reserve(
   1043                                 collector_per_unit_global_info->collector_pool,
   1044                                 *id, *id);
   1045             if (BCM_FAILURE(rv)) {
   1046                 return ((rv == BCM_E_RESOURCE) ? BCM_E_EXISTS : rv);
   1047             }
   1048         }
   1049     } else {
   1050         /* Else allocate the ID */
   1051         rv = shr_idxres_list_alloc(
   1052                          collector_per_unit_global_info->collector_pool,
   1053                                    (shr_idxres_element_t *)(&collector_id));
   1054         if (BCM_FAILURE(rv)) {
   1055             if (rv == BCM_E_RESOURCE) {
   1056                 LOG_ERROR(BSL_LS_BCM_COLLECTOR,
   1057                   (BSL_META_U(unit,
   1058                   "COLLECTOR(unit %d) Error: Cannot create more than"
   1059                   " %d collectors"), unit, BCM_INT_COLLECTOR_MAX_COLLECTORS));
   1060             }
   1061             return rv;
   1062         }
   1063         *id = collector_id;    
   1064     }
   1065 
   1066     /* WITH_ID and replace. */
   1067     if ((options & BCM_COLLECTOR_WITH_ID)  &&
   1068         (options & BCM_COLLECTOR_REPLACE)) {
   1069         /* Modify the collector info in the list with ID. */
   1070         rv = _bcm_xgs5_collector_list_collector_modify(unit, *id,
   1071                                                           collector_info);
   1072     }
   1073     else {
   1074         /* Add it to the list of collectors */
   1075         rv = _bcm_xgs5_collector_list_collector_add(unit, *id, collector_info);
   1076     }
   1077     if (BCM_FAILURE(rv)) {
   1078         /* Free up the collector id allocated */
   1079         if (!(options & BCM_COLLECTOR_REPLACE)) {
   1080             BCM_IF_ERROR_RETURN(
   1081                shr_idxres_list_free(
   1082                            collector_per_unit_global_info->collector_pool,*id));
   1083         }
   1084         return rv;
   1085     }
   1086 
   1087     return BCM_E_NONE;
   1088 }
   1089 
   1090 /*
   1091  * Function:
   1092  *      _bcm_xgs5_collector_get
   1093  * Purpose:
   1094  *      Gets a collector information
   1095  * Parameters:
   1096  *      unit            - (IN)  BCM device number
   1097  *      id              - (IN)  Collector Id
   1098  *      collector_info  - (OUT) Collector info
   1099  * Returns:
   1100  *      BCM_E_XXX   - BCM error code.
   1101  */
   1102 int _bcm_xgs5_collector_get(int unit,
   1103                              bcm_collector_t id,
   1104                              bcm_collector_info_t *collector_info)
   1105 {
   1106     int rv = BCM_E_NONE;
   1107 
   1108     if (collectors_info_list[unit] == NULL) {
   1109         return BCM_E_INIT;
   1110     }
   1111 
   1112     /* Ensure collector_info is not NULL */
   1113     if (collector_info == NULL) {
   1114         return BCM_E_PARAM;
   1115     }
   1116 
   1117     /* Get the collector info from the list
   1118      * using ID.
   1119      */
   1120     rv = _bcm_xgs5_collector_list_collector_get(unit, id,
   1121                                                    collector_info);
   1122 
   1123     /* If not found, return BCM_E_NOT_FOUND */
   1124     if (BCM_FAILURE(rv)) {
   1125         return rv;
   1126     }
   1127 
   1128     return BCM_E_NONE;
   1129 }
   1130 
   1131 /*
   1132  * Function:
   1133  *      _bcm_xgs5_collector_get_ids_all
   1134  * Purpose:
   1135  *      Get the ID list of all collectors configured.
   1136  * Parameters:
   1137  *      unit                 - (IN)  BCM device number
   1138  *      max_size             - (IN)  Size of the collector list array
   1139  *      collector_list       - (OUT) Collector id list
   1140  *      list_szie            - (OUT) NUmber of elements in the list
   1141  * Returns:
   1142  *      BCM_E_XXX   - BCM error code.
   1143  */
   1144 int _bcm_xgs5_collector_ids_get_all(
   1145                            int unit,
   1146                            int max_size,
   1147                            bcm_collector_t *collector_list,
   1148                            int *list_size)
   1149 {
   1150     int i;
   1151     int num_collectors;
   1152 
   1153     if (collectors_info_list[unit] == NULL) {
   1154         return BCM_E_INIT;
   1155     }
   1156 
   1157     /* If the max_size is non zero and list == NULL, return
   1158      * BCM_E_PARAM.
   1159      */
   1160     if (max_size != 0 && collector_list == NULL) {
   1161         return BCM_E_PARAM;
   1162     }
   1163 
   1164     num_collectors = 0;
   1165     *list_size = 0;
   1166     for (i = BCM_INT_COLLECTOR_COLLECTOR_START_ID;
   1167          i <= BCM_INT_COLLECTOR_COLLECTOR_END_ID; i++) {
   1168         if (collectors_info_list[unit][i].collector_id == i) {
   1169             /* Collector exists */
   1170             num_collectors++;
   1171             if (*list_size < max_size) {
   1172                 collector_list[*list_size] = i;
   1173                 (*list_size)++;
   1174             }
   1175         }
   1176     }
   1177 
   1178     /* If the max_size is 0 then return the number of collectors configured in
   1179      * list_size
   1180      */
   1181     if (max_size == 0) {
   1182         *list_size = num_collectors;
   1183         return BCM_E_NONE;
   1184     }
   1185 
   1186     return BCM_E_NONE;
   1187 }
   1188 
   1189 /*
   1190  * Function:
   1191  *      _bcm_xgs5_collector_destroy
   1192  * Purpose:
   1193  *      Destroys a collector
   1194  * Parameters:
   1195  *      unit           - (IN)  BCM device number
   1196  *      id             - (IN) Collector Id
   1197  * Returns:
   1198  *      BCM_E_XXX   - BCM error code.
   1199  */
   1200 int _bcm_xgs5_collector_destroy(int unit,
   1201                                  bcm_collector_t id)
   1202 {
   1203     int rv = BCM_E_NONE;
   1204      _bcm_collector_global_info_t *collector_per_unit_global_info =
   1205                             COLLECTOR_GLOBAL_INFO_GET(unit);
   1206 
   1207     if (collector_per_unit_global_info == NULL) {
   1208         LOG_ERROR(BSL_LS_BCM_COLLECTOR,
   1209                 (BSL_META_U(unit,
   1210                             "COLLECTOR(unit %d) Error: collector"
   1211                             " module is not initialized"), unit));
   1212         return BCM_E_INIT;
   1213     }
   1214 
   1215     if (collectors_info_list[unit] == NULL) {
   1216         return BCM_E_INIT;
   1217     }
   1218 
   1219     if (id > BCM_INT_COLLECTOR_COLLECTOR_END_ID) {
   1220         return BCM_E_PARAM;
   1221     }
   1222 
   1223     if (collectors_info_list[unit][id].ref_count != 0) {
   1224         LOG_ERROR(BSL_LS_BCM_COLLECTOR,
   1225                   (BSL_META_U(unit,
   1226                               "COLLECTOR(unit %d) Error: Collector in use\n"),
   1227                    unit));
   1228         return BCM_E_EXISTS;
   1229     }
   1230 
   1231     /* Delete the collector from the collector list with
   1232      * given ID.
   1233      */
   1234     rv = _bcm_xgs5_collector_list_collector_delete(unit, id);
   1235     /* If not found in the list, return BCM_E_NOT_FOUND */
   1236     if (BCM_FAILURE(rv)) {
   1237         return rv;
   1238     }
   1239 
   1240     /* Free up the ID from the pool */
   1241     BCM_IF_ERROR_RETURN(
   1242         shr_idxres_list_free(
   1243                    collector_per_unit_global_info->collector_pool, id));
   1244 
   1245     return BCM_E_NONE;
   1246 }
   1247 
   1248 /*
   1249  * Function:
   1250  *     _bcm_xgs5_collector_export_record_register
   1251  * Description:
   1252  *     To register the callback function for flow info export
   1253  * Parameters:
   1254  *     unit          device number
   1255  *     callback      user callback function
   1256  *     userdata      user data used as argument during callback
   1257  * Return:
   1258  *     BCM_E_NONE
   1259  *     BCM_E_PARAM
   1260  *     BCM_E_RESOURCE
   1261  *     BCM_E_UNAVAIL
   1262  */
   1263 int
   1264 _bcm_xgs5_collector_export_record_register(
   1265     int unit,
   1266     bcm_collector_t collector_id,
   1267     bcm_collector_callback_options_t callback_options,
   1268     bcm_collector_export_record_cb_f callback_fn,
   1269     void *userdata)
   1270 {
   1271     int rv = BCM_E_UNAVAIL;
   1272 
   1273 #if defined (BCM_FLOWTRACKER_SUPPORT)
   1274     bcm_flowtracker_collector_t ft_collector_id;
   1275     bcm_flowtracker_collector_callback_options_t ft_callback_options;
   1276     bcm_flowtracker_export_record_cb_f ft_callback_fn;
   1277 #endif /* BCM_FLOWTRACKER_SUPPORT */
   1278 
   1279 #if defined (BCM_FLOWTRACKER_SUPPORT)
   1280     if (soc_feature(unit, soc_feature_bscan_ft_fifodma_support)) {
   1281         ft_collector_id = collector_id;
   1282         ft_callback_fn = (bcm_flowtracker_export_record_cb_f)callback_fn;
   1283         sal_memcpy(&ft_callback_options, &callback_options,
   1284                    sizeof(bcm_collector_callback_options_t));
   1285 
   1286         rv = bcmi_ft_export_record_register(unit,
   1287                                             ft_collector_id,
   1288                                             ft_callback_options,
   1289                                             ft_callback_fn,
   1290                                             userdata);
   1291     }
   1292 #endif /* BCM_FLOWTRACKER_SUPPORT */
   1293 
   1294     return rv;
   1295 }
   1296 
   1297 
   1298 /*
   1299  * Function:
   1300  *     _bcm_xgs5_collector_export_record_unregister
   1301  * Description:
   1302  *     To unregister the callback function for flow info export
   1303  * Parameters:
   1304  *     unit          device number
   1305  *     callback      user callback function
   1306  *     userdata      user data used as argument during callback
   1307  * Return:
   1308  *     BCM_E_NONE
   1309  *     BCM_E_NOT_FOUND
   1310  *     BCM_E_UNAVAIL
   1311  *     BCM_E_INIT
   1312  */
   1313 int
   1314 _bcm_xgs5_collector_export_record_unregister(
   1315     int unit,
   1316     bcm_collector_t collector_id,
   1317     bcm_collector_callback_options_t callback_options,
   1318     bcm_collector_export_record_cb_f callback_fn)
   1319 {
   1320     int rv = BCM_E_UNAVAIL;
   1321 
   1322 #if defined (BCM_FLOWTRACKER_SUPPORT)
   1323     bcm_flowtracker_collector_t ft_collector_id;
   1324     bcm_flowtracker_collector_callback_options_t ft_callback_options;
   1325     bcm_flowtracker_export_record_cb_f ft_callback_fn;
   1326 #endif /* BCM_FLOWTRACKER_SUPPORT */
   1327 
   1328 #if defined (BCM_FLOWTRACKER_SUPPORT)
   1329     if (soc_feature(unit, soc_feature_bscan_ft_fifodma_support)) {
   1330         ft_collector_id = collector_id;
   1331         ft_callback_fn = (bcm_flowtracker_export_record_cb_f)callback_fn;
   1332         sal_memcpy(&ft_callback_options, &callback_options,
   1333                    sizeof(bcm_collector_callback_options_t));
   1334 
   1335         rv = bcmi_ft_export_record_unregister(unit,
   1336                                               ft_collector_id,
   1337                                               ft_callback_options,
   1338                                               ft_callback_fn);
   1339     }
   1340 #endif /* BCM_FLOWTRACKER_SUPPORT */
   1341 
   1342     return rv;
   1343 }
   1344 
   1345 
   1346 
   1347 
   1348 /*
   1349  * Function:
   1350  *     _bcm_xgs5_collector_ref_count_update
   1351  * Purpose:
   1352  *     Increment/Decrement reference count for a collector
   1353  * Parameters:
   1354  *     unit          - (IN) BCM device number
   1355  *     id            - (IN) Collector Id
   1356  *     update        - (IN) Reference count update (+/-)
   1357  * Returns:
   1358  *     BCM_E_XXX
   1359  */
   1360 int
   1361 _bcm_xgs5_collector_ref_count_update(int unit, bcm_collector_t id, int update)
   1362 {
   1363     if (id > BCM_INT_COLLECTOR_COLLECTOR_END_ID) {
   1364         return BCM_E_PARAM;
   1365     }
   1366 
   1367     if ((collectors_info_list[unit][id].ref_count + update) < 0) {
   1368         return BCM_E_PARAM;
   1369     }
   1370     collectors_info_list[unit][id].ref_count += update;
   1371 
   1372     if (collectors_info_list[unit][id].ref_count == 0) {
   1373         collectors_info_list[unit][id].user = _BCM_COLLECTOR_EXPORT_APP_NONE ;
   1374     }
   1375 
   1376     return BCM_E_NONE;
   1377 }
   1378 
   1379 /*
   1380  * Function:
   1381  *     _bcm_xgs5_collector_ref_count_get
   1382  * Purpose:
   1383  *     Get reference count for a collector
   1384  * Parameters:
   1385  *     unit          - (IN) BCM device number
   1386  *     id            - (IN) Collector Id
   1387  * Returns:
   1388  *     Reference count
   1389  */
   1390 int
   1391 _bcm_xgs5_collector_ref_count_get(int unit, bcm_collector_t id)
   1392 {
   1393     if (id > BCM_INT_COLLECTOR_COLLECTOR_END_ID) {
   1394         return 0;
   1395     }
   1396     return (collectors_info_list[unit][id].ref_count);
   1397 }
   1398 
   1399 /*
   1400  * Function:
   1401  *     _bcm_xgs5_collector_user_update
   1402  * Purpose:
   1403  *     Update the user for the collector.
   1404  * Parameters:
   1405  *     unit          - (IN) BCM device number
   1406  *     id            - (IN) Collector Id
   1407  *     user          - (IN) The user type of the calling app.
   1408  * Returns:
   1409  *     BCM_E_XXX
   1410  */
   1411 int
   1412 _bcm_xgs5_collector_user_update(int unit, bcm_collector_t id, _bcm_collector_export_app_t user)
   1413 {
   1414     if (id > BCM_INT_COLLECTOR_COLLECTOR_END_ID) {
   1415         return BCM_E_PARAM;
   1416     }
   1417 
   1418     collectors_info_list[unit][id].user = user;
   1419 
   1420     return BCM_E_NONE;
   1421 }
   1422 
   1423 /*
   1424  * Function:
   1425  *     _bcm_xgs5_collector_check_user_is_other
   1426  * Purpose:
   1427  *      Check if collector ID is used by other user.
   1428  * Parameters:
   1429  *     unit          - (IN) BCM device number
   1430  *     id            - (IN) Collector Id
   1431  *     my_user       - (IN) The user type of the calling app.
   1432  * Returns:
   1433  *     BCM_E_XXX
   1434  */
   1435 uint8
   1436 _bcm_xgs5_collector_check_user_is_other(int unit, bcm_collector_t id, _bcm_collector_export_app_t my_user)
   1437 {
   1438     if (id > BCM_INT_COLLECTOR_COLLECTOR_END_ID) {
   1439         return 0;
   1440     }
   1441 
   1442     if ((collectors_info_list[unit][id].user != _BCM_COLLECTOR_EXPORT_APP_NONE) &&
   1443         (collectors_info_list[unit][id].user != my_user)) {
   1444         return 1;
   1445     }
   1446 
   1447     return 0;
   1448 }
   1449 #ifdef BCM_WARM_BOOT_SUPPORT
   1450 
   1451 #define BCM_WB_COLLECTOR_VERSION_1_0      SOC_SCACHE_VERSION(1,0)
   1452 #define BCM_WB_COLLECTOR_VERSION_1_1      SOC_SCACHE_VERSION(1,1)
   1453 /* Added sync/recover for ipfix related fields in collector info. */
   1454 #define BCM_WB_COLLECTOR_VERSION_1_2      SOC_SCACHE_VERSION(1,2)
   1455 /* Added sync/recover for ProtoBuf related fields in collector info. */
   1456 #define BCM_WB_COLLECTOR_VERSION_1_3      SOC_SCACHE_VERSION(1,3)
   1457 /* Added sync/recover for Collector Type in collector info */
   1458 #define BCM_WB_COLLECTOR_VERSION_1_4      SOC_SCACHE_VERSION(1,4)
   1459 #define BCM_WB_COLLECTOR_DEFAULT_VERSION  BCM_WB_COLLECTOR_VERSION_1_4
   1460 
   1461 #define COLLECTOR_SCACHE_WRITE(_scache, _val, _type)                     \
   1462     do {                                                          \
   1463         _type _tmp = (_type) (_val);                              \
   1464         sal_memcpy((_scache), &(_tmp), sizeof(_type));            \
   1465         (_scache) += sizeof(_type);                               \
   1466     } while(0)
   1467 
   1468 #define COLLECTOR_SCACHE_READ(_scache, _var, _type)                      \
   1469     do {                                                          \
   1470         _type _tmp;                                               \
   1471         sal_memcpy(&(_tmp), (_scache), sizeof(_type));            \
   1472         (_scache) += sizeof(_type);                               \
   1473         (_var)     = (_tmp);                                      \
   1474     } while(0)
   1475 
   1476 /* Collector flags to be written in scache */
   1477 #define _BCM_COLLECTOR_WB_FLAGS_L4_CHECKSUM_ENABLE (1 << 0)
   1478 
   1479 /*
   1480  * Function:
   1481  *     _bcm_collector_info_sync
   1482  * Purpose:
   1483  *     Syncs all collectors information to scache
   1484  * Parameters:
   1485  *     unit   - (IN) Device unit number
   1486  *     scache - (IN) Pointer to current scache location
   1487  * Returns:
   1488  *     BCM_E_XXX
   1489  */
   1490 STATIC void
   1491 _bcm_collector_info_sync(int unit, uint8 **scache)
   1492 {
   1493 
   1494     int i, j;
   1495     _bcm_collector_info_t *collector_list = collectors_info_list[unit];
   1496     _bcm_collector_info_t *collector = NULL;
   1497     _bcm_collector_export_profile_info_t *export_profiles_list =
   1498                                      export_profiles_info_list[unit];
   1499     _bcm_collector_export_profile_info_t *export_profile = NULL;
   1500     uint32 collector_alloc_count = 0, export_profile_alloc_count = 0;
   1501     _bcm_collector_global_info_t  *collector_per_unit_global_info =
   1502                                     COLLECTOR_GLOBAL_INFO_GET(unit);
   1503     uint32 first, last, validLow, validHigh, freeCount;
   1504     uint32 flags;
   1505 
   1506     shr_idxres_list_state(collector_per_unit_global_info->collector_pool,
   1507             &first, &last,
   1508             &validLow, &validHigh,
   1509             &freeCount, &collector_alloc_count);
   1510     shr_idxres_list_state(collector_per_unit_global_info->export_profile_pool,
   1511             &first, &last,
   1512             &validLow, &validHigh,
   1513             &freeCount, &export_profile_alloc_count);
   1514 
   1515     /* Number of collectors configured */
   1516     COLLECTOR_SCACHE_WRITE(*scache, collector_alloc_count, uint32);
   1517 
   1518     /* Number of collector export profiles configured */
   1519     COLLECTOR_SCACHE_WRITE(*scache, export_profile_alloc_count, uint32);
   1520 
   1521     for (i = BCM_INT_COLLECTOR_COLLECTOR_START_ID;
   1522          i <= BCM_INT_COLLECTOR_COLLECTOR_END_ID; i++) {
   1523 
   1524         collector = &(collector_list[i]);
   1525 
   1526         if (collector->collector_id == BCM_COLLECTOR_INVALID_INDEX) {
   1527             /* Collector does not exist, continue */
   1528             continue;
   1529         }
   1530 
   1531         /* Collector Id */
   1532         COLLECTOR_SCACHE_WRITE(*scache, collector->collector_id, uint16);
   1533 
   1534         /* Transport type */
   1535         COLLECTOR_SCACHE_WRITE(*scache,
   1536                                collector->collector_info.transport_type,
   1537                                uint16);
   1538 
   1539         /* Dst mac addr */
   1540         for (j = 0; j < 6; j++) {
   1541             COLLECTOR_SCACHE_WRITE(*scache,
   1542                                    collector->collector_info.eth.dst_mac[j],
   1543                                    uint8);
   1544         }
   1545 
   1546         /* Src mac addr */
   1547         for (j = 0; j < 6; j++) {
   1548             COLLECTOR_SCACHE_WRITE(*scache,
   1549                                    collector->collector_info.eth.src_mac[j],
   1550                                    uint8);
   1551         }
   1552 
   1553         /* Vlan tag structure */
   1554         COLLECTOR_SCACHE_WRITE(*scache,
   1555                                collector->collector_info.eth.vlan_tag_structure,
   1556                                uint8);
   1557 
   1558         /* Outer TPID */
   1559         COLLECTOR_SCACHE_WRITE(*scache,
   1560                                collector->collector_info.eth.outer_tpid,
   1561                                uint16);
   1562 
   1563         /* Inner TPID */
   1564         COLLECTOR_SCACHE_WRITE(*scache,
   1565                                collector->collector_info.eth.inner_tpid,
   1566                                uint16);
   1567 
   1568         /* Outer vlan tag */
   1569         COLLECTOR_SCACHE_WRITE(*scache,
   1570                                collector->collector_info.eth.outer_vlan_tag,
   1571                                uint32);
   1572 
   1573         /* Inner vlan tag */
   1574         COLLECTOR_SCACHE_WRITE(*scache,
   1575                                collector->collector_info.eth.inner_vlan_tag,
   1576                                uint32);
   1577 
   1578         if(collector->collector_info.transport_type ==
   1579                        bcmCollectorTransportTypeIpv4Udp) {
   1580             /* Src IP */
   1581             COLLECTOR_SCACHE_WRITE(*scache,
   1582                     collector->collector_info.ipv4.src_ip, uint32);
   1583 
   1584             /* Dst IP */
   1585             COLLECTOR_SCACHE_WRITE(*scache,
   1586                     collector->collector_info.ipv4.dst_ip, uint32);
   1587 
   1588             /* DSCP */
   1589             COLLECTOR_SCACHE_WRITE(*scache,
   1590                     collector->collector_info.ipv4.dscp, uint8);
   1591 
   1592             /* TTL */
   1593             COLLECTOR_SCACHE_WRITE(*scache,
   1594                     collector->collector_info.ipv4.ttl, uint8);
   1595         }
   1596         else
   1597         {
   1598             /* Src IP */
   1599             for (j = 0; j < 16; j++) {
   1600                 COLLECTOR_SCACHE_WRITE(*scache,
   1601                         collector->collector_info.ipv6.src_ip[j],
   1602                         uint8);
   1603             }
   1604 
   1605             /* Dst IP */
   1606             for (j = 0; j < 16; j++) {
   1607                 COLLECTOR_SCACHE_WRITE(*scache,
   1608                         collector->collector_info.ipv6.dst_ip[j],
   1609                         uint8);
   1610             }
   1611 
   1612             /* Traffic class */
   1613             COLLECTOR_SCACHE_WRITE(*scache,
   1614                     collector->collector_info.ipv6.traffic_class, uint8);
   1615             /* Flow label */
   1616             COLLECTOR_SCACHE_WRITE(*scache,
   1617                     collector->collector_info.ipv6.flow_label, uint32);
   1618             /* Hop limit */
   1619             COLLECTOR_SCACHE_WRITE(*scache,
   1620                     collector->collector_info.ipv6.hop_limit, uint8);
   1621         }
   1622 
   1623         /* Src port */
   1624         COLLECTOR_SCACHE_WRITE(*scache,
   1625                                collector->collector_info.udp.src_port, uint16);
   1626 
   1627         /* Dst port */
   1628         COLLECTOR_SCACHE_WRITE(*scache,
   1629                                collector->collector_info.udp.dst_port, uint16);
   1630 
   1631     }
   1632 
   1633     for (i = BCM_INT_COLLECTOR_EXPORT_PROFILE_START_ID;
   1634          i <= BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID; i++) {
   1635 
   1636         export_profile = &(export_profiles_list[i]);
   1637 
   1638         if (export_profile->export_profile_id == BCM_COLLECTOR_INVALID_INDEX) {
   1639             /* Collector export profile does not exist, continue */
   1640             continue;
   1641         }
   1642 
   1643        /* Collector export profile Id */
   1644         COLLECTOR_SCACHE_WRITE(*scache,
   1645                                export_profile->export_profile_id, uint16);
   1646 
   1647         /* Collector export profile wire format */
   1648         COLLECTOR_SCACHE_WRITE(*scache,
   1649                    export_profile->export_profile_info.wire_format, uint32);
   1650  
   1651         /* Collector export profile export interval */
   1652         COLLECTOR_SCACHE_WRITE(*scache,
   1653                    export_profile->export_profile_info.export_interval, uint32);
   1654 
   1655         /* Collector export profile max packet length or num records */
   1656         if (export_profile->export_profile_info.flags &
   1657                             BCM_COLLECTOR_EXPORT_PROFILE_FLAGS_USE_NUM_RECORDS) {
   1658             COLLECTOR_SCACHE_WRITE(*scache,
   1659                                    export_profile->export_profile_info.num_records,
   1660                                    uint32);
   1661         } else {
   1662             COLLECTOR_SCACHE_WRITE(*scache,
   1663                                    export_profile->export_profile_info.max_packet_length,
   1664                                    uint32);
   1665         }
   1666      }
   1667 
   1668     for (i = BCM_INT_COLLECTOR_COLLECTOR_START_ID;
   1669          i <= BCM_INT_COLLECTOR_COLLECTOR_END_ID; i++) {
   1670 
   1671         collector = &(collector_list[i]);
   1672 
   1673         if (collector->collector_id == BCM_COLLECTOR_INVALID_INDEX) {
   1674             /* Collector does not exist, continue */
   1675             continue;
   1676         }
   1677 
   1678         /* Collector Id */
   1679         COLLECTOR_SCACHE_WRITE(*scache, collector->collector_id, uint16);
   1680 
   1681         flags = 0;
   1682         if((collector->collector_info.transport_type ==
   1683                                            bcmCollectorTransportTypeIpv4Udp) ||
   1684            (collector->collector_info.transport_type ==
   1685                                            bcmCollectorTransportTypeIpv6Udp)) {
   1686 
   1687             if (collector->collector_info.udp.flags &
   1688                                        BCM_COLLECTOR_UDP_FLAGS_CHECKSUM_ENABLE) {
   1689                 flags |= _BCM_COLLECTOR_WB_FLAGS_L4_CHECKSUM_ENABLE;
   1690             }
   1691         }
   1692         /* Collector flags */
   1693         COLLECTOR_SCACHE_WRITE(*scache, flags, uint32);
   1694     }
   1695 
   1696     for (i = BCM_INT_COLLECTOR_EXPORT_PROFILE_START_ID;
   1697          i <= BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID; i++) {
   1698 
   1699         export_profile = &(export_profiles_list[i]);
   1700 
   1701         if (export_profile->export_profile_id == BCM_COLLECTOR_INVALID_INDEX) {
   1702             /* Collector export profile does not exist, continue */
   1703             continue;
   1704         }
   1705 
   1706         /* Collector export profile Id */
   1707         COLLECTOR_SCACHE_WRITE(*scache,
   1708                                export_profile->export_profile_id, uint16);
   1709 
   1710         /* Export profile flags */
   1711         COLLECTOR_SCACHE_WRITE(*scache,
   1712                                export_profile->export_profile_info.flags, uint32);
   1713 
   1714     }
   1715 
   1716     /* Scache v2 sync */
   1717     for (i = BCM_INT_COLLECTOR_COLLECTOR_START_ID;
   1718          i <= BCM_INT_COLLECTOR_COLLECTOR_END_ID; i++) {
   1719 
   1720         collector = &(collector_list[i]);
   1721 
   1722         if (collector->collector_id == BCM_COLLECTOR_INVALID_INDEX) {
   1723             /* Collector does not exist, continue */
   1724             continue;
   1725         }
   1726 
   1727         /* Collector Id */
   1728         COLLECTOR_SCACHE_WRITE(*scache, collector->collector_id, uint16);
   1729 
   1730         /* Ipfix Protocol version */
   1731         COLLECTOR_SCACHE_WRITE(*scache,
   1732                                collector->collector_info.ipfix.version, int);
   1733 
   1734         /* Ipfix Initial sequence number */
   1735         COLLECTOR_SCACHE_WRITE(*scache,
   1736                 collector->collector_info.ipfix.initial_sequence_num, int);
   1737     }
   1738 
   1739     /* Scache v3 sync */
   1740     for (i = BCM_INT_COLLECTOR_COLLECTOR_START_ID;
   1741          i <= BCM_INT_COLLECTOR_COLLECTOR_END_ID; i++) {
   1742 
   1743         collector = &(collector_list[i]);
   1744 
   1745         if (collector->collector_id == BCM_COLLECTOR_INVALID_INDEX) {
   1746             /* Collector does not exist, continue */
   1747             continue;
   1748         }
   1749 
   1750         /* System Id length */
   1751         COLLECTOR_SCACHE_WRITE(*scache,
   1752                                collector->collector_info.protobuf.system_id_length, int);
   1753 
   1754         /* System Id */
   1755         for (j = 0; j < collector->collector_info.protobuf.system_id_length; j++) {
   1756             COLLECTOR_SCACHE_WRITE(*scache,
   1757                     collector->collector_info.protobuf.system_id[j],
   1758                     uint8);
   1759         }
   1760 
   1761         /* Component Id */
   1762         COLLECTOR_SCACHE_WRITE(*scache,
   1763                                collector->collector_info.protobuf.component_id, uint32);
   1764 
   1765     }
   1766 
   1767     /* Scache v4 sync */
   1768     for (i = BCM_INT_COLLECTOR_COLLECTOR_START_ID;
   1769          i <= BCM_INT_COLLECTOR_COLLECTOR_END_ID; i++) {
   1770 
   1771         collector = &(collector_list[i]);
   1772 
   1773         if (collector->collector_id == BCM_COLLECTOR_INVALID_INDEX) {
   1774             /* Collector does not exist, continue */
   1775             continue;
   1776         }
   1777 
   1778         /* Collector Type */
   1779         COLLECTOR_SCACHE_WRITE(*scache,
   1780                                collector->collector_info.collector_type, int);
   1781     }
   1782 }
   1783 
   1784 /*
   1785  * Function:
   1786  *     _bcm_xgs5_collector_sync
   1787  * Purpose:
   1788  *     Syncs Collector data to scache
   1789  * Parameters:
   1790  *     unit   - (IN) Device unit number
   1791  * Returns:
   1792  *     BCM_E_XXX
   1793  */
   1794 int
   1795 _bcm_xgs5_collector_sync(int unit)
   1796 {
   1797 
   1798     int                     stable_size;
   1799     soc_scache_handle_t     scache_handle;
   1800     uint8                  *scache = NULL;
   1801     _bcm_collector_global_info_t  *collector_per_unit_global_info =
   1802                                     COLLECTOR_GLOBAL_INFO_GET(unit);
   1803 
   1804     if (collector_per_unit_global_info == NULL) {
   1805         return BCM_E_NONE;
   1806     }
   1807 
   1808     /* Get Collector module storage size. */
   1809     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
   1810 
   1811     /* If level 2 store is not configured return from here. */
   1812     if (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) || (stable_size == 0)) {
   1813         return BCM_E_NONE;
   1814     }
   1815 
   1816     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COLLECTOR, 0);
   1817     BCM_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, scache_handle, 0, 0,
   1818                                                 &scache,
   1819                                                 BCM_WB_COLLECTOR_DEFAULT_VERSION,
   1820                                                 NULL));
   1821     if (NULL == scache) {
   1822         return BCM_E_INTERNAL;
   1823     }
   1824 
   1825     _bcm_collector_info_sync(unit, &scache);
   1826 
   1827     return BCM_E_NONE;
   1828 }
   1829 
   1830 /*
   1831  * Function:
   1832  *     _bcm_collector_recover
   1833  * Purpose:
   1834  *     Recover Collector data from scache
   1835  * Parameters:
   1836  *     unit          - (IN) Device unit number
   1837  *     recovered_ver - (IN) Recovered version
   1838  *     scache        - (IN) Pointer to current scache location
   1839  * Returns:
   1840  *     BCM_E_XXX
   1841  */
   1842 STATIC int
   1843 _bcm_collector_recover(int unit, uint16 recovered_ver, uint8 **scache)
   1844 {
   1845     int i = 0, j = 0;
   1846     int rv;
   1847     int recovered_count = 0;
   1848     uint16 collector_id;
   1849     uint16 collector_export_profile_id;
   1850     shr_idxres_element_t tmp_id = 0;
   1851     _bcm_collector_global_info_t *collector_per_unit_global_info =
   1852                                     COLLECTOR_GLOBAL_INFO_GET(unit);
   1853     _bcm_collector_info_t *collector = NULL;
   1854     _bcm_collector_export_profile_info_t *export_profile = NULL;
   1855     uint32 collector_alloc_count = 0, export_profile_alloc_count = 0;
   1856     uint32 flags;
   1857 
   1858     /* Number of collectors configured */
   1859     COLLECTOR_SCACHE_READ(*scache, collector_alloc_count, uint32);
   1860 
   1861     /* Number of collector export profiles configured */
   1862     COLLECTOR_SCACHE_READ(*scache, export_profile_alloc_count, uint32);
   1863 
   1864     /* Note that from v1.3 onwards, we are not syncing collector id
   1865      * per warmboot version and relying on collector Id from this loop v1.0
   1866      * This shall save scache memory for syncing/recovering relevant info
   1867      * per warmboot version.
   1868      */
   1869     for (i = 0; i< collector_alloc_count; i++) {
   1870 
   1871         /* Collector Id */
   1872         COLLECTOR_SCACHE_READ(*scache, collector_id, uint16);
   1873         if (collector_id > BCM_INT_COLLECTOR_COLLECTOR_END_ID)
   1874         {
   1875             LOG_ERROR(BSL_LS_BCM_COLLECTOR,
   1876                   (BSL_META_U(unit,
   1877                   "COLLECTOR(unit %d) Info: Recoved collector Id"
   1878                   " %d out of range"), unit,
   1879                   collector_id));
   1880             return BCM_E_INTERNAL;
   1881         }
   1882         collector = &(collectors_info_list[unit][collector_id]);
   1883 
   1884         collector->collector_id = collector_id;
   1885         tmp_id = collector_id;
   1886         rv = shr_idxres_list_reserve(
   1887                             collector_per_unit_global_info->collector_pool,
   1888                             tmp_id, tmp_id);
   1889         BCM_IF_ERROR_RETURN(rv);
   1890 
   1891         /* Transport type */
   1892         COLLECTOR_SCACHE_READ(*scache, collector->collector_info.transport_type,
   1893                               uint16);
   1894         /* Dst mac addr */
   1895         for (j = 0; j < 6; j++) {
   1896             COLLECTOR_SCACHE_READ(*scache,
   1897                                   collector->collector_info.eth.dst_mac[j],
   1898                                   uint8);
   1899         }
   1900 
   1901         /* Src mac addr */
   1902         for (j = 0; j < 6; j++) {
   1903             COLLECTOR_SCACHE_READ(*scache,
   1904                                   collector->collector_info.eth.src_mac[j],
   1905                                   uint8);
   1906         }
   1907 
   1908         /* Vlan tag structure */
   1909         COLLECTOR_SCACHE_READ(*scache,
   1910                               collector->collector_info.eth.vlan_tag_structure,
   1911                               uint8);
   1912 
   1913         /* Outer TPID */
   1914         COLLECTOR_SCACHE_READ(*scache,
   1915                               collector->collector_info.eth.outer_tpid, uint16);
   1916 
   1917         /* Inner TPID */
   1918         COLLECTOR_SCACHE_READ(*scache,
   1919                               collector->collector_info.eth.inner_tpid, uint16);
   1920 
   1921         /* Outer vlan tag */
   1922         COLLECTOR_SCACHE_READ(*scache,
   1923                               collector->collector_info.eth.outer_vlan_tag,
   1924                               uint32);
   1925 
   1926         /* Inner vlan tag */
   1927         COLLECTOR_SCACHE_READ(*scache,
   1928                               collector->collector_info.eth.inner_vlan_tag,
   1929                               uint32);
   1930 
   1931         if(collector->collector_info.transport_type ==
   1932                        bcmCollectorTransportTypeIpv4Udp) {
   1933             /* Src IP */
   1934             COLLECTOR_SCACHE_READ(*scache,
   1935                     collector->collector_info.ipv4.src_ip, uint32);
   1936 
   1937             /* Dst IP */
   1938             COLLECTOR_SCACHE_READ(*scache,
   1939                     collector->collector_info.ipv4.dst_ip, uint32);
   1940 
   1941             /* DSCP */
   1942             COLLECTOR_SCACHE_READ(*scache,
   1943                     collector->collector_info.ipv4.dscp, uint8);
   1944 
   1945             /* TTL */
   1946             COLLECTOR_SCACHE_READ(*scache,
   1947                     collector->collector_info.ipv4.ttl, uint8);
   1948         }
   1949         else
   1950         {
   1951             /* Src IP */
   1952             for (j = 0; j < 16; j++) {
   1953                 COLLECTOR_SCACHE_READ(*scache,
   1954                         collector->collector_info.ipv6.src_ip[j],
   1955                         uint8);
   1956             }
   1957 
   1958             /* Dst IP */
   1959             for (j = 0; j < 16; j++) {
   1960                 COLLECTOR_SCACHE_READ(*scache,
   1961                         collector->collector_info.ipv6.dst_ip[j],
   1962                         uint8);
   1963             }
   1964 
   1965             /* Traffic class */
   1966             COLLECTOR_SCACHE_READ(*scache,
   1967                     collector->collector_info.ipv6.traffic_class, uint8);
   1968             /* Flow label */
   1969             COLLECTOR_SCACHE_READ(*scache,
   1970                     collector->collector_info.ipv6.flow_label, uint32);
   1971             /* Hop limit */
   1972             COLLECTOR_SCACHE_READ(*scache,
   1973                     collector->collector_info.ipv6.hop_limit, uint8);
   1974         }
   1975 
   1976         /* Src port */
   1977         COLLECTOR_SCACHE_READ(*scache,
   1978                               collector->collector_info.udp.src_port, uint16);
   1979 
   1980         /* Dst port */
   1981         COLLECTOR_SCACHE_READ(*scache,
   1982                               collector->collector_info.udp.dst_port, uint16);
   1983 
   1984     }
   1985 
   1986     for (i = 0;
   1987          i < export_profile_alloc_count; i++) {
   1988 
   1989 
   1990         /* Collector export profile Id */
   1991         COLLECTOR_SCACHE_READ(*scache,
   1992                               collector_export_profile_id, uint16);
   1993         if (collector_export_profile_id >
   1994                    BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID)
   1995         {
   1996             return BCM_E_INTERNAL;
   1997         }
   1998         export_profile = 
   1999              &(export_profiles_info_list[unit][collector_export_profile_id]);
   2000 
   2001         export_profile->export_profile_id = collector_export_profile_id;
   2002 
   2003         tmp_id = collector_export_profile_id;
   2004         rv = shr_idxres_list_reserve(
   2005                             collector_per_unit_global_info->export_profile_pool,
   2006                             tmp_id, tmp_id);
   2007         BCM_IF_ERROR_RETURN(rv);
   2008 
   2009         /* Collector export profile wire format */
   2010         COLLECTOR_SCACHE_READ(*scache,
   2011                    export_profile->export_profile_info.wire_format, uint32);
   2012  
   2013         /* Collector export profile export interval */
   2014         COLLECTOR_SCACHE_READ(*scache,
   2015                    export_profile->export_profile_info.export_interval, uint32);
   2016         
   2017         /* Collector export profile max packet length */
   2018         COLLECTOR_SCACHE_READ(*scache,
   2019                  export_profile->export_profile_info.max_packet_length, uint32);
   2020      }   
   2021 
   2022     if (recovered_ver >= BCM_WB_COLLECTOR_VERSION_1_1) {
   2023         /* Scache v1 recovery */
   2024         for (i = 0; i< collector_alloc_count; i++) {
   2025 
   2026             /* Collector Id */
   2027             COLLECTOR_SCACHE_READ(*scache, collector_id, uint16);
   2028             if (collector_id > BCM_INT_COLLECTOR_COLLECTOR_END_ID)
   2029                 {
   2030                     LOG_ERROR(BSL_LS_BCM_COLLECTOR,
   2031                               (BSL_META_U(unit,
   2032                                           "COLLECTOR(unit %d) Info: Recoved collector Id"
   2033                                           " %d out of range"), unit,
   2034                                collector_id));
   2035                     return BCM_E_INTERNAL;
   2036                 }
   2037             collector = &(collectors_info_list[unit][collector_id]);
   2038 
   2039             /* Flags */
   2040             COLLECTOR_SCACHE_READ(*scache, flags, uint32);
   2041 
   2042             if (flags & _BCM_COLLECTOR_WB_FLAGS_L4_CHECKSUM_ENABLE) {
   2043                 collector->collector_info.udp.flags |= BCM_COLLECTOR_UDP_FLAGS_CHECKSUM_ENABLE;
   2044             }
   2045         }
   2046 
   2047         for (i = 0; i < export_profile_alloc_count; i++) {
   2048             /* Collector export profile Id */
   2049             COLLECTOR_SCACHE_READ(*scache,
   2050                                   collector_export_profile_id, uint16);
   2051             if (collector_export_profile_id > BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID) {
   2052                     return BCM_E_INTERNAL;
   2053             }
   2054             export_profile =
   2055                 &(export_profiles_info_list[unit][collector_export_profile_id]);
   2056             COLLECTOR_SCACHE_READ(*scache,
   2057                                   export_profile->export_profile_info.flags,
   2058                                   uint32);
   2059             if (export_profile->export_profile_info.flags &
   2060                            BCM_COLLECTOR_EXPORT_PROFILE_FLAGS_USE_NUM_RECORDS) {
   2061                 /* If the num_records flag is set, set copy num_records from
   2062                  * max_packet_length as we would written num_records into it while
   2063                  * syncing
   2064                  */
   2065                 export_profile->export_profile_info.num_records =
   2066                            export_profile->export_profile_info.max_packet_length;
   2067                 export_profile->export_profile_info.max_packet_length = 0;
   2068             }
   2069         }
   2070 
   2071     }
   2072 
   2073     if (recovered_ver >= BCM_WB_COLLECTOR_VERSION_1_2) {
   2074         /* Scache v2 recovery */
   2075         for (i = 0; i< collector_alloc_count; i++) {
   2076 
   2077             /* Collector Id */
   2078             COLLECTOR_SCACHE_READ(*scache, collector_id, uint16);
   2079             if (collector_id > BCM_INT_COLLECTOR_COLLECTOR_END_ID)
   2080             {
   2081                 LOG_ERROR(BSL_LS_BCM_COLLECTOR,
   2082                         (BSL_META_U(unit,
   2083                                     "COLLECTOR(unit %d) Info: Recoved collector Id"
   2084                                     " %d out of range"), unit,
   2085                          collector_id));
   2086                 return BCM_E_INTERNAL;
   2087             }
   2088             collector = &(collectors_info_list[unit][collector_id]);
   2089 
   2090             /* Ipfix version */
   2091             COLLECTOR_SCACHE_READ(*scache,
   2092                     collector->collector_info.ipfix.version, int);
   2093 
   2094             /* Ipfix Initial sequence number */
   2095             COLLECTOR_SCACHE_READ(*scache,
   2096                     collector->collector_info.ipfix.initial_sequence_num, int);
   2097         }
   2098     }
   2099 
   2100     if (recovered_ver >= BCM_WB_COLLECTOR_VERSION_1_3) {
   2101         /* Scache v3 recovery */
   2102         for (i = BCM_INT_COLLECTOR_COLLECTOR_START_ID, recovered_count = 0;
   2103                 ((i <= BCM_INT_COLLECTOR_COLLECTOR_END_ID) &&
   2104                  (recovered_count < collector_alloc_count)); i++) {
   2105 
   2106             /* Collector Id */
   2107             collector = &(collectors_info_list[unit][i]);
   2108 
   2109             if (collector->collector_id == BCM_COLLECTOR_INVALID_INDEX) {
   2110                 /* Collector does not exist, continue */
   2111                 continue;
   2112             }
   2113 
   2114             /* System Id length */
   2115             COLLECTOR_SCACHE_READ(*scache,
   2116                     collector->collector_info.protobuf.system_id_length, int);
   2117 
   2118             /* System Id */
   2119             for (j = 0; j < collector->collector_info.protobuf.system_id_length; j++) {
   2120                 COLLECTOR_SCACHE_READ(*scache,
   2121                         collector->collector_info.protobuf.system_id[j],
   2122                         uint8);
   2123             }
   2124 
   2125             /* Component Id */
   2126             COLLECTOR_SCACHE_READ(*scache,
   2127                     collector->collector_info.protobuf.component_id, uint32);
   2128 
   2129             recovered_count++;
   2130         }
   2131     }
   2132 
   2133     if (recovered_ver >= BCM_WB_COLLECTOR_VERSION_1_4) {
   2134         /* Scache v4 recovery */
   2135         for (i = BCM_INT_COLLECTOR_COLLECTOR_START_ID, recovered_count = 0;
   2136                 ((i <= BCM_INT_COLLECTOR_COLLECTOR_END_ID) &&
   2137                  (recovered_count < collector_alloc_count)); i++) {
   2138 
   2139             /* Collector Id */
   2140             collector = &(collectors_info_list[unit][i]);
   2141 
   2142             if (collector->collector_id == BCM_COLLECTOR_INVALID_INDEX) {
   2143                 /* Collector does not exist, continue */
   2144                 continue;
   2145             }
   2146 
   2147             /* Collector Type */
   2148             COLLECTOR_SCACHE_READ(*scache,
   2149                     collector->collector_info.collector_type, int);
   2150 
   2151             recovered_count++;
   2152         }
   2153     }
   2154 
   2155     return BCM_E_NONE;
   2156 }
   2157 
   2158 /*
   2159  * Function:
   2160  *     _bcm_collector_scache_size_get
   2161  * Purpose:
   2162  *     Get the size required to sync collector data to scache
   2163  * Parameters:
   2164  *     unit   - (IN) Device unit number
   2165  * Returns:
   2166  *     Required size
   2167  */
   2168 STATIC uint32
   2169 _bcm_collector_scache_size_get(int unit)
   2170 {
   2171     uint32 collecter_total_size = 0;
   2172     uint32 collecter_info_size = 0;
   2173     uint32 collecter_export_profile_info_size = 0;
   2174 
   2175 
   2176     /*******************/
   2177     /* Scache v0 size  */
   2178     /*******************/
   2179 
   2180     /* Max collectors configured */
   2181     collecter_total_size += sizeof(uint32);
   2182 
   2183     /* Max collector export profiles configured */
   2184     collecter_total_size += sizeof(uint32);
   2185 
   2186     /* Collector Id */
   2187     collecter_info_size += sizeof(uint16);
   2188 
   2189     /* Transport type */
   2190     collecter_info_size += sizeof(uint16);
   2191 
   2192     /* Dst mac addr */
   2193     collecter_info_size += (sizeof(uint8) * 6);
   2194 
   2195     /* Src mac addr */
   2196     collecter_info_size += (sizeof(uint8) * 6);
   2197 
   2198     /* Vlan tag structure */
   2199     collecter_info_size += sizeof(uint8);
   2200 
   2201     /* Outer TPID */
   2202     collecter_info_size += sizeof(uint16);
   2203 
   2204     /* Inner TPID */
   2205     collecter_info_size += sizeof(uint16);
   2206 
   2207     /* Outer vlan tag */
   2208     collecter_info_size += sizeof(uint32);
   2209 
   2210     /* Inner vlan tag */
   2211     collecter_info_size += sizeof(uint32);
   2212 
   2213     /*Consider IPv6 encap which can cover IPv4 as well*/
   2214     /* Src IP */
   2215     collecter_info_size += (sizeof(uint8) * 16);
   2216 
   2217     /* Dst IP */
   2218     collecter_info_size += (sizeof(uint8) * 16);
   2219 
   2220     /* Traffic class */
   2221     collecter_info_size += sizeof(uint8);
   2222 
   2223     /* Flow label */
   2224     collecter_info_size += sizeof(uint32);
   2225 
   2226     /* Hop limit */
   2227     collecter_info_size += sizeof(uint16);
   2228 
   2229     /* Dst port */
   2230     collecter_info_size += sizeof(uint16);
   2231 
   2232     /* Multiply by number of collectors */
   2233     collecter_info_size *= BCM_INT_COLLECTOR_MAX_COLLECTORS;
   2234 
   2235     /* Collector export profile Id */
   2236     collecter_export_profile_info_size += sizeof(uint16);
   2237 
   2238     /* Collector export profile wire format */
   2239     collecter_export_profile_info_size += sizeof(uint32);
   2240 
   2241     /* Collector export profile interval */
   2242     collecter_export_profile_info_size += sizeof(uint32);
   2243 
   2244     /* Collector export profile max packet size */
   2245     collecter_export_profile_info_size += sizeof(uint32);
   2246 
   2247     /* Multiply by number of collector export profiles */
   2248     collecter_export_profile_info_size *= BCM_INT_COLLECTOR_MAX_EXPORT_PROFILES;
   2249 
   2250     collecter_total_size += (collecter_info_size +
   2251                              collecter_export_profile_info_size); 
   2252 
   2253 
   2254     /*******************/
   2255     /* Scache v1 size  */
   2256     /*******************/
   2257     /* Collector Id */
   2258     collecter_total_size += (BCM_INT_COLLECTOR_MAX_COLLECTORS * sizeof(uint16));
   2259 
   2260     /* Collector flags */
   2261     collecter_total_size += (BCM_INT_COLLECTOR_MAX_COLLECTORS * sizeof(uint32));
   2262 
   2263     /* Export profile Id */
   2264     collecter_total_size += (BCM_INT_COLLECTOR_MAX_EXPORT_PROFILES * sizeof(uint16));
   2265 
   2266     /* Export profile flags */
   2267     collecter_total_size += (BCM_INT_COLLECTOR_MAX_EXPORT_PROFILES * sizeof(uint32));
   2268 
   2269     /*******************/
   2270     /* Scache v2 size  */
   2271     /*******************/
   2272     /* Collector Id */
   2273     collecter_total_size += (BCM_INT_COLLECTOR_MAX_COLLECTORS * sizeof(uint16));
   2274 
   2275     /* ipfix version */
   2276     collecter_total_size += (BCM_INT_COLLECTOR_MAX_COLLECTORS * sizeof(int));
   2277 
   2278     /* ipfix initial sequence number */
   2279     collecter_total_size += (BCM_INT_COLLECTOR_MAX_COLLECTORS * sizeof(int));
   2280 
   2281     /*******************/
   2282     /* Scache v3 size  */
   2283     /*******************/
   2284     /* System Id length */
   2285     collecter_total_size += (BCM_INT_COLLECTOR_MAX_COLLECTORS * sizeof(int));
   2286 
   2287     /* System Id */
   2288     collecter_total_size += (BCM_INT_COLLECTOR_MAX_COLLECTORS *
   2289                              BCM_COLLECTOR_PROTOBUF_MAX_SYSTEM_ID_LENGTH *
   2290                              sizeof(uint8));
   2291 
   2292     /* Component Id */
   2293     collecter_total_size += (BCM_INT_COLLECTOR_MAX_COLLECTORS * sizeof(uint32));
   2294 
   2295     /*******************/
   2296     /* Scache v4 size  */
   2297     /*******************/
   2298     /* Collector Type */
   2299     collecter_total_size += (BCM_INT_COLLECTOR_MAX_COLLECTORS * sizeof(int));
   2300 
   2301     return collecter_total_size;
   2302 }
   2303 
   2304 /*
   2305  * Function:
   2306  *      _bcm_collector_scache_alloc
   2307  * Purpose:
   2308  *      Collector WB scache alloc
   2309  * Parameters:
   2310  *      unit    - (IN) Unit number.
   2311  *      create  - (IN) 1 - Create, 0 - Realloc
   2312  * Returns:
   2313  *      BCM_E_XXX
   2314  * Notes:
   2315  */
   2316 STATIC int _bcm_collector_scache_alloc(int unit, int create)
   2317 {
   2318     uint32                  cur_size = 0;
   2319     uint32                  rqd_size = 0;
   2320     int                     rv = BCM_E_NONE;
   2321     soc_scache_handle_t     scache_handle;
   2322     uint8                  *scache = NULL;
   2323 
   2324     rqd_size += _bcm_collector_scache_size_get(unit);
   2325 
   2326     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COLLECTOR, 0);
   2327 
   2328     if (create) {
   2329         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 1, rqd_size,
   2330                                &scache, BCM_WB_COLLECTOR_DEFAULT_VERSION, NULL);
   2331         BCM_IF_ERROR_RETURN(rv);
   2332     } else {
   2333         /* Get current size */
   2334         rv = soc_scache_ptr_get(unit, scache_handle, &scache, &cur_size);
   2335         SOC_IF_ERROR_RETURN(rv);
   2336 
   2337         if (rqd_size > cur_size) {
   2338             /* Request the extra size */
   2339             rv = soc_scache_realloc(unit, scache_handle, rqd_size - cur_size);
   2340             SOC_IF_ERROR_RETURN(rv);
   2341         }
   2342     }
   2343 
   2344     return BCM_E_NONE;
   2345 }
   2346 
   2347 /*
   2348  * Function:
   2349  *      _bcm_collector_wb_recover
   2350  * Purpose:
   2351  *      Collector WB recovery
   2352  * Parameters:
   2353  *      unit - (IN) Unit number.
   2354  * Returns:
   2355  *      BCM_E_XXX
   2356  * Notes:
   2357  */
   2358 STATIC int _bcm_collector_wb_recover(int unit)
   2359 {
   2360     int                 stable_size;       /* Secondary storage size.   */
   2361     uint8               *scache = NULL;
   2362     soc_scache_handle_t scache_handle;
   2363     int                 rv = BCM_E_NONE;
   2364     uint16              recovered_ver = 0;
   2365 
   2366     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
   2367 
   2368     if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
   2369         SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COLLECTOR, 0);
   2370 
   2371         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 0, 0,
   2372                                      &scache, BCM_WB_COLLECTOR_DEFAULT_VERSION,
   2373                                      &recovered_ver);
   2374         if (BCM_E_NOT_FOUND == rv) {
   2375             /* Upgrading from SDK release that does not have warmboot state */
   2376             rv = _bcm_collector_scache_alloc(unit, 1);
   2377             return rv;
   2378         } else if (BCM_FAILURE(rv)) {
   2379             return rv;
   2380         }
   2381 
   2382         if (NULL == scache) {
   2383             return BCM_E_NOT_FOUND;
   2384         }
   2385     } else {
   2386         return BCM_E_NONE;
   2387     }
   2388 
   2389     /* Scache recovery */
   2390     BCM_IF_ERROR_RETURN(_bcm_collector_recover(unit, recovered_ver, &scache));
   2391 
   2392     /* Realloc any extra scache that may be needed */
   2393     BCM_IF_ERROR_RETURN(_bcm_collector_scache_alloc(unit, 0));
   2394 
   2395     return rv;
   2396 }
   2397 
   2398 #endif /* BCM_WARM_BOOT_SUPPORT */
   2399 
   2400 /*
   2401  * Function:
   2402  *      _bcm_xgs5_collector_detach
   2403  * Purpose:
   2404  *      Detaches the Collector module.
   2405  * Parameters:
   2406  *      unit         - (IN) BCM device number
   2407  * Returns:
   2408  *      BCM_E_XXX   - BCM error code.
   2409  */
   2410 int _bcm_xgs5_collector_detach(int unit)
   2411 {
   2412     _bcm_collector_global_info_t *collector_info_per_unit =
   2413                            COLLECTOR_GLOBAL_INFO_GET(unit);
   2414     int rv = BCM_E_NONE;
   2415 
   2416     if (collector_info_per_unit->collector_pool != NULL) {
   2417         rv = shr_idxres_list_destroy(collector_info_per_unit->collector_pool);
   2418         if (BCM_FAILURE(rv)) {
   2419             return rv;
   2420         }
   2421         collector_info_per_unit->collector_pool = NULL;
   2422     }
   2423     
   2424     /* Free up collector list */
   2425     BCM_IF_ERROR_RETURN(_bcm_xgs5_collector_list_destroy(unit));
   2426 
   2427     if (collector_info_per_unit->export_profile_pool != NULL) {
   2428         rv = shr_idxres_list_destroy(
   2429                          collector_info_per_unit->export_profile_pool);
   2430         if (BCM_FAILURE(rv)) {
   2431             return rv;
   2432         }
   2433         collector_info_per_unit->export_profile_pool = NULL;
   2434     }
   2435     /* Free up collector export profile list */
   2436     BCM_IF_ERROR_RETURN(_bcm_xgs5_collector_export_profile_list_destroy(unit));
   2437 
   2438     sal_free(collector_info_per_unit);
   2439     collector_global_info[unit] = NULL;
   2440 
   2441     return BCM_E_NONE; 
   2442 }
   2443 
   2444 /*
   2445  * Function:
   2446  *      _bcm_xgs5_collector_init
   2447  * Purpose:
   2448  *      Initializes the Collector module.
   2449  * Parameters:
   2450  *      unit         - (IN) BCM device number
   2451  * Returns:
   2452  *      BCM_E_XXX   - BCM error code.
   2453  */
   2454 int _bcm_xgs5_collector_init(int unit)
   2455 {
   2456      _bcm_collector_global_info_t *collector_info_per_unit =
   2457                              COLLECTOR_GLOBAL_INFO_GET(unit);
   2458     int rv = BCM_E_NONE;
   2459 
   2460     if (collector_info_per_unit != NULL) {
   2461         BCM_IF_ERROR_RETURN(_bcm_xgs5_collector_detach(unit));
   2462         collector_info_per_unit = NULL;
   2463     }
   2464 
   2465     _BCM_COLLECTOR_ALLOC(collector_info_per_unit, _bcm_collector_global_info_t,
   2466                  sizeof(_bcm_collector_global_info_t), "COLLECTOR_INFO_PER_UNIT");
   2467     if (collector_info_per_unit == NULL) {
   2468         return BCM_E_MEMORY;
   2469     }
   2470     collector_global_info[unit] = collector_info_per_unit;
   2471 
   2472     /* Create collector list */
   2473     BCM_IF_ERROR_RETURN(_bcm_xgs5_collector_list_create(unit));
   2474     rv = shr_idxres_list_create(&(collector_info_per_unit->collector_pool),
   2475                                 BCM_INT_COLLECTOR_COLLECTOR_START_ID,
   2476                                 BCM_INT_COLLECTOR_COLLECTOR_END_ID,
   2477                                 BCM_INT_COLLECTOR_COLLECTOR_START_ID,
   2478                                 BCM_INT_COLLECTOR_COLLECTOR_END_ID,
   2479                                 "collector IDs pool");
   2480 
   2481     if (BCM_FAILURE(rv)) {
   2482         BCM_IF_ERROR_RETURN(_bcm_xgs5_collector_detach(unit));
   2483         return rv;
   2484     }
   2485     /* Create collector export profile list */
   2486     rv = _bcm_xgs5_collector_export_profile_list_create(unit);
   2487     if (BCM_FAILURE(rv)) {
   2488         BCM_IF_ERROR_RETURN(_bcm_xgs5_collector_detach(unit));
   2489         return rv;
   2490     }
   2491     rv = shr_idxres_list_create(&(collector_info_per_unit->export_profile_pool),
   2492                                 BCM_INT_COLLECTOR_EXPORT_PROFILE_START_ID,
   2493                                 BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID,
   2494                                 BCM_INT_COLLECTOR_EXPORT_PROFILE_START_ID,
   2495                                 BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID,
   2496                                 "collector export profile IDs pool");
   2497     if (BCM_FAILURE(rv)) {
   2498         BCM_IF_ERROR_RETURN(_bcm_xgs5_collector_detach(unit));
   2499         return rv;
   2500     }
   2501 
   2502 #ifdef BCM_WARM_BOOT_SUPPORT
   2503     if (SOC_WARM_BOOT(unit)) {
   2504         rv = _bcm_collector_wb_recover(unit);
   2505     } else {
   2506         rv = _bcm_collector_scache_alloc(unit, 1);
   2507     }
   2508 #endif /* BCM_WARM_BOOT_SUPPORT */
   2509 
   2510     if (rv == BCM_E_NOT_FOUND) {
   2511         /* Continue with initialization if scache not found */
   2512         rv = BCM_E_NONE;
   2513     }
   2514     if (BCM_FAILURE(rv)) {
   2515         return (rv);
   2516     }
   2517 
   2518     return BCM_E_NONE;
   2519 }
   2520 
   2521 void
   2522 _bcm_xgs5_collector_encap_l2_dump(
   2523                     bcm_collector_eth_header_t *eth)
   2524 {
   2525    LOG_CLI((BSL_META("\t\tDST_MAC = %x:%x:%x:%x:%x:%x\r\n"),
   2526                     eth->dst_mac[0],
   2527                     eth->dst_mac[1],
   2528                     eth->dst_mac[2],
   2529                     eth->dst_mac[3],
   2530                     eth->dst_mac[4],
   2531                     eth->dst_mac[5])); 
   2532    LOG_CLI((BSL_META("\t\tSRC_MAC = %x:%x:%x:%x:%x:%x\r\n"),
   2533                     eth->src_mac[0],
   2534                     eth->src_mac[1],
   2535                     eth->src_mac[2],
   2536                     eth->src_mac[3],
   2537                     eth->src_mac[4],
   2538                     eth->src_mac[5])); 
   2539      LOG_CLI((BSL_META("\t\tVlan tag structure = %d\r\n"),
   2540                     eth->vlan_tag_structure));
   2541      LOG_CLI((BSL_META("\t\touter_tpid = %u\r\n"),
   2542                     eth->outer_tpid));
   2543      LOG_CLI((BSL_META("\t\tinner_tpid = %u\r\n"),
   2544                     eth->inner_tpid));
   2545      LOG_CLI((BSL_META("\t\touter_vlan_tag = %u\r\n"),
   2546                     eth->outer_vlan_tag));
   2547      LOG_CLI((BSL_META("\t\tinner_vlan_tag = %u\r\n"),
   2548                     eth->inner_vlan_tag));
   2549 }
   2550 
   2551 void
   2552 _bcm_xgs5_collector_encap_ipv4_dump(
   2553         bcm_collector_ipv4_header_t *ipv4)
   2554 {
   2555      LOG_CLI((BSL_META("\t\tsrc_ip = %x\r\n"),
   2556                     ipv4->src_ip));
   2557      LOG_CLI((BSL_META("\t\tdst_ip = %x\r\n"),
   2558                     ipv4->dst_ip));
   2559      LOG_CLI((BSL_META("\t\tdscp = %u\r\n"),
   2560                     ipv4->dscp));
   2561      LOG_CLI((BSL_META("\t\tttl = %u\r\n"),
   2562                     ipv4->ttl));
   2563 }
   2564 
   2565 void
   2566 _bcm_xgs5_collector_encap_ipv6_dump(
   2567         bcm_collector_ipv6_header_t *ipv6)
   2568 {
   2569     LOG_CLI((BSL_META("\t\tsrc_ip = %x:%x:%x:%x:%x:%x%x:%x:%x:%x:%x:%x%x:%x:%x:%x\r\n"),
   2570                 ipv6->src_ip[0],
   2571                 ipv6->src_ip[1],
   2572                 ipv6->src_ip[2],
   2573                 ipv6->src_ip[3],
   2574                 ipv6->src_ip[4],
   2575                 ipv6->src_ip[5],
   2576                 ipv6->src_ip[6],
   2577                 ipv6->src_ip[7],
   2578                 ipv6->src_ip[8],
   2579                 ipv6->src_ip[9],
   2580                 ipv6->src_ip[10],
   2581                 ipv6->src_ip[11],
   2582                 ipv6->src_ip[12],
   2583                 ipv6->src_ip[13],
   2584                 ipv6->src_ip[14],
   2585                 ipv6->src_ip[15]));
   2586      LOG_CLI((BSL_META("\t\tdst_ip = %x:%x:%x:%x:%x:%x%x:%x:%x:%x:%x:%x%x:%x:%x:%x\r\n"),
   2587                 ipv6->dst_ip[0],
   2588                 ipv6->dst_ip[1],
   2589                 ipv6->dst_ip[2],
   2590                 ipv6->dst_ip[3],
   2591                 ipv6->dst_ip[4],
   2592                 ipv6->dst_ip[5],
   2593                 ipv6->dst_ip[6],
   2594                 ipv6->dst_ip[7],
   2595                 ipv6->dst_ip[8],
   2596                 ipv6->dst_ip[9],
   2597                 ipv6->dst_ip[10],
   2598                 ipv6->dst_ip[11],
   2599                 ipv6->dst_ip[12],
   2600                 ipv6->dst_ip[13],
   2601                 ipv6->dst_ip[14],
   2602                 ipv6->dst_ip[15]));
   2603 
   2604     LOG_CLI((BSL_META("\t\ttraffic_class = %u\r\n"),
   2605                 ipv6->traffic_class));
   2606     LOG_CLI((BSL_META("\t\tflow_label = %u\r\n"),
   2607                 ipv6->flow_label));
   2608     LOG_CLI((BSL_META("\t\thop_limit = %u\r\n"),
   2609                 ipv6->hop_limit));
   2610 }
   2611 
   2612 void
   2613 _bcm_xgs5_collector_encap_udp_dump(
   2614         bcm_collector_udp_header_t *udp)
   2615 {
   2616      LOG_CLI((BSL_META("\t\tDst L4 port = %d\r\n"),
   2617                     udp->dst_port));
   2618      LOG_CLI((BSL_META("\t\tSrc L4 port = %d\r\n"),
   2619                     udp->src_port));
   2620 }
   2621 
   2622 char *_bcm_xgs5_collector_transport_type_str[bcmCollectorTransportTypeCount] =
   2623 {
   2624     "IPv4 UDP",
   2625     "IPv6 UDP",
   2626     "Raw"
   2627 };
   2628 
   2629 /*
   2630  * Function:
   2631  *     _bcm_xgs5_collector_dump
   2632  * Purpose:
   2633  *     Dump the collector info.
   2634  * Parameters:
   2635  *     unit          - (IN) BCM device number
   2636  *     collector_node - (IN) Collector information.
   2637  * Returns:
   2638  *     Nothing
   2639  */
   2640 void
   2641 _bcm_xgs5_collector_dump ( 
   2642     _bcm_collector_info_t *collector_node)
   2643 {
   2644      LOG_CLI((BSL_META("Collector ID = %d\r\n"),collector_node->collector_id));
   2645      LOG_CLI((BSL_META("\tTransport type = %s\r\n"),
   2646   _bcm_xgs5_collector_transport_type_str[collector_node->collector_info.transport_type]));
   2647      LOG_CLI((BSL_META("\tEncap info:\r\n")));
   2648      _bcm_xgs5_collector_encap_l2_dump(&(collector_node->collector_info.eth));
   2649     if (collector_node->collector_info.transport_type ==
   2650         bcmCollectorTransportTypeIpv4Udp) {
   2651      _bcm_xgs5_collector_encap_ipv4_dump(
   2652              &(collector_node->collector_info.ipv4));
   2653     } else {
   2654      _bcm_xgs5_collector_encap_ipv6_dump(
   2655              &(collector_node->collector_info.ipv6));
   2656     }
   2657      _bcm_xgs5_collector_encap_udp_dump(&(collector_node->collector_info.udp));
   2658 }
   2659 
   2660 /*
   2661  * Function:
   2662  *     _bcm_xgs5_collector_list_dump
   2663  * Purpose:
   2664  *     Dump the collector list.
   2665  * Parameters:
   2666  *     unit          - (IN) BCM device number
   2667  * Returns:
   2668  *     Nothing
   2669  */
   2670 void
   2671 _bcm_xgs5_collector_list_dump (int unit)
   2672 {
   2673     _bcm_collector_info_t *collector_node = NULL;
   2674     int i;
   2675 
   2676     if (collectors_info_list[unit] == NULL) {
   2677         return;
   2678     }
   2679 
   2680     for (i = BCM_INT_COLLECTOR_COLLECTOR_START_ID;
   2681          i <= BCM_INT_COLLECTOR_COLLECTOR_END_ID; i++) {
   2682         collector_node = &(collectors_info_list[unit][i]);
   2683         if (collector_node->collector_id !=
   2684                 BCM_COLLECTOR_INVALID_INDEX) {
   2685             _bcm_xgs5_collector_dump(collector_node);
   2686         }
   2687     } 
   2688 }
   2689 
   2690 char *_bcm_xgs5_wire_format_str[bcmCollectorWireFormatCount] =
   2691 {
   2692     "Ipfix",
   2693     "ProtoBuf",
   2694 };
   2695 
   2696 /*
   2697  * Function:
   2698  *     _bcm_xgs5_export_profile_dump
   2699  * Purpose:
   2700  *     Dump the collector export profile info.
   2701  * Parameters:
   2702  *     unit          - (IN) BCM device number
   2703  *     export_profile_node - (IN) Collector export profile information.
   2704  * Returns:
   2705  *     Nothing
   2706  */
   2707 void
   2708 _bcm_xgs5_export_profile_dump ( 
   2709     _bcm_collector_export_profile_info_t *export_profile_node)
   2710 {
   2711      LOG_CLI((BSL_META("Collector export profile ID = %d\r\n"),
   2712                        export_profile_node->export_profile_id));
   2713      LOG_CLI((BSL_META("\tWire format = %s\r\n"),
   2714                        _bcm_xgs5_wire_format_str
   2715                        [export_profile_node->export_profile_info.wire_format]));
   2716      LOG_CLI((BSL_META("\texport interval = %u\r\n"), 
   2717                    export_profile_node->export_profile_info.export_interval));
   2718      LOG_CLI((BSL_META("\tMax packet length = %u\r\n"), 
   2719                    export_profile_node->export_profile_info.max_packet_length));
   2720 }
   2721 
   2722 /*
   2723  * Function:
   2724  *     _bcm_xgs5_collector_export_profile_list_dump
   2725  * Purpose:
   2726  *     Dump the collector export profile list.
   2727  * Parameters:
   2728  *     unit          - (IN) BCM device number
   2729  * Returns:
   2730  *     Nothing
   2731  */
   2732 void
   2733 _bcm_xgs5_collector_export_profile_list_dump (int unit)
   2734 {
   2735     _bcm_collector_export_profile_info_t *export_profile_node = NULL;
   2736     int i;
   2737 
   2738     if (export_profiles_info_list[unit] == NULL) {
   2739         return;
   2740     }
   2741 
   2742     for (i = BCM_INT_COLLECTOR_EXPORT_PROFILE_START_ID;
   2743          i <= BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID; i++) {
   2744         export_profile_node = &(export_profiles_info_list[unit][i]);
   2745         if (export_profile_node->export_profile_id !=
   2746                 BCM_COLLECTOR_INVALID_INDEX) {
   2747             _bcm_xgs5_export_profile_dump(export_profile_node);
   2748         }
   2749     } 
   2750 }
   2751 
   2752 /* Dump routine for dumping
   2753  * collector list and export profile list.
   2754  */
   2755 void _bcm_xgs5_collector_sw_dump(int unit)
   2756 {
   2757     _bcm_xgs5_collector_list_dump(unit);
   2758     _bcm_xgs5_collector_export_profile_list_dump(unit);
   2759 }
   2760 
   2761 #else /* BCM_COLLECTOR_SUPPORT */
   2762 int _bcm_xgs5_collector_not_empty;
   2763 #endif /* BCM_COLLECTOR_SUPPORT */