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)*/