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

pstats.c (15248B)


      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  * Packetized Statistic
      8  * Purpose: API to set Packetized Statistic registers.
      9  */
     10 
     11 #if defined(INCLUDE_PSTATS)
     12 
     13 #include <sal/core/libc.h>
     14 
     15 #include <soc/drv.h>
     16 #include <soc/mem.h>
     17 #include <soc/debug.h>
     18 
     19 #include <bcm/error.h>
     20 #include <bcm/pstats.h>
     21 
     22 #include <bcm_int/esw/pstats.h>
     23 #include <bcm_int/esw/trident3.h>
     24 #include <bcm_int/esw/tomahawk2.h>
     25 #include <bcm_int/esw/helix5.h>
     26 #include <bcm_int/esw/tomahawk3.h>
     27 #include <bcm_int/esw_dispatch.h>
     28 
     29 #ifdef BCM_WARM_BOOT_SUPPORT
     30 #include <bcm_int/esw/switch.h>
     31 #endif /* BCM_WARM_BOOT_SUPPORT */
     32 
     33 _bcm_pstats_unit_driver_t *_bcm_pstats_unit_driver[BCM_MAX_NUM_UNITS];
     34 
     35 
     36 /*
     37  * Function:
     38  *      _bcm_pstats_deinit
     39  * Purpose:
     40  *      Deinitialize PSTATS driver functions.
     41  * Parameters:
     42  *      unit - (IN) StrataSwitch unit number.
     43  * Returns:
     44  *      BCM_E_XXX
     45  */
     46 void _bcm_pstats_deinit(int unit)
     47 {
     48     _bcm_pstats_unit_driver_t   *pstats_driver;
     49 
     50     pstats_driver = _BCM_PSTATS_UNIT_DRIVER(unit);
     51     if (pstats_driver == NULL) {
     52         return;
     53     }
     54 
     55 #if defined(BCM_HELIX5_SUPPORT)
     56     if (SOC_IS_HELIX5(unit)) {
     57         (void )bcm_hx5_pstats_deinit(unit);
     58     }
     59 #endif
     60 
     61 #if defined(BCM_TRIDENT3_SUPPORT)
     62     if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_HELIX5(unit)) {
     63         (void )bcm_td3_pstats_deinit(unit);
     64     }
     65 #endif
     66 
     67 #if defined(BCM_TOMAHAWK2_SUPPORT)
     68     if (SOC_IS_TOMAHAWK2(unit)) {
     69         (void )bcm_th2_pstats_deinit(unit);
     70     }
     71 #endif
     72 #if defined(BCM_TOMAHAWK3_SUPPORT)
     73     if (SOC_IS_TOMAHAWK3(unit)) {
     74         (void )bcm_th3_pstats_deinit(unit);
     75     }
     76 #endif
     77 
     78     if (NULL != pstats_driver->pstats_lock) {
     79         sal_mutex_destroy(pstats_driver->pstats_lock);
     80     }
     81 
     82     if (NULL != pstats_driver) {
     83         sal_free(pstats_driver);
     84     }
     85     _BCM_PSTATS_UNIT_DRIVER(unit) = NULL;
     86 
     87     return;
     88 }
     89 
     90 
     91 /*
     92  * Function:
     93  *      _bcm_pstats_init
     94  * Purpose:
     95  *      Initialize PSTATS driver functions.
     96  * Parameters:
     97  *      unit - (IN) StrataSwitch unit number.
     98  * Returns:
     99  *      BCM_E_XXX
    100  */
    101 int _bcm_pstats_init(int unit)
    102 {
    103     _bcm_pstats_unit_driver_t   *pstats_driver;
    104     int                         pstats_supported = 0;
    105     int                         rv = BCM_E_NONE;
    106     _bcm_pstats_deinit(unit);
    107     pstats_driver = _BCM_PSTATS_UNIT_DRIVER(unit);
    108 
    109     if (NULL == pstats_driver) {
    110         pstats_driver = sal_alloc(sizeof(_bcm_pstats_unit_driver_t), "pstats_unit_driver");
    111         if (pstats_driver == NULL) {
    112             return BCM_E_MEMORY;
    113         }
    114     }
    115 
    116     sal_memset(pstats_driver, 0, sizeof(_bcm_pstats_unit_driver_t));
    117 
    118     _BCM_PSTATS_UNIT_DRIVER(unit) = pstats_driver;
    119 
    120     if (NULL == pstats_driver->pstats_lock) {
    121         pstats_driver->pstats_lock = sal_mutex_create("pstats_lock");
    122     }
    123 
    124     if (NULL == pstats_driver->pstats_lock) {
    125         (void)_bcm_pstats_deinit(unit);
    126         return BCM_E_MEMORY;
    127     }
    128 
    129 #if defined(BCM_HELIX5_SUPPORT)
    130     if (SOC_IS_HELIX5(unit)) {
    131         rv = bcm_hx5_pstats_init(unit);
    132         if (BCM_FAILURE(rv)) {
    133             (void)_bcm_pstats_deinit(unit);
    134             return rv;
    135         }
    136         pstats_supported = 1;
    137     }
    138 #endif
    139 
    140 #if defined(BCM_TRIDENT3_SUPPORT)
    141     if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_HELIX5(unit)) {
    142         rv = bcm_td3_pstats_init(unit);
    143         if (BCM_FAILURE(rv)) {
    144             (void)_bcm_pstats_deinit(unit);
    145             return rv;
    146         }
    147         pstats_supported = 1;
    148     }
    149 #endif
    150 
    151 #if defined(BCM_TOMAHAWK2_SUPPORT)
    152     if (SOC_IS_TOMAHAWK2(unit)) {
    153         rv = bcm_th2_pstats_init(unit);
    154         if (BCM_FAILURE(rv)) {
    155             (void)_bcm_pstats_deinit(unit);
    156             return rv;
    157         }
    158         pstats_supported = 1;
    159     }
    160 #endif
    161 
    162 #if defined(BCM_TOMAHAWK3_SUPPORT)
    163     if (SOC_IS_TOMAHAWK3(unit)) {
    164         rv = bcm_th3_pstats_init(unit);
    165         if (BCM_FAILURE(rv)) {
    166             (void)_bcm_pstats_deinit(unit);
    167             return rv;
    168         }
    169         pstats_supported = 1;
    170     }
    171 #endif
    172 
    173     if (pstats_supported == 0) {
    174         return BCM_E_UNAVAIL;
    175     }
    176     return rv;
    177 }
    178 /*
    179  * Function:
    180  *      bcm_esw_pstats_session_create
    181  * Purpose:
    182  *      Create a PSTATS session instance for SDK management.
    183  * Parameters:
    184  *      unit - (IN) StrataSwitch unit number.
    185  *      options - (IN) BCM_PSTATS_OPTIONS_REPLACE: replace existing.
    186  *                     BCM_PSTATS_OPTIONS_WITH_ID: session_id argument is given.
    187  *      array_count - (IN) Number of elements in array.
    188  *      element_array - (IN) PSTATS session element array.
    189  *      session_id - (INOUT) id of a PSTATS session created via this API.
    190  * Returns:
    191  *      BCM_E_XXX
    192  */
    193 int
    194 bcm_esw_pstats_session_create(int unit, int options, int array_count,
    195                               bcm_pstats_session_element_t  *element_array,
    196                               bcm_pstats_session_id_t *session_id)
    197 {
    198     int rv = BCM_E_NONE;
    199     if (!soc_feature(unit, soc_feature_pstats)) {
    200         return BCM_E_UNAVAIL;
    201     }
    202 
    203     if (_bcm_pstats_unit_driver[unit]->session_create == NULL) {
    204         return BCM_E_UNAVAIL;
    205     }
    206 
    207     PSTATS_LOCK(unit);
    208     rv = _bcm_pstats_unit_driver[unit]->session_create(unit, options,
    209                                                        array_count,
    210                                                        element_array,
    211                                                        session_id);
    212     PSTATS_UNLOCK(unit);
    213     return rv;
    214 }
    215 
    216 /*
    217  * Function:
    218  *      bcm_esw_pstats_session_destroy
    219  * Purpose:
    220  *      Destroy an existing PSTATS session.
    221  * Parameters:
    222  *      unit - (IN) StrataSwitch unit number.
    223  *      session_id - (IN) id of a PSTATS session created via the
    224  *                        bcm_pstats_session_create
    225  * Returns:
    226  *      BCM_E_XXX
    227  */
    228 int
    229 bcm_esw_pstats_session_destroy(int unit,
    230                                bcm_pstats_session_id_t session_id)
    231 {
    232     int rv = BCM_E_NONE;
    233     if (!soc_feature(unit, soc_feature_pstats)) {
    234         return BCM_E_UNAVAIL;
    235     }
    236 
    237     if (_bcm_pstats_unit_driver[unit]->session_destroy == NULL) {
    238         return BCM_E_UNAVAIL;
    239     }
    240 
    241     PSTATS_LOCK(unit);
    242     rv = _bcm_pstats_unit_driver[unit]->session_destroy(unit, session_id);
    243     PSTATS_UNLOCK(unit);
    244     return rv;
    245 }
    246 
    247 /*
    248  * Function:
    249  *      bcm_esw_pstats_session_get
    250  * Purpose:
    251  *      Get an existing PSTATS session info.
    252  * Parameters:
    253  *      unit - (IN) StrataSwitch unit number.
    254  *      session_id - (IN) id of a PSTATS session created via the
    255  *                        bcm_pstats_session_create
    256  *      array_max - (IN) Maximum number of elements in array.
    257  *      element_array - (OUT) session elemnts array of a PSTATS session.
    258  *      array_count - (OUT) Number of elements in array.
    259  * Returns:
    260  *      BCM_E_XXX
    261  */
    262 int
    263 bcm_esw_pstats_session_get(int unit,
    264                            bcm_pstats_session_id_t session_id,
    265                            int array_max,
    266                            bcm_pstats_session_element_t *element_array,
    267                            int *array_count)
    268 {
    269     int rv = BCM_E_NONE;
    270     if (!soc_feature(unit, soc_feature_pstats)) {
    271         return BCM_E_UNAVAIL;
    272     }
    273 
    274     if (_bcm_pstats_unit_driver[unit]->session_get == NULL) {
    275         return BCM_E_UNAVAIL;
    276     }
    277 
    278     PSTATS_LOCK(unit);
    279     rv = _bcm_pstats_unit_driver[unit]->session_get(unit, session_id, array_max,
    280                                                     element_array,
    281                                                     array_count);
    282     PSTATS_UNLOCK(unit);
    283     return rv;
    284 }
    285 
    286 /*
    287  * Function:
    288  *      bcm_esw_pstats_data_sync
    289  * Purpose:
    290  *      Start a pstats sync operation.
    291  * Parameters:
    292  *      unit - (IN) StrataSwitch unit number
    293  * Returns:
    294  *      BCM_E_XXX
    295  */
    296 int
    297 bcm_esw_pstats_data_sync(int unit)
    298 {
    299     int rv = BCM_E_NONE;
    300     if (!soc_feature(unit, soc_feature_pstats)) {
    301         return BCM_E_UNAVAIL;
    302     }
    303 
    304     if (_bcm_pstats_unit_driver[unit]->data_sync == NULL) {
    305         return BCM_E_UNAVAIL;
    306     }
    307 
    308     PSTATS_LOCK(unit);
    309     rv = _bcm_pstats_unit_driver[unit]->data_sync(unit);
    310     PSTATS_UNLOCK(unit);
    311     return rv;
    312 }
    313 
    314 /*
    315  * Function:
    316  *      bcm_esw_pstats_session_data_get
    317  * Purpose:
    318  *      Get an existing PSTATS session data.
    319  * Parameters:
    320  *      unit - (IN) StrataSwitch unit number
    321  *      session_id - (IN) id of a PSTATS session created via the
    322  *                        bcm_pstats_session_create
    323  *      timestamp - (OUT) time stamp info.
    324  *      array_max - (IN) Maximum number of elements in array.
    325  *      data - (OUT) array of use count data.
    326  *      array_count - (OUT) Number of elements in array.
    327  * Returns:
    328  *      BCM_E_XXX
    329  */
    330 int
    331 bcm_esw_pstats_session_data_get(int unit, bcm_pstats_session_id_t session_id,
    332                                 bcm_pstats_timestamp_t *timestamp,
    333                                 int array_max,
    334                                 bcm_pstats_data_t *data_array,
    335                                 int *array_count)
    336 {
    337     int rv = BCM_E_NONE;
    338     if (!soc_feature(unit, soc_feature_pstats)) {
    339         return BCM_E_UNAVAIL;
    340     }
    341 
    342     if (_bcm_pstats_unit_driver[unit]->session_data_get == NULL) {
    343         return BCM_E_UNAVAIL;
    344     }
    345 
    346     PSTATS_LOCK(unit);
    347     rv = _bcm_pstats_unit_driver[unit]->session_data_get(unit, session_id,
    348                                                          FALSE,
    349                                                          timestamp,
    350                                                          array_max,
    351                                                          data_array,
    352                                                          array_count);
    353     PSTATS_UNLOCK(unit);
    354     return rv;
    355 }
    356 
    357 /*
    358  * Function:
    359  *      bcm_esw_pstats_session_data_sync_get
    360  * Purpose:
    361  *      Get an existing PSTATS session data.
    362  * Parameters:
    363  *      unit - (IN) StrataSwitch unit number
    364  *      session_id - (IN) id of a PSTATS session created via the
    365  *                        bcm_pstats_session_create
    366  *      timestamp - (OUT) time stamp info.
    367  *      array_max - (IN) Maximum number of elements in array.
    368  *      data - (OUT) array of use count data.
    369  *      array_count - (OUT) Number of elements in array.
    370  * Returns:
    371  *      BCM_E_XXX
    372  */
    373 int
    374 bcm_esw_pstats_session_data_sync_get(int unit, bcm_pstats_session_id_t session_id,
    375                                      bcm_pstats_timestamp_t *timestamp,
    376                                      int array_max,
    377                                      bcm_pstats_data_t *data_array,
    378                                      int *array_count)
    379 {
    380     int rv = BCM_E_NONE;
    381     if (!soc_feature(unit, soc_feature_pstats)) {
    382         return BCM_E_UNAVAIL;
    383     }
    384 
    385     if (_bcm_pstats_unit_driver[unit]->session_data_get == NULL) {
    386         return BCM_E_UNAVAIL;
    387     }
    388 
    389     PSTATS_LOCK(unit);
    390     rv = _bcm_pstats_unit_driver[unit]->session_data_get(unit, session_id,
    391                                                          TRUE,
    392                                                          timestamp,
    393                                                          array_max,
    394                                                          data_array,
    395                                                          array_count);
    396     PSTATS_UNLOCK(unit);
    397     return rv;
    398 }
    399 
    400 /*
    401  * Function:
    402  *      bcm_pstats_session_data_clear
    403  * Purpose:
    404  *      Clear an existing PSTATS session hw use counts and sw use counts buffer.
    405  * Parameters:
    406  *      unit - (IN) StrataSwitch unit number.
    407  *      session_id - (IN) id of a PSTATS session created via the
    408  *                        bcm_pstats_session_create.
    409  * Returns:
    410  *      BCM_E_XXX
    411  */
    412 int
    413 bcm_esw_pstats_session_data_clear(int unit, bcm_pstats_session_id_t session_id)
    414 {
    415     int rv = BCM_E_NONE;
    416     if (!soc_feature(unit, soc_feature_pstats)) {
    417         return BCM_E_UNAVAIL;
    418     }
    419 
    420     if (_bcm_pstats_unit_driver[unit]->session_data_clear == NULL) {
    421         return BCM_E_UNAVAIL;
    422     }
    423 
    424     PSTATS_LOCK(unit);
    425     rv = _bcm_pstats_unit_driver[unit]->session_data_clear(unit, session_id);
    426     PSTATS_UNLOCK(unit);
    427     return rv;
    428 }
    429 
    430 #ifdef BCM_WARM_BOOT_SUPPORT
    431 /*
    432  * Function:
    433  *      _bcm_esw_pstats_scache_size_get
    434  * Purpose:
    435  *      Get scache size of PSTATS module persisitent info for Level 2 Warm Boot.
    436  * Parameters:
    437  *      unit - StrataSwitch unit number.
    438  *      scache_size - scache size.
    439  * Returns:
    440  *      BCM_E_XXX
    441  */
    442 int
    443 _bcm_esw_pstats_scache_size_get(int unit, uint32 *scache_size)
    444 {
    445     if (!soc_feature(unit, soc_feature_pstats)) {
    446         return BCM_E_UNAVAIL;
    447     }
    448     if (_bcm_pstats_unit_driver[unit]->scache_size_get == NULL) {
    449         return BCM_E_UNAVAIL;
    450     }
    451     return _bcm_pstats_unit_driver[unit]->scache_size_get(unit, scache_size);
    452 }
    453 /*
    454  * Function:
    455  *      _bcm_esw_pstats_reinit
    456  * Purpose:
    457  *      Reinit PSTATS module persisitent info for Level 2 Warm Boot.
    458  * Parameters:
    459  *      unit - StrataSwitch unit number.
    460  *      scache_ptr - scache pointer
    461  * Returns:
    462  *      BCM_E_XXX
    463  */
    464 int
    465 _bcm_esw_pstats_reinit(int unit, uint8 **scache_ptr)
    466 {
    467     if (!soc_feature(unit, soc_feature_pstats)) {
    468         return BCM_E_UNAVAIL;
    469     }
    470     if (_bcm_pstats_unit_driver[unit]->pstats_reinit == NULL) {
    471         return BCM_E_UNAVAIL;
    472     }
    473     return _bcm_pstats_unit_driver[unit]->pstats_reinit(unit, scache_ptr);
    474 }
    475 /*
    476  * Function:
    477  *      _bcm_esw_pstats_sync
    478  * Purpose:
    479  *      Record PSTATS module persisitent info for Level 2 Warm Boot.
    480  * Parameters:
    481  *      unit - StrataSwitch unit number.
    482  * Returns:
    483  *      BCM_E_XXX
    484  */
    485 int
    486 _bcm_esw_pstats_sync(int unit, uint8 **scache_ptr)
    487 {
    488     if (!soc_feature(unit, soc_feature_pstats)) {
    489         return BCM_E_UNAVAIL;
    490     }
    491     if (_bcm_pstats_unit_driver[unit]->pstats_sync == NULL) {
    492         return BCM_E_UNAVAIL;
    493     }
    494     return _bcm_pstats_unit_driver[unit]->pstats_sync(unit, scache_ptr);
    495 }
    496 #endif
    497 
    498 /*
    499  * Function:
    500  *      bcm_esw_pstats_session_traverse
    501  * Purpose:
    502  *      Traverse through the pstats sessions and run callback at each session.
    503  * Parameters:
    504  *      unit - (IN) StrataSwitch unit number.
    505  *      cb - (IN) bcm_pstats_session_traverse_cb.
    506  *      user_data - (IN) User data to be passed to callback function.
    507  * Returns:
    508  *      BCM_E_XXX
    509  */
    510 int
    511 bcm_esw_pstats_session_traverse(int unit, bcm_pstats_session_traverse_cb cb,
    512                             void *user_data)
    513 {
    514     int rv = BCM_E_NONE;
    515     if (!soc_feature(unit, soc_feature_pstats)) {
    516         return BCM_E_UNAVAIL;
    517     }
    518 
    519     if (_bcm_pstats_unit_driver[unit]->session_traverse == NULL) {
    520         return BCM_E_UNAVAIL;
    521     }
    522 
    523     PSTATS_LOCK(unit);
    524     rv = _bcm_pstats_unit_driver[unit]->session_traverse(unit, cb, user_data);
    525     PSTATS_UNLOCK(unit);
    526     return rv;
    527 }
    528 
    529 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP
    530 /*
    531  * Function:
    532  *     bcm_esw_pstats_sw_dump
    533  * Purpose:
    534  *     Displays PSTATS information maintained by software.
    535  * Parameters:
    536  *     unit - Device unit number
    537  * Returns:
    538  *     None
    539  */
    540 void
    541 _bcm_esw_pstats_sw_dump(int unit)
    542 {
    543     if (!soc_feature(unit, soc_feature_pstats)) {
    544         return;
    545     }
    546     if (_bcm_pstats_unit_driver[unit]->pstats_sw_dump == NULL) {
    547         return;
    548     }
    549     return _bcm_pstats_unit_driver[unit]->pstats_sw_dump(unit);
    550 }
    551 #endif
    552 
    553 #else  /* INCLUDE_PSTATS */
    554 int bcm_esw_pstats_not_empty;
    555 #endif /* INCLUDE_PSTATS */