openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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