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

clock_config.c (162614B)


      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:    clock_config.c
      8  *
      9  * Purpose: 
     10  *
     11  * Functions:
     12  *      bcm_common_ptp_clock_accuracy_get
     13  *      bcm_common_ptp_clock_accuracy_set
     14  *      bcm_common_ptp_clock_quality_get
     15  *      bcm_common_ptp_clock_quality_set
     16  *      bcm_common_ptp_g8275p1_traceability_info_clock_class_map
     17  *      bcm_common_ptp_clock_current_dataset_get
     18  *      bcm_common_ptp_clock_default_dataset_get
     19  *      bcm_common_ptp_clock_domain_get
     20  *      bcm_common_ptp_clock_domain_set
     21  *      bcm_common_ptp_clock_get
     22  *      bcm_common_ptp_clock_parent_dataset_get
     23  *      bcm_common_ptp_clock_port_announce_receipt_timeout_get
     24  *      bcm_common_ptp_clock_port_announce_receipt_timeout_set
     25  *      bcm_common_ptp_clock_port_configure
     26  *      bcm_common_ptp_clock_port_dataset_get
     27  *      bcm_common_ptp_clock_port_delay_mechanism_get
     28  *      bcm_common_ptp_clock_port_delay_mechanism_set
     29  *      bcm_common_ptp_clock_port_disable
     30  *      bcm_common_ptp_clock_port_enable
     31  *      bcm_common_ptp_clock_port_info_get
     32  *      bcm_common_ptp_clock_port_latency_get
     33  *      bcm_common_ptp_clock_port_latency_set
     34  *      bcm_common_ptp_clock_port_log_announce_interval_get
     35  *      bcm_common_ptp_clock_port_log_announce_interval_set
     36  *      bcm_common_ptp_clock_port_log_min_delay_req_interval_get
     37  *      bcm_common_ptp_clock_port_log_min_delay_req_interval_set
     38  *      bcm_common_ptp_clock_port_log_min_pdelay_req_interval_get
     39  *      bcm_common_ptp_clock_port_log_min_pdelay_req_interval_set
     40  *      bcm_common_ptp_clock_port_log_sync_interval_get
     41  *      bcm_common_ptp_clock_port_log_sync_interval_set
     42  *      bcm_common_ptp_clock_port_mac_get
     43  *      bcm_common_ptp_clock_port_type_get
     44  *      bcm_common_ptp_clock_port_version_number_get
     45  *      bcm_common_ptp_clock_port_version_number_set
     46  *      bcm_common_ptp_clock_priority1_get
     47  *      bcm_common_ptp_clock_priority1_set
     48  *      bcm_common_ptp_clock_priority2_get
     49  *      bcm_common_ptp_clock_priority2_set
     50  *      bcm_common_ptp_clock_local_priority_get
     51  *      bcm_common_ptp_clock_local_priority_set
     52  *      bcm_common_ptp_clock_max_steps_removed_get
     53  *      bcm_common_ptp_clock_max_steps_removed_set
     54  *      bcm_common_ptp_clock_slaveonly_get
     55  *      bcm_common_ptp_clock_slaveonly_set
     56  *      bcm_common_ptp_clock_time_get
     57  *      bcm_common_ptp_clock_time_properties_get
     58  *      bcm_common_ptp_clock_time_set
     59  *      bcm_common_ptp_clock_timescale_get
     60  *      bcm_common_ptp_clock_timescale_set
     61  *      bcm_common_ptp_clock_traceability_get
     62  *      bcm_common_ptp_clock_traceability_set
     63  *      bcm_common_ptp_clock_user_description_set
     64  *      bcm_common_ptp_clock_utc_get
     65  *      bcm_common_ptp_clock_utc_set
     66  *      bcm_common_ptp_foreign_master_dataset_get
     67  *      bcm_common_ptp_clock_peer_age_timer_set
     68  *      bcm_common_ptp_clock_peer_age_timer_get
     69  *
     70  *      _bcm_ptp_clock_port_cache_info_get
     71  *      _bcm_ptp_clock_port_cache_info_set
     72  *      _bcm_ptp_clock_cache_port_state_get
     73  *      _bcm_ptp_clock_cache_port_state_set
     74  */
     75 
     76 #if defined(INCLUDE_PTP)
     77 
     78 #include <soc/defs.h>
     79 #include <soc/drv.h>
     80 #include <shared/bsl.h>
     81 #include <sal/core/boot.h>
     82 #include <shared/bsl.h>
     83 #include <bcm/ptp.h>
     84 #include <bcm_int/common/ptp.h>
     85 #include <bcm_int/ptp_common.h>
     86 #include <bcm_int/common/PTP_feature.h>
     87 #include <bcm/error.h>
     88 
     89 static const bcm_ptp_port_identity_t portid_all =
     90     {{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, PTP_IEEE1588_ALL_PORTS};
     91 
     92 #define BCM_APTS_OP_MODE_LIST_IDX_PTP      13
     93 #define BCM_APTS_MAX_OP_MODE_LIST_SIZE     6
     94 #define BCM_APTS_MAX_NUM_OP_MODE_LISTS     14
     95 
     96 typedef struct _bcm_ptp_apts_opt_mode_list_node_e {
     97     /* APTS op mode. */
     98     bcm_ptp_clock_apts_mode_t op_mode;
     99     /* required sources for corresponding mode */
    100     _bcm_ptp_apts_source_avail_t required_sources;
    101 } _bcm_ptp_apts_opt_mode_list_node_t;
    102 
    103 typedef struct _bcm_ptp_apts_opt_mode_list_e {
    104     int num_nodes;
    105     _bcm_ptp_apts_opt_mode_list_node_t op_mode_list[BCM_APTS_MAX_OP_MODE_LIST_SIZE];
    106 }_bcm_ptp_apts_opt_mode_list_t;
    107 
    108 int g_apts_enabled = 0;
    109 bcm_ptp_clock_apts_mode_t g_apts_current_op_mode = bcmPtpClockAptsModePtpPtp;
    110 _bcm_ptp_apts_source_avail_t g_apts_current_source_state = 0;
    111 bcm_ptp_clock_apts_source_t g_apts_usr_cfgd_priority_list[BCM_PTP_CLOCK_APTS_MAX_FREQ_SOURCES] = {bcmPtpClockAptsSourceLast};
    112 bcm_ptp_clock_apts_source_t g_apts_usr_cfgd_source_state = 0;
    113 static int g_apts_op_mode_list_idx = BCM_APTS_OP_MODE_LIST_IDX_PTP;
    114 
    115 static const _bcm_ptp_apts_opt_mode_list_t g_apts_op_mode_lists[BCM_APTS_MAX_NUM_OP_MODE_LISTS] = {
    116 {6, {{bcmPtpClockAptsModeSyncEGps, _bcm_ptp_apts_avail_gps_synce}, {bcmPtpClockAptsModeSyncEPtp, _bcm_ptp_apts_avail_ptp_synce}, {bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    117 {6, {{bcmPtpClockAptsModeSyncEPtp, _bcm_ptp_apts_avail_ptp_synce}, {bcmPtpClockAptsModeSyncEGps, _bcm_ptp_apts_avail_gps_synce}, {bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    118 {5, {{bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModeSyncEPtp, _bcm_ptp_apts_avail_ptp_synce}, {bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    119 {4, {{bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    120 {5, {{bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeSyncEGps, _bcm_ptp_apts_avail_gps_synce}, {bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    121 {4, {{bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    122 {4, {{bcmPtpClockAptsModeSyncEGps, _bcm_ptp_apts_avail_gps_synce}, {bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    123 {4, {{bcmPtpClockAptsModeSyncEPtp, _bcm_ptp_apts_avail_ptp_synce}, {bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    124 {3, {{bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    125 {3, {{bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    126 {3, {{bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeSyncEHoldover, _bcm_ptp_apts_avail_synce}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    127 {3, {{bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    128 {2, {{bcmPtpClockAptsModeGpsGps, _bcm_ptp_apts_avail_gps}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}},
    129 {2, {{bcmPtpClockAptsModePtpPtp, _bcm_ptp_apts_avail_ptp}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}, {bcmPtpClockAptsModeHoldoverHoldover, _bcm_ptp_apts_avail_none}}}
    130 };
    131 
    132 /*
    133  * Function:
    134  *      _bcm_ptp_clock_port_cache_info_get
    135  * Purpose:
    136  *      Get the clock port information cache of a PTP clock.
    137  * Parameters:
    138  *      unit       - (IN)  Unit number.
    139  *      ptp_id     - (IN)  PTP stack ID.
    140  *      clock_num  - (IN)  PTP clock number.
    141  *      clock_port - (IN)  PTP clock port number.
    142  *      port_info  - (OUT) PTP clock port information cache.
    143  * Returns:
    144  *      BCM_E_XXX
    145  * Notes:
    146  */
    147 int _bcm_ptp_clock_port_cache_info_get(
    148     int unit,
    149     bcm_ptp_stack_id_t ptp_id,
    150     int clock_num,
    151     uint32 clock_port,
    152     bcm_ptp_clock_port_info_t *port_info)
    153 {
    154     int rv = BCM_E_UNAVAIL;
    155 
    156     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    157             clock_port))) {
    158         return rv;
    159     }
    160 
    161     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    162         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate !=
    163             PTP_MEMSTATE_INITIALIZED)) {
    164         return BCM_E_UNAVAIL;
    165     }
    166 
    167     if ((clock_port < 1) ||
    168         (clock_port > _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
    169                                       .clock_array[clock_num]
    170                                       .clock_info.num_ports)) {
    171         return BCM_E_PORT;
    172     }
    173 
    174     *port_info = _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
    175                                  .clock_array[clock_num]
    176                                  .port_info[clock_port-1];
    177 
    178     return rv;
    179 }
    180 
    181 /*
    182  * Function:
    183  *      _bcm_ptp_clock_port_cache_info_set
    184  * Purpose:
    185  *      Set the clock port information cache of a PTP clock.
    186  * Parameters:
    187  *      unit       - (IN) Unit number.
    188  *      ptp_id     - (IN) PTP stack ID.
    189  *      clock_num  - (IN) PTP clock number.
    190  *      clock_port - (IN) PTP clock port number.
    191  *      port_info  - (IN) PTP clock port information cache.
    192  * Returns:
    193  *      BCM_E_XXX
    194  * Notes:
    195  */
    196 int _bcm_ptp_clock_port_cache_info_set(
    197     int unit,
    198     bcm_ptp_stack_id_t ptp_id,
    199     int clock_num,
    200     uint32 clock_port,
    201     const bcm_ptp_clock_port_info_t *port_info)
    202 {
    203     int rv = BCM_E_UNAVAIL;
    204 
    205     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    206             clock_port))) {
    207         return rv;
    208     }
    209 
    210     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    211         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate !=
    212             PTP_MEMSTATE_INITIALIZED)) {
    213         return BCM_E_UNAVAIL;
    214     }
    215 
    216     if ((clock_port < 1) ||
    217         (clock_port > _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
    218                                       .clock_array[clock_num]
    219                                       .clock_info.num_ports)) {
    220         return BCM_E_PORT;
    221     }
    222 
    223     _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
    224                     .clock_array[clock_num]
    225                     .port_info[clock_port-1] = *port_info;
    226 
    227     return rv;
    228 }
    229 
    230 /*
    231  * Function:
    232  *      _bcm_ptp_clock_cache_port_state_get
    233  * Purpose:
    234  *      Get a PTP port's portState from PTP clock information cache.
    235  * Parameters:
    236  *      unit       - (IN)  Unit number.
    237  *      ptp_id     - (IN)  PTP stack ID.
    238  *      clock_num  - (IN)  PTP clock number.
    239  *      clock_port - (IN)  PTP clock port number.
    240  *      portState  - (OUT) PTP clock port state.
    241  * Returns:
    242  *      BCM_E_XXX
    243  * Notes:
    244  */
    245 int
    246 _bcm_ptp_clock_cache_port_state_get(
    247     int unit,
    248     bcm_ptp_stack_id_t ptp_id,
    249     int clock_num,
    250     uint32 clock_port,
    251     _bcm_ptp_port_state_t *portState)
    252 {
    253     int rv = BCM_E_UNAVAIL;
    254 
    255     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    256             clock_port))) {
    257         return rv;
    258     }
    259 
    260     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    261         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate !=
    262             PTP_MEMSTATE_INITIALIZED)) {
    263         return BCM_E_UNAVAIL;
    264     }
    265 
    266     if (clock_port < 1 ||
    267         clock_port > _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
    268                      .clock_array[clock_num].clock_info.num_ports) {
    269         return BCM_E_PORT;
    270     }
    271 
    272     *portState = _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
    273                      .clock_array[clock_num].portState[clock_port-1];
    274 
    275     return rv;
    276 }
    277 
    278 /*
    279  * Function:
    280  *      _bcm_ptp_clock_cache_port_state_set
    281  * Purpose:
    282  *      Set a PTP port's portState in PTP clock information cache.
    283  * Parameters:
    284  *      unit       - (IN) Unit number.
    285  *      ptp_id     - (IN) PTP stack ID.
    286  *      clock_num  - (IN) PTP clock number.
    287  *      clock_port - (IN) PTP clock port number.
    288  *      portState  - (IN) PTP clock port state.
    289  * Returns:
    290  *      BCM_E_XXX
    291  * Notes:
    292  */
    293 int
    294 _bcm_ptp_clock_cache_port_state_set(
    295     int unit,
    296     bcm_ptp_stack_id_t ptp_id,
    297     int clock_num,
    298     uint32 clock_port,
    299     const _bcm_ptp_port_state_t portState)
    300 {
    301     int rv = BCM_E_UNAVAIL;
    302 
    303     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    304             clock_port))) {
    305         return rv;
    306     }
    307 
    308     if ((_bcm_common_ptp_unit_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    309         (_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].memstate !=
    310             PTP_MEMSTATE_INITIALIZED)) {
    311         return BCM_E_UNAVAIL;
    312     }
    313 
    314     if (clock_port < 1 ||
    315         clock_port > _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
    316                      .clock_array[clock_num].clock_info.num_ports) {
    317         return BCM_E_PORT;
    318     }
    319 
    320     _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
    321         .clock_array[clock_num].portState[clock_port-1] = portState;
    322 
    323     return rv;
    324 }
    325 
    326 /*
    327  * Function:
    328  *      bcm_common_ptp_clock_get
    329  * Purpose:
    330  *      Get configuration information (data and metadata) of a PTP clock.
    331  * Parameters:
    332  *      unit       - (IN)  Unit number.
    333  *      ptp_id     - (IN)  PTP stack ID.
    334  *      clock_num  - (IN)  PTP clock number.
    335  *      clock_info - (OUT) PTP clock information.
    336  * Returns:
    337  *      BCM_E_XXX
    338  * Notes:
    339  */
    340 int
    341 bcm_common_ptp_clock_get(
    342     int unit,
    343     bcm_ptp_stack_id_t ptp_id,
    344     int clock_num,
    345     bcm_ptp_clock_info_t *clock_info)
    346 {
    347     int rv = BCM_E_UNAVAIL;
    348 
    349     if (BCM_FAILURE(rv =
    350         _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, clock_info))) {
    351         LOG_ERROR(BSL_LS_BCM_COMMON,
    352                   (BSL_META_U(unit,
    353                               "_bcm_ptp_clock_cache_info_get failed\n")));
    354         return rv;
    355     }
    356 
    357     return rv;
    358 }
    359 
    360 /*
    361  * Function:
    362  *      bcm_common_ptp_clock_time_get
    363  * Purpose:
    364  *      Get local time of a PTP node.
    365  * Parameters:
    366  *      unit      - (IN)  Unit number.
    367  *      ptp_id    - (IN)  PTP stack ID.
    368  *      clock_num - (IN)  PTP clock number.
    369  *      time      - (OUT) PTP timestamp.
    370  * Returns:
    371  *      BCM_E_XXX
    372  * Notes:
    373  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.2.1.
    374  */
    375 int
    376 bcm_common_ptp_clock_time_get(
    377     int unit,
    378     bcm_ptp_stack_id_t ptp_id,
    379     int clock_num,
    380     bcm_ptp_timestamp_t *time)
    381 {
    382     int rv = BCM_E_UNAVAIL;
    383     uint64 seconds;
    384 
    385     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
    386     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
    387 
    388     bcm_ptp_port_identity_t portid;
    389 
    390     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    391             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    392         return rv;
    393     }
    394 
    395     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
    396             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
    397         return rv;
    398     }
    399 
    400     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
    401             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_TIME, 0, 0, resp, &resp_len);
    402 
    403     if (rv == BCM_E_NONE) {
    404         /*
    405          * Parse response.
    406          *    Octet 0...9 : Timestamp. 48-bit seconds, 32-bit nanoseconds.
    407          *    NOTICE: bcm_ptp_timestamp_t seconds member is 64-bit value.
    408          */
    409         seconds = _bcm_ptp_uint64_read(resp);
    410         COMPILER_64_SHR(seconds, 16); 
    411         COMPILER_64_SET(time->seconds, 
    412                 COMPILER_64_HI(seconds), COMPILER_64_LO(seconds));
    413         time->nanoseconds = _bcm_ptp_uint32_read(resp+6);
    414     }
    415 
    416     return rv;
    417 }
    418 
    419 /*
    420  * Function:
    421  *      bcm_common_ptp_clock_time_set
    422  * Purpose:
    423  *      Set local time of a PTP node.
    424  * Parameters:
    425  *      unit      - (IN) Unit number.
    426  *      ptp_id    - (IN) PTP stack ID.
    427  *      clock_num - (IN) PTP clock number.
    428  *      time      - (IN) PTP timestamp.
    429  * Returns:
    430  *      BCM_E_XXX
    431  * Notes:
    432  *      Function applies to a grandmaster node only.
    433  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.2.1.
    434  */
    435 int
    436 bcm_common_ptp_clock_time_set(
    437     int unit,
    438     bcm_ptp_stack_id_t ptp_id,
    439     int clock_num,
    440     bcm_ptp_timestamp_t *time)
    441 {
    442     int rv = BCM_E_UNAVAIL;
    443     uint64 seconds;
    444 
    445     uint8 payload[PTP_MGMTMSG_PAYLOAD_TIME_SIZE_OCTETS] = {0};
    446     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
    447     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
    448 
    449     bcm_ptp_port_identity_t portid;
    450 
    451     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    452             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    453         return rv;
    454     }
    455 
    456     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
    457             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
    458         return rv;
    459     }
    460 
    461     /*
    462      * Make payload.
    463      *    Octet 0...9 : Timestamp. 48-bit seconds, 32-bit nanoseconds.
    464      *    NOTICE: bcm_ptp_timestamp_t seconds member is 64-bit value.
    465      */
    466     COMPILER_64_SET(seconds, 
    467                 COMPILER_64_HI(time->seconds), COMPILER_64_LO(time->seconds));
    468     COMPILER_64_SHL(seconds, 16); 
    469     _bcm_ptp_uint64_write(payload, seconds);
    470     _bcm_ptp_uint32_write(payload+6, time->nanoseconds);
    471 
    472     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
    473             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_TIME,
    474             payload, PTP_MGMTMSG_PAYLOAD_TIME_SIZE_OCTETS,
    475             resp, &resp_len);
    476 
    477     return rv;
    478 }
    479 
    480 /*
    481  * Function:
    482  *      bcm_common_ptp_clock_user_description_set
    483  * Purpose:
    484  *      Set user description member of the default dataset.
    485  * Parameters:
    486  *      unit      - (IN) Unit number.
    487  *      ptp_id    - (IN) PTP stack ID.
    488  *      clock_num - (IN) PTP clock number.
    489  *      desc      - (IN) User description.
    490  * Returns:
    491  *      BCM_E_XXX
    492  * Notes:
    493  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.1.3.
    494  */
    495 int
    496 bcm_common_ptp_clock_user_description_set(
    497     int unit,
    498     bcm_ptp_stack_id_t ptp_id,
    499     int clock_num,
    500     uint8 *desc)
    501 {
    502     int rv = BCM_E_UNAVAIL;
    503 
    504     uint8 payload[PTP_MGMTMSG_PAYLOAD_MAX_USER_DESCRIPTION_SIZE_OCTETS] = {0};
    505     int desc_len;
    506 
    507     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
    508     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
    509 
    510     bcm_ptp_port_identity_t portid;
    511 
    512     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    513             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    514         return rv;
    515     }
    516 
    517     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
    518             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
    519         return rv;
    520     }
    521 
    522     /*
    523      * Make payload.
    524      *    Octet 0         : User description length (octets).
    525      *    Octet 1...(L-1) : User description.
    526      *    Octet L         : Conditional payload padding.
    527      */
    528     for (desc_len = 0;
    529          desc_len < (PTP_MGMTMSG_PAYLOAD_MAX_USER_DESCRIPTION_SIZE_OCTETS-1);
    530          ++desc_len) {
    531         if (desc[desc_len] == 0) {
    532             break;
    533         }
    534     }
    535 
    536     payload[0] = desc_len;
    537     sal_memcpy(payload+1, desc, desc_len);
    538     /*
    539      * NOTICE: Per IEEE Std. 1588-2008, Chapter 15.5.3.1.3, pad logic is
    540      *         used to yield an even-octet-sized management TLV data field
    541      *         with assumption that maximum USER_DESCRIPTION size is even.
    542      */
    543     if ((desc_len % 2) == 0) {
    544         ++desc_len;
    545     }
    546 
    547     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
    548             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_USER_DESCRIPTION,
    549             payload, (1+desc_len), resp, &resp_len);
    550 
    551     return rv;
    552 }
    553 
    554 /*
    555  * Function:
    556  *      bcm_common_ptp_clock_default_dataset_get
    557  * Purpose:
    558  *      Get PTP clock default dataset.
    559  * Parameters:
    560  *      unit      - (IN)  Unit number.
    561  *      ptp_id    - (IN)  PTP stack ID.
    562  *      clock_num - (IN)  PTP clock number.
    563  *      dataset   - (OUT) Default dataset.
    564  * Returns:
    565  *      BCM_E_XXX
    566  * Notes:
    567  *      The default dataset is relevant to PTP ordinary and boundary clocks.
    568  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.3.
    569  */
    570 int
    571 bcm_common_ptp_clock_default_dataset_get(
    572     int unit,
    573     bcm_ptp_stack_id_t ptp_id,
    574     int clock_num,
    575     bcm_ptp_default_dataset_t *dataset)
    576 {
    577     int rv = BCM_E_UNAVAIL;
    578 
    579     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
    580     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
    581     int i = 0;
    582 
    583     bcm_ptp_port_identity_t portid;
    584 
    585     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    586             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    587         return rv;
    588     }
    589 
    590     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
    591             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
    592         return rv;
    593     }
    594 
    595     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
    596             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_DEFAULT_DATASET,
    597             0, 0, resp, &resp_len);
    598 
    599     if (rv == BCM_E_NONE) {
    600         /*
    601          * Parse response.
    602          *    Octet 0: Two-step (TSC) and slave-only (SO) Booleans.
    603          *             |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|0|0|0|0|SO|TSC|.
    604          *    Octet 1       : Reserved.
    605          *    Octet 2...3   : Number of ports.
    606          *    Octet 4       : Priority1.
    607          *    Octet 5...8   : Clock quality.
    608          *    Octet 9       : Priority2.
    609          *    Octet 10...17 : Clock identity.
    610          *    Octet 18      : PTP domain number.
    611          */
    612         i = 0;
    613         dataset->flags = (0x03 & resp[i]);
    614         i = 2;
    615         dataset->number_ports = _bcm_ptp_uint16_read(resp+i);
    616         i += sizeof(uint16);
    617         dataset->priority1 = resp[i++];
    618 
    619         dataset->clock_quality.clock_class = resp[i++];
    620         dataset->clock_quality.clock_accuracy = resp[i++];
    621         dataset->clock_quality.offset_scaled_log_variance =
    622             _bcm_ptp_uint16_read(resp+i);
    623         i += sizeof(uint16);
    624 
    625         dataset->priority2 = resp[i++];
    626         sal_memcpy(dataset->clock_identity,
    627                    resp+i, sizeof(bcm_ptp_clock_identity_t));
    628         i += sizeof(bcm_ptp_clock_identity_t);
    629         dataset->domain_number = resp[i];
    630         i++;
    631 
    632         /* Firmware was sending Reserved value "0" at Byte offset#19 */
    633         if( (resp_len > i) && (0 != resp[i]) )
    634         {
    635             /* Read local priority if included in the message */
    636             dataset->local_priority = resp[i++];
    637         }
    638 
    639         if (PTP_UC_FEATURE_CHECK(PTP_G8275P1_MAX_STEPS_REMOVED)) {
    640             /* Read maxStepsRemoved if included in the message */
    641             dataset->max_steps_removed = resp[i];
    642         }
    643     }
    644 
    645     return rv;
    646 }
    647 
    648 /*
    649  * Function:
    650  *      bcm_common_ptp_clock_current_dataset_get
    651  * Purpose:
    652  *      Get PTP clock current dataset.
    653  * Parameters:
    654  *      unit      - (IN)  Unit number.
    655  *      ptp_id    - (IN)  PTP stack ID.
    656  *      clock_num - (IN)  PTP clock number.
    657  *      dataset   - (OUT) Current dataset.
    658  * Returns:
    659  *      BCM_E_XXX
    660  * Notes:
    661  *      The current dataset is relevant to PTP ordinary and boundary clocks.
    662  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.2 and 15.5.3.4.
    663  */
    664 int
    665 bcm_common_ptp_clock_current_dataset_get(
    666     int unit,
    667     bcm_ptp_stack_id_t ptp_id,
    668     int clock_num,
    669     bcm_ptp_current_dataset_t *dataset)
    670 {
    671     int rv = BCM_E_UNAVAIL;
    672 
    673     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
    674     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
    675     int i = 0;
    676 
    677     bcm_ptp_port_identity_t portid;
    678 
    679     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    680             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    681         return rv;
    682     }
    683 
    684     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
    685             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
    686         return rv;
    687     }
    688 
    689     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
    690             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CURRENT_DATASET,
    691             0, 0, resp, &resp_len);
    692 
    693     if (rv == BCM_E_NONE) {
    694         /*
    695          * Parse response.
    696          *    Octet 0...1   : Steps removed from master.
    697          *    Octet 2...9   : Offset from master (scaled nanoseconds).
    698          *    Octet 10...17 : Mean path delay (scaled nanoseconds).
    699          */
    700         i = 0;
    701         dataset->steps_removed = _bcm_ptp_uint16_read(resp);
    702         i += sizeof(uint16);
    703         dataset->offset_from_master = _bcm_ptp_uint64_read(resp+i);
    704         i += sizeof(uint64);
    705         dataset->mean_path_delay = _bcm_ptp_uint64_read(resp+i);
    706     }
    707 
    708     return rv;
    709 }
    710 
    711 /*
    712  * Function:
    713  *      bcm_common_ptp_clock_parent_dataset_get
    714  * Purpose:
    715  *      Get PTP clock parent dataset.
    716  * Parameters:
    717  *      unit      - (IN)  Unit number.
    718  *      ptp_id    - (IN)  PTP stack ID.
    719  *      clock_num - (IN)  PTP clock number.
    720  *      dataset   - (OUT) Parent dataset.
    721  * Returns:
    722  *      BCM_E_XXX
    723  * Notes:
    724  *      The parent dataset is relevant to PTP ordinary and boundary clocks.
    725  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.3 and 15.5.3.5.
    726  */
    727 int
    728 bcm_common_ptp_clock_parent_dataset_get(
    729     int unit,
    730     bcm_ptp_stack_id_t ptp_id,
    731     int clock_num,
    732     bcm_ptp_parent_dataset_t *dataset)
    733 {
    734     int rv = BCM_E_UNAVAIL;
    735 
    736     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
    737     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
    738     int i = 0;
    739 
    740     bcm_ptp_port_identity_t portid;
    741 
    742     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    743             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    744         return rv;
    745     }
    746 
    747     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
    748             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
    749         return rv;
    750     }
    751 
    752     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
    753             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_PARENT_DATASET,
    754             0, 0, resp, &resp_len);
    755 
    756     if (rv == BCM_E_NONE) {
    757         /*
    758          * Parse response.
    759          *    Octet 0...9   : Parent port identity.
    760          *    Octet 10      : Parent statistics (PS) Boolean.
    761          *                    |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|0|0|0|0|0|PS|.
    762          *    Octet 11      : Reserved.
    763          *    Octet 12...13 : Observed parent offset scaled log variance.
    764          *    Octet 14...17 : Observed parent clock phase change rate.
    765          *    Octet 18      : Grandmaster clock Priority1.
    766          *    Octet 19...22 : Grandmaster clock quality.
    767          *    Octet 23      : Grandmaster clock Priority2.
    768          *    Octet 24...31 : Grandmaster clock identity.
    769          */
    770         i = 0;
    771         sal_memcpy(dataset->parent_port_identity.clock_identity, resp,
    772                    sizeof(bcm_ptp_clock_identity_t));
    773         i += sizeof(bcm_ptp_clock_identity_t);
    774         dataset->parent_port_identity.port_number = _bcm_ptp_uint16_read(resp+i);
    775         i += sizeof(uint16);
    776 
    777         dataset->ps = (0x01 & resp[i]);
    778         i += 2;
    779 
    780         dataset->observed_parent_offset_scaled_log_variance =
    781             _bcm_ptp_uint16_read(resp+i);
    782         i += sizeof(uint16);
    783 
    784         dataset->observed_parent_clock_phase_change_rate =
    785             _bcm_ptp_uint32_read(resp+i);
    786         i += sizeof(uint32);
    787 
    788         dataset->grandmaster_priority1 = resp[i++];
    789 
    790         dataset->grandmaster_clock_quality.clock_class = resp[i++];
    791         dataset->grandmaster_clock_quality.clock_accuracy = resp[i++];
    792 
    793         dataset->grandmaster_clock_quality.offset_scaled_log_variance =
    794             _bcm_ptp_uint16_read(resp+i);
    795         i += sizeof(uint16);
    796 
    797         dataset->grandmaster_priority2 = resp[i++];
    798 
    799         sal_memcpy(dataset->grandmaster_identity, resp+i,
    800                    sizeof(bcm_ptp_clock_identity_t));
    801     }
    802 
    803     return rv;
    804 }
    805 
    806 /*
    807  * Function:
    808  *      bcm_common_ptp_clock_time_properties_get
    809  * Purpose:
    810  *      Get PTP clock time properties dataset.
    811  * Parameters:
    812  *      unit      - (IN)  Unit number.
    813  *      ptp_id    - (IN)  PTP stack ID.
    814  *      clock_num - (IN)  PTP clock number.
    815  *      dataset   - (OUT) Time properties dataset.
    816  * Returns:
    817  *      BCM_E_XXX
    818  * Notes:
    819  *      The time properties dataset is relevant to PTP ordinary and boundary clocks.
    820  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.4 and 15.5.3.6.
    821  */
    822 int
    823 bcm_common_ptp_clock_time_properties_get(
    824     int unit,
    825     bcm_ptp_stack_id_t ptp_id,
    826     int clock_num,
    827     bcm_ptp_time_properties_t *dataset)
    828 {
    829     int rv = BCM_E_UNAVAIL;
    830 
    831     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
    832     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
    833     int i = 0;
    834 
    835     bcm_ptp_port_identity_t portid;
    836 
    837     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    838             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    839         return rv;
    840     }
    841 
    842     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
    843             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
    844         return rv;
    845     }
    846 
    847     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
    848             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_TIME_PROPERTIES_DATASET,
    849             0, 0, resp, &resp_len);
    850 
    851     if (rv == BCM_E_NONE) {
    852         /*
    853          * Parse response.
    854          *    Octet 0...1 : UTC offset.
    855          *    Octet 2     : Leap-61 (LI-61), Leap-59 (LI-59), Valid UTC
    856          *                  Offset (UTCV), PTP timescale, time traceable
    857          *                  (TTRA), and frequency traceable (FTRA) Booleans.
    858          *                  |B7|B6|B5|B4|B3|B2|B1|B0| =
    859          *                  |0|0|FTRA|TTRA|PTP|UTCV|LI-59|LI-61|.
    860          *    Octet 3     : Time source.
    861          *    Octet 4..8  : pkt flags.
    862  */
    863         i = 0;
    864         dataset->utc_info.utc_offset = _bcm_ptp_uint16_read(resp);
    865         i += sizeof(uint16);
    866 
    867         dataset->utc_info.leap61 = (0x01 & resp[i]);
    868         dataset->utc_info.leap59 = ((0x02 & resp[i]) >> 1);
    869         dataset->utc_info.utc_valid = ((0x04 & resp[i]) >> 2);
    870 
    871         dataset->trace_info.time_traceable = ((0x10 & resp[i]) >> 4);
    872         dataset->trace_info.frequency_traceable = ((0x20 & resp[i]) >> 5);
    873 
    874         dataset->timescale_info.ptp_timescale = ((0x08 & resp[i++]) >> 3);
    875         dataset->timescale_info.time_source = (bcm_ptp_time_source_t)resp[i++];
    876 
    877         if (PTP_UC_FEATURE_CHECK(PTP_TIMEPROPERTIES_PKT_FLAGS)) {
    878             dataset->ptp_pkt_flags = _bcm_ptp_uint32_read(&resp[i]);
    879             i += sizeof(uint32);
    880         }
    881     }
    882 
    883     return rv;
    884 }
    885 
    886 /*
    887  * Function:
    888  *      bcm_common_ptp_foreign_master_dataset_get
    889  * Purpose:
    890  *      Get the foreign master dataset of a PTP clock port.
    891  * Parameters:
    892  *      unit      - (IN)  Unit number.
    893  *      ptp_id    - (IN)  PTP stack ID.
    894  *      clock_num - (IN)  PTP clock number.
    895  *      data_set  - (OUT) Foreign master dataset.
    896  * Returns:
    897  *      BCM_E_XXX
    898  * Notes:
    899  */
    900 int
    901 bcm_common_ptp_foreign_master_dataset_get(
    902     int unit,
    903     bcm_ptp_stack_id_t ptp_id,
    904     int clock_num,
    905     int port_num,
    906     bcm_ptp_foreign_master_dataset_t *data_set)
    907 {
    908     int rv = BCM_E_NONE;
    909 
    910     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
    911     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
    912 
    913     bcm_ptp_port_identity_t portid;
    914 
    915     unsigned num_masters;
    916     unsigned offset;
    917     unsigned index;
    918     unsigned module_num = 0;
    919     unsigned phy_port_num = 0;
    920     _bcm_ptp_clock_cache_t *clock_cache;
    921 
    922     BCM_IF_ERROR_RETURN(
    923         _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    924                                    PTP_CLOCK_PORT_NUMBER_DEFAULT));
    925 
    926     BCM_IF_ERROR_RETURN(
    927         bcm_common_ptp_clock_port_identity_get(unit, ptp_id, clock_num,
    928                                             port_num, &portid));
    929 
    930     clock_cache = &_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num];
    931     if (!clock_cache->in_use)
    932         return BCM_E_UNAVAIL;
    933 
    934     BCM_IF_ERROR_RETURN(
    935         _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
    936                                          PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_FOREIGN_MASTER_DATASET,
    937                                          0, 0, resp, &resp_len));
    938 
    939     /*
    940      * Parse response.
    941      *    Octet  0      : Number of foreign masters.
    942      *    Octet  1      : Current best master index.
    943      *    Octet  2..9   : FM#0 clockIdentity.
    944      *    Octet 10..11  : FM#0 Port number.
    945      *    Octet 12      : FM#0 Address type.
    946      *    Octet 13..28  : FM#0 Address.
    947      *    Octet 29      : FM#0 clockClass.
    948      *    Octet 30      : FM#0 grandmasterPriority1.
    949      *    Octet 31      : FM#0 grandmasterPriority2.
    950      *    Octet 32      : FM#0 Minimum clockClass since last query.
    951      *    Octet 33      : FM#0 Maximum clockClass since last query.
    952      *    Octet 34      : FM#0 Number of clockClass decrease events since last query.
    953      *    Octet 35      : FM#0 Number of clockClass increase events since last query.
    954      *    Octet 36..39  : FM#0 Milliseconds since Sync (max 1 hr).
    955      *    Octet 40..43  : FM#0 Milliseconds since Sync/Followup TS (max 1 hr).
    956      *    Octet 44..47  : FM#0 Milliseconds since Delay_Resp (max 1 hr).
    957      *    Octet 48..49  : FM#0 Announce messages in window.
    958      *    Octet 50..57  : FM#0 PDV scaled Allan variance (PTP variance of MTSDs).
    959      *    Octet 58..59  : FM#0 offset scaled log variance.
    960      *    Octet 60      : FM#0 clock accuracy.
    961      *    Octet 61..62  : FM#0 steps removed.
    962      *    Octet 63..70  : FM#0 Grandmaster clock Id.
    963      *    Octet 71..72  : FM#0 module number.
    964      *    Octet 73..74  : FM#0 physical port number.
    965      *    Octet 75..143 : FM#1 (as FM#0).
    966      *    ...
    967      */
    968 
    969     num_masters = resp[0];
    970     if (num_masters > _PTP_MAX_FOREIGN_MASTER_DATASET_ENTRIES) {
    971         num_masters = _PTP_MAX_FOREIGN_MASTER_DATASET_ENTRIES;
    972         rv = BCM_E_FULL;
    973     }
    974 
    975     if (resp[1] != 0xff) {
    976         data_set->current_best_master = resp[1];
    977     } else {
    978         data_set->current_best_master = 0;
    979     }
    980 
    981     index = 0;
    982     offset = 2;
    983 
    984     while (index < num_masters) {
    985         bcm_ptp_foreign_master_entry_t *fm = &data_set->foreign_master[index];
    986 
    987         sal_memcpy(fm->port_identity.clock_identity, resp + offset, BCM_PTP_CLOCK_EUID_IEEE1588_SIZE);
    988         offset += BCM_PTP_CLOCK_EUID_IEEE1588_SIZE;
    989 
    990         fm->port_identity.port_number = _bcm_ptp_uint16_read(resp + offset);
    991         offset += 2;
    992 
    993         fm->address.addr_type = *(resp + offset);
    994         offset += 1;
    995 
    996         memcpy(&fm->address.address[0], resp + offset, BCM_PTP_MAX_NETW_ADDR_SIZE);
    997         offset += BCM_PTP_MAX_NETW_ADDR_SIZE;
    998 
    999         fm->clockClass = *(resp + offset++);
   1000         fm->grandmasterPriority1 = *(resp + offset++);
   1001         fm->grandmasterPriority2 = *(resp + offset++);
   1002 
   1003         fm->clockClass_window.min = *(resp + offset++);
   1004         fm->clockClass_window.max = *(resp + offset++);
   1005         fm->clockClass_window.fall_events = *(resp + offset++);
   1006         fm->clockClass_window.rise_events = *(resp + offset++);
   1007 
   1008         fm->ms_since_sync = _bcm_ptp_uint32_read(resp + offset);
   1009         offset += 4;
   1010 
   1011         fm->ms_since_sync_ts = _bcm_ptp_uint32_read(resp + offset);
   1012         offset += 4;
   1013 
   1014         fm->ms_since_del_resp = _bcm_ptp_uint32_read(resp + offset);
   1015         offset += 4;
   1016 
   1017         fm->announce_messages = _bcm_ptp_uint16_read(resp + offset);
   1018         offset += 2;
   1019 
   1020         fm->pdv_scaled_allan_var = _bcm_ptp_uint64_read(resp + offset);
   1021         offset += 8;
   1022 
   1023         fm->offset_scaled_log_variance = _bcm_ptp_uint16_read(resp + offset);
   1024         offset += 2;
   1025 
   1026         fm->clock_accuracy = *(resp + offset++);
   1027 
   1028         fm->steps_removed = _bcm_ptp_uint16_read(resp + offset);
   1029         offset += 2;
   1030 
   1031         sal_memcpy(fm->grandmaster_identity, resp+offset,
   1032                    sizeof(bcm_ptp_clock_identity_t));
   1033         offset += BCM_PTP_CLOCK_EUID_IEEE1588_SIZE;
   1034 
   1035         if (SOC_HAS_PTP_INTERNAL_STACK_SUPPORT(unit)) {
   1036             module_num = _bcm_ptp_uint16_read(resp + offset);
   1037             offset += 2;
   1038 
   1039             phy_port_num = _bcm_ptp_uint16_read(resp + offset);
   1040             offset += 2;
   1041 
   1042             BCM_GPORT_MODPORT_SET(fm->phy_port, module_num, phy_port_num);
   1043         }
   1044 
   1045         ++index;
   1046     }
   1047 
   1048     data_set->num_foreign_masters = num_masters;
   1049 
   1050     return rv;
   1051 }
   1052 
   1053 /*
   1054  * Function:
   1055  *      bcm_common_ptp_clock_priority1_get
   1056  * Purpose:
   1057  *      Get priority1 member of a PTP clock default dataset.
   1058  * Parameters:
   1059  *      unit      - (IN)  Unit number.
   1060  *      ptp_id    - (IN)  PTP stack ID.
   1061  *      clock_num - (IN)  PTP clock number.
   1062  *      priority1 - (OUT) PTP clock priority1.
   1063  * Returns:
   1064  *      BCM_E_XXX
   1065  * Notes:
   1066  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.3.2.
   1067  */
   1068 int
   1069 bcm_common_ptp_clock_priority1_get(
   1070     int unit,
   1071     bcm_ptp_stack_id_t ptp_id,
   1072     int clock_num,
   1073     uint32 *priority1)
   1074 {
   1075     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1076     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1077 
   1078     bcm_ptp_port_identity_t portid;
   1079 
   1080     BCM_IF_ERROR_RETURN(
   1081         _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1082                                    PTP_CLOCK_PORT_NUMBER_DEFAULT));
   1083 
   1084     BCM_IF_ERROR_RETURN(
   1085         bcm_common_ptp_clock_port_identity_get(unit, ptp_id, clock_num,
   1086                                             PTP_IEEE1588_ALL_PORTS, &portid));
   1087 
   1088     BCM_IF_ERROR_RETURN(
   1089         _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1090                                          PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_PRIORITY1,
   1091                                          0, 0, resp, &resp_len));
   1092 
   1093     /*
   1094      * Parse response.
   1095      *    Octet 0 : Priority1.
   1096      *    Octet 1 : Reserved.
   1097      */
   1098     *priority1 = resp[0];
   1099 
   1100     return BCM_E_NONE;
   1101 }
   1102 
   1103 /*
   1104  * Function:
   1105  *      bcm_common_ptp_clock_priority1_set
   1106  * Purpose:
   1107  *      Set priority1 member of a PTP clock default dataset.
   1108  * Parameters:
   1109  *      unit      - (IN) Unit number.
   1110  *      ptp_id    - (IN) PTP stack ID.
   1111  *      clock_num - (IN) PTP clock number.
   1112  *      priority1 - (IN) PTP clock priority1.
   1113  * Returns:
   1114  *      BCM_E_XXX
   1115  * Notes:
   1116  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.3.2.
   1117  */
   1118 int
   1119 bcm_common_ptp_clock_priority1_set(
   1120     int unit,
   1121     bcm_ptp_stack_id_t ptp_id,
   1122     int clock_num,
   1123     uint32 priority1)
   1124 {
   1125     int rv = BCM_E_UNAVAIL;
   1126 
   1127     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   1128     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1129     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1130 
   1131     bcm_ptp_clock_info_t ci;
   1132     bcm_ptp_port_identity_t portid;
   1133 
   1134     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1135             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1136         return rv;
   1137     }
   1138 
   1139     /* PTP attribute profile range checking. */
   1140     if (BCM_FAILURE(rv =
   1141             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   1142         LOG_ERROR(BSL_LS_BCM_COMMON,
   1143                   (BSL_META_U(unit,
   1144                               "_bcm_ptp_clock_cache_info_get failed\n")));
   1145         return rv;
   1146     }
   1147 
   1148     if ((priority1 < ci.priority1_minimum) ||
   1149             (priority1 > ci.priority1_maximum)) {
   1150         /*
   1151          * Caller provided priority1 value is not in (min,max) range of
   1152          * PTP profile.
   1153          */
   1154         return BCM_E_PARAM;
   1155     }
   1156 
   1157     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1158             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1159         return rv;
   1160     }
   1161 
   1162     /*
   1163      * Make payload.
   1164      *    Octet 0 : Priority1.
   1165      *    Octet 1 : Reserved.
   1166      */
   1167     payload[0] = (uint8)priority1;
   1168 
   1169     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1170             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_PRIORITY1,
   1171             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   1172             resp, &resp_len);
   1173 
   1174     /* Update PTP clock cache. */
   1175     if (rv == BCM_E_NONE) {
   1176         ci.priority1 = (uint8)priority1;
   1177         rv = _bcm_ptp_clock_cache_info_set(unit, ptp_id, clock_num, &ci);
   1178     }
   1179 
   1180     return rv;
   1181 }
   1182 
   1183 /*
   1184  * Function:
   1185  *      bcm_common_ptp_clock_priority2_get
   1186  * Purpose:
   1187  *      Get priority2 member of a PTP clock default dataset.
   1188  * Parameters:
   1189  *      unit      - (IN) Unit number.
   1190  *      ptp_id    - (IN) PTP stack ID.
   1191  *      clock_num - (IN) PTP clock number.
   1192  *      priority2 - (OUT) PTP clock priority2.
   1193  * Returns:
   1194  *      BCM_E_XXX
   1195  * Notes:
   1196  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.3.3.
   1197  */
   1198 int
   1199 bcm_common_ptp_clock_priority2_get(
   1200     int unit,
   1201     bcm_ptp_stack_id_t ptp_id,
   1202     int clock_num,
   1203     uint32 *priority2)
   1204 {
   1205     int rv = BCM_E_UNAVAIL;
   1206 
   1207     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1208     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1209 
   1210     bcm_ptp_port_identity_t portid;
   1211 
   1212     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1213             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1214         return rv;
   1215     }
   1216 
   1217     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1218             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1219         return rv;
   1220     }
   1221 
   1222     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1223             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_PRIORITY2,
   1224             0, 0, resp, &resp_len);
   1225 
   1226     if (rv == BCM_E_NONE) {
   1227         /*
   1228          * Parse response.
   1229          *    Octet 0 : Priority2.
   1230          *    Octet 1 : Reserved.
   1231          */
   1232         *priority2 = resp[0];
   1233     }
   1234 
   1235     return rv;
   1236 }
   1237 
   1238 /*
   1239  * Function:
   1240  *      bcm_common_ptp_clock_priority2_set
   1241  * Purpose:
   1242  *      Set priority2 member of a PTP clock default dataset.
   1243  * Parameters:
   1244  *      unit      - (IN) Unit number.
   1245  *      ptp_id    - (IN) PTP stack ID.
   1246  *      clock_num - (IN) PTP clock number.
   1247  *      priority2 - (IN) PTP clock priority2.
   1248  * Returns:
   1249  *      BCM_E_XXX
   1250  * Notes:
   1251  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.3.3.
   1252  */
   1253 int
   1254 bcm_common_ptp_clock_priority2_set(
   1255     int unit,
   1256     bcm_ptp_stack_id_t ptp_id,
   1257     int clock_num,
   1258     uint32 priority2)
   1259 {
   1260     int rv = BCM_E_UNAVAIL;
   1261 
   1262     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   1263     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1264     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1265 
   1266     bcm_ptp_clock_info_t ci;
   1267     bcm_ptp_port_identity_t portid;
   1268 
   1269     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1270             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1271         return rv;
   1272     }
   1273 
   1274     /* PTP attribute profile range checking. */
   1275     if (BCM_FAILURE(rv =
   1276             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   1277         LOG_ERROR(BSL_LS_BCM_COMMON,
   1278                   (BSL_META_U(unit,
   1279                               "_bcm_ptp_clock_cache_info_get failed\n")));
   1280         return rv;
   1281     }
   1282 
   1283     if ((priority2 < ci.priority2_minimum) ||
   1284             (priority2 > ci.priority2_maximum)) {
   1285         /*
   1286          * Caller provided priority2 value is not in (min,max) range of
   1287          * PTP profile.
   1288          */
   1289         return BCM_E_PARAM;
   1290     }
   1291 
   1292     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1293             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1294         return rv;
   1295     }
   1296 
   1297     /*
   1298      * Make payload.
   1299      *    Octet 0 : Priority2.
   1300      *    Octet 1 : Reserved.
   1301      */
   1302     payload[0] = (uint8)priority2;
   1303 
   1304     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1305             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_PRIORITY2,
   1306             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   1307             resp, &resp_len);
   1308 
   1309     /* Update PTP clock cache. */
   1310     if (rv == BCM_E_NONE) {
   1311         ci.priority2 = (uint8)priority2;
   1312         rv = _bcm_ptp_clock_cache_info_set(unit, ptp_id, clock_num, &ci);
   1313     }
   1314 
   1315     return rv;
   1316 }
   1317 
   1318 /*
   1319  * Function:
   1320  *      bcm_common_ptp_clock_local_priority_get
   1321  * Purpose:
   1322  *      Get local priority configured for a PTP clock.
   1323  * Parameters:
   1324  *      unit           - (IN) Unit number.
   1325  *      ptp_id         - (IN) PTP stack ID.
   1326  *      clock_num      - (IN) PTP clock number.
   1327  *      local_priority - (OUT) PTP clock local priority.
   1328  * Returns:
   1329  *      BCM_E_XXX
   1330  * Notes:
   1331  *      Ref. G8275.1 (Telecom phase profile), Chapters 6.3.1 and 6.3.2 
   1332  */
   1333 int
   1334 bcm_common_ptp_clock_local_priority_get(
   1335     int unit,
   1336     bcm_ptp_stack_id_t ptp_id,
   1337     int clock_num,
   1338     uint8 *local_priority)
   1339 {
   1340     int rv = BCM_E_UNAVAIL;
   1341 
   1342     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1343     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1344 
   1345     bcm_ptp_port_identity_t portid;
   1346 
   1347     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1348             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1349         return rv;
   1350     }
   1351 
   1352     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1353             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1354         return rv;
   1355     }
   1356 
   1357     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1358             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CLOCK_LOCAL_PRIORITY,
   1359             0, 0, resp, &resp_len);
   1360 
   1361     if (rv == BCM_E_NONE) {
   1362         /*
   1363          * Parse response.
   1364          *    Octet 0 : local priority.
   1365          *    Octet 1 : Reserved.
   1366          */
   1367         *local_priority = resp[0];
   1368     }
   1369 
   1370     return rv;
   1371 }
   1372 
   1373 /*
   1374  * Function:
   1375  *      bcm_common_ptp_clock_local_priority_set
   1376  * Purpose:
   1377  *      Set local priority for a PTP clock.
   1378  * Parameters:
   1379  *      unit           - (IN) Unit number.
   1380  *      ptp_id         - (IN) PTP stack ID.
   1381  *      clock_num      - (IN) PTP clock number.
   1382  *      local_priority - (IN) PTP clock local priority.
   1383  * Returns:
   1384  *      BCM_E_XXX
   1385  * Notes:
   1386  *      Ref. G8275.1 (Telecom phase profile), Chapters 6.3.1 and 6.3.2 
   1387  */
   1388 int
   1389 bcm_common_ptp_clock_local_priority_set(
   1390     int unit,
   1391     bcm_ptp_stack_id_t ptp_id,
   1392     int clock_num,
   1393     uint8 local_priority)
   1394 {
   1395     int rv = BCM_E_UNAVAIL;
   1396 
   1397     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   1398     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1399     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1400 
   1401     bcm_ptp_clock_info_t ci;
   1402     bcm_ptp_port_identity_t portid;
   1403 
   1404     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1405             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1406         return rv;
   1407     }
   1408 
   1409     /* PTP attribute profile range checking. */
   1410     if (BCM_FAILURE(rv =
   1411             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   1412         LOG_ERROR(BSL_LS_BCM_COMMON,
   1413                   (BSL_META_U(unit,
   1414                               "_bcm_ptp_clock_cache_info_get failed\n")));
   1415         return rv;
   1416     }
   1417 
   1418     if (local_priority == 0) {
   1419         /* local priority value should be in the range of PTP profile (1-255) */
   1420         return BCM_E_PARAM;
   1421     }
   1422 
   1423     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1424             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1425         return rv;
   1426     }
   1427 
   1428     /*
   1429      * Make payload.
   1430      *    Octet 0 : local priority.
   1431      *    Octet 1 : Reserved.
   1432      */
   1433     payload[0] = local_priority;
   1434 
   1435     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1436             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_LOCAL_PRIORITY,
   1437             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   1438             resp, &resp_len);
   1439 
   1440     /* Update PTP clock cache. */
   1441     if (rv == BCM_E_NONE) {
   1442         ci.local_priority = local_priority;
   1443         rv = _bcm_ptp_clock_cache_info_set(unit, ptp_id, clock_num, &ci);
   1444     }
   1445 
   1446     return rv;
   1447 }
   1448 
   1449 
   1450 /*
   1451  * Function:
   1452  *      bcm_common_ptp_clock_max_steps_removed_get
   1453  * Purpose:
   1454  *      Get maxStepsRemoved configured for the PTP clock.
   1455  * Parameters:
   1456  *      unit              - (IN) Unit number.
   1457  *      ptp_id            - (IN) PTP stack ID.
   1458  *      clock_num         - (IN) PTP clock number.
   1459  *      max_steps_removed - (OUT) PTP clock's maxStepsRemoved.
   1460  * Returns:
   1461  *      BCM_E_XXX
   1462  * Notes:
   1463  *      Ref. G8275.1 (Telecom phase profile), Annex-F
   1464  */
   1465 int
   1466 bcm_common_ptp_clock_max_steps_removed_get(
   1467     int unit,
   1468     bcm_ptp_stack_id_t ptp_id,
   1469     int clock_num,
   1470     uint8 *max_steps_removed)
   1471 {
   1472     int rv = BCM_E_UNAVAIL;
   1473 
   1474     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1475     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1476 
   1477     bcm_ptp_port_identity_t portid;
   1478 
   1479     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1480             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1481         return rv;
   1482     }
   1483 
   1484     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1485             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1486         return rv;
   1487     }
   1488 
   1489     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1490             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CLOCK_MAX_STEPS_REMOVED,
   1491             0, 0, resp, &resp_len);
   1492 
   1493     if (rv == BCM_E_NONE) {
   1494         /*
   1495          * Parse response.
   1496          *    Octet 0 : max_steps_removed.
   1497          *    Octet 1 : Reserved.
   1498          */
   1499         *max_steps_removed = resp[0];
   1500     }
   1501 
   1502     return rv;
   1503 }
   1504 
   1505 /*
   1506  * Function:
   1507  *      bcm_common_ptp_clock_max_steps_removed_set
   1508  * Purpose:
   1509  *      Set max steps removed for the PTP clock.
   1510  * Parameters:
   1511  *      unit              - (IN) Unit number.
   1512  *      ptp_id            - (IN) PTP stack ID.
   1513  *      clock_num         - (IN) PTP clock number.
   1514  *      max_steps_removed - (IN) max acceptable steps removed
   1515  * Returns:
   1516  *      BCM_E_XXX
   1517  * Notes:
   1518  *      Ref. G8275.1 (Telecom phase profile), Annex-F
   1519  */
   1520 int
   1521 bcm_common_ptp_clock_max_steps_removed_set(
   1522     int unit,
   1523     bcm_ptp_stack_id_t ptp_id,
   1524     int clock_num,
   1525     uint8 max_steps_removed)
   1526 {
   1527     int rv = BCM_E_UNAVAIL;
   1528 
   1529     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   1530     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1531     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1532 
   1533     bcm_ptp_clock_info_t ci;
   1534     bcm_ptp_port_identity_t portid;
   1535 
   1536     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1537             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1538         return rv;
   1539     }
   1540 
   1541     /* PTP attribute profile range checking. */
   1542     if (BCM_FAILURE(rv =
   1543             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   1544         LOG_ERROR(BSL_LS_BCM_COMMON,
   1545                   (BSL_META_U(unit,
   1546                               "_bcm_ptp_clock_cache_info_get failed\n")));
   1547         return rv;
   1548     }
   1549 
   1550     if (0 == max_steps_removed) {
   1551         /* maxStepsRemoved value should be in the range of (1-255) */
   1552         LOG_ERROR(BSL_LS_BCM_PTP,
   1553                   (BSL_META_U(unit,
   1554                               "maxStepsRemoved should be in the range of 1-255 \n")));
   1555         return BCM_E_PARAM;
   1556     }
   1557 
   1558     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1559             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1560         return rv;
   1561     }
   1562 
   1563     /*
   1564      * Make payload.
   1565      *    Octet 0 : max_steps_removed.
   1566      *    Octet 1 : Reserved.
   1567      */
   1568     payload[0] = max_steps_removed;
   1569 
   1570     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1571             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_MAX_STEPS_REMOVED,
   1572             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   1573             resp, &resp_len);
   1574 
   1575     /* Update PTP clock cache. */
   1576     if (rv == BCM_E_NONE) {
   1577         ci.max_steps_removed = max_steps_removed;
   1578         rv = _bcm_ptp_clock_cache_info_set(unit, ptp_id, clock_num, &ci);
   1579     }
   1580 
   1581     return rv;
   1582 }
   1583 
   1584 /*
   1585  * Function:
   1586  *      bcm_common_ptp_clock_peer_age_timer_get
   1587  * Purpose:
   1588  *      Get PTP clock slave aging time configured.
   1589  * Parameters:
   1590  *      unit           - (IN) Unit number.
   1591  *      ptp_id         - (IN) PTP stack ID.
   1592  *      clock_num      - (IN) PTP clock number.
   1593  *      aging_time     - (OUT) PTP slave aging time.
   1594  * Returns:
   1595  *      BCM_E_XXX
   1596  */
   1597 int
   1598 bcm_common_ptp_clock_peer_age_timer_get(
   1599     int unit,
   1600     bcm_ptp_stack_id_t ptp_id,
   1601     int clock_num,
   1602     uint8 *aging_time)
   1603 {
   1604     int rv = BCM_E_UNAVAIL;
   1605 
   1606     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1607     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1608 
   1609     bcm_ptp_port_identity_t portid;
   1610 
   1611     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1612             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1613         return rv;
   1614     }
   1615 
   1616     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1617             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1618         return rv;
   1619     }
   1620 
   1621     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1622             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CLOCK_PEER_AGE_TIMER,
   1623             0, 0, resp, &resp_len);
   1624 
   1625     if (rv == BCM_E_NONE) {
   1626         /*
   1627          * Parse response.
   1628          *    Octet 0   : aging_time.
   1629          *    Octet 1-7 : Reserved
   1630          */
   1631         *aging_time = resp[0];
   1632     }
   1633 
   1634     return rv;
   1635 }
   1636 
   1637 /*
   1638  * Function:
   1639  *      bcm_common_ptp_clock_peer_age_timer_set
   1640  * Purpose:
   1641  *      Set slave aging time for Peer
   1642  * Parameters:
   1643  *      unit           - (IN) Unit number.
   1644  *      ptp_id         - (IN) PTP stack ID.
   1645  *      clock_num      - (IN) PTP clock number.
   1646  *      aging_time - (IN) Peer aging time.
   1647  * Returns:
   1648  *      BCM_E_XXX
   1649  * Notes:
   1650  */
   1651 int
   1652 bcm_common_ptp_clock_peer_age_timer_set(
   1653     int unit,
   1654     bcm_ptp_stack_id_t ptp_id,
   1655     int clock_num,
   1656     uint8 aging_time)
   1657 {
   1658     int rv = BCM_E_UNAVAIL;
   1659 
   1660     uint8 payload[PTP_MGMTMSG_PAYLOAD_CLOCK_PEER_AGE_TIMER_SIZE_OCTETS] = {0};
   1661     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1662     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1663 
   1664     bcm_ptp_port_identity_t portid;
   1665 
   1666     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1667             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1668         return rv;
   1669     }
   1670 
   1671     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1672             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1673         return rv;
   1674     }
   1675 
   1676     /*
   1677      * Make payload.
   1678      *    Octet 0   : aging_time
   1679      *    Octet 1-7 : Reserved
   1680      */
   1681 
   1682      payload[0]= aging_time;
   1683 
   1684     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1685             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_PEER_AGE_TIMER,
   1686             payload, PTP_MGMTMSG_PAYLOAD_CLOCK_PEER_AGE_TIMER_SIZE_OCTETS,
   1687             resp, &resp_len);
   1688 
   1689     return rv;
   1690 }
   1691 
   1692 /*
   1693  * Function:
   1694  *      bcm_common_ptp_pkt_flags_override_get
   1695  * Purpose:
   1696  *      Get PTP clock Slave Anncounce Flags Override Setting configured.
   1697  * Parameters:
   1698  *      unit           - (IN) Unit number.
   1699  *      ptp_id         - (IN) PTP stack ID.
   1700  *      clock_num      - (IN) PTP clock number.
   1701  *      override_flag  - (OUT) Mask (1 - Override, 0 - NoOverRide)
   1702  *      override_value - (OUT) Value
   1703  * Returns:
   1704  *      BCM_E_XXX
   1705  */
   1706 int
   1707 bcm_common_ptp_pkt_flags_override_get(
   1708     int unit,
   1709     bcm_ptp_stack_id_t ptp_id,
   1710     int clock_num,
   1711     uint32 *override_flag,
   1712     uint32 *override_value)
   1713 {
   1714     int rv = BCM_E_UNAVAIL;
   1715 
   1716     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1717     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1718 
   1719     bcm_ptp_port_identity_t portid;
   1720 
   1721     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1722             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1723         return rv;
   1724     }
   1725 
   1726     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1727             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1728         return rv;
   1729     }
   1730 
   1731     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1732             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CLOCK_FLAG_FIELD_OVERRIDE,
   1733             0, 0, resp, &resp_len);
   1734 
   1735     if (rv == BCM_E_NONE) {
   1736         /*
   1737          * Parse response.
   1738          *    Octet 0-1   : mask.
   1739          *    Octet 2-3 : value
   1740          */
   1741         *override_flag = _bcm_ptp_uint32_read(resp);
   1742         *override_value = _bcm_ptp_uint32_read(resp+4);
   1743     }
   1744 
   1745     return rv;
   1746 }
   1747 
   1748 /*
   1749  * Function:
   1750  *      bcm_common_ptp_pkt_flags_override_set
   1751  * Purpose:
   1752  *      Set slave aging time for Peer
   1753  * Parameters:
   1754  *      unit           - (IN) Unit number.
   1755  *      ptp_id         - (IN) PTP stack ID.
   1756  *      clock_num      - (IN) PTP clock number.
   1757  *      override_flag     - (IN) Mask
   1758  *      override_value    - (IN) Value
   1759  * Returns:
   1760  *      BCM_E_XXX
   1761  * Notes:
   1762  */
   1763 int
   1764 bcm_common_ptp_pkt_flags_override_set(
   1765     int unit,
   1766     bcm_ptp_stack_id_t ptp_id,
   1767     int clock_num,
   1768     uint32 override_flag,
   1769     uint32 override_value)
   1770 {
   1771     int rv = BCM_E_UNAVAIL;
   1772 
   1773     uint8 payload[PTP_MGMTMSG_PAYLOAD_CLOCK_FLAG_FIELD_OVERRIDE_SIZE_OCTETS] = {0};
   1774     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1775     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1776 
   1777     bcm_ptp_port_identity_t portid;
   1778 
   1779     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1780             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1781         return rv;
   1782     }
   1783 
   1784     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1785             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1786         return rv;
   1787     }
   1788 
   1789     /*
   1790      * Make payload.
   1791      *    Octet 0-1   : mask.
   1792      *    Octet 2-3 : Value
   1793      */
   1794 
   1795     _bcm_ptp_uint32_write(payload, override_flag);
   1796     _bcm_ptp_uint32_write(payload+4, override_value);
   1797 
   1798     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1799             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_FLAG_FIELD_OVERRIDE,
   1800             payload, PTP_MGMTMSG_PAYLOAD_CLOCK_FLAG_FIELD_OVERRIDE_SIZE_OCTETS,
   1801             resp, &resp_len);
   1802 
   1803     return rv;
   1804 }
   1805 
   1806 /*
   1807  * Function:
   1808  *      bcm_common_ptp_clock_domain_get
   1809  * Purpose:
   1810  *      Get PTP domain member of a PTP clock default dataset.
   1811  * Parameters:
   1812  *      unit      - (IN)  Unit number.
   1813  *      ptp_id    - (IN)  PTP stack ID.
   1814  *      clock_num - (IN)  PTP clock number.
   1815  *      domain    - (OUT) PTP clock domain.
   1816  * Returns:
   1817  *      BCM_E_XXX
   1818  * Notes:
   1819  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.3.4.
   1820  */
   1821 int
   1822 bcm_common_ptp_clock_domain_get(
   1823     int unit,
   1824     bcm_ptp_stack_id_t ptp_id,
   1825     int clock_num,
   1826     uint32 *domain)
   1827 {
   1828     int rv = BCM_E_UNAVAIL;
   1829 
   1830     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1831     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1832 
   1833     bcm_ptp_port_identity_t portid;
   1834 
   1835     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1836             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1837         return rv;
   1838     }
   1839 
   1840     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1841             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1842         return rv;
   1843     }
   1844 
   1845     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1846             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_DOMAIN,
   1847             0, 0, resp, &resp_len);
   1848 
   1849     if (rv == BCM_E_NONE) {
   1850         /*
   1851          * Parse response.
   1852          *    Octet 0 : PTP domain.
   1853          *    Octet 1 : Reserved.
   1854          */
   1855         *domain = resp[0];
   1856     }
   1857 
   1858     return rv;
   1859 }
   1860 
   1861 /*
   1862  * Function:
   1863  *      bcm_common_ptp_clock_domain_set
   1864  * Purpose:
   1865  *      Set PTP domain member of a PTP clock default dataset.
   1866  * Parameters:
   1867  *      unit      - (IN) Unit number.
   1868  *      ptp_id    - (IN) PTP stack ID.
   1869  *      clock_num - (IN) PTP clock number.
   1870  *      domain    - (IN) PTP clock domain.
   1871  * Returns:
   1872  *      BCM_E_XXX
   1873  * Notes:
   1874  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.3.4.
   1875  */
   1876 int
   1877 bcm_common_ptp_clock_domain_set(
   1878     int unit,
   1879     bcm_ptp_stack_id_t ptp_id,
   1880     int clock_num,
   1881     uint32 domain)
   1882 {
   1883     int rv = BCM_E_UNAVAIL;
   1884 
   1885     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   1886     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1887     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1888 
   1889     bcm_ptp_clock_info_t ci;
   1890     bcm_ptp_port_identity_t portid;
   1891 
   1892     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1893             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1894         return rv;
   1895     }
   1896 
   1897     /* PTP attribute profile range checking. */
   1898     if (BCM_FAILURE(rv =
   1899             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   1900         LOG_ERROR(BSL_LS_BCM_COMMON,
   1901                   (BSL_META_U(unit,
   1902                               "_bcm_ptp_clock_cache_info_get failed\n")));
   1903         return rv;
   1904     }
   1905 
   1906     if ((domain < ci.domain_number_minimum) ||
   1907             (domain > ci.domain_number_maximum)) {
   1908         /*
   1909          * Caller provided PTP domain value is not in (min,max) range of
   1910          * PTP profile.
   1911          */
   1912         return BCM_E_PARAM;
   1913     }
   1914 
   1915     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1916             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1917         return rv;
   1918     }
   1919 
   1920     /* Make payload.
   1921      *    Octet 0 : PTP domain.
   1922      *    Octet 1 : Reserved.
   1923      */
   1924     payload[0] = (uint8)domain;
   1925 
   1926     if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id,
   1927             clock_num, &portid, PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_DOMAIN,
   1928             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS, resp, &resp_len))) {
   1929             return rv;
   1930     }
   1931 
   1932     /* Remove signaled slaves. */
   1933     if (BCM_FAILURE(rv = bcm_common_ptp_signaled_unicast_slave_table_clear(unit, ptp_id,
   1934             clock_num, PTP_IEEE1588_ALL_PORTS, 0))) {
   1935         LOG_ERROR(BSL_LS_BCM_COMMON,
   1936                   (BSL_META_U(unit,
   1937                               "bcm_common_ptp_signaled_unicast_slave_table_clear failed\n")));
   1938         return rv;
   1939     }
   1940 
   1941     /* Remove static slaves. */
   1942     if (BCM_FAILURE(rv = _bcm_ptp_unicast_slave_host_reset(unit, ptp_id,
   1943             clock_num, PTP_IEEE1588_ALL_PORTS))) {
   1944         LOG_ERROR(BSL_LS_BCM_COMMON,
   1945                   (BSL_META_U(unit,
   1946                               "_bcm_ptp_unicast_slave_host_reset failed\n")));
   1947         return rv;
   1948     }
   1949 
   1950     /*
   1951      * Register domain with PTP management framework.
   1952      * Ensure subsequent management messages are configured with proper
   1953      * domain.
   1954      */
   1955     if (BCM_FAILURE(rv = _bcm_ptp_management_domain_set(unit, ptp_id,
   1956             clock_num, domain))) {
   1957         return rv;
   1958     }
   1959 
   1960     /* Update PTP clock cache. */
   1961     ci.domain_number = (uint8)domain;
   1962     rv = _bcm_ptp_clock_cache_info_set(unit, ptp_id, clock_num, &ci);
   1963 
   1964     return rv;
   1965 }
   1966 
   1967 /*
   1968  * Function:
   1969  *      bcm_common_ptp_clock_slaveonly_get
   1970  * Purpose:
   1971  *      Get slave-only (SO) flag of a PTP clock default dataset.
   1972  * Parameters:
   1973  *      unit      - (IN)  Unit number.
   1974  *      ptp_id    - (IN)  PTP stack ID.
   1975  *      clock_num - (IN)  PTP clock number.
   1976  *      slaveonly - (OUT) PTP clock slave-only (SO) flag.
   1977  * Returns:
   1978  *      BCM_E_XXX
   1979  * Notes:
   1980  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.3.5.
   1981  */
   1982 int
   1983 bcm_common_ptp_clock_slaveonly_get(
   1984     int unit,
   1985     bcm_ptp_stack_id_t ptp_id,
   1986     int clock_num,
   1987     uint32 *slaveonly)
   1988 {
   1989     int rv = BCM_E_UNAVAIL;
   1990 
   1991     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1992     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1993 
   1994     bcm_ptp_port_identity_t portid;
   1995 
   1996     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1997             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1998         return rv;
   1999     }
   2000 
   2001     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2002             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2003         return rv;
   2004     }
   2005 
   2006     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2007             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_SLAVE_ONLY,
   2008             0, 0, resp, &resp_len);
   2009 
   2010     if (rv == BCM_E_NONE) {
   2011         /*
   2012          * Parse response.
   2013          *    Octet 0 : Slave-only (SO) Boolean.
   2014          *              |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|0|0|0|0|0|SO|.
   2015          *    Octet 1 : Reserved.
   2016          */
   2017         *slaveonly = (0x01 & resp[0]);
   2018     }
   2019 
   2020     return rv;
   2021 }
   2022 
   2023 /*
   2024  * Function:
   2025  *      bcm_common_ptp_clock_slaveonly_set
   2026  * Purpose:
   2027  *      Set slave-only (SO) flag of a PTP clock default dataset.
   2028  * Parameters:
   2029  *      unit      - (IN) Unit number.
   2030  *      ptp_id    - (IN) PTP stack ID.
   2031  *      clock_num - (IN) PTP clock number.
   2032  *      slaveonly - (IN) PTP clock slave-only (SO) flag.
   2033  * Returns:
   2034  *      BCM_E_XXX
   2035  * Notes:
   2036  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.3.5.
   2037  */
   2038 int
   2039 bcm_common_ptp_clock_slaveonly_set(
   2040     int unit,
   2041     bcm_ptp_stack_id_t ptp_id,
   2042     int clock_num,
   2043     uint32 slaveonly)
   2044 {
   2045     int rv = BCM_E_UNAVAIL;
   2046 
   2047     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   2048     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2049     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2050 
   2051     bcm_ptp_clock_info_t ci;
   2052     bcm_ptp_port_identity_t portid;
   2053 
   2054     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2055             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2056         return rv;
   2057     }
   2058 
   2059     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2060             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2061         return rv;
   2062     }
   2063 
   2064     /*
   2065      * Make payload.
   2066      *    Octet 0 : Slave-only (SO) Boolean.
   2067      *              |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|0|0|0|0|0|SO|.
   2068      *    Octet 1 : Reserved.
   2069      */
   2070     payload[0] = (uint8)(1 & slaveonly);
   2071 
   2072     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2073             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_SLAVE_ONLY,
   2074             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   2075             resp, &resp_len);
   2076 
   2077     /* Update PTP clock cache. */
   2078     if (rv == BCM_E_NONE) {
   2079         if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_info_get(unit, ptp_id,
   2080                 clock_num, &ci))) {
   2081             LOG_ERROR(BSL_LS_BCM_COMMON,
   2082                       (BSL_META_U(unit,
   2083                                   "_bcm_ptp_clock_cache_info_get failed\n")));
   2084             return rv;
   2085         }
   2086 
   2087         ci.slaveonly = (uint8)(1 & slaveonly);
   2088         rv = _bcm_ptp_clock_cache_info_set(unit, ptp_id, clock_num, &ci);
   2089     }
   2090 
   2091     return rv;
   2092 }
   2093 
   2094 /*
   2095  * Function:
   2096  *      bcm_common_ptp_clock_accuracy_get
   2097  * Purpose:
   2098  *      Get clock quality, clock accuracy member of a PTP clock default dataset.
   2099  * Parameters:
   2100  *      unit      - (IN)  Unit number.
   2101  *      ptp_id    - (IN)  PTP stack ID.
   2102  *      clock_num - (IN)  PTP clock number.
   2103  *      accuracy  - (OUT) PTP clock accuracy.
   2104  * Returns:
   2105  *      BCM_E_XXX
   2106  * Notes:
   2107  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.2.2.
   2108  */
   2109 int
   2110 bcm_common_ptp_clock_accuracy_get(
   2111     int unit,
   2112     bcm_ptp_stack_id_t ptp_id,
   2113     int clock_num,
   2114     bcm_ptp_clock_accuracy_t *accuracy)
   2115 {
   2116     int rv = BCM_E_UNAVAIL;
   2117 
   2118     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2119     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2120 
   2121     bcm_ptp_port_identity_t portid;
   2122 
   2123     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2124             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2125         return rv;
   2126     }
   2127 
   2128     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2129             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2130         return rv;
   2131     }
   2132 
   2133     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2134             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CLOCK_ACCURACY,
   2135             0, 0, resp, &resp_len);
   2136 
   2137     if (rv == BCM_E_NONE) {
   2138         /*
   2139          * Parse response.
   2140          *    Octet 0 : PTP clock accuracy.
   2141          *    Octet 1 : Reserved.
   2142          */
   2143         *accuracy = (bcm_ptp_clock_accuracy_t)resp[0];
   2144     }
   2145 
   2146     return rv;
   2147 }
   2148 
   2149 /*
   2150  * Function:
   2151  *      bcm_common_ptp_clock_accuracy_set
   2152  * Purpose:
   2153  *      Set clock quality, clock accuracy member of a PTP clock default dataset.
   2154  * Parameters:
   2155  *      unit      - (IN) Unit number.
   2156  *      ptp_id    - (IN) PTP stack ID.
   2157  *      clock_num - (IN) PTP clock number.
   2158  *      accuracy  - (IN) PTP clock accuracy.
   2159  * Returns:
   2160  *      BCM_E_XXX
   2161  * Notes:
   2162  *      Function applies to a grandmaster node only.
   2163  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1 and 15.5.3.2.2.
   2164  */
   2165 int
   2166 bcm_common_ptp_clock_accuracy_set(
   2167     int unit,
   2168     bcm_ptp_stack_id_t ptp_id,
   2169     int clock_num,
   2170     bcm_ptp_clock_accuracy_t *accuracy)
   2171 {
   2172     int rv = BCM_E_UNAVAIL;
   2173 
   2174     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   2175     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2176     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2177 
   2178     bcm_ptp_port_identity_t portid;
   2179 
   2180     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2181             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2182         return rv;
   2183     }
   2184 
   2185     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2186             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2187         return rv;
   2188     }
   2189 
   2190     /*
   2191      * Make payload.
   2192      *    Octet 0 : PTP clock accuracy.
   2193      *    Octet 1 : Reserved.
   2194      */
   2195     payload[0] = (uint8)(*accuracy);
   2196 
   2197     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2198             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_ACCURACY,
   2199             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   2200             resp, &resp_len);
   2201 
   2202     return rv;
   2203 }
   2204 
   2205 /*
   2206  * Function:
   2207  *      bcm_common_ptp_clock_quality_get
   2208  * Purpose:
   2209  *      Get clock quality of a PTP clock default dataset.
   2210  * Parameters:
   2211  *      unit      - (IN)  Unit number.
   2212  *      ptp_id    - (IN)  PTP stack ID.
   2213  *      clock_num - (IN)  PTP clock number.
   2214  *      *clock_quality - (OUT) PTP clock quality
   2215  *      flags - (IN) identify fields of bcm_ptp_clock_quality_t to get 
   2216  * Returns:
   2217  *      BCM_E_XXX
   2218  * Notes:
   2219  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1.3.1
   2220  */
   2221 int
   2222 bcm_common_ptp_clock_quality_get(
   2223     int unit,
   2224     bcm_ptp_stack_id_t ptp_id,
   2225     int clock_num,
   2226     bcm_ptp_clock_quality_t *clock_quality,
   2227     uint32 flags)
   2228 {
   2229     int rv = BCM_E_UNAVAIL;
   2230 
   2231     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2232     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2233 
   2234     bcm_ptp_port_identity_t portid;
   2235 
   2236     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2237             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2238         return rv;
   2239     }
   2240 
   2241     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2242             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2243         return rv;
   2244     }
   2245 
   2246     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2247             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CLOCK_QUALITY,
   2248             0, 0, resp, &resp_len);
   2249 
   2250     if (rv == BCM_E_NONE) {
   2251         /*
   2252          * Parse response.
   2253          *    Octet 0   : PTP clock class.
   2254          *    Octet 1   : PTP clock accuracy.
   2255          *    Octet 2-3 : offset scaled log variance.
   2256          *    Octet 4-7 : Reserved
   2257          */
   2258 
   2259         if (BCM_PTP_CLOCK_QUALITY_CLASS & flags) {
   2260             clock_quality->clock_class = (uint8)resp[0];
   2261         }
   2262         if (BCM_PTP_CLOCK_QUALITY_ACCURACY & flags) {
   2263             clock_quality->clock_accuracy = (bcm_ptp_clock_accuracy_t)resp[1];
   2264         }
   2265         if (BCM_PTP_CLOCK_QUALITY_OFFSET_SCALED_LOG_VARIANCE & flags) {
   2266             clock_quality->offset_scaled_log_variance = _bcm_ptp_uint16_read(resp+2);
   2267         }
   2268     }
   2269 
   2270     return rv;
   2271 }
   2272 
   2273 /*
   2274  * Function:
   2275  *      bcm_common_ptp_clock_quality_set
   2276  * Purpose:
   2277  *      Sets clock quality of a PTP clock default dataset.
   2278  * Parameters:
   2279  *      unit      - (IN)  Unit number.
   2280  *      ptp_id    - (IN)  PTP stack ID.
   2281  *      clock_num - (IN)  PTP clock number.
   2282  *      clock_quality - (IN) PTP clock quality
   2283  *      flags - (IN) identify fields of bcm_ptp_clock_quality_t to set
   2284  * Returns:
   2285  *      BCM_E_XXX
   2286  * Notes:
   2287  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.1.3.1
   2288  */
   2289 int
   2290 bcm_common_ptp_clock_quality_set(
   2291     int unit,
   2292     bcm_ptp_stack_id_t ptp_id,
   2293     int clock_num,
   2294     bcm_ptp_clock_quality_t clock_quality,
   2295     uint32 flags)
   2296 {
   2297     int rv = BCM_E_UNAVAIL;
   2298 
   2299     uint8 payload[PTP_MGMTMSG_PAYLOAD_CLOCK_QUALITY_MSG_SIZE_OCTETS] = {0};
   2300     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2301     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2302 
   2303     bcm_ptp_port_identity_t portid;
   2304 
   2305     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2306             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2307         return rv;
   2308     }
   2309 
   2310     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2311             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2312         return rv;
   2313     }
   2314 
   2315     /*
   2316      * Make payload.
   2317      *    Octet 0   : flags (indicates fw about the fields being configured)
   2318      *    Octet 1   : PTP clock class.
   2319      *    Octet 2   : PTP clock accuracy.
   2320      *    Octet 3-4 : offset scaled log variance.
   2321      *    Octet 5-7 : Reserved
   2322      */
   2323 
   2324      payload[0]= (uint8) flags;
   2325      payload[1]= clock_quality.clock_class;
   2326      payload[2] = (uint8) clock_quality.clock_accuracy;
   2327      _bcm_ptp_uint16_write(payload+3, clock_quality.offset_scaled_log_variance);
   2328 
   2329     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2330             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_QUALITY,
   2331             payload, PTP_MGMTMSG_PAYLOAD_CLOCK_QUALITY_MSG_SIZE_OCTETS,
   2332             resp, &resp_len);
   2333 
   2334     return rv;
   2335 }
   2336 
   2337 /*
   2338  * Function:
   2339  *      bcm_common_ptp_g8275p1_traceability_info_clock_class_map
   2340  * Purpose:
   2341  *      Sets clock quality of a PTP clock default dataset.
   2342  * Parameters:
   2343  *      unit      - (IN)  Unit number.
   2344  *      ptp_id    - (IN)  PTP stack ID.
   2345  *      clock_num - (IN)  PTP clock number.
   2346  *      clock_quality - (IN) PTP clock quality
   2347  *      flags - (IN) identify fields of bcm_ptp_clock_quality_t to set
   2348  * Returns:
   2349  *      BCM_E_XXX
   2350  * Notes:
   2351  *      Ref. ITU-T G8275.1 telecom phase profile Table.2 Section6.4
   2352  */
   2353 int
   2354 bcm_common_ptp_g8275p1_traceability_info_clock_class_map(
   2355     int unit,
   2356     bcm_ptp_stack_id_t ptp_id,
   2357     int clock_num,
   2358     bcm_ptp_g8275p1_clock_traceability_info_t traceability_info,
   2359     uint8 *clock_class)
   2360 {
   2361     int rv = BCM_E_PARAM;
   2362 
   2363     bcm_ptp_port_identity_t portid;
   2364     uint8 source_category=0;
   2365 
   2366     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2367             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2368         return rv;
   2369     }
   2370 
   2371     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2372             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2373         return rv;
   2374     }
   2375 
   2376     if (traceability_info.clock_type == bcmPtpG8275P1ClockTypeTelecomTSC)
   2377     {
   2378         *clock_class = 255;
   2379         return BCM_E_NONE;
   2380     }
   2381 
   2382     /* map the received quality level to category of freq source
   2383     as defined in ITU-T G8275.1 spec (Table.3 Section 6.4) */
   2384     switch (traceability_info.ql)
   2385     {
   2386         case bcmPtpG8275P1QlOptIPrc:
   2387         case bcmPtpG8275P1QlOptIIPrs:
   2388             source_category = 0x1;
   2389             break;
   2390         case bcmPtpG8275P1QlOptISsua:
   2391         case bcmPtpG8275P1QlOptIISt2:
   2392             source_category = 0x2;
   2393             break;
   2394         case bcmPtpG8275P1QlOptISsub:
   2395         case bcmPtpG8275P1QlOptIISt3e:
   2396             source_category = 0x3;
   2397             break;
   2398         default:
   2399             source_category = 0x0;
   2400     }
   2401 
   2402     switch(traceability_info.clock_state)
   2403     {
   2404         case bcmPtpG8275P1ClockStateFreeRun:
   2405             *clock_class = 248;
   2406             rv = BCM_E_NONE;
   2407             break;
   2408         case bcmPtpG8275P1ClockStateLocked:
   2409             if (traceability_info.clock_type == bcmPtpG8275P1ClockTypeTelecomGM &&
   2410                 traceability_info.ql == bcmPtpG8275P1QlOptIPrc &&
   2411                 traceability_info.freq_traceable) {
   2412                 *clock_class = 6;
   2413                 rv = BCM_E_NONE;
   2414             }
   2415             break;
   2416         case bcmPtpG8275P1ClockStateHoldoverInSpec:
   2417             if ((source_category == 0x1 && traceability_info.freq_traceable) ||
   2418                 (source_category != 0x1 && (traceability_info.freq_traceable == 0))) {
   2419                 if( traceability_info.clock_type == bcmPtpG8275P1ClockTypeTelecomGM) {
   2420                     *clock_class = 7;
   2421                     rv = BCM_E_NONE;
   2422                 }
   2423                 else if( traceability_info.clock_type == bcmPtpG8275P1ClockTypeTelecomBC) {
   2424                     *clock_class = 135;
   2425                     rv = BCM_E_NONE;
   2426                 }
   2427             }
   2428             break;
   2429         case bcmPtpG8275P1ClockStateHoldoverOutOfSpec:
   2430             if (traceability_info.clock_type == bcmPtpG8275P1ClockTypeTelecomBC) {
   2431                 *clock_class = 165;
   2432                 rv = BCM_E_NONE;
   2433             }
   2434             else if (traceability_info.clock_type == bcmPtpG8275P1ClockTypeTelecomGM) {
   2435                 if (source_category == 0x1 && traceability_info.freq_traceable) {
   2436                     *clock_class = 140;
   2437                     rv = BCM_E_NONE;
   2438                 }
   2439                 else if (source_category == 0x2 && (traceability_info.freq_traceable == 0)) {
   2440                     *clock_class = 150;
   2441                     rv = BCM_E_NONE;
   2442                 }
   2443                 else if (source_category == 0x3 && (traceability_info.freq_traceable == 0)) {
   2444                     *clock_class = 160;
   2445                     rv = BCM_E_NONE;
   2446                 }
   2447             }
   2448             break;
   2449         default:
   2450             return BCM_E_PARAM;
   2451     }
   2452 
   2453     return rv;
   2454 }
   2455 
   2456 /*
   2457  * Function:
   2458  *      bcm_common_ptp_clock_timescale_get
   2459  * Purpose:
   2460  *      Get timescale members of a PTP clock time properties dataset.
   2461  * Parameters:
   2462  *      unit      - (IN)  Unit number.
   2463  *      ptp_id    - (IN)  PTP stack ID.
   2464  *      clock_num - (IN)  PTP clock number.
   2465  *      timescale - (OUT) PTP clock timescale properties.
   2466  * Returns:
   2467  *      BCM_E_XXX
   2468  * Notes:
   2469  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.6.4.
   2470  */
   2471 int
   2472 bcm_common_ptp_clock_timescale_get(
   2473     int unit,
   2474     bcm_ptp_stack_id_t ptp_id,
   2475     int clock_num,
   2476     bcm_ptp_timescale_t *timescale)
   2477 {
   2478     int rv = BCM_E_UNAVAIL;
   2479 
   2480     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2481     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2482 
   2483     bcm_ptp_port_identity_t portid;
   2484 
   2485     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2486             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2487         return rv;
   2488     }
   2489 
   2490     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2491             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2492         return rv;
   2493     }
   2494 
   2495     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2496             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_TIMESCALE_PROPERTIES,
   2497             0, 0, resp, &resp_len);
   2498 
   2499     if (rv == BCM_E_NONE) {
   2500         /*
   2501          * Parse response.
   2502          *    Octet 0 : PTP timescale Boolean.
   2503          *              |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|0|0|PTP|0|0|0|.
   2504          *    Octet 1 : Time source.
   2505          */
   2506         timescale->ptp_timescale = ((0x08 & resp[0]) >> 3);
   2507         timescale->time_source = (bcm_ptp_time_source_t)resp[1];
   2508     }
   2509 
   2510     return rv;
   2511 }
   2512 
   2513 /*
   2514  * Function:
   2515  *      bcm_common_ptp_clock_timescale_set
   2516  * Purpose:
   2517  *      Set timescale members of a PTP clock time properties dataset.
   2518  * Parameters:
   2519  *      unit      - (IN) Unit number.
   2520  *      ptp_id    - (IN) PTP stack ID.
   2521  *      clock_num - (IN) PTP clock number.
   2522  *      timescale - (IN) PTP clock timescale properties.
   2523  * Returns:
   2524  *      BCM_E_XXX
   2525  * Notes:
   2526  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.6.4.
   2527  */
   2528 int
   2529 bcm_common_ptp_clock_timescale_set(
   2530     int unit,
   2531     bcm_ptp_stack_id_t ptp_id,
   2532     int clock_num,
   2533     bcm_ptp_timescale_t *timescale)
   2534 {
   2535     int rv = BCM_E_UNAVAIL;
   2536 
   2537     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   2538     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2539     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2540 
   2541     bcm_ptp_port_identity_t portid;
   2542 
   2543     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2544             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2545         return rv;
   2546     }
   2547 
   2548     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2549             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2550         return rv;
   2551     }
   2552 
   2553     /*
   2554      * Make payload.
   2555      *    Octet 0 : PTP timescale Boolean.
   2556      *              |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|0|0|PTP|0|0|0|.
   2557      *    Octet 1 : Time source.
   2558      */
   2559     payload[0] = ((0x01 & timescale->ptp_timescale) << 3);
   2560     payload[1] = (uint8)(timescale->time_source);
   2561 
   2562     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2563             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_TIMESCALE_PROPERTIES,
   2564             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   2565             resp, &resp_len);
   2566 
   2567     return rv;
   2568 }
   2569 
   2570 /*
   2571  * Function:
   2572  *      bcm_common_ptp_clock_traceability_get
   2573  * Purpose:
   2574  *      Get traceability members of a PTP clock time properties dataset.
   2575  * Parameters:
   2576  *      unit      - (IN)  Unit number.
   2577  *      ptp_id    - (IN)  PTP stack ID.
   2578  *      clock_num - (IN)  PTP clock number.
   2579  *      trace     - (OUT) PTP clock traceability properties.
   2580  * Returns:
   2581  *      BCM_E_XXX
   2582  * Notes:
   2583  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.6.3.
   2584  */
   2585 int
   2586 bcm_common_ptp_clock_traceability_get(
   2587     int unit,
   2588     bcm_ptp_stack_id_t ptp_id,
   2589     int clock_num,
   2590     bcm_ptp_trace_t *trace)
   2591 {
   2592     int rv = BCM_E_UNAVAIL;
   2593 
   2594     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2595     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2596 
   2597     bcm_ptp_port_identity_t portid;
   2598 
   2599     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2600             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2601         return rv;
   2602     }
   2603 
   2604     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2605             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2606         return rv;
   2607     }
   2608 
   2609     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2610             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_TRACEABILITY_PROPERTIES,
   2611             0, 0, resp, &resp_len);
   2612 
   2613     if (rv == BCM_E_NONE) {
   2614         /*
   2615          * Parse response.
   2616          *    Octet 0 : Time traceable (TTRA) and frequency traceable (FTRA) Booleans.
   2617          *              |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|FTRA|TTRA|0|0|0|0|.
   2618          *    Octet 1 : Reserved.
   2619          */
   2620         trace->time_traceable = ((0x10 & resp[0]) >> 4);
   2621         trace->frequency_traceable = ((0x20 & resp[0]) >> 5);
   2622     }
   2623 
   2624     return rv;
   2625 }
   2626 
   2627 /*
   2628  * Function:
   2629  *      bcm_common_ptp_clock_traceability_set
   2630  * Purpose:
   2631  *      Set traceability members of a PTP clock time properties dataset.
   2632  * Parameters:
   2633  *      unit      - (IN) Unit number.
   2634  *      ptp_id    - (IN) PTP stack ID.
   2635  *      clock_num - (IN) PTP clock number.
   2636  *      trace     - (IN) PTP clock traceability properties.
   2637  * Returns:
   2638  *      BCM_E_XXX
   2639  * Notes:
   2640  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.6.3.
   2641  */
   2642 int
   2643 bcm_common_ptp_clock_traceability_set(
   2644     int unit,
   2645     bcm_ptp_stack_id_t ptp_id,
   2646     int clock_num,
   2647     bcm_ptp_trace_t *trace)
   2648 {
   2649     int rv = BCM_E_UNAVAIL;
   2650 
   2651     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   2652     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2653     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2654 
   2655     bcm_ptp_port_identity_t portid;
   2656 
   2657     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2658             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2659         return rv;
   2660     }
   2661 
   2662     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2663             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2664         return rv;
   2665     }
   2666     
   2667     /*
   2668      * Make payload.
   2669      *    Octet 0 : Time traceable (TTRA) and frequency traceable (FTRA) Booleans.
   2670      *              |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|FTRA|TTRA|0|0|0|0|.
   2671      *    Octet 1 :  B0 = NO_OVERRIDE
   2672      */
   2673     if (trace->time_traceable == BCM_PTP_TRACEABILITY_NO_OVERRIDE
   2674                && trace->frequency_traceable == BCM_PTP_TRACEABILITY_NO_OVERRIDE) {
   2675         /* Over Ride Clear Flag Set */
   2676         payload[1]= ((0x01 & trace->time_traceable) << 0) +
   2677                         ((0x01 & trace->check_trc_flag_enable) << 1);
   2678 
   2679     } else if (((trace->frequency_traceable == 0 && trace->time_traceable == 0)  ||
   2680                 (trace->frequency_traceable == 0 && trace->time_traceable == 1) ||
   2681                 (trace->frequency_traceable == 1 && trace->time_traceable == 0) ||
   2682                 (trace->frequency_traceable == 1 && trace->time_traceable == 1))) {
   2683 
   2684         payload[0]= ((0x01 & trace->time_traceable) << 4) +
   2685                     ((0x01 & trace->frequency_traceable) << 5);
   2686     } else {
   2687         return BCM_E_PARAM;
   2688     }
   2689 
   2690     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2691             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_TRACEABILITY_PROPERTIES,
   2692             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   2693             resp, &resp_len);
   2694 
   2695     return rv;
   2696 }
   2697 
   2698 /*
   2699  * Function:
   2700  *      bcm_common_ptp_clock_utc_get
   2701  * Purpose:
   2702  *      Get UTC members of a PTP clock time properties dataset.
   2703  * Parameters:
   2704  *      unit      - (IN)  Unit number.
   2705  *      ptp_id    - (IN)  PTP Stack ID
   2706  *      clock_num - (IN)  PTP Clock Number
   2707  *      utc       - (OUT) PTP clock coordinated universal time (UTC) properties.
   2708  * Returns:
   2709  *      BCM_E_XXX
   2710  * Notes:
   2711  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.6.2.
   2712  */
   2713 int
   2714 bcm_common_ptp_clock_utc_get(
   2715     int unit,
   2716     bcm_ptp_stack_id_t ptp_id,
   2717     int clock_num,
   2718     bcm_ptp_utc_t *utc)
   2719 {
   2720     int rv = BCM_E_UNAVAIL;
   2721 
   2722     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2723     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2724     int i = 0;
   2725 
   2726     bcm_ptp_port_identity_t portid;
   2727 
   2728     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2729             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2730         return rv;
   2731     }
   2732 
   2733     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2734             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2735         return rv;
   2736     }
   2737 
   2738     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2739             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_UTC_PROPERTIES,
   2740             0, 0, resp, &resp_len);
   2741 
   2742     if (rv == BCM_E_NONE) {
   2743         /*
   2744          * Parse response.
   2745          *    Octet 0...1 : UTC offset.
   2746          *    Octet 2     : Leap-61 (LI-61), Leap-59 (LI-59), and valid
   2747          *                  UTC offset (UTCV) Booleans.
   2748          *                  |B7|B6|B5|B4|B3|B2|B1|B0| =
   2749          *                  |0|0|0|0|0|UTCV|LI-59|LI-61|.
   2750          *    Octet 3: Reserved.
   2751          */
   2752         i = 0;
   2753         utc->utc_offset = _bcm_ptp_uint16_read(resp);
   2754         i += sizeof(uint16);
   2755 
   2756         utc->leap61 = (0x01 & resp[i]);
   2757         utc->leap59 = ((0x02 & resp[i]) >> 1);
   2758         utc->utc_valid = ((0x04 & resp[i]) >> 2);
   2759     }
   2760 
   2761     return rv;
   2762 }
   2763 
   2764 /*
   2765  * Function:
   2766  *      bcm_common_ptp_clock_utc_set
   2767  * Purpose:
   2768  *      Set UTC members of a PTP clock time properties dataset.
   2769  * Parameters:
   2770  *      unit      - (IN) Unit number.
   2771  *      ptp_id    - (IN) PTP Stack ID
   2772  *      clock_num - (IN) PTP Clock Number
   2773  *      utc       - (IN) PTP clock coordinated universal time (UTC) properties.
   2774  * Returns:
   2775  *      BCM_E_XXX
   2776  * Notes:
   2777  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.6.2.
   2778  */
   2779 int
   2780 bcm_common_ptp_clock_utc_set(
   2781     int unit,
   2782     bcm_ptp_stack_id_t ptp_id,
   2783     int clock_num,
   2784     bcm_ptp_utc_t *utc)
   2785 {
   2786     int rv = BCM_E_UNAVAIL;
   2787 
   2788     uint8 payload[PTP_MGMTMSG_PAYLOAD_UTC_PROPERTIES_SIZE_OCTETS] = {0};
   2789     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   2790     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   2791     int i = 0;
   2792 
   2793     bcm_ptp_port_identity_t portid;
   2794 
   2795     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   2796             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   2797         return rv;
   2798     }
   2799 
   2800     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   2801             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   2802         return rv;
   2803     }
   2804 
   2805     /*
   2806      * Make payload.
   2807      *    Octet 0...1 : UTC offset.
   2808      *    Octet 2     : Leap-61 (LI-61), Leap-59 (LI-59), and valid UTC
   2809      *                  offset (UTCV) Booleans.
   2810      *                  |B7|B6|B5|B4|B3|B2|B1|B0| =
   2811      *                  |0|0|0|0|0|UTCV|LI-59|LI-61|.
   2812      *    Octet 3: Reserved.
   2813      */
   2814     i = 0;
   2815     _bcm_ptp_uint16_write(payload, utc->utc_offset);
   2816     i += sizeof(uint16);
   2817 
   2818     payload[i] = ((0x01 & utc->leap61)) +
   2819                   ((0x01 & utc->leap59) << 1) +
   2820                   ((0x01 & utc->utc_valid) << 2);
   2821 
   2822     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   2823             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_UTC_PROPERTIES,
   2824             payload, PTP_MGMTMSG_PAYLOAD_UTC_PROPERTIES_SIZE_OCTETS,
   2825             resp, &resp_len);
   2826 
   2827     return rv;
   2828 }
   2829 
   2830 /*
   2831  * Function:
   2832  *      bcm_common_ptp_clock_port_type_get
   2833  * Purpose:
   2834  *      Get port type of a PTP clock port.
   2835  * Parameters:
   2836  *      unit       - (IN)  Unit number.
   2837  *      ptp_id     - (IN)  PTP stack ID.
   2838  *      clock_num  - (IN)  PTP clock number.
   2839  *      clock_port - (IN)  PTP clock port number.
   2840  *      type       - (OUT) PTP clock port type.
   2841  * Returns:
   2842  *      BCM_E_XXX
   2843  * Notes:
   2844  */
   2845 int
   2846 bcm_common_ptp_clock_port_type_get(
   2847     int unit,
   2848     bcm_ptp_stack_id_t ptp_id,
   2849     int clock_num,
   2850     uint32 clock_port,
   2851     bcm_ptp_port_type_t *type)
   2852 {
   2853     int rv = BCM_E_UNAVAIL;
   2854 
   2855     bcm_ptp_clock_port_info_t pi;
   2856 
   2857     if (BCM_FAILURE(rv =
   2858         _bcm_ptp_clock_port_cache_info_get(unit, ptp_id, clock_num, clock_port, &pi))) {
   2859         return rv;
   2860     }
   2861 
   2862     *type = pi.port_type;
   2863 
   2864     return rv;
   2865 }
   2866 
   2867 /*
   2868  * Function:
   2869  *      bcm_common_ptp_clock_port_protocol_get
   2870  * Purpose:
   2871  *      Get network protocol of a PTP clock port.
   2872  * Parameters:
   2873  *      unit       - (IN)  Unit number.
   2874  *      ptp_id     - (IN)  PTP stack ID.
   2875  *      clock_num  - (IN)  PTP clock number.
   2876  *      clock_port - (IN)  PTP clock port number.
   2877  *      protocol   - (OUT) PTP clock port network protocol.
   2878  * Returns:
   2879  *      BCM_E_XXX
   2880  * Notes:
   2881  */
   2882 int
   2883 bcm_common_ptp_clock_port_protocol_get(
   2884     int unit,
   2885     bcm_ptp_stack_id_t ptp_id,
   2886     int clock_num,
   2887     uint32 clock_port,
   2888     bcm_ptp_protocol_t *protocol)
   2889 {
   2890     int rv = BCM_E_UNAVAIL;
   2891 
   2892     bcm_ptp_clock_port_info_t pi;
   2893 
   2894     if (BCM_FAILURE(rv =
   2895         _bcm_ptp_clock_port_cache_info_get(unit, ptp_id, clock_num, clock_port, &pi))) {
   2896         return rv;
   2897     }
   2898 
   2899     *protocol = pi.port_address.addr_type;
   2900 
   2901     return rv;
   2902 }
   2903 
   2904 /*
   2905  * Function:
   2906  *      bcm_common_ptp_clock_port_mac_get
   2907  * Purpose:
   2908  *      Get MAC address of a PTP clock port.
   2909  * Parameters:
   2910  *      unit       - (IN)  Unit number.
   2911  *      ptp_id     - (IN)  PTP stack ID.
   2912  *      clock_num  - (IN)  PTP clock number.
   2913  *      clock_port - (IN)  PTP clock port number.
   2914  *      mac        - (OUT) PTP clock port MAC address.
   2915  * Returns:
   2916  *      BCM_E_XXX
   2917  * Notes:
   2918  */
   2919 int
   2920 bcm_common_ptp_clock_port_mac_get(
   2921     int unit,
   2922     bcm_ptp_stack_id_t ptp_id,
   2923     int clock_num,
   2924     uint32 clock_port,
   2925     bcm_mac_t *mac)
   2926 {
   2927     int rv = BCM_E_UNAVAIL;
   2928 
   2929     bcm_ptp_clock_port_info_t pi;
   2930 
   2931     if (BCM_FAILURE(rv =
   2932         _bcm_ptp_clock_port_cache_info_get(unit, ptp_id, clock_num, clock_port, &pi))) {
   2933         return rv;
   2934     }
   2935 
   2936     sal_memcpy(mac, pi.mac, sizeof(bcm_mac_t));
   2937 
   2938     return rv;
   2939 }
   2940 
   2941 /*
   2942  * Function:
   2943  *      bcm_common_ptp_clock_port_info_get
   2944  * Purpose:
   2945  *      Get configuration information (data and metadata) of a PTP clock port.
   2946  * Parameters:
   2947  *      unit       - (IN)  Unit number.
   2948  *      ptp_id     - (IN)  PTP stack ID.
   2949  *      clock_num  - (IN)  PTP clock number.
   2950  *      clock_port - (IN)  PTP clock port number.
   2951  *      info       - (OUT) PTP clock port configuration information.
   2952  * Returns:
   2953  *      BCM_E_XXX
   2954  * Notes:
   2955  */
   2956 int
   2957 bcm_common_ptp_clock_port_info_get(
   2958     int unit,
   2959     bcm_ptp_stack_id_t ptp_id,
   2960     int clock_num,
   2961     uint32 clock_port,
   2962     bcm_ptp_clock_port_info_t *info)
   2963 {
   2964     int rv = BCM_E_UNAVAIL;
   2965 
   2966     if (BCM_FAILURE(rv =
   2967         _bcm_ptp_clock_port_cache_info_get(unit, ptp_id, clock_num, clock_port, info))) {
   2968         return rv;
   2969     }
   2970 
   2971     return rv;
   2972 }
   2973 
   2974 /*
   2975  * Function:
   2976  *      bcm_common_ptp_clock_port_dataset_get
   2977  * Purpose:
   2978  *      Get PTP clock port dataset.
   2979  * Parameters:
   2980  *      unit       - (IN)  Unit number.
   2981  *      ptp_id     - (IN)  PTP stack ID.
   2982  *      clock_num  - (IN)  PTP clock number.
   2983  *      clock_port - (IN)  PTP clock port number.
   2984  *      dataset    - (OUT) Port dataset.
   2985  * Returns:
   2986  *      BCM_E_XXX
   2987  * Notes:
   2988  *      The port dataset is relevant to PTP ordinary and boundary clocks.
   2989  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.
   2990  */
   2991 int
   2992 bcm_common_ptp_clock_port_dataset_get(
   2993     int unit,
   2994     bcm_ptp_stack_id_t ptp_id,
   2995     int clock_num,
   2996     uint32 clock_port,
   2997     bcm_ptp_port_dataset_t *dataset)
   2998 {
   2999     int rv = BCM_E_UNAVAIL;
   3000 
   3001     bcm_ptp_clock_port_info_t pi;
   3002     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3003     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3004     int i = 0;
   3005     _bcm_ptp_clock_cache_t *clock_cache;
   3006 
   3007     bcm_ptp_port_identity_t portid;
   3008 
   3009     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3010             clock_port))) {
   3011         return rv;
   3012     }
   3013 
   3014     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3015             clock_num, clock_port, &portid))) {
   3016         return rv;
   3017     }
   3018 
   3019     clock_cache = &_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num];
   3020     if (!clock_cache->in_use)
   3021         return BCM_E_UNAVAIL;
   3022 
   3023     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3024             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_PORT_DATASET,
   3025             0, 0, resp, &resp_len);
   3026 
   3027     if (rv == BCM_E_NONE) {
   3028         /*
   3029          * Parse response.
   3030          *    Octet 0...9   : PTP port identity.
   3031          *    Octet 10      : Port state.
   3032          *    Octet 11      : Log minimum delay request interval.
   3033          *    Octet 12...19 : Peer mean path delay (nanoseconds).
   3034          *    Octet 20      : Log announce interval.
   3035          *    Octet 21      : Announce receipt timeout.
   3036          *    Octet 22      : Log synchronization interval.
   3037          *    Octet 23      : Delay mechanism.
   3038          *    Octet 24      : Log minimum peer delay request interval.
   3039          *    Octet 25      : |B7|B6|B5|B4|B3|B2|B1|B0|.
   3040          *                    |B4...B7| = Reserved.
   3041          *                    |B0...B3| = Version number.
   3042          */
   3043         i = 0;
   3044         sal_memcpy(dataset->port_identity.clock_identity, resp,
   3045                    sizeof(bcm_ptp_clock_identity_t));
   3046         i += sizeof(bcm_ptp_clock_identity_t);
   3047 
   3048         dataset->port_identity.port_number = _bcm_ptp_uint16_read(resp+i);
   3049         i += sizeof(uint16);
   3050 
   3051         dataset->port_state = resp[i++];
   3052         dataset->log_min_delay_req_interval = (int8)resp[i++];
   3053 
   3054         dataset->peer_mean_path_delay = _bcm_ptp_uint64_read(resp+i);
   3055         i += sizeof(uint64);
   3056 
   3057         dataset->log_announce_interval = (int8)resp[i++];
   3058         dataset->announce_receipt_timeout = resp[i++];
   3059         dataset->log_sync_interval = (int8)resp[i++];
   3060         dataset->delay_mechanism = resp[i++];
   3061         dataset->log_min_pdelay_req_interval = (int8)resp[i++];
   3062 
   3063         dataset->version_number = (0x0f & resp[i++]);
   3064 
   3065         dataset->local_priority = (uint8)resp[i++];
   3066         dataset->signal_fail = (int8)resp[i++];
   3067 
   3068         if (BCM_FAILURE(rv =
   3069             _bcm_ptp_clock_port_cache_info_get(unit, ptp_id, clock_num, clock_port, &pi))) {
   3070             return rv;
   3071         }
   3072 
   3073         if(pi.port_type == bcmPTPPortTypeMasterOnly)
   3074             dataset->not_slave = TRUE;
   3075         else
   3076             dataset->not_slave = FALSE;
   3077     }
   3078 
   3079     return rv;
   3080 }
   3081 
   3082 /*
   3083  * Function:
   3084  *      bcm_common_ptp_clock_port_delay_mechanism_get
   3085  * Purpose:
   3086  *      Get delay mechanism member of a PTP clock port dataset.
   3087  * Parameters:
   3088  *      unit            - (IN)  Unit number.
   3089  *      ptp_id          - (IN)  PTP stack ID.
   3090  *      clock_num       - (IN)  PTP clock number.
   3091  *      clock_port      - (IN)  PTP clock port number.
   3092  *      delay_mechanism - (OUT) PTP clock port delay mechanism.
   3093  * Returns:
   3094  *      BCM_E_XXX
   3095  * Notes:
   3096  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.5.
   3097  */
   3098 int
   3099 bcm_common_ptp_clock_port_delay_mechanism_get(
   3100     int unit,
   3101     bcm_ptp_stack_id_t ptp_id,
   3102     int clock_num,
   3103     uint32 clock_port,
   3104     uint32 *delay_mechanism)
   3105 {
   3106     int rv = BCM_E_UNAVAIL;
   3107 
   3108     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3109     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3110 
   3111     bcm_ptp_port_identity_t portid;
   3112 
   3113     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3114             clock_port))) {
   3115         return rv;
   3116     }
   3117 
   3118     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3119             clock_num, clock_port, &portid))) {
   3120         return rv;
   3121     }
   3122 
   3123     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3124             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_DELAY_MECHANISM,
   3125             0, 0, resp, &resp_len);
   3126 
   3127     if (rv == BCM_E_NONE) {
   3128         /*
   3129          * Parse response.
   3130          *    Octet 0 : Delay mechanism.
   3131          *    Octet 1 : Reserved.
   3132          */
   3133         *delay_mechanism = resp[0];
   3134     }
   3135 
   3136     return rv;
   3137 }
   3138 
   3139 /*
   3140  * Function:
   3141  *      bcm_common_ptp_clock_port_delay_mechanism_set
   3142  * Purpose:
   3143  *      Set delay mechanism member of a PTP clock port dataset.
   3144  * Parameters:
   3145  *      unit            - (IN) Unit number.
   3146  *      ptp_id          - (IN) PTP stack ID.
   3147  *      clock_num       - (IN) PTP clock number.
   3148  *      clock_port      - (IN) PTP clock port number.
   3149  *      delay_mechanism - (IN) PTP clock port delay mechanism.
   3150  * Returns:
   3151  *      BCM_E_XXX
   3152  * Notes:
   3153  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.5.
   3154  */
   3155 int
   3156 bcm_common_ptp_clock_port_delay_mechanism_set(
   3157     int unit,
   3158     bcm_ptp_stack_id_t ptp_id,
   3159     int clock_num,
   3160     uint32 clock_port,
   3161     uint32 delay_mechanism)
   3162 {
   3163     int rv = BCM_E_UNAVAIL;
   3164 
   3165     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   3166     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3167     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3168 
   3169     bcm_ptp_port_identity_t portid;
   3170 
   3171     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3172             clock_port))) {
   3173         return rv;
   3174     }
   3175 
   3176     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3177             clock_num, clock_port, &portid))) {
   3178         return rv;
   3179     }
   3180 
   3181     /*
   3182      * Make payload.
   3183      *    Octet 0 : Delay mechanism.
   3184      *    Octet 1 : Reserved.
   3185      */
   3186     payload[0] = (uint8)delay_mechanism;
   3187 
   3188     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3189             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_DELAY_MECHANISM,
   3190             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   3191             resp, &resp_len);
   3192 
   3193     return rv;
   3194 }
   3195 
   3196 /*
   3197  * Function:
   3198  *      bcm_common_ptp_clock_port_latency_get
   3199  * Purpose:
   3200  *      Get PTP clock port expected asymmetric latencies.
   3201  * Parameters:
   3202  *      unit        - (IN)  Unit number.
   3203  *      ptp_id      - (IN)  PTP stack ID.
   3204  *      clock_num   - (IN)  PTP clock number.
   3205  *      clock_port  - (IN)  PTP clock port number.
   3206  *      latency_in  - (OUT) PTP clock port inbound latency (ns).
   3207  *      latency_out - (OUT) PTP clock port outbound latency (ns).
   3208  * Returns:
   3209  *      BCM_E_XXX
   3210  * Notes:
   3211  *      Function is an implementation-specific PTP management message.
   3212  */
   3213 int
   3214 bcm_common_ptp_clock_port_latency_get(
   3215     int unit,
   3216     bcm_ptp_stack_id_t ptp_id,
   3217     int clock_num,
   3218     uint32 clock_port,
   3219     uint32 *latency_in,
   3220     uint32 *latency_out)
   3221 {
   3222     
   3223     return BCM_E_UNAVAIL;
   3224 }
   3225 
   3226 /*
   3227  * Function:
   3228  *      bcm_common_ptp_clock_port_latency_set
   3229  * Purpose:
   3230  *      Set PTP clock port expected asymmetric latencies.
   3231  * Parameters:
   3232  *      unit        - (IN) Unit number.
   3233  *      ptp_id      - (IN) PTP stack ID.
   3234  *      clock_num   - (IN) PTP clock number.
   3235  *      clock_port  - (IN) PTP clock port number.
   3236  *      latency_in  - (IN) PTP clock port inbound latency (ns).
   3237  *      latency_out - (IN) PTP clock port outbound latency (ns).
   3238  * Returns:
   3239  *      BCM_E_XXX
   3240  * Notes:
   3241  *      Function is an implementation-specific PTP management message.
   3242  */
   3243 int
   3244 bcm_common_ptp_clock_port_latency_set(
   3245     int unit,
   3246     bcm_ptp_stack_id_t ptp_id,
   3247     int clock_num,
   3248     uint32 clock_port,
   3249     uint32 latency_in,
   3250     uint32 latency_out)
   3251 {
   3252     int rv = BCM_E_UNAVAIL;
   3253 
   3254     uint8 payload[PTP_MGMTMSG_PAYLOAD_PORT_LATENCY_SIZE_OCTETS] = {0};
   3255     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3256     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3257     uint64 latency;
   3258     int i = 0;
   3259 
   3260     bcm_ptp_port_identity_t portid;
   3261 
   3262     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3263             clock_port))) {
   3264         return rv;
   3265     }
   3266 
   3267     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3268             clock_num, clock_port, &portid))) {
   3269         return rv;
   3270     }
   3271 
   3272     /*
   3273      * Make payload.
   3274      *    Octet 0...2   : Custom management message key/identifier.
   3275      *                    Octet 0= 'B'; Octet 1= 'C'; Octet 2= 'M'.
   3276      *    Octet 3...5   : Reserved.
   3277      *    Octet 6...13  : Inbound port latency.
   3278      *                    Binary fixed-point value. Time (ns)= latency_in/(2^16).
   3279      *    Octet 14...21 : Outbound port latency.
   3280      *                    Binary fixed-point value. Time (ns)= latency_out/(2^16).
   3281      */
   3282     i = 0;
   3283     payload[i++] = 'B';
   3284     payload[i++] = 'C';
   3285     payload[i++] = 'M';
   3286     i += 3;
   3287 
   3288     COMPILER_64_SET(latency, 0, latency_in);
   3289     COMPILER_64_SHL(latency, 16);
   3290     _bcm_ptp_uint64_write(payload+i, latency);
   3291     i += sizeof(uint64);
   3292     COMPILER_64_SET(latency, 0, latency_out);
   3293     COMPILER_64_SHL(latency, 16);
   3294     _bcm_ptp_uint64_write(payload+i, latency);
   3295 
   3296     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3297             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_PORT_LATENCY,
   3298             payload, PTP_MGMTMSG_PAYLOAD_PORT_LATENCY_SIZE_OCTETS,
   3299             resp, &resp_len);
   3300 
   3301     return rv;
   3302 }
   3303 
   3304 /*
   3305  * Function:
   3306  *      bcm_common_ptp_clock_port_log_announce_interval_get
   3307  * Purpose:
   3308  *      Get log announce interval of a PTP clock port dataset.
   3309  * Parameters:
   3310  *      unit       - (IN)  Unit number.
   3311  *      ptp_id     - (IN)  PTP stack ID.
   3312  *      clock_num  - (IN)  PTP clock number.
   3313  *      clock_port - (IN)  PTP clock port number.
   3314  *      interval   - (OUT) PTP clock port log announce interval.
   3315  * Returns:
   3316  *      BCM_E_XXX
   3317  * Notes:
   3318  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.2.
   3319  */
   3320 int
   3321 bcm_common_ptp_clock_port_log_announce_interval_get(
   3322     int unit,
   3323     bcm_ptp_stack_id_t ptp_id,
   3324     int clock_num,
   3325     uint32 clock_port,
   3326     int *interval)
   3327 {
   3328     int rv = BCM_E_UNAVAIL;
   3329 
   3330     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3331     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3332 
   3333     bcm_ptp_port_identity_t portid;
   3334 
   3335     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3336             clock_port))) {
   3337         return rv;
   3338     }
   3339 
   3340     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3341             clock_num, clock_port, &portid))) {
   3342         return rv;
   3343     }
   3344 
   3345     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3346             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_LOG_ANNOUNCE_INTERVAL,
   3347             0, 0, resp, &resp_len);
   3348 
   3349     if (rv == BCM_E_NONE) {
   3350         /*
   3351          * Parse response.
   3352          *    Octet 0 : Log announce interval.
   3353          *    Octet 1 : Reserved.
   3354          */
   3355         *interval = (int8)resp[0];
   3356     }
   3357 
   3358     return rv;
   3359 }
   3360 
   3361 /*
   3362  * Function:
   3363  *      bcm_common_ptp_clock_port_log_announce_interval_set
   3364  * Purpose:
   3365  *      Set log announce interval of a PTP clock port dataset.
   3366  * Parameters:
   3367  *      unit       - (IN) Unit number.
   3368  *      ptp_id     - (IN) PTP stack ID.
   3369  *      clock_num  - (IN) PTP clock number.
   3370  *      clock_port - (IN) PTP clock port number.
   3371  *      interval   - (IN) PTP clock port log announce interval.
   3372  * Returns:
   3373  *      BCM_E_XXX
   3374  * Notes:
   3375  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.2.
   3376  */
   3377 int
   3378 bcm_common_ptp_clock_port_log_announce_interval_set(
   3379     int unit,
   3380     bcm_ptp_stack_id_t ptp_id,
   3381     int clock_num,
   3382     uint32 clock_port,
   3383     int interval)
   3384 {
   3385     int rv = BCM_E_UNAVAIL;
   3386 
   3387     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   3388     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3389     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3390 
   3391     bcm_ptp_clock_info_t ci;
   3392     bcm_ptp_clock_port_info_t pi;
   3393     bcm_ptp_port_identity_t portid;
   3394 
   3395     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3396             clock_port))) {
   3397         return rv;
   3398     }
   3399 
   3400     /* PTP attribute profile range checking. */
   3401     if (BCM_FAILURE(rv =
   3402             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   3403         LOG_ERROR(BSL_LS_BCM_COMMON,
   3404                   (BSL_META_U(unit,
   3405                               "_bcm_ptp_clock_cache_info_get failed\n")));
   3406         return rv;
   3407     }
   3408 
   3409     if ((interval < ci.log_announce_interval_minimum) ||
   3410             (interval > ci.log_announce_interval_maximum)) {
   3411         /*
   3412          * Caller provided log announce interval value is not in (min,max)
   3413          * range of PTP profile.
   3414          */
   3415         return BCM_E_PARAM;
   3416     }
   3417 
   3418     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3419             clock_num, clock_port, &portid))) {
   3420         return rv;
   3421     }
   3422 
   3423     /*
   3424      * Make payload.
   3425      *    Octet 0 : Log announce interval.
   3426      *    Octet 1 : Reserved.
   3427      */
   3428     payload[0] = (uint8)interval;
   3429 
   3430     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3431             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_LOG_ANNOUNCE_INTERVAL,
   3432             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   3433             resp, &resp_len);
   3434 
   3435     /* Update PTP clock port cache. */
   3436     if (rv == BCM_E_NONE) {
   3437         if (BCM_FAILURE(rv = _bcm_ptp_clock_port_cache_info_get(unit, ptp_id,
   3438                 clock_num, clock_port, &pi))) {
   3439             return rv;
   3440         }
   3441 
   3442         pi.log_announce_interval = interval;
   3443         rv = _bcm_ptp_clock_port_cache_info_set(unit, ptp_id, clock_num,
   3444                 clock_port, &pi);
   3445     }
   3446 
   3447     return rv;
   3448 }
   3449 
   3450 /*
   3451  * Function:
   3452  *      bcm_common_ptp_clock_port_announce_receipt_timeout_get
   3453  * Purpose:
   3454  *      Get announce receipt timeout member of a PTP clock port dataset.
   3455  * Parameters:
   3456  *      unit       - (IN)  Unit number.
   3457  *      ptp_id     - (IN)  PTP stack ID.
   3458  *      clock_num  - (IN)  PTP clock number.
   3459  *      clock_port - (IN)  PTP clock port number.
   3460  *      timeout    - (OUT) PTP clock port announce receipt timeout.
   3461  * Returns:
   3462  *      BCM_E_XXX
   3463  * Notes:
   3464  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.3.
   3465  */
   3466 int
   3467 bcm_common_ptp_clock_port_announce_receipt_timeout_get(
   3468     int unit,
   3469     bcm_ptp_stack_id_t ptp_id,
   3470     int clock_num,
   3471     uint32 clock_port,
   3472     uint32 *timeout)
   3473 {
   3474     int rv = BCM_E_UNAVAIL;
   3475 
   3476     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3477     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3478 
   3479     bcm_ptp_port_identity_t portid;
   3480 
   3481     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3482             clock_port))) {
   3483         return rv;
   3484     }
   3485 
   3486     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3487             clock_num, clock_port, &portid))) {
   3488         return rv;
   3489     }
   3490 
   3491     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3492             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_ANNOUNCE_RECEIPT_TIMEOUT,
   3493             0, 0, resp, &resp_len);
   3494 
   3495     if (rv == BCM_E_NONE) {
   3496         /*
   3497          * Parse response.
   3498          *    Octet 0 : Announce receipt timeout.
   3499          *    Octet 1 : Reserved.
   3500          */
   3501         *timeout = resp[0];
   3502     }
   3503 
   3504     return rv;
   3505 }
   3506 
   3507 /*
   3508  * Function:
   3509  *      bcm_common_ptp_clock_port_announce_receipt_timeout_set
   3510  * Purpose:
   3511  *      Set announce receipt timeout member of a PTP clock port dataset.
   3512  * Parameters:
   3513  *      unit       - (IN) Unit number.
   3514  *      ptp_id     - (IN) PTP stack ID.
   3515  *      clock_num  - (IN) PTP clock number.
   3516  *      clock_port - (IN) PTP clock port number.
   3517  *      timeout    - (IN) PTP clock port announce receipt timeout.
   3518  * Returns:
   3519  *      BCM_E_XXX
   3520  * Notes:
   3521  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.3.
   3522  */
   3523 int
   3524 bcm_common_ptp_clock_port_announce_receipt_timeout_set(
   3525     int unit,
   3526     bcm_ptp_stack_id_t ptp_id,
   3527     int clock_num,
   3528     uint32 clock_port,
   3529     uint32 timeout)
   3530 {
   3531     int rv = BCM_E_UNAVAIL;
   3532 
   3533     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   3534     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3535     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3536 
   3537     bcm_ptp_clock_info_t ci;
   3538     bcm_ptp_clock_port_info_t pi;
   3539     bcm_ptp_port_identity_t portid;
   3540 
   3541     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3542             clock_port))) {
   3543         return rv;
   3544     }
   3545 
   3546     /* PTP attribute profile range checking. */
   3547     if (BCM_FAILURE(rv =
   3548             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   3549         LOG_ERROR(BSL_LS_BCM_COMMON,
   3550                   (BSL_META_U(unit,
   3551                             "_bcm_ptp_clock_cache_info_get failed\n")));
   3552         return rv;
   3553     }
   3554 
   3555     if ((timeout < ci.announce_receipt_timeout_minimum) ||
   3556             (timeout > ci.announce_receipt_timeout_maximum)) {
   3557         /*
   3558          * Caller provided announce receipt timeout value is not in (min,max)
   3559          * range of PTP profile.
   3560          */
   3561         return BCM_E_PARAM;
   3562     }
   3563 
   3564     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3565             clock_num, clock_port, &portid))) {
   3566         return rv;
   3567     }
   3568 
   3569     /*
   3570      * Make payload.
   3571      *    Octet 0 : Announce receipt timeout.
   3572      *    Octet 1 : Reserved.
   3573      */
   3574     payload[0] = (uint8)timeout;
   3575 
   3576     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3577             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_ANNOUNCE_RECEIPT_TIMEOUT,
   3578             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   3579             resp, &resp_len);
   3580 
   3581     /* Update PTP clock port cache. */
   3582     if (rv == BCM_E_NONE) {
   3583         if (BCM_FAILURE(rv = _bcm_ptp_clock_port_cache_info_get(unit, ptp_id,
   3584                 clock_num, clock_port, &pi))) {
   3585             return rv;
   3586         }
   3587 
   3588         pi.announce_receipt_timeout = (uint8)timeout;
   3589         rv = _bcm_ptp_clock_port_cache_info_set(unit, ptp_id, clock_num,
   3590                 clock_port, &pi);
   3591     }
   3592 
   3593     return rv;
   3594 }
   3595 
   3596 /*
   3597  * Function:
   3598  *      bcm_common_ptp_clock_port_log_sync_interval_get
   3599  * Purpose:
   3600  *      Get log sync interval member of a PTP clock port dataset.
   3601  * Parameters:
   3602  *      unit       - (IN)  Unit number.
   3603  *      ptp_id     - (IN)  PTP stack ID.
   3604  *      clock_num  - (IN)  PTP clock number.
   3605  *      clock_port - (IN)  PTP clock port number.
   3606  *      interval   - (OUT) PTP clock port log sync interval.
   3607  * Returns:
   3608  *      BCM_E_XXX
   3609  * Notes:
   3610  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.4.
   3611  */
   3612 int
   3613 bcm_common_ptp_clock_port_log_sync_interval_get(
   3614     int unit,
   3615     bcm_ptp_stack_id_t ptp_id,
   3616     int clock_num,
   3617     uint32 clock_port,
   3618     int *interval)
   3619 {
   3620     int rv = BCM_E_UNAVAIL;
   3621 
   3622     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3623     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3624 
   3625     bcm_ptp_port_identity_t portid;
   3626 
   3627     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3628             clock_port))) {
   3629         return rv;
   3630     }
   3631 
   3632     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3633             clock_num, clock_port, &portid))) {
   3634         return rv;
   3635     }
   3636 
   3637     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3638             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_LOG_SYNC_INTERVAL,
   3639             0, 0, resp, &resp_len);
   3640 
   3641     if (rv == BCM_E_NONE) {
   3642         /*
   3643          * Parse response.
   3644          *    Octet 0 : Log sync interval.
   3645          *    Octet 1 : Reserved.
   3646          */
   3647         *interval = (int8)resp[0];
   3648     }
   3649 
   3650     return rv;
   3651 }
   3652 
   3653 /*
   3654  * Function:
   3655  *      bcm_common_ptp_clock_port_log_sync_interval_set
   3656  * Purpose:
   3657  *      Set log sync interval member of a PTP clock port dataset.
   3658  * Parameters:
   3659  *      unit       - (IN) Unit number.
   3660  *      ptp_id     - (IN) PTP stack ID.
   3661  *      clock_num  - (IN) PTP clock number.
   3662  *      clock_port - (IN) PTP clock port number.
   3663  *      interval   - (IN) PTP clock port log sync interval.
   3664  * Returns:
   3665  *      BCM_E_XXX
   3666  * Notes:
   3667  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.4.
   3668  */
   3669 int
   3670 bcm_common_ptp_clock_port_log_sync_interval_set(
   3671     int unit,
   3672     bcm_ptp_stack_id_t ptp_id,
   3673     int clock_num,
   3674     uint32 clock_port,
   3675     int interval)
   3676 {
   3677     int rv = BCM_E_UNAVAIL;
   3678 
   3679     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   3680     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3681     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3682 
   3683     bcm_ptp_clock_info_t ci;
   3684     bcm_ptp_clock_port_info_t pi;
   3685     bcm_ptp_port_identity_t portid;
   3686 
   3687     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3688             clock_port))) {
   3689         return rv;
   3690     }
   3691 
   3692     /* PTP attribute profile range checking. */
   3693     if (BCM_FAILURE(rv =
   3694             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   3695         LOG_ERROR(BSL_LS_BCM_COMMON,
   3696                   (BSL_META_U(unit,
   3697                               "_bcm_ptp_clock_cache_info_get failed\n")));
   3698         return rv;
   3699     }
   3700 
   3701     if ((interval < ci.log_sync_interval_minimum) ||
   3702             (interval > ci.log_sync_interval_maximum)) {
   3703         /*
   3704          * Caller provided log sync interval value is not in (min,max)
   3705          * range of PTP profile.
   3706          */
   3707         return BCM_E_PARAM;
   3708     }
   3709 
   3710     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3711             clock_num, clock_port, &portid))) {
   3712         return rv;
   3713     }
   3714 
   3715     /*
   3716      * Make payload.
   3717      *    Octet 0 : Log sync interval.
   3718      *    Octet 1 : Reserved.
   3719      */
   3720     payload[0] = (uint8)interval;
   3721 
   3722     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3723             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_LOG_SYNC_INTERVAL,
   3724             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   3725             resp, &resp_len);
   3726 
   3727     /* Update PTP clock port cache. */
   3728     if (rv == BCM_E_NONE) {
   3729         if (BCM_FAILURE(rv = _bcm_ptp_clock_port_cache_info_get(unit, ptp_id,
   3730                 clock_num, clock_port, &pi))) {
   3731             return rv;
   3732         }
   3733 
   3734         pi.log_sync_interval = interval;
   3735         rv = _bcm_ptp_clock_port_cache_info_set(unit, ptp_id, clock_num,
   3736                 clock_port, &pi);
   3737     }
   3738 
   3739     return rv;
   3740 }
   3741 
   3742 /*
   3743  * Function:
   3744  *      bcm_common_ptp_clock_port_version_number_get
   3745  * Purpose:
   3746  *      Get PTP version number member of a PTP clock port dataset.
   3747  * Parameters:
   3748  *      unit       - (IN)  Unit number.
   3749  *      ptp_id     - (IN)  PTP stack ID.
   3750  *      clock_num  - (IN)  PTP clock number.
   3751  *      clock_port - (IN)  PTP clock port number.
   3752  *      version    - (OUT) PTP clock port PTP version number.
   3753  * Returns:
   3754  *      BCM_E_XXX
   3755  * Notes:
   3756  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.7.
   3757  */
   3758 int
   3759 bcm_common_ptp_clock_port_version_number_get(
   3760     int unit,
   3761     bcm_ptp_stack_id_t ptp_id,
   3762     int clock_num,
   3763     uint32 clock_port,
   3764     uint32 *version)
   3765 {
   3766     int rv = BCM_E_UNAVAIL;
   3767 
   3768     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3769     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3770 
   3771     bcm_ptp_port_identity_t portid;
   3772 
   3773     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3774             clock_port))) {
   3775         return rv;
   3776     }
   3777 
   3778     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3779             clock_num, clock_port, &portid))) {
   3780         return rv;
   3781     }
   3782 
   3783     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3784             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_VERSION_NUMBER,
   3785             0, 0, resp, &resp_len);
   3786 
   3787     if (rv == BCM_E_NONE) {
   3788         /*
   3789          * Parse response.
   3790          *    Octet 0 : PTP version number.
   3791          *    Octet 1 : Reserved.
   3792          */
   3793         *version = (0x0f & resp[0]);
   3794     }
   3795 
   3796     return rv;
   3797 }
   3798 
   3799 /*
   3800  * Function:
   3801  *      bcm_common_ptp_clock_port_version_number_set
   3802  * Purpose:
   3803  *      Set PTP version number member of a PTP clock port dataset.
   3804  * Parameters:
   3805  *      unit       - (IN) Unit number.
   3806  *      ptp_id     - (IN) PTP stack ID.
   3807  *      clock_num  - (IN) PTP clock number.
   3808  *      clock_port - (IN) PTP clock port number.
   3809  *      version    - (IN) PTP clock port PTP version number.
   3810  * Returns:
   3811  *      BCM_E_XXX
   3812  * Notes:
   3813  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.7.
   3814  */
   3815 int
   3816 bcm_common_ptp_clock_port_version_number_set(
   3817     int unit,
   3818     bcm_ptp_stack_id_t ptp_id,
   3819     int clock_num,
   3820     uint32 clock_port,
   3821     uint32 version)
   3822 {
   3823     return BCM_E_UNAVAIL;
   3824 }
   3825 
   3826 /*
   3827  * Function:
   3828  *      bcm_common_ptp_clock_port_log_min_pdelay_req_interval_get
   3829  * Purpose:
   3830  *      Get log minimum peer delay (PDelay) request interval member of a PTP
   3831  *      clock port dataset.
   3832  * Parameters:
   3833  *      unit       - (IN)  Unit number.
   3834  *      ptp_id     - (IN)  PTP stack ID.
   3835  *      clock_num  - (IN)  PTP clock number.
   3836  *      clock_port - (IN)  PTP clock port number.
   3837  *      interval   - (OUT) PTP clock port log minimum peer delay (PDelay)
   3838  *                         request interval.
   3839  * Returns:
   3840  *      BCM_E_XXX
   3841  * Notes:
   3842  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.6.
   3843  */
   3844 int
   3845 bcm_common_ptp_clock_port_log_min_pdelay_req_interval_get(
   3846     int unit,
   3847     bcm_ptp_stack_id_t ptp_id,
   3848     int clock_num,
   3849     uint32 clock_port,
   3850     int *interval)
   3851 {
   3852     int rv = BCM_E_UNAVAIL;
   3853 
   3854     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3855     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3856 
   3857     bcm_ptp_port_identity_t portid;
   3858 
   3859     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3860             clock_port))) {
   3861         return rv;
   3862     }
   3863 
   3864     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3865             clock_num, clock_port, &portid))) {
   3866         return rv;
   3867     }
   3868 
   3869     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3870             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_LOG_MIN_PDELAY_REQ_INTERVAL,
   3871             0, 0, resp, &resp_len);
   3872 
   3873     if (rv == BCM_E_NONE) {
   3874         /*
   3875          * Parse response.
   3876          *    Octet 0 : Log minimum peer delay request interval.
   3877          *    Octet 1 : Reserved.
   3878          */
   3879         *interval = (int8)resp[0];
   3880     }
   3881 
   3882     return rv;
   3883 }
   3884 
   3885 /*
   3886  * Function:
   3887  *      bcm_common_ptp_clock_port_log_min_pdelay_req_interval_set
   3888  * Purpose:
   3889  *      Set log minimum peer delay (PDelay) request interval member of a PTP
   3890  *      clock port dataset.
   3891  * Parameters:
   3892  *      unit       - (IN) Unit number.
   3893  *      ptp_id     - (IN) PTP stack ID.
   3894  *      clock_num  - (IN) PTP clock number.
   3895  *      clock_port - (IN) PTP clock port number.
   3896  *      interval   - (IN) PTP clock port log minimum peer delay (PDelay)
   3897  *                        request interval.
   3898  * Returns:
   3899  *      BCM_E_XXX
   3900  * Notes:
   3901  *      Ref. IEEE Std. 1588-2008, Chapters 8.2.5 and 15.5.3.7.6.
   3902  */
   3903 int
   3904 bcm_common_ptp_clock_port_log_min_pdelay_req_interval_set(
   3905     int unit,
   3906     bcm_ptp_stack_id_t ptp_id,
   3907     int clock_num,
   3908     uint32 clock_port,
   3909     int interval)
   3910 {
   3911     int rv = BCM_E_UNAVAIL;
   3912 
   3913     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   3914     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   3915     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   3916 
   3917     bcm_ptp_clock_info_t ci;
   3918     bcm_ptp_port_identity_t portid;
   3919 
   3920     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3921             clock_port))) {
   3922         return rv;
   3923     }
   3924 
   3925     /* PTP attribute profile range checking. */
   3926     if (BCM_FAILURE(rv =
   3927             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   3928         LOG_ERROR(BSL_LS_BCM_COMMON,
   3929                   (BSL_META_U(unit,
   3930                               "_bcm_ptp_clock_cache_info_get failed\n")));
   3931         return rv;
   3932     }
   3933 
   3934     if ((interval < ci.log_min_delay_req_interval_minimum) ||
   3935             (interval > ci.log_min_delay_req_interval_maximum)) {
   3936         /*
   3937          * Caller provided log minimum peer delay (PDelay) request interval
   3938          * value is not in (min,max) range of PTP profile.
   3939          */
   3940         return BCM_E_PARAM;
   3941     }
   3942 
   3943     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   3944             clock_num, clock_port, &portid))) {
   3945         return rv;
   3946     }
   3947 
   3948     /*
   3949      * Make payload.
   3950      *    Octet 0 : Log minimum peer delay request interval.
   3951      *    Octet 1 : Reserved.
   3952      */
   3953     payload[0] = (uint8)interval;
   3954 
   3955     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   3956             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_LOG_MIN_PDELAY_REQ_INTERVAL,
   3957             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   3958             resp, &resp_len);
   3959 
   3960     return rv;
   3961 }
   3962 
   3963 /*
   3964  * Function:
   3965  *      bcm_common_ptp_clock_port_log_min_delay_req_interval_get
   3966  * Purpose:
   3967  *      Get log minimum delay request interval member of a PTP clock port
   3968  *      dataset.
   3969  * Parameters:
   3970  *      unit       - (IN)  Unit number.
   3971  *      ptp_id     - (IN)  PTP stack ID.
   3972  *      clock_num  - (IN)  PTP clock number.
   3973  *      clock_port - (IN)  PTP clock port number.
   3974  *      interval   - (OUT) PTP clock port log minimum delay request interval.
   3975  *                         request interval.
   3976  * Returns:
   3977  *      BCM_E_XXX
   3978  * Notes:
   3979  *      Function is an implementation-specific PTP management message.
   3980  *      Ref. IEEE Std. 1588-2008, Chapter 8.2.5.
   3981  */
   3982 int
   3983 bcm_common_ptp_clock_port_log_min_delay_req_interval_get(
   3984     int unit,
   3985     bcm_ptp_stack_id_t ptp_id,
   3986     int clock_num,
   3987     uint32 clock_port,
   3988     int *interval)
   3989 {
   3990     int rv = BCM_E_UNAVAIL;
   3991     bcm_ptp_port_dataset_t dataset;
   3992 
   3993     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   3994             clock_port))) {
   3995         return rv;
   3996     }
   3997 
   3998     rv = bcm_common_ptp_clock_port_dataset_get(unit, ptp_id,
   3999             clock_num, clock_port, &dataset);
   4000 
   4001     if (rv == BCM_E_NONE) {
   4002         *interval = dataset.log_min_delay_req_interval;
   4003     }
   4004 
   4005     return rv;
   4006 }
   4007 
   4008 /*
   4009  * Function:
   4010  *      bcm_common_ptp_clock_port_log_min_delay_req_interval_set
   4011  * Purpose:
   4012  *      Set log minimum delay request interval member of a PTP clock port
   4013  *      dataset.
   4014  * Parameters:
   4015  *      unit       - (IN) Unit number.
   4016  *      ptp_id     - (IN) PTP stack ID.
   4017  *      clock_num  - (IN) PTP clock number.
   4018  *      clock_port - (IN) PTP clock port number.
   4019  *      interval   - (IN) PTP clock port log minimum delay request interval.
   4020  *                        request interval.
   4021  * Returns:
   4022  *      BCM_E_XXX
   4023  * Notes:
   4024  *      Function is an implementation-specific PTP management message.
   4025  *      Ref. IEEE Std. 1588-2008, Chapter 8.2.5.
   4026  */
   4027 int
   4028 bcm_common_ptp_clock_port_log_min_delay_req_interval_set(
   4029     int unit,
   4030     bcm_ptp_stack_id_t ptp_id,
   4031     int clock_num,
   4032     uint32 clock_port,
   4033     int interval)
   4034 {
   4035     int rv = BCM_E_UNAVAIL;
   4036 
   4037     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   4038     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4039     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4040 
   4041     bcm_ptp_clock_info_t ci;
   4042     bcm_ptp_clock_port_info_t pi;
   4043     bcm_ptp_port_identity_t portid;
   4044 
   4045     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   4046             clock_port))) {
   4047         return rv;
   4048     }
   4049 
   4050     /* PTP attribute profile range checking. */
   4051     if (BCM_FAILURE(rv =
   4052             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   4053         LOG_ERROR(BSL_LS_BCM_COMMON,
   4054                   (BSL_META_U(unit,
   4055                               "_bcm_ptp_clock_cache_info_get failed\n")));
   4056         return rv;
   4057     }
   4058 
   4059     if ((interval < ci.log_min_delay_req_interval_minimum) ||
   4060             (interval > ci.log_min_delay_req_interval_maximum)) {
   4061         /*
   4062          * Caller provided log minimum delay request interval value is
   4063          * not in (min,max) range of PTP profile.
   4064          */
   4065         return BCM_E_PARAM;
   4066     }
   4067 
   4068     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4069             clock_num, clock_port, &portid))) {
   4070         return rv;
   4071     }
   4072 
   4073     /*
   4074      * Make payload.
   4075      *    Octet 0 : Log minimum peer delay request interval.
   4076      *    Octet 1 : Reserved.
   4077      */
   4078     payload[0] = (uint8)interval;
   4079 
   4080     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   4081             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_LOG_MIN_DELAY_REQ_INTERVAL,
   4082             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   4083             resp, &resp_len);
   4084 
   4085     /* Update PTP clock port cache. */
   4086     if (rv == BCM_E_NONE) {
   4087         if (BCM_FAILURE(rv = _bcm_ptp_clock_port_cache_info_get(unit, ptp_id,
   4088                 clock_num, clock_port, &pi))) {
   4089             return rv;
   4090         }
   4091 
   4092         pi.log_min_delay_req_interval = interval;
   4093         rv = _bcm_ptp_clock_port_cache_info_set(unit, ptp_id, clock_num,
   4094                 clock_port, &pi);
   4095     }
   4096 
   4097     return rv;
   4098 }
   4099 
   4100 /*
   4101  * Function:
   4102  *      bcm_common_ptp_clock_port_enable
   4103  * Purpose:
   4104  *      Enable a PTP clock port of an ordinary clock (OC) or a boundary
   4105  *      clock (BC).
   4106  * Parameters:
   4107  *      unit       - (IN) Unit number.
   4108  *      ptp_id     - (IN) PTP stack ID.
   4109  *      clock_num  - (IN) PTP clock number.
   4110  *      clock_port - (IN) PTP clock port number.
   4111  * Returns:
   4112  *      BCM_E_XXX
   4113  * Notes:
   4114  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.2.3.
   4115  */
   4116 int
   4117 bcm_common_ptp_clock_port_enable(
   4118     int unit,
   4119     bcm_ptp_stack_id_t ptp_id,
   4120     int clock_num,
   4121     uint32 clock_port)
   4122 {
   4123     int rv = BCM_E_UNAVAIL;
   4124 
   4125     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4126     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4127 
   4128     bcm_ptp_port_identity_t portid;
   4129 
   4130     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   4131             clock_port))) {
   4132         return rv;
   4133     }
   4134 
   4135     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4136             clock_num, clock_port, &portid))) {
   4137         return rv;
   4138     }
   4139 
   4140     /* Empty payload. */
   4141 
   4142     if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id,
   4143             clock_num, &portid, PTP_MGMTMSG_CMD, PTP_MGMTMSG_ID_ENABLE_PORT,
   4144             0, 0, resp, &resp_len))) {
   4145         return rv;
   4146     }
   4147 
   4148     /* Restore/re-subscribe static unicast slave table. */
   4149     if (BCM_FAILURE(rv = _bcm_ptp_unicast_slave_stack_restore(unit, ptp_id,
   4150             clock_num, clock_port))) {
   4151         LOG_ERROR(BSL_LS_BCM_COMMON,
   4152                   (BSL_META_U(unit,
   4153                               "_bcm_ptp_unicast_slave_stack_restore failed\n")));
   4154         return rv;
   4155     }
   4156 
   4157     return BCM_E_NONE;
   4158 }
   4159 
   4160 /*
   4161  * Function:
   4162  *      bcm_common_ptp_clock_port_disable
   4163  * Purpose:
   4164  *      Disable a PTP clock port of an ordinary clock (OC) or a boundary
   4165  *      clock (BC).
   4166  * Parameters:
   4167  *      unit       - (IN) Unit number.
   4168  *      ptp_id     - (IN) PTP stack ID.
   4169  *      clock_num  - (IN) PTP clock number.
   4170  *      clock_port - (IN) PTP clock port number.
   4171  * Returns:
   4172  *      BCM_E_XXX
   4173  * Notes:
   4174  *      Ref. IEEE Std. 1588-2008, Chapter 15.5.3.2.4.
   4175  */
   4176 int
   4177 bcm_common_ptp_clock_port_disable(
   4178     int unit,
   4179     bcm_ptp_stack_id_t ptp_id,
   4180     int clock_num,
   4181     uint32 clock_port)
   4182 {
   4183     int rv = BCM_E_UNAVAIL;
   4184 
   4185     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4186     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4187 
   4188     bcm_ptp_port_identity_t portid;
   4189 
   4190     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   4191             clock_port))) {
   4192         return rv;
   4193     }
   4194 
   4195     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4196             clock_num, clock_port, &portid))) {
   4197         return rv;
   4198     }
   4199 
   4200     /* Empty payload. */
   4201 
   4202     if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id,
   4203             clock_num, &portid, PTP_MGMTMSG_CMD, PTP_MGMTMSG_ID_DISABLE_PORT,
   4204             0, 0, resp, &resp_len))) {
   4205         return rv;
   4206     }
   4207 
   4208     /* Remove signaled slaves. */
   4209     if (BCM_FAILURE(rv = bcm_common_ptp_signaled_unicast_slave_table_clear(unit, ptp_id,
   4210             clock_num, clock_port, 0))) {
   4211         LOG_ERROR(BSL_LS_BCM_COMMON,
   4212                   (BSL_META_U(unit,
   4213                               "bcm_common_ptp_signaled_unicast_slave_table_clear failed\n")));
   4214         return rv;
   4215     }
   4216 
   4217     /*
   4218      * NOTE: Implementation.
   4219      * Firmware clears unicast slaves, which is sufficient to prevent sending
   4220      * PTP messages from a disabled port. Do not clear static unicast slaves,
   4221      * so table can be restored/re-subscribed if port is re-enabled. See also
   4222      * ENABLE_PORT management message API.
   4223      */
   4224 
   4225     /* Remove static slaves. */
   4226     /*
   4227     if (BCM_FAILURE(rv = _bcm_ptp_unicast_slave_host_reset(unit, ptp_id,
   4228             clock_num, clock_port))) {
   4229         LOG_ERROR(BSL_LS_BCM_COMMON,
   4230                   (BSL_META_U(unit,
   4231                               "_bcm_ptp_unicast_slave_host_reset failed\n")));
   4232         return rv;
   4233     }
   4234      */
   4235 
   4236     return BCM_E_NONE;
   4237 }
   4238 
   4239 /*
   4240  * Function:
   4241  *      bcm_common_ptp_clock_port_configure
   4242  * Purpose:
   4243  *      Configure a PTP clock port.
   4244  * Parameters:
   4245  *      unit       - (IN) Unit number.
   4246  *      ptp_id     - (IN) PTP stack ID.
   4247  *      clock_num  - (IN) PTP clock number.
   4248  *      clock_port - (IN) PTP clock port number.
   4249  *      info       - (IN) PTP clock port configuration information.
   4250  * Returns:
   4251  *      BCM_E_XXX
   4252  * Notes:
   4253  */
   4254 int
   4255 bcm_common_ptp_clock_port_configure(
   4256     int unit,
   4257     bcm_ptp_stack_id_t ptp_id,
   4258     int clock_num,
   4259     uint32 clock_port,
   4260     bcm_ptp_clock_port_info_t *info)
   4261 {
   4262     int rv = BCM_E_UNAVAIL;
   4263 
   4264     uint8 payload[PTP_MGMTMSG_PAYLOAD_CONFIGURE_CLOCK_PORT_SIZE_OCTETS] = {0};
   4265     uint16 payload_len = 0;
   4266     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4267     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4268     int i = 0;
   4269     uint8 *format_str = 0;
   4270     uint8 *mask_str = 0;
   4271 
   4272     bcm_ptp_clock_info_t ci;
   4273     bcm_ptp_port_identity_t portid;
   4274 
   4275     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   4276             clock_port))) {
   4277         return rv;
   4278     }
   4279 
   4280     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4281             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   4282         return rv;
   4283     }
   4284     /* Get the clock Info */
   4285     if (BCM_FAILURE(rv =
   4286             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   4287         LOG_ERROR(BSL_LS_BCM_COMMON,
   4288                   (BSL_META_U(unit,
   4289                               "_bcm_ptp_clock_cache_info_get failed\n")));
   4290         return rv;
   4291     }
   4292 
   4293 
   4294     /* Remove signaled slaves. */
   4295     if (BCM_FAILURE(rv = bcm_common_ptp_signaled_unicast_slave_table_clear(unit, ptp_id,
   4296             clock_num, clock_port, 1))) {
   4297         PTP_ERROR_FUNC("\n bcm_common_ptp_signaled_unicast_slave_table_clear");
   4298         return rv;
   4299     }
   4300 
   4301     /*
   4302      * Make payload.
   4303      *    Octet 0...2     : Custom management message key/identifier.
   4304      *                      Octet 0= 'B'; Octet 1= 'C'; Octet 2= 'M'.
   4305      *    Octet 3...5     : Reserved.
   4306      *    Octet 6         : PTP clock number.
   4307      *    Octet 7...8     : PTP clock port number.
   4308      *    Octet 9...14    : Port MAC address.
   4309      *    Octet 15        : Network protocol.
   4310      *    Octet 16...31   : Port address.
   4311      *    Octet 32        : Port type.
   4312      *    Octet 33        : Log minimum delay request interval.
   4313      *    Octet 34        : Multicast L2 header size (octets).
   4314      *    Octet 35...98   : Multicast L2 header.
   4315      *    Octet 99        : Multicast (peer delay) L2 header size (octets).
   4316      *    Octet 100...163 : Multicast (peer delay) L2 header.
   4317      *    Octet 164       : Multicast Tx enable Boolean.
   4318      *    Octet 165...166 : Port Rx packets VLAN.
   4319      *    Octet 167...170 : Port Rx packets port mask (high 32 bits).
   4320      *    Octet 171...174 : Port Rx packets port mask (low 32 bits).
   4321      *    Octet 175       : Port Rx packets criteria mask.
   4322      *    Octet 176       : Rx timestamp mechanism.
   4323      *    Octet 177       : Local priority.
   4324      *          Virtual port's configuration
   4325      *    Octet 178       : clock class.
   4326      *    Octet 179       : clock accuracy.
   4327      *    Octet 180-181   : offset scaled log var.
   4328      *    Octet 182-183   : steps removed.
   4329      *    Octet 184       : GM priority2.
   4330      *    Octet 185-188   : TOD offset sec.
   4331      *    Octet 189-192   : TOD offset nsec.
   4332      *    Octet 193       : TOD format type.
   4333      *    Octet 194       : TOD Fmt string length.
   4334      *    Octet 195-226   : TOD Fmt string.
   4335      *    Octet 227       : TOD Mask string length.
   4336      *    Octet 228-355   : TOD Mask string.
   4337      *    Octet 356-357   : Ethertype for TOD pkts.
   4338      *    Octet 358       : 1PPS GPIO pin#.
   4339      */
   4340     i = 0;
   4341     payload[i++] = 'B';
   4342     payload[i++] = 'C';
   4343     payload[i++] = 'M';
   4344     i += 3;
   4345 
   4346     payload[i++] = clock_num;
   4347 
   4348     _bcm_ptp_uint16_write(payload+i, clock_port);
   4349     i += sizeof(uint16);
   4350 
   4351     sal_memcpy(payload+i, info->mac, PTP_MAC_ADDR_SIZE_BYTES);
   4352     i += PTP_MAC_ADDR_SIZE_BYTES;
   4353 
   4354     payload[i++] = info->port_address.addr_type;
   4355 
   4356     switch (info->port_address.addr_type) {
   4357     case (bcmPTPUDPIPv4):
   4358         /* Ethernet/UDP/IPv4 address. */
   4359         sal_memcpy(payload+i, info->port_address.address,
   4360                    PTP_IPV4_ADDR_SIZE_BYTES);
   4361         break;
   4362 
   4363     case (bcmPTPUDPIPv6):
   4364         /* Ethernet/UDP/IPv6 address. */
   4365         sal_memcpy(payload+i, info->port_address.address,
   4366                    PTP_IPV6_ADDR_SIZE_BYTES);
   4367         break;
   4368 
   4369     case (bcmPTPIEEE8023):
   4370         /* Ethernet Layer 2. */
   4371         sal_memcpy(payload+i, info->port_address.address,
   4372                    PTP_MAC_ADDR_SIZE_BYTES);
   4373         break;
   4374 
   4375     default:
   4376         /* Invalid address type. */
   4377         return BCM_E_UNAVAIL;
   4378     }
   4379 
   4380     i += BCM_PTP_MAX_NETW_ADDR_SIZE;
   4381 
   4382     payload[i++] = info->port_type;
   4383 
   4384     if ((info->log_min_delay_req_interval < ci.log_min_delay_req_interval_minimum) ||
   4385             (info->log_min_delay_req_interval > ci.log_min_delay_req_interval_maximum)) {
   4386         /*
   4387          * Caller provided log minimum peer delay (PDelay) request interval
   4388          * value is not in (min,max) range of PTP profile.
   4389          */
   4390         return BCM_E_PARAM;
   4391     }
   4392     payload[i++] = info->log_min_delay_req_interval;
   4393 
   4394     if (info->multicast_l2_size > PTP_MAX_L2_HEADER_LENGTH) {
   4395         /* Multicast L2 header length exceeds device-compliant maximum size. */
   4396         return BCM_E_PARAM;
   4397     }
   4398     payload[i++] = info->multicast_l2_size;
   4399     sal_memcpy(payload+i, info->multicast_l2, info->multicast_l2_size);
   4400     i += PTP_MSG_L2_HEADER_LENGTH;
   4401 
   4402     if (info->multicast_pdelay_l2_size > PTP_MAX_L2_HEADER_LENGTH) {
   4403         /* Multicast peer-delay L2 header length exceeds device-compliant maximum size. */
   4404         return BCM_E_PARAM;
   4405     }
   4406     payload[i++] = info->multicast_pdelay_l2_size;
   4407     sal_memcpy(payload+i, info->multicast_pdelay_l2,
   4408                info->multicast_pdelay_l2_size);
   4409     i += PTP_MSG_L2_HEADER_LENGTH;
   4410 
   4411     payload[i++] = (1 & info->multicast_tx_enable);
   4412 
   4413     _bcm_ptp_uint16_write(payload+i, info->rx_packets_vlan);
   4414     i += sizeof(uint16);
   4415 
   4416     _bcm_ptp_uint32_write(payload+i, info->rx_packets_port_mask_high32);
   4417     i += sizeof(uint32);
   4418 
   4419     _bcm_ptp_uint32_write(payload+i, info->rx_packets_port_mask_low32);
   4420     i += sizeof(uint32);
   4421 
   4422     payload[i++] = info->rx_packets_criteria_mask;
   4423     payload[i++] = info->rx_timestamp_mechanism;
   4424     payload[i++] = info->local_priority;
   4425 
   4426     if (info->port_type == bcmPTPPortTypeVirtual ||
   4427                 info->port_type == bcmPTPPortTypeCustomizedVirtual) {
   4428         /* include virtual port's configuration  */
   4429         payload[i++] = info->vport_info.clock_class;
   4430         payload[i++] = (uint8)info->vport_info.clock_accuracy;
   4431 
   4432         _bcm_ptp_uint16_write(payload+i, info->vport_info.offset_scaled_log_variance);
   4433         i += sizeof(uint16);
   4434 
   4435         _bcm_ptp_uint16_write(payload+i, info->vport_info.steps_removed);
   4436         i += sizeof(uint16);
   4437 
   4438         payload[i++] = info->vport_info.GM_prio2;
   4439 
   4440         _bcm_ptp_uint32_write(payload+i, info->vport_info.tod_offset_sec);
   4441         i += sizeof(uint32);
   4442 
   4443         _bcm_ptp_uint32_write(payload+i, info->vport_info.tod_offset_ns);
   4444         i += sizeof(uint32);
   4445 
   4446         /* convert to firmware order */
   4447         payload[i++] = (info->vport_info.format + 1);
   4448 
   4449         format_str = info->vport_info.format_str;
   4450         payload[i++] = ( (format_str) ?
   4451 		                   MIN( strlen((char*)format_str), PTP_TIMESOURCE_TODIN_MGMTMSG_FORMAT_LENGTH ) :
   4452 						   0);
   4453         if (format_str) {
   4454             sal_memcpy(&payload[i], format_str, PTP_TIMESOURCE_TODIN_MGMTMSG_FORMAT_LENGTH);
   4455         }
   4456         i += PTP_TIMESOURCE_TODIN_MGMTMSG_FORMAT_LENGTH;
   4457 
   4458         mask_str = info->vport_info.mask_str;
   4459         payload[i++] = ((mask_str) ? strlen((char*)mask_str) : 0);
   4460         if (mask_str) {
   4461             sal_memcpy(&payload[i], mask_str, PTP_TIMESOURCE_TODIN_MGMTMSG_MASK_LENGTH);
   4462         }
   4463         i += PTP_TIMESOURCE_TODIN_MGMTMSG_MASK_LENGTH;
   4464 
   4465         _bcm_ptp_uint16_write(payload+i, info->vport_info.ether_type);
   4466         i += sizeof(uint16);
   4467 
   4468         payload[i++] = info->vport_info.onepps_in_gpio;
   4469         if (PTP_UC_FEATURE_CHECK(PTP_VP_TOD_IN_SERIAL)) {
   4470             payload[i++] = info->vport_info.tod_source;
   4471             _bcm_ptp_uint32_write(payload+i, info->vport_info.tod_baud_rate);
   4472             i += sizeof(uint32);
   4473         }
   4474     }
   4475 
   4476 	if (i <= PTP_MGMTMSG_PAYLOAD_CONFIGURE_CLOCK_PORT_SIZE_OCTETS) {
   4477         payload_len = i;
   4478     }
   4479 /*  Commenting below check to prevent coverity error
   4480 	else {
   4481         return BCM_E_INTERNAL;
   4482     }
   4483 */
   4484 
   4485     if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id,
   4486             clock_num, &portid,
   4487             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CONFIGURE_CLOCK_PORT,
   4488             payload, payload_len,
   4489             resp, &resp_len))) {
   4490         return rv;
   4491     }
   4492 
   4493     if (BCM_FAILURE(rv =
   4494             _bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci))) {
   4495         LOG_ERROR(BSL_LS_BCM_COMMON,
   4496                   (BSL_META_U(unit,
   4497                               "_bcm_ptp_clock_cache_info_get failed\n")));
   4498         return rv;
   4499     }
   4500 
   4501     if (ci.type != bcmPTPClockTypeTransparent)
   4502     {
   4503         /* Set log announce interval. */
   4504         if (BCM_FAILURE(rv =
   4505                 bcm_common_ptp_clock_port_log_announce_interval_set(unit, ptp_id,
   4506                 clock_num, clock_port, (int)(info->log_announce_interval)))) {
   4507             return rv;
   4508         }
   4509 
   4510         /* Set log sync interval. */
   4511         if (BCM_FAILURE(rv =
   4512                 bcm_common_ptp_clock_port_log_sync_interval_set(unit, ptp_id,
   4513                 clock_num, clock_port, info->log_sync_interval))) {
   4514             return rv;
   4515         }
   4516 
   4517         /* Set announce receipt timeout. */
   4518         if (BCM_FAILURE(rv =
   4519                 bcm_common_ptp_clock_port_announce_receipt_timeout_set(unit, ptp_id,
   4520                 clock_num, clock_port, info->announce_receipt_timeout))) {
   4521             return rv;
   4522         }
   4523     }
   4524 
   4525     /* Set delay mechanism. */
   4526     if (BCM_FAILURE(rv =
   4527             bcm_common_ptp_clock_port_delay_mechanism_set(unit, ptp_id,
   4528             clock_num, clock_port, info->delay_mechanism))) {
   4529         return rv;
   4530     }
   4531 
   4532     /* Assign PTP clock port information to cache. */
   4533     _bcm_common_ptp_unit_array[unit].stack_array[ptp_id]
   4534                             .clock_array[clock_num]
   4535                             .port_info[clock_port-1] = *info;
   4536 
   4537     return rv;
   4538 }
   4539 
   4540 /*
   4541  * Function:
   4542  *      _bcm_ptp_clock_class_set
   4543  * Purpose:
   4544  *      Set the PTP clock class.
   4545  * Parameters:
   4546  *      unit       - (IN) Unit number.
   4547  *      ptp_id     - (IN) PTP stack ID.
   4548  *      clock_num  - (IN) PTP clock number.
   4549  *      clockClass - (IN) PTP clock class.
   4550  * Returns:
   4551  *      BCM_E_XXX - Function status.
   4552  * Notes:
   4553  */
   4554 int
   4555 _bcm_ptp_clock_class_set(
   4556     int unit,
   4557     bcm_ptp_stack_id_t ptp_id,
   4558     int clock_num,
   4559     uint8 clockClass)
   4560 {
   4561     int rv = BCM_E_NONE;
   4562     int i = 0;
   4563 
   4564     uint8 payload[PTP_MGMTMSG_PAYLOAD_CLOCK_CLASS_SIZE_OCTETS] = {0};
   4565     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4566     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4567 
   4568     bcm_ptp_clock_info_t ci;
   4569     bcm_ptp_port_identity_t portid;
   4570 
   4571     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
   4572             clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   4573         return rv;
   4574     }
   4575 
   4576     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4577             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   4578         /* On error, target message to (all clocks, all ports) portIdentity. */
   4579         portid = portid_all;
   4580     }
   4581 
   4582     /*
   4583      * Make payload.
   4584      *    Octet 0...5 : Custom management message key/identifier.
   4585      *                  BCM<null><null><null>.
   4586      *    Octet 6     : PTP clockClass.
   4587      *    Octet 7     : Reserved.
   4588      */
   4589     sal_memcpy(payload, "BCM\0\0\0", 6);
   4590     i = 6;
   4591     payload[i] = clockClass;
   4592 
   4593     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num,
   4594             &portid, PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_CLASS,
   4595             payload, PTP_MGMTMSG_PAYLOAD_CLOCK_CLASS_SIZE_OCTETS,
   4596             resp, &resp_len);
   4597 
   4598     /* Update PTP clock cache. */
   4599     if (rv == BCM_E_NONE) {
   4600         if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_info_get(unit, ptp_id,
   4601                 clock_num, &ci))) {
   4602             LOG_ERROR(BSL_LS_BCM_COMMON,
   4603                       (BSL_META_U(unit,
   4604                                   "_bcm_ptp_clock_cache_info_get\n")));
   4605             return rv;
   4606         }
   4607 
   4608         ci.clock_class = clockClass;
   4609         rv = _bcm_ptp_clock_cache_info_set(unit, ptp_id, clock_num, &ci);
   4610     }
   4611 
   4612     return rv;
   4613 }
   4614 
   4615 /*
   4616  * Function:
   4617  *      _bcm_ptp_system_log_configure
   4618  * Purpose:
   4619  *      Set the debug log level for the firmware.
   4620  * Parameters:
   4621  *      unit       - (IN) Unit number.
   4622  *      ptp_id     - (IN) PTP stack ID.
   4623  *      clock_num  - (IN) PTP clock number.
   4624  *      level_mask - (IN) bitmask of log levels
   4625  * Returns:
   4626  *      BCM_E_XXX
   4627  */
   4628 int
   4629 _bcm_ptp_system_log_configure(int unit, bcm_ptp_stack_id_t ptp_id, int clock_num,
   4630                               uint32 debug_mask, uint64 udp_log_mask,
   4631                               bcm_mac_t src_mac, bcm_mac_t dest_mac,
   4632                               uint16 tpid, uint16 vid, uint8 ttl,
   4633                               bcm_ip_t src_addr, bcm_ip_t dest_addr,
   4634                               uint16 udp_port)
   4635 {
   4636     int rv = BCM_E_UNAVAIL;
   4637 
   4638     uint8 payload[PTP_MGMTMSG_PAYLOAD_LOG_LEVEL_SIZE_OCTETS] = {0};
   4639     uint8 *curs = &payload[0];
   4640     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4641     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4642 
   4643     bcm_ptp_port_identity_t portid;
   4644 
   4645     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   4646             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   4647         return rv;
   4648     }
   4649 
   4650     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4651             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   4652         return rv;
   4653     }
   4654 
   4655 #ifdef BCM_PTP_EXT_SERVO_SUPPORT
   4656     if (BCM_FAILURE(rv = _bcm_ptp_servo_debug_level_set(unit, ptp_id, clock_num, 0, debug_mask))) {
   4657         LOG_ERROR(BSL_LS_BCM_PTP,
   4658                         (BSL_META_U(unit, "_bcm_ptp_servo_debug_level_set() \n")));
   4659     }
   4660 
   4661     if (BCM_FAILURE(rv = _bcm_ptp_servo_sys_log_set(unit, ptp_id, clock_num, udp_log_mask, dest_addr, udp_port))) {
   4662 	    LOG_ERROR(BSL_LS_BCM_PTP,
   4663 			  (BSL_META_U(unit, "_bcm_ptp_servo_sys_log_set() \n")));
   4664     }
   4665 
   4666 	if(!PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
   4667         /* log level mask bits for ext servo are consumed. clear them */
   4668         debug_mask   &= 0xFF00FFFF;
   4669         udp_log_mask &= 0xFF00FFFF;
   4670     }
   4671 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */
   4672 
   4673     /*
   4674      * Make payload.
   4675      *    Octet 0..5:   BCM<nul><nul><nul>
   4676      *    Octet 6..9:  new debug mask level
   4677      *    Octet 10..17: new log mask level
   4678      *    Octet 18..23: src_mac for log packets
   4679      *    Octet 24..29: dst_mac for log packets
   4680      *    Octet 30..31: tpid for log packets
   4681      *    Octet 32..33: vid for log packets
   4682      *    Octet 34:     TTL for log packets
   4683      *    Octet 35..38: src_ip for log packets
   4684      *    Octet 39..42: dst_ip for log packets
   4685      *    Octet 43..46: UDP port for log packets
   4686      */
   4687     sal_memcpy(curs, "BCM\0\0\0", 6); curs += 6;
   4688     _bcm_ptp_uint32_write(curs, debug_mask);   curs += 4;
   4689     _bcm_ptp_uint64_write(curs, udp_log_mask); curs += 8;
   4690     sal_memcpy(curs, src_mac, 6);        curs += 6;
   4691     sal_memcpy(curs, dest_mac, 6);       curs += 6;
   4692     _bcm_ptp_uint16_write(curs, tpid); curs += 2;
   4693     _bcm_ptp_uint16_write(curs, vid);  curs += 2;
   4694     *curs = ttl;  curs++;
   4695     _bcm_ptp_uint32_write(curs, src_addr);  curs += 4;
   4696     _bcm_ptp_uint32_write(curs, dest_addr); curs += 4;
   4697     _bcm_ptp_uint16_write(curs, udp_port);  curs += 2;
   4698 
   4699     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num,
   4700                                           &portid, PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_LOG_LEVEL,
   4701                                           payload, curs - payload, resp, &resp_len);
   4702 
   4703     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   4704             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_LOG_LEVEL,
   4705             payload, PTP_MGMTMSG_PAYLOAD_LOG_LEVEL_SIZE_OCTETS,
   4706             resp, &resp_len);
   4707 
   4708     return rv;
   4709 }
   4710 
   4711 /*
   4712  * Function:
   4713  *      _bcm_ptp_tunnel_arp_set
   4714  * Purpose:
   4715  *      Set flag to turn on/off ARP packet tunneling.
   4716  * Parameters:
   4717  *      unit   - (IN) Unit number.
   4718  *      ptp_id - (IN) PTP stack ID.
   4719  *      flag   - (IN) Tunnel ARP packets Boolean.
   4720  * Returns:
   4721  *      BCM_E_XXX
   4722  * Notes:
   4723  */
   4724 int
   4725 _bcm_ptp_tunnel_arp_set(
   4726     int unit,
   4727     bcm_ptp_stack_id_t ptp_id,
   4728     uint8 flag)
   4729 {
   4730     int rv = BCM_E_UNAVAIL;
   4731 
   4732     uint8 payload[PTP_MGMTMSG_PAYLOAD_TUNNEL_ARP_SIZE_OCTETS] = {0};
   4733     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4734     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4735     int i = 0;
   4736 
   4737     bcm_ptp_port_identity_t portid;
   4738 
   4739     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
   4740             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   4741         return rv;
   4742     }
   4743 
   4744     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4745             PTP_CLOCK_NUMBER_DEFAULT, PTP_IEEE1588_ALL_PORTS, &portid))) {
   4746         /* On error, target message to (all clocks, all ports) portIdentity. */
   4747         portid = portid_all;
   4748     }
   4749 
   4750     /*
   4751      * Parse response.
   4752      *    Octet 0...5 : Custom management message key/identifier.
   4753      *                  BCM<null><null><null>.
   4754      *    Octet 6     : Tunnel ARP packets Boolean.
   4755      *    Octet 7     : Reserved (pad).
   4756      */
   4757     sal_memcpy(payload, "BCM\0\0\0", 6);
   4758     i = 6;
   4759     payload[i] = (flag & 0x01);
   4760 
   4761     rv = _bcm_ptp_management_message_send(unit, ptp_id, PTP_CLOCK_NUMBER_DEFAULT,
   4762             &portid, PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_TUNNEL_ARP,
   4763             payload, PTP_MGMTMSG_PAYLOAD_TUNNEL_ARP_SIZE_OCTETS,
   4764             resp, &resp_len);
   4765 
   4766     return rv;
   4767 }
   4768 
   4769 /*
   4770  * Function:
   4771  *      bcm_common_clock_bmca_override_get
   4772  * Purpose:
   4773  *      Set flag to turn on/off ARP packet tunneling.
   4774  * Parameters:
   4775  *      unit         - (IN) Unit number.
   4776  *      ptp_id       - (IN) PTP stack ID.
   4777  *      flags        - (IN) Flag mask.
   4778  *      enable_mask  - (IN) Enable/Disable use of flag for BMCA
   4779  * Returns:
   4780  *      BCM_E_XXX
   4781  * Notes:
   4782  * Flags parameter will be used to identify a flag and enable_mask value
   4783  * will be used to enable/disable the use of the flag for Alternate BMCA
   4784  * when G8275.1 profile is enabled. Mask bit 0-Flag received in Announce
   4785  * messages will be used to qualify/dis-qualify the master from BMCA.
   4786  * Mask bit 1-Flag received in Announce messages will NOT be used for BMCA
   4787  *
   4788  * NOTE: This feature is valid only when G.8275.1 profile is enabled.
   4789  *       Otherwise the Mask bit value is ignored during BMCA.
   4790  */
   4791 int bcm_common_clock_bmca_override_set(
   4792         int unit,
   4793         bcm_ptp_stack_id_t ptp_id,
   4794         int clock_num,
   4795         uint32 flags,
   4796         uint32 enable_mask)
   4797 {
   4798     int rv = BCM_E_UNAVAIL;
   4799 
   4800     uint8 payload[PTP_MGMTMSG_PAYLOAD_CLOCK_BMCA_FLAG_OVERRIDE_SIZE_OCTETS] = {0};
   4801     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4802     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4803 
   4804     bcm_ptp_port_identity_t portid;
   4805 
   4806     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   4807             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   4808         return rv;
   4809     }
   4810 
   4811     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4812             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   4813         return rv;
   4814     }
   4815 
   4816     /*
   4817      * Make payload.
   4818      *    Octet 0-3 : flags.
   4819      *    Octet 4-7 : enable_mask
   4820      */
   4821 
   4822     _bcm_ptp_uint32_write(payload, flags);
   4823     _bcm_ptp_uint32_write(payload+4, enable_mask);
   4824 
   4825     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   4826             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_BMCA_FLAG_OVERRIDE,
   4827             payload, PTP_MGMTMSG_PAYLOAD_CLOCK_BMCA_FLAG_OVERRIDE_SIZE_OCTETS,
   4828             resp, &resp_len);
   4829     return rv;
   4830 }
   4831 
   4832 /*
   4833  * Function:
   4834  *      bcm_common_clock_bmca_override_get
   4835  * Purpose:
   4836  *      Set flag to turn on/off ARP packet tunneling.
   4837  * Parameters:
   4838  *      unit         - (IN) Unit number.
   4839  *      ptp_id       - (IN) PTP stack ID.
   4840  *      flags        - (OUT) Flag mask.
   4841  *      enable_mask  - (OUT) Enable/Disable use of flag for BMCA
   4842  * Returns:
   4843  *      BCM_E_XXX
   4844  * Notes:
   4845  * Flags parameter will be used to identify a flag and enable_mask value
   4846  * will be used to enable/disable the use of the flag for Alternate BMCA
   4847  * when G8275.1 profile is enabled. Mask bit 0-Flag received in Announce
   4848  * messages will be used to qualify/dis-qualify the master from BMCA.
   4849  * Mask bit 1-Flag received in Announce messages will NOT be used for BMCA
   4850  *
   4851  * NOTE: This feature is valid only when G.8275.1 profile is enabled.
   4852  *       Otherwise the Mask bit value is ignored during BMCA.
   4853  */
   4854 int bcm_common_clock_bmca_override_get(
   4855         int unit,
   4856         bcm_ptp_stack_id_t ptp_id,
   4857         int clock_num,
   4858         uint32 *flags,
   4859         uint32 *enable_mask)
   4860 {
   4861     int rv = BCM_E_UNAVAIL;
   4862 
   4863     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4864     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4865 
   4866     bcm_ptp_port_identity_t portid;
   4867 
   4868     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   4869             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   4870         return rv;
   4871     }
   4872 
   4873     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4874             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   4875         return rv;
   4876     }
   4877 
   4878     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   4879             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CLOCK_BMCA_FLAG_OVERRIDE,
   4880             0, 0, resp, &resp_len);
   4881 
   4882     if (rv == BCM_E_NONE) {
   4883         /*
   4884          * Parse response.
   4885          *    Octet 0-3 : flags.
   4886          *    Octet 4-7 : enable_mask
   4887          */
   4888         *flags = _bcm_ptp_uint32_read(resp);
   4889         *enable_mask = _bcm_ptp_uint32_read(resp+4);
   4890     }
   4891 
   4892     return rv;
   4893 }
   4894 
   4895 /*
   4896  * Function:
   4897  *      _bcm_common_clock_apts_mode_set
   4898  * Parameters:
   4899  *      unit         - (IN) Unit number.
   4900  *      ptp_id       - (IN) PTP stack ID.
   4901  *      flags        - (IN) op_mode.
   4902  * Returns:
   4903  *      BCM_E_XXX
   4904  * Notes:
   4905  * APTS op_mode parameter is sent to FW
   4906  */
   4907 int _bcm_common_clock_apts_mode_set(
   4908         int unit,
   4909         bcm_ptp_stack_id_t ptp_id,
   4910         int clock_num,
   4911         bcm_ptp_clock_apts_mode_t op_mode,
   4912         int apts_enabled)
   4913 {
   4914     int rv = BCM_E_UNAVAIL;
   4915 
   4916     uint8 payload[PTP_MGMTMSG_PAYLOAD_CLOCK_APTS_MODE_CHANGED_SIZE_OCTETS] = {0};
   4917     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   4918     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   4919 
   4920     bcm_ptp_port_identity_t portid;
   4921 
   4922     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   4923             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   4924         return rv;
   4925     }
   4926 
   4927     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   4928             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   4929         return rv;
   4930     }
   4931 
   4932     /*
   4933      * Make payload.
   4934      *    Octet 0-3 : apts_enabled.
   4935      *    Octet 4-7 : op_mode.
   4936      */
   4937 
   4938     _bcm_ptp_uint32_write(payload, apts_enabled);
   4939     _bcm_ptp_uint32_write(payload+4, (uint32)op_mode);
   4940 
   4941     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   4942             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_APTS_MODE_CHANGED,
   4943             payload, PTP_MGMTMSG_PAYLOAD_CLOCK_APTS_MODE_CHANGED_SIZE_OCTETS,
   4944             resp, &resp_len);
   4945     return rv;
   4946 }
   4947 
   4948 void _bcm_ptp_apts_get_op_mode_string(bcm_ptp_clock_apts_mode_t op_mode, char *ret_str)
   4949 {
   4950     switch (op_mode){
   4951     case bcmPtpClockAptsModeSyncEGps:
   4952         strcpy(ret_str,"SyncE|GPS");
   4953         break;
   4954     case bcmPtpClockAptsModeSyncEPtp:
   4955         strcpy(ret_str,"SyncE|PTP");
   4956         break;
   4957     case bcmPtpClockAptsModeGpsGps:
   4958         strcpy(ret_str,"GPS|GPS");
   4959         break;
   4960     case bcmPtpClockAptsModePtpPtp:
   4961         strcpy(ret_str,"PTP|PTP");
   4962         break;
   4963     case bcmPtpClockAptsModeSyncEHoldover:
   4964         strcpy(ret_str,"SyncE|Holdover");
   4965         break;
   4966     case bcmPtpClockAptsModeHoldoverHoldover:
   4967         strcpy(ret_str,"Holdover|Holdover");
   4968         break;
   4969     default:
   4970         strcpy(ret_str,"Error invalid op_mode!");
   4971         break;
   4972     }
   4973     return;
   4974 }
   4975 void _bcm_ptp_apts_update_current_mode()
   4976 {
   4977     int i;
   4978     bcm_ptp_clock_apts_mode_t old_op_mode = g_apts_current_op_mode;
   4979     char old_op_mode_str[20] = {0}, new_op_mode_str[20] = {0};
   4980 
   4981     for (i = 0; i < g_apts_op_mode_lists[g_apts_op_mode_list_idx].num_nodes; i++)
   4982     {
   4983         if((g_apts_op_mode_lists[g_apts_op_mode_list_idx].op_mode_list[i].required_sources & g_apts_current_source_state) == g_apts_op_mode_lists[g_apts_op_mode_list_idx].op_mode_list[i].required_sources){
   4984             g_apts_current_op_mode = g_apts_op_mode_lists[g_apts_op_mode_list_idx].op_mode_list[i].op_mode;
   4985             break;
   4986         }
   4987     }
   4988 
   4989     if (old_op_mode != g_apts_current_op_mode){
   4990         _bcm_ptp_apts_get_op_mode_string(old_op_mode, old_op_mode_str);
   4991         _bcm_ptp_apts_get_op_mode_string(g_apts_current_op_mode, new_op_mode_str);
   4992         _bcm_common_clock_apts_mode_set(0,0,0,g_apts_current_op_mode, g_apts_enabled);
   4993         cli_out("[APTS] Operating mode changed <Freq source|Time source>: %s -> %s", old_op_mode_str, new_op_mode_str);
   4994     }
   4995     return;
   4996 }
   4997 
   4998 
   4999 int _bcm_ptp_apts_clk_src_2_source_avail(
   5000     bcm_ptp_clock_apts_source_t in_source,
   5001     _bcm_ptp_apts_source_avail_t *out_source)
   5002 {
   5003     int rv = BCM_E_NONE;
   5004 
   5005     switch(in_source){
   5006     case bcmPtpClockAptsSourceSynceInternalDpll:
   5007         *out_source = _bcm_ptp_apts_avail_synce;
   5008         break;
   5009 
   5010     case bcmPtpClockAptsSourceSynceExternalDpll:
   5011         *out_source = _bcm_ptp_apts_avail_synce;
   5012         break;
   5013 
   5014     case bcmPtpClockAptsSourceGps:
   5015         *out_source = _bcm_ptp_apts_avail_gps;
   5016         break;
   5017 
   5018     case bcmPtpClockAptsSourcePtp:
   5019         *out_source = _bcm_ptp_apts_avail_ptp;
   5020         break;
   5021 
   5022     default:
   5023         PTP_ERROR("Error: Invalid source priority!\n");
   5024         rv = BCM_E_PARAM;
   5025         break;
   5026 
   5027     }
   5028 
   5029     return rv;
   5030 }
   5031 
   5032 /*
   5033  * This API is used to enable/disable the APTS automatic switching
   5034  * feature.
   5035  */
   5036 int bcm_common_ptp_clock_apts_enable_get(
   5037     int unit,
   5038     bcm_ptp_stack_id_t ptp_id,
   5039     int clock_num,
   5040     int *enable)
   5041 {
   5042     int rv = BCM_E_NONE;
   5043     *enable = g_apts_enabled;
   5044     return rv;
   5045 }
   5046 
   5047 /*
   5048  * This API is used to enable/disable the APTS automatic switching
   5049  * feature.
   5050  */
   5051 int bcm_common_ptp_clock_apts_enable_set(
   5052     int unit,
   5053     bcm_ptp_stack_id_t ptp_id,
   5054     int clock_num,
   5055     int enable)
   5056 {
   5057     int rv = BCM_E_NONE;
   5058     g_apts_enabled = enable;
   5059     if (enable == 0){
   5060         g_apts_current_op_mode = bcmPtpClockAptsModePtpPtp;
   5061         g_apts_op_mode_list_idx = BCM_APTS_OP_MODE_LIST_IDX_PTP;
   5062     }
   5063 
   5064     _bcm_ptp_apts_update_current_mode();
   5065     return rv;
   5066 }
   5067 
   5068 /*
   5069  * This API is used to get the priority order for time and frequency
   5070  * sources.
   5071  */
   5072 int bcm_common_ptp_clock_apts_source_prio_get(
   5073     int unit,
   5074     bcm_ptp_stack_id_t ptp_id,
   5075     int clock_num,
   5076     int *num_sources,
   5077     bcm_ptp_clock_apts_source_t *priority_list)
   5078 {
   5079     int rv = BCM_E_NONE;
   5080     priority_list = g_apts_usr_cfgd_priority_list;
   5081     return rv;
   5082 }
   5083 
   5084 /*
   5085  * This API is used to get the priority order for time and frequency
   5086  * sources.
   5087  */
   5088 int bcm_common_ptp_clock_apts_source_prio_set(
   5089     int unit,
   5090     bcm_ptp_stack_id_t ptp_id,
   5091     int clock_num,
   5092     int num_sources,
   5093     bcm_ptp_clock_apts_source_t *priority_list)
   5094 {
   5095     int rv = BCM_E_NONE;
   5096     int i = 0;
   5097     _bcm_ptp_apts_source_avail_t avail_prio_list[BCM_PTP_CLOCK_APTS_MAX_FREQ_SOURCES] = {_bcm_ptp_apts_avail_none};
   5098 
   5099     if (g_apts_enabled == 0){
   5100         return BCM_E_DISABLED;
   5101     }
   5102 
   5103     for (i = 0; i < num_sources; i++)
   5104     {
   5105         if (BCM_FAILURE(rv = _bcm_ptp_apts_clk_src_2_source_avail(priority_list[i], &avail_prio_list[i]))){
   5106             rv = BCM_E_PARAM;
   5107             return rv;
   5108         }
   5109         g_apts_usr_cfgd_priority_list[i] = priority_list[i];
   5110     }
   5111 
   5112     /* Start finding the operating mode list index */
   5113     if ((avail_prio_list[0] == _bcm_ptp_apts_avail_synce) && (avail_prio_list[1] == _bcm_ptp_apts_avail_gps) && (avail_prio_list[2] == _bcm_ptp_apts_avail_ptp)){
   5114         g_apts_op_mode_list_idx = 0;
   5115     }
   5116     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_synce) && (avail_prio_list[1] == _bcm_ptp_apts_avail_ptp) && (avail_prio_list[2] == _bcm_ptp_apts_avail_gps)){
   5117         g_apts_op_mode_list_idx = 1;
   5118     }
   5119     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_gps) && (avail_prio_list[1] == _bcm_ptp_apts_avail_synce) && (avail_prio_list[2] == _bcm_ptp_apts_avail_ptp)){
   5120         g_apts_op_mode_list_idx = 2;
   5121     }
   5122     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_gps) && (avail_prio_list[1] == _bcm_ptp_apts_avail_ptp) && (avail_prio_list[2] == _bcm_ptp_apts_avail_synce)){
   5123         g_apts_op_mode_list_idx = 3;
   5124     }
   5125     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_ptp) && (avail_prio_list[1] == _bcm_ptp_apts_avail_synce) && (avail_prio_list[2] == _bcm_ptp_apts_avail_gps)){
   5126         g_apts_op_mode_list_idx = 4;
   5127     }
   5128     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_ptp) && (avail_prio_list[1] == _bcm_ptp_apts_avail_gps) && (avail_prio_list[2] == _bcm_ptp_apts_avail_synce)){
   5129         g_apts_op_mode_list_idx = 5;
   5130     }
   5131     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_synce) && (avail_prio_list[1] == _bcm_ptp_apts_avail_gps) && (avail_prio_list[2] == _bcm_ptp_apts_avail_none)){
   5132         g_apts_op_mode_list_idx = 6;
   5133     }
   5134     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_synce) && (avail_prio_list[1] == _bcm_ptp_apts_avail_ptp) && (avail_prio_list[2] == _bcm_ptp_apts_avail_none)){
   5135         g_apts_op_mode_list_idx = 7;
   5136     }
   5137     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_gps) && (avail_prio_list[1] == _bcm_ptp_apts_avail_synce) && (avail_prio_list[2] == _bcm_ptp_apts_avail_none)){
   5138         g_apts_op_mode_list_idx = 8;
   5139     }
   5140     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_gps) && (avail_prio_list[1] == _bcm_ptp_apts_avail_ptp) && (avail_prio_list[2] == _bcm_ptp_apts_avail_none)){
   5141         g_apts_op_mode_list_idx = 9;
   5142     }
   5143     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_ptp) && (avail_prio_list[1] == _bcm_ptp_apts_avail_synce) && (avail_prio_list[2] == _bcm_ptp_apts_avail_none)){
   5144         g_apts_op_mode_list_idx = 10;
   5145     }
   5146     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_ptp) && (avail_prio_list[1] == _bcm_ptp_apts_avail_gps) && (avail_prio_list[2] == _bcm_ptp_apts_avail_none)){
   5147         g_apts_op_mode_list_idx = 11;
   5148     }
   5149     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_gps) && (avail_prio_list[1] == _bcm_ptp_apts_avail_none) && (avail_prio_list[2] == _bcm_ptp_apts_avail_none)){
   5150         g_apts_op_mode_list_idx = 12;
   5151     }
   5152     else if ((avail_prio_list[0] == _bcm_ptp_apts_avail_ptp) && (avail_prio_list[1] == _bcm_ptp_apts_avail_none) && (avail_prio_list[2] == _bcm_ptp_apts_avail_none)){
   5153         g_apts_op_mode_list_idx = 13;
   5154     }
   5155     else
   5156     {
   5157         rv = BCM_E_PARAM;
   5158     }
   5159 
   5160     _bcm_ptp_apts_update_current_mode();
   5161 
   5162     return rv;
   5163 }
   5164 
   5165 /*
   5166  *  This API can be used by the user application to retrieve the current
   5167  * operating mode of the APTS system.
   5168  */
   5169 int bcm_common_ptp_clock_apts_mode_get(
   5170     int unit,
   5171     bcm_ptp_stack_id_t ptp_id,
   5172     int clock_num,
   5173     bcm_ptp_clock_apts_mode_t *current_mode)
   5174 {
   5175     int rv = BCM_E_NONE;
   5176     *current_mode = g_apts_current_op_mode;
   5177     return rv;
   5178 }
   5179 
   5180 /*
   5181  * This API is used by the to indicate if a time and/or frequency source
   5182  * is available or not.
   5183  */
   5184 int bcm_common_ptp_clock_apts_source_enable_get(
   5185     int unit,
   5186     bcm_ptp_stack_id_t ptp_id,
   5187     int clock_num,
   5188     bcm_ptp_clock_apts_source_t source,
   5189     int *enable)
   5190 {
   5191     int rv = BCM_E_NONE;
   5192     *enable = g_apts_usr_cfgd_source_state & source;
   5193     return rv;
   5194 }
   5195 
   5196 /*
   5197  * This API is used by the to indicate if a time and/or frequency source
   5198  * is available or not.
   5199  */
   5200 int bcm_common_ptp_clock_apts_source_enable_set(
   5201     int unit,
   5202     bcm_ptp_stack_id_t ptp_id,
   5203     int clock_num,
   5204     bcm_ptp_clock_apts_source_t source,
   5205     int enable)
   5206 {
   5207     int rv = BCM_E_UNAVAIL;
   5208     _bcm_ptp_apts_source_avail_t source_avail = 0;
   5209 
   5210     if (g_apts_enabled == 0){
   5211         return BCM_E_DISABLED;
   5212     }
   5213 
   5214     if (source >= 0x08) {
   5215         rv = BCM_E_PARAM;
   5216         LOG_ERROR(BSL_LS_BCM_COMMON,(BSL_META_U(unit,"bcm_common_ptp_clock_apts_source_enable_set: not valid for PTP source\n")));
   5217     }
   5218     else {
   5219         g_apts_usr_cfgd_source_state = source & enable;
   5220         if ((g_apts_usr_cfgd_source_state & 0x3) == 0x03){
   5221             rv = BCM_E_PARAM;
   5222             LOG_ERROR(BSL_LS_BCM_COMMON,(BSL_META_U(unit,"bcm_common_ptp_clock_apts_source_enable_set: Incorrect syncE configuration\n")));
   5223         }
   5224         source_avail = (g_apts_usr_cfgd_source_state >> 1) | (((g_apts_usr_cfgd_source_state & 0x03) > 0) ? 1 : 0);
   5225         g_apts_current_source_state &= (source_avail | 0x4);
   5226         _bcm_ptp_apts_update_current_mode();
   5227         rv = BCM_E_NONE;
   5228     }
   5229     return rv;
   5230 }
   5231 
   5232 #endif /* defined(INCLUDE_PTP)*/