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

tsn_taf.c (83651B)


      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  * Purpose:
      8  * Manage common functionality for TSN TAF implementation.
      9  */
     10 
     11 #include <shared/bsl.h>
     12 #include <soc/drv.h>
     13 #include <soc/scache.h>
     14 #include <bcm/port.h>
     15 #include <bcm/error.h>
     16 #include <bcm/types.h>
     17 #include <bcm/tsn.h>
     18 #include <bcm_int/esw/tsn.h>
     19 #include <bcm_int/esw/tsn_taf.h>
     20 #if defined(BCM_GREYHOUND2_SUPPORT)
     21 #include <bcm_int/esw/greyhound2.h>
     22 #endif /* BCM_GREYHOUND2_SUPPORT */
     23 #if defined(BCM_WARM_BOOT_SUPPORT)
     24 #include <bcm/module.h>
     25 #include <bcm_int/esw/switch.h>
     26 #endif /* BCM_WARM_BOOT_SUPPORT */
     27 
     28 #if defined(BCM_TSN_SUPPORT)
     29 typedef struct bcmi_tsn_taf_control_s {
     30     sal_mutex_t taf_mutex;
     31     const bcmi_tsn_taf_dev_info_t *taf_dev_info;
     32 } bcmi_tsn_taf_control_t;
     33 
     34 /* TSN stat control */
     35 STATIC bcmi_tsn_taf_control_t *taf_control[BCM_MAX_NUM_UNITS];
     36 
     37 /* TSN calendar profile */
     38 STATIC bcmi_tsn_taf_profile_t *taf_profile_pending
     39                                [SOC_MAX_NUM_DEVICES][BCMI_TSN_TAF_GATE_NUM];
     40 STATIC bcmi_tsn_taf_profile_t *taf_profile_active
     41                                [SOC_MAX_NUM_DEVICES][BCMI_TSN_TAF_GATE_NUM];
     42 
     43 /* helper macro */
     44 #define TSN_TAF_LOCK(tc) \
     45             sal_mutex_take((tc)->taf_mutex, sal_mutex_FOREVER)
     46 #define TSN_TAF_UNLOCK(tc) \
     47             sal_mutex_give((tc)->taf_mutex)
     48 
     49 #define TSN_TAF_INIT_ERROR_WITH_CLEAN(_op_)             \
     50         do {                                            \
     51             int _rv_ = (_op_);                          \
     52             if (BCM_FAILURE(_rv_)) {                    \
     53                 bcmi_esw_tsn_taf_cleanup(unit);         \
     54                 return (_rv_);                          \
     55             }                                           \
     56         } while (0)
     57 
     58 /* helper macro to execute dispatched specific device function */
     59 #define TSN_TAF_FUNC(_name_, _args_)                  \
     60         ((NULL == taf_control[unit]->taf_dev_info->   \
     61           tsn_taf_##_name_) ? BCM_E_INIT :            \
     62          (taf_control[unit]->taf_dev_info->           \
     63           tsn_taf_##_name_)_args_)
     64 
     65 #define TSN_TAF_DATA(_name_)                          \
     66          (taf_control[unit]->taf_dev_info->           \
     67           tsn_taf_##_name_)
     68 
     69 /*
     70  * Function:
     71  *    bcmi_esw_tsn_taf_instance_get
     72  * Description:
     73  *    Helper function to retrieve TAF control pointer
     74  * Parameters:
     75  *    unit  - (IN) BCM device number
     76  *    tc   - (OUT) TAF control data structure
     77  * Returns:
     78  *    BCM_E_XXX
     79  */
     80 STATIC int
     81 bcmi_esw_tsn_taf_instance_get(
     82     int unit,
     83     bcmi_tsn_taf_control_t **tc)
     84 {
     85     if (NULL == tc) {
     86         return BCM_E_PARAM;
     87     }
     88 
     89     if (!soc_feature(unit, soc_feature_tsn_taf)) {
     90         return BCM_E_UNAVAIL;
     91     }
     92 
     93     if (NULL == taf_control[unit]) {
     94         return BCM_E_INIT;
     95     }
     96 
     97     *tc = taf_control[unit];
     98     return BCM_E_NONE;
     99 }
    100 #endif /* BCM_TSN_SUPPORT */
    101 
    102 /*
    103  * Function:
    104  *    bcm_esw_tsn_taf_gate_create
    105  * Description:
    106  *    Allocate TAF gate
    107  * Parameters:
    108  *    unit          - (IN) Unit number
    109  *    flags         - (IN) flags, BCM_TSN_TAF_XXXX
    110  *    taf_gate_id   - (OUT) taf gate
    111  * Returns:
    112  *    BCM_E_XXX
    113  */
    114 int
    115 bcm_esw_tsn_taf_gate_create(int unit, int flags, int *taf_gate_id)
    116 {
    117     int rv = BCM_E_UNAVAIL;
    118 
    119 #if defined(BCM_TSN_SUPPORT)
    120     bcmi_tsn_taf_control_t *tc;
    121 
    122     BCM_IF_ERROR_RETURN(
    123         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    124 
    125     TSN_TAF_LOCK(tc);
    126     rv = TSN_TAF_FUNC(gate_create, (unit, flags, taf_gate_id));
    127     TSN_TAF_UNLOCK(tc);
    128 #endif /* BCM_TSN_SUPPORT */
    129 
    130     return rv;
    131 }
    132 
    133 /*
    134  * Function:
    135  *    bcm_esw_tsn_taf_gate_traverse
    136  * Description:
    137  *    Allocate TAF gate
    138  * Parameters:
    139  *    unit          - (IN) Unit number
    140  *     cb           - (IN) A pointer to callback function to call
    141  *                         for each taf gate.
    142  *     user_data    - (IN) Pointer to user data to supply in the callback
    143  * Returns:
    144  *    BCM_E_XXX
    145  */
    146 int
    147 bcm_esw_tsn_taf_gate_traverse(
    148     int unit,
    149     bcm_tsn_taf_gate_traverse_cb cb,
    150     void *user_data)
    151 {
    152     int rv = BCM_E_UNAVAIL;
    153 
    154 #if defined(BCM_TSN_SUPPORT)
    155     bcmi_tsn_taf_control_t *tc;
    156 
    157     BCM_IF_ERROR_RETURN(
    158         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    159 
    160     TSN_TAF_LOCK(tc);
    161     rv = TSN_TAF_FUNC(gate_traverse, (unit, cb, user_data));
    162     TSN_TAF_UNLOCK(tc);
    163 #endif /* BCM_TSN_SUPPORT */
    164 
    165     return rv;
    166 }
    167 
    168 /*
    169  * Function:
    170  *    bcm_esw_tsn_taf_gate_destroy
    171  * Description:
    172  *    Free TAF gate
    173  * Parameters:
    174  *    unit          - (IN) Unit number
    175  *    taf_gate_id   - (IN) taf gate
    176  * Returns:
    177  *    BCM_E_XXX
    178  */
    179 int
    180 bcm_esw_tsn_taf_gate_destroy(int unit, int taf_gate_id)
    181 {
    182     int rv = BCM_E_UNAVAIL;
    183 
    184 #if defined(BCM_TSN_SUPPORT)
    185     bcmi_tsn_taf_control_t *tc;
    186 
    187     BCM_IF_ERROR_RETURN(
    188         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    189 
    190     TSN_TAF_LOCK(tc);
    191     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
    192 
    193     if (BCM_SUCCESS(rv)) {
    194         rv = TSN_TAF_FUNC(gate_destroy, (unit, taf_gate_id));
    195     }
    196     TSN_TAF_UNLOCK(tc);
    197 #endif /* BCM_TSN_SUPPORT */
    198 
    199     return rv;
    200 }
    201 
    202 /*
    203  * Function:
    204  *    bcm_esw_tsn_taf_status_get
    205  * Description:
    206  *    Get the TAF gate status
    207  * Parameters:
    208  *    unit          - (IN) Unit number
    209  *    taf_gate_id   - (IN) taf gate
    210  *    type          - (IN) status type
    211  *    arg           - (OUT)parameter
    212  * Returns:
    213  *    BCM_E_XXX
    214  */
    215 int
    216 bcm_esw_tsn_taf_status_get(
    217     int unit,
    218     int taf_gate_id,
    219     bcm_tsn_taf_status_t type,
    220     uint32 *arg)
    221 {
    222     int rv = BCM_E_UNAVAIL;
    223 
    224 #if defined(BCM_TSN_SUPPORT)
    225     bcmi_tsn_taf_control_t *tc;
    226 
    227     BCM_IF_ERROR_RETURN(
    228         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    229 
    230     TSN_TAF_LOCK(tc);
    231     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
    232 
    233     if (BCM_SUCCESS(rv)) {
    234         rv = TSN_TAF_FUNC(status_get, (unit, taf_gate_id, type, arg));
    235     }
    236     TSN_TAF_UNLOCK(tc);
    237 #endif /* BCM_TSN_SUPPORT */
    238 
    239     return rv;
    240 }
    241 
    242 /*
    243  * Function:
    244  *    bcmi_esw_tsn_taf_port_control_set
    245  * Description:
    246  *    Set various TAF configurations at specific port
    247  * Parameters:
    248  *    unit          - (IN) Unit number
    249  *    gport         - (IN) gport
    250  *    type          - (IN) control type
    251  *    arg           - (IN) parameter
    252  * Returns:
    253  *    BCM_E_XXX
    254  */
    255 int
    256 bcmi_esw_tsn_taf_port_control_set(
    257     int unit,
    258     bcm_gport_t gport,
    259     bcm_tsn_control_t type,
    260     uint32 arg)
    261 {
    262     int rv = BCM_E_UNAVAIL;
    263 
    264 #if defined(BCM_TSN_SUPPORT)
    265     bcmi_tsn_taf_control_t *tc;
    266 
    267     BCM_IF_ERROR_RETURN(
    268         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    269 
    270     TSN_TAF_LOCK(tc);
    271     rv = TSN_TAF_FUNC(port_control_set, (unit, gport, type, arg));
    272     TSN_TAF_UNLOCK(tc);
    273 #endif /* BCM_TSN_SUPPORT */
    274 
    275     return rv;
    276 }
    277 
    278 /*
    279  * Function:
    280  *    bcmi_esw_tsn_taf_port_control_get
    281  * Description:
    282  *    Get various TAF configurations at specific port
    283  * Parameters:
    284  *    unit          - (IN) Unit number
    285  *    gport         - (IN) gport
    286  *    type          - (IN) control type
    287  *    arg           - (OUT) parameter
    288  * Returns:
    289  *    BCM_E_XXX
    290  */
    291 int
    292 bcmi_esw_tsn_taf_port_control_get(
    293     int unit,
    294     bcm_gport_t gport,
    295     bcm_tsn_control_t type,
    296     uint32 *arg)
    297 {
    298     int rv = BCM_E_UNAVAIL;
    299 
    300 #if defined(BCM_TSN_SUPPORT)
    301     bcmi_tsn_taf_control_t *tc;
    302 
    303     BCM_IF_ERROR_RETURN(
    304         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    305 
    306     TSN_TAF_LOCK(tc);
    307     rv = TSN_TAF_FUNC(port_control_get, (unit, gport, type, arg));
    308     TSN_TAF_UNLOCK(tc);
    309 #endif /* BCM_TSN_SUPPORT */
    310 
    311     return rv;
    312 }
    313 
    314 #if defined(BCM_TSN_SUPPORT)
    315 /*
    316  * Function:
    317  *    bcmi_esw_tsn_taf_gate_pri_map_valid
    318  * Purpose:
    319  *      helper function to check config valid or not
    320  * Parameters:
    321  *      config - (IN) Priority Map configuration
    322  * Returns:
    323  *    BCM_E_XXX
    324  */
    325 
    326 STATIC int
    327 bcmi_esw_tsn_taf_gate_pri_map_valid(
    328     int unit,
    329     bcm_tsn_pri_map_config_t *config)
    330 {
    331     int i;
    332     int no_assign_any_gate = 1;
    333 
    334     if (NULL == config) {
    335         return BCM_E_PARAM;
    336     }
    337 
    338     if (config->map_type != bcmTsnPriMapTypeTafGate) {
    339         return BCM_E_PARAM;
    340     }
    341 
    342     if (config->num_map_entries != TSN_TAF_DATA(gate_intpri_num)) {
    343         return BCM_E_PARAM;
    344     }
    345 
    346     for (i = 0; i < config->num_map_entries; i++) {
    347         uint32 valid_flags;
    348 
    349         valid_flags = BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_EXPRESS |
    350                       BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_PREEMPT;
    351         if (config->map_entries[i].flags & (~valid_flags)) {
    352             return BCM_E_PARAM;
    353         }
    354         if (config->map_entries[i].flags &
    355             BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_EXPRESS) {
    356             no_assign_any_gate = 0;
    357             break;
    358         }
    359         if (config->map_entries[i].flags &
    360             BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_PREEMPT) {
    361             no_assign_any_gate = 0;
    362             break;
    363         }
    364     }
    365 
    366     if (1 == no_assign_any_gate) {
    367         return BCM_E_PARAM;
    368     } else {
    369         return BCM_E_NONE;
    370     }
    371 }
    372 
    373 /*
    374  * Function:
    375  *    bcmi_esw_tsn_taf_gate_pri_map_set
    376  * Purpose:
    377  *      Set the Priority Map configuration to hardware
    378  * Parameters:
    379  *      unit   - (IN) Unit number
    380  *      sw_idx - (IN) SW memory index
    381  *      config - (OUT) Priority Map configuration
    382  * Returns:
    383  *    BCM_E_XXX
    384  */
    385 STATIC int
    386 bcmi_esw_tsn_taf_gate_pri_map_set(
    387     int unit,
    388     uint32 sw_idx,
    389     bcm_tsn_pri_map_config_t *config)
    390 {
    391     int rv = BCM_E_NONE;
    392     bcmi_tsn_taf_control_t *tc;
    393     int i;
    394 
    395     if (NULL == config) {
    396         return BCM_E_PARAM;
    397     }
    398 
    399     BCM_IF_ERROR_RETURN(
    400         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    401 
    402     BCM_IF_ERROR_RETURN(
    403         bcmi_esw_tsn_taf_gate_pri_map_valid(unit, config));
    404 
    405     TSN_TAF_LOCK(tc);
    406     /* check all taf_gate id has been allocated first */
    407     for (i = 0; i < config->num_map_entries; i++) {
    408 
    409         if (config->map_entries[i].flags &
    410             BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_EXPRESS) {
    411             rv = TSN_TAF_FUNC(gate_check,
    412                     (unit, config->map_entries[i].taf_gate_express));
    413             if (BCM_FAILURE(rv)) {
    414                 break;
    415             }
    416         }
    417 
    418         if (config->map_entries[i].flags &
    419             BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_PREEMPT) {
    420             rv = TSN_TAF_FUNC(gate_check,
    421                     (unit, config->map_entries[i].taf_gate_preempt));
    422             if (BCM_FAILURE(rv)) {
    423                 break;
    424             }
    425         }
    426     }
    427 
    428     /* set priority map */
    429     if (BCM_SUCCESS(rv)) {
    430         rv = TSN_TAF_FUNC(gate_pri_map_set, (unit, sw_idx, config));
    431     }
    432     TSN_TAF_UNLOCK(tc);
    433 
    434     return rv;
    435 }
    436 
    437 /*
    438  * Function:
    439  *    bcmi_esw_tsn_taf_gate_pri_map_get
    440  * Purpose:
    441  *      Get the Priority Map configuration to hardware
    442  * Parameters:
    443  *      unit   - (IN) Unit number
    444  *      sw_idx - (IN) SW memory index
    445  *      config - (OUT) Priority Map configuration
    446  * Returns:
    447  *    BCM_E_XXX
    448  */
    449 STATIC int
    450 bcmi_esw_tsn_taf_gate_pri_map_get(
    451     int unit,
    452     uint32 sw_idx,
    453     bcm_tsn_pri_map_config_t *config)
    454 {
    455     int rv = BCM_E_NONE;
    456     bcmi_tsn_taf_control_t *tc;
    457 
    458     BCM_IF_ERROR_RETURN(
    459         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    460 
    461     TSN_TAF_LOCK(tc);
    462     rv = TSN_TAF_FUNC(gate_pri_map_get, (unit, sw_idx, config));
    463     TSN_TAF_UNLOCK(tc);
    464 
    465     return rv;
    466 }
    467 
    468 /*
    469  * Function:
    470  *    bcmi_esw_tsn_taf_gate_wb_hw_existed
    471  * Purpose:
    472  *   check if the HW existed value or not
    473  * Parameters:
    474  *   unit   - (IN) Unit being initialized
    475  *   sw_idx - (IN) SW memory index
    476  * Returns:
    477  *   BCM_E_NOT_FOUND means HW doesn't exist
    478  *   BCM_E_NONE means HW existed
    479  */
    480 STATIC int
    481 bcmi_esw_tsn_taf_gate_pri_map_wb_hw_existed(
    482     int unit,
    483     uint32 sw_idx)
    484 {
    485     int rv = BCM_E_NONE;
    486     bcmi_tsn_taf_control_t *tc;
    487     bcm_tsn_pri_map_config_t config;
    488 
    489     BCM_IF_ERROR_RETURN(
    490         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    491 
    492     TSN_TAF_LOCK(tc);
    493     rv = TSN_TAF_FUNC(gate_pri_map_get, (unit, sw_idx, &config));
    494     TSN_TAF_UNLOCK(tc);
    495 
    496     if (BCM_SUCCESS(rv)) {
    497         rv = bcmi_esw_tsn_taf_gate_pri_map_valid(unit, &config);
    498     }
    499     return rv;
    500 }
    501 
    502 
    503 /*
    504  * Function:
    505  *    bcmi_esw_tsn_taf_gate_pri_map_delete
    506  * Purpose:
    507  *      Delete the Priority Map configuration on hardware
    508  * Parameters:
    509  *      unit   - (IN) Unit number
    510  *      sw_idx - (IN) SW memory index
    511  * Returns:
    512  *    BCM_E_XXX
    513  */
    514 STATIC int
    515 bcmi_esw_tsn_taf_gate_pri_map_delete(
    516     int unit,
    517     uint32 sw_idx)
    518 {
    519     int rv = BCM_E_NONE;
    520     bcmi_tsn_taf_control_t *tc;
    521 
    522     BCM_IF_ERROR_RETURN(
    523         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    524 
    525     TSN_TAF_LOCK(tc);
    526     rv = TSN_TAF_FUNC(gate_pri_map_delete, (unit, sw_idx));
    527     TSN_TAF_UNLOCK(tc);
    528 
    529     return rv;
    530 }
    531 
    532 /*
    533  * Function:
    534  *    bcmi_esw_tsn_taf_gate_pri_map_hw_idx_get
    535  * Purpose:
    536  *      Get HW memory base index
    537  * Parameters:
    538  *      unit     - (IN) Unit number
    539  *      sw_idx   - (IN) SW memory index
    540  *      hw_index - (OUT) HW memory base index
    541  * Returns:
    542  *    BCM_E_XXX
    543  */
    544 STATIC int
    545 bcmi_esw_tsn_taf_gate_pri_map_hw_idx_get(
    546     int unit,
    547     uint32 sw_idx,
    548     uint32 *hw_idx)
    549 {
    550     int rv = BCM_E_UNAVAIL;
    551 
    552     /* simple sw/hw index conversion need not be protected by TAF lock
    553      * invoke device-dispatched function directly
    554      */
    555 #if defined(BCM_GREYHOUND2_SUPPORT)
    556     if (SOC_IS_GREYHOUND2(unit)) {
    557        rv = bcmi_gh2_taf_gate_pri_map_hw_idx_get(unit, sw_idx, hw_idx);
    558     }
    559 #endif /* BCM_GREYHOUND2_SUPPORT */
    560 
    561     return rv;
    562 }
    563 
    564 /*
    565  * Function:
    566  *    bcmi_esw_tsn_taf_gate_pri_map_sw_idx_get
    567  * Purpose:
    568  *      Get SW memory index
    569  * Parameters:
    570  *      unit     - (IN) Unit number
    571  *      hw_index - (IN) HW memory base index
    572  *      sw_idx   - (OUT) SW memory index
    573  * Returns:
    574  *    BCM_E_XXX
    575  */
    576 STATIC int
    577 bcmi_esw_tsn_taf_gate_pri_map_sw_idx_get(
    578     int unit,
    579     uint32 hw_idx,
    580     uint32 *sw_idx)
    581 {
    582     int rv = BCM_E_UNAVAIL;
    583 
    584     /* simple sw/hw index conversion need not be protected by TAF lock
    585      * invoke device-dispatched function directly
    586      */
    587 #if defined(BCM_GREYHOUND2_SUPPORT)
    588     if (SOC_IS_GREYHOUND2(unit)) {
    589        rv = bcmi_gh2_taf_gate_pri_map_sw_idx_get(unit, hw_idx, sw_idx);
    590     }
    591 #endif /* BCM_GREYHOUND2_SUPPORT */
    592 
    593     return rv;
    594 }
    595 #endif /* BCM_TSN_SUPPORT */
    596 
    597 /*
    598  * Function:
    599  *     bcm_esw_tsn_taf_profile_create
    600  * Purpose:
    601  *     Create a profile by specifying the profile settings including calendar
    602  *     table, ptp time information for PTP mode.
    603  *     A profile id will be assigned along with the settings.
    604  * Parameters:
    605  *     unit             - (IN) unit number
    606  *     taf_gate         - (IN) TAF gate
    607  *     profile          - (IN) Pointer to profile structure which specifies
    608  *                             entries in calendar table, ptp time information
    609  *                             for PTP mode
    610  *     pid              - (OUT) profile id
    611  * Returns:
    612  *     BCM_E_XXX
    613  */
    614 int
    615 bcm_esw_tsn_taf_profile_create(
    616     int unit,
    617     int taf_gate,
    618     bcm_tsn_taf_profile_t *profile,
    619     bcm_tsn_taf_profile_id_t *pid)
    620 {
    621     int rv = BCM_E_UNAVAIL;
    622 
    623  #if defined(BCM_TSN_SUPPORT)
    624     bcmi_tsn_taf_control_t *tc;
    625     bcmi_tsn_taf_profile_t *profile_i;
    626 
    627     BCM_IF_ERROR_RETURN(
    628         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    629 
    630     TSN_TAF_LOCK(tc);
    631 
    632     /* parameter check */
    633     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
    634 
    635     if (BCM_SUCCESS(rv)) {
    636         rv = TSN_TAF_FUNC(
    637                  calendar_param_check, (unit, taf_gate, profile));
    638     }
    639 
    640     /* create a internal profile with a new pid */
    641     if (BCM_SUCCESS(rv)) {
    642         rv = TSN_TAF_FUNC(
    643                  calendar_profile_create, (unit, profile, pid, &profile_i));
    644     }
    645 
    646     /* increase the ref_cnt for maxbyte and CosQ profile
    647      * which are specified by the user
    648      */
    649     if (BCM_SUCCESS(rv)) {
    650         rv = TSN_TAF_FUNC(
    651                  calendar_resource_alloc, (unit, taf_gate, profile));
    652     }
    653 
    654     /* copy the user data into internal profile database
    655      * , and set the status as "Init"
    656      */
    657     if (BCM_SUCCESS(rv)) {
    658         profile_i->taf_gate = taf_gate;
    659         profile_i->status = bcmTsnTafProfileInit;
    660         COMPILER_64_SET(profile_i->config_change_time.seconds, 0, 0);
    661         profile_i->config_change_time.nanoseconds = 0;
    662         sal_memcpy(&(profile_i->data), profile, sizeof(bcm_tsn_taf_profile_t));
    663     }
    664     TSN_TAF_UNLOCK(tc);
    665 #endif /* BCM_TSN_SUPPORT */
    666 
    667     return rv;
    668 }
    669 
    670 /*
    671  * Function:
    672  *     bcm_esw_tsn_taf_profile_set
    673  * Purpose:
    674  *     Modify the profile information
    675  * Parameters:
    676  *     unit             - (IN) unit number
    677  *     taf_gate         - (IN) TAF gate
    678  *     pid              - (IN) profile id
    679  *     profile          - (IN) pointer to profile structure
    680  * Returns:
    681  *     BCM_E_XXX
    682  */
    683 int
    684 bcm_esw_tsn_taf_profile_set(
    685     int unit,
    686     int taf_gate,
    687     bcm_tsn_taf_profile_id_t pid,
    688     bcm_tsn_taf_profile_t *profile)
    689 {
    690     int rv = BCM_E_UNAVAIL;
    691 
    692 #if defined(BCM_TSN_SUPPORT)
    693     int schedule_exist;
    694     bcmi_tsn_taf_control_t *tc;
    695     bcmi_tsn_taf_profile_t *profile_i;
    696 
    697     BCM_IF_ERROR_RETURN(
    698         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    699 
    700     if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) {
    701         return BCM_E_PARAM;
    702     }
    703 
    704     TSN_TAF_LOCK(tc);
    705 
    706     /* For the new input, check the parameter */
    707     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
    708 
    709     if (BCM_SUCCESS(rv)) {
    710         rv = TSN_TAF_FUNC(calendar_param_check, (unit, taf_gate, profile));
    711     }
    712 
    713     /* Get the previous internal data */
    714     if (BCM_SUCCESS(rv)) {
    715         rv = TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i));
    716     }
    717 
    718     if (BCM_SUCCESS(rv)) {
    719         if (profile_i->taf_gate != taf_gate) {
    720             rv = BCM_E_PARAM;
    721         }
    722     }
    723 
    724     /* cannot change if this profile has been operated in
    725      * Pending or Active status
    726      */
    727     if (BCM_SUCCESS(rv)) {
    728         if (profile_i->status == bcmTsnTafProfilePending ||
    729             profile_i->status == bcmTsnTafProfileActive) {
    730             rv = BCM_E_BUSY;
    731         }
    732     }
    733 
    734     /* if this profile has already be scheduled as Committed status
    735      *  ==> try to re-create a new schedule entry
    736      */
    737     if (BCM_SUCCESS(rv)) {
    738         rv = TSN_TAF_FUNC(schedule_exist, (unit, profile_i, &schedule_exist));
    739     }
    740 
    741     if (BCM_SUCCESS(rv) && 1 == schedule_exist &&
    742         bcmTsnTafProfileCommitted == profile_i->status) {
    743 #if 1
    744         rv = TSN_TAF_FUNC(schedule_insert,
    745                           (unit, taf_gate,
    746                            &(profile->ptp_base_time),
    747                            profile_i));
    748 #endif
    749 
    750     }
    751 
    752     /* increase the ref_cnt for the new maxbyte and CosQ profile id
    753      * which are specified by the user
    754      */
    755     if (BCM_SUCCESS(rv)) {
    756         rv = TSN_TAF_FUNC(
    757                  calendar_resource_alloc, (unit, taf_gate, profile));
    758     }
    759 
    760     /* decrease the ref_cnt for the previous maxbyte and CosQ profile id */
    761     if (BCM_SUCCESS(rv)) {
    762         rv = TSN_TAF_FUNC(
    763                  calendar_resource_free, (unit, taf_gate, &(profile_i->data)));
    764     }
    765 
    766     /* reset its status as Init */
    767     if (BCM_SUCCESS(rv)) {
    768         profile_i->status = bcmTsnTafProfileInit;
    769         sal_memcpy(&(profile_i->data), profile, sizeof(bcm_tsn_taf_profile_t));
    770     }
    771     TSN_TAF_UNLOCK(tc);
    772 #endif /* BCM_TSN_SUPPORT */
    773 
    774     return rv;
    775 }
    776 
    777 /*
    778  * Function:
    779  *     bcm_esw_tsn_taf_profile_get
    780  * Purpose:
    781  *     Get the profile information by specifying the profile id.
    782  * Parameters:
    783  *     unit             - (IN) unit number
    784  *     taf_gate         - (IN) TAF gate
    785  *     pid              - (IN) profile id
    786  *     profile          - (OUT) pointer to profile structure
    787  * Returns:
    788  *     BCM_E_XXX
    789  */
    790 int
    791 bcm_esw_tsn_taf_profile_get(
    792     int unit,
    793     int taf_gate,
    794     bcm_tsn_taf_profile_id_t pid,
    795     bcm_tsn_taf_profile_t *profile)
    796 {
    797     int rv = BCM_E_UNAVAIL;
    798 
    799 #if defined(BCM_TSN_SUPPORT)
    800     bcmi_tsn_taf_control_t *tc;
    801     bcmi_tsn_taf_profile_t *profile_i;
    802 
    803     if (NULL == profile) {
    804         return BCM_E_PARAM;
    805     }
    806     bcm_tsn_taf_profile_t_init(profile);
    807 
    808     BCM_IF_ERROR_RETURN(
    809         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    810 
    811     if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) {
    812         return BCM_E_PARAM;
    813     }
    814 
    815     TSN_TAF_LOCK(tc);
    816     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
    817 
    818     if (BCM_SUCCESS(rv)) {
    819         rv = TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i));
    820     }
    821 
    822     if (BCM_SUCCESS(rv)) {
    823         if (profile_i->taf_gate != taf_gate) {
    824             rv = BCM_E_PARAM;
    825         }
    826     }
    827 
    828     if (BCM_SUCCESS(rv)) {
    829         sal_memcpy(profile, &(profile_i->data), sizeof(bcm_tsn_taf_profile_t));
    830     }
    831     TSN_TAF_UNLOCK(tc);
    832 #endif /* BCM_TSN_SUPPORT */
    833 
    834     return rv;
    835 }
    836 
    837 #if defined(BCM_TSN_SUPPORT)
    838 /*
    839  * Function:
    840  *     bcmi_esw_tsn_taf_profile_pick_pending
    841  * Purpose:
    842  *     helper function for ptp-mode
    843  *     pick a candidate from timeline to act in pending status
    844  * Parameters:
    845  *     unit             - (IN) unit number
    846  *     taf_gate         - (IN) TAF gate
    847  *     pid              - (IN) profile id
    848  *     status           - (OUT) pointer to profile status structure
    849  * Returns:
    850  *     BCM_E_XXX
    851  */
    852 STATIC int
    853 bcmi_esw_tsn_taf_profile_pick_pending(
    854     int unit,
    855     int taf_gate)
    856 {
    857     bcmi_tsn_taf_profile_t *candidate = NULL;
    858 
    859     if (NULL != taf_profile_pending[unit][taf_gate]) {
    860         /* skip this if there has already existed a pending entry */
    861         return BCM_E_NONE;
    862     }
    863 
    864 #if 1
    865     BCM_IF_ERROR_RETURN(
    866         TSN_TAF_FUNC(
    867             schedule_pick, (unit, taf_gate,
    868                             taf_profile_active[unit][taf_gate], &candidate)));
    869 #endif
    870 
    871 
    872 
    873     if (NULL != candidate) {
    874         /* kick off this schedule according to the schedule time
    875          * if candidate existes
    876          */
    877         BCM_IF_ERROR_RETURN(
    878             TSN_TAF_FUNC(calendar_kickoff,
    879                          (unit, taf_gate, candidate)));
    880 
    881         /* record this schedule time as final config change time in database */
    882         BCM_IF_ERROR_RETURN(
    883             TSN_TAF_FUNC(schedule_get,
    884                          (unit, candidate, &(candidate->config_change_time))));
    885 
    886         /* remove schedule and change its status to pending */
    887         BCM_IF_ERROR_RETURN(
    888             TSN_TAF_FUNC(schedule_remove,
    889                          (unit, taf_gate, candidate)));
    890         candidate->status = bcmTsnTafProfilePending;
    891 
    892         /* udpate current pending profile */
    893         taf_profile_pending[unit][taf_gate] = candidate;
    894     }
    895     return BCM_E_NONE;
    896 }
    897 #endif /* BCM_TSN_SUPPORT */
    898 
    899 /*
    900  * Function:
    901  *     bcm_esw_tsn_taf_profile_commit
    902  * Purpose:
    903  *     Commit the profile to indicate the profile is ready to write to hardware.
    904  * Parameters:
    905  *     unit             - (IN) unit number
    906  *     taf_gate         - (IN) TAF gate
    907  *     pid              - (IN) profile id
    908  * Returns:
    909  *     BCM_E_XXX
    910  */
    911 int
    912 bcm_esw_tsn_taf_profile_commit(
    913     int unit,
    914     int taf_gate,
    915     bcm_tsn_taf_profile_id_t pid)
    916 {
    917     int rv = BCM_E_UNAVAIL;
    918 
    919 #if defined(BCM_TSN_SUPPORT)
    920     uint32 use_ptp;
    921     bcmi_tsn_taf_control_t *tc;
    922     bcmi_tsn_taf_profile_t *profile_i;
    923 
    924     BCM_IF_ERROR_RETURN(
    925         bcmi_esw_tsn_taf_instance_get(unit, &tc));
    926 
    927     if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) {
    928         return BCM_E_PARAM;
    929     }
    930 
    931     TSN_TAF_LOCK(tc);
    932     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
    933 
    934     if (BCM_SUCCESS(rv)) {
    935         rv = TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i));
    936     }
    937 
    938     if (BCM_SUCCESS(rv)) {
    939         if (profile_i->taf_gate != taf_gate) {
    940             rv = BCM_E_PARAM;
    941         }
    942     }
    943 
    944     if (BCM_SUCCESS(rv)) {
    945         if (profile_i->status != bcmTsnTafProfileInit) {
    946             /* we only accept to commit the profile with init state */
    947             rv = BCM_E_CONFIG;
    948         }
    949     }
    950 
    951     if (BCM_SUCCESS(rv)) {
    952         uint32 taf_enable;
    953 
    954         rv = TSN_TAF_FUNC(gate_control_get,
    955                 (unit, taf_gate, bcmTsnTafControlEnable, &taf_enable));
    956         if (BCM_SUCCESS(rv) && 0 == taf_enable) {
    957             /* need to enable TAF on this gate first before commit profile */
    958             rv = BCM_E_CONFIG;
    959         }
    960     }
    961 
    962     if (BCM_SUCCESS(rv)) {
    963         rv = TSN_TAF_FUNC(gate_control_get,
    964                 (unit, taf_gate, bcmTsnTafControlUsePTPTime, &use_ptp));
    965     }
    966 
    967     if (BCM_SUCCESS(rv)) {
    968         if (1 == use_ptp) {
    969             uint32 is_locked;
    970             /* if this taf gate is operated in PTP mode,
    971              * create and insert a schedule entry into timeline
    972              * , set its state as commit then wait scheduling
    973              */
    974 
    975 
    976             /* if clock does not be locked, cannot commit */
    977             if (BCM_SUCCESS(rv)) {
    978                 rv = TSN_TAF_FUNC(global_control_get,
    979                                   (unit, bcmTsnTafControlTAFPTPLock,
    980                                    &is_locked));
    981             }
    982 
    983             if (BCM_SUCCESS(rv) && 0 == is_locked) {
    984                 LOG_WARN(BSL_LS_BCMAPI_TSN,
    985                          (BSL_META_U(unit, "need to ensure TAF ptp lock\
    986                                             before commit\n")));
    987                 rv = BCM_E_CONFIG;
    988             }
    989 
    990             /* insert this new schedule */
    991             if (BCM_SUCCESS(rv)) {
    992 #if 1
    993                 rv = TSN_TAF_FUNC(
    994                         schedule_insert, (unit, taf_gate,
    995                                           &(profile_i->data.ptp_base_time),
    996                                           profile_i));
    997 #endif
    998 
    999             }
   1000 
   1001             /* try to see if there is any profile could be selected
   1002              * as pending status
   1003              */
   1004             if (BCM_SUCCESS(rv)) {
   1005                 profile_i->status = bcmTsnTafProfileCommitted;
   1006                 rv = bcmi_esw_tsn_taf_profile_pick_pending(
   1007                         unit,
   1008                         taf_gate);
   1009             }
   1010 
   1011 
   1012         } else {
   1013             /* if this taf gate is operated in non-PTP mode,
   1014              *  setup into hw directly, and enter pending state
   1015              */
   1016             if (NULL != taf_profile_pending[unit][taf_gate]) {
   1017                 rv = BCM_E_BUSY;
   1018             }
   1019             if (BCM_SUCCESS(rv)) {
   1020                 rv = TSN_TAF_FUNC(calendar_kickoff,
   1021                         (unit, taf_gate, profile_i));
   1022             }
   1023             if (BCM_SUCCESS(rv)) {
   1024                 profile_i->status = bcmTsnTafProfilePending;
   1025                 taf_profile_pending[unit][taf_gate] = profile_i;
   1026             }
   1027         }
   1028     }
   1029 
   1030     TSN_TAF_UNLOCK(tc);
   1031 #endif /* BCM_TSN_SUPPORT */
   1032 
   1033     return rv;
   1034 }
   1035 
   1036 #if defined(BCM_TSN_SUPPORT)
   1037 /*
   1038  * Function:
   1039  *     bcmi_esw_tsn_taf_profile_destroy
   1040  * Purpose:
   1041  *     helper function to destroy profile
   1042  */
   1043 STATIC int
   1044 bcmi_esw_tsn_taf_profile_destroy(
   1045     int unit,
   1046     int taf_gate,
   1047     bcm_tsn_taf_profile_id_t pid,
   1048     void *user_data)
   1049 {
   1050     bcmi_tsn_taf_profile_t *profile_i;
   1051     int schedule_exist;
   1052 
   1053     if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) {
   1054         return BCM_E_PARAM;
   1055     }
   1056 
   1057     BCM_IF_ERROR_RETURN(
   1058         TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i)));
   1059 
   1060     if (profile_i->taf_gate != taf_gate) {
   1061         return BCM_E_PARAM;
   1062     }
   1063 
   1064     if (profile_i->status == bcmTsnTafProfilePending ||
   1065         profile_i->status == bcmTsnTafProfileActive) {
   1066         return BCM_E_BUSY;
   1067     }
   1068 
   1069     BCM_IF_ERROR_RETURN(
   1070         TSN_TAF_FUNC(schedule_exist, (unit, profile_i, &schedule_exist)));
   1071 
   1072     if (1 == schedule_exist) {
   1073         BCM_IF_ERROR_RETURN(
   1074             TSN_TAF_FUNC(schedule_remove, (unit, taf_gate, profile_i)));
   1075     }
   1076 
   1077     BCM_IF_ERROR_RETURN(
   1078         TSN_TAF_FUNC(calendar_resource_free,
   1079                      (unit, taf_gate, &(profile_i->data))));
   1080 
   1081     BCM_IF_ERROR_RETURN(
   1082         TSN_TAF_FUNC(calendar_profile_destroy, (unit, pid)));
   1083 
   1084     return BCM_E_NONE;
   1085 }
   1086 #endif /* BCM_TSN_SUPPORT */
   1087 
   1088 /*
   1089  * Function:
   1090  *     bcm_esw_tsn_taf_profile_destroy
   1091  * Purpose:
   1092  *     Destroy the profile and associated resources.
   1093  * Parameters:
   1094  *     unit             - (IN) unit number
   1095  *     taf_gate         - (IN) TAF gate
   1096  *     pid              - (IN) profile id
   1097  * Returns:
   1098  *     BCM_E_XXX
   1099  */
   1100 int
   1101 bcm_esw_tsn_taf_profile_destroy(
   1102     int unit,
   1103     int taf_gate,
   1104     bcm_tsn_taf_profile_id_t pid)
   1105 {
   1106     int rv = BCM_E_UNAVAIL;
   1107 
   1108 #if defined(BCM_TSN_SUPPORT)
   1109     bcmi_tsn_taf_control_t *tc;
   1110 
   1111     BCM_IF_ERROR_RETURN(
   1112         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1113 
   1114     TSN_TAF_LOCK(tc);
   1115     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
   1116 
   1117     if (BCM_SUCCESS(rv)) {
   1118         rv = bcmi_esw_tsn_taf_profile_destroy(unit, taf_gate, pid, NULL);
   1119     }
   1120     TSN_TAF_UNLOCK(tc);
   1121 #endif /* BCM_TSN_SUPPORT */
   1122 
   1123     return rv;
   1124 }
   1125 
   1126 
   1127 /*
   1128  * Function:
   1129  *     bcm_esw_tsn_taf_profile_destroy_all
   1130  * Purpose:
   1131  *     Destroy all the profile associated with the taf_gate.
   1132  * Parameters:
   1133  *     unit             - (IN) unit number
   1134  *     taf_gate         - (IN) TAF gate
   1135  * Returns:
   1136  *     BCM_E_XXX
   1137  */
   1138 int
   1139 bcm_esw_tsn_taf_profile_destroy_all(
   1140     int unit,
   1141     int taf_gate)
   1142 {
   1143     int rv = BCM_E_UNAVAIL;
   1144 
   1145 #if defined(BCM_TSN_SUPPORT)
   1146     bcmi_tsn_taf_control_t *tc;
   1147 
   1148     BCM_IF_ERROR_RETURN(
   1149         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1150 
   1151     TSN_TAF_LOCK(tc);
   1152     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
   1153 
   1154     if (BCM_SUCCESS(rv)) {
   1155         rv = TSN_TAF_FUNC(calendar_profile_traverse,
   1156                 (unit, taf_gate, bcmi_esw_tsn_taf_profile_destroy, NULL));
   1157     }
   1158     TSN_TAF_UNLOCK(tc);
   1159 #endif /* BCM_TSN_SUPPORT */
   1160 
   1161     return rv;
   1162 }
   1163 
   1164 #if defined(BCM_TSN_SUPPORT)
   1165 /*
   1166  * Function:
   1167  *     bcmi_esw_tsn_taf_profile_reset
   1168  * Purpose:
   1169  *     helper function to reset profile back to init status (is_init = 1)
   1170  *                                   or fall into error status (is_init = 0)
   1171  *     And need to cancel all schedule for commited profile
   1172  *
   1173  *                      is_init = 1     is_init = 0
   1174  *      INIT                INIT            INIT
   1175  *      ERROR               INIT            ERROR
   1176  *      EXPIRED             INIT            EXPIRED
   1177  *      COMMITTED           INIT            ERROR
   1178  *      PENDING             INIT            ERROR
   1179  *      ACTIVE              INIT            ERROR
   1180  */
   1181 STATIC int
   1182 bcmi_esw_tsn_taf_profile_reset(
   1183     int unit,
   1184     int taf_gate,
   1185     bcm_tsn_taf_profile_id_t pid,
   1186     void *user_data)
   1187 {
   1188     bcmi_tsn_taf_profile_t *profile_i;
   1189     int is_init;
   1190 
   1191     if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) {
   1192         return BCM_E_PARAM;
   1193     }
   1194 
   1195     if (NULL == user_data) {
   1196         return BCM_E_INTERNAL; /* should not happen */
   1197     }
   1198     is_init = *((int *)user_data);
   1199 
   1200     BCM_IF_ERROR_RETURN(
   1201         TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i)));
   1202 
   1203     if (profile_i->taf_gate != taf_gate) {
   1204         return BCM_E_PARAM;
   1205     }
   1206 
   1207     switch (profile_i->status) {
   1208         case bcmTsnTafProfileInit:
   1209             /* skip profile with init status */
   1210             break;
   1211         case bcmTsnTafProfileExpired:
   1212         case bcmTsnTafProfileError: /* fall through */
   1213             if (1 == is_init) {
   1214                 profile_i->status = bcmTsnTafProfileInit;
   1215             }
   1216             break;
   1217         case bcmTsnTafProfileCommitted:
   1218             /* commit status only for ptp mode
   1219              * so there should exist schedule entry
   1220              */
   1221              BCM_IF_ERROR_RETURN(
   1222                  TSN_TAF_FUNC(schedule_remove, (unit, taf_gate, profile_i)));
   1223              profile_i->status = (1 == is_init) ? bcmTsnTafProfileInit
   1224                                                 : bcmTsnTafProfileError;
   1225              break;
   1226         case bcmTsnTafProfilePending:
   1227             if (taf_profile_pending[unit][taf_gate] != profile_i) {
   1228                 return BCM_E_INTERNAL;
   1229             }
   1230             taf_profile_pending[unit][taf_gate] = NULL;
   1231             profile_i->status = (1 == is_init) ? bcmTsnTafProfileInit
   1232                                                : bcmTsnTafProfileError;
   1233             break;
   1234         case bcmTsnTafProfileActive:
   1235             if (taf_profile_active[unit][taf_gate] != profile_i) {
   1236                 return BCM_E_INTERNAL;
   1237             }
   1238             taf_profile_active[unit][taf_gate] = NULL;
   1239             profile_i->status = (1 == is_init) ? bcmTsnTafProfileInit
   1240                                                : bcmTsnTafProfileError;
   1241             break;
   1242         default:
   1243             return BCM_E_INTERNAL; /* unknown status? */
   1244     }
   1245 
   1246     return BCM_E_NONE;
   1247 }
   1248 
   1249 /* control data for bcmi_esw_tsn_taf_profile_reset_all */
   1250 #define BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_NON_PTP (0)
   1251 #define BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_PTP     (1)
   1252 #define BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_BOTH    (2)
   1253 
   1254 typedef struct bcmi_tsn_taf_profile_reset_control_s {
   1255     int is_init; /* 1 : reset status back to init status
   1256                   * 0 : fall into error status
   1257                   */
   1258     int active_mode; /* BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_XXX */
   1259     int need_event; /* 1 : need raise event
   1260                      * 0 : need not raise event
   1261                      */
   1262     bcm_tsn_taf_event_type_t event_type; /* event type if need_event = 1 */
   1263 } bcmi_tsn_taf_profile_reset_control_t;
   1264 
   1265 /*
   1266  * Function:
   1267  *     bcmi_esw_tsn_taf_profile_reset_all
   1268  * Purpose:
   1269  *     Reset all the profile associated with the taf_gate.
   1270  * Parameters:
   1271  *     unit             - (IN) unit number
   1272  *     taf_gate         - (IN) TAF gate
   1273  *     is_init          - (IN) 1 : reset status back to init status
   1274  *                             0 : fall into error status
   1275  * Returns:
   1276  *     BCM_E_XXX
   1277  */
   1278 STATIC int
   1279 bcmi_esw_tsn_taf_profile_reset_all(
   1280     int unit,
   1281     int taf_gate,
   1282     void *control_data)
   1283 {
   1284     bcmi_tsn_taf_profile_reset_control_t *control_ptr;
   1285 
   1286     if (NULL == control_data) {
   1287         return BCM_E_PARAM;
   1288     }
   1289     control_ptr = (bcmi_tsn_taf_profile_reset_control_t *)control_data;
   1290 
   1291     /* gate mode check, skip handling if not match */
   1292     if (control_ptr->active_mode !=
   1293         BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_BOTH) {
   1294 
   1295         uint32 use_ptp;
   1296 
   1297         BCM_IF_ERROR_RETURN(
   1298             TSN_TAF_FUNC(gate_control_get,
   1299                 (unit, taf_gate, bcmTsnTafControlUsePTPTime, &use_ptp)));
   1300 
   1301         if (control_ptr->active_mode ==
   1302             BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_NON_PTP &&
   1303             1 == use_ptp) {
   1304             return BCM_E_NONE;
   1305         }
   1306 
   1307         if (control_ptr->active_mode ==
   1308             BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_PTP &&
   1309             0 == use_ptp) {
   1310             return BCM_E_NONE;
   1311         }
   1312     }
   1313 
   1314     /* reset profile status */
   1315     BCM_IF_ERROR_RETURN(
   1316         TSN_TAF_FUNC(calendar_profile_traverse,
   1317             (unit, taf_gate, bcmi_esw_tsn_taf_profile_reset,
   1318              &(control_ptr->is_init))));
   1319 
   1320     /* raise event if need */
   1321     if (1 == control_ptr->need_event) {
   1322         BCM_IF_ERROR_RETURN(
   1323             TSN_TAF_FUNC(event_notify,
   1324                 (unit, taf_gate, control_ptr->event_type)));
   1325     }
   1326 
   1327     return BCM_E_NONE;
   1328 }
   1329 #endif /* BCM_TSN_SUPPORT */
   1330 
   1331 /*
   1332  * Function:
   1333  *     bcm_esw_tsn_taf_profile_traverse
   1334  * Purpose:
   1335  *     Traverse the set of profiles associated with the taf gate.
   1336  * Parameters:
   1337  *     unit             - (IN) unit number
   1338  *     taf_gate         - (IN) TAF gate
   1339  *     cb               - (IN) A pointer to callback function to call
   1340  *                             for each profile in the specified taf gate.
   1341  *     user_data        - (IN) Pointer to user data to supply in the callback
   1342  * Returns:
   1343  *     BCM_E_XXX
   1344  */
   1345 int
   1346 bcm_esw_tsn_taf_profile_traverse(
   1347     int unit,
   1348     int taf_gate,
   1349     bcm_tsn_taf_profile_traverse_cb cb,
   1350     void *user_data)
   1351 {
   1352     int rv = BCM_E_UNAVAIL;
   1353 
   1354 #if defined(BCM_TSN_SUPPORT)
   1355     bcmi_tsn_taf_control_t *tc;
   1356 
   1357     BCM_IF_ERROR_RETURN(
   1358         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1359 
   1360     TSN_TAF_LOCK(tc);
   1361     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
   1362 
   1363     if (BCM_SUCCESS(rv)) {
   1364         rv = TSN_TAF_FUNC(calendar_profile_traverse, (unit, taf_gate, cb,
   1365                                                       user_data));
   1366     }
   1367     TSN_TAF_UNLOCK(tc);
   1368 #endif /* BCM_TSN_SUPPORT */
   1369 
   1370     return rv;
   1371 }
   1372 
   1373 /*
   1374  * Function:
   1375  *     bcm_esw_tsn_taf_profile_status_get
   1376  * Purpose:
   1377  *     Get the profile status like profile state, config change time and
   1378  *     entries in the hardware calendar table.
   1379  * Parameters:
   1380  *     unit             - (IN) unit number
   1381  *     taf_gate         - (IN) TAF gate
   1382  *     pid              - (IN) profile id
   1383  *     status           - (OUT) pointer to profile status structure
   1384  * Returns:
   1385  *     BCM_E_XXX
   1386  */
   1387 int
   1388 bcm_esw_tsn_taf_profile_status_get(
   1389     int unit,
   1390     int taf_gate,
   1391     bcm_tsn_taf_profile_id_t pid,
   1392     bcm_tsn_taf_profile_status_t *status)
   1393 {
   1394     int rv = BCM_E_UNAVAIL;
   1395 
   1396 #if defined(BCM_TSN_SUPPORT)
   1397     bcmi_tsn_taf_control_t *tc;
   1398     bcmi_tsn_taf_profile_t *profile_i;
   1399 
   1400     BCM_IF_ERROR_RETURN(
   1401         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1402 
   1403     if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX || NULL == status) {
   1404         return BCM_E_PARAM;
   1405     }
   1406     bcm_tsn_taf_profile_status_t_init(status);
   1407 
   1408     TSN_TAF_LOCK(tc);
   1409     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
   1410 
   1411     if (BCM_SUCCESS(rv)) {
   1412         rv = TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i));
   1413     }
   1414 
   1415     if (BCM_SUCCESS(rv)) {
   1416         if (profile_i->taf_gate != taf_gate) {
   1417             rv = BCM_E_PARAM;
   1418         }
   1419     }
   1420 
   1421     if (BCM_SUCCESS(rv)) {
   1422         status->profile_state = profile_i->status;
   1423         status->num_entries = profile_i->data.num_entries;
   1424         COMPILER_64_COPY(status->config_change_time.seconds,
   1425                          profile_i->config_change_time.seconds);
   1426         status->config_change_time.nanoseconds =
   1427             profile_i->config_change_time.nanoseconds;
   1428         sal_memcpy(status->entries, profile_i->data.entries,
   1429                    sizeof(bcm_tsn_taf_entry_t) *
   1430                    BCM_TSN_TAF_CALENDAR_TABLE_SIZE);
   1431     }
   1432     TSN_TAF_UNLOCK(tc);
   1433 #endif /* BCM_TSN_SUPPORT */
   1434 
   1435     return rv;
   1436 }
   1437 
   1438 /*
   1439  * Function:
   1440  *    bcm_esw_tsn_taf_control_set
   1441  * Description:
   1442  *    Set various TAF configurations at specific gate
   1443  * Parameters:
   1444  *    unit          - (IN) Unit number
   1445  *    taf_gate_id   - (IN) taf gate (-1 for global setting)
   1446  *    type          - (IN) control type
   1447  *    arg           - (IN) parameter
   1448  * Returns:
   1449  *    BCM_E_XXX
   1450  */
   1451 int
   1452 bcm_esw_tsn_taf_control_set(
   1453     int unit,
   1454     int taf_gate_id,
   1455     bcm_tsn_taf_control_t type,
   1456     uint32 arg)
   1457 {
   1458     int rv = BCM_E_UNAVAIL;
   1459 
   1460 #if defined(BCM_TSN_SUPPORT)
   1461     bcmi_tsn_taf_control_t *tc;
   1462 
   1463     BCM_IF_ERROR_RETURN(
   1464         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1465 
   1466     TSN_TAF_LOCK(tc);
   1467 
   1468     if (bcmTsnTafControlTAFPTPLock == type) {
   1469         /* PTP Lock is a global setting */
   1470         if (taf_gate_id != -1) {
   1471             rv = BCM_E_PARAM;
   1472         } else {
   1473             rv = TSN_TAF_FUNC(global_control_set, (unit, type, arg));
   1474         }
   1475 
   1476         /* if ptp clock is out-of-snyc during ptp mode
   1477          *  1. let all profile enter into error status
   1478          *  2. raise out-of-sync event
   1479          */
   1480         if (BCM_SUCCESS(rv) && 0 == arg) {
   1481             bcmi_tsn_taf_profile_reset_control_t control_data;
   1482 
   1483             sal_memset(&control_data, 0, sizeof(control_data));
   1484             control_data.is_init = 0; /* reset to error status */
   1485             control_data.active_mode =
   1486                 BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_PTP;
   1487             control_data.need_event = 1;
   1488             control_data.event_type = bcmTsnTafEventTAFPTPOutOfSyncErr;
   1489             rv = TSN_TAF_FUNC(gate_traverse,
   1490                     (unit, bcmi_esw_tsn_taf_profile_reset_all, &control_data));
   1491         }
   1492     } else {
   1493         int need_to_reset = 0;
   1494 
   1495         /* For the other control type, check gate id first */
   1496         rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   1497 
   1498         if (BCM_SUCCESS(rv)) {
   1499             if (type == bcmTsnTafControlEnable ||
   1500                 type == bcmTsnTafControlUsePTPTime) {
   1501 
   1502                 uint32 prev_arg;
   1503 
   1504                 rv = TSN_TAF_FUNC(
   1505                          gate_control_get,
   1506                             (unit, taf_gate_id, type, &prev_arg));
   1507 
   1508                 if (BCM_SUCCESS(rv)) {
   1509                     if (type == bcmTsnTafControlEnable) {
   1510                         /* Reset all profiles after disable TAF */
   1511                         if (prev_arg != arg && arg == 0) {
   1512                             need_to_reset = 1;
   1513                         }
   1514                     } else if (type == bcmTsnTafControlUsePTPTime) {
   1515                         /* If the user wants to change between ptp and
   1516                          * non-ptp mode, need to disable TAF first
   1517                          */
   1518                         uint32 taf_enable;
   1519 
   1520                         rv = TSN_TAF_FUNC(
   1521                                 gate_control_get,
   1522                                     (unit, taf_gate_id,
   1523                                      bcmTsnTafControlEnable, &taf_enable));
   1524 
   1525                         if (BCM_SUCCESS(rv) && prev_arg != arg &&
   1526                             1 == taf_enable) {
   1527                             LOG_WARN(
   1528                                 BSL_LS_BCMAPI_TSN,
   1529                                 (BSL_META_U(unit, "need to disable TAF first\
   1530                                                    before change PTP mode\n")));
   1531                             rv = BCM_E_CONFIG;
   1532                         }
   1533                     }
   1534                 }
   1535             }
   1536         }
   1537 
   1538         if (BCM_SUCCESS(rv)) {
   1539             rv = TSN_TAF_FUNC(gate_control_set, (unit, taf_gate_id, type, arg));
   1540         }
   1541         if (BCM_SUCCESS(rv) && 1 == need_to_reset) {
   1542             bcmi_tsn_taf_profile_reset_control_t control_data;
   1543 
   1544             sal_memset(&control_data, 0, sizeof(control_data));
   1545             control_data.is_init = 1; /* reset to init status */
   1546             control_data.active_mode =
   1547                 BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_BOTH;
   1548             control_data.need_event = 0;
   1549             rv = bcmi_esw_tsn_taf_profile_reset_all(unit, taf_gate_id,
   1550                                                     &control_data);
   1551         }
   1552     }
   1553     TSN_TAF_UNLOCK(tc);
   1554 #endif /* BCM_TSN_SUPPORT */
   1555 
   1556     return rv;
   1557 }
   1558 
   1559 /*
   1560  * Function:
   1561  *    bcm_esw_tsn_taf_control_get
   1562  * Description:
   1563  *    Get various TAF configurations at specific gate
   1564  * Parameters:
   1565  *    unit          - (IN) Unit number
   1566  *    taf_gate_id   - (IN) taf gate
   1567  *    type          - (IN) control type
   1568  *    arg           - (OUT)parameter
   1569  * Returns:
   1570  *    BCM_E_XXX
   1571  */
   1572 int
   1573 bcm_esw_tsn_taf_control_get(
   1574     int unit,
   1575     int taf_gate_id,
   1576     bcm_tsn_taf_control_t type,
   1577     uint32 *arg)
   1578 {
   1579     int rv = BCM_E_UNAVAIL;
   1580 
   1581 #if defined(BCM_TSN_SUPPORT)
   1582     bcmi_tsn_taf_control_t *tc;
   1583 
   1584     BCM_IF_ERROR_RETURN(
   1585         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1586 
   1587     TSN_TAF_LOCK(tc);
   1588     if (bcmTsnTafControlTAFPTPLock == type) {
   1589         /* PTP Lock is a global setting */
   1590         if (taf_gate_id != -1) {
   1591             rv = BCM_E_PARAM;
   1592         } else {
   1593             rv = TSN_TAF_FUNC(global_control_get, (unit, type, arg));
   1594         }
   1595     } else {
   1596         /* For the other control type, check gate id first */
   1597         rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   1598 
   1599         if (BCM_SUCCESS(rv)) {
   1600             rv = TSN_TAF_FUNC(gate_control_get, (unit, taf_gate_id, type, arg));
   1601         }
   1602     }
   1603     TSN_TAF_UNLOCK(tc);
   1604 #endif /* BCM_TSN_SUPPORT */
   1605 
   1606     return rv;
   1607 }
   1608 
   1609 #if defined(BCM_TSN_SUPPORT)
   1610 STATIC int
   1611 bcmi_esw_tsn_taf_interrupt_handle(
   1612     int unit
   1613     )
   1614 {
   1615     int rv = BCM_E_NONE;
   1616     soc_control_t *soc = SOC_CONTROL(unit);
   1617     bcmi_tsn_taf_control_t *tc;
   1618     int need_to_handle, taf_gate, start_handle;
   1619     SHR_BITDCL gate_bitmap[_SHR_BITDCLSIZE(BCMI_TSN_TAF_GATE_NUM)];
   1620 
   1621     /* Start to handle interrupt after all modules are inited
   1622      * Consider that some interrupt signal are shared with others in init phase
   1623      */
   1624     if (soc == NULL || !(soc->soc_flags & SOC_F_ALL_MODULES_INITED)) {
   1625         return BCM_E_NONE;
   1626     }
   1627 
   1628     BCM_IF_ERROR_RETURN(
   1629         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1630 
   1631 
   1632     TSN_TAF_LOCK(tc);
   1633 
   1634     /* start to handle */
   1635     start_handle = 0;
   1636     rv = TSN_TAF_FUNC(interrupt_handle_start, (unit));
   1637 
   1638     /* handle profile switch done */
   1639     if (BCM_SUCCESS(rv)) {
   1640         start_handle = 1;
   1641         rv = TSN_TAF_FUNC(
   1642                 interrupt_handle_switch,
   1643                     (unit, &need_to_handle,
   1644                      gate_bitmap, _SHR_BITDCLSIZE(BCMI_TSN_TAF_GATE_NUM)));
   1645     }
   1646 
   1647     if (BCM_SUCCESS(rv) && need_to_handle) {
   1648         SHR_BIT_ITER(gate_bitmap, BCMI_TSN_TAF_GATE_NUM, taf_gate) {
   1649             uint32 use_ptp;
   1650             bcmi_tsn_taf_profile_t *p_act = taf_profile_active[unit][taf_gate];
   1651             bcmi_tsn_taf_profile_t *p_ped = taf_profile_pending[unit][taf_gate];
   1652 
   1653             if (NULL != p_act) {
   1654                 p_act->status = bcmTsnTafProfileExpired;
   1655                 taf_profile_active[unit][taf_gate] = NULL;
   1656             }
   1657 
   1658             if (NULL == p_ped) {
   1659                 LOG_WARN(BSL_LS_BCMAPI_TSN,
   1660                           (BSL_META_U(unit, "bcmi_esw_tsn_taf_interrupt_handle:\
   1661                                              no pending profile ?\n")));
   1662                 rv = BCM_E_INTERNAL; /* there is no any pending profile ? */
   1663                 break;
   1664             }
   1665             p_ped->status = bcmTsnTafProfileActive;
   1666             taf_profile_pending[unit][taf_gate] = NULL;
   1667             taf_profile_active[unit][taf_gate] = p_ped;
   1668 
   1669             rv = TSN_TAF_FUNC(gate_control_get,
   1670                 (unit, taf_gate, bcmTsnTafControlUsePTPTime, &use_ptp));
   1671             if (BCM_FAILURE(rv)) {
   1672                 break;
   1673             }
   1674 
   1675             /* for ptp-mode, check whether to pick a new candidate profile
   1676              * to be pending
   1677              */
   1678             if (1 == use_ptp) {
   1679                 rv = bcmi_esw_tsn_taf_profile_pick_pending(
   1680                         unit,
   1681                         taf_gate);
   1682                 if (BCM_FAILURE(rv)) {
   1683                    break;
   1684                 }
   1685             }
   1686         }
   1687     }
   1688 
   1689     /* handle error of active profile */
   1690     if (BCM_SUCCESS(rv)) {
   1691         rv = TSN_TAF_FUNC(
   1692                 interrupt_handle_error,
   1693                     (unit, &need_to_handle,
   1694                      gate_bitmap, _SHR_BITDCLSIZE(BCMI_TSN_TAF_GATE_NUM)));
   1695     }
   1696     if (BCM_SUCCESS(rv) && need_to_handle) {
   1697         bcmi_tsn_taf_profile_reset_control_t control_data;
   1698 
   1699         sal_memset(&control_data, 0, sizeof(control_data));
   1700         control_data.is_init = 0; /* reset to error status */
   1701         control_data.active_mode =
   1702             BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_BOTH;
   1703         control_data.need_event = 0;
   1704 
   1705         SHR_BIT_ITER(gate_bitmap, BCMI_TSN_TAF_GATE_NUM, taf_gate) {
   1706             rv = bcmi_esw_tsn_taf_profile_reset_all(unit, taf_gate,
   1707                                                     &control_data);
   1708             if (BCM_FAILURE(rv)) {
   1709                 break;
   1710             }
   1711         }
   1712     }
   1713 
   1714     /* handle Tod Window event */
   1715     if (BCM_SUCCESS(rv)) {
   1716         rv = TSN_TAF_FUNC(interrupt_handle_tod, (unit, &need_to_handle));
   1717     }
   1718     if (BCM_SUCCESS(rv) && need_to_handle) {
   1719         for (taf_gate = 0; taf_gate < BCMI_TSN_TAF_GATE_NUM; taf_gate++) {
   1720             uint32 use_ptp;
   1721 
   1722             rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
   1723             if (BCM_FAILURE(rv)) {
   1724                 rv = BCM_E_NONE;
   1725                 continue; /* skip invalid gate */
   1726             }
   1727 
   1728             rv = TSN_TAF_FUNC(gate_control_get,
   1729                     (unit, taf_gate, bcmTsnTafControlUsePTPTime, &use_ptp));
   1730             if (BCM_FAILURE(rv)) {
   1731                break;
   1732             }
   1733 
   1734             if (0 == use_ptp) {
   1735                 continue; /* skip the gate operated in non-ptp mode */
   1736             }
   1737 
   1738             /* check whether to pick a new candidate to pending status */
   1739             rv = bcmi_esw_tsn_taf_profile_pick_pending(
   1740                     unit,
   1741                     taf_gate);
   1742             if (BCM_FAILURE(rv)) {
   1743                break;
   1744             }
   1745         }
   1746     }
   1747 
   1748     /* invoke user registered callback */
   1749     if (BCM_SUCCESS(rv)) {
   1750         rv = TSN_TAF_FUNC(interrupt_handle_user_cb, (unit));
   1751     }
   1752 
   1753     /* finish handling no matter rv is BCM_E_NONE or not */
   1754     if (1 == start_handle) {
   1755         (void)TSN_TAF_FUNC(interrupt_handle_finish, (unit));
   1756     }
   1757 
   1758     TSN_TAF_UNLOCK(tc);
   1759     return rv;
   1760 }
   1761 #endif /* BCM_TSN_SUPPORT */
   1762 
   1763 /*
   1764  * Function:
   1765  *     bcm_esw_tsn_taf_event_register
   1766  * Purpose:
   1767  *     The callback function registration by specifying port or traffic class to
   1768  *     handle the TAF events.
   1769  * Parameters:
   1770  *     unit             - (IN) unit number
   1771  *     event_types      - (IN) The set of TAF events for which the specified
   1772  *                             callback should be invoked.
   1773  *     taf_gate         - (IN) taf gate
   1774  *     cb               - (IN) callback function
   1775  *     user_data        - (IN) Pinter to user data to supply in the callback.
   1776  * Returns:
   1777  *     BCM_E_XXX
   1778  */
   1779 int
   1780 bcm_esw_tsn_taf_event_register(
   1781     int unit,
   1782     bcm_tsn_taf_event_types_t event_types,
   1783     int taf_gate,
   1784     bcm_tsn_taf_event_cb cb,
   1785     void *user_data)
   1786 {
   1787     int rv = BCM_E_UNAVAIL;
   1788 
   1789 #if defined(BCM_TSN_SUPPORT)
   1790     bcmi_tsn_taf_control_t *tc;
   1791 
   1792     BCM_IF_ERROR_RETURN(
   1793         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1794 
   1795     TSN_TAF_LOCK(tc);
   1796     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
   1797 
   1798     if (BCM_SUCCESS(rv)) {
   1799         rv = TSN_TAF_FUNC(
   1800                  event_register, (unit, taf_gate, event_types, cb, user_data));
   1801     }
   1802     TSN_TAF_UNLOCK(tc);
   1803 #endif /* BCM_TSN_SUPPORT */
   1804 
   1805     return rv;
   1806 }
   1807 
   1808 /*
   1809  * Function:
   1810  *     bcm_esw_tsn_taf_event_unregister
   1811  * Purpose:
   1812  *     The callback function unregistration of TAF events by specifying port or
   1813  *     traffic class.
   1814  * Parameters:
   1815  *     unit             - (IN) unit number
   1816  *     event_types      - (IN) The set of TAF events for which the specified
   1817  *                             callback should be invoked.
   1818  *     taf_gate         - (IN) taf gate
   1819  *     cb               - (IN) callback function
   1820  * Returns:
   1821  *     BCM_E_XXX
   1822  */
   1823 int
   1824 bcm_esw_tsn_taf_event_unregister(
   1825     int unit,
   1826     bcm_tsn_taf_event_types_t event_types,
   1827     int taf_gate,
   1828     bcm_tsn_taf_event_cb cb)
   1829 {
   1830     int rv = BCM_E_UNAVAIL;
   1831 
   1832 #if defined(BCM_TSN_SUPPORT)
   1833     bcmi_tsn_taf_control_t *tc;
   1834 
   1835     BCM_IF_ERROR_RETURN(
   1836         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1837 
   1838     TSN_TAF_LOCK(tc);
   1839     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate));
   1840 
   1841     if (BCM_SUCCESS(rv)) {
   1842         rv = TSN_TAF_FUNC(
   1843                  event_unregister, (unit, taf_gate, event_types, cb));
   1844     }
   1845     TSN_TAF_UNLOCK(tc);
   1846 #endif /* BCM_TSN_SUPPORT */
   1847 
   1848     return rv;
   1849 }
   1850 
   1851 /*
   1852  * Function:
   1853  *     bcm_esw_tsn_taf_gate_max_bytes_profile_create
   1854  * Purpose:
   1855  *     Create profile of maximum bytes that pass through the TAF gate
   1856  * Parameters:
   1857  *     unit             - (IN) unit number
   1858  *     taf_gate_id      - (IN) taf gate
   1859  *     max_bytes        - (IN) maximum bytes
   1860  *     profile_id       - (OUT) profile id
   1861  * Returns:
   1862  *     BCM_E_XXX
   1863  */
   1864 int
   1865 bcm_esw_tsn_taf_gate_max_bytes_profile_create(
   1866     int unit,
   1867     int taf_gate_id,
   1868     uint64 max_bytes,
   1869     int *profile_id)
   1870 {
   1871     int rv = BCM_E_UNAVAIL;
   1872 
   1873 #if defined(BCM_TSN_SUPPORT)
   1874     bcmi_tsn_taf_control_t *tc;
   1875 
   1876     BCM_IF_ERROR_RETURN(
   1877         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1878 
   1879     TSN_TAF_LOCK(tc);
   1880     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   1881 
   1882     if (BCM_SUCCESS(rv)) {
   1883         rv = TSN_TAF_FUNC(
   1884                 gate_max_bytes_profile_create,
   1885                     (unit, taf_gate_id, max_bytes, profile_id));
   1886     }
   1887     TSN_TAF_UNLOCK(tc);
   1888 #endif /* BCM_TSN_SUPPORT */
   1889 
   1890     return rv;
   1891 }
   1892 
   1893 /*
   1894  * Function:
   1895  *     bcm_esw_tsn_taf_gate_max_bytes_profile_set
   1896  * Purpose:
   1897  *     Set profile of maximum bytes that pass through the TAF gate
   1898  * Parameters:
   1899  *     unit             - (IN) unit number
   1900  *     taf_gate_id      - (IN) taf gate
   1901  *     profile_id       - (IN) profile id
   1902  *     max_bytes        - (IN) maximum bytes
   1903  * Returns:
   1904  *     BCM_E_XXX
   1905  */
   1906 int
   1907 bcm_esw_tsn_taf_gate_max_bytes_profile_set(
   1908     int unit,
   1909     int taf_gate_id,
   1910     int profile_id,
   1911     uint64 max_bytes)
   1912 {
   1913     int rv = BCM_E_UNAVAIL;
   1914 
   1915 #if defined(BCM_TSN_SUPPORT)
   1916     bcmi_tsn_taf_control_t *tc;
   1917 
   1918     BCM_IF_ERROR_RETURN(
   1919         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1920 
   1921     TSN_TAF_LOCK(tc);
   1922     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   1923 
   1924     if (BCM_SUCCESS(rv)) {
   1925         rv = TSN_TAF_FUNC(
   1926                 gate_max_bytes_profile_set,
   1927                     (unit, taf_gate_id, profile_id, max_bytes));
   1928     }
   1929     TSN_TAF_UNLOCK(tc);
   1930 #endif /* BCM_TSN_SUPPORT */
   1931 
   1932     return rv;
   1933 }
   1934 
   1935 /*
   1936  * Function:
   1937  *     bcm_esw_tsn_taf_gate_max_bytes_profile_get
   1938  * Purpose:
   1939  *     Get profile of maximum bytes that pass through the TAF gate
   1940  * Parameters:
   1941  *     unit             - (IN) unit number
   1942  *     taf_gate_id      - (IN) taf gate
   1943  *     profile_id       - (IN) profile id
   1944  *     max_bytes        - (OUT) maximum bytes
   1945  * Returns:
   1946  *     BCM_E_XXX
   1947  */
   1948 int
   1949 bcm_esw_tsn_taf_gate_max_bytes_profile_get(
   1950     int unit,
   1951     int taf_gate_id,
   1952     int profile_id,
   1953     uint64 *max_bytes)
   1954 {
   1955     int rv = BCM_E_UNAVAIL;
   1956 
   1957 #if defined(BCM_TSN_SUPPORT)
   1958     bcmi_tsn_taf_control_t *tc;
   1959 
   1960     BCM_IF_ERROR_RETURN(
   1961         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   1962 
   1963     TSN_TAF_LOCK(tc);
   1964     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   1965 
   1966     if (BCM_SUCCESS(rv)) {
   1967         rv = TSN_TAF_FUNC(
   1968                 gate_max_bytes_profile_get,
   1969                     (unit, taf_gate_id, profile_id, max_bytes));
   1970     }
   1971     TSN_TAF_UNLOCK(tc);
   1972 #endif /* BCM_TSN_SUPPORT */
   1973 
   1974     return rv;
   1975 }
   1976 
   1977 /*
   1978  * Function:
   1979  *     bcm_esw_tsn_taf_gate_max_bytes_profile_destroy
   1980  * Purpose:
   1981  *     Destroy profile of maximum bytes that pass through the TAF gate
   1982  * Parameters:
   1983  *     unit             - (IN) unit number
   1984  *     taf_gate_id      - (IN) taf gate
   1985  *     profile_id       - (IN) profile id
   1986  * Returns:
   1987  *     BCM_E_XXX
   1988  */
   1989 int
   1990 bcm_esw_tsn_taf_gate_max_bytes_profile_destroy(
   1991     int unit,
   1992     int taf_gate_id,
   1993     int profile_id)
   1994 {
   1995     int rv = BCM_E_UNAVAIL;
   1996 
   1997 #if defined(BCM_TSN_SUPPORT)
   1998     bcmi_tsn_taf_control_t *tc;
   1999 
   2000     BCM_IF_ERROR_RETURN(
   2001         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2002 
   2003     TSN_TAF_LOCK(tc);
   2004     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2005 
   2006     if (BCM_SUCCESS(rv)) {
   2007         rv = TSN_TAF_FUNC(
   2008                 gate_max_bytes_profile_destroy,
   2009                     (unit, taf_gate_id, profile_id));
   2010     }
   2011     TSN_TAF_UNLOCK(tc);
   2012 #endif /* BCM_TSN_SUPPORT */
   2013 
   2014     return rv;
   2015 }
   2016 
   2017 /*
   2018  * Function:
   2019  *     bcm_esw_tsn_taf_gate_max_bytes_profile_traverse
   2020  * Purpose:
   2021  *     Traverse profile of maximum bytes that pass through the TAF gate
   2022  * Parameters:
   2023  *     unit             - (IN) unit number
   2024  *     taf_gate_id      - (IN) taf gate
   2025  *     cb               - (IN) callback function
   2026  *     user_data        - (IN) user data
   2027  * Returns:
   2028  *     BCM_E_XXX
   2029  */
   2030 int
   2031 bcm_esw_tsn_taf_gate_max_bytes_profile_traverse(
   2032     int unit,
   2033     int taf_gate_id,
   2034     bcm_tsn_taf_gate_max_bytes_profile_traverse_cb cb,
   2035     void *user_data)
   2036 {
   2037     int rv = BCM_E_UNAVAIL;
   2038 
   2039 #if defined(BCM_TSN_SUPPORT)
   2040     bcmi_tsn_taf_control_t *tc;
   2041 
   2042     BCM_IF_ERROR_RETURN(
   2043         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2044 
   2045     TSN_TAF_LOCK(tc);
   2046     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2047 
   2048     if (BCM_SUCCESS(rv)) {
   2049         rv = TSN_TAF_FUNC(
   2050                 gate_max_bytes_profile_traverse,
   2051                     (unit, taf_gate_id, cb, user_data));
   2052     }
   2053     TSN_TAF_UNLOCK(tc);
   2054 #endif /* BCM_TSN_SUPPORT */
   2055 
   2056     return rv;
   2057 }
   2058 
   2059 /*
   2060  * Function:
   2061  *     bcm_esw_tsn_taf_cosq_mapping_profile_create
   2062  * Purpose:
   2063  *     Create TAF Cos mapping profile
   2064  * Parameters:
   2065  *     unit             - (IN) unit number
   2066  *     cosq_profile     - (OUT) profile id
   2067  * Returns:
   2068  *     BCM_E_XXX
   2069  */
   2070 int
   2071 bcm_esw_tsn_taf_cosq_mapping_profile_create(
   2072     int unit,
   2073     int *cosq_profile)
   2074 {
   2075     int rv = BCM_E_UNAVAIL;
   2076 
   2077 #if defined(BCM_TSN_SUPPORT)
   2078     bcmi_tsn_taf_control_t *tc;
   2079 
   2080     BCM_IF_ERROR_RETURN(
   2081         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2082 
   2083     TSN_TAF_LOCK(tc);
   2084     rv = TSN_TAF_FUNC(
   2085              cosq_mapping_profile_create, (unit, cosq_profile));
   2086     TSN_TAF_UNLOCK(tc);
   2087 #endif /* BCM_TSN_SUPPORT */
   2088 
   2089     return rv;
   2090 }
   2091 
   2092 /*
   2093  * Function:
   2094  *     bcm_esw_tsn_taf_cosq_mapping_profile_set
   2095  * Purpose:
   2096  *     Set TAF Cos mapping profile
   2097  * Parameters:
   2098  *     unit             - (IN) unit number
   2099  *     cosq_profile     - (IN) profile id
   2100  *     priority         - (IN) internal priority
   2101  *     cosq             - (IN) CosQ id
   2102  * Returns:
   2103  *     BCM_E_XXX
   2104  */
   2105 int
   2106 bcm_esw_tsn_taf_cosq_mapping_profile_set(
   2107     int unit,
   2108     int cosq_profile,
   2109     bcm_cos_t priority,
   2110     bcm_cos_queue_t cosq)
   2111 {
   2112     int rv = BCM_E_UNAVAIL;
   2113 
   2114 #if defined(BCM_TSN_SUPPORT)
   2115     bcmi_tsn_taf_control_t *tc;
   2116 
   2117     BCM_IF_ERROR_RETURN(
   2118         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2119 
   2120     TSN_TAF_LOCK(tc);
   2121     rv = TSN_TAF_FUNC(
   2122              cosq_mapping_profile_set, (unit, cosq_profile, priority, cosq));
   2123     TSN_TAF_UNLOCK(tc);
   2124 #endif /* BCM_TSN_SUPPORT */
   2125 
   2126     return rv;
   2127 }
   2128 
   2129 /*
   2130  * Function:
   2131  *     bcm_esw_tsn_taf_cosq_mapping_profile_get
   2132  * Purpose:
   2133  *     Get TAF Cos mapping profile
   2134  * Parameters:
   2135  *     unit             - (IN) unit number
   2136  *     cosq_profile     - (IN) profile id
   2137  *     priority         - (IN) internal priority
   2138  *     cosq             - (OUT)CosQ id
   2139  * Returns:
   2140  *     BCM_E_XXX
   2141  */
   2142 int
   2143 bcm_esw_tsn_taf_cosq_mapping_profile_get(
   2144     int unit,
   2145     int cosq_profile,
   2146     bcm_cos_t priority,
   2147     bcm_cos_queue_t *cosq)
   2148 {
   2149     int rv = BCM_E_UNAVAIL;
   2150 
   2151 #if defined(BCM_TSN_SUPPORT)
   2152     bcmi_tsn_taf_control_t *tc;
   2153 
   2154     BCM_IF_ERROR_RETURN(
   2155         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2156 
   2157     TSN_TAF_LOCK(tc);
   2158     rv = TSN_TAF_FUNC(
   2159              cosq_mapping_profile_get, (unit, cosq_profile, priority, cosq));
   2160     TSN_TAF_UNLOCK(tc);
   2161 #endif /* BCM_TSN_SUPPORT */
   2162 
   2163     return rv;
   2164 }
   2165 
   2166 /*
   2167  * Function:
   2168  *     bcm_esw_tsn_taf_cosq_mapping_profile_destroy
   2169  * Purpose:
   2170  *     Destroy TAF Cos mapping profile
   2171  * Parameters:
   2172  *     unit             - (IN) unit number
   2173  *     cosq_profile     - (IN) profile id
   2174  * Returns:
   2175  *     BCM_E_XXX
   2176  */
   2177 int
   2178 bcm_esw_tsn_taf_cosq_mapping_profile_destroy(
   2179     int unit,
   2180     int cosq_profile)
   2181 {
   2182     int rv = BCM_E_UNAVAIL;
   2183 
   2184 #if defined(BCM_TSN_SUPPORT)
   2185     bcmi_tsn_taf_control_t *tc;
   2186 
   2187     BCM_IF_ERROR_RETURN(
   2188         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2189 
   2190     TSN_TAF_LOCK(tc);
   2191     rv = TSN_TAF_FUNC(
   2192              cosq_mapping_profile_destroy, (unit, cosq_profile));
   2193     TSN_TAF_UNLOCK(tc);
   2194 #endif /* BCM_TSN_SUPPORT */
   2195 
   2196     return rv;
   2197 }
   2198 
   2199 /*
   2200  * Function:
   2201  *     bcm_esw_tsn_taf_cosq_mapping_profile_traverse
   2202  * Purpose:
   2203  *     Traverse TAF Cos mapping profile
   2204  * Parameters:
   2205  *     unit             - (IN) unit number
   2206  *     cb               - (IN) callback function
   2207  *     user_data        - (IN) user data
   2208  * Returns:
   2209  *     BCM_E_XXX
   2210  */
   2211 int
   2212 bcm_esw_tsn_taf_cosq_mapping_profile_traverse(
   2213     int unit,
   2214     bcm_tsn_taf_cosq_mapping_profile_traverse_cb cb,
   2215     void *user_data)
   2216 {
   2217     int rv = BCM_E_UNAVAIL;
   2218 
   2219 #if defined(BCM_TSN_SUPPORT)
   2220     bcmi_tsn_taf_control_t *tc;
   2221 
   2222     BCM_IF_ERROR_RETURN(
   2223         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2224 
   2225     TSN_TAF_LOCK(tc);
   2226     rv = TSN_TAF_FUNC(
   2227              cosq_mapping_profile_traverse, (unit, cb, user_data));
   2228     TSN_TAF_UNLOCK(tc);
   2229 #endif /* BCM_TSN_SUPPORT */
   2230 
   2231     return rv;
   2232 }
   2233 
   2234 /*
   2235  * Function:
   2236  *      bcm_esw_tsn_taf_gate_stat_set
   2237  * Description:
   2238  *      Set 64-bit counter value for specified TAF gate statistic type
   2239  * Parameters:
   2240  *      unit             - (IN) unit number
   2241  *      taf_gate_id      - (IN) TAF gate id
   2242  *      stat             - (IN) TAF gate stat types
   2243  *      val              - (IN) counter value
   2244  *
   2245  * Return Value:
   2246  *      BCM_E_XXX
   2247  * Notes:
   2248  */
   2249 int
   2250 bcm_esw_tsn_taf_gate_stat_set(
   2251     int unit,
   2252     int taf_gate_id,
   2253     bcm_tsn_taf_gate_stat_t stat,
   2254     uint64 val)
   2255 {
   2256     int rv = BCM_E_UNAVAIL;
   2257 
   2258 #if defined(BCM_TSN_SUPPORT)
   2259     bcmi_tsn_taf_control_t *tc;
   2260 
   2261     BCM_IF_ERROR_RETURN(
   2262         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2263 
   2264     TSN_TAF_LOCK(tc);
   2265     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2266 
   2267     if (BCM_SUCCESS(rv)) {
   2268         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2269                           (unit, taf_gate_id, 1, &stat, &val,
   2270                            bcmiTsnStatCounterActionWrite));
   2271     }
   2272     TSN_TAF_UNLOCK(tc);
   2273 #endif /* BCM_TSN_SUPPORT */
   2274 
   2275     return rv;
   2276 }
   2277 
   2278 /*
   2279  * Function:
   2280  *      bcm_esw_tsn_taf_gate_stat_set32
   2281  * Description:
   2282  *      Set lower 32-bit counter value for specified TAF gate statistic type
   2283  * Parameters:
   2284  *      unit             - (IN) unit number
   2285  *      taf_gate_id      - (IN) TAF gate id
   2286  *      stat             - (IN) TAF gate stat types
   2287  *      val              - (IN) counter value
   2288  *
   2289  * Return Value:
   2290  *      BCM_E_XXX
   2291  * Notes:
   2292  */
   2293 int
   2294 bcm_esw_tsn_taf_gate_stat_set32(
   2295     int unit,
   2296     int taf_gate_id,
   2297     bcm_tsn_taf_gate_stat_t stat,
   2298     uint32 val)
   2299 {
   2300     int rv = BCM_E_UNAVAIL;
   2301 
   2302 #if defined(BCM_TSN_SUPPORT)
   2303     bcmi_tsn_taf_control_t *tc;
   2304     uint64 value64;
   2305 
   2306     BCM_IF_ERROR_RETURN(
   2307         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2308 
   2309     COMPILER_64_SET(value64, 0, val);
   2310 
   2311     TSN_TAF_LOCK(tc);
   2312     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2313 
   2314     if (BCM_SUCCESS(rv)) {
   2315         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2316                           (unit, taf_gate_id, 1, &stat, &value64,
   2317                            bcmiTsnStatCounterActionWrite));
   2318     }
   2319     TSN_TAF_UNLOCK(tc);
   2320 #endif /* BCM_TSN_SUPPORT */
   2321 
   2322     return rv;
   2323 }
   2324 
   2325 /*
   2326  * Function:
   2327  *      bcm_esw_tsn_taf_gate_stat_get
   2328  * Description:
   2329  *      Get 64-bit counter value for specified TAF gate statistic type
   2330  * Parameters:
   2331  *      unit             - (IN) unit number
   2332  *      taf_gate_id      - (IN) TAF gate id
   2333  *      stat             - (IN) TAF gate stat types
   2334  *      val              - (OUT)counter value
   2335  *
   2336  * Return Value:
   2337  *      BCM_E_XXX
   2338  * Notes:
   2339  */
   2340 int
   2341 bcm_esw_tsn_taf_gate_stat_get(
   2342     int unit,
   2343     int taf_gate_id,
   2344     bcm_tsn_taf_gate_stat_t stat,
   2345     uint64 *val)
   2346 {
   2347     int rv = BCM_E_UNAVAIL;
   2348 
   2349 #if defined(BCM_TSN_SUPPORT)
   2350     bcmi_tsn_taf_control_t *tc;
   2351 
   2352     BCM_IF_ERROR_RETURN(
   2353         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2354 
   2355     TSN_TAF_LOCK(tc);
   2356     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2357 
   2358     if (BCM_SUCCESS(rv)) {
   2359         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2360                           (unit, taf_gate_id, 1, &stat, val,
   2361                            bcmiTsnStatCounterActionRead));
   2362     }
   2363     TSN_TAF_UNLOCK(tc);
   2364 #endif /* BCM_TSN_SUPPORT */
   2365 
   2366     return rv;
   2367 }
   2368 
   2369 /*
   2370  * Function:
   2371  *      bcm_esw_tsn_taf_gate_stat_get32
   2372  * Description:
   2373  *      Get lower 32-bit counter value for specified TAF gate statistic type
   2374  * Parameters:
   2375  *      unit             - (IN) unit number
   2376  *      taf_gate_id      - (IN) TAF gate id
   2377  *      stat             - (IN) TAF gate stat types
   2378  *      val              - (OUT)counter value
   2379  *
   2380  * Return Value:
   2381  *      BCM_E_XXX
   2382  * Notes:
   2383  */
   2384 int
   2385 bcm_esw_tsn_taf_gate_stat_get32(
   2386     int unit,
   2387     int taf_gate_id,
   2388     bcm_tsn_taf_gate_stat_t stat,
   2389     uint32 *val)
   2390 {
   2391     int rv = BCM_E_UNAVAIL;
   2392 
   2393 #if defined(BCM_TSN_SUPPORT)
   2394     bcmi_tsn_taf_control_t *tc;
   2395     uint64 value64;
   2396 
   2397     if (NULL == val) {
   2398         return BCM_E_PARAM;
   2399     }
   2400 
   2401     BCM_IF_ERROR_RETURN(
   2402         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2403 
   2404     TSN_TAF_LOCK(tc);
   2405     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2406 
   2407     if (BCM_SUCCESS(rv)) {
   2408         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2409                           (unit, taf_gate_id, 1, &stat, &value64,
   2410                            bcmiTsnStatCounterActionRead));
   2411     }
   2412     TSN_TAF_UNLOCK(tc);
   2413 
   2414     if (BCM_SUCCESS(rv)) {
   2415         *val = COMPILER_64_LO(value64);
   2416     }
   2417 #endif /* BCM_TSN_SUPPORT */
   2418 
   2419     return rv;
   2420 }
   2421 
   2422 /*
   2423  * Function:
   2424  *      bcm_esw_tsn_taf_gate_stat_multi_set
   2425  * Description:
   2426  *      Set 64-bit counter value for multiple TAF gate statistic types.
   2427  * Parameters:
   2428  *      unit             - (IN) unit number
   2429  *      taf_gate_id      - (IN) TAF gate id
   2430  *      nstat            - (IN) number of element in stat_arr and value_arr
   2431  *      stat_arr         - (IN) TAF gate stat types
   2432  *      value_arr        - (IN) counter value
   2433  *
   2434  * Return Value:
   2435  *      BCM_E_XXX
   2436  * Notes:
   2437  */
   2438 int
   2439 bcm_esw_tsn_taf_gate_stat_multi_set(
   2440     int unit,
   2441     int taf_gate_id,
   2442     int nstat,
   2443     bcm_tsn_taf_gate_stat_t *stat_arr,
   2444     uint64 *value_arr)
   2445 {
   2446     int rv = BCM_E_UNAVAIL;
   2447 
   2448 #if defined(BCM_TSN_SUPPORT)
   2449     bcmi_tsn_taf_control_t *tc;
   2450 
   2451     if (nstat < 0 || nstat > bcmTsnTafGateStatCount) {
   2452         return BCM_E_PARAM;
   2453     }
   2454 
   2455     BCM_IF_ERROR_RETURN(
   2456         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2457 
   2458     TSN_TAF_LOCK(tc);
   2459     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2460 
   2461     if (BCM_SUCCESS(rv)) {
   2462         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2463                           (unit, taf_gate_id, nstat, stat_arr, value_arr,
   2464                            bcmiTsnStatCounterActionWrite));
   2465     }
   2466     TSN_TAF_UNLOCK(tc);
   2467 #endif /* BCM_TSN_SUPPORT */
   2468 
   2469     return rv;
   2470 }
   2471 
   2472 /*
   2473  * Function:
   2474  *      bcm_esw_tsn_taf_gate_stat_multi_set32
   2475  * Description:
   2476  *      Set lower 32-bit counter value for multiple TAF gate statistic types.
   2477  * Parameters:
   2478  *      unit             - (IN) unit number
   2479  *      taf_gate_id      - (IN) TAF gate id
   2480  *      nstat            - (IN) number of element in stat_arr and value_arr
   2481  *      stat_arr         - (IN) TAF gate stat types
   2482  *      value_arr        - (IN) counter value
   2483  *
   2484  * Return Value:
   2485  *      BCM_E_XXX
   2486  * Notes:
   2487  */
   2488 int
   2489 bcm_esw_tsn_taf_gate_stat_multi_set32(
   2490     int unit,
   2491     int taf_gate_id,
   2492     int nstat,
   2493     bcm_tsn_taf_gate_stat_t *stat_arr,
   2494     uint32 *value_arr)
   2495 {
   2496 
   2497     int rv = BCM_E_UNAVAIL;
   2498 
   2499 #if defined(BCM_TSN_SUPPORT)
   2500     bcmi_tsn_taf_control_t *tc;
   2501     uint64 *value64_arr = NULL;
   2502     int i;
   2503 
   2504     BCM_IF_ERROR_RETURN(
   2505         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2506 
   2507     if (NULL == value_arr) {
   2508         return BCM_E_PARAM;
   2509     }
   2510 
   2511     if (nstat < 0 || nstat > bcmTsnTafGateStatCount) {
   2512         return BCM_E_PARAM;
   2513     }
   2514 
   2515     value64_arr = sal_alloc(nstat * sizeof(uint64), "value64_arr");
   2516     if (NULL == value64_arr) {
   2517         return BCM_E_MEMORY;
   2518     }
   2519     for (i = 0; i < nstat ; i++) {
   2520         COMPILER_64_SET(value64_arr[i], 0, value_arr[i]);
   2521     }
   2522 
   2523     TSN_TAF_LOCK(tc);
   2524     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2525 
   2526     if (BCM_SUCCESS(rv)) {
   2527         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2528                           (unit, taf_gate_id, nstat, stat_arr, value64_arr,
   2529                            bcmiTsnStatCounterActionWrite));
   2530     }
   2531     TSN_TAF_UNLOCK(tc);
   2532     sal_free(value64_arr);
   2533 #endif /* BCM_TSN_SUPPORT */
   2534 
   2535     return rv;
   2536 
   2537 }
   2538 
   2539 /*
   2540  * Function:
   2541  *      bcm_esw_tsn_taf_gate_stat_multi_get
   2542  * Description:
   2543  *      Get 64-bit counter value for multiple TAF gate statistic types.
   2544  * Parameters:
   2545  *      unit             - (IN) unit number
   2546  *      taf_gate_id      - (IN) TAF gate id
   2547  *      nstat            - (IN) size of stat_arr and value_arr
   2548  *      stat_arr         - (IN) TAF gate stat types
   2549  *      value_arr        - (OUT)counter value
   2550  *
   2551  * Return Value:
   2552  *      BCM_E_XXX
   2553  * Notes:
   2554  */
   2555 int
   2556 bcm_esw_tsn_taf_gate_stat_multi_get(
   2557     int unit,
   2558     int taf_gate_id,
   2559     int nstat,
   2560     bcm_tsn_taf_gate_stat_t *stat_arr,
   2561     uint64 *value_arr)
   2562 {
   2563     int rv = BCM_E_UNAVAIL;
   2564 
   2565  #if defined(BCM_TSN_SUPPORT)
   2566     bcmi_tsn_taf_control_t *tc;
   2567 
   2568     if (nstat < 0 || nstat > bcmTsnTafGateStatCount) {
   2569         return BCM_E_PARAM;
   2570     }
   2571 
   2572     BCM_IF_ERROR_RETURN(
   2573         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2574 
   2575     TSN_TAF_LOCK(tc);
   2576     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2577 
   2578     if (BCM_SUCCESS(rv)) {
   2579         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2580                           (unit, taf_gate_id, nstat, stat_arr, value_arr,
   2581                            bcmiTsnStatCounterActionRead));
   2582     }
   2583     TSN_TAF_UNLOCK(tc);
   2584 #endif /* BCM_TSN_SUPPORT */
   2585 
   2586     return rv;
   2587 }
   2588 
   2589 /*
   2590  * Function:
   2591  *      bcm_esw_tsn_taf_gate_stat_multi_get32
   2592  * Description:
   2593  *      Get lower 32-bit counter value for multiple TAF gate statistic types.
   2594  * Parameters:
   2595  *      unit             - (IN) unit number
   2596  *      taf_gate_id      - (IN) TAF gate id
   2597  *      nstat            - (IN) size of stat_arr and value_arr
   2598  *      stat_arr         - (IN) TAF gate stat types
   2599  *      value_arr        - (OUT)counter value
   2600  *
   2601  * Return Value:
   2602  *      BCM_E_XXX
   2603  * Notes:
   2604  */
   2605 int
   2606 bcm_esw_tsn_taf_gate_stat_multi_get32(
   2607     int unit,
   2608     int taf_gate_id,
   2609     int nstat,
   2610     bcm_tsn_taf_gate_stat_t *stat_arr,
   2611     uint32 *value_arr)
   2612 {
   2613     int rv = BCM_E_UNAVAIL;
   2614 
   2615 #if defined(BCM_TSN_SUPPORT)
   2616     bcmi_tsn_taf_control_t *tc;
   2617     uint64 *value64_arr = NULL;
   2618     int i;
   2619 
   2620     BCM_IF_ERROR_RETURN(
   2621         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2622 
   2623     if (NULL == value_arr) {
   2624         return BCM_E_PARAM;
   2625     }
   2626 
   2627     if (nstat < 0 || nstat > bcmTsnTafGateStatCount) {
   2628         return BCM_E_PARAM;
   2629     }
   2630 
   2631     value64_arr = sal_alloc(nstat * sizeof(uint64), "value64_arr");
   2632     if (NULL == value64_arr) {
   2633         return BCM_E_MEMORY;
   2634     }
   2635 
   2636     TSN_TAF_LOCK(tc);
   2637     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2638 
   2639     if (BCM_SUCCESS(rv)) {
   2640         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2641                           (unit, taf_gate_id, nstat, stat_arr, value64_arr,
   2642                            bcmiTsnStatCounterActionRead));
   2643     }
   2644     TSN_TAF_UNLOCK(tc);
   2645 
   2646     if (BCM_SUCCESS(rv)) {
   2647         for (i = 0; i < nstat ; i++) {
   2648             value_arr[i] = COMPILER_64_LO(value64_arr[i]);
   2649         }
   2650     }
   2651     sal_free(value64_arr);
   2652 #endif /* BCM_TSN_SUPPORT */
   2653 
   2654     return rv;
   2655 }
   2656 
   2657 /*
   2658  * Function:
   2659  *      bcm_esw_tsn_taf_gate_stat_sync_get
   2660  * Description:
   2661  *      Get the specified hardware statistics (64-bit) from the device.
   2662  * Parameters:
   2663  *      unit             - (IN) unit number
   2664  *      taf_gate_id      - (IN) TAF gate id
   2665  *      stat             - (IN) TAF gate stat types
   2666  *      val              - (OUT)counter value
   2667  *
   2668  * Return Value:
   2669  *      BCM_E_XXX
   2670  * Notes:
   2671  */
   2672 int
   2673 bcm_esw_tsn_taf_gate_stat_sync_get(
   2674     int unit,
   2675     int taf_gate_id,
   2676     bcm_tsn_taf_gate_stat_t stat,
   2677     uint64 *val)
   2678 {
   2679     int rv = BCM_E_UNAVAIL;
   2680 
   2681 #if defined(BCM_TSN_SUPPORT)
   2682     bcmi_tsn_taf_control_t *tc;
   2683 
   2684     BCM_IF_ERROR_RETURN(
   2685         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2686 
   2687     TSN_TAF_LOCK(tc);
   2688     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2689 
   2690     if (BCM_SUCCESS(rv)) {
   2691         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2692                           (unit, taf_gate_id, 1, &stat, val,
   2693                            bcmiTsnStatCounterActionReadSync));
   2694     }
   2695     TSN_TAF_UNLOCK(tc);
   2696 #endif /* BCM_TSN_SUPPORT */
   2697 
   2698     return rv;
   2699 }
   2700 
   2701 /*
   2702  * Function:
   2703  *      bcm_esw_tsn_taf_gate_stat_sync_get32
   2704  * Description:
   2705  *      Get the specified hardware statistics (32-bit) from the device.
   2706  * Parameters:
   2707  *      unit             - (IN) unit number
   2708  *      taf_gate_id      - (IN) TAF gate id
   2709  *      stat             - (IN) TAF gate stat types
   2710  *      val              - (OUT)counter value
   2711  *
   2712  * Return Value:
   2713  *      BCM_E_XXX
   2714  * Notes:
   2715  */
   2716 int
   2717 bcm_esw_tsn_taf_gate_stat_sync_get32(
   2718     int unit,
   2719     int taf_gate_id,
   2720     bcm_tsn_taf_gate_stat_t stat,
   2721     uint32 *val)
   2722 {
   2723     int rv = BCM_E_UNAVAIL;
   2724 
   2725 #if defined(BCM_TSN_SUPPORT)
   2726     bcmi_tsn_taf_control_t *tc;
   2727     uint64 value64;
   2728 
   2729     BCM_IF_ERROR_RETURN(
   2730         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2731 
   2732     if (NULL == val) {
   2733         return BCM_E_PARAM;
   2734     }
   2735 
   2736     TSN_TAF_LOCK(tc);
   2737     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2738 
   2739     if (BCM_SUCCESS(rv)) {
   2740         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2741                           (unit, taf_gate_id, 1, &stat, &value64,
   2742                            bcmiTsnStatCounterActionReadSync));
   2743     }
   2744     TSN_TAF_UNLOCK(tc);
   2745 
   2746 
   2747     if (BCM_SUCCESS(rv)) {
   2748         *val = COMPILER_64_LO(value64);
   2749     }
   2750 #endif /* BCM_TSN_SUPPORT */
   2751 
   2752     return rv;
   2753 }
   2754 
   2755 /*
   2756  * Function:
   2757  *      bcm_esw_tsn_taf_gate_stat_sync_multi_get
   2758  * Description:
   2759  *      Get multiple hardware statistics (64-bit) from the device
   2760  * Parameters:
   2761  *      unit             - (IN) unit number
   2762  *      taf_gate_id      - (IN) TAF gate id
   2763  *      nstat            - (IN) size of stat_arr and value_arr
   2764  *      stat_arr         - (IN) TAF gate stat types
   2765  *      value_arr        - (OUT)counter value
   2766  *
   2767  * Return Value:
   2768  *      BCM_E_XXX
   2769  * Notes:
   2770  */
   2771 int
   2772 bcm_esw_tsn_taf_gate_stat_sync_multi_get(
   2773     int unit,
   2774     int taf_gate_id,
   2775     int nstat,
   2776     bcm_tsn_taf_gate_stat_t *stat_arr,
   2777     uint64 *value_arr)
   2778 {
   2779     int rv = BCM_E_UNAVAIL;
   2780 
   2781 #if defined(BCM_TSN_SUPPORT)
   2782     bcmi_tsn_taf_control_t *tc;
   2783 
   2784     if (nstat < 0 || nstat > bcmTsnTafGateStatCount) {
   2785         return BCM_E_PARAM;
   2786     }
   2787 
   2788     BCM_IF_ERROR_RETURN(
   2789         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2790 
   2791     TSN_TAF_LOCK(tc);
   2792     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2793 
   2794     if (BCM_SUCCESS(rv)) {
   2795         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2796                           (unit, taf_gate_id, nstat, stat_arr, value_arr,
   2797                            bcmiTsnStatCounterActionReadSync));
   2798     }
   2799     TSN_TAF_UNLOCK(tc);
   2800 #endif /* BCM_TSN_SUPPORT */
   2801 
   2802     return rv;
   2803 }
   2804 
   2805 /*
   2806  * Function:
   2807  *      bcm_esw_tsn_taf_gate_stat_sync_multi_get32
   2808  * Description:
   2809  *      Get multiple hardware statistics (32-bit) from the device
   2810  * Parameters:
   2811  *      unit             - (IN) unit number
   2812  *      taf_gate_id      - (IN) TAF gate id
   2813  *      nstat            - (IN) size of stat_arr and value_arr
   2814  *      stat_arr         - (IN) TAF gate stat types
   2815  *      value_arr        - (OUT)counter value
   2816  *
   2817  * Return Value:
   2818  *      BCM_E_XXX
   2819  * Notes:
   2820  */
   2821 int
   2822 bcm_esw_tsn_taf_gate_stat_sync_multi_get32(
   2823     int unit,
   2824     int taf_gate_id,
   2825     int nstat,
   2826     bcm_tsn_taf_gate_stat_t *stat_arr,
   2827     uint32 *value_arr)
   2828 {
   2829     int rv = BCM_E_UNAVAIL;
   2830 
   2831 #if defined(BCM_TSN_SUPPORT)
   2832     bcmi_tsn_taf_control_t *tc;
   2833     uint64 *value64_arr = NULL;
   2834     int i;
   2835 
   2836     BCM_IF_ERROR_RETURN(
   2837         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2838 
   2839     if (NULL == value_arr) {
   2840         return BCM_E_PARAM;
   2841     }
   2842 
   2843     if (nstat < 0 || nstat > bcmTsnTafGateStatCount) {
   2844         return BCM_E_PARAM;
   2845     }
   2846 
   2847     value64_arr = sal_alloc(nstat * sizeof(uint64), "value64_arr");
   2848     if (NULL == value64_arr) {
   2849         return BCM_E_MEMORY;
   2850     }
   2851 
   2852     TSN_TAF_LOCK(tc);
   2853     rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id));
   2854 
   2855     if (BCM_SUCCESS(rv)) {
   2856         rv = TSN_TAF_FUNC(gate_stat_counter_access,
   2857                           (unit, taf_gate_id, nstat, stat_arr, value64_arr,
   2858                            bcmiTsnStatCounterActionReadSync));
   2859     }
   2860     TSN_TAF_UNLOCK(tc);
   2861 
   2862     if (BCM_SUCCESS(rv)) {
   2863         for (i = 0; i < nstat ; i++) {
   2864             value_arr[i] = COMPILER_64_LO(value64_arr[i]);
   2865         }
   2866     }
   2867     sal_free(value64_arr);
   2868 #endif /* BCM_TSN_SUPPORT */
   2869 
   2870     return rv;
   2871 }
   2872 
   2873 #if defined(BCM_TSN_SUPPORT)
   2874 /*
   2875  * Function:
   2876  *    bcmi_esw_tsn_taf_gate_stat_sync
   2877  * Description:
   2878  *    Callback function for counter collection on a specific gate
   2879  * Parameters:
   2880  *    unit - (IN) Unit number
   2881  * Returns:
   2882  *    BCM_E_XXX
   2883  */
   2884 
   2885 STATIC int
   2886 bcmi_esw_tsn_taf_gate_stat_sync(
   2887     int unit,
   2888     int taf_gate,
   2889     void *user_data)
   2890 {
   2891     return TSN_TAF_FUNC(gate_stat_counter_sync, (unit, taf_gate));
   2892 }
   2893 
   2894 /*
   2895  * Function:
   2896  *    bcmi_esw_tsn_stat_counter_cb
   2897  * Description:
   2898  *    Callback function for counter collection
   2899  * Parameters:
   2900  *    unit - (IN) Unit number
   2901  * Returns:
   2902  *    BCM_E_XXX
   2903  */
   2904 STATIC void
   2905 bcmi_esw_tsn_taf_gate_stat_cb(int unit)
   2906 {
   2907     bcmi_tsn_taf_control_t *tc;
   2908     int rv;
   2909 
   2910     rv = bcmi_esw_tsn_taf_instance_get(unit, &tc);
   2911     if (BCM_FAILURE(rv)) {
   2912         return;
   2913     }
   2914 
   2915     TSN_TAF_LOCK(tc);
   2916     (void)TSN_TAF_FUNC(gate_traverse,
   2917                        (unit, bcmi_esw_tsn_taf_gate_stat_sync, NULL));
   2918     TSN_TAF_UNLOCK(tc);
   2919 }
   2920 
   2921 /* TAF gate Priority Map driver set */
   2922 tsn_pri_map_info_t bcmi_taf_gate_pri_map_info = {
   2923     "taf_gate_priority_map",                 /* table_name */
   2924     0,                                       /* table_size,
   2925                                               * init at bcmi_esw_tsn_taf_init */
   2926     0,                                       /* entry_size,
   2927                                               * init at bcmi_esw_tsn_taf_init */
   2928     bcmi_esw_tsn_taf_gate_pri_map_set,       /* tsn_pri_map_set */
   2929     bcmi_esw_tsn_taf_gate_pri_map_get,       /* tsn_pri_map_get */
   2930     bcmi_esw_tsn_taf_gate_pri_map_delete,    /* tsn_pri_map_delete */
   2931     bcmi_esw_tsn_taf_gate_pri_map_hw_idx_get, /* tsn_pri_map_hw_index_get */
   2932     bcmi_esw_tsn_taf_gate_pri_map_sw_idx_get, /* tsn_pri_map_sw_idx_get */
   2933     bcmi_esw_tsn_taf_gate_pri_map_wb_hw_existed  /* tsn_pri_map_wb_hw_existed */
   2934 };
   2935 
   2936 #if defined(BCM_WARM_BOOT_SUPPORT)
   2937 int
   2938 bcmi_esw_tsn_taf_sync(int unit)
   2939 {
   2940     int rv = BCM_E_UNAVAIL;
   2941 
   2942  #if defined(BCM_TSN_SUPPORT)
   2943     bcmi_tsn_taf_control_t *tc;
   2944     soc_scache_handle_t scache_handle;
   2945     uint8 *scache_ptr;
   2946     int scache_size;
   2947 
   2948     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TSN,
   2949                           BCM_TSN_WB_SCACHE_PART_TAF);
   2950 
   2951     BCM_IF_ERROR_RETURN(
   2952         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2953 
   2954     TSN_TAF_LOCK(tc);
   2955     rv = TSN_TAF_FUNC(get_scache_size, (unit, &scache_size));
   2956 
   2957     if (BCM_SUCCESS(rv)) {
   2958         rv = _bcm_esw_scache_ptr_get(
   2959                  unit, scache_handle, TRUE,
   2960                  scache_size,
   2961                  &scache_ptr, BCM_TSN_WB_DEFAULT_VERSION, NULL);
   2962     }
   2963 
   2964     if (BCM_SUCCESS(rv)) {
   2965         rv = TSN_TAF_FUNC(sync, (unit, scache_ptr));
   2966     }
   2967     TSN_TAF_UNLOCK(tc);
   2968 #endif /* BCM_TSN_SUPPORT */
   2969 
   2970     return rv;
   2971 }
   2972 
   2973 int
   2974 bcmi_esw_tsn_taf_reload(int unit)
   2975 {
   2976     int rv = BCM_E_UNAVAIL;
   2977 
   2978 #if defined(BCM_TSN_SUPPORT)
   2979     bcmi_tsn_taf_control_t *tc;
   2980     soc_scache_handle_t scache_handle;
   2981     uint8 *scache_ptr;
   2982     int scache_size;
   2983 
   2984     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TSN,
   2985                           BCM_TSN_WB_SCACHE_PART_TAF);
   2986 
   2987     BCM_IF_ERROR_RETURN(
   2988         bcmi_esw_tsn_taf_instance_get(unit, &tc));
   2989 
   2990     TSN_TAF_LOCK(tc);
   2991     rv = TSN_TAF_FUNC(get_scache_size, (unit, &scache_size));
   2992 
   2993     if (BCM_SUCCESS(rv)) {
   2994         rv = _bcm_esw_scache_ptr_get(
   2995                  unit, scache_handle, FALSE,
   2996                  scache_size,
   2997                  &scache_ptr, BCM_TSN_WB_DEFAULT_VERSION, NULL);
   2998     }
   2999 
   3000     if (BCM_E_NOT_FOUND == rv) {
   3001         /* Maybe proceed with Level 1 Warm Boot */
   3002         TSN_TAF_UNLOCK(tc);
   3003         return BCM_E_NONE;
   3004     } else if (BCM_E_NONE == rv) {
   3005         if (NULL == scache_ptr) {
   3006             rv = BCM_E_INTERNAL;
   3007         } else {
   3008             rv = TSN_TAF_FUNC(reload, (unit, scache_ptr));
   3009         }
   3010     }
   3011 
   3012     if (BCM_SUCCESS(rv)) {
   3013         /* after reloading in chip level successfully,
   3014          * all internal profile has already been recoverd
   3015          *  ==> start to recover taf_profile_pending/active in esw layer
   3016          */
   3017         int gate_id, profile_id;
   3018 
   3019         for (gate_id = 0; gate_id < BCMI_TSN_TAF_GATE_NUM; gate_id++) {
   3020             rv = TSN_TAF_FUNC(gate_check, (unit, gate_id));
   3021             if (BCM_FAILURE(rv)) {
   3022                 rv = BCM_E_NONE;
   3023                 continue; /* skip invalid gate */
   3024             }
   3025 
   3026             for (profile_id = 0; profile_id < BCMI_TSN_TAF_PROFILE_NUM_MAX;
   3027                  profile_id++) {
   3028 
   3029                 bcmi_tsn_taf_profile_t *profile_i;
   3030 
   3031                 rv = TSN_TAF_FUNC(
   3032                          calendar_profile_get, (unit, profile_id,
   3033                                                 &profile_i));
   3034                 if (BCM_FAILURE(rv)) {
   3035                     rv = BCM_E_NONE;
   3036                     continue; /* skip invalid profile id */
   3037                 } else if (profile_i->taf_gate != gate_id) {
   3038                     continue; /* skip the profile not owned by this gate */
   3039                 }
   3040 
   3041                 if (profile_i->status == bcmTsnTafProfilePending) {
   3042                     taf_profile_pending[unit][gate_id] = profile_i;
   3043                 } else if (profile_i->status == bcmTsnTafProfileActive) {
   3044                     taf_profile_active[unit][gate_id] = profile_i;
   3045                 }
   3046             }
   3047         }
   3048     }
   3049 
   3050     TSN_TAF_UNLOCK(tc);
   3051 
   3052     /* register handler to handle interrupt after recover database */
   3053     if (BCM_SUCCESS(rv)) {
   3054 #if defined(BCM_GREYHOUND2_SUPPORT)
   3055         if (SOC_IS_GREYHOUND2(unit)) {
   3056             rv = soc_gh2_taf_event_handler_register(
   3057                     unit, bcmi_esw_tsn_taf_interrupt_handle);
   3058         }
   3059 #endif /* BCM_GREYHOUND2_SUPPORT */
   3060     }
   3061 #endif /* BCM_TSN_SUPPORT */
   3062 
   3063     return rv;
   3064 }
   3065 #endif /* BCM_WARM_BOOT_SUPPORT */
   3066 
   3067 
   3068 /*
   3069  * Function:
   3070  *    bcmi_esw_tsn_taf_cleanup
   3071  * Description:
   3072  *    Clean and free all allocated TAF resources
   3073  * Parameters:
   3074  *    unit - (IN) Unit number
   3075  * Returns:
   3076  *    BCM_E_XXX
   3077  */
   3078 void
   3079 bcmi_esw_tsn_taf_cleanup(int unit)
   3080 {
   3081     if (taf_control[unit] != NULL) {
   3082         int i;
   3083 
   3084         if (NULL != taf_control[unit]->taf_dev_info) {
   3085             TSN_TAF_FUNC(cleanup, (unit));
   3086         }
   3087 
   3088         if (NULL != taf_control[unit]->taf_mutex) {
   3089             sal_mutex_destroy(taf_control[unit]->taf_mutex);
   3090             taf_control[unit]->taf_mutex = NULL;
   3091         }
   3092 
   3093         for (i = 0; i < BCMI_TSN_TAF_GATE_NUM; i++) {
   3094             taf_profile_pending[unit][i] = NULL;
   3095             taf_profile_active[unit][i] = NULL;
   3096         }
   3097 
   3098 #if defined(BCM_GREYHOUND2_SUPPORT)
   3099         if (SOC_IS_GREYHOUND2(unit)) {
   3100             soc_gh2_taf_event_handler_register(unit, NULL);
   3101         }
   3102 #endif /* BCM_GREYHOUND2_SUPPORT */
   3103 
   3104         soc_counter_extra_unregister(unit, bcmi_esw_tsn_taf_gate_stat_cb);
   3105 
   3106         sal_free(taf_control[unit]);
   3107         taf_control[unit] = NULL;
   3108     }
   3109 }
   3110 
   3111 /*
   3112  * Function:
   3113  *    bcmi_esw_tsn_taf_init
   3114  * Description:
   3115  *    Initialize and allocate all required resources for TAF
   3116  *    in both coldboot and warmboot
   3117  * Parameters:
   3118  *    unit - (IN) Unit number
   3119  * Returns:
   3120  *    BCM_E_XXX
   3121  */
   3122 int
   3123 bcmi_esw_tsn_taf_init(int unit)
   3124 {
   3125     int rv = BCM_E_NONE;
   3126     bcmi_tsn_taf_control_t *tc;
   3127 
   3128     /* Clean up the TAF related resources */
   3129     if (taf_control[unit] != NULL) {
   3130         bcmi_esw_tsn_taf_cleanup(unit);
   3131     }
   3132 
   3133     /* Allocate TAF resource for this unit. */
   3134     taf_control[unit] = sal_alloc(sizeof(bcmi_tsn_taf_control_t),
   3135                                   "taf control");
   3136     tc = taf_control[unit];
   3137     if (NULL == tc) {
   3138         TSN_TAF_INIT_ERROR_WITH_CLEAN(BCM_E_MEMORY);
   3139     }
   3140     sal_memset(tc, 0, sizeof(bcmi_tsn_taf_control_t));
   3141 
   3142     /* Get the chip bcmi_tsn_taf_dev_info_t structure. */
   3143 #if defined(BCM_GREYHOUND2_SUPPORT)
   3144     if (SOC_IS_GREYHOUND2(unit)) {
   3145         rv = bcmi_gh2_taf_info_init(unit, &tc->taf_dev_info);
   3146         if (BCM_SUCCESS(rv) && NULL == tc->taf_dev_info) {
   3147             TSN_TAF_INIT_ERROR_WITH_CLEAN(BCM_E_INIT);
   3148         }
   3149     } else
   3150 #endif /* BCM_GREYHOUND2_SUPPORT */
   3151     {
   3152         TSN_TAF_INIT_ERROR_WITH_CLEAN(BCM_E_UNAVAIL);
   3153     }
   3154 
   3155     tc->taf_mutex = sal_mutex_create("taf mutex");
   3156     if (NULL == tc->taf_mutex) {
   3157         TSN_TAF_INIT_ERROR_WITH_CLEAN(BCM_E_RESOURCE);
   3158     }
   3159 
   3160     /* init functionality per-chip */
   3161     TSN_TAF_INIT_ERROR_WITH_CLEAN(
   3162         TSN_TAF_FUNC(init, (unit)));
   3163 
   3164     /* Register callback function for gate stat counter */
   3165     TSN_TAF_INIT_ERROR_WITH_CLEAN(
   3166         soc_counter_extra_register(unit, bcmi_esw_tsn_taf_gate_stat_cb));
   3167 
   3168     /* setup primap driver parameter per-chip */
   3169     bcmi_taf_gate_pri_map_info.table_size = TSN_TAF_DATA(gate_profile_num);
   3170     bcmi_taf_gate_pri_map_info.entry_size = TSN_TAF_DATA(gate_intpri_num);
   3171 
   3172     return BCM_E_NONE;
   3173 }
   3174 
   3175 /*
   3176  * Function:
   3177  *    bcmi_esw_tsn_taf_coldboot_init
   3178  * Description:
   3179  *    Initialize and allocate all required resources for TAF in coldboot
   3180  * Parameters:
   3181  *    unit - (IN) Unit number
   3182  * Returns:
   3183  *    BCM_E_XXX
   3184  */
   3185 int
   3186 bcmi_esw_tsn_taf_coldboot_init(int unit)
   3187 {
   3188     /* register handler to handle interrupt */
   3189 #if defined(BCM_GREYHOUND2_SUPPORT)
   3190     if (SOC_IS_GREYHOUND2(unit)) {
   3191         TSN_TAF_INIT_ERROR_WITH_CLEAN(
   3192             soc_gh2_taf_event_handler_register(
   3193                 unit, bcmi_esw_tsn_taf_interrupt_handle));
   3194     }
   3195 #endif /* BCM_GREYHOUND2_SUPPORT */
   3196 
   3197     return BCM_E_NONE;
   3198 }
   3199 #endif /* BCM_TSN_SUPPORT */