telecom.c (75325B)
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: telecom.c 8 * 9 * Purpose: 10 * 11 * Functions: 12 * bcm_common_ptp_telecom_g8265_init 13 * bcm_common_ptp_telecom_g8265_shutdown 14 * bcm_common_ptp_telecom_g8265_network_option_get 15 * bcm_common_ptp_telecom_g8265_network_option_set 16 * bcm_common_ptp_telecom_g8265_quality_level_set 17 * bcm_common_ptp_telecom_g8265_receipt_timeout_get 18 * bcm_common_ptp_telecom_g8265_receipt_timeout_set 19 * bcm_common_ptp_telecom_g8265_pktstats_thresholds_get 20 * bcm_common_ptp_telecom_g8265_pktstats_thresholds_set 21 * bcm_common_ptp_telecom_g8265_packet_master_list 22 * bcm_common_ptp_telecom_g8265_packet_master_best_get 23 * bcm_common_ptp_telecom_g8265_packet_master_get 24 * bcm_common_ptp_telecom_g8265_packet_master_add 25 * bcm_common_ptp_telecom_g8265_packet_master_remove 26 * bcm_common_ptp_telecom_g8265_packet_master_lockout_set 27 * bcm_common_ptp_telecom_g8265_packet_master_non_reversion_set 28 * bcm_common_ptp_telecom_g8265_packet_master_wait_duration_set 29 * bcm_common_ptp_telecom_g8265_packet_master_priority_override 30 * bcm_common_ptp_telecom_g8265_packet_master_priority_set 31 * 32 * _bcm_ptp_telecom_g8265_map_clockClass_QL 33 * _bcm_ptp_telecom_g8265_verbose_level_set 34 * _bcm_ptp_telecom_g8265_profile_enabled_set 35 * _bcm_ptp_telecom_g8265_controller 36 * _bcm_ptp_telecom_g8265_AMT_set 37 * _bcm_ptp_telecom_g8265_master_selector 38 * _bcm_ptp_telecom_g8265_PTSF_set 39 * _bcm_ptp_telecom_g8265_packet_master_PTSF_set 40 * _bcm_ptp_telecom_g8265_degrade_ql_set 41 * _bcm_ptp_telecom_g8265_packet_master_degrade_ql_set 42 * _bcm_ptp_telecom_g8265_wait_to_restore_set 43 * _bcm_ptp_telecom_g8265_packet_master_wait_to_restore_set 44 * _bcm_ptp_telecom_g8265_packet_master_fmds_processor 45 * _bcm_ptp_telecom_g8265_packet_master_priority_calculator 46 * _bcm_ptp_telecom_g8265_packet_master_manager 47 * _bcm_ptp_telecom_g8265_packet_master_lookup 48 * _bcm_ptp_telecom_g8265_packet_master_make 49 * _bcm_ptp_telecom_g8265_packet_master_printout 50 * _bcm_ptp_telecom_g8265_event_description 51 */ 52 53 #if defined(INCLUDE_PTP) 54 55 #include <bcm/ptp.h> 56 #include <bcm_int/common/ptp.h> 57 #include <bcm_int/ptp_common.h> 58 #include <bcm/error.h> 59 #include <shared/bsl.h> 60 #include <sal/core/dpc.h> 61 #include <sal/core/time.h> 62 63 /* Definitions. */ 64 #define PTP_TELECOM_CONTROLLER_DPC_TIME_USEC_DEFAULT (1000000) 65 #define PTP_TELECOM_CONTROLLER_DPC_TIME_USEC_IDLE (3000000) 66 #define PTP_TELECOM_MUTEX_TIMEOUT_USEC (100000) 67 68 #define PTP_TELECOM_MESSAGE_ELAPSED_TIME_MSEC_MAX (3600000) 69 #define PTP_TELECOM_MESSAGE_ELAPSED_TIME_MSEC_UNAVAIL ((uint32)-1) 70 71 #define PACKET_MASTER(index) (telecom.gm[index]) 72 #define PACKET_MASTER_BEST PACKET_MASTER(telecom.selected_gm) 73 74 #define PACKET_MASTER_INVALID(PKT_MASTER) \ 75 (bcm_ptp_telecom_g8265_pktmaster_state_unused == PKT_MASTER.state || \ 76 (bcm_ptp_telecom_g8265_ql_I_dnu == PKT_MASTER.quality_level) || \ 77 (bcm_ptp_telecom_g8265_ql_II_dus == PKT_MASTER.quality_level) || \ 78 (bcm_ptp_telecom_g8265_ql_invalid == PKT_MASTER.quality_level) || \ 79 1 == PKT_MASTER.selector.lockout || \ 80 1 == PKT_MASTER.selector.wait_to_restore || \ 81 1 == PKT_MASTER.ptsf.loss_announce || \ 82 1 == PKT_MASTER.ptsf.loss_sync || \ 83 1 == PKT_MASTER.ptsf.unusable || \ 84 1 == PKT_MASTER.hql.degrade_ql) 85 86 /* Macros. */ 87 #define PTP_TELECOM_MUTEX_TAKE() \ 88 PTP_MUTEX_TAKE(telecom_g8265_mutex, PTP_TELECOM_MUTEX_TIMEOUT_USEC) 89 90 #define PTP_TELECOM_MUTEX_RELEASE_RETURN(__rv__) \ 91 PTP_MUTEX_RELEASE_RETURN(telecom_g8265_mutex, __rv__) 92 93 #define PTP_TELECOM_EVENT_REGISTER(__GM__,__event__) \ 94 do { \ 95 if (++telecom_fifo.head >= PTP_TELECOM_EVENT_FIFO_SIZE || \ 96 telecom_fifo.head <= 0) { \ 97 telecom_fifo.head = 0; \ 98 } \ 99 telecom_fifo.events[telecom_fifo.head].timestamp = sal_time(); \ 100 telecom_fifo.events[telecom_fifo.head].pktmaster = *__GM__; \ 101 telecom_fifo.events[telecom_fifo.head].type = 0; \ 102 telecom_fifo.events[telecom_fifo.head].type |= (1u << __event__); \ 103 } while (0) 104 105 #define PTP_TELECOM_EVENT_HEAD_PRINT() \ 106 do { \ 107 if (telecom_g8265_verbose_level) { \ 108 uint32 lcl_type = telecom_fifo.events[telecom_fifo.head].type; \ 109 bcm_ptp_telecom_g8265_pktmaster_t *lcl_gm = \ 110 &telecom_fifo.events[telecom_fifo.head].pktmaster; \ 111 \ 112 LOG_CLI((BSL_META("Telecom Event: %s @ %u\n"), \ 113 _bcm_ptp_telecom_g8265_event_description(lcl_type), \ 114 (uint32)telecom_fifo.events[telecom_fifo.head].timestamp)); \ 115 _bcm_ptp_telecom_g8265_packet_master_printout(lcl_gm, 0); \ 116 } \ 117 } while (0) 118 119 /* Constants and variables. */ 120 static int telecom_g8265_init = 0; 121 static int telecom_g8265_mstr_unavail = 0; 122 static uint32 telecom_g8265_verbose_level = 0; 123 static _bcm_ptp_mutex_t telecom_g8265_mutex = 0x0; 124 125 static const bcm_ptp_telecom_g8265_pktmaster_t pktmaster_zero; 126 static _bcm_ptp_telecom_g8265_event_fifo_t telecom_fifo; 127 static bcm_ptp_telecom_g8265_profile_t telecom; 128 static shr_rdpc_t telecom_g8265_controller_rdpc; 129 130 131 /* Static functions. */ 132 static int _bcm_ptp_telecom_g8265_profile_enabled_set( 133 int unit, bcm_ptp_stack_id_t ptp_id, int clock_num, uint8 enabled); 134 135 static sal_usecs_t _bcm_ptp_telecom_g8265_controller( 136 void **arg_unit, void **arg_ptp_id, 137 void **arg_clock_num, void **unused); 138 139 static int _bcm_ptp_telecom_g8265_AMT_set( 140 int unit, bcm_ptp_stack_id_t ptp_id, int clock_num, uint32 clock_port); 141 142 static int _bcm_ptp_telecom_g8265_master_selector( 143 void); 144 145 static int _bcm_ptp_telecom_g8265_PTSF_set( 146 void); 147 148 static int _bcm_ptp_telecom_g8265_packet_master_PTSF_set( 149 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster); 150 151 static int _bcm_ptp_telecom_g8265_degrade_ql_set( 152 void); 153 154 static int _bcm_ptp_telecom_g8265_packet_master_degrade_ql_set( 155 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster); 156 157 static int _bcm_ptp_telecom_g8265_wait_to_restore_set( 158 void); 159 160 static int _bcm_ptp_telecom_g8265_packet_master_wait_to_restore_set( 161 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster); 162 163 static int _bcm_ptp_telecom_g8265_packet_master_fmds_processor( 164 int unit, bcm_ptp_stack_id_t ptp_id, int clock_num, 165 bcm_ptp_foreign_master_dataset_t *FMds); 166 167 static int _bcm_ptp_telecom_g8265_packet_master_priority_calculator( 168 uint8 gmPriority1, uint8 gmPriority2, 169 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster); 170 171 static int _bcm_ptp_telecom_g8265_packet_master_manager( 172 bcm_ptp_clock_port_address_t *address, int *index); 173 174 static int _bcm_ptp_telecom_g8265_packet_master_lookup( 175 bcm_ptp_clock_port_address_t *address, int *index); 176 177 static int _bcm_ptp_telecom_g8265_packet_master_make( 178 bcm_ptp_clock_port_address_t *address, 179 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster); 180 181 static int _bcm_ptp_telecom_g8265_packet_master_printout( 182 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster, uint8 flags); 183 184 static const char* _bcm_ptp_telecom_g8265_event_description( 185 uint32 type); 186 187 /* 188 * Function: 189 * bcm_common_ptp_telecom_g8265_init 190 * Purpose: 191 * Initialize the telecom profile. 192 * Parameters: 193 * unit - (IN) Unit number. 194 * ptp_id - (IN) PTP stack ID. 195 * clock_num - (IN) PTP clock number. 196 * Returns: 197 * BCM_E_XXX - Function status. 198 * Notes: 199 */ 200 int 201 bcm_common_ptp_telecom_g8265_init( 202 int unit, 203 bcm_ptp_stack_id_t ptp_id, 204 int clock_num) 205 { 206 int rv; 207 int el; 208 209 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 210 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 211 return rv; 212 } 213 214 if (!telecom_g8265_mutex) { 215 telecom_g8265_mutex = _bcm_ptp_mutex_create("telecom_packet_master_array"); 216 } 217 218 telecom_g8265_mstr_unavail = 0; 219 220 if (shr_rdpc_callback_created(&telecom_g8265_controller_rdpc) == BCM_E_INIT) { 221 /* RDPC (and associated lock) is left in place on cleanup, so only create it once */ 222 shr_rdpc_callback_create(&telecom_g8265_controller_rdpc, &_bcm_ptp_telecom_g8265_controller); 223 } 224 225 /* Set ITU-T G.781 synchronization networking option. */ 226 telecom.network_option = bcm_ptp_telecom_g8265_network_option_disable; 227 228 /* 229 * Set PTP message receipt timeouts. 230 * NOTE : announceReceiptTimeout is not referenced in current implementation. 231 * PTSF lossAnnounce is handled in the firmware foreignMasterDS logic. 232 */ 233 telecom.receipt_timeouts.announce = PTP_TELECOM_ANNOUNCE_RECEIPT_TIMEOUT_MSEC_DEFAULT; 234 telecom.receipt_timeouts.sync = PTP_TELECOM_SYNC_RECEIPT_TIMEOUT_MSEC_DEFAULT; 235 telecom.receipt_timeouts.delay_resp = PTP_TELECOM_DELAYRESP_RECEIPT_TIMEOUT_MSEC_DEFAULT; 236 237 /* Set packet statistics thresholds. */ 238 COMPILER_64_SET(telecom.thresholds.pdv_scaled_allan_var, 0, 239 PTP_TELECOM_PDV_SCALED_ALLAN_VARIANCE_THRESHOLD_NSECSQ_DEFAULT); 240 241 /* Set selected packet master. */ 242 telecom.previous_gm = -1; 243 telecom.selected_gm = 0; 244 245 /* Initialize packet master array entries. */ 246 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 247 PACKET_MASTER(el) = pktmaster_zero; 248 PACKET_MASTER(el).selector.non_reversion = PTP_TELECOM_NON_REVERSION_MODE_DEFAULT; 249 COMPILER_64_SET(PACKET_MASTER(el).selector.wait_sec, 0, PTP_TELECOM_WAIT_TO_RESTORE_SEC_DEFAULT); 250 PACKET_MASTER(el).state = bcm_ptp_telecom_g8265_pktmaster_state_unused; 251 } 252 253 /* Initialize event FIFO. */ 254 telecom_fifo.head = -1; 255 256 telecom_g8265_init = 1; 257 return BCM_E_NONE; 258 } 259 260 /* 261 * Function: 262 * bcm_common_ptp_telecom_g8265_shutdown 263 * Purpose: 264 * Shut down the telecom profile. 265 * Parameters: 266 * unit - (IN) Unit number. 267 * Returns: 268 * BCM_E_XXX - Function status. 269 * Notes: 270 */ 271 int 272 bcm_common_ptp_telecom_g8265_shutdown( 273 int unit) 274 { 275 /* Cancel telecom controller repeating delayed procedure call. */ 276 shr_rdpc_callback_stop(&telecom_g8265_controller_rdpc); 277 return BCM_E_NONE; 278 } 279 280 /* 281 * Function: 282 * bcm_common_ptp_telecom_g8265_network_option_get 283 * Purpose: 284 * Get telecom profile ITU-T G.781 network option. 285 * Parameters: 286 * unit - (IN) Unit number. 287 * ptp_id - (IN) PTP stack ID. 288 * clock_num - (IN) PTP clock number. 289 * network_option - (OUT) Telecom profile ITU-T G.781 network option. 290 * |Disable |Option I |Option II |Option III | 291 * Returns: 292 * BCM_E_XXX - Function status. 293 * Notes: 294 */ 295 int 296 bcm_common_ptp_telecom_g8265_network_option_get( 297 int unit, 298 bcm_ptp_stack_id_t ptp_id, 299 int clock_num, 300 bcm_ptp_telecom_g8265_network_option_t *network_option) 301 { 302 *network_option = telecom.network_option; 303 return BCM_E_NONE; 304 } 305 306 /* 307 * Function: 308 * bcm_common_ptp_telecom_g8265_network_option_set 309 * Purpose: 310 * Set telecom profile ITU-T G.781 network option. 311 * Parameters: 312 * unit - (IN) Unit number. 313 * ptp_id - (IN) PTP stack ID. 314 * clock_num - (IN) PTP clock number. 315 * network_option - (IN) Telecom profile ITU-T G.781 network option. 316 * |Disable |Option I |Option II |Option III | 317 * Returns: 318 * BCM_E_XXX - Function status. 319 * Notes: 320 */ 321 int 322 bcm_common_ptp_telecom_g8265_network_option_set( 323 int unit, 324 bcm_ptp_stack_id_t ptp_id, 325 int clock_num, 326 bcm_ptp_telecom_g8265_network_option_t network_option) 327 { 328 int rv; 329 uint8 enabled; 330 331 telecom.network_option = network_option; 332 333 enabled = (bcm_ptp_telecom_g8265_network_option_disable == network_option) ? (0):(1); 334 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_profile_enabled_set(unit, ptp_id, 335 clock_num, enabled))){ 336 return rv; 337 } 338 return BCM_E_NONE; 339 } 340 341 /* 342 * Function: 343 * bcm_common_ptp_telecom_g8265_quality_level_set 344 * Purpose: 345 * Set the ITU-T G.781 quality level (QL) of local clock. 346 * Parameters: 347 * unit - (IN) Unit number. 348 * ptp_id - (IN) PTP stack ID. 349 * clock_num - (IN) PTP clock number. 350 * QL - (IN) Quality level. 351 * Returns: 352 * BCM_E_XXX - Function status. 353 * Notes: 354 * Ref. ITU-T G.781 and ITU-T G.8265.1. 355 * Quality level is mapped to PTP clockClass. 356 * Quality level is used to infer ITU-T G.781 synchronization network 357 * option. ITU-T G.781 synchronization network option must be uniform 358 * among slave and its packet masters. 359 */ 360 int 361 bcm_common_ptp_telecom_g8265_quality_level_set( 362 int unit, 363 bcm_ptp_stack_id_t ptp_id, 364 int clock_num, 365 bcm_ptp_telecom_g8265_quality_level_t QL) 366 { 367 int rv = BCM_E_NONE; 368 uint8 clockClass; 369 bcm_ptp_clock_info_t ci; 370 371 if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_info_get(unit, ptp_id, 372 clock_num, &ci))) { 373 return rv; 374 } 375 376 if (ci.slaveonly) { 377 /* Packet slave clock. Supersede caller-provided QL. */ 378 QL = bcm_ptp_telecom_g8265_ql_na_slv; 379 } else { 380 /* Set ITU-T G.781 synchronization networking option. */ 381 if (telecom.network_option != (QL /0x10)) { 382 LOG_CLI((BSL_META_U(unit, 383 "ITU-T G.781 synchronization networking " 384 "option changed.\n"))); 385 } 386 telecom.network_option = QL / 0x10; 387 } 388 389 /* Set PTP clockClass. */ 390 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_map_QL_clockClass(QL, &clockClass))) { 391 return rv; 392 } 393 394 if (BCM_FAILURE(rv = _bcm_ptp_clock_class_set(unit, ptp_id, clock_num, clockClass))) { 395 return rv; 396 } 397 398 return BCM_E_NONE; 399 } 400 401 /* 402 * Function: 403 * bcm_common_ptp_telecom_g8265_receipt_timeout_get 404 * Purpose: 405 * Get PTP |Announce|Sync|Delay_Resp| message receipt timeout req'd for 406 * packet timing signal fail (PTSF) analysis. 407 * Parameters: 408 * unit - (IN) Unit number. 409 * ptp_id - (IN) PTP stack ID. 410 * clock_num - (IN) PTP clock number. 411 * messageType - (IN) PTP message type. 412 * receiptTimeout - (OUT) PTP |Announce|Sync|Delay_Resp| message receipt timeout. 413 * Returns: 414 * BCM_E_XXX - Function status. 415 * Notes: 416 */ 417 int 418 bcm_common_ptp_telecom_g8265_receipt_timeout_get( 419 int unit, 420 bcm_ptp_stack_id_t ptp_id, 421 int clock_num, 422 bcm_ptp_message_type_t messageType, 423 uint32 *receiptTimeout) 424 { 425 switch (messageType) { 426 case bcmPTP_MESSAGE_TYPE_ANNOUNCE: 427 *receiptTimeout = telecom.receipt_timeouts.announce; 428 break; 429 430 case bcmPTP_MESSAGE_TYPE_SYNC: 431 *receiptTimeout = telecom.receipt_timeouts.sync; 432 break; 433 434 case bcmPTP_MESSAGE_TYPE_DELAY_RESP: 435 *receiptTimeout = telecom.receipt_timeouts.delay_resp; 436 break; 437 438 default: 439 *receiptTimeout = 0; 440 return BCM_E_PARAM; 441 } 442 443 return BCM_E_NONE; 444 } 445 446 /* 447 * Function: 448 * bcm_common_ptp_telecom_g8265_receipt_timeout_set 449 * Purpose: 450 * Set PTP |Announce|Sync|Delay_Resp| message receipt timeout req'd for 451 * packet timing signal fail (PTSF) analysis. 452 * Parameters: 453 * unit - (IN) Unit number. 454 * ptp_id - (IN) PTP stack ID. 455 * clock_num - (IN) PTP clock number. 456 * messageType - (IN) PTP message type. 457 * receiptTimeout - (IN) PTP |Announce|Sync|Delay_Resp| message receipt timeout. 458 * Returns: 459 * BCM_E_XXX - Function status. 460 * Notes: 461 */ 462 int 463 bcm_common_ptp_telecom_g8265_receipt_timeout_set( 464 int unit, 465 bcm_ptp_stack_id_t ptp_id, 466 int clock_num, 467 bcm_ptp_message_type_t messageType, 468 uint32 receiptTimeout) 469 { 470 switch (messageType) { 471 case bcmPTP_MESSAGE_TYPE_ANNOUNCE: 472 telecom.receipt_timeouts.announce = receiptTimeout; 473 break; 474 475 case bcmPTP_MESSAGE_TYPE_SYNC: 476 telecom.receipt_timeouts.sync = receiptTimeout; 477 break; 478 479 case bcmPTP_MESSAGE_TYPE_DELAY_RESP: 480 telecom.receipt_timeouts.delay_resp = receiptTimeout; 481 break; 482 483 default: 484 return BCM_E_PARAM; 485 } 486 487 return BCM_E_NONE; 488 } 489 490 /* Function: 491 * bcm_common_ptp_telecom_g8265_pktstats_thresholds_get 492 * Purpose: 493 * Get packet timing and PDV statistics thresholds req'd for packet timing 494 * signal fail (PTSF) analysis. 495 * Parameters: 496 * unit - (IN) Unit number. 497 * ptp_id - (IN) PTP stack ID. 498 * clock_num - (IN) PTP clock number. 499 * thresholds - (OUT) Packet timing and PDV statistics thresholds. 500 * Returns: 501 * BCM_E_XXX - Function status. 502 * Notes: 503 */ 504 int 505 bcm_common_ptp_telecom_g8265_pktstats_thresholds_get( 506 int unit, 507 bcm_ptp_stack_id_t ptp_id, 508 int clock_num, 509 bcm_ptp_telecom_g8265_pktstats_t *thresholds) 510 { 511 COMPILER_64_SET(thresholds->pdv_scaled_allan_var, 512 COMPILER_64_HI(telecom.thresholds.pdv_scaled_allan_var), 513 COMPILER_64_LO(telecom.thresholds.pdv_scaled_allan_var)); 514 515 return BCM_E_NONE; 516 } 517 518 /* Function: 519 * bcm_common_ptp_telecom_g8265_pktstats_thresholds_set 520 * Purpose: 521 * Set packet timing and PDV statistics thresholds req'd for packet timing 522 * signal fail (PTSF) analysis. 523 * Parameters: 524 * unit - (IN) Unit number. 525 * ptp_id - (IN) PTP stack ID. 526 * clock_num - (IN) PTP clock number. 527 * thresholds - (IN) Packet timing and PDV statistics thresholds. 528 * Returns: 529 * BCM_E_XXX - Function status. 530 * Notes: 531 */ 532 int 533 bcm_common_ptp_telecom_g8265_pktstats_thresholds_set( 534 int unit, 535 bcm_ptp_stack_id_t ptp_id, 536 int clock_num, 537 bcm_ptp_telecom_g8265_pktstats_t thresholds) 538 { 539 int rv = BCM_E_NONE; 540 COMPILER_64_SET(telecom.thresholds.pdv_scaled_allan_var, 541 COMPILER_64_HI(thresholds.pdv_scaled_allan_var), 542 COMPILER_64_LO(thresholds.pdv_scaled_allan_var)); 543 return rv; 544 } 545 546 /* 547 * Function: 548 * bcm_common_ptp_telecom_g8265_packet_master_list 549 * Purpose: 550 * Get list of in-use packet masters. 551 * Parameters: 552 * unit - (IN) Unit number. 553 * ptp_id - (IN) PTP stack ID. 554 * clock_num - (IN) PTP clock number. 555 * max_num_masters - (IN) Maximum number of packet masters. 556 * num_masters - (OUT) Number of in-use packet masters. 557 * best_master - (OUT) Best packet master list index. 558 * pktmaster - (OUT) Packet masters. 559 * Returns: 560 * BCM_E_XXX - Function status. 561 * Notes: 562 */ 563 int 564 bcm_common_ptp_telecom_g8265_packet_master_list( 565 int unit, 566 bcm_ptp_stack_id_t ptp_id, 567 int clock_num, 568 int max_num_masters, 569 int *num_masters, 570 int *best_master, 571 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster) 572 { 573 int el; 574 575 *num_masters = 0; 576 *best_master = -1; 577 578 PTP_TELECOM_MUTEX_TAKE(); 579 580 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 581 if (bcm_ptp_telecom_g8265_pktmaster_state_unused != PACKET_MASTER(el).state) { 582 if (*num_masters == max_num_masters) { 583 /* Insufficient caller-provided table size for result. */ 584 *num_masters = 0; 585 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_RESOURCE); 586 } 587 if (telecom.selected_gm == el) { 588 *best_master = *num_masters; 589 } 590 pktmaster[(*num_masters)++] = PACKET_MASTER(el); 591 } 592 } 593 594 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 595 } 596 597 /* 598 * Function: 599 * bcm_common_ptp_telecom_g8265_packet_master_best_get 600 * Purpose: 601 * Get current best packet master clock as defined by telecom profile 602 * master selection logic. 603 * Parameters: 604 * unit - (IN) Unit number. 605 * ptp_id - (IN) PTP stack ID. 606 * clock_num - (IN) PTP clock number. 607 * pktmaster - (OUT) Best packet master clock. 608 * Returns: 609 * BCM_E_XXX - Function status. 610 * Notes: 611 */ 612 int 613 bcm_common_ptp_telecom_g8265_packet_master_best_get( 614 int unit, 615 bcm_ptp_stack_id_t ptp_id, 616 int clock_num, 617 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster) 618 { 619 PTP_TELECOM_MUTEX_TAKE(); 620 621 if (bcm_ptp_telecom_g8265_pktmaster_state_unused != PACKET_MASTER_BEST.state) { 622 *pktmaster = PACKET_MASTER_BEST; 623 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 624 } 625 626 *pktmaster = pktmaster_zero; 627 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NOT_FOUND); 628 } 629 630 /* 631 * Function: 632 * bcm_common_ptp_telecom_g8265_packet_master_get 633 * Purpose: 634 * Get packet master by address. 635 * Parameters: 636 * unit - (IN) Unit number. 637 * ptp_id - (IN) PTP stack ID. 638 * clock_num - (IN) PTP clock number. 639 * address - (IN) Packet master address. 640 * pktmaster - (OUT) Packet master. 641 * Returns: 642 * BCM_E_XXX - Function status. 643 * Notes: 644 */ 645 int 646 bcm_common_ptp_telecom_g8265_packet_master_get( 647 int unit, 648 bcm_ptp_stack_id_t ptp_id, 649 int clock_num, 650 bcm_ptp_clock_port_address_t *address, 651 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster) 652 { 653 int rv; 654 int el; 655 656 PTP_TELECOM_MUTEX_TAKE(); 657 658 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_lookup(address, &el))) { 659 *pktmaster = pktmaster_zero; 660 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_lookup()"); 661 PTP_TELECOM_MUTEX_RELEASE_RETURN(rv); 662 } 663 664 *pktmaster = PACKET_MASTER(el); 665 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 666 } 667 668 /* 669 * Function: 670 * bcm_common_ptp_telecom_g8265_packet_master_add 671 * Purpose: 672 * Add a packet master. 673 * Parameters: 674 * unit - (IN) Unit number. 675 * ptp_id - (IN) PTP stack ID. 676 * clock_num - (IN) PTP clock number. 677 * port_num - (IN) PTP clock port number. 678 * address - (IN) Packet master address. 679 * Returns: 680 * BCM_E_XXX - Function status. 681 * Notes: 682 */ 683 int 684 bcm_common_ptp_telecom_g8265_packet_master_add( 685 int unit, 686 bcm_ptp_stack_id_t ptp_id, 687 int clock_num, 688 int port_num, 689 bcm_ptp_clock_port_address_t *address) 690 { 691 int rv; 692 int el; 693 694 PTP_TELECOM_MUTEX_TAKE(); 695 696 697 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_manager(address, &el))) { 698 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_manager()"); 699 PTP_TELECOM_MUTEX_RELEASE_RETURN(rv); 700 } 701 702 /* Initialize packet master data. */ 703 _bcm_ptp_telecom_g8265_packet_master_make(address, &PACKET_MASTER(el)); 704 705 /* Register event. */ 706 PTP_TELECOM_EVENT_REGISTER(&PACKET_MASTER(el), PTP_TELECOM_EVENT_GM_ADDED_BIT); 707 PTP_TELECOM_EVENT_HEAD_PRINT(); 708 709 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 710 } 711 712 /* 713 * Function: 714 * bcm_common_ptp_telecom_g8265_packet_master_remove 715 * Purpose: 716 * Remove a packet master. 717 * Parameters: 718 * unit - (IN) Unit number. 719 * ptp_id - (IN) PTP stack ID. 720 * clock_num - (IN) PTP clock number. 721 * port_num - (IN) PTP clock port number. 722 * address - (IN) Packet master address. 723 * Returns: 724 * BCM_E_XXX - Function status. 725 * Notes: 726 */ 727 int 728 bcm_common_ptp_telecom_g8265_packet_master_remove( 729 int unit, 730 bcm_ptp_stack_id_t ptp_id, 731 int clock_num, 732 int port_num, 733 bcm_ptp_clock_port_address_t *address) 734 { 735 int rv; 736 int el; 737 738 PTP_TELECOM_MUTEX_TAKE(); 739 740 741 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_manager(address, &el))) { 742 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_manager()"); 743 PTP_TELECOM_MUTEX_RELEASE_RETURN(rv); 744 } 745 746 /* Register event. */ 747 PTP_TELECOM_EVENT_REGISTER(&PACKET_MASTER(el), PTP_TELECOM_EVENT_GM_REMOVED_BIT); 748 PTP_TELECOM_EVENT_HEAD_PRINT(); 749 750 /* Clear packet master data. */ 751 PACKET_MASTER(el) = pktmaster_zero; 752 PACKET_MASTER(el).selector.non_reversion = PTP_TELECOM_NON_REVERSION_MODE_DEFAULT; 753 COMPILER_64_SET(PACKET_MASTER(el).selector.wait_sec, 0, PTP_TELECOM_WAIT_TO_RESTORE_SEC_DEFAULT); 754 PACKET_MASTER(el).state = bcm_ptp_telecom_g8265_pktmaster_state_unused; 755 756 /* If previous GM is being removed, reset it to enable proper AMT notification of new GM */ 757 if (el == telecom.previous_gm) 758 { 759 telecom.previous_gm = -1; 760 } 761 /* Call telecom controller (so changes take effect immediately). */ 762 if (telecom.network_option != bcm_ptp_telecom_g8265_network_option_disable) { 763 shr_rdpc_callback_start(&telecom_g8265_controller_rdpc, 0, 764 INT_TO_PTR(unit), INT_TO_PTR(ptp_id), INT_TO_PTR(clock_num), 0); 765 } 766 767 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 768 } 769 770 /* 771 * Function: 772 * bcm_common_ptp_telecom_g8265_packet_master_lockout_set 773 * Purpose: 774 * Set packet master lockout to exclude from master selection process. 775 * Parameters: 776 * unit - (IN) Unit number. 777 * ptp_id - (IN) PTP stack ID. 778 * clock_num - (IN) PTP clock number. 779 * lockout - (IN) Packet master lockout Boolean. 780 * address - (IN) Packet master address. 781 * Returns: 782 * BCM_E_XXX - Function status. 783 * Notes: 784 */ 785 int 786 bcm_common_ptp_telecom_g8265_packet_master_lockout_set( 787 int unit, 788 bcm_ptp_stack_id_t ptp_id, 789 int clock_num, 790 uint8 lockout, 791 bcm_ptp_clock_port_address_t *address) 792 { 793 int rv; 794 int el; 795 796 PTP_TELECOM_MUTEX_TAKE(); 797 798 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_lookup(address, &el))) { 799 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_lookup()"); 800 PTP_TELECOM_MUTEX_RELEASE_RETURN(rv); 801 } 802 PACKET_MASTER(el).selector.lockout = lockout ? 1:0; 803 804 #ifdef BCM_PTP_EXT_SERVO_SUPPORT 805 _bcm_ptp_servo_master_lockout_set(unit, ptp_id, clock_num, lockout, &PACKET_MASTER(el).port_identity); 806 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */ 807 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 808 } 809 810 /* 811 * Function: 812 * bcm_common_ptp_telecom_g8265_packet_master_non_reversion_set 813 * Purpose: 814 * Set packet master non-reversion to control master selection process 815 * if master fails or is unavailable. 816 * Parameters: 817 * unit - (IN) Unit number. 818 * ptp_id - (IN) PTP stack ID. 819 * clock_num - (IN) PTP clock number. 820 * nonrev - (IN) Packet master non-reversion Boolean. 821 * address - (IN) Packet master address. 822 * Returns: 823 * BCM_E_XXX - Function status. 824 * Notes: 825 */ 826 int 827 bcm_common_ptp_telecom_g8265_packet_master_non_reversion_set( 828 int unit, 829 bcm_ptp_stack_id_t ptp_id, 830 int clock_num, 831 uint8 nonrev, 832 bcm_ptp_clock_port_address_t *address) 833 { 834 int rv; 835 int el; 836 837 PTP_TELECOM_MUTEX_TAKE(); 838 839 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_lookup(address, &el))) { 840 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_lookup()"); 841 PTP_TELECOM_MUTEX_RELEASE_RETURN(rv); 842 } 843 PACKET_MASTER(el).selector.non_reversion = nonrev ? 1:0; 844 845 if (nonrev) { 846 /* 847 * Clear historical information so non-revertive behavior applies 848 * from this point forward. 849 */ 850 PACKET_MASTER(el).ptsf.counter = 0; 851 COMPILER_64_ZERO(PACKET_MASTER(el).ptsf.timestamp); 852 853 PACKET_MASTER(el).hql.counter = 0; 854 COMPILER_64_ZERO(PACKET_MASTER(el).hql.timestamp); 855 } 856 857 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 858 } 859 860 /* 861 * Function: 862 * bcm_common_ptp_telecom_g8265_packet_master_wait_duration_set 863 * Purpose: 864 * Set packet master wait-to-restore duration to control master selection 865 * process if master fails or is unavailable. 866 * Parameters: 867 * unit - (IN) Unit number. 868 * ptp_id - (IN) PTP stack ID. 869 * clock_num - (IN) PTP clock number. 870 * wait_sec - (IN) Packet master wait-to-restore duration. 871 * address - (IN) Packet master address. 872 * Returns: 873 * BCM_E_XXX - Function status. 874 * Notes: 875 */ 876 int 877 bcm_common_ptp_telecom_g8265_packet_master_wait_duration_set( 878 int unit, 879 bcm_ptp_stack_id_t ptp_id, 880 int clock_num, 881 uint64 wait_sec, 882 bcm_ptp_clock_port_address_t *address) 883 { 884 int rv; 885 int el; 886 887 PTP_TELECOM_MUTEX_TAKE(); 888 889 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_lookup(address, &el))) { 890 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_lookup()"); 891 PTP_TELECOM_MUTEX_RELEASE_RETURN(rv); 892 } 893 PACKET_MASTER(el).selector.wait_sec = wait_sec; 894 895 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 896 } 897 898 /* 899 * Function: 900 * bcm_common_ptp_telecom_g8265_packet_master_priority_override 901 * Purpose: 902 * Set priority override of packet master. 903 * Parameters: 904 * unit - (IN) Unit number. 905 * ptp_id - (IN) PTP stack ID. 906 * clock_num - (IN) PTP clock number. 907 * override - (IN) Packet master priority override Boolean. 908 * address - (IN) Packet master address. 909 * Returns: 910 * BCM_E_XXX - Function status. 911 * Notes: 912 * Priority override controls whether a packet master's priority value 913 * is set automatically using grandmaster priority1 / priority2 in PTP 914 * announce message (i.e., override equals TRUE) or via host API calls 915 * (i.e., override equals FALSE). 916 */ 917 int 918 bcm_common_ptp_telecom_g8265_packet_master_priority_override( 919 int unit, 920 bcm_ptp_stack_id_t ptp_id, 921 int clock_num, 922 uint8 override, 923 bcm_ptp_clock_port_address_t *address) 924 { 925 int rv; 926 int el; 927 928 PTP_TELECOM_MUTEX_TAKE(); 929 930 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_lookup(address, &el))) { 931 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_lookup()"); 932 PTP_TELECOM_MUTEX_RELEASE_RETURN(rv); 933 } 934 PACKET_MASTER(el).priority.override = override; 935 936 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 937 } 938 939 /* 940 * Function: 941 * bcm_common_ptp_telecom_g8265_packet_master_priority_set 942 * Purpose: 943 * Set priority of packet master. 944 * Parameters: 945 * unit - (IN) Unit number. 946 * ptp_id - (IN) PTP stack ID. 947 * clock_num - (IN) PTP clock number. 948 * priority - (IN) Packet master priority. 949 * address - (IN) Packet master address. 950 * Returns: 951 * BCM_E_XXX - Function status. 952 * Notes: 953 * Ref. ITU-T G.8265.1. 954 */ 955 int 956 bcm_common_ptp_telecom_g8265_packet_master_priority_set( 957 int unit, 958 bcm_ptp_stack_id_t ptp_id, 959 int clock_num, 960 uint16 priority, 961 bcm_ptp_clock_port_address_t *address) 962 { 963 int rv; 964 int el; 965 966 PTP_TELECOM_MUTEX_TAKE(); 967 968 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_lookup(address, &el))) { 969 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_lookup()"); 970 PTP_TELECOM_MUTEX_RELEASE_RETURN(rv); 971 } 972 PACKET_MASTER(el).priority.value = priority; 973 974 PTP_TELECOM_MUTEX_RELEASE_RETURN(BCM_E_NONE); 975 } 976 977 /* 978 * Function: 979 * _bcm_ptp_telecom_g8265_map_QL_clockClass 980 * Purpose: 981 * Map ITU-T G.781 quality level to PTP clock class. 982 * Parameters: 983 * QL - (IN) Quality level. 984 * clockClass - (OUT) PTP clock class. 985 * Returns: 986 * BCM_E_XXX - Function status. 987 * Notes: 988 * Ref. ITU-T G.8265.1, Clause 6.7.3.1. 989 */ 990 int 991 _bcm_ptp_telecom_g8265_map_QL_clockClass( 992 bcm_ptp_telecom_g8265_quality_level_t QL, 993 uint8 *clockClass) 994 { 995 switch (QL) { 996 case bcm_ptp_telecom_g8265_ql_II_prs: 997 *clockClass = 80; 998 break; 999 case bcm_ptp_telecom_g8265_ql_II_stu: 1000 /* Fall through. */ 1001 case bcm_ptp_telecom_g8265_ql_III_unk: 1002 *clockClass = 82; 1003 break; 1004 case bcm_ptp_telecom_g8265_ql_I_prc: 1005 *clockClass = 84; 1006 break; 1007 case bcm_ptp_telecom_g8265_ql_II_st2: 1008 *clockClass = 86; 1009 break; 1010 case bcm_ptp_telecom_g8265_ql_I_ssua: 1011 /* Fall through. */ 1012 case bcm_ptp_telecom_g8265_ql_II_tnc: 1013 *clockClass = 90; 1014 break; 1015 case bcm_ptp_telecom_g8265_ql_I_ssub: 1016 *clockClass = 96; 1017 break; 1018 case bcm_ptp_telecom_g8265_ql_II_st3e: 1019 *clockClass = 100; 1020 break; 1021 case bcm_ptp_telecom_g8265_ql_II_st3: 1022 *clockClass = 102; 1023 break; 1024 case bcm_ptp_telecom_g8265_ql_I_sec: 1025 /* Fall through. */ 1026 case bcm_ptp_telecom_g8265_ql_III_sec: 1027 *clockClass = 104; 1028 break; 1029 case bcm_ptp_telecom_g8265_ql_II_smc: 1030 *clockClass = 106; 1031 break; 1032 case bcm_ptp_telecom_g8265_ql_II_prov: 1033 *clockClass = 108; 1034 break; 1035 case bcm_ptp_telecom_g8265_ql_I_dnu: 1036 /* Fall through. */ 1037 case bcm_ptp_telecom_g8265_ql_II_dus: 1038 *clockClass = 110; 1039 break; 1040 case bcm_ptp_telecom_g8265_ql_na_slv: 1041 /* Not applicable (packet slave). */ 1042 *clockClass = 255; 1043 break; 1044 default: 1045 /* 1046 * Mapping unsuccessful. 1047 * Maximum alternate PTP profile clockClass value in range [68,122] 1048 * used by telecom profile. Ref. IEEE Std. 1588-2008, Clause 7.6.2.4. 1049 */ 1050 *clockClass = 122; 1051 return BCM_E_PARAM; 1052 } 1053 1054 return BCM_E_NONE; 1055 } 1056 1057 /* 1058 * Function: 1059 * _bcm_ptp_telecom_g8265_map_clockClass_QL 1060 * Purpose: 1061 * Map PTP clock class to ITU-T G.781 quality level. 1062 * Parameters: 1063 * clockClass - (IN) PTP clock class. 1064 * QL - (OUT) Quality level. 1065 * Returns: 1066 * BCM_E_XXX - Function status. 1067 * Notes: 1068 * Transformation requires ITU-T G.781 network option. 1069 */ 1070 int 1071 _bcm_ptp_telecom_g8265_map_clockClass_QL( 1072 uint8 clockClass, 1073 bcm_ptp_telecom_g8265_quality_level_t *QL) 1074 { 1075 if (clockClass == 255) { 1076 *QL = bcm_ptp_telecom_g8265_ql_na_slv; 1077 return BCM_E_NONE; 1078 } 1079 1080 switch (telecom.network_option) { 1081 case (bcm_ptp_telecom_g8265_network_option_I): 1082 switch (clockClass) { 1083 case 84: 1084 *QL = bcm_ptp_telecom_g8265_ql_I_prc; 1085 break; 1086 case 90: 1087 *QL = bcm_ptp_telecom_g8265_ql_I_ssua; 1088 break; 1089 case 96: 1090 *QL = bcm_ptp_telecom_g8265_ql_I_ssub; 1091 break; 1092 case 104: 1093 *QL = bcm_ptp_telecom_g8265_ql_I_sec; 1094 break; 1095 case 110: 1096 *QL = bcm_ptp_telecom_g8265_ql_I_dnu; 1097 break; 1098 default: 1099 *QL = bcm_ptp_telecom_g8265_ql_invalid; 1100 return BCM_E_PARAM; 1101 } 1102 break; 1103 case (bcm_ptp_telecom_g8265_network_option_II): 1104 switch (clockClass) { 1105 case 80: 1106 *QL = bcm_ptp_telecom_g8265_ql_II_prs; 1107 break; 1108 case 82: 1109 *QL = bcm_ptp_telecom_g8265_ql_II_stu; 1110 break; 1111 case 86: 1112 *QL = bcm_ptp_telecom_g8265_ql_II_st2; 1113 break; 1114 case 90: 1115 *QL = bcm_ptp_telecom_g8265_ql_II_tnc; 1116 break; 1117 case 100: 1118 *QL = bcm_ptp_telecom_g8265_ql_II_st3e; 1119 break; 1120 case 102: 1121 *QL = bcm_ptp_telecom_g8265_ql_II_st3; 1122 break; 1123 case 106: 1124 *QL = bcm_ptp_telecom_g8265_ql_II_smc; 1125 break; 1126 case 108: 1127 *QL = bcm_ptp_telecom_g8265_ql_II_prov; 1128 break; 1129 case 110: 1130 *QL = bcm_ptp_telecom_g8265_ql_II_dus; 1131 break; 1132 default: 1133 *QL = bcm_ptp_telecom_g8265_ql_invalid; 1134 return BCM_E_PARAM; 1135 } 1136 break; 1137 case (bcm_ptp_telecom_g8265_network_option_III): 1138 switch (clockClass) { 1139 case 82: 1140 *QL = bcm_ptp_telecom_g8265_ql_III_unk; 1141 break; 1142 case 104: 1143 *QL = bcm_ptp_telecom_g8265_ql_III_sec; 1144 break; 1145 default: 1146 *QL = bcm_ptp_telecom_g8265_ql_invalid; 1147 return BCM_E_PARAM; 1148 } 1149 break; 1150 default: 1151 *QL = bcm_ptp_telecom_g8265_ql_invalid; 1152 return BCM_E_PARAM; 1153 } 1154 1155 return BCM_E_NONE; 1156 } 1157 1158 /* 1159 * Function: 1160 * _bcm_ptp_telecom_g8265_verbose_level_set 1161 * Purpose: 1162 * Set flags to control verbosity of status, error, and event messages. 1163 * Parameters: 1164 * flags - (IN) Telecom profile message control flags. 1165 * Returns: 1166 * BCM_E_XXX - Function status. 1167 * Notes: 1168 */ 1169 int 1170 _bcm_ptp_telecom_g8265_verbose_level_set( 1171 uint32 flags) 1172 { 1173 telecom_g8265_verbose_level = flags; 1174 return BCM_E_NONE; 1175 } 1176 1177 /* 1178 * Function: 1179 * _bcm_ptp_telecom_g8265_profile_enabled_set 1180 * Purpose: 1181 * Set telecom profile enabled Boolean. 1182 * Parameters: 1183 * unit - (IN) Unit number. 1184 * ptp_id - (IN) PTP stack ID. 1185 * clock_num - (IN) PTP clock number. 1186 * enabled - (IN) Telecom profile enabled Boolean. 1187 * Returns: 1188 * BCM_E_XXX - Function status. 1189 * Notes: 1190 */ 1191 static int 1192 _bcm_ptp_telecom_g8265_profile_enabled_set( 1193 int unit, 1194 bcm_ptp_stack_id_t ptp_id, 1195 int clock_num, 1196 uint8 enabled) 1197 { 1198 int rv; 1199 int i; 1200 1201 uint8 payload[PTP_MGMTMSG_PAYLOAD_TELECOM_PROFILE_ENABLED_SIZE_OCTETS] = {0}; 1202 uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS]; 1203 int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 1204 1205 bcm_ptp_port_identity_t portid; 1206 bcm_ptp_clock_info_t ci; 1207 1208 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, 1209 PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1210 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1211 return rv; 1212 } 1213 1214 /* 1215 * Make payload. 1216 * Octet 0...5 : Custom management message key/identifier. 1217 * BCM<null><null><null>. 1218 * Octet 6 : Telecom profile enabled Boolean. 1219 * Octet 7 : Reserved. 1220 */ 1221 sal_memcpy(payload, "BCM\0\0\0", 6); 1222 i = 6; 1223 payload[i] = enabled ? 1:0; 1224 1225 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 1226 clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) { 1227 PTP_ERROR_FUNC("bcm_common_ptp_clock_port_identity_get()"); 1228 return rv; 1229 } 1230 1231 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, 1232 &portid, PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_TELECOM_PROFILE_ENABLED, 1233 payload, PTP_MGMTMSG_PAYLOAD_TELECOM_PROFILE_ENABLED_SIZE_OCTETS, 1234 resp, &resp_len))) { 1235 PTP_ERROR_FUNC("_bcm_ptp_management_message_send()"); 1236 return rv; 1237 } 1238 1239 /* Start telecom controller DPC iff telecom profile is enabled. */ 1240 if (enabled) { 1241 shr_rdpc_callback_start(&telecom_g8265_controller_rdpc, PTP_TELECOM_CONTROLLER_DPC_TIME_USEC_DEFAULT, 1242 INT_TO_PTR(unit), INT_TO_PTR(ptp_id), INT_TO_PTR(clock_num), 0); 1243 } else { 1244 shr_rdpc_callback_stop(&telecom_g8265_controller_rdpc); 1245 } 1246 1247 /* Update clock cache. */ 1248 if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_info_get(unit, ptp_id, 1249 clock_num, &ci))) { 1250 PTP_ERROR_FUNC("_bcm_ptp_clock_cache_info_get()"); 1251 return rv; 1252 } 1253 1254 if (enabled) { 1255 SHR_BITSET(&ci.flags, PTP_CLOCK_FLAGS_TELECOM_PROFILE_BIT); 1256 } else { 1257 SHR_BITCLR(&ci.flags, PTP_CLOCK_FLAGS_TELECOM_PROFILE_BIT); 1258 } 1259 1260 if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_info_set(unit, ptp_id, 1261 clock_num, &ci))) { 1262 PTP_ERROR_FUNC("_bcm_ptp_clock_cache_info_set()"); 1263 return rv; 1264 } 1265 1266 /* 1267 * Manage signaling module behavior(s) and configurable PTP attributes 1268 * based on the active PTP profile. 1269 */ 1270 if (BCM_FAILURE(rv = _bcm_ptp_signaling_manager(unit, ptp_id, clock_num, 1271 SHR_BITGET(&ci.flags, PTP_CLOCK_FLAGS_TELECOM_PROFILE_BIT)))) { 1272 PTP_ERROR_FUNC("_bcm_ptp_signaling_manager()"); 1273 return rv; 1274 } 1275 1276 1277 1278 return BCM_E_NONE; 1279 } 1280 1281 /* 1282 * Function: 1283 * _bcm_ptp_telecom_g8265_controller 1284 * Purpose: 1285 * Run telecom profile controller (as RDPC). 1286 * Parameters: 1287 * arg_unit - (IN) Unit number (as void*). 1288 * arg_ptp_id - (IN) PTP stack ID (as void*). 1289 * arg_clock_num - (IN) PTP clock number (as void*). 1290 * unused - (IN) Unused. 1291 * Returns: 1292 * Interval before next call 1293 * Notes: 1294 */ 1295 static sal_usecs_t 1296 _bcm_ptp_telecom_g8265_controller( 1297 void **arg_unit, 1298 void **arg_ptp_id, 1299 void **arg_clock_num, 1300 void **unused) 1301 { 1302 int rv; 1303 1304 int unit = PTR_TO_INT(*arg_unit); 1305 bcm_ptp_stack_id_t ptp_id = (bcm_ptp_stack_id_t)PTR_TO_INT(*arg_ptp_id); 1306 int clock_num = PTR_TO_INT(*arg_clock_num); 1307 bcm_ptp_clock_info_t ci; 1308 1309 bcm_ptp_foreign_master_dataset_t FMds; 1310 int isnew_amt = 0; 1311 1312 if (telecom.network_option == bcm_ptp_telecom_g8265_network_option_disable) { 1313 /* 1314 * Telecom controller DPC should not be running. 1315 * (Shutdown with data consistency enforcement.) 1316 */ 1317 if (BCM_FAILURE(rv = bcm_common_ptp_telecom_g8265_network_option_set(unit, ptp_id, clock_num, 1318 bcm_ptp_telecom_g8265_network_option_disable))) { 1319 PTP_ERROR_FUNC("bcm_common_ptp_telecom_g8265_network_option_set()"); 1320 } 1321 return (sal_usecs_t)0; /* stop the RDPC from running */ 1322 } 1323 1324 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1325 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1326 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1327 return PTP_TELECOM_CONTROLLER_DPC_TIME_USEC_IDLE; 1328 } 1329 1330 if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_info_get(unit, ptp_id, 1331 clock_num, &ci))) { 1332 PTP_ERROR_FUNC("_bcm_ptp_clock_cache_info_get()"); 1333 return PTP_TELECOM_CONTROLLER_DPC_TIME_USEC_IDLE; 1334 } 1335 1336 if (0 == ci.slaveonly) { 1337 return PTP_TELECOM_CONTROLLER_DPC_TIME_USEC_IDLE; 1338 } 1339 1340 if (BCM_FAILURE(rv = bcm_common_ptp_foreign_master_dataset_get(unit, ptp_id, 1341 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT, &FMds))) { 1342 PTP_ERROR_FUNC("bcm_common_ptp_foreign_master_dataset_get()"); 1343 return PTP_TELECOM_CONTROLLER_DPC_TIME_USEC_IDLE; 1344 } 1345 1346 if ((rv = _bcm_ptp_mutex_take(telecom_g8265_mutex, PTP_TELECOM_MUTEX_TIMEOUT_USEC))) { 1347 PTP_ERROR_FUNC("_bcm_ptp_mutex_take()"); 1348 return PTP_TELECOM_CONTROLLER_DPC_TIME_USEC_IDLE; 1349 } 1350 1351 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_fmds_processor(unit, 1352 ptp_id, clock_num, &FMds))) { 1353 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_packet_master_fmds_processor()"); 1354 goto telecom_mutex_release; 1355 } 1356 1357 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_master_selector())) { 1358 /* PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_master_selector()"); */ 1359 if (telecom_g8265_mstr_unavail == 0) { 1360 telecom_g8265_mstr_unavail = 1; 1361 isnew_amt = 1; 1362 telecom.previous_gm = -1; 1363 } 1364 goto telecom_mutex_release; 1365 } 1366 1367 if (telecom.previous_gm != telecom.selected_gm) { 1368 /* GM changed. */ 1369 telecom_g8265_mstr_unavail = 0; 1370 isnew_amt = 1; 1371 telecom.previous_gm = telecom.selected_gm; 1372 1373 /* Register event. */ 1374 PTP_TELECOM_EVENT_REGISTER(&PACKET_MASTER_BEST, PTP_TELECOM_EVENT_GM_SELECTED_BIT); 1375 PTP_TELECOM_EVENT_HEAD_PRINT(); 1376 } 1377 1378 telecom_mutex_release: 1379 _bcm_ptp_mutex_give(telecom_g8265_mutex); 1380 1381 if (1 == isnew_amt) { 1382 1383 /* GM changed - update ToP acceptable master table (AMT). */ 1384 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_AMT_set(unit, ptp_id, clock_num, 1385 PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1386 PTP_ERROR_FUNC("_bcm_ptp_telecom_g8265_AMT_set()"); 1387 } 1388 } 1389 1390 return PTP_TELECOM_CONTROLLER_DPC_TIME_USEC_DEFAULT; 1391 } 1392 1393 /* 1394 * Function: 1395 * _bcm_ptp_telecom_g8265_AMT_set 1396 * Purpose: 1397 * Set acceptable master table (AMT), which provides the mechanism to use 1398 * the best packet master for frequency synchronization. 1399 * Parameters: 1400 * unit - (IN) Unit number. 1401 * ptp_id - (IN) PTP stack ID. 1402 * clock_num - (IN) PTP clock number. 1403 * clock_port - (IN) PTP clock port number. 1404 * pktmaster - (IN) Packet master. 1405 * Returns: 1406 * BCM_E_XXX - Function status. 1407 * Notes: 1408 */ 1409 static int 1410 _bcm_ptp_telecom_g8265_AMT_set( 1411 int unit, 1412 bcm_ptp_stack_id_t ptp_id, 1413 int clock_num, 1414 uint32 clock_port) 1415 { 1416 int rv; 1417 int i; 1418 1419 uint8 payload[128] = {0}; 1420 uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS]; 1421 int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 1422 1423 bcm_ptp_port_identity_t portid; 1424 int addr_len = 0; 1425 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster; 1426 1427 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, 1428 clock_port))) { 1429 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1430 return rv; 1431 } 1432 1433 1434 1435 /* Set AMT. */ 1436 if (PACKET_MASTER_INVALID(PACKET_MASTER_BEST)) { 1437 1438 i = 0; 1439 /* Set number of acceptable masters as zero */ 1440 _bcm_ptp_uint16_write(payload, 0); 1441 i += sizeof(uint16); 1442 1443 } else { 1444 1445 pktmaster = &PACKET_MASTER_BEST; 1446 1447 /* 1448 * Make payload. 1449 * 0...1 : Number of acceptable master table entries. 1450 * 2...3 : AMT#0 network protocol. 1451 * 4...5 : AMT#0 address length. 1452 * 6...N-1 : AMT#0 address. 1453 * N : AMT#0 alternatePriority1. 1454 * N+1 : Reserved. 1455 */ 1456 i = 0; 1457 _bcm_ptp_uint16_write(payload, 1); 1458 i += sizeof(uint16); 1459 1460 _bcm_ptp_uint16_write(payload + i, pktmaster->port_address.addr_type); 1461 i += sizeof(uint16); 1462 1463 addr_len = _bcm_ptp_addr_len((int)pktmaster->port_address.addr_type); 1464 if (0 == addr_len) { 1465 return BCM_E_PARAM; 1466 } 1467 1468 _bcm_ptp_uint16_write(payload + i, addr_len); 1469 i += sizeof(uint16); 1470 sal_memcpy(payload + i, pktmaster->port_address.address, addr_len); 1471 i += addr_len; 1472 1473 payload[i++] = pktmaster->grandmaster_priority1; 1474 payload[i++] = 0x00; 1475 } 1476 1477 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 1478 clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) { 1479 PTP_ERROR_FUNC("bcm_common_ptp_clock_port_identity_get()"); 1480 return rv; 1481 } 1482 1483 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, 1484 &portid, PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_ACCEPTABLE_MASTER_TABLE, 1485 payload, i, resp, &resp_len))) { 1486 return rv; 1487 } 1488 1489 /* Enable AMT. */ 1490 1491 /* 1492 * Make payload. 1493 * Octet 0 : Acceptable master table enabled (EN) Boolean. 1494 * |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|0|0|0|0|0|EN|. 1495 * Octet 1 : Reserved. 1496 */ 1497 payload[0] = 0x01; 1498 payload[1] = 0x00; 1499 1500 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 1501 clock_num, clock_port, &portid))) { 1502 PTP_ERROR_FUNC("bcm_common_ptp_clock_port_identity_get()"); 1503 return rv; 1504 } 1505 1506 rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid, 1507 PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_ACCEPTABLE_MASTER_TABLE_ENABLED, 1508 payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS, 1509 resp, &resp_len); 1510 1511 return rv; 1512 } 1513 1514 /* 1515 * Function: 1516 * _bcm_ptp_telecom_g8265_master_selector 1517 * Purpose: 1518 * Choose a master clock via telecom profile master selection process. 1519 * Parameters: 1520 * NONE 1521 * Returns: 1522 * BCM_E_XXX - Function status. 1523 * Notes: 1524 * Ref. ITU-T G.8265.1, Clause 6.7.3. 1525 */ 1526 static int 1527 _bcm_ptp_telecom_g8265_master_selector( 1528 void) 1529 { 1530 int el; 1531 uint8 unknown_gm = 0; 1532 1533 /* Update PTSF properties. */ 1534 _bcm_ptp_telecom_g8265_PTSF_set(); 1535 1536 /* Update QL-degradation event properties. */ 1537 _bcm_ptp_telecom_g8265_degrade_ql_set(); 1538 1539 /* Update wait-to-restore. */ 1540 _bcm_ptp_telecom_g8265_wait_to_restore_set(); 1541 1542 if (PACKET_MASTER_INVALID(PACKET_MASTER_BEST)) { 1543 /* Prior best master is no longer valid. */ 1544 unknown_gm = 1; 1545 } 1546 1547 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 1548 if (PACKET_MASTER_INVALID(PACKET_MASTER(el))) { 1549 /* Packet master does not meet master selector criteria. */ 1550 continue; 1551 } 1552 1553 if (1 == unknown_gm) { 1554 unknown_gm = 0; 1555 telecom.selected_gm = el; 1556 } 1557 1558 if (PACKET_MASTER(el).clock_class < PACKET_MASTER_BEST.clock_class) { 1559 /* 1560 * Higher quality level (QL) than currently selected packet master. 1561 * NOTE : ITU-T G.781 quality level (QL) is inversely proportional 1562 * to PTP clockClass attribute. Ref. ITU-T G.8265.1, Clause 1563 * 6.7.3.1, Table 1. 1564 */ 1565 telecom.selected_gm = el; 1566 } else if (PACKET_MASTER(el).clock_class == PACKET_MASTER_BEST.clock_class) { 1567 if (PACKET_MASTER(el).priority.value < 1568 PACKET_MASTER_BEST.priority.value) { 1569 /* Higher priority (lower numerical value) than currently selected packet master. */ 1570 telecom.selected_gm = el; 1571 } 1572 } 1573 } 1574 1575 if (1 == unknown_gm) { 1576 return BCM_E_UNAVAIL; 1577 } else { 1578 return BCM_E_NONE; 1579 } 1580 1581 } 1582 1583 /* 1584 * Function: 1585 * _bcm_ptp_telecom_g8265_PTSF_set 1586 * Purpose: 1587 * Set packet timing signal fail (PTSF) properties of in-use packet 1588 * master array entries. 1589 * Parameters: 1590 * NONE 1591 * Returns: 1592 * BCM_E_XXX - Function status. 1593 * Notes: 1594 */ 1595 static int 1596 _bcm_ptp_telecom_g8265_PTSF_set( 1597 void) 1598 { 1599 int rv; 1600 int el; 1601 1602 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 1603 if (bcm_ptp_telecom_g8265_pktmaster_state_unused == PACKET_MASTER(el).state) { 1604 continue; 1605 } 1606 1607 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_PTSF_set( 1608 &PACKET_MASTER(el)))) { 1609 return rv; 1610 } 1611 } 1612 1613 return BCM_E_NONE; 1614 } 1615 1616 /* 1617 * Function: 1618 * _bcm_ptp_telecom_g8265_packet_master_PTSF_set 1619 * Purpose: 1620 * Set packet timing signal fail (PTSF) properties. 1621 * Parameters: 1622 * pktmaster - (IN/OUT) Packet master. 1623 * Returns: 1624 * BCM_E_XXX - Function status. 1625 * Notes: 1626 */ 1627 static int 1628 _bcm_ptp_telecom_g8265_packet_master_PTSF_set( 1629 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster) 1630 { 1631 if (NULL == pktmaster || 1632 bcm_ptp_telecom_g8265_pktmaster_state_unused == pktmaster->state) { 1633 return BCM_E_UNAVAIL; 1634 } 1635 1636 /* 1637 * PTSF lossAnnounce? 1638 * Test ITU-T G.8265.1 criteria on non-receipt of PTP announce messages, 1639 * indicating loss of channel traceability information. 1640 */ 1641 pktmaster->ptsf.loss_announce = 1642 (pktmaster->elapsed_times.announce > telecom.receipt_timeouts.announce) ? 1:0; 1643 1644 /* 1645 * PTSF lossSync? 1646 * Test ITU-T G.8265.1 criteria on non-receipt of PTP timing messages, 1647 * indicating loss of packet timing signal. 1648 */ 1649 pktmaster->ptsf.loss_timing_sync = 1650 (pktmaster->elapsed_times.sync > telecom.receipt_timeouts.sync) ? 1:0; 1651 1652 pktmaster->ptsf.loss_timing_sync_ts = 1653 (pktmaster->elapsed_times.sync_ts > telecom.receipt_timeouts.sync) ? 1:0; 1654 1655 pktmaster->ptsf.loss_timing_delay = 1656 (pktmaster->elapsed_times.delay_resp > telecom.receipt_timeouts.delay_resp) ? 1:0; 1657 1658 /* 1659 * One-way operation. 1660 * NOTE: Bypass PTSF analysis of Delay_Resp messages. 1661 * Delay request and delay response messages are not exchanged. 1662 * Firmware overwrites time since last Delay_Resp with all-ones. 1663 */ 1664 if (pktmaster->elapsed_times.delay_resp == PTP_TELECOM_MESSAGE_ELAPSED_TIME_MSEC_UNAVAIL) { 1665 pktmaster->ptsf.loss_timing_delay = 0; 1666 } 1667 1668 pktmaster->ptsf.loss_sync = pktmaster->ptsf.loss_timing_sync | 1669 pktmaster->ptsf.loss_timing_sync_ts | 1670 pktmaster->ptsf.loss_timing_delay; 1671 1672 #ifdef BCM_PTP_EXT_SERVO_SUPPORT 1673 /* PTSF unusable is set unsolicitedly based on servo notification. 1674 Nothing to be done here */ 1675 #else 1676 /* 1677 * PTSF unusable? 1678 * Reference implementation: apply packet timing statistics criteria, 1679 * incl. thresholds on packet delay variation (PDV) statistical metrics. 1680 */ 1681 pktmaster->ptsf.unusable = COMPILER_64_GT(pktmaster->pktstats.pdv_scaled_allan_var, 1682 telecom.thresholds.pdv_scaled_allan_var) ? 1:0; 1683 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */ 1684 1685 if (0 == pktmaster->fmds_counter) { 1686 /* 1687 * Startup/discovery dynamics. 1688 * Bypass PTSF criteria for wait-to-restore/non-reversion classifications 1689 * until a packet master is recognized in foreignMasterDS. 1690 */ 1691 COMPILER_64_ZERO(pktmaster->ptsf.timestamp); 1692 pktmaster->ptsf.counter = 0; 1693 } else if (pktmaster->ptsf.loss_announce || pktmaster->ptsf.loss_sync || pktmaster->ptsf.unusable) { 1694 /* 1695 * PTSF criteria met? 1696 * Set PTSF timestamp and PTSF occurence counter. 1697 */ 1698 COMPILER_64_SET(pktmaster->ptsf.timestamp, 0, _bcm_ptp_monotonic_time()); 1699 if (pktmaster->ptsf.counter < ((uint32)-1)) { 1700 ++pktmaster->ptsf.counter; 1701 } 1702 1703 /* Register event(s). */ 1704 if (pktmaster->ptsf.loss_announce) { 1705 PTP_TELECOM_EVENT_REGISTER(pktmaster, PTP_TELECOM_EVENT_PTSF_LOSS_ANNOUNCE_BIT); 1706 PTP_TELECOM_EVENT_HEAD_PRINT(); 1707 } 1708 if (pktmaster->ptsf.loss_timing_sync) { 1709 PTP_TELECOM_EVENT_REGISTER(pktmaster, PTP_TELECOM_EVENT_PTSF_LOSS_SYNC_BIT); 1710 PTP_TELECOM_EVENT_HEAD_PRINT(); 1711 } 1712 if (pktmaster->ptsf.loss_timing_sync_ts) { 1713 PTP_TELECOM_EVENT_REGISTER(pktmaster, PTP_TELECOM_EVENT_PTSF_LOSS_SYNC_TS_BIT); 1714 PTP_TELECOM_EVENT_HEAD_PRINT(); 1715 } 1716 if (pktmaster->ptsf.loss_timing_delay) { 1717 PTP_TELECOM_EVENT_REGISTER(pktmaster, PTP_TELECOM_EVENT_PTSF_LOSS_DELAY_RESP_BIT); 1718 PTP_TELECOM_EVENT_HEAD_PRINT(); 1719 } 1720 if (pktmaster->ptsf.unusable) { 1721 PTP_TELECOM_EVENT_REGISTER(pktmaster, PTP_TELECOM_EVENT_PTSF_UNUSABLE_BIT); 1722 PTP_TELECOM_EVENT_HEAD_PRINT(); 1723 } 1724 } 1725 1726 return BCM_E_NONE; 1727 } 1728 1729 /* 1730 * Function: 1731 * _bcm_ptp_telecom_g8265_degrade_ql_set 1732 * Purpose: 1733 * Set QL-degradation event properties of in-use packet master array entries. 1734 * Parameters: 1735 * NONE 1736 * Returns: 1737 * BCM_E_XXX - Function status. 1738 * Notes: 1739 */ 1740 static int 1741 _bcm_ptp_telecom_g8265_degrade_ql_set( 1742 void) 1743 { 1744 int rv; 1745 int el; 1746 1747 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 1748 if (bcm_ptp_telecom_g8265_pktmaster_state_unused == PACKET_MASTER(el).state) { 1749 continue; 1750 } 1751 1752 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_degrade_ql_set( 1753 &PACKET_MASTER(el)))) { 1754 return rv; 1755 } 1756 } 1757 1758 return BCM_E_NONE; 1759 } 1760 1761 /* 1762 * Function: 1763 * _bcm_ptp_telecom_g8265_packet_master_degrade_ql_set 1764 * Purpose: 1765 * Set QL-degradation event properties. 1766 * Parameters: 1767 * pktmaster - (IN/OUT) Packet master. 1768 * Returns: 1769 * BCM_E_XXX - Function status. 1770 * Notes: 1771 */ 1772 static int 1773 _bcm_ptp_telecom_g8265_packet_master_degrade_ql_set( 1774 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster) 1775 { 1776 if (NULL == pktmaster || 1777 bcm_ptp_telecom_g8265_pktmaster_state_unused == pktmaster->state) { 1778 return BCM_E_UNAVAIL; 1779 } 1780 1781 /* 1782 * QL degradation? 1783 * NOTE: An increase of PTP clockClass over consecutive queries of foreign 1784 * master dataset is only condition presently considered. Additional 1785 * criteria might be worthwhile in subsequent implementations. 1786 */ 1787 pktmaster->hql.degrade_ql = 1788 (pktmaster->hql.clock_class_window.rise_events) ? 1:0; 1789 1790 if (0 == pktmaster->fmds_counter) { 1791 /* 1792 * Startup/discovery dynamics. 1793 * Bypass QL degradation criteria for wait-to-restore/non-reversion classifications 1794 * until a packet master is recognized in foreignMasterDS. 1795 */ 1796 COMPILER_64_ZERO(pktmaster->hql.timestamp); 1797 pktmaster->hql.counter = 0; 1798 } else if (pktmaster->hql.degrade_ql) { 1799 /* 1800 * QL degradation criteria met? 1801 * Set QL-degradation event timestamp and occurence counter. 1802 */ 1803 COMPILER_64_SET(pktmaster->hql.timestamp, 0, _bcm_ptp_monotonic_time()); 1804 if (pktmaster->hql.counter < ((uint32)-1)) { 1805 ++pktmaster->hql.counter; 1806 } 1807 1808 /* Register event. */ 1809 PTP_TELECOM_EVENT_REGISTER(pktmaster, PTP_TELECOM_EVENT_QL_DEGRADED_BIT); 1810 PTP_TELECOM_EVENT_HEAD_PRINT(); 1811 } 1812 1813 return BCM_E_NONE; 1814 } 1815 1816 /* 1817 * Function: 1818 * _bcm_ptp_telecom_g8265_wait_to_restore_set 1819 * Purpose: 1820 * Set wait-to-restore attribute of in-use packet master array entries. 1821 * Parameters: 1822 * NONE 1823 * Returns: 1824 * BCM_E_XXX - Function status. 1825 * Notes: 1826 */ 1827 static int 1828 _bcm_ptp_telecom_g8265_wait_to_restore_set( 1829 void) 1830 { 1831 int rv; 1832 int el; 1833 1834 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 1835 if (bcm_ptp_telecom_g8265_pktmaster_state_unused == PACKET_MASTER(el).state) { 1836 continue; 1837 } 1838 1839 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_wait_to_restore_set( 1840 &PACKET_MASTER(el)))) { 1841 return rv; 1842 } 1843 } 1844 1845 return BCM_E_NONE; 1846 } 1847 1848 /* 1849 * Function: 1850 * _bcm_ptp_telecom_g8265_packet_master_wait_to_restore_set 1851 * Purpose: 1852 * Set wait-to-restore attribute. 1853 * Parameters: 1854 * pktmaster - (IN/OUT) Packet master. 1855 * Returns: 1856 * BCM_E_XXX - Function status. 1857 * Notes: 1858 */ 1859 static int 1860 _bcm_ptp_telecom_g8265_packet_master_wait_to_restore_set( 1861 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster) 1862 { 1863 sal_time_t t = _bcm_ptp_monotonic_time(); 1864 uint64 t_pass; 1865 1866 if (NULL == pktmaster || bcm_ptp_telecom_g8265_pktmaster_state_unused == pktmaster->state) { 1867 return BCM_E_UNAVAIL; 1868 } 1869 1870 COMPILER_64_SET(t_pass, 0, t); 1871 COMPILER_64_SUB_64(t_pass, pktmaster->selector.wait_sec); 1872 1873 if (pktmaster->selector.non_reversion && (pktmaster->ptsf.counter || pktmaster->hql.counter)) { 1874 /* 1875 * Non-reversion mode. 1876 * Packet-master PTSF or QL degradation has occurred at least once. 1877 * Prevent selection of master via TRUE wait-to-restore setting. 1878 */ 1879 pktmaster->selector.wait_to_restore = 1; 1880 } else if (COMPILER_64_LT(t_pass, pktmaster->ptsf.timestamp) || 1881 COMPILER_64_LT(t_pass, pktmaster->hql.timestamp)) { 1882 /* Elapsed-time criterion. 1883 * Time since most recent PTSF or QL-degradation event is less than 1884 * prescribed wait-to-restore duration. Prevent selection of master 1885 * via TRUE wait-to-restore setting. 1886 */ 1887 pktmaster->selector.wait_to_restore = 1; 1888 } else { 1889 pktmaster->selector.wait_to_restore = 0; 1890 } 1891 1892 return BCM_E_NONE; 1893 } 1894 1895 /* 1896 * Function: 1897 * _bcm_ptp_telecom_g8265_packet_master_fmds_processor 1898 * Purpose: 1899 * Query foreign master dataset and assign attributes, data, and derived 1900 * quantities to corresponding packet master entries. 1901 * Parameters: 1902 * unit - (IN) Unit number. 1903 * ptp_id - (IN) PTP stack ID. 1904 * clock_num - (IN) PTP clock number. 1905 * FMds - (IN) Foreign master dataset. 1906 * Returns: 1907 * BCM_E_XXX - Function status. 1908 * Notes: 1909 */ 1910 static int 1911 _bcm_ptp_telecom_g8265_packet_master_fmds_processor( 1912 int unit, 1913 bcm_ptp_stack_id_t ptp_id, 1914 int clock_num, 1915 bcm_ptp_foreign_master_dataset_t *FMds) 1916 { 1917 int rv; 1918 int i, el; 1919 1920 bcm_ptp_foreign_master_entry_t *fm; 1921 _bcm_ptp_port_state_t portState; 1922 1923 /* 1924 * "Clear" packet master state, message receipt times, etc. to account for 1925 * the foreignMasterDS firmware logic to dynamically remove foreign master 1926 * entries. 1927 */ 1928 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 1929 if (bcm_ptp_telecom_g8265_pktmaster_state_unused != PACKET_MASTER(el).state) { 1930 PACKET_MASTER(el).state = bcm_ptp_telecom_g8265_pktmaster_state_init; 1931 1932 PACKET_MASTER(el).elapsed_times.announce = PTP_TELECOM_MESSAGE_ELAPSED_TIME_MSEC_MAX; 1933 PACKET_MASTER(el).elapsed_times.sync = PTP_TELECOM_MESSAGE_ELAPSED_TIME_MSEC_MAX; 1934 PACKET_MASTER(el).elapsed_times.sync_ts = PTP_TELECOM_MESSAGE_ELAPSED_TIME_MSEC_MAX; 1935 PACKET_MASTER(el).elapsed_times.delay_resp = PTP_TELECOM_MESSAGE_ELAPSED_TIME_MSEC_MAX; 1936 1937 COMPILER_64_ALLONES(PACKET_MASTER(el).pktstats.pdv_scaled_allan_var); 1938 } 1939 } 1940 1941 /* Update packet master attributes. */ 1942 for (i = 0; i < FMds->num_foreign_masters; ++i) { 1943 fm = &FMds->foreign_master[i]; 1944 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_lookup(&fm->address, &el))) { 1945 if (fm->address.addr_type == bcmPTPUDPIPv4) { 1946 LOG_VERBOSE(BSL_LS_BCM_PTP, 1947 (BSL_META_U(unit, 1948 "\n %s: pkt master not found for foreign master %u.%u.%u.%u"), FUNCTION_NAME(), 1949 fm->address.address[0], fm->address.address[1], 1950 fm->address.address[2], fm->address.address[3])); 1951 } else if (fm->address.addr_type == bcmPTPUDPIPv6) { 1952 LOG_VERBOSE(BSL_LS_BCM_PTP, 1953 (BSL_META_U(unit, 1954 "\n %s: pkt master not found for foreign master %02x%02x:%02x%02x:%02x%02x: \ 1955 %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"), FUNCTION_NAME(), 1956 fm->address.address[0], fm->address.address[1], fm->address.address[2], fm->address.address[3], 1957 fm->address.address[4], fm->address.address[5], fm->address.address[6], fm->address.address[7], 1958 fm->address.address[8], fm->address.address[9], fm->address.address[10], fm->address.address[11], 1959 fm->address.address[12], fm->address.address[13], fm->address.address[14], fm->address.address[15])); 1960 } 1961 continue; 1962 } 1963 1964 /* 1965 * Update foreignMasterDS entry counter for this packet master to keep 1966 * track of number of times it has shown up in foreignMasterDS queries. 1967 * Do not rollover. 1968 */ 1969 if (PACKET_MASTER(el).fmds_counter < ((uint32)-1)) { 1970 ++PACKET_MASTER(el).fmds_counter; 1971 } 1972 1973 PACKET_MASTER(el).port_identity = fm->port_identity; 1974 1975 PACKET_MASTER(el).clock_class = fm->clockClass; 1976 _bcm_ptp_telecom_g8265_map_clockClass_QL(PACKET_MASTER(el).clock_class, &PACKET_MASTER(el).quality_level); 1977 1978 _bcm_ptp_telecom_g8265_packet_master_priority_calculator( 1979 fm->grandmasterPriority1, fm->grandmasterPriority2, &PACKET_MASTER(el)); 1980 1981 /* 1982 * Extract basic clockClass statistics accummulated over foreignMasterDs 1983 * query window to facilitate an appraisal of reduction in QL conditions. 1984 */ 1985 PACKET_MASTER(el).hql.clock_class_window = fm->clockClass_window; 1986 1987 /* 1988 * Extract elapsed times since receipt of messages from foreignMasterDS. 1989 * NOTE: A master in foreignMasterDS implies PTSF lossAnnounce is false. 1990 * Set elapsed time of last announce message to zero to guarantee. 1991 */ 1992 PACKET_MASTER(el).elapsed_times.announce = 0; 1993 PACKET_MASTER(el).elapsed_times.sync = fm->ms_since_sync; 1994 PACKET_MASTER(el).elapsed_times.sync_ts = fm->ms_since_sync_ts; 1995 PACKET_MASTER(el).elapsed_times.delay_resp = fm->ms_since_del_resp; 1996 1997 /* 1998 * Zero elapsed times since receipt of Sync, Follow_Up (Sync timestamp), and Delay_Resp 1999 * if portState is neither slave nor uncalibrated for consistency with firmware Rx/Tx. 2000 */ 2001 if (BCM_SUCCESS(_bcm_ptp_clock_cache_port_state_get(unit, ptp_id, clock_num, 2002 PTP_CLOCK_PORT_NUMBER_DEFAULT, &portState)) && 2003 (portState != _bcm_ptp_state_uncalibrated) && (portState != _bcm_ptp_state_slave)) { 2004 PACKET_MASTER(el).elapsed_times.sync = 0; 2005 PACKET_MASTER(el).elapsed_times.sync_ts = 0; 2006 PACKET_MASTER(el).elapsed_times.delay_resp = 0; 2007 } 2008 2009 COMPILER_64_SET(PACKET_MASTER(el).pktstats.pdv_scaled_allan_var, 2010 COMPILER_64_HI(fm->pdv_scaled_allan_var), 2011 COMPILER_64_LO(fm->pdv_scaled_allan_var)); 2012 2013 PACKET_MASTER(el).state = bcm_ptp_telecom_g8265_pktmaster_state_valid; 2014 } 2015 2016 return BCM_E_NONE; 2017 } 2018 2019 /* 2020 * Function: 2021 * _bcm_ptp_telecom_g8265_packet_master_priority_calculator 2022 * Purpose: 2023 * Calculate packet master priority based on associated grandmaster's 2024 * priority1 and priority2 attributes. 2025 * Parameters: 2026 * gmPriority1 - (IN) PTP grandmaster clock priority1. 2027 * gmPriority2 - (IN) PTP grandmaster clock priority2. 2028 * pktmaster - (IN/OUT) Packet master clock. 2029 * Returns: 2030 * BCM_E_XXX - Function status. 2031 * Notes: 2032 */ 2033 static int 2034 _bcm_ptp_telecom_g8265_packet_master_priority_calculator( 2035 uint8 gmPriority1, 2036 uint8 gmPriority2, 2037 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster) 2038 { 2039 pktmaster->grandmaster_priority1 = gmPriority1; 2040 pktmaster->grandmaster_priority2 = gmPriority2; 2041 2042 if (1 == pktmaster->priority.override) { 2043 /* 2044 * Packet master priority calculated automatically from PTP priority1 2045 * and priority2 attributes, which are available in Announce messages 2046 * for example. Otherwise (i.e., override equals FALSE), the priority 2047 * is prescribed via host API calls. 2048 */ 2049 pktmaster->priority.value = (gmPriority1 << 8) + gmPriority2; 2050 } 2051 2052 return BCM_E_NONE; 2053 } 2054 2055 /* 2056 * Function: 2057 * _bcm_ptp_telecom_g8265_packet_master_manager 2058 * Purpose: 2059 * Manage/assign packet master array resources and identify/lookup the 2060 * entry with matching address. 2061 * Parameters: 2062 * address - (IN) Packet master address. 2063 * index - (OUT) Packet master index. 2064 * Returns: 2065 * BCM_E_XXX - Function status. 2066 * Notes: 2067 */ 2068 static int 2069 _bcm_ptp_telecom_g8265_packet_master_manager( 2070 bcm_ptp_clock_port_address_t *address, 2071 int *index) 2072 { 2073 int rv; 2074 int el; 2075 2076 /* Existing packet master array entry. */ 2077 if (BCM_SUCCESS(rv = _bcm_ptp_telecom_g8265_packet_master_lookup(address, index))) { 2078 return BCM_E_NONE; 2079 } 2080 2081 /* New packet master array entry. */ 2082 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 2083 if (bcm_ptp_telecom_g8265_pktmaster_state_unused == PACKET_MASTER(el).state) { 2084 *index = el; 2085 return BCM_E_NONE; 2086 } 2087 } 2088 2089 /* No available packet master array entries. */ 2090 *index = -1; 2091 return BCM_E_FULL; 2092 } 2093 2094 /* 2095 * Function: 2096 * _bcm_ptp_telecom_g8265_packet_master_lookup 2097 * Purpose: 2098 * Look up a packet master in the packet master array based on address. 2099 * Parameters: 2100 * address - (IN) Packet master address. 2101 * index - (OUT) Packet master array index. 2102 * Returns: 2103 * BCM_E_XXX - Function status. 2104 * Notes: 2105 */ 2106 static int 2107 _bcm_ptp_telecom_g8265_packet_master_lookup( 2108 bcm_ptp_clock_port_address_t *address, 2109 int *index) 2110 { 2111 int el; 2112 2113 /* Existing packet master array entry. */ 2114 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 2115 if (bcm_ptp_telecom_g8265_pktmaster_state_unused != PACKET_MASTER(el).state) { 2116 /* Scan packet master array for entry with matching address. */ 2117 if (_bcm_ptp_port_address_compare(address, &PACKET_MASTER(el).port_address)) { 2118 /* Select corresponding packet master. */ 2119 *index = el; 2120 return BCM_E_NONE; 2121 } 2122 } 2123 } 2124 2125 return BCM_E_NOT_FOUND; 2126 } 2127 2128 /* 2129 * Function: 2130 * _bcm_ptp_telecom_g8265_packet_master_make 2131 * Purpose: 2132 * Initialize new packet master. 2133 * Parameters: 2134 * address - (IN) Packet master address. 2135 * pktmaster - (OUT) Packet master. 2136 * Returns: 2137 * BCM_E_XXX - Function status. 2138 * Notes: 2139 */ 2140 static int 2141 _bcm_ptp_telecom_g8265_packet_master_make( 2142 bcm_ptp_clock_port_address_t *address, 2143 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster) 2144 { 2145 if (NULL == pktmaster) { 2146 return BCM_E_FAIL; 2147 } 2148 2149 /* Set address. */ 2150 pktmaster->port_address = *address; 2151 2152 /* Set state. */ 2153 pktmaster->state = bcm_ptp_telecom_g8265_pktmaster_state_init; 2154 2155 /* Set attributes. */ 2156 pktmaster->priority.override = 1; 2157 _bcm_ptp_telecom_g8265_packet_master_priority_calculator( 2158 PTP_CLOCK_PRESETS_PRIORITY1_MAXIMUM, PTP_CLOCK_PRESETS_PRIORITY2_MAXIMUM, 2159 pktmaster); 2160 2161 return BCM_E_NONE; 2162 } 2163 2164 /* 2165 * Function: 2166 * _bcm_ptp_telecom_g8265_packet_master_printout 2167 * Purpose: 2168 * Print packet master information. 2169 * Parameters: 2170 * pktmaster - (IN) Packet master. 2171 * flags - (IN) Printout control flags. 2172 * Returns: 2173 * BCM_E_XXX - Function status. 2174 * Notes: 2175 */ 2176 static int 2177 _bcm_ptp_telecom_g8265_packet_master_printout( 2178 bcm_ptp_telecom_g8265_pktmaster_t *pktmaster, 2179 uint8 flags) 2180 { 2181 if (NULL == pktmaster) { 2182 return BCM_E_FAIL; 2183 } 2184 2185 2186 2187 switch (pktmaster->port_address.addr_type) { 2188 case bcmPTPUDPIPv4: 2189 LOG_CLI((BSL_META("Master IP Address (IPv4): %d.%d.%d.%d\n"), 2190 pktmaster->port_address.address[0], 2191 pktmaster->port_address.address[1], 2192 pktmaster->port_address.address[2], 2193 pktmaster->port_address.address[3])); 2194 break; 2195 case bcmPTPUDPIPv6: 2196 LOG_CLI((BSL_META("Master IP Address (IPv6): %02x%02x:%02x%02x:%02x%02x:" 2197 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n"), 2198 pktmaster->port_address.address[0], 2199 pktmaster->port_address.address[1], 2200 pktmaster->port_address.address[2], 2201 pktmaster->port_address.address[3], 2202 pktmaster->port_address.address[4], 2203 pktmaster->port_address.address[5], 2204 pktmaster->port_address.address[6], 2205 pktmaster->port_address.address[7], 2206 pktmaster->port_address.address[8], 2207 pktmaster->port_address.address[9], 2208 pktmaster->port_address.address[10], 2209 pktmaster->port_address.address[11], 2210 pktmaster->port_address.address[12], 2211 pktmaster->port_address.address[13], 2212 pktmaster->port_address.address[14], 2213 pktmaster->port_address.address[15])); 2214 break; 2215 default: 2216 LOG_CLI((BSL_META("Master IP Address:\n"))); 2217 } 2218 2219 return BCM_E_NONE; 2220 } 2221 2222 /* 2223 * Function: 2224 * _bcm_ptp_telecom_g8265_event_description 2225 * Purpose: 2226 * Interpret telecom event(s). 2227 * Parameters: 2228 * type - (IN) Telecom event(s). 2229 * Returns: 2230 * Telecom event description. 2231 * Notes: 2232 */ 2233 static const char* 2234 _bcm_ptp_telecom_g8265_event_description( 2235 uint32 type) 2236 { 2237 if (type & (1u << PTP_TELECOM_EVENT_PTSF_LOSS_ANNOUNCE_BIT)) { 2238 return "PTSF lossAnnounce"; 2239 } else if (type & (1u << PTP_TELECOM_EVENT_PTSF_LOSS_SYNC_BIT)) { 2240 return "PTSF lossSync (lossTimingSync)"; 2241 } else if (type & (1u << PTP_TELECOM_EVENT_PTSF_LOSS_SYNC_TS_BIT)) { 2242 return "PTSF lossSync (lossTimingSyncTS)"; 2243 } else if (type & (1u << PTP_TELECOM_EVENT_PTSF_LOSS_DELAY_RESP_BIT)) { 2244 return "PTSF lossSync (lossTimingDelay)"; 2245 } else if (type & (1u << PTP_TELECOM_EVENT_PTSF_UNUSABLE_BIT)) { 2246 return "PTSF unusable"; 2247 } else if (type & (1u << PTP_TELECOM_EVENT_QL_DEGRADED_BIT)) { 2248 return "QL Degraded"; 2249 } else if (type & (1u << PTP_TELECOM_EVENT_GM_ADDED_BIT)) { 2250 return "MASTER Added"; 2251 } else if (type & (1u << PTP_TELECOM_EVENT_GM_REMOVED_BIT)) { 2252 return "MASTER Removed"; 2253 } else if (type & (1u << PTP_TELECOM_EVENT_GM_SELECTED_BIT)) { 2254 return "MASTER Selected"; 2255 } else { 2256 return "UNKNOWN"; 2257 } 2258 } 2259 2260 #ifdef BCM_PTP_EXT_SERVO_SUPPORT 2261 /* 2262 * Function: 2263 * _bcm_ptp_telecom_g8265_packet_master_best_get 2264 * Purpose: 2265 * Fetch the port identity of the best packet master. 2266 * Parameters: 2267 * unit - (IN) Unit number. 2268 * ptp_id - (IN) PTP stack ID. 2269 * clock_num - (IN) PTP clock number. 2270 * master_portId - (OUT) Packet master address. 2271 * Returns: 2272 * BCM_E_XXX - Function status. 2273 * Notes: 2274 */ 2275 int 2276 _bcm_ptp_telecom_g8265_packet_master_best_get( 2277 int unit, 2278 bcm_ptp_stack_id_t ptp_id, 2279 int clock_num, 2280 bcm_ptp_port_identity_t * master_portId) 2281 { 2282 int rv = BCM_E_NONE; 2283 2284 if (PACKET_MASTER_INVALID(PACKET_MASTER_BEST)) { 2285 /* Prior best master is no longer valid. */ 2286 return BCM_E_FAIL; 2287 } 2288 2289 *master_portId = PACKET_MASTER_BEST.port_identity; 2290 return rv; 2291 } 2292 2293 /* 2294 * Function: 2295 * _bcm_ptp_telecom_g8265_packet_master_portid_lookup 2296 * Purpose: 2297 * Look up a packet master in the packet master array based on port identity. 2298 * Parameters: 2299 * address - (IN) Packet master port id. 2300 * index - (OUT) Packet master array index. 2301 * Returns: 2302 * BCM_E_XXX - Function status. 2303 * Notes: 2304 */ 2305 static int 2306 _bcm_ptp_telecom_g8265_packet_master_portid_lookup( 2307 bcm_ptp_port_identity_t *port_id, 2308 int *index) 2309 { 2310 int el; 2311 2312 /* Existing packet master array entry. */ 2313 for (el = 0; el < PTP_TELECOM_MAX_NUMBER_PKTMASTERS; ++el) { 2314 if (bcm_ptp_telecom_g8265_pktmaster_state_unused != PACKET_MASTER(el).state) { 2315 /* Scan packet master array for entry with matching address. */ 2316 if (_bcm_ptp_peer_portid_compare(port_id, &PACKET_MASTER(el).port_identity)) { 2317 /* Select corresponding packet master. */ 2318 *index = el; 2319 return BCM_E_NONE; 2320 } 2321 } 2322 } 2323 2324 return BCM_E_NOT_FOUND; 2325 } 2326 2327 2328 /* 2329 * Function: 2330 * _bcm_ptp_telecom_g8265_packet_master_ptsf_unusable_set 2331 * Purpose: 2332 * Set or clear PTSF-unsuable for the packet master. 2333 * Parameters: 2334 * unit - (IN) Unit number. 2335 * ptp_id - (IN) PTP stack ID. 2336 * clock_num - (IN) PTP clock number. 2337 * master_portId - (IN) Packet master portId. 2338 * ptsf - (IN) PTSF state 2339 * Returns: 2340 * BCM_E_XXX - Function status. 2341 * Notes: 2342 */ 2343 int 2344 _bcm_ptp_telecom_g8265_packet_master_ptsf_unusable_set( 2345 int unit, 2346 bcm_ptp_stack_id_t ptp_id, 2347 int clock_num, 2348 bcm_ptp_port_identity_t * master_portId, 2349 int ptsf_state) 2350 { 2351 int index; 2352 int rv = BCM_E_NONE; 2353 2354 if (BCM_FAILURE(rv = _bcm_ptp_telecom_g8265_packet_master_portid_lookup(master_portId, &index))) { 2355 return BCM_E_FAIL; 2356 } 2357 2358 PACKET_MASTER(index).ptsf.unusable = ptsf_state; 2359 return rv; 2360 } 2361 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */ 2362 2363 #endif /* defined(INCLUDE_PTP) */