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

ext_servo.c (42122B)


      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  */
      8 
      9 #if defined(INCLUDE_PTP)
     10 
     11 #include <bcm/ptp.h>
     12 #include <bcm_int/common/ptp.h>
     13 #include <bcm_int/ptp_common.h>
     14 #include <bcm/error.h>
     15 
     16 
     17 #ifdef BCM_PTP_EXT_SERVO_SUPPORT
     18 #include "mngApi/mngApiCmdStruct.h"
     19 
     20 #define BCM_PTP_EXT_SERVO_TS_RATE_MAX 128 /* IDT servo supports max 128 pps */
     21 
     22 static uint32 servo_debug_mask;
     23 static uint32 servo_syslog_mask;
     24 static uint32 servo_syslog_destip;
     25 static uint32 servo_syslog_destport;
     26 
     27 static int    servo_state = E_srvLoStateInvalid;
     28 
     29 static const bcm_ptp_port_identity_t portid_all =
     30     {{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, PTP_IEEE1588_ALL_PORTS};
     31 
     32 extern bcm_ptp_mbox_tsevent_stats_t mbox_tsevent_stats;
     33 static int  _bcm_ptp_ext_servo_ptsf_set(int unit,  bcm_ptp_stack_id_t ptp_id,
     34                         int clock_num,   bcm_ptp_port_identity_t *master,
     35                         T_osBool b_signalFail);
     36 
     37 typedef struct master_table_entry_s {
     38     bcm_ptp_port_identity_t       master_portId;
     39     bcm_ptp_clock_port_address_t  master_portaddr;
     40 	int                           in_use;
     41 } master_table_entry_t;
     42 
     43 master_table_entry_t     master_table[BCM_PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES];
     44 bcm_ptp_port_identity_t  bestmaster_portId = {{0,0,0,0,0,0,0,0},0};
     45 
     46 int _bcm_ptp_ext_servo_master_table_init() {
     47     int i=0;
     48 	for (i=0; i<BCM_PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES; i++) {
     49 		sal_memset(&master_table[i].master_portId, 0, sizeof(bcm_ptp_port_identity_t));
     50 		sal_memset(&master_table[i].master_portaddr, 0, sizeof(bcm_ptp_clock_port_address_t));
     51 		master_table[i].in_use = 0;
     52 	}
     53 	return BCM_E_NONE;
     54 }
     55 
     56 int _bcm_ptp_ext_servo_master_table_entry_add(int unit,
     57     bcm_ptp_stack_id_t             ptp_id, 
     58     int                            clock_num, 
     59     bcm_ptp_port_identity_t *      master_portId,
     60     bcm_ptp_clock_port_address_t * master_portaddr,
     61     uint8                          unicast,
     62     int                            *inst_num)
     63 {
     64 	int i=0;
     65 
     66 	for (i=0; i<BCM_PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES; i++) {
     67         if(_bcm_ptp_port_address_compare(master_portaddr, &master_table[i].master_portaddr)) {
     68             master_table[i].in_use = 1;
     69             *inst_num = i;
     70 			return BCM_E_NONE;
     71 		}
     72 	}
     73 	if(i == BCM_PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES) {
     74 		/* master entry not exists */
     75 		for (i=0; i<BCM_PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES; i++) {
     76 			if(master_table[i].in_use == 0) {
     77 				master_table[i].master_portaddr.addr_type = master_portaddr->addr_type;
     78 				sal_memcpy(&master_table[i].master_portaddr.address, master_portaddr->address, BCM_PTP_MAX_NETW_ADDR_SIZE);
     79 				sal_memcpy(&master_table[i].master_portId, master_portId, sizeof(master_portId));
     80 				master_table[i].in_use = 1;
     81 				*inst_num = i;
     82 				return BCM_E_NONE;
     83 			}
     84 		}
     85 		if(BCM_PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES) {
     86 			/* NO free entry available */
     87             LOG_INFO(BSL_LS_BCM_PTP,
     88                 (BSL_META_U(0, " No free entry/instance available\n")));
     89 			return BCM_E_FULL;
     90 		}
     91 	}
     92 	return BCM_E_NONE;
     93 }
     94 
     95 int _bcm_ptp_ext_servo_master_table_entry_delete( int unit,
     96     bcm_ptp_stack_id_t             ptp_id, 
     97     int                            clock_num, 
     98     bcm_ptp_port_identity_t *      master_portId,
     99     bcm_ptp_clock_port_address_t * master_portaddr,
    100     uint8                          unicast, 
    101     int                            *inst_num)
    102 {
    103 	int i=0;
    104 
    105 	for (i=0; i<BCM_PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES; i++) {
    106         if(_bcm_ptp_port_address_compare(master_portaddr, &master_table[i].master_portaddr)) {
    107             master_table[i].in_use = 0;
    108             LOG_INFO(BSL_LS_BCM_PTP,
    109                     (BSL_META_U(0, " *** Master deleted at instance number [%d] ***\n"), i));
    110             *inst_num = i;
    111 			return BCM_E_NONE;
    112 		}
    113 	}
    114 	if(i == BCM_PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES) {
    115 		/* master entry not exists */
    116 		return BCM_E_NOT_FOUND;
    117 	}
    118     return BCM_E_NONE;
    119 }
    120 
    121 void InitializeStackAdaptor()
    122 {
    123   /* Initialize IDT stack adaptor */
    124   if( !IDTStackAdaptor_Initialized() )
    125     {
    126       IDTStackAdaptor_Init();
    127     }
    128 }
    129 
    130 int _bcm_ptp_ext_servo_mapped_state_get(
    131     T_srvLoStateId                 servo_state,
    132     bcm_ptp_servo_state_t *        mapped_state)
    133 {
    134 
    135     int rv = BCM_E_NONE;
    136 
    137     switch(servo_state) {
    138         case E_srvLoInitialState:
    139             *mapped_state = bcmPtpServoStateInitial;
    140             break;
    141         case E_srvLoUnqualifiedState:
    142             *mapped_state = bcmPtpServoStateUnqualified;
    143             break;
    144         case E_srvLoLockAcqState:
    145             *mapped_state = bcmPtpServoStateAcquiring ;
    146             break;
    147         case E_srvLoFrequencyLockedState:
    148             *mapped_state = bcmPtpServoStateFreqLocked;
    149             break;
    150         case E_srvLoTimeLockedState:
    151             *mapped_state = bcmPtpServoStateTimeLocked;
    152             break;
    153         case E_srvLoHoldoverInSpecState:
    154             *mapped_state = bcmPtpServoStateHoldoverInSpec;
    155             break;
    156         case E_srvLoHoldoverOutOfSpecState:
    157             *mapped_state = bcmPtpServoStateHoldoverOutOfSpec;
    158             break;
    159         case E_srvLoFreeRunState:
    160             *mapped_state = bcmPtpServoStateFreerun;
    161             break;
    162         default:
    163             rv = BCM_E_INTERNAL;
    164             break;
    165     }
    166     return rv;
    167 }
    168 
    169 void _bcm_ptp_ext_servo_pdvThresholdExceeded_cb( const T_ieee1588PortIdentity *masterPortId,
    170                                                  T_srvPdvValues currentPdv,
    171                                                  T_osBool set )
    172 {
    173     bcm_ptp_port_identity_t master_portId;
    174     bcm_ptp_clock_info_t *clock_info;
    175 
    176     clock_info = &_bcm_common_ptp_unit_array[0].stack_array[0].clock_array[0].clock_info;
    177     if (masterPortId) {
    178         sal_memcpy(&master_portId.clock_identity, &masterPortId->clockIdentity, sizeof(bcm_ptp_clock_identity_t));
    179         master_portId.port_number = masterPortId->portNumber;
    180     }
    181 
    182     if (PTP_CLOCK_IS_G8265P1_PROF(clock_info)) {
    183         if (BCM_FAILURE(_bcm_ptp_telecom_g8265_packet_master_ptsf_unusable_set( 0, 0, 0, &master_portId, set ))) {
    184             LOG_ERROR(BSL_LS_BCM_COMMON,
    185                 (BSL_META_U(0, "ptsf_unusable set failed \n")));
    186         }
    187     }
    188 
    189     if (PTP_CLOCK_IS_G8275P2_PROF(clock_info)) {
    190         _bcm_ptp_ext_servo_ptsf_set( 0, 0, 0, &master_portId, set );
    191     }
    192 
    193 
    194     LOG_INFO(BSL_LS_BCM_PTP,
    195         (BSL_META_U(0, "\n *****  PDV threshold exceeded[%d] for master[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%d] current PDV[DL/UL: %Lf/%Lf] ***** \n"),
    196              set,
    197              masterPortId->clockIdentity.clockId[0], masterPortId->clockIdentity.clockId[1],
    198              masterPortId->clockIdentity.clockId[2], masterPortId->clockIdentity.clockId[3],
    199              masterPortId->clockIdentity.clockId[4], masterPortId->clockIdentity.clockId[5],
    200              masterPortId->clockIdentity.clockId[6], masterPortId->clockIdentity.clockId[7],
    201              masterPortId->portNumber,
    202              currentPdv.downlink, currentPdv.uplink));
    203 }
    204 
    205 void _bcm_ptp_ext_servo_losmStateChanged_cb( T_srvLoStateId prevStateId,
    206                                              T_srvLoStateId currentStateId,
    207                                              T_srvLoStateMachineEvent losmEvent )
    208 {
    209     int rv = BCM_E_NONE;
    210     bcm_ptp_servo_state_t servo_state;
    211 
    212     if (BCM_FAILURE(rv = _bcm_ptp_ext_servo_mapped_state_get(currentStateId, &servo_state))) {
    213         PTP_ERROR_FUNC("_bcm_ptp_ext_servo_mapped_state_get()");
    214     }
    215 
    216     if (BCM_FAILURE(_bcm_ptp_servo_state_set( 0, 0, 0, servo_state))) {
    217 	  LOG_ERROR(BSL_LS_BCM_COMMON,
    218 			  (BSL_META_U(0, "servo state set failed \n")));
    219     }
    220 
    221     LOG_INFO(BSL_LS_BCM_PTP,
    222             (BSL_META_U(0, "SERVO STATE CHANGE : [%d -> %d] [%d] Event[%d]\n"), prevStateId, currentStateId, servo_state, losmEvent));
    223 
    224 }
    225 
    226 T_userCallbacks _bcm_ptp_cb_func = { 
    227                     (T_pdvThresholdExceededCallback)_bcm_ptp_ext_servo_pdvThresholdExceeded_cb, 
    228                     (T_losmStateChangedCallback)_bcm_ptp_ext_servo_losmStateChanged_cb
    229                     };
    230 
    231 #if 0
    232 void register_cb( T_pdvThresholdExceededCallback pdv_cb, T_losmStateChangedCallback loState_cb) {
    233     
    234     _bcm_ptp_cb_func.userPdvThresholdExceededCallback = pdv_cb;
    235     _bcm_ptp_cb_func.userLosmStateChangedCallback = loState_cb;
    236 
    237 }
    238 #endif
    239 
    240 T_osBool _bcm_ptp_ext_servo_GetClockId(  T_osUint16 instance, T_ieee1588ClockIdentity *clockIdentity )
    241 {
    242     _bcm_ptp_clock_cache_t *clock_cache;
    243 
    244 	clock_cache = &_bcm_common_ptp_unit_array[0].stack_array[0].clock_array[0];
    245 	sal_memcpy(&clockIdentity->clockId, &clock_cache->clock_info.clock_identity, sizeof(clockIdentity->clockId));
    246 
    247     LOG_VERBOSE(BSL_LS_BCM_PTP,
    248             (BSL_META_U(0, "\n Servo issued get clock identity[%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x]\n"),
    249 			    clockIdentity->clockId[0], clockIdentity->clockId[1], clockIdentity->clockId[2],
    250 			    clockIdentity->clockId[3], clockIdentity->clockId[4], clockIdentity->clockId[5],
    251                 clockIdentity->clockId[6], clockIdentity->clockId[7]));
    252 
    253     return E_osTrue;
    254 }
    255 
    256 int
    257 _bcm_ptp_servo_init(int unit, 
    258     bcm_ptp_stack_id_t             ptp_id,
    259     int                            clock_num,
    260     bcm_ptp_osc_type_t             osc_type)
    261 {
    262   T_mngDeviceAdaptorTsConfig idtTsAdaptorConfig;
    263   T_mngDeviceAdaptorTS *idtTsAdaptor;
    264   int rv = BCM_E_NONE;
    265   int i=0;
    266   char syslog_ip[SAL_IPADDR_STR_LEN];
    267 
    268   T_cmnConfigParameterSet configParam;
    269 
    270   T_swVerisonInfo swVersionInfo;
    271   const char *releaseId = NULL, *commitId = NULL;
    272   T_cmnErrorCode errorCode = E_cmnErrorCode_InvalidApiCommand;
    273   T_idtStackConfigCallbacks cfgCallbacks;
    274 
    275   if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    276     LOG_INFO(BSL_LS_BCM_PTP,
    277         (BSL_META_U(unit, " configured to use BRCM servo \n")));
    278     return rv ;
    279   }
    280 
    281   sal_memset(&configParam, 0 , sizeof(configParam));
    282 
    283   cmnInitConfigStructure(&configParam);
    284  
    285   LOG_INFO(BSL_LS_BCM_PTP,
    286           (BSL_META_U(unit, " ConfigParam Init done: frequencyLockThresholdPpb [%Lf]\n"), 
    287 		      configParam.externalConfig.referenceTrackerConfig[0].frequencyLockThresholdPpb)); 
    288 
    289   configParam.externalConfig.stackInstanceConfig[ 0 ].slaveOnly       = E_osTrue;
    290   configParam.externalConfig.messageLoggingConfig.stdoutSelectionMask = E_cmnSyncErrorMessages | E_cmnErrorMessages;
    291  
    292   if(servo_syslog_mask) {
    293 
    294     configParam.externalConfig.messageLoggingConfig.syslog.selectionMask = servo_syslog_mask;
    295     configParam.externalConfig.messageLoggingConfig.syslog.udpPort = servo_syslog_destport;
    296 
    297     format_ipaddr(syslog_ip, servo_syslog_destip);
    298     sal_memcpy(configParam.externalConfig.messageLoggingConfig.syslog.ipAddress, syslog_ip, SAL_IPADDR_STR_LEN);
    299 
    300     LOG_VERBOSE(BSL_LS_BCM_PTP,
    301             (BSL_META_U(unit, "\n Configuring syslog settings: IP[%s] port[%d]"), 
    302             configParam.externalConfig.messageLoggingConfig.syslog.ipAddress, 
    303             configParam.externalConfig.messageLoggingConfig.syslog.udpPort));
    304   }
    305 
    306   configParam.externalConfig.referenceTrackerType                    = E_srvAdaptiveTimeReferenceTracker;
    307   configParam.externalConfig.tsInstances                             = 1;
    308   
    309   switch (osc_type) {
    310     case bcmPTPOscTypeOCXO:
    311         configParam.externalConfig.oscillatorType = E_srvOcxo;
    312         break;
    313     case bcmPTPOscTypeTCXO: 
    314         configParam.externalConfig.oscillatorType = E_srvTcxo;
    315         break;
    316     case bcmPTPOscTypeMiniOCXO:
    317         configParam.externalConfig.oscillatorType = E_srvMiniOcxo;
    318         break;
    319     default:
    320         /* Current 3rd party servo supports only OCXO, mini-OCXO, TCXO and SyncE as osc types*/
    321         configParam.externalConfig.oscillatorType = E_srvOcxo;
    322         break;
    323   }
    324 
    325   /* servo ref tracker config */
    326   for (i=0; i< BCM_PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES; i++) {
    327     configParam.externalConfig.referenceTrackerConfig[i].stationarityMeasure1LowerBound = 0.4;
    328     configParam.externalConfig.referenceTrackerConfig[i].stationarityMeasure1UpperBound = 2.5;
    329     configParam.externalConfig.referenceTrackerConfig[i].stationarityMeasure2UpperBound = 250;
    330   }
    331 
    332   bsl_printf(" \nLoopFilterMinResponseTimeSeconds : %d ", configParam.externalConfig.referenceTrackerConfig[0].dcoLoopFilterMinResponseTimeSeconds);
    333   bsl_printf("\n dcoLoopFilterMaxFfoCorrection : %d", configParam.externalConfig.referenceTrackerConfig[0].dcoLoopFilterMaxFfoCorrection);
    334   bsl_printf("\n dcoLoopFilterIntegralBranchGain : %Lf ", configParam.externalConfig.referenceTrackerConfig[0].dcoLoopFilterIntegralBranchGain);
    335   bsl_printf("\n dcoLoopFilterBandwidthScalar : %Lf ", configParam.externalConfig.referenceTrackerConfig[0].dcoLoopFilterBandwidthScalar);
    336   bsl_printf("\n desiredPrecisionSeconds : %Lf \n", configParam.externalConfig.referenceTrackerConfig[0].desiredPrecisionSeconds);
    337   bsl_printf("\n timeLockThresholdNanoseconds: %Lf ", configParam.externalConfig.referenceTrackerConfig[0].timeLockThresholdNanoseconds);
    338   bsl_printf("\n phaseSnapThresholdSeconds: %Lf \n", configParam.externalConfig.referenceTrackerConfig[0].phaseSnapThresholdSeconds);
    339 
    340   /***************************/
    341   /* Initialize time stamper */
    342   /***************************/
    343   idtTsAdaptor= mngGetDeviceAdaptorTS();
    344 
    345   sal_memset( &idtTsAdaptorConfig, 0, sizeof(idtTsAdaptorConfig) );
    346 
    347   idtTsAdaptorConfig.tsInstances      = configParam.externalConfig.tsInstances;
    348   idtTsAdaptorConfig.warmStartEnabled = configParam.externalConfig.warmStartConfig.warmStartEnabled;
    349 
    350   if( !mngDeviceAdaptorTS_Initialize( idtTsAdaptor, &idtTsAdaptorConfig ) )
    351     {
    352       LOG_ERROR(BSL_LS_BCM_PTP,
    353         (BSL_META_U(unit, " Device adaptor TS initialization failed \n")));
    354       return BCM_E_INIT;
    355     }
    356 
    357   /****************************************************************/
    358   /* Initialize IDT stack adaptor once.                           */
    359   /****************************************************************/
    360   InitializeStackAdaptor();
    361 
    362   cfgCallbacks.configSetParamFunc_cb = NULL;
    363   cfgCallbacks.configIfNameFunc_cb = NULL;
    364   cfgCallbacks.configGetLocalPrio_cb = NULL;
    365   cfgCallbacks.configGetWaitToRestore_cb = NULL;
    366   cfgCallbacks.configGetLocalClockIdentity_cb = _bcm_ptp_ext_servo_GetClockId;
    367 
    368   IDTStackAdaptor_RegisterStackConfigCallbacks(&cfgCallbacks );
    369 
    370 
    371   /*******************************/
    372   /* Start IDT PTP servo session */
    373   /*******************************/
    374   mngPtpLoggerStart( &configParam.externalConfig.messageLoggingConfig );
    375 
    376   /* register_cb((T_pdvThresholdExceededCallback)_bcm_ptp_ext_servo_pdvThresholdExceeded_cb, (T_losmStateChangedCallback)_bcm_ptp_ext_servo_losmStateChanged_cb);*/
    377 
    378   mngPtpSessionStart( &configParam, &_bcm_ptp_cb_func );
    379   
    380   errorCode = mngApi_GetSoftwareVersion( &releaseId, &commitId );
    381 
    382   if( E_cmnErrorCode_OK == errorCode )
    383   {
    384       sal_memset( &swVersionInfo, 0, sizeof(T_swVerisonInfo) );
    385 	  sal_memcpy( swVersionInfo.releaseId, releaseId, SW_RELEASE_ID_MAX_SIZE - 1 );
    386 	  sal_memcpy( swVersionInfo.commitId, commitId, SW_COMMIT_ID_MAX_SIZE - 1 );
    387       LOG_INFO(BSL_LS_BCM_PTP,
    388           (BSL_META_U(unit, "Servo version [Release :%s] [Commit :%s]\n"), 
    389 		      (char *)swVersionInfo.releaseId, 
    390 			  (char *)swVersionInfo.commitId));
    391   } else {
    392       PTP_ERROR("Failed to get sw version");
    393   }
    394 
    395   if (servo_debug_mask) {
    396     if (BCM_FAILURE(rv = _bcm_ptp_servo_debug_level_set(unit, ptp_id, clock_num, E_cmnLog_stdout, servo_debug_mask))) {
    397         PTP_ERROR_FUNC("_bcm_ptp_servo_debug_level_set()");
    398 	}
    399   } else {
    400     errorCode = mngApi_SetMessageLogLevel( E_cmnLog_stdout, E_cmnNonStackMessageAll );
    401     if( E_cmnErrorCode_OK != errorCode )
    402     {
    403       PTP_ERROR("Failed to set message log level ");
    404     }
    405   }
    406 
    407   /* Reset servo state */
    408   servo_state = E_srvLoStateInvalid;
    409   LOG_INFO(BSL_LS_BCM_PTP, (BSL_META_U(unit, " Servo init complete \n")));
    410 
    411   _bcm_ptp_ext_servo_master_table_init();
    412 
    413   return 0;
    414 }
    415 
    416 int
    417 _bcm_ptp_servo_deinit(int unit, 
    418     bcm_ptp_stack_id_t             ptp_id,
    419     int                            clock_num)
    420 {
    421   int rv = BCM_E_NONE;
    422 
    423   if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    424     LOG_VERBOSE(BSL_LS_BCM_PTP,
    425         (BSL_META_U(unit, " configured to use BRCM servo \n")));
    426     return rv ;
    427   }
    428 
    429   if( IDTStackAdaptor_Initialized() ) {
    430     mngPtpSessionStop();
    431     IDTStackAdaptor_DeInit();
    432   }
    433 
    434   LOG_INFO(BSL_LS_BCM_PTP,
    435         (BSL_META_U(unit, " Servo de-init complete\n")));
    436 
    437   return rv;
    438 }
    439 
    440 
    441 /*
    442  * Function:
    443  *     _bcm_ptp_servo_master_add 
    444  * Purpose:
    445  *      Notify 3rd-party servo of the 1588 master addition.
    446  * Parameters:
    447  *      unit               - (IN) Unit number.
    448  *      ptp_id             - (IN) PTP stack ID.
    449  *      clock_num          - (IN) PTP clock number.
    450  *      inst_num           - (IN) Instance/Master number.
    451  *      master_portId      - (IN) master port identity.
    452  *      master_portaddr    - (IN) master port address.
    453  *      unicast            - (IN) unicast master.
    454  *      clockClass         - (IN) clock class of the master.
    455  *      best_master_portId - (IN) best master identity.
    456  * Returns:
    457  *      BCM_E_XXX - Function status.
    458  * Notes:
    459  *   best_master_portId can be NULL only for G.8265.1 profile.
    460  */
    461 int
    462 _bcm_ptp_servo_master_add(int unit, 
    463     bcm_ptp_stack_id_t             ptp_id, 
    464     int                            clock_num, 
    465     uint16                         inst_num, 
    466     bcm_ptp_port_identity_t *      master_portId,
    467     bcm_ptp_clock_port_address_t * master_portaddr,
    468     uint8                          unicast,
    469     unsigned char                  clockClass)
    470 {
    471     int rv = BCM_E_NONE;
    472     int instance=0;
    473     T_ieee1588PortIdentity best_master = {{{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 };
    474 	T_idtMasterInfo master_info;
    475 
    476     bcm_ptp_clock_info_t *clock_info;
    477 
    478 	if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    479         return rv ;
    480     }
    481 
    482     if(!master_portId ) { 
    483         return BCM_E_PARAM;
    484 	}
    485 
    486     clock_info = &_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num].clock_info;
    487 
    488     sal_memset(&master_info, 0 , sizeof(master_info));
    489 
    490     sal_memcpy(&master_info.portIdentity.clockIdentity, &master_portId->clock_identity, sizeof(bcm_ptp_clock_identity_t));
    491     master_info.portIdentity.portNumber = master_portId->port_number; 
    492     /* Port address not being used. skip it */
    493 	master_info.isUnicast = unicast;
    494     /* master_info.clockClass = clockClass;*/
    495 
    496     
    497     if (inst_num == PTP_EXT_SERVO_MSTR_INST_UNKNOWN) {
    498         if(PTP_CLOCK_IS_G8275P1_PROF(clock_info)) {
    499             /* G.8275.1 profile shall NOT use ext servo */
    500             return BCM_E_PARAM;
    501         } else {
    502             if(BCM_FAILURE(rv = _bcm_ptp_ext_servo_master_table_entry_add(unit, ptp_id, clock_num, master_portId, master_portaddr,1, &instance))) {
    503                 PTP_ERROR_FUNC("_bcm_ptp_ext_servo_master_table_entry_add()");
    504             }
    505             inst_num = (uint16)instance;
    506 	        LOG_VERBOSE(BSL_LS_BCM_PTP, (BSL_META_U(unit, "\n _bcm_ptp_ext_servo_master_table_entry_add returned inst_num[%d] instance[%d]\n"), inst_num, instance));
    507         }
    508     }
    509 
    510     sal_memcpy(&best_master.clockIdentity, bestmaster_portId.clock_identity, sizeof(bcm_ptp_clock_identity_t));
    511     best_master.portNumber = bestmaster_portId.port_number;
    512 
    513     rv = IDTStackAdaptor_AddMaster(inst_num, &master_info, &best_master, NULL );
    514 
    515     LOG_VERBOSE(BSL_LS_BCM_PTP,
    516                   (BSL_META_U(unit, "\n AddMaster[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%d]  \
    517                       \nBestMaster[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%d] \n Instance[%d] rv[%d]\n"),
    518 				      master_info.portIdentity.clockIdentity.clockId[0], master_info.portIdentity.clockIdentity.clockId[1],
    519 				      master_info.portIdentity.clockIdentity.clockId[2], master_info.portIdentity.clockIdentity.clockId[3],
    520 				      master_info.portIdentity.clockIdentity.clockId[4], master_info.portIdentity.clockIdentity.clockId[5],
    521 				      master_info.portIdentity.clockIdentity.clockId[6], master_info.portIdentity.clockIdentity.clockId[7],
    522 					  master_info.portIdentity.portNumber,
    523 				      best_master.clockIdentity.clockId[0], best_master.clockIdentity.clockId[1],
    524 				      best_master.clockIdentity.clockId[2], best_master.clockIdentity.clockId[3],
    525 				      best_master.clockIdentity.clockId[4], best_master.clockIdentity.clockId[5],
    526 				      best_master.clockIdentity.clockId[6], best_master.clockIdentity.clockId[7],
    527 					  best_master.portNumber, inst_num, rv));
    528 
    529     if (rv) {
    530         return BCM_E_FAIL;
    531     }
    532 
    533     return rv ;
    534 }
    535 
    536 /*
    537  * Function:
    538  *     _bcm_ptp_servo_master_remove
    539  * Purpose:
    540  *      Notify 3rd-party servo of the 1588 master removal.
    541  * Parameters:
    542  *      unit               - (IN) Unit number.
    543  *      ptp_id             - (IN) PTP stack ID.
    544  *      clock_num          - (IN) PTP clock number.
    545  *      master_portId      - (IN) master port identity.
    546  *      best_master_portId - (IN) new best master identity.
    547  * Returns:
    548  *      BCM_E_XXX - Function status.
    549  * Notes:
    550  *   best_master_portId can be NULL only for G.8265.1 profile.
    551  */
    552 int
    553 _bcm_ptp_servo_master_remove(int unit, 
    554     bcm_ptp_stack_id_t             ptp_id, 
    555     int                            clock_num, 
    556     uint16                         inst_num, 
    557     uint8                          unicast,
    558     bcm_ptp_port_identity_t *      master_portId,
    559     bcm_ptp_port_identity_t *      best_master_portId,
    560     bcm_ptp_clock_port_address_t * master_portaddr)
    561 {
    562     int rv = BCM_E_NONE;
    563 
    564 	T_ieee1588PortIdentity master;
    565     T_ieee1588PortIdentity best_master = {{{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 };
    566 	int instance;
    567 
    568 	if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    569         return rv ;
    570     }
    571 
    572     if(!master_portId) { 
    573         return BCM_E_PARAM;
    574 	}
    575     if (inst_num == PTP_EXT_SERVO_MSTR_INST_UNKNOWN) {
    576         if (BCM_FAILURE(rv = _bcm_ptp_ext_servo_master_table_entry_delete(unit, ptp_id, clock_num, master_portId, master_portaddr, 1, &instance))) {
    577             PTP_ERROR_FUNC("_bcm_ptp_ext_servo_master_table_entry_delete()");
    578             inst_num = 0;
    579         }
    580         inst_num = (uint16) instance;
    581 	}
    582 
    583     sal_memcpy(&master.clockIdentity, &master_portId->clock_identity, IDT_CLKID_BYTE_SIZE);
    584     master.portNumber = master_portId->port_number; 
    585 
    586     sal_memcpy(&best_master.clockIdentity, bestmaster_portId.clock_identity, sizeof(bcm_ptp_clock_identity_t));
    587     best_master.portNumber = bestmaster_portId.port_number;
    588 
    589     rv = IDTStackAdaptor_DeleteMaster(&master, &best_master, NULL);
    590 
    591     LOG_VERBOSE(BSL_LS_BCM_PTP,
    592                   (BSL_META_U(unit, "\n DeleteMaster[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%d] 	\
    593                        \nBestMaster[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%d] \n rv[%d] \n"),
    594                        master.clockIdentity.clockId[0], master.clockIdentity.clockId[1],
    595                        master.clockIdentity.clockId[2], master.clockIdentity.clockId[3],
    596                        master.clockIdentity.clockId[4], master.clockIdentity.clockId[5],
    597                        master.clockIdentity.clockId[6], master.clockIdentity.clockId[7],
    598                        master.portNumber,
    599                        best_master.clockIdentity.clockId[0], best_master.clockIdentity.clockId[1],
    600                        best_master.clockIdentity.clockId[2], best_master.clockIdentity.clockId[3],
    601                        best_master.clockIdentity.clockId[4], best_master.clockIdentity.clockId[5],
    602                        best_master.clockIdentity.clockId[6], best_master.clockIdentity.clockId[7],
    603                        best_master.portNumber, rv));
    604 
    605     if (rv) {
    606         return BCM_E_FAIL;
    607     }
    608     return rv ;
    609 }
    610 /*
    611  * Function:
    612  *    _bcm_ptp_servo_best_master_update 
    613  * Purpose:
    614  *      Notify 3rd-party servo of the new best master selected.
    615  * Parameters:
    616  *      unit               - (IN) Unit number.
    617  *      ptp_id             - (IN) PTP stack ID.
    618  *      clock_num          - (IN) PTP clock number.
    619  *      best_master_portId - (IN) best master identity.
    620  * Returns:
    621  *      BCM_E_XXX - Function status.
    622  * Notes:
    623  */
    624 
    625 int
    626 _bcm_ptp_servo_best_master_update(int unit,
    627     bcm_ptp_stack_id_t             ptp_id,
    628     int                            clock_num,
    629     bcm_ptp_port_identity_t *      best_master_portId)
    630 {
    631     int rv = BCM_E_NONE;
    632 
    633     T_ieee1588PortIdentity best_master = {{{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 };
    634     bcm_ptp_clock_info_t *clock_info;
    635 	bcm_ptp_port_identity_t clk_portid;
    636 
    637     clock_info = &_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num].clock_info;
    638 
    639 	sal_memcpy(&clk_portid.clock_identity, &clock_info->clock_identity, sizeof(bcm_ptp_clock_identity_t));
    640 	clk_portid.port_number = 0;
    641 
    642 	if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    643         return rv ;
    644     }
    645 
    646     if(!best_master_portId) {
    647         return BCM_E_PARAM;
    648 	}
    649 
    650     if (best_master_portId) {
    651         if (_bcm_ptp_peer_portid_compare(best_master_portId, &clk_portid)) {
    652             sal_memset(&bestmaster_portId.clock_identity, 0, sizeof(bcm_ptp_clock_identity_t));
    653             bestmaster_portId.port_number = 0;
    654 			/* retain best_master as 0's */
    655 		} else {
    656             sal_memcpy(&bestmaster_portId.clock_identity, &best_master_portId->clock_identity, sizeof(bcm_ptp_clock_identity_t));
    657             bestmaster_portId.port_number = best_master_portId->port_number;
    658         }
    659         sal_memcpy(&best_master.clockIdentity, &bestmaster_portId.clock_identity, sizeof(bcm_ptp_clock_identity_t));
    660         best_master.portNumber = bestmaster_portId.port_number;
    661     }
    662     rv = IDTStackAdaptor_UpdateBestMasterSelection(&best_master);
    663 
    664     LOG_INFO(BSL_LS_BCM_PTP,
    665                   (BSL_META_U(unit, "\n UpdatedBestMaster[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%d] rv[%d] \n"),
    666                        best_master.clockIdentity.clockId[0], best_master.clockIdentity.clockId[1],
    667                        best_master.clockIdentity.clockId[2], best_master.clockIdentity.clockId[3],
    668                        best_master.clockIdentity.clockId[4], best_master.clockIdentity.clockId[5],
    669                        best_master.clockIdentity.clockId[6], best_master.clockIdentity.clockId[7],
    670                        best_master.portNumber, rv));
    671 
    672     if (rv) {
    673         return BCM_E_FAIL;
    674     }
    675     
    676     return rv ;
    677 }
    678 
    679 int
    680 _bcm_ptp_servo_master_replace(int unit, 
    681     bcm_ptp_stack_id_t             ptp_id, 
    682     int                            clock_num, 
    683     uint16                         inst_num, 
    684     bcm_ptp_port_identity_t *      prev_master_portId,
    685     bcm_ptp_port_identity_t *      master_portId,
    686     uint8                          unicast)
    687 {
    688     int rv = BCM_E_NONE;
    689     T_ieee1588PortIdentity best_master = {{{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 };
    690     T_ieee1588PortIdentity prev_master = {{{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 };
    691 	T_idtMasterInfo master_info;
    692 
    693 	if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    694         return rv ;
    695     }
    696 
    697     if(!master_portId || !prev_master_portId) { 
    698         return BCM_E_PARAM;
    699 	}
    700 
    701     sal_memset(&master_info, 0 , sizeof(master_info));
    702 
    703     sal_memcpy(&master_info.portIdentity.clockIdentity, &master_portId->clock_identity, sizeof(bcm_ptp_clock_identity_t));
    704     master_info.portIdentity.portNumber = master_portId->port_number; 
    705     /* Port address not being used. skip it */
    706 	master_info.isUnicast = unicast;
    707 
    708     sal_memcpy(&best_master.clockIdentity, bestmaster_portId.clock_identity, sizeof(bcm_ptp_clock_identity_t));
    709     best_master.portNumber = bestmaster_portId.port_number;
    710 
    711     if (prev_master_portId) {
    712         sal_memcpy(&prev_master.clockIdentity, prev_master_portId->clock_identity, sizeof(bcm_ptp_clock_identity_t));
    713         prev_master.portNumber = prev_master_portId->port_number;
    714     }
    715 
    716     rv = IDTStackAdaptor_ReplaceMaster(inst_num, &master_info, &prev_master, &best_master, NULL );
    717 
    718     LOG_VERBOSE(BSL_LS_BCM_PTP,
    719                   (BSL_META_U(unit, "\n ReplacingMaster[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%d]  \
    720                       \nPrevMaster[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%d] \n Instance[%d] rv[%d]\n"),
    721 				      master_info.portIdentity.clockIdentity.clockId[0], master_info.portIdentity.clockIdentity.clockId[1],
    722 				      master_info.portIdentity.clockIdentity.clockId[2], master_info.portIdentity.clockIdentity.clockId[3],
    723 				      master_info.portIdentity.clockIdentity.clockId[4], master_info.portIdentity.clockIdentity.clockId[5],
    724 				      master_info.portIdentity.clockIdentity.clockId[6], master_info.portIdentity.clockIdentity.clockId[7],
    725 					  master_info.portIdentity.portNumber,
    726 				      prev_master.clockIdentity.clockId[0], prev_master.clockIdentity.clockId[1],
    727 				      prev_master.clockIdentity.clockId[2], prev_master.clockIdentity.clockId[3],
    728 				      prev_master.clockIdentity.clockId[4], prev_master.clockIdentity.clockId[5],
    729 				      prev_master.clockIdentity.clockId[6], prev_master.clockIdentity.clockId[7],
    730 					  prev_master.portNumber, inst_num, rv));
    731 
    732     if (rv) {
    733         return BCM_E_FAIL;
    734     }
    735 
    736     return rv ;
    737 }
    738 
    739 
    740 /*
    741  * Function:
    742  *    _bcm_ptp_servo_pdv_threshold_set 
    743  * Purpose:
    744  *      Set the PDV threshold.
    745  * Parameters:
    746  *      unit               - (IN) Unit number.
    747  *      ptp_id             - (IN) PTP stack ID.
    748  *      clock_num          - (IN) PTP clock number.
    749  *      PDV threshold      - (IN) PDV threshold value.
    750  * Returns:
    751  *      BCM_E_XXX - Function status.
    752  * Notes:
    753  */
    754 
    755 int
    756 _bcm_ptp_servo_pdv_threshold_set(int unit, 
    757     bcm_ptp_stack_id_t             ptp_id, 
    758     int                            clock_num, 
    759     bcm_ptp_telecom_g8265_pktstats_t thresholds)
    760 {
    761     int rv = BCM_E_NONE;
    762     int i=0;
    763     T_srvPdvValues pdvThreshold;
    764 
    765 	if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    766         return rv ;
    767     }
    768 
    769     pdvThreshold.downlink = thresholds.pdv_scaled_allan_var;
    770     pdvThreshold.uplink = thresholds.pdv_scaled_allan_var;
    771 
    772     for (i=0; i<IDT_COMPILE_MAX_NUM_STACK_INSTANCES; i++) {
    773         rv = mngApi_ReferenceTracker_SetPdvThreshold(i, &pdvThreshold);
    774     }
    775 
    776     if (rv) {
    777         return BCM_E_FAIL;
    778     }
    779     
    780     return rv ;
    781 }
    782 
    783 #if 0
    784 int
    785 _bcm_ptp_servo_master_ptsf_set(int unit, 
    786     bcm_ptp_stack_id_t             ptp_id, 
    787     int                            clock_num, 
    788     T_ieee1588PortIdentity *      master_portId,
    789     int                            ptsf_state)
    790 {
    791     int rv = BCM_E_NONE;
    792 
    793     bcm_ptp_port_identity_t       pkt_master_portId;
    794 
    795     if (master_portId) {
    796         sal_memcpy(&pkt_master_portId.clock_identity, &master_portId->clockIdentity, sizeof(bcm_ptp_clock_identity_t));
    797         pkt_master_portId.port_number = master_portId->portNumber;
    798     }
    799     if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_ptsf_unusable_set(unit, ptp_id, clock_num, &pkt_master_portId, ptsf_state))){
    800         PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_ptsf_unusable_set()");
    801     }
    802     
    803     return rv ;
    804 }
    805 #endif
    806 
    807 /*
    808  * Function:
    809  *    
    810  * Purpose:
    811  *      Notify 3rd-party servo of the new best master selected.
    812  * Parameters:
    813  *      unit               - (IN) Unit number.
    814  *      ptp_id             - (IN) PTP stack ID.
    815  *      clock_num          - (IN) PTP clock number.
    816  *      best_master_portId - (IN) best master identity.
    817  * Returns:
    818  *      BCM_E_XXX - Function status.
    819  * Notes:
    820  */
    821 
    822 int
    823 _bcm_ptp_servo_master_lockout_set(int unit, 
    824     bcm_ptp_stack_id_t             ptp_id, 
    825     int                            clock_num, 
    826     int                            lock_out, 
    827     bcm_ptp_port_identity_t *      master_portId)
    828 {
    829     int rv = BCM_E_NONE;
    830 
    831 	T_ieee1588PortIdentity master;
    832 
    833 	if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    834         return rv ;
    835     }
    836 
    837     if(!master_portId) { 
    838         return BCM_E_PARAM;
    839 	}
    840 
    841     if (master_portId) {
    842         sal_memcpy(&master.clockIdentity, &master_portId->clock_identity, sizeof(bcm_ptp_clock_identity_t));
    843         master.portNumber = master_portId->port_number;
    844     }
    845 
    846     if (lock_out) {
    847         rv = IDTStackAdaptor_SuspendMaster(&master);
    848     } else {
    849         rv = IDTStackAdaptor_ResumeMaster(&master);
    850     }
    851 
    852     LOG_INFO(BSL_LS_BCM_PTP,
    853                   (BSL_META_U(unit, "\n LockOutMaster[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%d] lock_out[%d] rv[%d] \n "),
    854 				      master.clockIdentity.clockId[0], master.clockIdentity.clockId[1],
    855 				      master.clockIdentity.clockId[2], master.clockIdentity.clockId[3],
    856 				      master.clockIdentity.clockId[4], master.clockIdentity.clockId[5],
    857 				      master.clockIdentity.clockId[6], master.clockIdentity.clockId[7],
    858 					  master.portNumber, lock_out, rv));
    859 
    860 
    861     if (rv) {
    862         return BCM_E_FAIL;
    863     }
    864     
    865     return rv ;
    866 }
    867 
    868 int
    869 _bcm_ptp_servo_debug_level_set(int unit,
    870     bcm_ptp_stack_id_t             ptp_id,
    871     int                            clock_num,
    872     uint16                         log_id,
    873     uint32                         log_level_mask)
    874 {
    875     int rv = BCM_E_NONE;
    876     T_cmnMessageLevelRegister messageLevelMask = 0;
    877   
    878     if( !IDTStackAdaptor_Initialized() ) {
    879         servo_debug_mask = log_level_mask;
    880         return rv;
    881     }
    882 
    883     /* log_id:0 is STDOUT */
    884 	if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    885         return rv ;
    886     }
    887  
    888 	/* bitmap in cmd_ptp_debug defined inline with Extservo log levels */
    889 	messageLevelMask = (log_level_mask >>16) & 0xFF;
    890 
    891     LOG_VERBOSE(BSL_LS_BCM_PTP,
    892             (BSL_META_U(unit, " LogLevelmask[0x%0x] MessagelevelMask[0x%0x] \n"), log_level_mask, messageLevelMask));
    893 
    894     rv = mngApi_SetMessageLogLevel(log_id, messageLevelMask);
    895 
    896     if (rv) {
    897         return BCM_E_FAIL;
    898     }
    899 
    900     return rv ;
    901 }
    902 
    903 int
    904 _bcm_ptp_servo_sys_log_set(int unit,
    905     bcm_ptp_stack_id_t             ptp_id,
    906     int                            clock_num,
    907     uint32                         log_udp_mask,
    908     bcm_ip_t                       dest_addr,
    909     uint16                         port)
    910 {
    911     int rv = BCM_E_NONE;
    912 
    913     char syslog_ip[SAL_IPADDR_STR_LEN];
    914   
    915     if( !IDTStackAdaptor_Initialized() ) {
    916         /* backup the syslog settings and use at init time */
    917         servo_syslog_mask = log_udp_mask;
    918         servo_syslog_destip = dest_addr;
    919         servo_syslog_destport = port;
    920         return rv;
    921     } else {
    922         if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
    923             return rv ;
    924         }
    925 
    926         format_ipaddr(syslog_ip, servo_syslog_destip);
    927 
    928         /* Close the sys log socket, if already configured */
    929         rv = mngApi_CloseSyslog();
    930         if (rv) {
    931             return BCM_E_FAIL;
    932         }
    933         LOG_INFO(BSL_LS_BCM_PTP,
    934             (BSL_META_U(unit, " syslog socket closed \n")));
    935 
    936         if (log_udp_mask) {
    937           rv = mngApi_OpenSyslog(syslog_ip, port, log_udp_mask);
    938           if (rv) {
    939             return BCM_E_FAIL;
    940           }
    941           LOG_INFO(BSL_LS_BCM_PTP,
    942               (BSL_META_U(unit, " syslog socket opened \n")));
    943         }
    944     }
    945     return rv ;
    946 }
    947 
    948 uint32 _bcm_ptp_servo_usecintv_get(int8 log_int) {
    949   switch(log_int) 
    950   {
    951     case -4:
    952       return 62500; 
    953     case -5:
    954       return 31250;
    955     case -6:
    956       return 15625;
    957     case -7:
    958       /* 128pps - Interval is 7812.5 usec */
    959       return 7812;
    960     case -3:
    961       return 125000;
    962     case -2:
    963       return 250000;
    964     case -1:
    965       return 500000;
    966     case 0:
    967       return 1000000;
    968     case 1:
    969       return 2000000;
    970     case 2:
    971       return 4000000;
    972     case 3:
    973       return 8000000;
    974     case 4:
    975       return 16000000;
    976     default:
    977       return 0;
    978   }
    979 }
    980 
    981 #ifdef BCM_PTP_EXT_SERVO_ABS_TS_SUPPORT
    982 /* absolute timestamps */
    983 int _bcm_ptp_servo_AddFullTimestamps(int unit,
    984     bcm_ptp_stack_id_t             ptp_id,
    985     int                            clock_num,
    986     bcm_ptp_port_identity_t *      master_portId,
    987     int                            num_TS,
    988     uint8*                         ts_ptr,
    989     _bcm_ptp_ts_type_t             direction,
    990     uint32                         int_usec)
    991 {
    992 
    993     int rv = BCM_E_NONE;
    994     int idx=0;
    995 
    996 	T_ieee1588PortIdentity master;
    997     T_ieee1588Timestamp txTS, rxTS;
    998 
    999 	if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
   1000         return rv ;
   1001     }
   1002 
   1003     if(!master_portId) { 
   1004         return BCM_E_PARAM;
   1005 	}
   1006 
   1007     sal_memcpy(&master.clockIdentity, &master_portId->clock_identity, sizeof(bcm_ptp_clock_identity_t));
   1008     master.portNumber = master_portId->port_number; 
   1009 
   1010     LOG_DEBUG(BSL_LS_BCM_PTP,
   1011             (BSL_META_U(unit, "Add Timestamps to servo: int[%dusec] num_TS[%d] direction[%d]\n"), int_usec, num_TS, direction));
   1012 
   1013     for (idx=0; idx<num_TS; idx++) {
   1014 		txTS.seconds = _bcm_ptp_uint64_read(ts_ptr);
   1015 		ts_ptr+=8;
   1016 		txTS.nanoseconds = _bcm_ptp_uint32_read(ts_ptr);
   1017 		ts_ptr+=4;
   1018 		rxTS.seconds = _bcm_ptp_uint64_read(ts_ptr);
   1019 		ts_ptr+=8;
   1020 		rxTS.nanoseconds = _bcm_ptp_uint32_read(ts_ptr);
   1021 		ts_ptr+=4;
   1022 
   1023 		LOG_DEBUG(BSL_LS_BCM_PTP,
   1024 		    (BSL_META_U(unit, "txTS[%llx.%x] rxTS[%llx.%x] \n"), (long long unsigned int)txTS.seconds, txTS.nanoseconds, 
   1025 		                                                (long long unsigned int)rxTS.seconds, rxTS.nanoseconds));
   1026 
   1027         if (direction == _bcm_ptp_ts_type_downlink) {
   1028             rv = IDTStackAdaptor_AddDownlinkTimeStamps( &master,  txTS, 0, rxTS, int_usec);
   1029             if (rv) {
   1030                 PTP_ERROR_FUNC("IDTStackAdaptor_AddDownlinkTimeStamps( )");
   1031                 return BCM_E_FAIL;
   1032             }
   1033         } else {
   1034             rv = IDTStackAdaptor_AddUplinkTimeStamps( &master,  txTS, 0, rxTS, int_usec);
   1035             if (rv) {
   1036                 PTP_ERROR_FUNC("IDTStackAdaptor_AddDownlinkTimeStamps( )");
   1037                 return BCM_E_FAIL;
   1038             }
   1039         }
   1040     }
   1041     return rv;
   1042 }
   1043 #else
   1044 /* timestamp differences */
   1045 int _bcm_ptp_servo_AddTimestampDiffs(int unit,
   1046     bcm_ptp_stack_id_t             ptp_id,
   1047     int                            clock_num,
   1048     bcm_ptp_port_identity_t *      master_portId,
   1049     int                            num_TS,
   1050     bcm_ptp_timestamp_t            first_TS,
   1051     uint8*                         ts_ptr,
   1052     _bcm_ptp_ts_type_t             direction,
   1053     uint32                         int_usec)
   1054 {
   1055 
   1056     int rv = BCM_E_NONE;
   1057 
   1058 	T_ieee1588PortIdentity master;
   1059     T_ieee1588Timestamp firstTS = {0, 0};
   1060 	int i=0;
   1061     int64_t ts_diff_arr[num_TS];
   1062 
   1063 	if(PTP_SERVO_IS_BCM(unit, ptp_id, clock_num)) {
   1064         return rv ;
   1065     }
   1066 
   1067     if(!master_portId) { 
   1068         return BCM_E_PARAM;
   1069 	}
   1070 
   1071     LOG_DEBUG(BSL_LS_BCM_PTP,
   1072             (BSL_META_U(unit, "\nAdd Timestamps to servo: int[%dusec] num_TS[%d] direction[%d]\n"), int_usec, num_TS, direction));
   1073 
   1074     LOG_DEBUG(BSL_LS_BCM_PTP,
   1075             (BSL_META_U(unit, " first_TS[0x%016llx %lldsec.%unsec] \n"), (long long int)first_TS.seconds, (long long int)first_TS.seconds, first_TS.nanoseconds));
   1076 
   1077     for (i=0; i<num_TS; i++) {
   1078 		ts_diff_arr[i] = _bcm_ptp_int64_read(ts_ptr +(i*8));
   1079         LOG_DEBUG(BSL_LS_BCM_PTP,
   1080             (BSL_META_U(unit, " [%d][0x%016llx/%lldnsec] \n"), i, (long long int)ts_diff_arr[i], (long long int)ts_diff_arr[i]));
   1081 	}
   1082 
   1083     sal_memcpy(&master.clockIdentity, &master_portId->clock_identity, sizeof(bcm_ptp_clock_identity_t));
   1084     master.portNumber = master_portId->port_number; 
   1085 
   1086 #if 0
   1087     /* Enable only for debugging with first TS pair */
   1088     firstTS.seconds = first_TS.seconds;
   1089     firstTS.nanoseconds = first_TS.nanoseconds;
   1090 #endif
   1091 
   1092     if(num_TS > BCM_PTP_EXT_SERVO_TS_RATE_MAX) {
   1093         LOG_VERBOSE(BSL_LS_BCM_PTP,
   1094             (BSL_META_U(unit, "\n ***** NUM_TS exceeded max limit : int[%dusec] num_TS[%d] direction[%d] ***** \n"), int_usec, num_TS, direction));
   1095         if (direction == _bcm_ptp_ts_type_downlink) {
   1096             mbox_tsevent_stats.event_dl_ts_above_thres++;
   1097         } else {
   1098             mbox_tsevent_stats.event_ul_ts_above_thres++;
   1099         }
   1100         num_TS = BCM_PTP_EXT_SERVO_TS_RATE_MAX;
   1101         /* return BCM_E_FAIL; */
   1102     }
   1103 
   1104     if (direction == _bcm_ptp_ts_type_downlink) {
   1105         mbox_tsevent_stats.event_dl_ts++;
   1106         rv = IDTStackAdaptor_AddDownlinkTimeStampDifferences( &master, firstTS, num_TS, (T_osInt64 *)ts_diff_arr, int_usec );
   1107         mbox_tsevent_stats.event_dl_ts_handled++;
   1108         if (rv) {
   1109             return BCM_E_FAIL;
   1110         }
   1111     } else {
   1112         mbox_tsevent_stats.event_ul_ts++;
   1113         rv = IDTStackAdaptor_AddUplinkTimeStampDifferences( &master, firstTS, num_TS, (T_osInt64 *)ts_diff_arr, int_usec );
   1114         mbox_tsevent_stats.event_ul_ts_handled++;
   1115         if (rv) {
   1116            return BCM_E_FAIL;
   1117         }
   1118     }
   1119     return rv;
   1120 }
   1121 #endif /* BCM_PTP_EXT_SERVO_ABS_TS_SUPPORT */
   1122 
   1123 /*
   1124  * Function:
   1125  *      _bcm_ptp_ext_servo_ptsf_set
   1126  * Purpose:
   1127  *      set PTP servo state and status information.
   1128  * Parameters:
   1129  *      unit      - (IN)  Unit number.
   1130  *      ptp_id    - (IN)  PTP stack ID.
   1131  *      clock_num - (IN)  PTP clock number.
   1132  *      state     - (IN)  PTP ext-servo's state.
   1133  * Returns:
   1134  *      BCM_E_XXX - Function status.
   1135  * Notes:
   1136  */
   1137 static int
   1138 _bcm_ptp_ext_servo_ptsf_set(
   1139     int unit,
   1140     bcm_ptp_stack_id_t ptp_id,
   1141     int clock_num,
   1142     bcm_ptp_port_identity_t *master,
   1143     T_osBool b_signalFail)
   1144 {
   1145     int rv = BCM_E_UNAVAIL;
   1146 
   1147     uint8 payload[PTP_MGMTMSG_PAYLOAD_PTSF_UNUSABLE_MSG_SIZE_OCTETS] = {0};
   1148     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1149     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1150     int i = 0;
   1151 
   1152     bcm_ptp_port_identity_t portid;
   1153 
   1154     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
   1155             clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1156         return rv;
   1157     }
   1158 
   1159     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1160             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1161         /* On error, target message to (all clocks, all ports) portIdentity. */
   1162         portid = portid_all;
   1163     }
   1164 
   1165     i = 0;
   1166     sal_memcpy(payload,
   1167                master->clock_identity,
   1168                sizeof(bcm_ptp_clock_identity_t));
   1169     i += sizeof(bcm_ptp_clock_identity_t);
   1170 
   1171     _bcm_ptp_uint16_write(payload + i, master->port_number);
   1172     i += 2;
   1173 
   1174     payload[i] = b_signalFail ? 1 : 0;
   1175 
   1176     if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id,
   1177             clock_num, &portid,
   1178             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_PORT_PTSF_UNUSABLE,
   1179             payload, PTP_MGMTMSG_PAYLOAD_PTSF_UNUSABLE_MSG_SIZE_OCTETS,
   1180             resp, &resp_len))) {
   1181         return rv;
   1182     }
   1183     return rv;
   1184 }
   1185 
   1186 
   1187 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */
   1188 
   1189 #endif /* defined(INCLUDE_PTP)*/