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

ptp_init.c (45334B)


      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  * File:    ptp_init.c
      8  *
      9  * Purpose: 
     10  *
     11  * Functions:
     12  *      bcm_common_ptp_detach
     13  *      bcm_common_ptp_lock
     14  *      bcm_common_ptp_unlock
     15  *      bcm_common_ptp_init
     16  *      bcm_common_ptp_stack_create
     17  *      bcm_common_ptp_time_format_set
     18  *      bcm_common_ptp_cb_register
     19  *      bcm_common_ptp_cb_unregister
     20  *
     21  *      _bcm_ptp_clock_cache_init
     22  *      _bcm_ptp_clock_cache_detach
     23  *      _bcm_ptp_clock_cache_stack_create
     24  *      _bcm_ptp_clock_cache_info_create
     25  *      _bcm_ptp_clock_cache_info_get
     26  *      _bcm_ptp_clock_cache_info_set
     27  *      _bcm_ptp_clock_cache_signal_get
     28  *      _bcm_ptp_clock_cache_signal_set
     29  *      _bcm_ptp_clock_cache_tod_input_get
     30  *      _bcm_ptp_clock_cache_tod_input_set
     31  *      _bcm_ptp_clock_cache_tod_output_get
     32  *      _bcm_ptp_clock_cache_tod_output_set
     33  */
     34 
     35 #if defined(INCLUDE_PTP)
     36 
     37 #include <soc/defs.h>
     38 #include <soc/drv.h>
     39 #include <sal/core/dpc.h>
     40 #include <shared/bsl.h>
     41 
     42 #if defined(BCM_CMICM_SUPPORT)
     43 #include <soc/uc.h>
     44 #endif
     45 
     46 #include <bcm/ptp.h>
     47 #include <bcm_int/common/ptp.h>
     48 #include <bcm_int/ptp_common.h>
     49 #include <bcm/error.h>
     50 
     51 #include <soc/uc_msg.h>
     52 
     53 
     54 
     55 static int next_stack_id[BCM_MAX_NUM_UNITS] = {0};  /* per-unit ID of next stack */
     56 _bcm_ptp_unit_cache_t _bcm_common_ptp_unit_array[BCM_MAX_NUM_UNITS] = {{0}};
     57 _bcm_ptp_info_t _bcm_common_ptp_info[BCM_MAX_NUM_UNITS];
     58 
     59 /*
     60  * Function:
     61  *      bcm_common_ptp_lock
     62  * Purpose:
     63  *      Locks the unit mutex
     64  * Parameters:
     65  *      unit - (IN) Unit number.
     66  * Returns:
     67  *      BCM_E_NONE
     68  *      BCM_E_INIT
     69  * Notes:
     70  */
     71 int bcm_common_ptp_lock(int unit)
     72 {
     73     if (_bcm_common_ptp_info[unit].mutex == NULL) {
     74         return BCM_E_INIT;
     75     }
     76 
     77     return _bcm_ptp_mutex_take(_bcm_common_ptp_info[unit].mutex, 100);
     78 }
     79 
     80 /*
     81  * Function:
     82  *      bcm_common_ptp_unlock
     83  * Purpose:
     84  *      Unlocks the unit mutex
     85  * Parameters:
     86  *      unit - (IN) Unit number.
     87  * Returns:
     88  *      BCM_E_NONE
     89  *      BCM_E_INTERNAL
     90  * Notes:
     91  */
     92 int bcm_common_ptp_unlock(int unit)
     93 {
     94     if (_bcm_ptp_mutex_give(_bcm_common_ptp_info[unit].mutex) != 0) {
     95         return BCM_E_INTERNAL;
     96     }
     97 
     98     return BCM_E_NONE;
     99 }
    100 
    101 /*
    102  * Function:
    103  *      bcm_common_ptp_init
    104  * Purpose:
    105  *      Initialize the PTP subsystem
    106  * Parameters:
    107  *      unit - (IN) Unit number.
    108  * Returns:
    109  *      BCM_E_XXX
    110  * Notes:
    111  */
    112 int
    113 bcm_common_ptp_init(
    114     int unit)
    115 {
    116     int rv = BCM_E_NONE;
    117 
    118     if (soc_feature(unit, soc_feature_ptp)) {
    119         if (_bcm_common_ptp_info[unit].mutex == NULL) {
    120             _bcm_common_ptp_info[unit].mutex = _bcm_ptp_mutex_create("ptp.mutex");
    121             if (_bcm_common_ptp_info[unit].mutex == NULL) {
    122                 rv = BCM_E_MEMORY;
    123             }
    124         }
    125 
    126         if (_bcm_common_ptp_info[unit].stack_info == NULL){
    127             _bcm_common_ptp_info[unit].stack_info = soc_cm_salloc(unit,
    128                 sizeof(_bcm_ptp_stack_info_t)*PTP_MAX_STACKS_PER_UNIT, "ptp_stack_info");
    129             sal_memset(_bcm_common_ptp_info[unit].stack_info, 0,
    130                 sizeof(_bcm_ptp_stack_info_t)*PTP_MAX_STACKS_PER_UNIT);
    131         }
    132 
    133         _bcm_common_ptp_info[unit].memstate = PTP_MEMSTATE_INITIALIZED;
    134 
    135         if (BCM_FAILURE(rv = _bcm_ptp_rx_init(unit))) {
    136             PTP_ERROR_FUNC("_bcm_ptp_rx_init()");
    137             return rv;
    138         }
    139 
    140         if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_init(unit))) {
    141             PTP_ERROR_FUNC("_bcm_ptp_clock_cache_init()");
    142             return rv;
    143         }
    144 
    145         if (BCM_FAILURE(rv = _bcm_ptp_management_init(unit))) {
    146             PTP_ERROR_FUNC("_bcm_ptp_management_init()");
    147             return rv;
    148         }
    149 
    150         if (BCM_FAILURE(rv = _bcm_ptp_unicast_master_table_init(unit))) {
    151             PTP_ERROR_FUNC("_bcm_ptp_unicast_master_table_init()");
    152             return rv;
    153         }
    154 
    155         if (BCM_FAILURE(rv = _bcm_ptp_unicast_slave_table_init(unit))) {
    156             PTP_ERROR_FUNC("_bcm_ptp_unicast_slave_table_init()");
    157             return rv;
    158         }
    159 
    160         if (BCM_FAILURE(rv = _bcm_ptp_acceptable_master_table_init(unit))) {
    161             PTP_ERROR_FUNC("_bcm_ptp_acceptable_master_table_init()");
    162             return rv;
    163         }
    164     }
    165 
    166     return BCM_E_NONE;
    167 }
    168 
    169 /*
    170  * Function:
    171  *      bcm_common_ptp_detach
    172  * Purpose:
    173  *      Shut down the PTP subsystem
    174  * Parameters:
    175  *      unit - (IN) Unit number.
    176  * Returns:
    177  *      BCM_E_XXX
    178  * Notes:
    179  */
    180 int 
    181 bcm_common_ptp_detach(
    182     int unit)
    183 {
    184     int i;
    185     int rv = BCM_E_NONE;
    186     
    187 
    188     if (soc_feature(unit, soc_feature_ptp)) {
    189         for (i = 0; i < PTP_MAX_STACKS_PER_UNIT; ++i) {
    190             if (_bcm_common_ptp_info[unit].stack_info[i].in_use) {
    191                 if (BCM_FAILURE(rv = bcm_common_ptp_stack_destroy(unit, i))) {
    192                     PTP_ERROR_FUNC("bcm_common_ptp_stack_destroy()");
    193                 }
    194             }
    195         }
    196 
    197         if (BCM_FAILURE(rv = _bcm_ptp_rx_detach(unit))) {
    198             PTP_ERROR_FUNC("_bcm_ptp_rx_detach()");
    199         }
    200 
    201         if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_detach(unit))) {
    202             PTP_ERROR_FUNC("_bcm_ptp_clock_cache_detach()");
    203         }
    204 
    205         if (BCM_FAILURE(rv = _bcm_ptp_management_detach(unit))) {
    206             PTP_ERROR_FUNC("_bcm_ptp_management_detach()");
    207         }
    208 
    209         if (BCM_FAILURE(rv = _bcm_ptp_unicast_master_table_detach(unit))) {
    210             PTP_ERROR_FUNC("_bcm_ptp_unicast_master_table_detach()");
    211         }
    212 
    213         if (BCM_FAILURE(rv = _bcm_ptp_unicast_slave_table_detach(unit))) {
    214             PTP_ERROR_FUNC("_bcm_ptp_unicast_slave_table_detach()");
    215         }
    216 
    217         if (BCM_FAILURE(rv = _bcm_ptp_acceptable_master_table_detach(unit))) {
    218             PTP_ERROR_FUNC("_bcm_ptp_acceptable_master_table_detach()");
    219         }
    220     
    221         if (_bcm_common_ptp_info[unit].stack_info != NULL){ 
    222             soc_cm_sfree(unit, _bcm_common_ptp_info[unit].stack_info);
    223             _bcm_common_ptp_info[unit].stack_info = NULL;
    224         }
    225 
    226         if (_bcm_common_ptp_info[unit].mutex != NULL) {
    227             _bcm_ptp_mutex_destroy(_bcm_common_ptp_info[unit].mutex);
    228             _bcm_common_ptp_info[unit].mutex = NULL;
    229         }
    230 
    231     }
    232 
    233     return BCM_E_NONE;
    234 }
    235 
    236 #if defined(BCM_CMICM_SUPPORT) && defined(BCM_PTP_INTERNAL_STACK_SUPPORT)
    237 /*
    238  * Function:
    239  *     _bcm_ptp_ts0_ts1_combined_mode_config_send
    240  * Purpose:
    241  *     Functioin to send ts0 ts1 combined mode enable flag
    242  * Parameters:
    243  *      unit - (IN) Unit number.
    244  * Returns:
    245  *      BCM_E_xxx
    246  * Notes:
    247  */
    248 int
    249 _bcm_ptp_ts0_ts1_combined_mode_config_send(
    250     int unit,
    251     int ts0_ts1_combined_mode_en, int uC)
    252 {
    253    mos_msg_data_t start_msg;
    254    int rc;
    255    int timeout_usec=1900000;
    256 
    257    start_msg.s.mclass = MOS_MSG_CLASS_1588;
    258    start_msg.s.subclass = MOS_MSG_SUBCLASS_TS0_TS1_COMBINED_MODE_EN;
    259    start_msg.s.len = 0;
    260    start_msg.s.data = bcm_htonl(ts0_ts1_combined_mode_en);
    261 
    262    rc = soc_cmic_uc_msg_send(unit, uC, &start_msg, timeout_usec);
    263    if (BCM_FAILURE(rc)) {
    264         LOG_WARN(BSL_LS_BCM_PTP, (BSL_META_U(unit,
    265            "Error is sending ptp profile configuration\n")
    266            ));
    267         rc = BCM_E_FAIL;
    268    }
    269    return (rc);
    270 }
    271 #endif
    272 
    273 /*
    274  * Function:
    275  *      bcm_common_ptp_stack_create
    276  * Purpose:
    277  *      Create a PTP stack instance
    278  * Parameters:
    279  *      unit - (IN) Unit number.
    280  *      ptp_info - (IN/OUT) Pointer to an PTP Stack Info structure
    281  * Returns:
    282  *      BCM_E_xxx
    283  * Notes:
    284  */
    285 int 
    286 bcm_common_ptp_stack_create(
    287     int unit,
    288     bcm_ptp_stack_info_t *info)
    289 {
    290     int rv = BCM_E_NONE;
    291     _bcm_ptp_stack_info_t *stack_p;
    292     _bcm_ptp_info_t *ptp_info_p;
    293     pbmp_t pbmp = {{0x03008000}};
    294 
    295     SET_PTP_INFO;
    296     if (soc_feature(unit, soc_feature_ptp)) {
    297         rv = bcm_common_ptp_lock(unit);
    298         if (BCM_FAILURE(rv)) {
    299            return rv;
    300         }
    301 
    302         if ((info->flags & BCM_PTP_STACK_WITH_ID) == 0) {
    303             info->id = (bcm_ptp_stack_id_t) next_stack_id[unit]++;
    304         }
    305 
    306         if (info->id >= PTP_MAX_STACKS_PER_UNIT) {
    307             /* Zero-based stack ID exceeds max. */
    308             rv = BCM_E_PARAM;
    309             goto done;
    310         }
    311 
    312         /* Check if stack is in use. */
    313         stack_p = &ptp_info_p->stack_info[info->id];
    314         if (stack_p->in_use) {
    315             rv = BCM_E_EXISTS;
    316             goto done;
    317         }
    318 
    319         stack_p->stack_id = info->id;
    320         stack_p->unit = unit;
    321         stack_p->in_use = 1;
    322         stack_p->flags = info->flags;
    323 
    324         stack_p->unicast_master_table_size = PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES;
    325         stack_p->acceptable_master_table_size = PTP_MAX_ACCEPTABLE_MASTER_TABLE_ENTRIES;
    326         stack_p->unicast_slave_table_size = PTP_MAX_UNICAST_SLAVE_TABLE_ENTRIES;
    327         stack_p->multicast_slave_stats_size = PTP_MAX_MULTICAST_SLAVE_STATS_ENTRIES;
    328 
    329         /* Check if the stack supports Keystone */
    330         if (info->flags & BCM_PTP_STACK_EXTERNAL_TOP) {
    331 #if defined(BCM_PTP_EXTERNAL_STACK_SUPPORT)
    332             if (BCM_FAILURE(rv = _bcm_ptp_external_stack_create(unit, info, stack_p->stack_id))) {
    333                 PTP_ERROR_FUNC("_bcm_ptp_external_stack_create()");
    334                 goto done;
    335             }
    336             stack_p->memstate = PTP_MEMSTATE_INITIALIZED;
    337 #else
    338             rv = BCM_E_PARAM;
    339             goto done;
    340 #endif
    341         } else {
    342 #if defined(BCM_PTP_INTERNAL_STACK_SUPPORT)
    343 
    344             if (BCM_FAILURE(rv = _bcm_ptp_internal_stack_create(unit, info, stack_p->stack_id))) {
    345                 stack_p->in_use = 0;
    346                 next_stack_id[unit]--;
    347                 goto done;
    348             }
    349             stack_p->memstate = PTP_MEMSTATE_INITIALIZED;
    350 #else
    351             LOG_WARN(BSL_LS_BCM_PTP, (BSL_META_U(unit,
    352                "Neither PTP internal nor external stack support is enabled\n")
    353                ));
    354             rv = BCM_E_UNAVAIL;
    355             goto done;
    356 #endif
    357         }
    358         if (stack_p->memstate != PTP_MEMSTATE_INITIALIZED) {
    359             LOG_WARN(BSL_LS_BCM_PTP, (BSL_META_U(unit,
    360                      "Found no supported PTP platforms\n\n")));
    361 
    362             rv = BCM_E_FAIL;
    363             goto done;
    364         }
    365 
    366 #if defined(BCM_CMICM_SUPPORT) && defined(BCM_PTP_INTERNAL_STACK_SUPPORT)
    367         if (BCM_FAILURE(rv = _bcm_ptp_ts0_ts1_combined_mode_config_send(unit,
    368             (stack_p->flags & BCM_PTP_STACK_TIMESTAMPER_COMBINED_MODE), stack_p->int_state.core_num))) {
    369             rv = BCM_E_FAIL;
    370             goto done;
    371         }
    372 #endif
    373 
    374         if (BCM_FAILURE(rv = _bcm_ptp_rx_stack_create(                  /* call with blank MACs for Katana */
    375                 unit, stack_p->stack_id, &stack_p->ext_info.host_mac,
    376                 &stack_p->ext_info.top_mac, stack_p->ext_info.tpid,
    377                 stack_p->ext_info.vlan))) {
    378             PTP_ERROR_FUNC("_bcm_ptp_rx_stack_create()");
    379             goto done;
    380         }
    381 
    382         if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_stack_create(
    383             unit,stack_p->stack_id))) {
    384             PTP_ERROR_FUNC("_bcm_ptp_clock_cache_stack_create()");
    385             goto done;
    386         }
    387 
    388         if (BCM_FAILURE(rv = _bcm_ptp_management_stack_create(
    389                 unit, stack_p->stack_id, &stack_p->ext_info.host_mac, 
    390                 &stack_p->ext_info.top_mac, stack_p->ext_info.host_ip_addr, 
    391                 stack_p->ext_info.top_ip_addr, stack_p->ext_info.vlan, 
    392                 stack_p->ext_info.vlan_pri, pbmp))) {
    393             PTP_ERROR_FUNC("_bcm_ptp_management_stack_create()");
    394             goto done;
    395         }
    396 
    397         if (BCM_FAILURE(rv = _bcm_ptp_unicast_master_table_stack_create(
    398                unit, stack_p->stack_id))) {
    399             PTP_ERROR_FUNC("_bcm_ptp_unicast_master_table_stack_create()");
    400             goto done;
    401         }
    402 
    403         if (BCM_FAILURE(rv = _bcm_ptp_unicast_slave_table_stack_create(
    404                 unit, stack_p->stack_id))) {
    405             PTP_ERROR_FUNC("_bcm_ptp_unicast_slave_table_stack_create()");
    406             goto done;
    407         }
    408 
    409         if (BCM_FAILURE(rv = _bcm_ptp_acceptable_master_table_stack_create(
    410                 unit, stack_p->stack_id))) {
    411             PTP_ERROR_FUNC("_bcm_ptp_acceptable_master_table_stack_create()");
    412             goto done;
    413         }
    414 
    415         if (BCM_FAILURE(rv = _bcm_ptp_tunnel_queue_init(
    416                 unit, stack_p->stack_id))) {
    417             PTP_ERROR_FUNC("_bcm_ptp_tunnel_queue_init()");
    418             goto done;
    419         }
    420 
    421         if (BCM_FAILURE(rv = _bcm_ptp_timestamp_queue_init(
    422                 unit, stack_p->stack_id))) {
    423             PTP_ERROR_FUNC("_bcm_ptp_timestamp_queue_init()");
    424             goto done;
    425         }
    426 
    427         if (BCM_FAILURE(rv = _bcm_ptp_signaling_init(
    428                 unit, stack_p->stack_id))) {
    429             PTP_ERROR_FUNC("_bcm_ptp_unicast_signaling_init()");
    430             goto done;
    431         }
    432 
    433         if (BCM_FAILURE(rv = bcm_common_ptp_telecom_g8265_init(
    434                 unit, stack_p->stack_id, PTP_CLOCK_NUMBER_DEFAULT))) {
    435             PTP_ERROR_FUNC("bcm_common_ptp_telecom_g8265_init()");
    436             goto done;
    437         }
    438 
    439         if (BCM_FAILURE(rv = _bcm_ptp_ctdev_init(unit, stack_p->stack_id,
    440                 PTP_CLOCK_NUMBER_DEFAULT, 0))) {
    441             PTP_ERROR_FUNC("_bcm_ptp_ctdev_init()");
    442             goto done;
    443         }
    444 
    445         /* T-DPLL support. */
    446         if (BCM_FAILURE(rv = bcm_tdpll_dpll_instance_init(unit, stack_p->stack_id))) {
    447             PTP_ERROR_FUNC("bcm_tdpll_dpll_instance_init()");
    448             goto done;
    449         }
    450 
    451         if (BCM_FAILURE(rv = bcm_tdpll_input_clock_init(unit, stack_p->stack_id))) {
    452             PTP_ERROR_FUNC("bcm_tdpll_input_clock_init()");
    453             goto done;
    454         }
    455 
    456         if (BCM_FAILURE(rv = bcm_tdpll_output_clock_init(unit, stack_p->stack_id))) {
    457             PTP_ERROR_FUNC("bcm_tdpll_output_clock_init()");
    458             goto done;
    459         }
    460 
    461         if (BCM_FAILURE(rv = bcm_esmc_init(unit, stack_p->stack_id))) {
    462             PTP_ERROR_FUNC("bcm_esmc_init()");
    463             goto done;
    464         }
    465 
    466         if (BCM_FAILURE(rv = bcm_tdpll_esmc_init(unit, stack_p->stack_id))) {
    467             PTP_ERROR_FUNC("bcm_tdpll_esmc_init()");
    468             goto done;
    469         }
    470 
    471 done:
    472         BCM_IF_ERROR_RETURN(bcm_common_ptp_unlock(unit));
    473         if (rv == BCM_E_NONE) {
    474             LOG_VERBOSE(BSL_LS_BCM_PTP, (BSL_META_U(unit,
    475                         "PTP stack created\n")));
    476         }
    477     } else {
    478         rv = BCM_E_UNAVAIL;
    479         LOG_WARN(BSL_LS_BCM_PTP, (BSL_META_U(unit,
    480                  "PTP not supported on this unit\n")));
    481     }
    482 
    483     return rv;
    484 }
    485 
    486 /* bcm_ptp_stack_destroy: halts firmware (for internal stack) and undoes creation */
    487 int bcm_common_ptp_stack_destroy(int unit, bcm_ptp_stack_id_t ptp_id)
    488 {
    489     int rv;
    490 
    491     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 0, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    492         PTP_ERROR_FUNC("PTP on unit not initialized.");
    493         return BCM_E_INIT;
    494     }
    495 
    496     BCM_IF_ERROR_RETURN(_bcm_ptp_stack_shutdown(unit, ptp_id));
    497 
    498     /* Halt the firmware if it is an internal stack */
    499 #if defined(BCM_CMICM_SUPPORT) && defined(BCM_PTP_INTERNAL_STACK_SUPPORT)
    500     if (SOC_HAS_PTP_INTERNAL_STACK_SUPPORT(unit)) {
    501         _bcm_ptp_stack_info_t *stack_p = &_bcm_common_ptp_info[unit].stack_info[ptp_id];
    502 
    503         if ((stack_p->flags & BCM_PTP_STACK_EXTERNAL_TOP) == 0 && stack_p->in_use) {
    504             /* Stop the uc messaging before uc reset */
    505             soc_cmic_uc_msg_uc_stop(unit, stack_p->int_state.core_num);
    506 
    507             /* halt core running PTP: */
    508             soc_uc_reset(unit, stack_p->int_state.core_num);
    509         }
    510     }
    511 #endif
    512     BCM_IF_ERROR_RETURN(_bcm_ptp_stack_cleanup(unit, ptp_id));
    513 
    514     return BCM_E_NONE;
    515 }
    516 
    517 #if defined(BCM_PTP_INTERNAL_STACK_SUPPORT)
    518 /* Callback from MCS messaging layer: called before and after uC shutdown */
    519 int _bcm_ptp_stack_deinit_callback(int unit,
    520                                    int uC,
    521                                    soc_cmic_uc_shutdown_stage_t stage,
    522                                    void *user_data)
    523 {
    524     int ptp_id = PTR_TO_INT(user_data);
    525 
    526     LOG_VERBOSE(BSL_LS_BCM_PTP, (BSL_META_U(unit,
    527                 "PTP stack deinit callback:  Unit: %d, ID: %d, stage: %d\n"),
    528                 unit, ptp_id, (int)stage));
    529 
    530     switch (stage) {
    531     case SOC_CMIC_UC_SHUTDOWN_STARTING:
    532         /* Shut down threads */
    533         _bcm_ptp_stack_shutdown(unit, ptp_id);
    534         break;
    535     case SOC_CMIC_UC_SHUTDOWN_HALTED:
    536         /* Deallocate shared mem now that uC is halted */
    537         _bcm_ptp_stack_cleanup(unit, ptp_id);
    538         break;
    539     default:
    540         break;
    541     }
    542 
    543     return BCM_E_NONE;
    544 }
    545 #endif /* BCM_PTP_INTERNAL_STACK_SUPPORT */
    546 
    547 int _bcm_ptp_stack_shutdown(int unit, bcm_ptp_stack_id_t ptp_id)
    548 {
    549     int rv = BCM_E_FAIL;
    550     _bcm_ptp_stack_info_t *stack_p;
    551 
    552     rv = bcm_common_ptp_lock(unit);
    553     if (BCM_FAILURE(rv)) {
    554         return rv;
    555     }
    556 
    557     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 0, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    558         PTP_ERROR_FUNC("PTP on unit not initialized.");
    559         goto done;
    560     }
    561 
    562     stack_p = &_bcm_common_ptp_info[unit].stack_info[ptp_id];
    563     if (!stack_p->in_use || stack_p->memstate != PTP_MEMSTATE_INITIALIZED) {
    564         PTP_ERROR_FUNC("PTP stack not in use.");
    565         goto done;
    566     }
    567 
    568     stack_p->memstate = PTP_MEMSTATE_HALTING;
    569 
    570     if (BCM_FAILURE(rv = _bcm_ptp_tunnel_queue_cleanup(unit, ptp_id))) {
    571         PTP_ERROR_FUNC("_bcm_ptp_tunnel_queue_cleanup()");
    572         goto done;
    573     }
    574 
    575     if (BCM_FAILURE(rv = _bcm_ptp_timestamp_queue_cleanup(unit, ptp_id))) {
    576         PTP_ERROR_FUNC("_bcm_ptp_timestamp_queue_cleanup()");
    577         goto done;
    578     }
    579 
    580 #ifdef BCM_PTP_EXT_SERVO_SUPPORT
    581     if (BCM_FAILURE(rv = _bcm_ptp_servo_deinit(unit, ptp_id, PTP_CLOCK_NUMBER_DEFAULT))) {
    582         PTP_ERROR_FUNC("_bcm_ptp_timestamp_queue_cleanup()");
    583         goto done;
    584     }
    585 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */
    586 
    587     if (BCM_FAILURE(rv = _bcm_ptp_signaling_cleanup(unit, ptp_id))) {
    588         PTP_ERROR_FUNC("_bcm_ptp_signaling_cleanup()");
    589         goto done;
    590     }
    591 
    592     if (BCM_FAILURE(rv = _bcm_ptp_acceptable_master_table_stack_destroy(unit, ptp_id))) {
    593         PTP_ERROR_FUNC("_bcm_ptp_acceptable_master_table_stack_destroy()");
    594         goto done;
    595     }
    596 
    597     if (BCM_FAILURE(rv = _bcm_ptp_unicast_slave_table_stack_destroy(unit, ptp_id))) {
    598         PTP_ERROR_FUNC("_bcm_ptp_unicast_slave_table_stack_destroy()");
    599         goto done;
    600     }
    601 
    602     if (BCM_FAILURE(rv = _bcm_ptp_unicast_master_table_stack_destroy(unit, ptp_id))) {
    603         PTP_ERROR_FUNC("_bcm_ptp_unicast_master_table_stack_destroy()");
    604         goto done;
    605     }
    606 
    607     if (BCM_FAILURE(rv = _bcm_ptp_management_stack_destroy(unit, ptp_id))) {
    608         PTP_ERROR_FUNC("_bcm_ptp_management_stack_destroy()");
    609         goto done;
    610     }
    611 
    612     if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_stack_destroy(unit, ptp_id))) {
    613         PTP_ERROR_FUNC("_bcm_ptp_clock_cache_stack_destroy()");
    614         goto done;
    615     }
    616 
    617     if (BCM_FAILURE(rv = _bcm_ptp_rx_stack_destroy(unit, ptp_id))) {
    618         PTP_ERROR_FUNC("_bcm_ptp_rx_stack_destroy()");
    619         goto done;
    620     }
    621 
    622     if (BCM_FAILURE(rv = bcm_tdpll_esmc_cleanup(unit, ptp_id))) {
    623         PTP_ERROR_FUNC("bcm_tdpll_esmc_cleanup()");
    624         goto done;
    625     }
    626 
    627     if (BCM_FAILURE(rv = bcm_esmc_cleanup(unit, ptp_id))) {
    628         PTP_ERROR_FUNC("bcm_esmc_cleanup()");
    629         goto done;
    630     }
    631 
    632     if (BCM_FAILURE(rv = bcm_tdpll_output_clock_cleanup(unit, ptp_id))) {
    633         PTP_ERROR_FUNC("bcm_tdpll_output_clock_cleanup()");
    634         goto done;
    635     }
    636 
    637     if (BCM_FAILURE(rv = bcm_tdpll_input_clock_cleanup(unit))) {
    638         PTP_ERROR_FUNC("bcm_tdpll_input_clock_cleanup()");
    639         goto done;
    640     }
    641 
    642     if (BCM_FAILURE(rv = bcm_tdpll_dpll_instance_cleanup(unit, ptp_id))) {
    643         PTP_ERROR_FUNC("bcm_tdpll_instance_cleanup()");
    644         return rv;
    645     }
    646 
    647     if (BCM_FAILURE(rv = bcm_common_ptp_telecom_g8265_shutdown(unit))) {
    648         PTP_ERROR_FUNC("bcm_common_ptp_telecom_g8265_shutdown()");
    649         return rv;
    650     }
    651 
    652  done:
    653     BCM_IF_ERROR_RETURN(bcm_common_ptp_unlock(unit));
    654     if (rv == BCM_E_NONE) {
    655         LOG_VERBOSE(BSL_LS_BCM_PTP, (BSL_META_U(unit,
    656                     "PTP stack destroyed\n")));
    657     }
    658 
    659     return BCM_E_NONE;
    660 }
    661 
    662 
    663 /* _bcm_ptp_stack_cleanup:
    664    Cleans up after the remote-running stack has been terminated
    665 */
    666 int _bcm_ptp_stack_cleanup(int unit, bcm_ptp_stack_id_t ptp_id)
    667 {
    668     int rv = BCM_E_FAIL;
    669     _bcm_ptp_stack_info_t *stack_p;
    670 
    671     rv = bcm_common_ptp_lock(unit);
    672     if (BCM_FAILURE(rv)) {
    673         return rv;
    674     }
    675 
    676     if (_bcm_common_ptp_info[unit].memstate != PTP_MEMSTATE_INITIALIZED) {
    677         rv = BCM_E_INIT;
    678         goto done;
    679     }
    680 
    681     stack_p = &_bcm_common_ptp_info[unit].stack_info[ptp_id];
    682 
    683     if (stack_p->memstate != PTP_MEMSTATE_HALTING) {
    684         rv = BCM_E_FAIL;
    685         goto done;
    686     }
    687 
    688 #if defined(BCM_PTP_INTERNAL_STACK_SUPPORT)
    689     if ((stack_p->flags & BCM_PTP_STACK_EXTERNAL_TOP) == 0) {
    690         _bcm_ptp_internal_stack_cleanup(unit, ptp_id);
    691     }
    692 #endif /* BCM_PTP_INTERNAL_STACK_SUPPORT */
    693 
    694     /* only supporting a single stack per unit currently, so just reset */
    695     stack_p->in_use = 0;
    696     next_stack_id[unit] = 0;
    697     stack_p->memstate = PTP_MEMSTATE_STARTUP;
    698 
    699  done:
    700     BCM_IF_ERROR_RETURN(bcm_common_ptp_unlock(unit));
    701     return rv;
    702 }
    703 
    704 
    705 /* _bcm_ptp_running:
    706  *   Returns: BCM_E_NONE if PTP is running on the unit
    707  */
    708 int _bcm_ptp_running(int unit)
    709 {
    710     int ptp_id = 0;     /* Checks stack 0 on unit */
    711     _bcm_ptp_stack_info_t *stack_p = &_bcm_common_ptp_info[unit].stack_info[ptp_id];
    712 
    713     if (BCM_FAILURE(_bcm_ptp_function_precheck(unit, ptp_id, 0, 
    714                     PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    715         return BCM_E_UNAVAIL;
    716     }
    717         
    718     if (!stack_p->in_use || stack_p->memstate != PTP_MEMSTATE_INITIALIZED) {
    719          return BCM_E_UNAVAIL;
    720     }
    721         
    722     return BCM_E_NONE;
    723 }
    724 /*
    725  * Function:
    726  *      bcm_common_ptp_stack_get
    727  * Purpose:
    728  *      Get a PTP stack instance
    729  * Parameters:
    730  *      unit - Unit number
    731  *      ptp_id - ID of stack to get
    732  *      ptp_info - info structs for stack
    733  * Returns:
    734  *      int
    735  * Notes:
    736  */
    737 int
    738 bcm_common_ptp_stack_get(
    739     int unit,
    740     bcm_ptp_stack_id_t ptp_id,
    741     bcm_ptp_stack_info_t *ptp_info)
    742 {
    743     _bcm_ptp_stack_info_t *stack_p;
    744 
    745     if (!ptp_info || ptp_id >= PTP_MAX_STACKS_PER_UNIT) {
    746         return BCM_E_PARAM;
    747     }
    748     stack_p = &_bcm_common_ptp_info[unit].stack_info[ptp_id];
    749 
    750     if (!stack_p->in_use) {
    751         return BCM_E_INIT;
    752     }
    753 
    754     ptp_info->id = ptp_id;
    755     ptp_info->flags = stack_p->flags;
    756 
    757 #if defined(BCM_PTP_INTERNAL_STACK_SUPPORT)
    758     if (SOC_HAS_PTP_EXTERNAL_STACK_SUPPORT(unit)) {
    759         if (stack_p->flags & BCM_PTP_STACK_EXTERNAL_TOP) {
    760             ptp_info->ext_stack_info = &stack_p->ext_info;
    761         }
    762     }
    763 #endif /* BCM_PTP_INTERNAL_STACK_SUPPORT */
    764 
    765     return BCM_E_NONE;
    766 }
    767 
    768 /*
    769  * Function:
    770  *      bcm_common_ptp_stack_get_all
    771  * Purpose:
    772  *      Gets all PTP stack instances
    773  * Parameters:
    774  *      unit - Unit number
    775  *      max_size - maximum number of stacks to return
    776  *      ptp_info - info structs for stacks
    777  *      no_of_stacks - actual number of stacks that can be returned
    778  * Returns:
    779  *      int
    780  * Notes:
    781  */
    782 int
    783 bcm_common_ptp_stack_get_all(
    784     int unit,
    785     int max_size, 
    786     bcm_ptp_stack_info_t *ptp_info,
    787     int *no_of_stacks)
    788 {
    789     int i;
    790 
    791     *no_of_stacks = next_stack_id[unit] = 0;
    792     for (i = 0; i < max_size && i < *no_of_stacks; ++i) {
    793         BCM_IF_ERROR_RETURN(bcm_common_ptp_stack_get(unit, i, &ptp_info[i]));
    794     }
    795 
    796     return BCM_E_NONE;
    797 }
    798 
    799         
    800 /*
    801  * Function:
    802  *      bcm_common_ptp_time_format_set
    803  * Purpose:
    804  *      Set Time Of Day format for PTP stack instance.
    805  * Parameters:
    806  *      unit - (IN) Unit number.
    807  *      ptp_info - (IN) PTP Stack ID
    808  *      format - (IN) Time of Day format
    809  * Returns:
    810  *      BCM_E_xxx
    811  * Notes:
    812  */
    813 int 
    814 bcm_common_ptp_time_format_set(
    815     int unit, 
    816     bcm_ptp_stack_id_t ptp_id, 
    817     bcm_ptp_time_type_t type)
    818 {
    819     return BCM_E_UNAVAIL;
    820 }
    821 
    822 /*
    823  * Function:
    824  *      bcm_common_ptp_cb_register
    825  * Purpose:
    826  *      Register a callback for handling PTP events
    827  * Parameters:
    828  *      unit - (IN) Unit number.
    829  *      cb_types - (IN) The set of PTP callbacks types for which the specified callback should be called
    830  *      cb - (IN) A pointer to the callback function to call for the specified PTP events
    831  *      user_data - (IN) Pointer to user data to supply in the callback
    832  * Returns:
    833  *      BCM_E_xxx
    834  * Notes:
    835  */
    836 int 
    837 bcm_common_ptp_cb_register(
    838     int unit, 
    839     bcm_ptp_cb_types_t cb_types, 
    840     bcm_ptp_cb cb, 
    841     void *user_data)
    842 {
    843     int rv = BCM_E_UNAVAIL;
    844 
    845     if (soc_feature(unit, soc_feature_ptp)) {
    846         rv = bcm_common_ptp_lock(unit);
    847         if (BCM_FAILURE(rv)) {
    848            return rv;
    849         }
    850 
    851         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeManagement)) {
    852             rv = _bcm_ptp_register_management_callback(unit, cb, user_data);
    853         }
    854 
    855         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeEvent)) {
    856             rv = _bcm_ptp_register_event_callback(unit, cb, user_data);
    857         }
    858 
    859         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeFault)) {
    860             rv = _bcm_ptp_register_fault_callback(unit, cb, user_data);
    861         }
    862 
    863         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeSignal)) {
    864             rv = _bcm_ptp_register_signal_callback(unit, cb, user_data);
    865         }
    866 
    867         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeCheckPeers)) {
    868             rv = _bcm_ptp_register_peers_callback(unit, cb, user_data);
    869         }
    870 
    871         BCM_IF_ERROR_RETURN(bcm_common_ptp_unlock(unit));
    872     }
    873 
    874     return rv;
    875 }
    876 
    877 /*
    878  * Function:
    879  *      bcm_common_ptp_cb_unregister
    880  * Purpose:
    881  *      Unregister a callback for handling PTP events
    882  * Parameters:
    883  *      unit - (IN) Unit number.
    884  *      event_types - (IN) The set of PTP events to unregister for the specified callback
    885  *      cb - (IN) A pointer to the callback function to unregister from the specified PTP events
    886  * Returns:
    887  *      BCM_E_xxx
    888  * Notes:
    889  */
    890 int 
    891 bcm_common_ptp_cb_unregister(
    892     int unit, 
    893     bcm_ptp_cb_types_t cb_types, 
    894     bcm_ptp_cb cb)
    895 {
    896     int rv = BCM_E_UNAVAIL;
    897 
    898     if (soc_feature(unit, soc_feature_ptp)) {
    899         rv = bcm_common_ptp_lock(unit);
    900         if (BCM_FAILURE(rv)) {
    901            return rv;
    902         }
    903 
    904         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeManagement)) {
    905             rv = _bcm_ptp_unregister_management_callback(unit);
    906         }
    907 
    908         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeEvent)) {
    909             rv = _bcm_ptp_unregister_event_callback(unit);
    910         }
    911 
    912         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeFault)) {
    913             rv = _bcm_ptp_unregister_fault_callback(unit);
    914         }
    915 
    916         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeSignal)) {
    917             rv = _bcm_ptp_unregister_signal_callback(unit);
    918         }
    919 
    920         if (SHR_BITGET(cb_types.w, bcmPTPCallbackTypeCheckPeers)) {
    921             rv = _bcm_ptp_unregister_peers_callback(unit);
    922         }
    923 
    924         BCM_IF_ERROR_RETURN(bcm_common_ptp_unlock(unit));
    925     }
    926 
    927     return rv;
    928 }
    929 
    930 /*
    931  * Function:
    932  *      _bcm_ptp_clock_cache_init
    933  * Purpose:
    934  *      Initialize the PTP clock information caches a unit.
    935  * Parameters:
    936  *      unit - (IN) Unit number.
    937  * Returns:
    938  *      BCM_E_XXX
    939  * Notes:
    940  */
    941 int 
    942 _bcm_ptp_clock_cache_init(
    943     int unit)
    944 {
    945     int rv = BCM_E_UNAVAIL;
    946     
    947     _bcm_ptp_stack_cache_t *stack_p;
    948     
    949     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, PTP_STACK_ID_DEFAULT,
    950             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    951         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");  
    952         return rv;
    953     }
    954         
    955     
    956     if (NULL == _bcm_common_ptp_unit_array[unit].stack_array) {
    957         stack_p = sal_alloc(PTP_MAX_STACKS_PER_UNIT*
    958                             sizeof(_bcm_ptp_stack_cache_t),"Unit PTP Clock Information Caches");
    959     } else {
    960         stack_p = _bcm_common_ptp_unit_array[unit].stack_array;
    961     }
    962     
    963     if (!stack_p) {
    964         _bcm_common_ptp_unit_array[unit].memstate = PTP_MEMSTATE_FAILURE;
    965         return BCM_E_MEMORY;
    966     }
    967 
    968     memset(stack_p, 0x00, sizeof (_bcm_ptp_stack_cache_t));
    969 
    970     _bcm_common_ptp_unit_array[unit].stack_array = stack_p;
    971     _bcm_common_ptp_unit_array[unit].memstate = PTP_MEMSTATE_INITIALIZED;
    972     
    973     return rv;
    974 }
    975 
    976 /*
    977  * Function:
    978  *      _bcm_ptp_clock_cache_detach
    979  * Purpose:
    980  *      Shut down the PTP clock information caches a unit.
    981  * Parameters:
    982  *      unit - (IN) Unit number.
    983  * Returns:
    984  *      BCM_E_XXX
    985  * Notes:
    986  */
    987 int 
    988 _bcm_ptp_clock_cache_detach(
    989     int unit)
    990 {
    991     if(_bcm_common_ptp_unit_array[unit].stack_array) {
    992         _bcm_common_ptp_unit_array[unit].memstate = PTP_MEMSTATE_STARTUP;
    993         sal_free(_bcm_common_ptp_unit_array[unit].stack_array);
    994         _bcm_common_ptp_unit_array[unit].stack_array = NULL;
    995     }
    996     return BCM_E_NONE;
    997 }
    998 
    999 /*
   1000  * Function:
   1001  *      _bcm_ptp_clock_cache_stack_create
   1002  * Purpose:
   1003  *      Create the PTP clock information caches of a PTP stack.
   1004  * Parameters:
   1005  *      unit    - (IN) Unit number.
   1006  *      ptp_id  - (IN) PTP stack ID.
   1007  * Returns:
   1008  *      BCM_E_XXX
   1009  * Notes:
   1010  */
   1011 int 
   1012 _bcm_ptp_clock_cache_stack_create(
   1013     int unit, 
   1014     bcm_ptp_stack_id_t ptp_id)
   1015 {
   1016     int rv = BCM_E_UNAVAIL;
   1017     int i;
   1018     _bcm_ptp_clock_cache_t *clock_p;
   1019     
   1020     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
   1021             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1022         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");  
   1023         return rv;
   1024     }
   1025         
   1026     if (_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) {
   1027         return BCM_E_UNAVAIL;
   1028     }
   1029 
   1030     
   1031     clock_p = sal_alloc(PTP_MAX_CLOCK_INSTANCES*sizeof(_bcm_ptp_clock_cache_t),
   1032                         "Stack PTP Information Caches");
   1033 
   1034     if (!clock_p) {
   1035         _bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate = 
   1036             PTP_MEMSTATE_FAILURE;
   1037         return BCM_E_MEMORY;
   1038     }
   1039 
   1040     /* Mark the clocks in the newly-created clock array as not-in-use */
   1041     for (i = 0; i < PTP_MAX_CLOCK_INSTANCES; ++i) {
   1042         clock_p[i].in_use = 0;
   1043     }
   1044 
   1045     _bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array = clock_p;
   1046     _bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate = 
   1047         PTP_MEMSTATE_INITIALIZED;
   1048     
   1049     return rv;
   1050 }
   1051 
   1052 /*
   1053  * Function:
   1054  *      _bcm_ptp_clock_cache_stack_destroy
   1055  * Purpose:
   1056  *      Destroy the PTP clock information caches of a PTP stack.
   1057  * Parameters:
   1058  *      unit    - (IN) Unit number.
   1059  *      ptp_id  - (IN) PTP stack ID.
   1060  * Returns:
   1061  *      BCM_E_XXX
   1062  * Notes:
   1063  */
   1064 int
   1065 _bcm_ptp_clock_cache_stack_destroy(
   1066     int unit,
   1067     bcm_ptp_stack_id_t ptp_id)
   1068 {
   1069     int rv;
   1070     int i;
   1071     _bcm_ptp_clock_cache_t *clock_array;
   1072 
   1073     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
   1074             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1075         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
   1076         return rv;
   1077     }
   1078 
   1079     if (_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) {
   1080         return BCM_E_UNAVAIL;
   1081     }
   1082 
   1083     if (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate == PTP_MEMSTATE_INITIALIZED) {
   1084         _bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate = PTP_MEMSTATE_STARTUP;
   1085         clock_array = _bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array;
   1086         for (i = 0; i < PTP_MAX_CLOCK_INSTANCES; ++i) {
   1087             if (clock_array->in_use == 1) {
   1088                 _bcm_ptp_mutex_destroy(clock_array[i].peerTable.lock);
   1089             }
   1090         }
   1091         sal_free(clock_array);
   1092         _bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array = 0;
   1093     }
   1094 
   1095     return BCM_E_NONE;
   1096 }
   1097 
   1098 /*
   1099  * Function:
   1100  *      _bcm_ptp_clock_cache_info_create
   1101  * Purpose:
   1102  *      Create the information cache of a PTP clock.
   1103  * Parameters:
   1104  *      unit      - (IN) Unit number.
   1105  *      ptp_id    - (IN) PTP stack ID.
   1106  *      clock_num - (IN) PTP clock number.
   1107  * Returns:
   1108  *      BCM_E_XXX
   1109  * Notes:
   1110  */
   1111 int 
   1112 _bcm_ptp_clock_cache_info_create(
   1113     int unit, 
   1114     bcm_ptp_stack_id_t ptp_id,
   1115     int clock_num)
   1116 {
   1117     int rv = BCM_E_UNAVAIL;
   1118     _bcm_ptp_clock_cache_t *clock_cache;
   1119     int i;
   1120 
   1121     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1122             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1123         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");  
   1124         return rv;
   1125     }
   1126         
   1127     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1128         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate != 
   1129             PTP_MEMSTATE_INITIALIZED)) {
   1130         return BCM_E_UNAVAIL;
   1131     }
   1132 
   1133     clock_cache = &_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num];
   1134 
   1135     sal_memset(&clock_cache->clock_info, 0, sizeof(bcm_ptp_clock_info_t));
   1136     sal_memset(clock_cache->signal_output, 0, sizeof(bcm_ptp_signal_output_t) * PTP_MAX_OUTPUT_SIGNALS);
   1137     sal_memset(clock_cache->tod_input, 0, sizeof(bcm_ptp_tod_input_t) * PTP_MAX_TOD_INPUTS);
   1138     sal_memset(clock_cache->tod_output, 0, sizeof(bcm_ptp_tod_output_t) * PTP_MAX_TOD_OUTPUTS);
   1139     sal_memset(clock_cache->port_info, 0, sizeof(bcm_ptp_clock_port_info_t) * PTP_MAX_CLOCK_INSTANCE_PORTS);
   1140     sal_memset(clock_cache->portState, 0, sizeof(_bcm_ptp_port_state_t) * PTP_MAX_CLOCK_INSTANCE_PORTS);
   1141 
   1142     clock_cache->peerTable.num_peers = 0;
   1143     if (!clock_cache->in_use) {
   1144         clock_cache->peerTable.lock = _bcm_ptp_mutex_create("ptpstat.mutex");
   1145         if (clock_cache->peerTable.lock == NULL) {
   1146             return BCM_E_MEMORY;
   1147         }
   1148     }
   1149 
   1150     /* Initialize port states. */
   1151     for (i = 0; i < PTP_MAX_CLOCK_INSTANCE_PORTS; ++i) {
   1152         clock_cache->portState[i] = _bcm_ptp_state_initializing;
   1153     }
   1154 
   1155     return rv;
   1156 }
   1157 
   1158 /*
   1159  * Function:
   1160  *      _bcm_ptp_clock_cache_info_get
   1161  * Purpose:
   1162  *      Get the clock information cache of a PTP clock.
   1163  * Parameters:
   1164  *      unit       - (IN)  Unit number.
   1165  *      ptp_id     - (IN)  PTP stack ID.
   1166  *      clock_num  - (IN)  PTP clock number.
   1167  *      clock_info - (OUT) PTP clock information cache.
   1168  * Returns:
   1169  *      BCM_E_XXX
   1170  * Notes:
   1171  */
   1172 int _bcm_ptp_clock_cache_info_get(
   1173     int unit, 
   1174     bcm_ptp_stack_id_t ptp_id,
   1175     int clock_num,
   1176     bcm_ptp_clock_info_t *clock_info)
   1177 {
   1178     int rv = BCM_E_UNAVAIL;
   1179     
   1180     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1181             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1182         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");  
   1183         return rv;
   1184     }
   1185         
   1186     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1187         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate != 
   1188             PTP_MEMSTATE_INITIALIZED)) {
   1189         return BCM_E_UNAVAIL;
   1190     }        
   1191 
   1192     *clock_info = _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
   1193                                   .clock_array[clock_num].clock_info;
   1194     
   1195     return rv;
   1196 }
   1197 
   1198 /*
   1199  * Function:
   1200  *      _bcm_ptp_clock_cache_info_set
   1201  * Purpose:
   1202  *      Set the clock information cache of a PTP clock.
   1203  * Parameters:
   1204  *      unit       - (IN) Unit number.
   1205  *      ptp_id     - (IN) PTP stack ID.
   1206  *      clock_num  - (IN) PTP clock number.
   1207  *      clock_info - (IN) PTP clock information cache.
   1208  * Returns:
   1209  *      BCM_E_XXX
   1210  * Notes:
   1211  */
   1212 int _bcm_ptp_clock_cache_info_set(
   1213     int unit, 
   1214     bcm_ptp_stack_id_t ptp_id,
   1215     int clock_num,
   1216     const bcm_ptp_clock_info_t *clock_info)
   1217 {
   1218     int rv = BCM_E_UNAVAIL;
   1219          
   1220     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1221             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1222         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");  
   1223         return rv;
   1224     }
   1225         
   1226     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1227         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate != 
   1228             PTP_MEMSTATE_INITIALIZED)) {
   1229         return BCM_E_UNAVAIL;
   1230     }        
   1231 
   1232     _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
   1233                     .clock_array[clock_num].clock_info = *clock_info;
   1234     
   1235     return rv;
   1236 }
   1237 
   1238 int _bcm_ptp_clock_cache_signal_get(
   1239     int unit, 
   1240     bcm_ptp_stack_id_t ptp_id,
   1241     int clock_num,
   1242     int signal_num,
   1243     bcm_ptp_signal_output_t *signal)
   1244 {
   1245     int rv = BCM_E_UNAVAIL;
   1246     
   1247     if (signal_num >= PTP_MAX_OUTPUT_SIGNALS || signal_num < 0) {
   1248         return BCM_E_PARAM;
   1249     }
   1250 
   1251     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1252             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1253         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");  
   1254         return rv;
   1255     }
   1256         
   1257     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1258         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate != 
   1259             PTP_MEMSTATE_INITIALIZED)) {
   1260         return BCM_E_UNAVAIL;
   1261     }        
   1262 
   1263     *signal = _bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num].signal_output[signal_num];
   1264     
   1265     return rv;
   1266 }
   1267 
   1268 
   1269 int _bcm_ptp_clock_cache_signal_set(
   1270     int unit, 
   1271     bcm_ptp_stack_id_t ptp_id,
   1272     int clock_num,
   1273     int signal_num,
   1274     const bcm_ptp_signal_output_t *signal)
   1275 {
   1276     int rv = BCM_E_UNAVAIL;
   1277     
   1278     if (signal_num >= PTP_MAX_OUTPUT_SIGNALS || signal_num < 0) {
   1279         return BCM_E_PARAM;
   1280     }
   1281 
   1282     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1283             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1284         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");  
   1285         return rv;
   1286     }
   1287         
   1288     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1289         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate != 
   1290             PTP_MEMSTATE_INITIALIZED)) {
   1291         return BCM_E_UNAVAIL;
   1292     }        
   1293 
   1294     _bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num].signal_output[signal_num] = *signal;
   1295     
   1296     return rv;
   1297 }
   1298 
   1299 /*
   1300  * Function:
   1301  *      _bcm_ptp_clock_cache_tod_input_get
   1302  * Purpose:
   1303  *      Get a ToD input configuration from PTP clock information cache.
   1304  * Parameters:
   1305  *      unit          - (IN)  Unit number.
   1306  *      ptp_id        - (IN)  PTP stack ID.
   1307  *      clock_num     - (IN)  PTP clock number.
   1308  *      tod_input_num - (IN)  ToD input configuration number.
   1309  *      tod_input     - (OUT) ToD input configuration.
   1310  * Returns:
   1311  *      BCM_E_XXX - Function status.
   1312  * Notes:
   1313  */
   1314 int _bcm_ptp_clock_cache_tod_input_get(
   1315     int unit,
   1316     bcm_ptp_stack_id_t ptp_id,
   1317     int clock_num,
   1318     int tod_input_num,
   1319     bcm_ptp_tod_input_t *tod_input)
   1320 {
   1321     int rv = BCM_E_UNAVAIL;
   1322 
   1323     if (tod_input_num >= PTP_MAX_TOD_INPUTS || tod_input_num < 0) {
   1324         return BCM_E_PARAM;
   1325     }
   1326 
   1327     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1328             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1329         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
   1330         return rv;
   1331     }
   1332 
   1333     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1334         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate !=
   1335             PTP_MEMSTATE_INITIALIZED)) {
   1336         return BCM_E_UNAVAIL;
   1337     }
   1338 
   1339     *tod_input = _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
   1340                                               .clock_array[clock_num]
   1341                                               .tod_input[tod_input_num];
   1342 
   1343     return rv;
   1344 }
   1345 
   1346 /*
   1347  * Function:
   1348  *      _bcm_ptp_clock_cache_tod_input_set
   1349  * Purpose:
   1350  *      Set a ToD input configuration in PTP clock information cache.
   1351  * Parameters:
   1352  *      unit          - (IN) Unit number.
   1353  *      ptp_id        - (IN) PTP stack ID.
   1354  *      clock_num     - (IN) PTP clock number.
   1355  *      tod_input_num - (IN) ToD input configuration number.
   1356  *      tod_input     - (IN) ToD input configuration.
   1357  * Returns:
   1358  *      BCM_E_XXX - Function status.
   1359  * Notes:
   1360  */
   1361 int _bcm_ptp_clock_cache_tod_input_set(
   1362     int unit,
   1363     bcm_ptp_stack_id_t ptp_id,
   1364     int clock_num,
   1365     int tod_input_num,
   1366     const bcm_ptp_tod_input_t *tod_input)
   1367 {
   1368     int rv = BCM_E_UNAVAIL;
   1369 
   1370     if (tod_input_num >= PTP_MAX_TOD_INPUTS || tod_input_num < 0) {
   1371         return BCM_E_PARAM;
   1372     }
   1373 
   1374     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1375             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1376         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
   1377         return rv;
   1378     }
   1379 
   1380     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1381         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate != 
   1382             PTP_MEMSTATE_INITIALIZED)) {
   1383         return BCM_E_UNAVAIL;
   1384     }
   1385 
   1386     _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
   1387                                  .clock_array[clock_num]
   1388                                  .tod_input[tod_input_num] = *tod_input;
   1389 
   1390     return rv;
   1391 }
   1392 
   1393 /*
   1394  * Function:
   1395  *      _bcm_ptp_clock_cache_tod_output_get
   1396  * Purpose:
   1397  *      Get a ToD output configuration from PTP clock information cache.
   1398  * Parameters:
   1399  *      unit           - (IN)  Unit number.
   1400  *      ptp_id         - (IN)  PTP stack ID.
   1401  *      clock_num      - (IN)  PTP clock number.
   1402  *      tod_output_num - (IN)  ToD output configuration number.
   1403  *      tod_output     - (OUT) ToD output configuration.
   1404  * Returns:
   1405  *      BCM_E_XXX - Function status.
   1406  * Notes:
   1407  */
   1408 int _bcm_ptp_clock_cache_tod_output_get(
   1409     int unit,
   1410     bcm_ptp_stack_id_t ptp_id,
   1411     int clock_num,
   1412     int tod_output_num,
   1413     bcm_ptp_tod_output_t *tod_output)
   1414 {
   1415     int rv = BCM_E_UNAVAIL;
   1416 
   1417     if (tod_output_num >= PTP_MAX_TOD_OUTPUTS || tod_output_num < 0) {
   1418         return BCM_E_PARAM;
   1419     }
   1420 
   1421     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1422             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1423         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
   1424         return rv;
   1425     }
   1426 
   1427     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1428         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate != 
   1429             PTP_MEMSTATE_INITIALIZED)) {
   1430         return BCM_E_UNAVAIL;
   1431     }
   1432 
   1433     *tod_output = _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
   1434                                                .clock_array[clock_num]
   1435                                                .tod_output[tod_output_num];
   1436 
   1437     return rv;
   1438 }
   1439 
   1440 /*
   1441  * Function:
   1442  *      _bcm_ptp_clock_cache_tod_output_set
   1443  * Purpose:
   1444  *      Set a ToD output configuration in PTP clock information cache.
   1445  * Parameters:
   1446  *      unit           - (IN) Unit number.
   1447  *      ptp_id         - (IN) PTP stack ID.
   1448  *      clock_num      - (IN) PTP clock number.
   1449  *      tod_output_num - (IN) ToD output configuration number.
   1450  *      tod_output     - (IN) ToD output configuration.
   1451  * Returns:
   1452  *      BCM_E_XXX - Function status.
   1453  * Notes:
   1454  */
   1455 int _bcm_ptp_clock_cache_tod_output_set(
   1456     int unit,
   1457     bcm_ptp_stack_id_t ptp_id,
   1458     int clock_num,
   1459     int tod_output_num,
   1460     const bcm_ptp_tod_output_t *tod_output)
   1461 {
   1462     int rv = BCM_E_UNAVAIL;
   1463 
   1464     if (tod_output_num >= PTP_MAX_TOD_OUTPUTS || tod_output_num < 0) {
   1465         return BCM_E_PARAM;
   1466     }
   1467 
   1468     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1469             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1470         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
   1471         return rv;
   1472     }
   1473 
   1474     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1475         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate != 
   1476             PTP_MEMSTATE_INITIALIZED)) {
   1477         return BCM_E_UNAVAIL;
   1478     }
   1479 
   1480     _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
   1481                                  .clock_array[clock_num]
   1482                                  .tod_output[tod_output_num] = *tod_output;
   1483 
   1484     return rv;
   1485 }
   1486 
   1487 
   1488 extern int _bcm_ptp_set_max_unicast_masters(
   1489     int unit,
   1490     bcm_ptp_stack_id_t ptp_id,
   1491     int max_masters)
   1492 {
   1493     _bcm_ptp_info_t *ptp_info_p;
   1494     if (soc_feature(unit, soc_feature_ptp) == 0) {
   1495         return BCM_E_UNAVAIL;
   1496     }
   1497 
   1498     SET_PTP_INFO;
   1499     if (ptp_info_p->memstate != PTP_MEMSTATE_INITIALIZED) {
   1500         return BCM_E_PARAM;
   1501     }
   1502 
   1503     ptp_info_p->stack_info->unicast_master_table_size = max_masters;
   1504     return BCM_E_NONE;
   1505 }
   1506 
   1507 
   1508 extern int _bcm_ptp_set_max_acceptable_masters(
   1509     int unit,
   1510     bcm_ptp_stack_id_t ptp_id,
   1511     int max_masters)
   1512 {
   1513     _bcm_ptp_info_t *ptp_info_p;
   1514     if (soc_feature(unit, soc_feature_ptp) == 0) {
   1515         return BCM_E_UNAVAIL;
   1516     }
   1517 
   1518     SET_PTP_INFO;
   1519     if (ptp_info_p->memstate != PTP_MEMSTATE_INITIALIZED) {
   1520         return BCM_E_PARAM;
   1521     }
   1522 
   1523     ptp_info_p->stack_info->acceptable_master_table_size = max_masters;
   1524     return BCM_E_NONE;
   1525 }
   1526 
   1527 
   1528 extern int _bcm_ptp_set_max_unicast_slaves(
   1529     int unit,
   1530     bcm_ptp_stack_id_t ptp_id,
   1531     int max_slaves)
   1532 {
   1533     _bcm_ptp_info_t *ptp_info_p;
   1534     if (soc_feature(unit, soc_feature_ptp) == 0) {
   1535         return BCM_E_UNAVAIL;
   1536     }
   1537 
   1538     SET_PTP_INFO;
   1539     if (ptp_info_p->memstate != PTP_MEMSTATE_INITIALIZED) {
   1540         return BCM_E_PARAM;
   1541     }
   1542 
   1543     ptp_info_p->stack_info->unicast_slave_table_size = max_slaves;
   1544     return BCM_E_NONE;
   1545 }
   1546 
   1547 extern int _bcm_ptp_set_max_multicast_slave_stats(
   1548     int unit,
   1549     bcm_ptp_stack_id_t ptp_id,
   1550     int max_entries)
   1551 {
   1552     _bcm_ptp_info_t *ptp_info_p;
   1553     if (soc_feature(unit, soc_feature_ptp) == 0) {
   1554         return BCM_E_UNAVAIL;
   1555     }
   1556 
   1557     SET_PTP_INFO;
   1558     if (ptp_info_p->memstate != PTP_MEMSTATE_INITIALIZED) {
   1559         return BCM_E_PARAM;
   1560     }
   1561 
   1562     ptp_info_p->stack_info->multicast_slave_stats_size = max_entries;
   1563     return BCM_E_NONE;
   1564 }
   1565 
   1566 
   1567 #endif /* defined(INCLUDE_PTP)*/