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

preemption_cnt.c (11817B)


      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 #include <shared/bsl.h>
      8 #include <soc/drv.h>
      9 #include <bcm/port.h>
     10 #include <bcm/error.h>
     11 #include <bcm/types.h>
     12 #include <bcm_int/esw/preemption_cnt.h>
     13 #if defined(BCM_GREYHOUND2_SUPPORT)
     14 #include <bcm_int/esw/greyhound2.h>
     15 #endif
     16 
     17 #if defined(BCM_PREEMPTION_SUPPORT)
     18 /* preemption counter control data for each device */
     19 typedef struct bcmi_preemption_counter_control_s {
     20     sal_mutex_t counter_mutex;
     21     bcmi_preemption_counte_func_t dev_func;
     22 } bcmi_preemption_counter_control_t;
     23 STATIC bcmi_preemption_counter_control_t *preemption_counter_control
     24                                           [SOC_MAX_NUM_DEVICES];
     25 
     26 /* lock/uplock helper function */
     27 #define PREEMPTION_COUNTER_LOCK(_pc_) \
     28         sal_mutex_take((_pc_)->counter_mutex, sal_mutex_FOREVER);
     29 #define PREEMPTION_COUNTER_UNLOCK(_pc_) \
     30         sal_mutex_give((_pc_)->counter_mutex);
     31 
     32 /*
     33  * Function:
     34  *      bcmi_esw_preemption_counter_multi_get32
     35  * Purpose:
     36  *      Get 32-bit counter value for multiple port statistic types.
     37  * Parameters:
     38  *      unit       - (IN) Unit number.
     39  *      sync_mode  - (IN) hwcount is to be synced to sw count
     40  *      local_port - (IN) GPORT ID
     41  *      nstat      - (IN) Number of elements in stat array
     42  *      stat_arr   - (IN) New statistics descriptors array
     43  *      value_arr  - (OUT)New counters values
     44  * Returns:
     45  *      BCM_E_XXX
     46  * Notes:
     47  */
     48 int
     49 bcmi_esw_preemption_counter_multi_get32(int unit, int sync_mode,
     50                                         bcm_port_t local_port, int nstat,
     51                                         bcm_port_stat_t *stat_arr,
     52                                         uint32 *value_arr)
     53 {
     54     int i;
     55 
     56     if (NULL == stat_arr || NULL == value_arr) {
     57         return BCM_E_PARAM;
     58     }
     59     for (i = 0; i < nstat; i++) {
     60         BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_get32(unit, sync_mode,
     61                                                               local_port,
     62                                                               stat_arr[i],
     63                                                               &(value_arr[i])));
     64     }
     65     return BCM_E_NONE;
     66 }
     67 
     68 /*
     69  * Function:
     70  *      bcmi_esw_preemption_counter_multi_set32
     71  * Purpose:
     72  *      Set 32-bit counter value for multiple port statistic types.
     73  * Parameters:
     74  *      unit       - (IN) Unit number.
     75  *      local_port - (IN) GPORT ID
     76  *      nstat      - (IN) Number of elements in stat array
     77  *      stat_arr   - (IN) New statistics descriptors array
     78  *      value_arr  - (IN) New counters values
     79  * Returns:
     80  *      BCM_E_XXX
     81  * Notes:
     82  */
     83 int
     84 bcmi_esw_preemption_counter_multi_set32(int unit,
     85                                         bcm_port_t local_port, int nstat,
     86                                         bcm_port_stat_t *stat_arr,
     87                                         uint32 *value_arr)
     88 {
     89     int i;
     90 
     91     if (NULL == stat_arr || NULL == value_arr) {
     92         return BCM_E_PARAM;
     93     }
     94     for (i = 0; i < nstat; i++) {
     95         BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_set32(unit,
     96                                                               local_port,
     97                                                               stat_arr[i],
     98                                                               value_arr[i]));
     99     }
    100     return BCM_E_NONE;
    101 }
    102 
    103 /*
    104  * Function:
    105  *      bcmi_esw_preemption_counter_multi_get
    106  * Purpose:
    107  *      Get 64-bit counter value for multiple port statistic types.
    108  * Parameters:
    109  *      unit       - (IN) Unit number.
    110  *      sync_mode   - (IN) hwcount is to be synced to sw count
    111  *      local_port - (IN) GPORT ID
    112  *      nstat      - (IN) Number of elements in stat array
    113  *      stat_arr   - (IN) New statistics descriptors array
    114  *      value_arr  - (OUT)New counters values
    115  * Returns:
    116  *      BCM_E_XXX
    117  * Notes:
    118  */
    119 int
    120 bcmi_esw_preemption_counter_multi_get(int unit, int sync_mode,
    121                                       bcm_port_t local_port, int nstat,
    122                                       bcm_port_stat_t *stat_arr,
    123                                       uint64 *value_arr)
    124 {
    125     int i;
    126 
    127     if (NULL == stat_arr || NULL == value_arr) {
    128         return BCM_E_PARAM;
    129     }
    130     for (i = 0; i < nstat; i++) {
    131         BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_get(unit, sync_mode,
    132                                                             local_port,
    133                                                             stat_arr[i],
    134                                                             &(value_arr[i])));
    135     }
    136     return BCM_E_NONE;
    137 }
    138 
    139 /*
    140  * Function:
    141  *      bcmi_esw_preemption_counter_multi_set
    142  * Purpose:
    143  *      Set 64-bit counter value for multiple port statistic types.
    144  * Parameters:
    145  *      unit       - (IN) Unit number.
    146  *      local_port - (IN) GPORT ID
    147  *      nstat      - (IN) Number of elements in stat array
    148  *      stat_arr   - (IN) New statistics descriptors array
    149  *      value_arr  - (IN) New counters values
    150  * Returns:
    151  *      BCM_E_XXX
    152  * Notes:
    153  */
    154 int
    155 bcmi_esw_preemption_counter_multi_set(int unit,
    156                                       bcm_port_t local_port, int nstat,
    157                                       bcm_port_stat_t *stat_arr,
    158                                       uint64 *value_arr)
    159 {
    160     int i;
    161 
    162     if (NULL == stat_arr || NULL == value_arr) {
    163         return BCM_E_PARAM;
    164     }
    165     for (i = 0; i < nstat; i++) {
    166         BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_set(unit,
    167                                                             local_port,
    168                                                             stat_arr[i],
    169                                                             value_arr[i]));
    170     }
    171     return BCM_E_NONE;
    172 }
    173 
    174 /*
    175  * Function:
    176  *      bcmi_esw_preemption_counter_get32
    177  * Purpose:
    178  *      Get lower 32-bit counter value for specified port statistic
    179  *      type.
    180  *      if sync_mode is set, sync the sw accumulated count
    181  *      with hw count value first, else return sw count.
    182  * Parameters:
    183  *      unit        - (IN) Unit number.
    184  *      sync_mode   - (IN) hwcount is to be synced to sw count
    185  *      local_port  - (IN) GPORT ID
    186  *      stat        - (IN) Type of the counter to retrieve.
    187  *      val         - (OUT) Pointer to a counter value.
    188  * Returns:
    189  *      BCM_E_XXX
    190  * Notes:
    191  */
    192 int
    193 bcmi_esw_preemption_counter_get32(int unit, int sync_mode, bcm_port_t local_port,
    194                                   bcm_port_stat_t stat, uint32 *val)
    195 {
    196     uint64 val64;
    197 
    198     if (NULL == val) {
    199         return BCM_E_PARAM;
    200     }
    201     BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_get(unit, sync_mode,
    202                                                         local_port,
    203                                                         stat, &val64));
    204     *val = COMPILER_64_LO(val64);
    205     return BCM_E_NONE;
    206 }
    207 
    208 /*
    209  * Function:
    210  *      bcmi_esw_preemption_counter_set32
    211  * Purpose:
    212  *      Set lower 32-bit counter value for specified port statistic
    213  *      type.
    214  * Parameters:
    215  *      unit        - (IN) Unit number.
    216  *      local_port  - (IN) GPORT ID
    217  *      stat        - (IN) Type of the counter to retrieve.
    218  *      val         - (OUT) Pointer to a counter value.
    219  * Returns:
    220  *      BCM_E_XXX
    221  * Notes:
    222  */
    223 int
    224 bcmi_esw_preemption_counter_set32(int unit, bcm_port_t local_port,
    225                                   bcm_port_stat_t stat, uint32 val)
    226 {
    227     uint64 val64;
    228 
    229     COMPILER_64_SET(val64, 0, val);
    230     BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_set(unit, local_port,
    231                                                         stat, val64));
    232     return BCM_E_NONE;
    233 }
    234 
    235 /*
    236  * Function:
    237  *      bcmi_esw_preemption_counter_get
    238  * Purpose:
    239  *      Get 64-bit counter value for specified port statistic type.
    240  *      if sync_mode is set, sync the sw accumulated count
    241  *      with hw count value first, else return sw count.
    242  * Parameters:
    243  *      unit        - (IN) Unit number.
    244  *      sync_mode   - (IN) hwcount is to be synced to sw count
    245  *      local_port  - (IN) GPORT ID
    246  *      stat        - (IN) Type of the counter to retrieve.
    247  *      val         - (OUT) Pointer to a counter value.
    248  * Returns:
    249  *      BCM_E_XXX
    250  * Notes:
    251  */
    252 int
    253 bcmi_esw_preemption_counter_get(int unit, int sync_mode, bcm_port_t local_port,
    254                                 bcm_port_stat_t stat, uint64 *val)
    255 {
    256     bcmi_preemption_counter_control_t *pc = preemption_counter_control[unit];
    257     int rv;
    258 
    259     if (NULL == pc) {
    260         return BCM_E_INIT;
    261     }
    262 
    263     PREEMPTION_COUNTER_LOCK(pc);
    264     rv = pc->dev_func.preemption_counter_get(unit, sync_mode, local_port,
    265                                              stat, val);
    266     PREEMPTION_COUNTER_UNLOCK(pc);
    267 
    268     return rv;
    269 }
    270 
    271 /*
    272  * Function:
    273  *      bcmi_esw_preemption_counter_set32
    274  * Purpose:
    275  *      Set 64-bit counter value for specified port statistic type.
    276  * Parameters:
    277  *      unit        - (IN) Unit number.
    278  *      local_port  - (IN) GPORT ID
    279  *      stat        - (IN) Type of the counter to retrieve.
    280  *      val         - (OUT) Pointer to a counter value.
    281  * Returns:
    282  *      BCM_E_XXX
    283  * Notes:
    284  */
    285 int
    286 bcmi_esw_preemption_counter_set(int unit, bcm_port_t local_port,
    287                                 bcm_port_stat_t stat, uint64 val)
    288 {
    289     bcmi_preemption_counter_control_t *pc = preemption_counter_control[unit];
    290     int rv;
    291 
    292     if (NULL == pc) {
    293         return BCM_E_INIT;
    294     }
    295 
    296     PREEMPTION_COUNTER_LOCK(pc);
    297     rv = pc->dev_func.preemption_counter_set(unit, local_port, stat, val);
    298     PREEMPTION_COUNTER_UNLOCK(pc);
    299 
    300     return rv;
    301 }
    302 
    303 /*
    304  * Function:
    305  *      bcmi_esw_preemption_counter_cleanup
    306  * Purpose:
    307  *      cleanup resource after detach
    308  * Parameters:
    309  *      unit        - (IN) Unit number.
    310  * Returns:
    311  *      BCM_E_XXX
    312  * Notes:
    313  */
    314 int
    315 bcmi_esw_preemption_counter_cleanup(int unit)
    316 {
    317     if (NULL != preemption_counter_control[unit]) {
    318         preemption_counter_control[unit]->dev_func.preemption_counter_clean(unit);
    319         if (NULL != preemption_counter_control[unit]->counter_mutex) {
    320             sal_mutex_destroy(preemption_counter_control[unit]->counter_mutex);
    321             preemption_counter_control[unit]->counter_mutex = NULL;
    322         }
    323         sal_free(preemption_counter_control[unit]);
    324         preemption_counter_control[unit] = NULL;
    325     }
    326     return BCM_E_NONE;
    327 }
    328 
    329 /*
    330  * Function:
    331  *      bcmi_esw_preemption_counter_init
    332  * Purpose:
    333  *      init premption counter module
    334  * Parameters:
    335  *      unit        - (IN) Unit number.
    336  * Returns:
    337  *      BCM_E_XXX
    338  * Notes:
    339  */
    340 int
    341 bcmi_esw_preemption_counter_init(int unit)
    342 {
    343     bcmi_preemption_counter_control_t *pc = NULL;
    344     int rv;
    345 
    346     if (NULL != preemption_counter_control[unit]) {
    347         bcmi_esw_preemption_counter_cleanup(unit);
    348     }
    349     preemption_counter_control[unit] =
    350         sal_alloc(sizeof(bcmi_preemption_counter_control_t),
    351                   "preemption counter control");
    352     pc = preemption_counter_control[unit];
    353     if (NULL == pc) {
    354         return BCM_E_MEMORY;
    355     }
    356     sal_memset(pc, 0, sizeof(bcmi_preemption_counter_control_t));
    357     pc->counter_mutex = sal_mutex_create("counter_mutex");
    358     if (NULL == pc->counter_mutex) {
    359         bcmi_esw_preemption_counter_cleanup(unit);
    360         return BCM_E_INTERNAL;
    361     }
    362 
    363     /* init chip-specific func */
    364     rv = BCM_E_UNAVAIL;
    365 #if defined(BCM_GREYHOUND2_SUPPORT)
    366     if (SOC_IS_GREYHOUND2(unit)) {
    367         rv = bcmi_gh2_preemption_counter_dev_func_init(&(pc->dev_func));
    368     }
    369 #endif
    370     if (BCM_FAILURE(rv)) {
    371         bcmi_esw_preemption_counter_cleanup(unit);
    372         return rv;
    373     }
    374 
    375     rv = pc->dev_func.preemption_counter_init(unit);
    376     if (BCM_FAILURE(rv)) {
    377         bcmi_esw_preemption_counter_cleanup(unit);
    378         return rv;
    379     }
    380 
    381     return BCM_E_NONE;
    382 }
    383 #endif /* BCM_PREEMPTION_SUPPORT */