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

sum.c (64796B)


      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  * SUM - Switch Utilization Monitor Embedded Application APP interface
      8  * Purpose: API to Initialize SUM embedded app Structures.
      9  */
     10 #if defined(BCM_TOMAHAWK3_SUPPORT)
     11 #include <shared/bsl.h>
     12 #include <shared/pbmp.h>
     13 #include <shared/alloc.h>
     14 #include <shared/bslenum.h>
     15 #include <shared/idxres_fl.h>
     16 
     17 #include <soc/defs.h>
     18 #include <soc/drv.h>
     19 #include <soc/uc.h>
     20 
     21 #include <bcm/types.h>
     22 #include <bcm/error.h>
     23 #include <bcm/sum.h>
     24 
     25 #include <bcm_int/common/sum_feature.h>
     26 #include <bcm_int/common/sum.h>
     27 #include <bcm_int/common/rx.h>
     28 
     29 #include <soc/shared/sum.h>
     30 #include <soc/shared/sum_msg.h>
     31 #include <soc/shared/sum_pack.h>
     32 #include <soc/shared/shr_pkt.h>
     33 
     34 #include <bcm_int/tomahawk3_dispatch.h>
     35 #include <soc/tomahawk3.h>
     36 
     37 #ifdef BCM_WARM_BOOT_SUPPORT
     38 #include <soc/scache.h>
     39 #include <bcm_int/esw/switch.h>
     40 #endif /* BCM_WARM_BOOT_SUPPORT */
     41 
     42 #if defined(INCLUDE_SUM)
     43 /*Global to hold the SUM firmware version for feature compatibility check */
     44 uint32 sum_firmware_version = 0;
     45 
     46 /* SUM global information */
     47 _bcm_int_sum_info_t *sum_global_info[BCM_MAX_NUM_UNITS] = {0};
     48 static sal_mutex_t mutex[BCM_MAX_NUM_UNITS];
     49 
     50 /* List of SUM configuration information */
     51 bcm_sum_config_t sum_global_config[BCM_MAX_NUM_UNITS];
     52 bcm_pbmp_t       sum_global_pbmp[BCM_MAX_NUM_UNITS];
     53 
     54 /*
     55  * Function:
     56  *      _bcm_sum_convert_uc_error
     57  * Purpose:
     58  *      Converts uController error code to corresponding BCM error code.
     59  * Parameters:
     60  *      uc_rv  - (IN) uController error code to convert.
     61  * Returns:
     62  *      BCM_E_XXX   - BCM error code.
     63  * Notes:
     64  */
     65 STATIC int
     66 _bcm_sum_convert_uc_error(uint32 uc_rv)
     67 {
     68     int rv = BCM_E_NONE;
     69 
     70     switch(uc_rv) {
     71     case SHR_SUM_UC_E_NONE:
     72         rv = BCM_E_NONE;
     73         break;
     74     case SHR_SUM_UC_E_INTERNAL:
     75         rv = BCM_E_INTERNAL;
     76         break;
     77     case SHR_SUM_UC_E_MEMORY:
     78         rv = BCM_E_MEMORY;
     79         break;
     80     case SHR_SUM_UC_E_UNIT:
     81         rv = BCM_E_UNIT;
     82         break;
     83     case SHR_SUM_UC_E_PARAM:
     84         rv = BCM_E_PARAM;
     85         break;
     86     case SHR_SUM_UC_E_EMPTY:
     87         rv = BCM_E_EMPTY;
     88         break;
     89     case SHR_SUM_UC_E_FULL:
     90         rv = BCM_E_FULL;
     91         break;
     92     case SHR_SUM_UC_E_NOT_FOUND:
     93         rv = BCM_E_NOT_FOUND;
     94         break;
     95     case SHR_SUM_UC_E_EXISTS:
     96         rv = BCM_E_EXISTS;
     97         break;
     98     case SHR_SUM_UC_E_TIMEOUT:
     99         rv = BCM_E_TIMEOUT;
    100         break;
    101     case SHR_SUM_UC_E_BUSY:
    102         rv = BCM_E_BUSY;
    103         break;
    104     case SHR_SUM_UC_E_FAIL:
    105         rv = BCM_E_FAIL;
    106         break;
    107     case SHR_SUM_UC_E_DISABLED:
    108         rv = BCM_E_DISABLED;
    109         break;
    110     case SHR_SUM_UC_E_BADID:
    111         rv = BCM_E_BADID;
    112         break;
    113     case SHR_SUM_UC_E_RESOURCE:
    114         rv = BCM_E_RESOURCE;
    115         break;
    116     case SHR_SUM_UC_E_CONFIG:
    117         rv = BCM_E_CONFIG;
    118         break;
    119     case SHR_SUM_UC_E_UNAVAIL:
    120         rv = BCM_E_UNAVAIL;
    121         break;
    122     case SHR_SUM_UC_E_INIT:
    123         rv = BCM_E_INIT;
    124         break;
    125     case SHR_SUM_UC_E_PORT:
    126         rv = BCM_E_PORT;
    127         break;
    128     default:
    129         rv = BCM_E_INTERNAL;
    130         break;
    131     }
    132 
    133     return rv;
    134 }
    135 
    136 STATIC int
    137 _bcm_sum_msg_send_receive(int unit, uint8 s_subclass,
    138                           uint16 s_len, uint32 s_data,
    139                           uint8 r_subclass, uint16 *r_len,
    140                           sal_usecs_t timeout)
    141 {
    142     int rv;
    143     mos_msg_data_t send, reply;
    144     uint32 uc_rv;
    145     _bcm_int_sum_info_t *sum_info = SUM_INFO_GET(unit);
    146     uint8 *dma_buffer;
    147     int dma_buffer_len;
    148 
    149     dma_buffer = sum_info->dma_buffer;
    150     dma_buffer_len = sum_info->dma_buffer_len;
    151 
    152     sal_memset(&send, 0, sizeof(send));
    153     sal_memset(&reply, 0, sizeof(reply));
    154     send.s.mclass = MOS_MSG_CLASS_SUM;
    155     send.s.subclass = s_subclass;
    156     send.s.len = bcm_htons(s_len);
    157 
    158     /*
    159      * Set 'data' to DMA buffer address if a DMA operation is
    160      * required for send or receive.
    161      */
    162     if (MOS_MSG_DMA_MSG(s_subclass) ||
    163         MOS_MSG_DMA_MSG(r_subclass)) {
    164         send.s.data = bcm_htonl(soc_cm_l2p(unit, dma_buffer));
    165     } else {
    166         send.s.data = bcm_htonl(s_data);
    167     }
    168 
    169     /* Flush DMA memory */
    170     if (MOS_MSG_DMA_MSG(s_subclass)) {
    171         soc_cm_sflush(unit, dma_buffer, s_len);
    172     }
    173 
    174     /* Invalidate DMA memory to read */
    175     if (MOS_MSG_DMA_MSG(r_subclass)) {
    176         soc_cm_sinval(unit, dma_buffer, dma_buffer_len);
    177     }
    178 
    179     rv = soc_cmic_uc_msg_send_receive(unit, sum_info->uc_num,
    180             &send, &reply,
    181             timeout);
    182     if (rv != SOC_E_NONE){
    183         return BCM_E_INTERNAL;
    184     }
    185 
    186     /* Convert SUM uController error code to BCM */
    187     uc_rv  = bcm_ntohl(reply.s.data);
    188     rv     = _bcm_sum_convert_uc_error(uc_rv);
    189 
    190     *r_len = bcm_ntohs(reply.s.len);
    191 
    192     /*Check reply class and subclass*/
    193     if((rv == SOC_E_NONE) && ((reply.s.mclass != MOS_MSG_CLASS_SUM) ||
    194        (reply.s.subclass != r_subclass)))
    195     {
    196         return BCM_E_INTERNAL;
    197     }
    198     return rv;
    199 }
    200 
    201 /*******************************************************
    202  *                                                     *
    203  *           SUM EMBEDDED APP APIs                     *
    204  */
    205 
    206 STATIC int
    207 bcm_sum_eapp_config_get_msg(int unit,
    208                             bcm_sum_config_t *config,
    209                             bcm_pbmp_t *pbmp)
    210 {
    211     shr_sum_msg_ctrl_config_t config_msg;
    212     _bcm_int_sum_info_t       *sum_info = SUM_INFO_GET(unit);
    213     uint8 *buffer_req = NULL, *buffer_ptr = NULL;
    214     uint16 buffer_len = 0, reply_len = 0;
    215     uint32 port_loop;
    216 
    217     if ((config == NULL) || (pbmp == NULL)) {
    218         return BCM_E_PARAM;
    219     }
    220 
    221     BCM_PBMP_CLEAR(*pbmp);
    222     sal_memset(config, 0, sizeof(bcm_sum_config_t));
    223     sal_memset(&config_msg, 0, sizeof(shr_sum_msg_ctrl_config_t));
    224 
    225     BCM_IF_ERROR_RETURN(_bcm_sum_msg_send_receive(unit, MOS_MSG_SUBCLASS_SUM_CONFIG_GET,
    226                                                   buffer_len, 0,
    227                                                   MOS_MSG_SUBCLASS_SUM_CONFIG_GET_REPLY, &reply_len,
    228                                                   SHR_SUM_MAX_UC_MSG_TIMEOUT));
    229     buffer_req      = sum_info->dma_buffer;
    230     buffer_ptr      = shr_sum_msg_ctrl_config_unpack(buffer_req, &config_msg);
    231     buffer_len      = buffer_ptr - buffer_req;
    232 
    233     if (reply_len != buffer_len) {
    234         return BCM_E_INTERNAL;
    235     }
    236     config->usec_sample_interval = config_msg.usec_sample_interval;
    237     config->sum_type = config_msg.sum_type;
    238     for (port_loop = 0; port_loop < config_msg.num_ports; ++port_loop) {
    239         if (SOC_PORT_VALID(unit, config_msg.lports[port_loop])) {
    240             BCM_PBMP_PORT_SET(*pbmp, config_msg.lports[port_loop]);
    241         }
    242     }
    243 
    244     return BCM_E_NONE;
    245 }
    246 
    247 
    248 STATIC int
    249 bcm_sum_eapp_config_msg(int unit, bcm_sum_config_t *config,
    250                         bcm_pbmp_t pbmp, uint8 sum_wb_indicate)
    251 {
    252     shr_sum_msg_ctrl_config_t config_msg;
    253     _bcm_int_sum_info_t       *sum_info = SUM_INFO_GET(unit);
    254     uint8                     *buffer_req = NULL, *buffer_ptr = NULL;
    255     uint16                    buffer_len = 0, reply_len = 0;
    256     soc_info_t                *si;
    257     uint32                    port;
    258 
    259     sal_memset(&config_msg, 0, sizeof(config_msg));
    260     si = &SOC_INFO(unit);
    261 
    262     if (config->max_history) {
    263         sum_info->host_buffer = (bcm_sum_stat_info_t *)soc_cm_salloc(unit,
    264                                          (SUM_STAT_SIZE * config->max_history),
    265                                          "SUM Host buffer allocate");
    266         if (!sum_info->host_buffer) {
    267             LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
    268                             "SUM App Failed to create host buffer\n")));
    269             return BCM_E_MEMORY;
    270         }
    271         sal_memset(sum_info->host_buffer, 0,
    272                    (SUM_STAT_SIZE * config->max_history));
    273         config_msg.host_buf_addr = (uint32)
    274               bcm_htonl(soc_cm_l2p(unit, sum_info->host_buffer));
    275     } else {
    276         config_msg.host_buf_addr = 0;
    277     }
    278     config_msg.usec_sample_interval = config->usec_sample_interval;
    279     config_msg.max_history = config->max_history;
    280     config_msg.sum_type = config->sum_type;
    281     config_msg.mib_tbl_addr = soc_mem_addr_get(unit, CDMIB_MEMm, 0, 0, 0, &config_msg.mib_tbl_acc_type);
    282     config_msg.sum_wb_indicate = sum_wb_indicate;
    283 
    284     BCM_PBMP_ITER(pbmp, port) {
    285         config_msg.lports[config_msg.num_ports] = port;
    286         config_msg.pports[config_msg.num_ports] = si->port_l2p_mapping[port];
    287         ++config_msg.num_ports;
    288     }
    289 
    290     if ((SHR_SUM_MIN_SAMPLE_INTERVAL * config_msg.num_ports) >
    291         config->usec_sample_interval) {
    292         LOG_WARN(BSL_LS_BCM_SUM, (BSL_META_U(unit,
    293                  "SUM sample interval %d is low num_port: %d\n"),
    294                  config->usec_sample_interval, config_msg.num_ports));
    295     }
    296 
    297     buffer_req      = sum_info->dma_buffer;
    298     buffer_ptr      = shr_sum_msg_ctrl_config_pack(buffer_req, &config_msg);
    299     buffer_len      = buffer_ptr - buffer_req;
    300 
    301     BCM_IF_ERROR_RETURN(_bcm_sum_msg_send_receive(unit, MOS_MSG_SUBCLASS_SUM_CONFIG_SET,
    302                                                   buffer_len, 0,
    303                                                   MOS_MSG_SUBCLASS_SUM_CONFIG_SET_REPLY,
    304                                                   &reply_len, SHR_SUM_MAX_UC_MSG_TIMEOUT));
    305     return BCM_E_NONE;
    306 }
    307 
    308 #ifdef BCM_WARM_BOOT_SUPPORT
    309 
    310 #define BCM_WB_SUM_VERSION_1_0      SOC_SCACHE_VERSION(1,0)
    311 #define BCM_WB_SUM_DEFAULT_VERSION  BCM_WB_SUM_VERSION_1_0
    312 
    313 #define SUM_SCACHE_WRITE(_scache, _val, _type)                    \
    314     do {                                                          \
    315         _type _tmp = (_type) (_val);                              \
    316         sal_memcpy((_scache), &(_tmp), sizeof(_type));            \
    317         (_scache) += sizeof(_type);                               \
    318     } while(0)
    319 
    320 #define SUM_SCACHE_READ(_scache, _var, _type)                     \
    321     do {                                                          \
    322         _type _tmp;                                               \
    323         sal_memcpy(&(_tmp), (_scache), sizeof(_type));            \
    324         (_scache) += sizeof(_type);                               \
    325         (_var)     = (_tmp);                                      \
    326     } while(0)
    327 
    328 /*
    329  * Function:
    330  *     _bcm_th3_sum_scache_v0_size_get
    331  * Purpose:
    332  *     Get the size required to sync SUM data to scache v0
    333  * Parameters:
    334  *     unit   - (IN) Device unit number
    335  * Returns:
    336  *     Required size
    337  */
    338 STATIC uint32
    339 _bcm_th3_sum_scache_v0_size_get(int unit)
    340 {
    341     uint32 size = 0;
    342 
    343     /* SUM status */
    344     size += sizeof(uint32);
    345 
    346     /* SUM maximum number of sample history */
    347     size += sizeof(uint32);
    348 
    349     return size;
    350 }
    351 
    352 /*
    353  * Function:
    354  *     _bcm_th3_sum_scache_v0_sync
    355  * Purpose:
    356  *     Sync SUM data to scache v0
    357  * Parameters:
    358  *     unit   - (IN) Device unit number
    359  *     scache - (IN) Pointer to current scache location
    360  * Returns:
    361  *     BCM_E_XXX
    362  */
    363 STATIC void
    364 _bcm_th3_sum_scache_v0_sync(int unit, uint8 **scache)
    365 {
    366     _bcm_int_sum_info_t *sum_info = SUM_INFO_GET(unit);
    367     bcm_sum_config_t *global_config = (&(sum_global_config[unit]));
    368 
    369     if (sum_info == NULL) {
    370         SUM_SCACHE_WRITE(*scache, 0, uint32);
    371         SUM_SCACHE_WRITE(*scache, 0, uint32);
    372         return;
    373     }
    374 
    375     /* SUM status */
    376     SUM_SCACHE_WRITE(*scache, sum_info->status, uint32);
    377 
    378     if (global_config == NULL) {
    379         SUM_SCACHE_WRITE(*scache, 0, uint32);
    380         return;
    381     }
    382 
    383     /* SUM maximum number of sample history */
    384     SUM_SCACHE_WRITE(*scache, global_config->max_history, uint32);
    385 }
    386 
    387 /*
    388  * Function:
    389  *     _bcm_th3_sum_scache_v0_recover
    390  * Purpose:
    391  *     Recover SUM data from scache v0
    392  * Parameters:
    393  *     unit   - (IN) Device unit number
    394  *     scache - (IN) Pointer to current scache location
    395  * Returns:
    396  *     BCM_E_XXX
    397  */
    398 STATIC int
    399 _bcm_th3_sum_scache_v0_recover(int unit, uint8 **scache)
    400 {
    401     _bcm_int_sum_info_t *sum_info = SUM_INFO_GET(unit);
    402     bcm_sum_config_t    *global_config = (&(sum_global_config[unit]));
    403 
    404     /* SUM status */
    405     if (sum_info == NULL) {
    406         return BCM_E_NONE;
    407     }
    408     SUM_SCACHE_READ(*scache, sum_info->status, uint32);
    409 
    410     /* SUM maximum number of sample history */
    411     if (global_config == NULL) {
    412         return BCM_E_NONE;
    413     }
    414     SUM_SCACHE_READ(*scache, global_config->max_history, uint32);
    415 
    416     return BCM_E_NONE;
    417 }
    418 
    419 /*
    420  * Function:
    421  *      _bcm_th3_sum_scache_alloc
    422  * Purpose:
    423  *      SUM WB scache alloc
    424  * Parameters:
    425  *      unit    - (IN) Unit number.
    426  *      create  - (IN) 1 - Create, 0 - Realloc
    427  * Returns:
    428  *      BCM_E_XXX
    429  * Notes:
    430  */
    431 STATIC int _bcm_th3_sum_scache_alloc(int unit, int create)
    432 {
    433     uint32                  cur_size = 0;
    434     uint32                  rqd_size = 0;
    435     int                     rv = BCM_E_NONE;
    436     soc_scache_handle_t     scache_handle;
    437     uint8                  *scache = NULL;
    438 
    439     rqd_size += _bcm_th3_sum_scache_v0_size_get(unit);
    440 
    441     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_SUM, 0);
    442 
    443     if (create) {
    444         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 1, rqd_size,
    445                 &scache, BCM_WB_SUM_DEFAULT_VERSION, NULL);
    446         BCM_IF_ERROR_RETURN(rv);
    447     } else {
    448         /* Get current size */
    449         rv = soc_scache_ptr_get(unit, scache_handle, &scache, &cur_size);
    450         SOC_IF_ERROR_RETURN(rv);
    451 
    452         if (rqd_size > cur_size) {
    453             /* Request the extra size */
    454             rv = soc_scache_realloc(unit, scache_handle, rqd_size - cur_size);
    455             SOC_IF_ERROR_RETURN(rv);
    456         }
    457     }
    458 
    459     return BCM_E_NONE;
    460 }
    461 
    462 /*
    463  * Function:
    464  *      _bcm_th3_sum_sync
    465  * Purpose:
    466  *      Warmboot scache sync
    467  * Parameters:
    468  *      unit - (IN) Unit number.
    469  * Returns:
    470  *      BCM_E_XXX
    471  * Notes:
    472  */
    473 int _bcm_th3_sum_sync(int unit)
    474 {
    475     int                     stable_size;
    476     int                     rv = BCM_E_NONE;
    477     soc_scache_handle_t     scache_handle;
    478     uint8                  *scache = NULL;
    479     _bcm_int_sum_info_t    *sum_info = SUM_INFO_GET(unit);
    480     bcm_sum_config_t       *global_config = (&(sum_global_config[unit]));
    481     bcm_pbmp_t             *global_pbmp   = (&(sum_global_pbmp[unit]));
    482     bcm_sum_stat_info_t    *old_host_buffer_add;
    483 
    484     /* Get SUM module storage size. */
    485     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
    486 
    487     /* If level 2 store is not configured return from here. */
    488     if (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) || (stable_size == 0)) {
    489         return BCM_E_NONE;
    490     }
    491 
    492     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_SUM, 0);
    493     BCM_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, scache_handle, 0, 0,
    494                 &scache, 0, NULL));
    495     if (NULL == scache) {
    496         return BCM_E_INTERNAL;
    497     }
    498 
    499     /* Sync SUM scache v0 */
    500     _bcm_th3_sum_scache_v0_sync(unit, &scache);
    501 
    502     if (sum_info == NULL) {
    503         return BCM_E_NONE;
    504     }
    505     old_host_buffer_add = (bcm_sum_stat_info_t *)sum_info->host_buffer;
    506     global_config->max_history = 0;
    507 
    508     /* Inform SUM EAPP of the change/addition in/of configuration information */
    509     rv = bcm_sum_eapp_config_msg(unit, global_config, *global_pbmp, 1);
    510 
    511     if (BCM_FAILURE(rv)) {
    512         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
    513                         "SUM App Config set uc communication failed \n")));
    514         if (old_host_buffer_add != NULL)
    515             soc_cm_sfree(unit, old_host_buffer_add);
    516 
    517         return rv;
    518     }
    519 
    520     if (old_host_buffer_add != NULL)
    521         soc_cm_sfree(unit, old_host_buffer_add);
    522 
    523     return BCM_E_NONE;
    524 }
    525 
    526 
    527 /*
    528  * Function:
    529  *      _bcm_th3_sum_wb_recover
    530  * Purpose:
    531  *      SUM WB recovery
    532  * Parameters:
    533  *      unit - (IN) Unit number.
    534  * Returns:
    535  *      BCM_E_XXX
    536  * Notes:
    537  */
    538 STATIC int _bcm_th3_sum_wb_recover(int unit)
    539 {
    540     int                 stable_size;       /* Secondary storage size.   */
    541     uint8               *scache = NULL;
    542     soc_scache_handle_t scache_handle;
    543     int                 rv = BCM_E_NONE;
    544     uint16              recovered_ver = 0;
    545 
    546     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
    547 
    548     if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
    549         SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_SUM, 0);
    550 
    551         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 0, 0,
    552                 &scache, BCM_WB_SUM_DEFAULT_VERSION,
    553                 &recovered_ver);
    554         if (BCM_E_NOT_FOUND == rv) {
    555             /* Upgrading from SDK release that does not have warmboot state */
    556             rv = _bcm_th3_sum_scache_alloc(unit, 1);
    557             return rv;
    558         } else if (BCM_FAILURE(rv)) {
    559             return rv;
    560         }
    561 
    562         if (NULL == scache) {
    563             return BCM_E_NOT_FOUND;
    564         }
    565     } else {
    566         return BCM_E_NONE;
    567     }
    568 
    569     /* Scache recovery */
    570     BCM_IF_ERROR_RETURN(_bcm_th3_sum_scache_v0_recover(unit, &scache));
    571 
    572     /* Realloc any extra scache that may be needed */
    573     BCM_IF_ERROR_RETURN(_bcm_th3_sum_scache_alloc(unit, 0));
    574 
    575     return rv;
    576 }
    577 #endif /* BCM_WARM_BOOT_SUPPORT */
    578 
    579 STATIC int
    580 bcm_sum_eapp_detach(int unit)
    581 {
    582     _bcm_int_sum_info_t *sum_info = SUM_INFO_GET(unit);
    583     int                          rv = BCM_E_NONE;
    584     int                          status = 0;
    585     uint16                       reply_len = 0;
    586 
    587     if (!SOC_WARM_BOOT(unit)) {
    588         /* Un Init the app */
    589         SOC_IF_ERROR_RETURN(soc_uc_status(unit, sum_info->uc_num, &status));
    590         if (status) {
    591             rv = _bcm_sum_msg_send_receive(unit, MOS_MSG_SUBCLASS_SUM_SHUTDOWN,
    592                                            0, 0,
    593                                            MOS_MSG_SUBCLASS_SUM_SHUTDOWN_REPLY,
    594                                            &reply_len,
    595                                            SHR_SUM_MAX_UC_MSG_TIMEOUT);
    596             if (BCM_SUCCESS(rv) && (reply_len != 0)) {
    597                 return BCM_E_INTERNAL;
    598             }
    599         }
    600     }
    601 
    602     /*
    603      * Free DMA buffer
    604  */
    605     if (sum_info->dma_buffer != NULL) {
    606         soc_cm_sfree(unit, sum_info->dma_buffer);
    607         sum_info->dma_buffer = NULL;
    608     }
    609 
    610     /*
    611      * Free Host Stats buffer
    612  */
    613     if (sum_info->host_buffer != NULL) {
    614         soc_cm_sfree(unit, sum_info->host_buffer);
    615         sum_info->host_buffer = NULL;
    616     }
    617     sum_info->status = 0;
    618 
    619     return BCM_E_NONE;
    620 }
    621 
    622 STATIC int
    623 bcm_sum_eapp_init(int unit)
    624 {
    625     int                         rv = BCM_E_NONE;
    626     int                         uc = 0;
    627     int                         status;
    628     uint16                      reply_len = 0;
    629     _bcm_int_sum_info_t         *sum_info = SUM_INFO_GET(unit);
    630     bcm_sum_config_t            *global_config = (&(sum_global_config[unit]));
    631     bcm_pbmp_t                  *global_pbmp   = (&(sum_global_pbmp[unit]));
    632     bcm_sum_stat_info_t         *old_host_buffer_add;
    633 
    634     /* Init the app */
    635     /*
    636      * Start SUM application in BTE (Broadcom Task Engine) uController,
    637      * if not already running (warm boot).
    638      * Determine which uController is running SUM  by choosing the first
    639      * uC that returns successfully.
    640      */
    641     for (uc = 0; uc < CMICM_NUM_UCS; uc++) {
    642         rv = soc_uc_status(unit, uc, &status);
    643         if ((rv == SOC_E_NONE) && (status != 0)) {
    644             rv = soc_cmic_uc_appl_init(unit, uc, MOS_MSG_CLASS_SUM,
    645                     SHR_SUM_MAX_UC_MSG_TIMEOUT,
    646                     SUM_SDK_VERSION,
    647                     SUM_UC_MIN_VERSION,
    648                     NULL, NULL);
    649             if (SOC_E_NONE == rv) {
    650                 /* SUM started successfully */
    651                 break;
    652             }
    653         }
    654     }
    655 
    656     if (uc >= CMICM_NUM_UCS) {
    657         /* Could not find or start SUM appl */
    658         LOG_WARN(BSL_LS_BCM_SUM,
    659                 (BSL_META_U(unit,
    660                             "uKernel SUM application not available\n")));
    661         return BCM_E_NONE;
    662     }
    663     sum_info->uc_num                 = uc;
    664 
    665     /* Detach if already initialized */
    666     if (sum_info->status) {
    667         BCM_IF_ERROR_RETURN(bcm_sum_eapp_detach(unit));
    668         return BCM_E_INIT;
    669     }
    670 
    671     if (!SOC_WARM_BOOT(unit)) {
    672         /* Send the init config to UKERNEL */
    673         rv = _bcm_sum_msg_send_receive(unit, MOS_MSG_SUBCLASS_SUM_INIT,
    674                                        0, 0,
    675                                        MOS_MSG_SUBCLASS_SUM_INIT_REPLY,
    676                                        &reply_len,
    677                                        SHR_SUM_MAX_UC_MSG_TIMEOUT);
    678         if (BCM_SUCCESS(rv) && (reply_len != 0)) {
    679             return BCM_E_INTERNAL;
    680         }
    681         sal_memset(global_config, 0, sizeof(bcm_sum_config_t));
    682         sal_memset(global_pbmp, 0, sizeof(bcm_pbmp_t));
    683     } else {
    684         /* Get the Config info */
    685         rv = bcm_sum_eapp_config_get_msg(unit, global_config, global_pbmp);
    686         if (BCM_FAILURE(rv)) {
    687             return rv;
    688         }
    689 
    690         /* Inform SUM EAPP of the change/addition in/of configuration information */
    691         old_host_buffer_add = (bcm_sum_stat_info_t *)sum_info->host_buffer;
    692         rv = bcm_sum_eapp_config_msg(unit, global_config, *global_pbmp, 1);
    693 
    694         if (BCM_FAILURE(rv)) {
    695             LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
    696                             "SUM App Config set uc communication failed \n")));
    697             if (old_host_buffer_add != NULL)
    698                 soc_cm_sfree(unit, old_host_buffer_add);
    699 
    700             return rv;
    701         }
    702         if (old_host_buffer_add != NULL)
    703             soc_cm_sfree(unit, old_host_buffer_add);
    704 
    705     }
    706 
    707     return BCM_E_NONE;
    708 }
    709 
    710 STATIC int
    711 bcm_sum_peak_stat_info_get(int unit,
    712                            uint32 max_samples,
    713                            bcm_sum_stat_info_t *stats_data,
    714                            uint32 *num_samples,
    715                            uint32 sample_period)
    716 {
    717     shr_sum_msg_buf_info_t    buf_msg;
    718     _bcm_int_sum_info_t       *sum_info = SUM_INFO_GET(unit);
    719     bcm_sum_config_t *global_config = (&(sum_global_config[unit]));
    720     uint8 *buffer_req = NULL, *buffer_ptr = NULL;
    721     uint16 buffer_len = 0, reply_len = 0;
    722     uint32 cur_num_sample, peak_offset, cur_offset, max_num_sample;
    723     uint64 peak_value;
    724     bcm_sum_stat_info_t *stats_ptr =  NULL;
    725 
    726     sal_memset(stats_data, 0, (max_samples * SUM_STAT_SIZE));
    727     sal_memset(&buf_msg, 0, sizeof(buf_msg));
    728 
    729     /* Get stats configuration data from uC */
    730     BCM_IF_ERROR_RETURN(_bcm_sum_msg_send_receive(unit, MOS_MSG_SUBCLASS_SUM_STAT_GET,
    731                                                   buffer_len, 0,
    732                                                   MOS_MSG_SUBCLASS_SUM_STAT_GET_REPLY, &reply_len,
    733                                                   SHR_SUM_MAX_UC_MSG_TIMEOUT));
    734     buffer_req      = sum_info->dma_buffer;
    735     buffer_ptr      = shr_sum_msg_ctrl_stat_config_unpack(buffer_req, &buf_msg);
    736     buffer_len      = buffer_ptr - buffer_req;
    737 
    738     if (reply_len != buffer_len) {
    739         return BCM_E_INTERNAL;
    740     }
    741 
    742     if (buf_msg.host_buf_status) {
    743         cur_num_sample = global_config->max_history;
    744     } else {
    745         cur_num_sample = buf_msg.host_buf_cur_offset;
    746     }
    747 
    748     if (!cur_num_sample) {
    749         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
    750                   "SUM App No sample avaliable yet\n")));
    751         return BCM_E_NONE;
    752     }
    753 
    754     if (cur_num_sample > (sample_period / buf_msg.sample_interval)) {
    755         cur_num_sample = (sample_period / buf_msg.sample_interval);
    756     }
    757 
    758     if (!cur_num_sample) {
    759         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
    760                         "SUM App usec sample period %d too low than sample interval: %d \n"),
    761                         sample_period, buf_msg.sample_interval));
    762         return BCM_E_PARAM;
    763     }
    764 
    765     *num_samples = 0;
    766     if ((global_config->sum_type == bcmSumTypeTxPktCnt) ||
    767         (global_config->sum_type == bcmSumTypeTxPktByteCnt) ||
    768         (global_config->sum_type == bcmSumTypeRxTxPktCnt) ||
    769         (global_config->sum_type == bcmSumTypeTxRxPktByteCnt)) {
    770         if (cur_num_sample > buf_msg.host_buf_cur_offset) {
    771             max_num_sample = buf_msg.host_buf_cur_offset;
    772             peak_offset = 0;
    773             stats_ptr   = (bcm_sum_stat_info_t *)
    774                   &sum_info->host_buffer[peak_offset];
    775             COMPILER_64_COPY(peak_value,
    776                              stats_ptr->tx_pkt_count);
    777             for (cur_offset = 1; cur_offset < max_num_sample; ++cur_offset) {
    778                 stats_ptr   = (bcm_sum_stat_info_t *)
    779                       &sum_info->host_buffer[cur_offset];
    780                 if (COMPILER_64_GT(stats_ptr->tx_pkt_count, peak_value)) {
    781                     COMPILER_64_COPY(peak_value,
    782                                      stats_ptr->tx_pkt_count);
    783                     peak_offset = cur_offset;
    784                 }
    785             }
    786             cur_offset     = (global_config->max_history -
    787                               (cur_num_sample - max_num_sample));
    788             for (; cur_offset < global_config->max_history; ++cur_offset) {
    789                 stats_ptr   = (bcm_sum_stat_info_t *)
    790                       &sum_info->host_buffer[cur_offset];
    791                 if (COMPILER_64_GT(stats_ptr->tx_pkt_count, peak_value)) {
    792                     COMPILER_64_COPY(peak_value,
    793                                      stats_ptr->tx_pkt_count);
    794                     peak_offset = cur_offset;
    795                 }
    796             }
    797         } else {
    798             max_num_sample = buf_msg.host_buf_cur_offset;
    799             peak_offset = max_num_sample - cur_num_sample;
    800             cur_offset = peak_offset + 1;
    801             stats_ptr   = (bcm_sum_stat_info_t *)
    802                   &sum_info->host_buffer[peak_offset];
    803             COMPILER_64_COPY(peak_value,
    804                              stats_ptr->tx_pkt_count);
    805             for (; cur_offset < max_num_sample; ++cur_offset) {
    806                 stats_ptr   = (bcm_sum_stat_info_t *)
    807                       &sum_info->host_buffer[cur_offset];
    808                 if (COMPILER_64_GT(stats_ptr->tx_pkt_count, peak_value)) {
    809                     COMPILER_64_COPY(peak_value,
    810                                      stats_ptr->tx_pkt_count);
    811                     peak_offset = cur_offset;
    812                 }
    813             }
    814         }
    815         stats_ptr   = (bcm_sum_stat_info_t *)
    816               &sum_info->host_buffer[peak_offset];
    817         sal_memcpy(&stats_data[*num_samples], stats_ptr, SUM_STAT_SIZE);
    818         stats_data[*num_samples].sum_type = bcmSumTypeTxPktCnt;
    819         *num_samples = (*num_samples + 1);
    820     }
    821 
    822     if (((global_config->sum_type == bcmSumTypeRxPktCnt) ||
    823          (global_config->sum_type == bcmSumTypeRxPktByteCnt) ||
    824          (global_config->sum_type == bcmSumTypeRxTxPktCnt) ||
    825          (global_config->sum_type == bcmSumTypeTxRxPktByteCnt)) &&
    826         (*num_samples < max_samples)) {
    827         if (cur_num_sample > buf_msg.host_buf_cur_offset) {
    828             max_num_sample = buf_msg.host_buf_cur_offset;
    829             peak_offset = 0;
    830             stats_ptr   = (bcm_sum_stat_info_t *)
    831                   &sum_info->host_buffer[peak_offset];
    832             COMPILER_64_COPY(peak_value,
    833                              stats_ptr->rx_pkt_count);
    834             for (cur_offset = 1; cur_offset < max_num_sample; ++cur_offset) {
    835                 stats_ptr   = (bcm_sum_stat_info_t *)
    836                       &sum_info->host_buffer[cur_offset];
    837                 if (COMPILER_64_GT(stats_ptr->rx_pkt_count, peak_value)) {
    838                     COMPILER_64_COPY(peak_value,
    839                                      stats_ptr->rx_pkt_count);
    840                     peak_offset = cur_offset;
    841                 }
    842             }
    843             cur_offset     = (global_config->max_history -
    844                               (cur_num_sample - max_num_sample));
    845             for (; cur_offset < global_config->max_history; ++cur_offset) {
    846                 stats_ptr   = (bcm_sum_stat_info_t *)
    847                       &sum_info->host_buffer[cur_offset];
    848                 if (COMPILER_64_GT(stats_ptr->rx_pkt_count, peak_value)) {
    849                     COMPILER_64_COPY(peak_value,
    850                                      stats_ptr->rx_pkt_count);
    851                     peak_offset = cur_offset;
    852                 }
    853             }
    854         } else {
    855             max_num_sample = buf_msg.host_buf_cur_offset;
    856             peak_offset = max_num_sample - cur_num_sample;
    857             cur_offset = peak_offset + 1;
    858             stats_ptr   = (bcm_sum_stat_info_t *)
    859                   &sum_info->host_buffer[peak_offset];
    860             COMPILER_64_COPY(peak_value,
    861                              stats_ptr->rx_pkt_count);
    862             for (; cur_offset < max_num_sample; ++cur_offset) {
    863                 stats_ptr   = (bcm_sum_stat_info_t *)
    864                       &sum_info->host_buffer[cur_offset];
    865                 if (COMPILER_64_GT(stats_ptr->rx_pkt_count, peak_value)) {
    866                     COMPILER_64_COPY(peak_value,
    867                                      stats_ptr->rx_pkt_count);
    868                     peak_offset = cur_offset;
    869                 }
    870             }
    871         }
    872         stats_ptr   = (bcm_sum_stat_info_t *)
    873               &sum_info->host_buffer[peak_offset];
    874         sal_memcpy(&stats_data[*num_samples], stats_ptr, SUM_STAT_SIZE);
    875         stats_data[*num_samples].sum_type = bcmSumTypeRxPktCnt;
    876         *num_samples = (*num_samples + 1);
    877     }
    878 
    879     if (((global_config->sum_type == bcmSumTypeTxByteCnt) ||
    880          (global_config->sum_type == bcmSumTypeTxPktByteCnt) ||
    881          (global_config->sum_type == bcmSumTypeRxTxByteCnt) ||
    882          (global_config->sum_type == bcmSumTypeTxRxPktByteCnt)) &&
    883         (*num_samples < max_samples)) {
    884         if (cur_num_sample > buf_msg.host_buf_cur_offset) {
    885             max_num_sample = buf_msg.host_buf_cur_offset;
    886             peak_offset = 0;
    887             stats_ptr   = (bcm_sum_stat_info_t *)
    888                   &sum_info->host_buffer[peak_offset];
    889             COMPILER_64_COPY(peak_value,
    890                              stats_ptr->tx_byte_count);
    891             for (cur_offset = 1; cur_offset < max_num_sample; ++cur_offset) {
    892                 stats_ptr   = (bcm_sum_stat_info_t *)
    893                       &sum_info->host_buffer[cur_offset];
    894                 if (COMPILER_64_GT(stats_ptr->tx_byte_count, peak_value)) {
    895                     COMPILER_64_COPY(peak_value,
    896                                      stats_ptr->tx_byte_count);
    897                     peak_offset = cur_offset;
    898                 }
    899             }
    900             cur_offset     = (global_config->max_history -
    901                               (cur_num_sample - max_num_sample));
    902             for (; cur_offset < global_config->max_history; ++cur_offset) {
    903                 stats_ptr   = (bcm_sum_stat_info_t *)
    904                       &sum_info->host_buffer[cur_offset];
    905                 if (COMPILER_64_GT(stats_ptr->tx_byte_count, peak_value)) {
    906                     COMPILER_64_COPY(peak_value,
    907                                      stats_ptr->tx_byte_count);
    908                     peak_offset = cur_offset;
    909                 }
    910             }
    911         } else {
    912             max_num_sample = buf_msg.host_buf_cur_offset;
    913             peak_offset = max_num_sample - cur_num_sample;
    914             cur_offset = peak_offset + 1;
    915             stats_ptr   = (bcm_sum_stat_info_t *)
    916                   &sum_info->host_buffer[peak_offset];
    917             COMPILER_64_COPY(peak_value,
    918                              stats_ptr->tx_byte_count);
    919             for (; cur_offset < max_num_sample; ++cur_offset) {
    920                 stats_ptr   = (bcm_sum_stat_info_t *)
    921                       &sum_info->host_buffer[cur_offset];
    922                 if (COMPILER_64_GT(stats_ptr->tx_byte_count, peak_value)) {
    923                     COMPILER_64_COPY(peak_value,
    924                                      stats_ptr->tx_byte_count);
    925                     peak_offset = cur_offset;
    926                 }
    927             }
    928         }
    929         stats_ptr   = (bcm_sum_stat_info_t *)
    930               &sum_info->host_buffer[peak_offset];
    931         sal_memcpy(&stats_data[*num_samples], stats_ptr, SUM_STAT_SIZE);
    932         stats_data[*num_samples].sum_type = bcmSumTypeTxByteCnt;
    933         *num_samples = (*num_samples + 1);
    934     }
    935 
    936     if (((global_config->sum_type == bcmSumTypeRxByteCnt) ||
    937          (global_config->sum_type == bcmSumTypeRxPktByteCnt) ||
    938          (global_config->sum_type == bcmSumTypeRxTxByteCnt) ||
    939          (global_config->sum_type == bcmSumTypeTxRxPktByteCnt)) &&
    940         (*num_samples < max_samples)) {
    941         if (cur_num_sample > buf_msg.host_buf_cur_offset) {
    942             max_num_sample = buf_msg.host_buf_cur_offset;
    943             peak_offset = 0;
    944             stats_ptr   = (bcm_sum_stat_info_t *)
    945                   &sum_info->host_buffer[peak_offset];
    946             COMPILER_64_COPY(peak_value,
    947                              stats_ptr->rx_byte_count);
    948             for (cur_offset = 1; cur_offset < max_num_sample; ++cur_offset) {
    949                 stats_ptr   = (bcm_sum_stat_info_t *)
    950                       &sum_info->host_buffer[cur_offset];
    951                 if (COMPILER_64_GT(stats_ptr->rx_byte_count, peak_value)) {
    952                     COMPILER_64_COPY(peak_value,
    953                                      stats_ptr->rx_byte_count);
    954                     peak_offset = cur_offset;
    955                 }
    956             }
    957             cur_offset     = (global_config->max_history -
    958                               (cur_num_sample - max_num_sample));
    959             for (; cur_offset < global_config->max_history; ++cur_offset) {
    960                 stats_ptr   = (bcm_sum_stat_info_t *)
    961                       &sum_info->host_buffer[cur_offset];
    962                 if (COMPILER_64_GT(stats_ptr->rx_byte_count, peak_value)) {
    963                     COMPILER_64_COPY(peak_value,
    964                                      stats_ptr->rx_byte_count);
    965                     peak_offset = cur_offset;
    966                 }
    967             }
    968         } else {
    969             max_num_sample = buf_msg.host_buf_cur_offset;
    970             peak_offset = max_num_sample - cur_num_sample;
    971             cur_offset = peak_offset + 1;
    972             stats_ptr   = (bcm_sum_stat_info_t *)
    973                   &sum_info->host_buffer[peak_offset];
    974             COMPILER_64_COPY(peak_value,
    975                              stats_ptr->rx_byte_count);
    976             for (; cur_offset < max_num_sample; ++cur_offset) {
    977                 stats_ptr   = (bcm_sum_stat_info_t *)
    978                       &sum_info->host_buffer[cur_offset];
    979                 if (COMPILER_64_GT(stats_ptr->rx_byte_count, peak_value)) {
    980                     COMPILER_64_COPY(peak_value,
    981                                      stats_ptr->rx_byte_count);
    982                     peak_offset = cur_offset;
    983                 }
    984             }
    985         }
    986         stats_ptr   = (bcm_sum_stat_info_t *)
    987               &sum_info->host_buffer[peak_offset];
    988         sal_memcpy(&stats_data[*num_samples], stats_ptr, SUM_STAT_SIZE);
    989         stats_data[*num_samples].sum_type = bcmSumTypeRxByteCnt;
    990         *num_samples = (*num_samples + 1);
    991     }
    992 
    993     return BCM_E_NONE;
    994 }
    995 
    996 STATIC int
    997 bcm_sum_mini_stat_info_get(int unit,
    998                            uint32 max_samples,
    999                            bcm_sum_stat_info_t *stats_data,
   1000                            uint32 *num_samples,
   1001                            uint32 sample_period)
   1002 {
   1003     shr_sum_msg_buf_info_t    buf_msg;
   1004     _bcm_int_sum_info_t       *sum_info = SUM_INFO_GET(unit);
   1005     bcm_sum_config_t *global_config = (&(sum_global_config[unit]));
   1006     uint8 *buffer_req = NULL, *buffer_ptr = NULL;
   1007     uint16 buffer_len = 0, reply_len = 0;
   1008     uint32 cur_num_sample, mini_offset, cur_offset, max_num_sample;
   1009     uint64 mini_value;
   1010     bcm_sum_stat_info_t *stats_ptr =  NULL;
   1011 
   1012     sal_memset(stats_data, 0, (max_samples * SUM_STAT_SIZE));
   1013     sal_memset(&buf_msg, 0, sizeof(buf_msg));
   1014 
   1015     /* Get stats configuration data from uC */
   1016     BCM_IF_ERROR_RETURN(_bcm_sum_msg_send_receive(unit, MOS_MSG_SUBCLASS_SUM_STAT_GET,
   1017                                                   buffer_len, 0,
   1018                                                   MOS_MSG_SUBCLASS_SUM_STAT_GET_REPLY, &reply_len,
   1019                                                   SHR_SUM_MAX_UC_MSG_TIMEOUT));
   1020     buffer_req      = sum_info->dma_buffer;
   1021     buffer_ptr      = shr_sum_msg_ctrl_stat_config_unpack(buffer_req, &buf_msg);
   1022     buffer_len      = buffer_ptr - buffer_req;
   1023 
   1024     if (reply_len != buffer_len) {
   1025         return BCM_E_INTERNAL;
   1026     }
   1027     if (buf_msg.host_buf_status) {
   1028         cur_num_sample = global_config->max_history;
   1029     } else {
   1030         cur_num_sample = buf_msg.host_buf_cur_offset;
   1031     }
   1032 
   1033     if (!cur_num_sample) {
   1034         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
   1035                   "SUM App No sample avaliable yet\n")));
   1036         return BCM_E_NONE;
   1037     }
   1038 
   1039     if (cur_num_sample > (sample_period / buf_msg.sample_interval)) {
   1040         cur_num_sample = (sample_period / buf_msg.sample_interval);
   1041     }
   1042 
   1043     if (!cur_num_sample) {
   1044         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
   1045                         "SUM App usec sample period %d too low than sample interval: %d \n"),
   1046                         sample_period, buf_msg.sample_interval));
   1047         return BCM_E_PARAM;
   1048     }
   1049 
   1050     *num_samples = 0;
   1051     if ((global_config->sum_type == bcmSumTypeTxPktCnt) ||
   1052         (global_config->sum_type == bcmSumTypeTxPktByteCnt) ||
   1053         (global_config->sum_type == bcmSumTypeRxTxPktCnt) ||
   1054         (global_config->sum_type == bcmSumTypeTxRxPktByteCnt)) {
   1055         if (cur_num_sample > buf_msg.host_buf_cur_offset) {
   1056             max_num_sample = buf_msg.host_buf_cur_offset;
   1057             mini_offset = 0;
   1058             stats_ptr   = (bcm_sum_stat_info_t *)
   1059                   &sum_info->host_buffer[mini_offset];
   1060             COMPILER_64_COPY(mini_value,
   1061                              stats_ptr->tx_pkt_count);
   1062             for (cur_offset = 1; cur_offset < max_num_sample; ++cur_offset) {
   1063                 stats_ptr   = (bcm_sum_stat_info_t *)
   1064                       &sum_info->host_buffer[cur_offset];
   1065                 if (COMPILER_64_LT(stats_ptr->tx_pkt_count, mini_value)) {
   1066                     COMPILER_64_COPY(mini_value,
   1067                                      stats_ptr->tx_pkt_count);
   1068                     mini_offset = cur_offset;
   1069                 }
   1070             }
   1071             cur_offset     = (global_config->max_history -
   1072                               (cur_num_sample - max_num_sample));
   1073             for (; cur_offset < global_config->max_history; ++cur_offset) {
   1074                 stats_ptr   = (bcm_sum_stat_info_t *)
   1075                       &sum_info->host_buffer[cur_offset];
   1076                 if (COMPILER_64_LT(stats_ptr->tx_pkt_count, mini_value)) {
   1077                     COMPILER_64_COPY(mini_value,
   1078                                      stats_ptr->tx_pkt_count);
   1079                     mini_offset = cur_offset;
   1080                 }
   1081             }
   1082         } else {
   1083             max_num_sample = buf_msg.host_buf_cur_offset;
   1084             mini_offset = max_num_sample - cur_num_sample;
   1085             cur_offset = mini_offset + 1;
   1086             stats_ptr   = (bcm_sum_stat_info_t *)
   1087                   &sum_info->host_buffer[mini_offset];
   1088             COMPILER_64_COPY(mini_value,
   1089                              stats_ptr->tx_pkt_count);
   1090             for (; cur_offset < max_num_sample; ++cur_offset) {
   1091                 stats_ptr   = (bcm_sum_stat_info_t *)
   1092                       &sum_info->host_buffer[cur_offset];
   1093                 if (COMPILER_64_LT(stats_ptr->tx_pkt_count, mini_value)) {
   1094                     COMPILER_64_COPY(mini_value,
   1095                                      stats_ptr->tx_pkt_count);
   1096                     mini_offset = cur_offset;
   1097                 }
   1098             }
   1099         }
   1100         stats_ptr   = (bcm_sum_stat_info_t *)
   1101               &sum_info->host_buffer[mini_offset];
   1102         sal_memcpy(&stats_data[*num_samples], stats_ptr, SUM_STAT_SIZE);
   1103         stats_data[*num_samples].sum_type = bcmSumTypeTxPktCnt;
   1104         *num_samples = (*num_samples + 1);
   1105     }
   1106 
   1107     if (((global_config->sum_type == bcmSumTypeRxPktCnt) ||
   1108          (global_config->sum_type == bcmSumTypeRxPktByteCnt) ||
   1109          (global_config->sum_type == bcmSumTypeRxTxPktCnt) ||
   1110          (global_config->sum_type == bcmSumTypeTxRxPktByteCnt)) &&
   1111         (*num_samples < max_samples)) {
   1112         if (cur_num_sample > buf_msg.host_buf_cur_offset) {
   1113             max_num_sample = buf_msg.host_buf_cur_offset;
   1114             mini_offset = 0;
   1115             stats_ptr   = (bcm_sum_stat_info_t *)
   1116                   &sum_info->host_buffer[mini_offset];
   1117             COMPILER_64_COPY(mini_value,
   1118                              stats_ptr->rx_pkt_count);
   1119             for (cur_offset = 1; cur_offset < max_num_sample; ++cur_offset) {
   1120                 stats_ptr   = (bcm_sum_stat_info_t *)
   1121                       &sum_info->host_buffer[cur_offset];
   1122                 if (COMPILER_64_LT(stats_ptr->rx_pkt_count, mini_value)) {
   1123                     COMPILER_64_COPY(mini_value,
   1124                                      stats_ptr->rx_pkt_count);
   1125                     mini_offset = cur_offset;
   1126                 }
   1127             }
   1128             cur_offset     = (global_config->max_history -
   1129                               (cur_num_sample - max_num_sample));
   1130             for (; cur_offset < global_config->max_history; ++cur_offset) {
   1131                 stats_ptr   = (bcm_sum_stat_info_t *)
   1132                       &sum_info->host_buffer[cur_offset];
   1133                 if (COMPILER_64_LT(stats_ptr->rx_pkt_count, mini_value)) {
   1134                     COMPILER_64_COPY(mini_value,
   1135                                      stats_ptr->rx_pkt_count);
   1136                     mini_offset = cur_offset;
   1137                 }
   1138             }
   1139         } else {
   1140             max_num_sample = buf_msg.host_buf_cur_offset;
   1141             mini_offset = max_num_sample - cur_num_sample;
   1142             cur_offset = mini_offset + 1;
   1143             stats_ptr   = (bcm_sum_stat_info_t *)
   1144                   &sum_info->host_buffer[mini_offset];
   1145             COMPILER_64_COPY(mini_value,
   1146                              stats_ptr->rx_pkt_count);
   1147             for (; cur_offset < max_num_sample; ++cur_offset) {
   1148                 stats_ptr   = (bcm_sum_stat_info_t *)
   1149                       &sum_info->host_buffer[cur_offset];
   1150                 if (COMPILER_64_LT(stats_ptr->rx_pkt_count, mini_value)) {
   1151                     COMPILER_64_COPY(mini_value,
   1152                                      stats_ptr->rx_pkt_count);
   1153                     mini_offset = cur_offset;
   1154                 }
   1155             }
   1156         }
   1157         stats_ptr   = (bcm_sum_stat_info_t *)
   1158               &sum_info->host_buffer[mini_offset];
   1159         sal_memcpy(&stats_data[*num_samples], stats_ptr, SUM_STAT_SIZE);
   1160         stats_data[*num_samples].sum_type = bcmSumTypeRxPktCnt;
   1161         *num_samples = (*num_samples + 1);
   1162     }
   1163 
   1164     if (((global_config->sum_type == bcmSumTypeTxByteCnt) ||
   1165          (global_config->sum_type == bcmSumTypeTxPktByteCnt) ||
   1166          (global_config->sum_type == bcmSumTypeRxTxByteCnt) ||
   1167          (global_config->sum_type == bcmSumTypeTxRxPktByteCnt)) &&
   1168         (*num_samples < max_samples)) {
   1169         if (cur_num_sample > buf_msg.host_buf_cur_offset) {
   1170             max_num_sample = buf_msg.host_buf_cur_offset;
   1171             mini_offset = 0;
   1172             stats_ptr   = (bcm_sum_stat_info_t *)
   1173                   &sum_info->host_buffer[mini_offset];
   1174             COMPILER_64_COPY(mini_value,
   1175                              stats_ptr->tx_byte_count);
   1176             for (cur_offset = 1; cur_offset < max_num_sample; ++cur_offset) {
   1177                 stats_ptr   = (bcm_sum_stat_info_t *)
   1178                       &sum_info->host_buffer[cur_offset];
   1179                 if (COMPILER_64_LT(stats_ptr->tx_byte_count, mini_value)) {
   1180                     COMPILER_64_COPY(mini_value,
   1181                                      stats_ptr->tx_byte_count);
   1182                     mini_offset = cur_offset;
   1183                 }
   1184             }
   1185             cur_offset     = (global_config->max_history -
   1186                               (cur_num_sample - max_num_sample));
   1187             for (; cur_offset < global_config->max_history; ++cur_offset) {
   1188                 stats_ptr   = (bcm_sum_stat_info_t *)
   1189                       &sum_info->host_buffer[cur_offset];
   1190                 if (COMPILER_64_LT(stats_ptr->tx_byte_count, mini_value)) {
   1191                     COMPILER_64_COPY(mini_value,
   1192                                      stats_ptr->tx_byte_count);
   1193                     mini_offset = cur_offset;
   1194                 }
   1195             }
   1196         } else {
   1197             max_num_sample = buf_msg.host_buf_cur_offset;
   1198             mini_offset = max_num_sample - cur_num_sample;
   1199             cur_offset = mini_offset + 1;
   1200             stats_ptr   = (bcm_sum_stat_info_t *)
   1201                   &sum_info->host_buffer[mini_offset];
   1202             COMPILER_64_COPY(mini_value,
   1203                              stats_ptr->tx_byte_count);
   1204             for (; cur_offset < max_num_sample; ++cur_offset) {
   1205                 stats_ptr   = (bcm_sum_stat_info_t *)
   1206                       &sum_info->host_buffer[cur_offset];
   1207                 if (COMPILER_64_LT(stats_ptr->tx_byte_count, mini_value)) {
   1208                     COMPILER_64_COPY(mini_value,
   1209                                      stats_ptr->tx_byte_count);
   1210                     mini_offset = cur_offset;
   1211                 }
   1212             }
   1213         }
   1214         stats_ptr   = (bcm_sum_stat_info_t *)
   1215               &sum_info->host_buffer[mini_offset];
   1216         sal_memcpy(&stats_data[*num_samples], stats_ptr, SUM_STAT_SIZE);
   1217         stats_data[*num_samples].sum_type = bcmSumTypeTxByteCnt;
   1218         *num_samples = (*num_samples + 1);
   1219     }
   1220 
   1221     if (((global_config->sum_type == bcmSumTypeRxByteCnt) ||
   1222          (global_config->sum_type == bcmSumTypeRxPktByteCnt) ||
   1223          (global_config->sum_type == bcmSumTypeRxTxByteCnt) ||
   1224          (global_config->sum_type == bcmSumTypeTxRxPktByteCnt)) &&
   1225         (*num_samples < max_samples)) {
   1226         if (cur_num_sample > buf_msg.host_buf_cur_offset) {
   1227             max_num_sample = buf_msg.host_buf_cur_offset;
   1228             mini_offset = 0;
   1229             stats_ptr   = (bcm_sum_stat_info_t *)
   1230                   &sum_info->host_buffer[mini_offset];
   1231             COMPILER_64_COPY(mini_value,
   1232                              stats_ptr->rx_byte_count);
   1233             for (cur_offset = 1; cur_offset < max_num_sample; ++cur_offset) {
   1234                 stats_ptr   = (bcm_sum_stat_info_t *)
   1235                       &sum_info->host_buffer[cur_offset];
   1236                 if (COMPILER_64_LT(stats_ptr->rx_byte_count, mini_value)) {
   1237                     COMPILER_64_COPY(mini_value,
   1238                                      stats_ptr->rx_byte_count);
   1239                     mini_offset = cur_offset;
   1240                 }
   1241             }
   1242             cur_offset     = (global_config->max_history -
   1243                               (cur_num_sample - max_num_sample));
   1244             for (; cur_offset < global_config->max_history; ++cur_offset) {
   1245                 stats_ptr   = (bcm_sum_stat_info_t *)
   1246                       &sum_info->host_buffer[cur_offset];
   1247                 if (COMPILER_64_LT(stats_ptr->rx_byte_count, mini_value)) {
   1248                     COMPILER_64_COPY(mini_value,
   1249                                      stats_ptr->rx_byte_count);
   1250                     mini_offset = cur_offset;
   1251                 }
   1252             }
   1253         } else {
   1254             max_num_sample = buf_msg.host_buf_cur_offset;
   1255             mini_offset = max_num_sample - cur_num_sample;
   1256             cur_offset = mini_offset + 1;
   1257             stats_ptr   = (bcm_sum_stat_info_t *)
   1258                   &sum_info->host_buffer[mini_offset];
   1259             COMPILER_64_COPY(mini_value,
   1260                              stats_ptr->rx_byte_count);
   1261             for (; cur_offset < max_num_sample; ++cur_offset) {
   1262                 stats_ptr   = (bcm_sum_stat_info_t *)
   1263                       &sum_info->host_buffer[cur_offset];
   1264                 if (COMPILER_64_LT(stats_ptr->rx_byte_count, mini_value)) {
   1265                     COMPILER_64_COPY(mini_value,
   1266                                      stats_ptr->rx_byte_count);
   1267                     mini_offset = cur_offset;
   1268                 }
   1269             }
   1270         }
   1271         stats_ptr   = (bcm_sum_stat_info_t *)
   1272               &sum_info->host_buffer[mini_offset];
   1273         sal_memcpy(&stats_data[*num_samples], stats_ptr, SUM_STAT_SIZE);
   1274         stats_data[*num_samples].sum_type = bcmSumTypeRxByteCnt;
   1275         *num_samples = (*num_samples + 1);
   1276     }
   1277 
   1278     return BCM_E_NONE;
   1279 }
   1280 
   1281 STATIC int
   1282 bcm_sum_usage_info_get(int unit,
   1283                        uint32 max_samples,
   1284                        bcm_sum_stat_info_t *stats_data,
   1285                        uint32 *num_samples,
   1286                        uint32 sample_period)
   1287 {
   1288     shr_sum_msg_buf_info_t    buf_msg;
   1289     _bcm_int_sum_info_t       *sum_info = SUM_INFO_GET(unit);
   1290     bcm_sum_config_t *global_config = (&(sum_global_config[unit]));
   1291     uint8 *buffer_req = NULL, *buffer_ptr = NULL;
   1292     uint16 buffer_len = 0, reply_len = 0;
   1293     uint32 cur_num_sample, cur_offset;
   1294     bcm_sum_stat_info_t *stats_ptr =  NULL;
   1295 
   1296     sal_memset(stats_data, 0, (max_samples * SUM_STAT_SIZE));
   1297     sal_memset(&buf_msg, 0, sizeof(buf_msg));
   1298 
   1299     /* Get stats configuration data from uC */
   1300     BCM_IF_ERROR_RETURN(_bcm_sum_msg_send_receive(unit, MOS_MSG_SUBCLASS_SUM_STAT_GET,
   1301                                                   buffer_len, 0,
   1302                                                   MOS_MSG_SUBCLASS_SUM_STAT_GET_REPLY, &reply_len,
   1303                                                   SHR_SUM_MAX_UC_MSG_TIMEOUT));
   1304     buffer_req      = sum_info->dma_buffer;
   1305     buffer_ptr      = shr_sum_msg_ctrl_stat_config_unpack(buffer_req, &buf_msg);
   1306     buffer_len      = buffer_ptr - buffer_req;
   1307 
   1308     if (reply_len != buffer_len) {
   1309         return BCM_E_INTERNAL;
   1310     }
   1311     if (!max_samples) {
   1312         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
   1313                   "SUM App No sample avaliable yet\n")));
   1314         return BCM_E_NONE;
   1315     }
   1316 
   1317     if (max_samples > (sample_period / buf_msg.sample_interval)) {
   1318         max_samples = (sample_period / buf_msg.sample_interval);
   1319     }
   1320     if (!max_samples) {
   1321         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
   1322                         "SUM App usec sample period %d too low than sample interval: %d \n"),
   1323                         sample_period, buf_msg.sample_interval));
   1324         return BCM_E_PARAM;
   1325     }
   1326 
   1327     if (buf_msg.host_buf_status) {
   1328         if (max_samples > global_config->max_history) {
   1329             *num_samples = global_config->max_history;
   1330         } else {
   1331             *num_samples = max_samples;
   1332         }
   1333 
   1334         cur_num_sample = buf_msg.host_buf_cur_offset;
   1335         if ((*num_samples) > cur_num_sample) {
   1336             cur_offset = (*num_samples) - cur_num_sample;
   1337             stats_ptr  = (bcm_sum_stat_info_t *)
   1338                    &sum_info->host_buffer[(global_config->max_history - 1 - cur_offset)];
   1339             sal_memcpy(stats_data, stats_ptr,
   1340                        (cur_offset * SUM_STAT_SIZE));
   1341             stats_ptr  = (bcm_sum_stat_info_t *)&sum_info->host_buffer[0];
   1342             sal_memcpy(&stats_data[cur_offset], stats_ptr,
   1343                        (cur_num_sample * SUM_STAT_SIZE));
   1344         } else {
   1345             cur_offset = cur_num_sample - (*num_samples);
   1346             stats_ptr  = (bcm_sum_stat_info_t *)
   1347                    &sum_info->host_buffer[cur_offset];
   1348             sal_memcpy(stats_data, stats_ptr, ((*num_samples) * SUM_STAT_SIZE));
   1349         }
   1350     } else {
   1351         cur_num_sample = buf_msg.host_buf_cur_offset;
   1352         if (cur_num_sample < max_samples) {
   1353             *num_samples = cur_num_sample;
   1354             stats_ptr  = (bcm_sum_stat_info_t *)&sum_info->host_buffer[0];
   1355             sal_memcpy(stats_data, stats_ptr,
   1356                        (cur_num_sample * SUM_STAT_SIZE));
   1357         } else {
   1358             cur_offset = cur_num_sample - max_samples;
   1359             *num_samples = max_samples;
   1360             stats_ptr  = (bcm_sum_stat_info_t *)
   1361                   &sum_info->host_buffer[cur_offset];
   1362             sal_memcpy(stats_data, stats_ptr,
   1363                        (max_samples * SUM_STAT_SIZE));
   1364         }
   1365     }
   1366 
   1367     return BCM_E_NONE;
   1368 }
   1369 
   1370 /*******************************************************
   1371  *                                                     *
   1372  *           SUM EMBEDDED APP TH3 APIs                 *
   1373  */
   1374 /*
   1375  * Function:
   1376  *      _bcm_th3_sum_detach
   1377  * Purpose:
   1378  *      Shut down the SUM app and SUM module.
   1379  * Parameters:
   1380  *      unit         - (IN) BCM device number
   1381  * Returns:
   1382  *      BCM_E_XXX   - BCM error code.
   1383  */
   1384 STATIC int
   1385 _bcm_th3_sum_detach(int unit)
   1386 {
   1387     /* De-init the embedded app */
   1388     int rv = BCM_E_NONE;
   1389     _bcm_int_sum_info_t *sum_info = SUM_INFO_GET(unit);
   1390 
   1391     if (sum_info == NULL) {
   1392         return BCM_E_NONE;
   1393     }
   1394 
   1395     rv = bcm_sum_eapp_detach(unit);
   1396     if (BCM_FAILURE(rv)) {
   1397         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
   1398                         "SUM: Failed to Detach")));
   1399         return rv;
   1400     }
   1401 
   1402     sal_free(sum_info);
   1403     sum_info              = NULL;
   1404     sum_global_info[unit] = NULL;
   1405 
   1406     return rv;
   1407 }
   1408 
   1409 /*
   1410  * Function:
   1411  *      _bcm_th3_sum_init
   1412  * Purpose:
   1413  *      Initializes the SUM module.
   1414  * Parameters:
   1415  *      unit         - (IN) BCM device number
   1416  * Returns:
   1417  *      BCM_E_XXX   - BCM error code.
   1418  */
   1419 STATIC int
   1420 _bcm_th3_sum_init(int unit)
   1421 {
   1422     /* Init the embedded app */
   1423     int rv = BCM_E_NONE;
   1424     _bcm_int_sum_info_t *sum_info = SUM_INFO_GET(unit);
   1425     int sum_enable = 0;
   1426 
   1427     sum_enable = soc_property_get(unit, spn_SUM_ENABLE, 0);
   1428     if (!sum_enable) {
   1429         /* Silently return since sum is not enabled */
   1430         return BCM_E_NONE;
   1431     }
   1432 
   1433     if (sum_info != NULL) {
   1434         BCM_IF_ERROR_RETURN(_bcm_th3_sum_detach(unit));
   1435         sum_info = NULL;
   1436     }
   1437 
   1438     _BCM_SUM_ALLOC(sum_info, _bcm_int_sum_info_t,
   1439                    sizeof(_bcm_int_sum_info_t), "SUM INFO");
   1440     if (sum_info == NULL) {
   1441         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
   1442                         "SUM: Failed to allocate memory")));
   1443         return BCM_E_MEMORY;
   1444     }
   1445     sum_global_info[unit] = sum_info;
   1446     sum_info->uc_num            = -1;
   1447     sum_info->host_buffer       = NULL;
   1448 
   1449 #ifdef BCM_WARM_BOOT_SUPPORT
   1450     if (SOC_WARM_BOOT(unit)) {
   1451         rv = _bcm_th3_sum_wb_recover(unit);
   1452         if (!(sum_info->status)) {
   1453             sal_free(sum_info);
   1454             sum_global_info[unit] = NULL;
   1455             return BCM_E_NONE;
   1456         }
   1457     } else {
   1458         rv = _bcm_th3_sum_scache_alloc(unit, 1);
   1459     }
   1460 #endif /* BCM_WARM_BOOT_SUPPORT */
   1461 
   1462     /*
   1463      * Allocate DMA buffer
   1464      *
   1465      * DMA buffer will be used to send and receive 'long' messages
   1466      * between SDK Host and uController (BTE).
   1467      */
   1468     sum_info->dma_buffer_len = sizeof(shr_sum_msg_ctrl_t);
   1469     sum_info->dma_buffer = soc_cm_salloc(unit, sum_info->dma_buffer_len,
   1470                                          "SUM DMA buffer allocate");
   1471     if (!sum_info->dma_buffer) {
   1472         BCM_IF_ERROR_RETURN(bcm_sum_eapp_detach(unit));
   1473         return BCM_E_MEMORY;
   1474     }
   1475     sal_memset(sum_info->dma_buffer, 0, sum_info->dma_buffer_len);
   1476 
   1477     rv = bcm_sum_eapp_init(unit);
   1478     if (BCM_FAILURE(rv)) {
   1479         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
   1480                         "SUM App Config set uc message communication failed \n")));
   1481         return rv;
   1482     }
   1483 
   1484     if (sum_info->uc_num == -1) {
   1485         /* Could not start SUM appl */
   1486         sal_free(sum_info);
   1487         sum_info = NULL;
   1488         sum_global_info[unit] = NULL;
   1489         return BCM_E_NONE;
   1490     }
   1491     sum_info->status = 1;
   1492 
   1493     return BCM_E_NONE;
   1494 }
   1495 
   1496 /*
   1497  * Function:
   1498  *      _bcm_th3_sum_config_set
   1499  * Purpose:
   1500  *      Set a SUM Configuration information
   1501  * Parameters:
   1502  *      unit            - (IN)  BCM device number
   1503  *      config          - (IN)  Configuration information
   1504  * Returns:
   1505  *      BCM_E_XXX   - BCM error code.
   1506  */
   1507 STATIC int
   1508 _bcm_th3_sum_config_set(int unit,
   1509                         bcm_sum_config_t *config,
   1510                         bcm_pbmp_t pbmp)
   1511 {
   1512     int                 rv = BCM_E_NONE;
   1513     _bcm_int_sum_info_t *sum_info = SUM_INFO_GET(unit);
   1514     bcm_sum_config_t    *global_config = (&(sum_global_config[unit]));
   1515     bcm_pbmp_t          *global_pbmp   = (&(sum_global_pbmp[unit]));
   1516     bcm_sum_stat_info_t *old_host_buffer_add;
   1517 
   1518     if (sum_info == NULL) {
   1519         return BCM_E_INIT;
   1520     }
   1521 
   1522     if (config == NULL) {
   1523         return BCM_E_PARAM;
   1524     }
   1525 
   1526     old_host_buffer_add = (bcm_sum_stat_info_t *)sum_info->host_buffer;
   1527     sal_memcpy(global_config, config, sizeof(bcm_sum_config_t));
   1528     BCM_PBMP_ASSIGN(*global_pbmp, pbmp);
   1529 
   1530     /* Inform SUM EAPP of the change/addition in/of configuration information */
   1531     rv = bcm_sum_eapp_config_msg(unit, config, pbmp, 0);
   1532 
   1533     if (BCM_FAILURE(rv)) {
   1534         LOG_ERROR(BSL_LS_BCM_SUM, (BSL_META_U(unit,
   1535                         "SUM App Config set uc communication failed \n")));
   1536         if (old_host_buffer_add != NULL)
   1537             soc_cm_sfree(unit, old_host_buffer_add);
   1538 
   1539         return rv;
   1540     }
   1541 
   1542     if (old_host_buffer_add != NULL)
   1543         soc_cm_sfree(unit, old_host_buffer_add);
   1544 
   1545     return rv;
   1546 }
   1547 
   1548 /*
   1549  * Function:
   1550  *      _bcm_th3_sum_config_get
   1551  * Purpose:
   1552  *      Get SUM configuration information
   1553  * Parameters:
   1554  *      unit             - (IN)  BCM device number
   1555  *      config           - (OUT)  Configuration information info
   1556  * Returns:
   1557  *      BCM_E_XXX   - BCM error code.
   1558  */
   1559 STATIC int
   1560 _bcm_th3_sum_config_get(int unit,
   1561                         bcm_sum_config_t *config,
   1562                         bcm_pbmp_t *pbmp)
   1563 {
   1564     int rv = BCM_E_NONE;
   1565     _bcm_int_sum_info_t *sum_info = SUM_INFO_GET(unit);
   1566     bcm_sum_config_t *global_config = NULL;
   1567     bcm_pbmp_t       *global_pbmp = NULL;
   1568 
   1569     if (sum_info == NULL) {
   1570         return BCM_E_INIT;
   1571     }
   1572 
   1573     global_config = (bcm_sum_config_t *)(&(sum_global_config[unit]));
   1574     if (global_config == NULL) {
   1575         return BCM_E_INIT;
   1576     }
   1577 
   1578     if ((config == NULL) ||
   1579         (pbmp == NULL)) {
   1580         return BCM_E_PARAM;
   1581     }
   1582 
   1583     global_pbmp = (bcm_pbmp_t *)(&(sum_global_pbmp[unit]));
   1584     if (global_pbmp == NULL) {
   1585         return BCM_E_INIT;
   1586     }
   1587     sal_memcpy(config, global_config, sizeof(bcm_sum_config_t));
   1588     BCM_PBMP_ASSIGN(*pbmp, *global_pbmp);
   1589 
   1590     return rv;
   1591 }
   1592 
   1593 /*
   1594  * Function:
   1595  *      _bcm_th3_sum_stat_info_get
   1596  * Purpose:
   1597  *      Get SUM statistics information data
   1598  * Parameters:
   1599  *      unit            - (IN)  BCM device number
   1600  *      stat_data       - (OUT) Statistics information data
   1601  * Returns:
   1602  *      BCM_E_XXX   - BCM error code.
   1603  */
   1604 STATIC int
   1605 _bcm_th3_sum_stat_info_get(int unit,
   1606                            uint32 max_samples,
   1607                            bcm_sum_stat_info_t *stats_data,
   1608                            uint32 *num_samples,
   1609                            bcm_sum_stat_type_t stat_type,
   1610                            uint32 usec_sample_period)
   1611 {
   1612     int rv = BCM_E_NONE;
   1613     _bcm_int_sum_info_t *sum_info = SUM_INFO_GET(unit);
   1614     bcm_sum_config_t *global_config = NULL;
   1615     bcm_pbmp_t       *global_pbmp = NULL;
   1616 
   1617     if (sum_info == NULL) {
   1618         return BCM_E_INIT;
   1619     }
   1620 
   1621     global_config = (bcm_sum_config_t *)(&(sum_global_config[unit]));
   1622     if (global_config == NULL) {
   1623         return BCM_E_INIT;
   1624     }
   1625 
   1626     global_pbmp = (bcm_pbmp_t *)(&(sum_global_pbmp[unit]));
   1627     if (global_pbmp == NULL) {
   1628         return BCM_E_INIT;
   1629     }
   1630 
   1631     if ((stats_data == NULL) ||
   1632         (max_samples < 1)) {
   1633         return BCM_E_PARAM;
   1634     }
   1635 
   1636     if (stat_type == bcmSumPeakUsageInfo) {
   1637         rv = bcm_sum_peak_stat_info_get(unit, max_samples,
   1638                                         stats_data, num_samples,
   1639                                         usec_sample_period);
   1640     } else if (stat_type == bcmSumMinimumUsageInfo) {
   1641         rv = bcm_sum_mini_stat_info_get(unit, max_samples,
   1642                                         stats_data, num_samples,
   1643                                         usec_sample_period);
   1644     } else  if (stat_type == bcmSumUsageInfo) {
   1645         rv = bcm_sum_usage_info_get(unit, max_samples,
   1646                                     stats_data, num_samples,
   1647                                     usec_sample_period);
   1648     } else {
   1649         return BCM_E_PARAM;
   1650     }
   1651 
   1652     return rv;
   1653 }
   1654 
   1655 int bcm_tomahawk3_sum_lock(int unit)
   1656 {
   1657     if (mutex[unit] == NULL) {
   1658         return BCM_E_INIT;
   1659     }
   1660 
   1661     sal_mutex_take(mutex[unit], sal_mutex_FOREVER);
   1662     return BCM_E_NONE;
   1663 }
   1664 
   1665 int bcm_tomahawk3_sum_unlock(int unit)
   1666 {
   1667     if (mutex[unit] == NULL) {
   1668         return BCM_E_INIT;
   1669     }
   1670 
   1671     if (sal_mutex_give(mutex[unit]) != 0) {
   1672         return BCM_E_INTERNAL;
   1673     }
   1674     return BCM_E_NONE;
   1675 }
   1676 #endif  /* INCLUDE_SUM */
   1677 
   1678 /*
   1679  * Function:
   1680  *      bcm_tomahawk3_sum_init
   1681  * Purpose:
   1682  *      Initializes the SUM module.
   1683  * Parameters:
   1684  *      unit         - (IN) BCM device number
   1685  * Returns:
   1686  *      BCM_E_XXX   - BCM error code.
   1687  */
   1688 int bcm_tomahawk3_sum_init(int unit)
   1689 {
   1690     int result = BCM_E_UNAVAIL;
   1691 #if defined(INCLUDE_SUM)
   1692     /* Create mutex */
   1693     if (mutex[unit] == NULL) {
   1694         mutex[unit] = sal_mutex_create("int.mutex");
   1695         if (mutex[unit] == NULL) {
   1696             return BCM_E_MEMORY;
   1697         }
   1698     }
   1699 
   1700     if (soc_feature(unit, soc_feature_sum)) {
   1701         result = _bcm_th3_sum_init(unit);
   1702     }
   1703 
   1704     /* If init itself fails, there is no point in having the mutex.
   1705      * Destroy it.
   1706      */
   1707     if (BCM_FAILURE(result)) {
   1708         sal_mutex_destroy(mutex[unit]);
   1709         mutex[unit] = NULL;
   1710     }
   1711 #endif  /* INCLUDE_SUM */
   1712     return result;
   1713 }
   1714 
   1715 /*
   1716  * Function:
   1717  *      bcm_tomahawk3_sum_detach
   1718  * Purpose:
   1719  *      Shut down the SUM app and SUM module. 
   1720  * Parameters:
   1721  *      unit         - (IN) BCM device number
   1722  * Returns:
   1723  *      BCM_E_XXX   - BCM error code.
   1724  */
   1725 int bcm_tomahawk3_sum_detach(int unit)
   1726 {
   1727     int result = BCM_E_UNAVAIL;
   1728 #if defined(INCLUDE_SUM)
   1729     /* Take lock */
   1730     BCM_IF_ERROR_RETURN(bcm_tomahawk3_sum_lock(unit));
   1731 
   1732     if (soc_feature(unit, soc_feature_sum)) {
   1733         result = _bcm_th3_sum_detach(unit);
   1734     }
   1735 
   1736     /* Release lock */
   1737     BCM_IF_ERROR_RETURN(bcm_tomahawk3_sum_unlock(unit));
   1738 #endif  /* INCLUDE_SUM */
   1739     return result;
   1740 }
   1741 
   1742 /*
   1743  * Function:
   1744  *      bcm_tomahawk3_sum_config_set
   1745  * Purpose:
   1746  *      Set a SUM Configuration information
   1747  * Parameters:
   1748  *      unit            - (IN)  BCM device number
   1749  *      config          - (IN)  Configuration information
   1750  * Returns:
   1751  *      BCM_E_XXX   - BCM error code.
   1752  */
   1753 int bcm_tomahawk3_sum_config_set(int unit,
   1754                                  bcm_sum_config_t *config_data,
   1755                                  bcm_pbmp_t pbmp)
   1756 {
   1757     int result = BCM_E_UNAVAIL;
   1758 #if defined(INCLUDE_SUM)
   1759     /* Take lock */
   1760     BCM_IF_ERROR_RETURN(bcm_tomahawk3_sum_lock(unit));
   1761 
   1762     /* SUM app config set API. */
   1763     if (soc_feature(unit, soc_feature_sum)) {
   1764         result = _bcm_th3_sum_config_set(unit,
   1765                                          config_data, pbmp);
   1766     }
   1767 
   1768     /* Release lock */
   1769     BCM_IF_ERROR_RETURN(bcm_tomahawk3_sum_unlock(unit));
   1770 #endif  /* INCLUDE_SUM */
   1771     return result;
   1772 }
   1773 
   1774 /*
   1775  * Function:
   1776  *      bcm_tomahawk3_sum_config_get
   1777  * Purpose:
   1778  *      Get SUM configuration information
   1779  * Parameters:
   1780  *      unit             - (IN)  BCM device number
   1781  *      config           - (OUT)  Configuration information info
   1782  * Returns:
   1783  *      BCM_E_XXX   - BCM error code.
   1784  */
   1785 int bcm_tomahawk3_sum_config_get(int unit,
   1786                                  bcm_sum_config_t *config_data,
   1787                                  bcm_pbmp_t *pbmp)
   1788 {
   1789     int result = BCM_E_UNAVAIL;
   1790 #if defined(INCLUDE_SUM)
   1791     /* Take lock */
   1792     BCM_IF_ERROR_RETURN(bcm_tomahawk3_sum_lock(unit));
   1793 
   1794     /* SUM app config get API. */
   1795     if (soc_feature(unit, soc_feature_sum)) {
   1796         result = _bcm_th3_sum_config_get(unit, config_data,
   1797                                          pbmp);
   1798     }
   1799 
   1800     /* Release lock */
   1801     BCM_IF_ERROR_RETURN(bcm_tomahawk3_sum_unlock(unit));
   1802 #endif  /* INCLUDE_SUM */
   1803     return result;
   1804 }
   1805 
   1806 /*
   1807  * Function:
   1808  *      bcm_tomahawk3_sum_stat_get
   1809  * Purpose:
   1810  *      Get SUM statistics information data
   1811  * Parameters:
   1812  *      unit            - (IN)  BCM device number
   1813  *      stat_data       - (OUT) Statistics information data
   1814  * Returns:
   1815  *      BCM_E_XXX   - BCM error code.
   1816  */
   1817 int bcm_tomahawk3_sum_stat_get(int unit,
   1818                                uint32 max_samples,
   1819                                bcm_sum_stat_info_t *stats_data,
   1820                                uint32 *num_samples,
   1821                                bcm_sum_stat_type_t stat_type,
   1822                                uint32 usec_sample_period)
   1823 {
   1824     int result = BCM_E_UNAVAIL;
   1825 #if defined(INCLUDE_SUM)
   1826     /* Take lock */
   1827     BCM_IF_ERROR_RETURN(bcm_tomahawk3_sum_lock(unit));
   1828 
   1829     /*  SUM app stats get API.  */
   1830     if (soc_feature(unit, soc_feature_sum)) {
   1831         result = _bcm_th3_sum_stat_info_get(unit, max_samples,
   1832                                             stats_data, num_samples,
   1833                                             stat_type,
   1834                                             usec_sample_period);
   1835     }
   1836 
   1837     /* Release lock */
   1838     BCM_IF_ERROR_RETURN(bcm_tomahawk3_sum_unlock(unit));
   1839 #endif  /* INCLUDE_SUM */
   1840     return result;
   1841 }
   1842 #else /* BCM_TOMAHAWK3_SUPPORT */
   1843 int _tomahawk3_sum_not_empty;
   1844 #endif /* BCM_TOMAHAWK3_SUPPORT */