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

tdpll_esmc.c (39389B)


      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: tdpll_esmc.c
      8  *
      9  * Purpose: Telecom DPLL Ethernet Synchronization Messaging Channel (ESMC) support.
     10  *
     11  * Functions:
     12  *      bcm_tdpll_esmc_init
     13  *      bcm_tdpll_esmc_rx_state_machine
     14  *      bcm_tdpll_esmc_holdover_event_send
     15  *      bcm_tdpll_esmc_switch_event_send
     16  *      bcm_tdpll_esmc_ql_get
     17  *      bcm_tdpll_esmc_ql_set
     18  *      bcm_tdpll_esmc_holdover_ql_get
     19  *      bcm_tdpll_esmc_holdover_ql_set
     20  *      bcm_tdpll_esmc_mac_get
     21  *      bcm_tdpll_esmc_mac_set
     22  *      bcm_tdpll_esmc_rx_enable_get
     23  *      bcm_tdpll_esmc_rx_enable_set
     24  *      bcm_tdpll_esmc_tx_enable_get
     25  *      bcm_tdpll_esmc_tx_enable_set
     26  *      bcm_tdpll_esmc_rx_portbitmap_get
     27  *      bcm_tdpll_esmc_rx_portbitmap_set
     28  *      bcm_tdpll_esmc_tx_portbitmap_get
     29  *      bcm_tdpll_esmc_tx_portbitmap_set
     30  *
     31  *      bcm_tdpll_esmc_info_pdu_tx
     32  *      bcm_tdpll_esmc_1588_clock_ql_get
     33  */
     34 
     35 #if defined(INCLUDE_PTP)
     36 
     37 #include <bcm/ptp.h>
     38 #include <bcm_int/common/ptp.h>
     39 #include <bcm_int/ptp_common.h>
     40 #include <bcm/error.h>
     41 #include <shared/util.h>
     42 
     43 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
     44 #include <bcm_int/common/esmc.h>
     45 #else
     46 /* Definitions. */
     47 #define TDPLL_ESMC_NETWORK_OPTION_DEFAULT (bcm_esmc_network_option_g781_II)
     48 #define TDPLL_ESMC_QL_DEFAULT             (bcm_esmc_g781_II_ql_smc)
     49 #define TDPLL_ESMC_SSM_CODE_DEFAULT       (0x0c)
     50 
     51 #define TDPLL_ESMC_RX_ENABLE_DEFAULT                (0)
     52 #define TDPLL_ESMC_TX_ENABLE_DEFAULT                (0)
     53 
     54 #define TDPLL_ESMC_INFO_PDU_DPC_TIME_USEC_DEFAULT   (1000000/TDPLL_DPLL_INSTANCE_NUM_MAX)
     55 #define TDPLL_ESMC_INFO_PDU_DPC_TIME_USEC_IDLE      (10000000)
     56 
     57 /* Macros. */
     58 
     59 /* Types. */
     60 
     61 /* Constants and variables. */
     62 static bcm_tdpll_esmc_data_t objdata;
     63 
     64 static shr_rdpc_t tdpll_tx_rdpc;
     65 /* Static functions. */
     66 static sal_usecs_t bcm_tdpll_esmc_info_pdu_tx(
     67     void **arg_unit, void **arg_stack_id,
     68     void **arg_dpll_index, void **unused);
     69 
     70 static int bcm_tdpll_esmc_1588_clock_ql_get(
     71     int unit, bcm_ptp_stack_id_t ptp_id,
     72     bcm_esmc_network_option_t network_option,
     73     bcm_esmc_quality_level_t *ql);
     74 
     75 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
     76 
     77 /*
     78  * Function:
     79  *      bcm_tdpll_esmc_init()
     80  * Purpose:
     81  *      Initialize T-DPLL Ethernet Synchronization Messaging Channel (ESMC).
     82  * Parameters:
     83  *      unit      - (IN) Unit number.
     84  *      stack_id  - (IN) Stack identifier index.
     85  * Returns:
     86  *      BCM_E_XXX - Function status.
     87  * Notes:
     88  */
     89 int
     90 bcm_tdpll_esmc_init(
     91     int unit,
     92     int stack_id)
     93 {
     94 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
     95     return bcm_extdpll_esmc_init(unit, stack_id);
     96 #else
     97     int i;
     98 
     99     objdata.rx_enable = TDPLL_ESMC_RX_ENABLE_DEFAULT ? 1:0;
    100     for (i = 0; i < TDPLL_DPLL_INSTANCE_NUM_MAX; ++i) {
    101         objdata.tx_enable[i] = TDPLL_ESMC_TX_ENABLE_DEFAULT ? 1:0;
    102         SOC_PBMP_CLEAR(objdata.tx_pbmp[i]);
    103         SOC_PBMP_CLEAR(objdata.rx_pbmp[i]);
    104     }
    105 
    106     objdata.network_option = TDPLL_ESMC_NETWORK_OPTION_DEFAULT;
    107     for (i = 0; i < TDPLL_DPLL_INSTANCE_NUM_MAX; ++i) {
    108         objdata.pdu_data[i].ql = TDPLL_ESMC_QL_DEFAULT;
    109         objdata.holdover_ql[i] = TDPLL_ESMC_QL_DEFAULT;
    110     }
    111 
    112     for (i = 0; i < TDPLL_DPLL_INSTANCE_NUM_MAX; ++i) {
    113         objdata.pdu_data[i].ssm_code = TDPLL_ESMC_SSM_CODE_DEFAULT;
    114         objdata.holdover_ssm_code[i] = TDPLL_ESMC_SSM_CODE_DEFAULT;
    115     }
    116 
    117     for (i = 0; i < TDPLL_DPLL_INSTANCE_NUM_MAX; ++i) {
    118         objdata.pdu_data[i].essm_code = bcmEsmcEssmCodeNone;
    119         objdata.pdu_data[i].essm_flag = 0x0;
    120         objdata.pdu_data[i].essm_eec_count = 0x0;
    121         objdata.pdu_data[i].essm_eeec_count= 0x0;
    122     }
    123 
    124 
    125     if (shr_rdpc_callback_created(&tdpll_tx_rdpc) == BCM_E_INIT) {
    126         /* This lock is left in place on cleanup, so only create it once */
    127         shr_rdpc_callback_create(&tdpll_tx_rdpc, bcm_tdpll_esmc_info_pdu_tx);
    128     }
    129 
    130     /* QL Change callback. */
    131     objdata.ql_change_callback = NULL;
    132 
    133     return BCM_E_NONE;
    134 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    135 }
    136 
    137 /*
    138  * Function:
    139  *      bcm_tdpll_esmc_cleanup()
    140  * Purpose:
    141  *      Uninitialize T-DPLL Ethernet Synchronization Messaging Channel (ESMC).
    142  * Parameters:
    143  *      unit      - (IN) Unit number.
    144  *      stack_id  - (IN) Stack identifier index.
    145  * Returns:
    146  *      BCM_E_XXX - Function status.
    147  * Notes:
    148  */
    149 int
    150 bcm_tdpll_esmc_cleanup(
    151     int unit,
    152     int stack_id)
    153 {
    154 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    155     return bcm_extdpll_esmc_cleanup(unit, stack_id);
    156 #else
    157     int i;
    158 
    159     objdata.rx_enable = 0;
    160     for (i = 0; i < TDPLL_DPLL_INSTANCE_NUM_MAX; ++i) {
    161         objdata.tx_enable[i] = 0;
    162     }
    163 
    164     shr_rdpc_callback_stop(&tdpll_tx_rdpc);
    165 
    166     return BCM_E_NONE;
    167 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    168 }
    169 
    170 #ifndef BCM_ESMC_EXTDPLL_SUPPORT
    171 static int
    172 bcm_common_tdpll_esmc_handle_rx_essm_code(
    173     int unit,
    174     int stack_id,
    175     int dpll_index,
    176     bcm_esmc_pdu_data_t *esmc_pdu_data)
    177 {
    178     if (objdata.pdu_data[dpll_index].essm_code == bcmEsmcEssmCodeNone) {
    179         return BCM_E_NONE;
    180     }
    181     /* incoming pdu's ESSM code is not copied */
    182     objdata.pdu_data[dpll_index].essm_flag = esmc_pdu_data->essm_flag;
    183     objdata.pdu_data[dpll_index].essm_eec_count = esmc_pdu_data->essm_eec_count;
    184     objdata.pdu_data[dpll_index].essm_eeec_count = esmc_pdu_data->essm_eeec_count;
    185 
    186     switch (objdata.pdu_data[dpll_index].essm_code) {
    187         case bcmEsmcEssmCodeEEC:
    188             objdata.pdu_data[dpll_index].essm_eec_count++;
    189             break;
    190         case bcmEsmcEssmCodeEEEC:
    191             objdata.pdu_data[dpll_index].essm_eeec_count++;
    192         default:
    193             break;
    194     }
    195     return BCM_E_NONE;
    196 }
    197 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    198 
    199 /*
    200  * Function:
    201  *      bcm_tdpll_esmc_rx_state_machine()
    202  * Purpose:
    203  *      Execute state machine for Rx ESMC PDU.
    204  * Parameters:
    205  *      unit          - (IN) Unit number.
    206  *      stack_id      - (IN) Stack identifier index.
    207  *      ingress_port  - (IN) Ingress port.
    208  *      esmc_pdu_data - (IN) ESMC PDU.
    209  * Returns:
    210  *      BCM_E_XXX - Function status.
    211  * Notes:
    212  *      State machine updates the SSM/QL of a T-DPLL input clock, transmits an
    213  *      ESMC event PDU upon change to SSM/QL of selected reference clock, etc.
    214  */
    215 int
    216 bcm_common_tdpll_esmc_rx_state_machine(
    217     int unit,
    218     int stack_id,
    219     int ingress_port,
    220     bcm_esmc_pdu_data_t *esmc_pdu_data)
    221 {
    222 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    223     return bcm_extdpll_esmc_rx_state_machine(unit, stack_id, ingress_port, esmc_pdu_data);
    224 #else
    225     int rv;
    226 
    227     int dpll_index = 0;
    228     int input_clock_index;
    229     int reference_index;
    230 
    231     bcm_esmc_quality_level_t input_clock_ql;
    232     bcm_esmc_quality_level_t esmc_pdu_ql;
    233     bcm_tdpll_input_clock_ql_change_cb_data_t cb_data;
    234 
    235     bcm_esmc_pdu_data_t pdu_data;
    236 
    237     /* Update networking option. */
    238     bcm_esmc_g781_option_get(unit, stack_id, &objdata.network_option);
    239 
    240     /* Look up ESMC PDU source in input clock set. */
    241     if (BCM_SUCCESS(rv = bcm_tdpll_input_clock_port_lookup(unit, stack_id,
    242             ingress_port, &input_clock_index))) {
    243         /* Update input clock MAC address. ESMC PDU from a known SyncE input clock. */
    244         bcm_tdpll_input_clock_mac_set(unit, stack_id, input_clock_index,
    245             &esmc_pdu_data->source_mac);
    246     } else if (BCM_FAILURE(rv = bcm_tdpll_input_clock_mac_lookup(unit, stack_id,
    247             &esmc_pdu_data->source_mac, &input_clock_index))) {
    248         /* Do nothing. ESMC PDU not from a known source / input clock. */
    249         return BCM_E_NONE;
    250     }
    251 
    252     /* Input clock SSM/QL change. */
    253     if (BCM_FAILURE(rv = bcm_tdpll_input_clock_ql_get(unit, stack_id,
    254             input_clock_index, &input_clock_ql))) {
    255         PTP_ERROR_FUNC("bcm_tdpll_input_clock_ql_get()");
    256         return rv;
    257     }
    258 
    259     if (BCM_FAILURE(rv = bcm_esmc_SSM_QL_map(unit, objdata.network_option,
    260             esmc_pdu_data->ssm_code, &esmc_pdu_ql))) {
    261         PTP_ERROR_FUNC("bcm_esmc_SSM_QL_map()");
    262         return rv;
    263     }
    264 
    265     if (input_clock_ql != esmc_pdu_ql) {
    266         if (BCM_FAILURE(rv = bcm_tdpll_input_clock_ql_set(unit, stack_id,
    267                 input_clock_index, esmc_pdu_ql))) {
    268                 PTP_ERROR_FUNC("bcm_tdpll_input_clock_ql_set()");
    269             return rv;
    270         }
    271         cb_data.input_clk_index = input_clock_index;
    272         cb_data.prior_ql = input_clock_ql;
    273         cb_data.current_ql = esmc_pdu_ql;
    274         if (objdata.ql_change_callback) {
    275             objdata.ql_change_callback(unit, stack_id, &cb_data);
    276         }
    277     }
    278 
    279     /* Selected reference clock SSM/QL change. */
    280     for (dpll_index = 0; dpll_index < TDPLL_DPLL_INSTANCE_NUM_MAX; ++dpll_index) {
    281         if ((0 == objdata.tx_enable[dpll_index]) ||
    282                     SOC_PBMP_IS_NULL(objdata.tx_pbmp[dpll_index])) {
    283             /* ESMC Tx not enabled for DPLL. */
    284             continue;
    285         }
    286 
    287 
    288         if (BCM_FAILURE(rv = bcm_tdpll_input_clock_dpll_reference_get(unit, stack_id,
    289                 dpll_index, &reference_index))) {
    290             /*
    291              * Do nothing. T-DPLL reference clock lookup failure.
    292              * Holdover logic shall initiate update to local node ESMC attributes and issue
    293              * an ESMC event PDU upon entry to holdover.
    294              */
    295             continue;
    296         }
    297 
    298         if (reference_index != input_clock_index) {
    299             /* Do nothing. ESMC PDU is not from T-DPLL current / active reference clock. */
    300             continue;
    301         }
    302 
    303         bcm_common_tdpll_esmc_handle_rx_essm_code(unit, stack_id, dpll_index, esmc_pdu_data);
    304 
    305         if (input_clock_ql == esmc_pdu_ql) {
    306             /* Do nothing. ESMC PDU from known source / input clock but SSM/QL is unchanged. */
    307             continue;
    308         }
    309 
    310 
    311         if (objdata.pdu_data[dpll_index].ssm_code != esmc_pdu_data->ssm_code) {
    312             /* Update local node ESMC attributes. */
    313             objdata.pdu_data[dpll_index].ssm_code = esmc_pdu_data->ssm_code;
    314             if (BCM_FAILURE(rv = bcm_esmc_SSM_QL_map(unit, objdata.network_option,
    315                     objdata.pdu_data[dpll_index].ssm_code, &objdata.pdu_data[dpll_index].ql))) {
    316                 PTP_ERROR_FUNC("bcm_esmc_SSM_QL_map()");
    317                 continue;
    318             }
    319 
    320             /* Transmit ESMC event PDU. */
    321             pdu_data = objdata.pdu_data[dpll_index];
    322             pdu_data.pdu_type = bcm_esmc_pdu_type_event;
    323             if (BCM_FAILURE(rv = bcm_esmc_tx(unit, stack_id, objdata.tx_pbmp[dpll_index],
    324                     &pdu_data))) {
    325                 PTP_ERROR_FUNC("bcm_esmc_tx()");
    326             }
    327         }
    328     }
    329 
    330     return BCM_E_NONE;
    331 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    332 }
    333 
    334 /*
    335  * Function:
    336  *      bcm_tdpll_esmc_holdover_event_send()
    337  * Purpose:
    338  *      Update ESMC and issue event PDU as result of holdover entry.
    339  * Parameters:
    340  *      unit       - (IN) Unit number.
    341  *      stack_id   - (IN) Stack identifier index.
    342  *      dpll_index - (IN) DPLL instance number.
    343  * Returns:
    344  *      BCM_E_XXX - Function status.
    345  * Notes:
    346  */
    347 int
    348 bcm_tdpll_esmc_holdover_event_send(
    349     int unit,
    350     int stack_id,
    351     int dpll_index)
    352 {
    353 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    354     return BCM_E_UNAVAIL;
    355 #else
    356     int rv;
    357     bcm_esmc_pdu_data_t pdu_data;
    358 
    359     /* Argument checking and error handling. */
    360     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    361         return BCM_E_PARAM;
    362     }
    363 
    364     if (objdata.pdu_data[dpll_index].ql == objdata.holdover_ql[dpll_index]) {
    365         /* Do nothing. ESMC QL is unchanged. */
    366         return BCM_E_NONE;
    367     }
    368 
    369     objdata.pdu_data[dpll_index].ql = objdata.holdover_ql[dpll_index];
    370     objdata.pdu_data[dpll_index].ssm_code = objdata.holdover_ssm_code[dpll_index];
    371 
    372     if (objdata.tx_enable[dpll_index]
    373         && SOC_PBMP_NOT_NULL(objdata.tx_pbmp[dpll_index])) {
    374         /* Transmit ESMC event PDU. */
    375         pdu_data = objdata.pdu_data[dpll_index];
    376         pdu_data.pdu_type = bcm_esmc_pdu_type_event;
    377         if (BCM_FAILURE(rv = bcm_esmc_tx(unit, stack_id, objdata.tx_pbmp[dpll_index],
    378                 &pdu_data))) {
    379             PTP_ERROR_FUNC("bcm_esmc_tx()");
    380         }
    381     }
    382 
    383     return BCM_E_NONE;
    384 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    385 }
    386 
    387 /*
    388  * Function:
    389  *      bcm_tdpll_esmc_switch_event_send()
    390  * Purpose:
    391  *      Update ESMC and issue event PDU as result of reference switch.
    392  * Parameters:
    393  *      unit       - (IN) Unit number.
    394  *      stack_id   - (IN) Stack identifier index.
    395  *      dpll_index - (IN) DPLL instance number.
    396  *      ql         - (IN) QL.
    397  * Returns:
    398  *      BCM_E_XXX - Function status.
    399  * Notes:
    400  */
    401 int
    402 bcm_tdpll_esmc_switch_event_send(
    403     int unit,
    404     int stack_id,
    405     int dpll_index,
    406     bcm_esmc_quality_level_t ql)
    407 {
    408 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    409     return BCM_E_UNAVAIL;
    410 #else
    411     int rv;
    412     bcm_esmc_pdu_data_t pdu_data;
    413 
    414     /* Argument checking and error handling. */
    415     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    416         return BCM_E_PARAM;
    417     }
    418 
    419     if (ql == objdata.pdu_data[dpll_index].ql) {
    420         /* Do nothing. ESMC QL is unchanged. */
    421         return BCM_E_NONE;
    422     }
    423 
    424     /* Update networking option. */
    425     bcm_esmc_g781_option_get(unit, stack_id, &objdata.network_option);
    426 
    427     objdata.pdu_data[dpll_index].ql = ql;
    428     if (BCM_FAILURE(rv = bcm_esmc_QL_SSM_map(unit, objdata.network_option,
    429             objdata.pdu_data[dpll_index].ql, &objdata.pdu_data[dpll_index].ssm_code))) {
    430         PTP_ERROR_FUNC("bcm_esmc_QL_SSM_map");
    431         return rv;
    432     }
    433 
    434     if (objdata.tx_enable[dpll_index]
    435         && SOC_PBMP_NOT_NULL(objdata.tx_pbmp[dpll_index])) {
    436         /* Transmit ESMC event PDU. */
    437         pdu_data = objdata.pdu_data[dpll_index];
    438         pdu_data.pdu_type = bcm_esmc_pdu_type_event;
    439         if (BCM_FAILURE(rv = bcm_esmc_tx(unit, stack_id, objdata.tx_pbmp[dpll_index],
    440                 &pdu_data))) {
    441             PTP_ERROR_FUNC("bcm_esmc_tx()");
    442         }
    443     }
    444 
    445     return BCM_E_NONE;
    446 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    447 }
    448 
    449 /*
    450  * Function:
    451  *      bcm_tdpll_esmc_ql_get()
    452  * Purpose:
    453  *      Get quality level (QL) for ESMC.
    454  * Parameters:
    455  *      unit       - (IN) Unit number.
    456  *      stack_id   - (IN) Stack identifier index.
    457  *      dpll_index - (IN) DPLL instance number.
    458  *      ql         - (OUT) QL.
    459  * Returns:
    460  *      BCM_E_XXX - Function status.
    461  * Notes:
    462  */
    463 int
    464 bcm_common_tdpll_esmc_ql_get(
    465     int unit,
    466     int stack_id,
    467     int dpll_index,
    468     bcm_esmc_quality_level_t *ql)
    469 {
    470 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    471      return bcm_extdpll_esmc_ql_get(unit, stack_id, ql);
    472 #else
    473     /* Argument checking and error handling. */
    474     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    475         return BCM_E_PARAM;
    476     }
    477 
    478     *ql = objdata.pdu_data[dpll_index].ql;
    479     return BCM_E_NONE;
    480 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    481 }
    482 
    483 /*
    484  * Function:
    485  *      bcm_tdpll_esmc_ql_set()
    486  * Purpose:
    487  *      Set quality level (QL) for ESMC.
    488  * Parameters:
    489  *      unit       - (IN) Unit number.
    490  *      stack_id   - (IN) Stack identifier index.
    491  *      dpll_index - (IN) DPLL instance number.
    492  *      ql         - (IN) QL.
    493  * Returns:
    494  *      BCM_E_XXX - Function status.
    495  * Notes:
    496  *      Assignment is transient. QL shall be overwritten by subsequent
    497  *      ESMC PDUs received from a T-DPLL selected reference clock.
    498  */
    499 int
    500 bcm_common_tdpll_esmc_ql_set(
    501     int unit,
    502     int stack_id,
    503     int dpll_index,
    504     bcm_esmc_quality_level_t ql)
    505 {
    506 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    507      return bcm_extdpll_esmc_ql_set(unit, stack_id, dpll_index, ql);
    508 #else
    509     int rv;
    510 
    511     /* Argument checking and error handling. */
    512     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    513         return BCM_E_PARAM;
    514     }
    515 
    516     /* Update networking option. */
    517     bcm_esmc_g781_option_get(unit, stack_id, &objdata.network_option);
    518 
    519     objdata.pdu_data[dpll_index].ql = ql;
    520     if (BCM_FAILURE(rv = bcm_esmc_QL_SSM_map(unit, objdata.network_option,
    521             objdata.pdu_data[dpll_index].ql, &objdata.pdu_data[dpll_index].ssm_code))) {
    522         PTP_ERROR_FUNC("bcm_esmc_QL_SSM_map");
    523         return rv;
    524     }
    525 
    526     return BCM_E_NONE;
    527 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    528 }
    529 
    530 /*
    531  * Function:
    532  *      bcm_tdpll_esmc_holdover_ql_get()
    533  * Purpose:
    534  *      Get quality level (QL) for ESMC during holdover.
    535  * Parameters:
    536  *      unit       - (IN) Unit number.
    537  *      stack_id   - (IN) Stack identifier index.
    538  *      dpll_index - (IN) DPLL instance number.
    539  *      ql         - (OUT) QL.
    540  * Returns:
    541  *      BCM_E_XXX - Function status.
    542  * Notes:
    543  */
    544 int
    545 bcm_common_tdpll_esmc_holdover_ql_get(
    546     int unit,
    547     int stack_id,
    548     int dpll_index,
    549     bcm_esmc_quality_level_t *ql)
    550 {
    551 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    552     return BCM_E_UNAVAIL;
    553 #else
    554     /* Argument checking and error handling. */
    555     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    556         return BCM_E_PARAM;
    557     }
    558 
    559     *ql = objdata.holdover_ql[dpll_index];
    560     return BCM_E_NONE;
    561 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    562 }
    563 
    564 /*
    565  * Function:
    566  *      bcm_tdpll_esmc_holdover_ql_set()
    567  * Purpose:
    568  *      Set quality level (QL) for ESMC during holdover.
    569  * Parameters:
    570  *      unit       - (IN) Unit number.
    571  *      stack_id   - (IN) Stack identifier index.
    572  *      dpll_index - (IN) DPLL instance number.
    573  *      ql         - (IN) QL.
    574  * Returns:
    575  *      BCM_E_XXX - Function status.
    576  * Notes:
    577  */
    578 int
    579 bcm_common_tdpll_esmc_holdover_ql_set(
    580     int unit,
    581     int stack_id,
    582     int dpll_index,
    583     bcm_esmc_quality_level_t ql)
    584 {
    585 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    586     return BCM_E_UNAVAIL;
    587 #else
    588     int rv;
    589 
    590     /* Argument checking and error handling. */
    591     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    592         return BCM_E_PARAM;
    593     }
    594 
    595     /* Update networking option. */
    596     bcm_esmc_g781_option_get(unit, stack_id, &objdata.network_option);
    597 
    598     objdata.holdover_ql[dpll_index] = ql;
    599     if (BCM_FAILURE(rv = bcm_esmc_QL_SSM_map(unit, objdata.network_option,
    600             objdata.holdover_ql[dpll_index], &objdata.holdover_ssm_code[dpll_index]))) {
    601         PTP_ERROR_FUNC("bcm_esmc_QL_SSM_map");
    602         return rv;
    603     }
    604 
    605     return BCM_E_NONE;
    606 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    607 }
    608 
    609 /*
    610  * Function:
    611  *      bcm_tdpll_esmc_mac_get()
    612  * Purpose:
    613  *      Get MAC address for ESMC.
    614  * Parameters:
    615  *      unit       - (IN) Unit number.
    616  *      stack_id   - (IN) Stack identifier index.
    617  *      dpll_index - (IN) DPLL instance number.
    618  *      mac        - (OUT) Local port MAC address.
    619  * Returns:
    620  *      BCM_E_XXX - Function status.
    621  * Notes:
    622  *      MAC address is used as source MAC in Tx'd ESMC info and event PDUs.
    623  *      MAC address is used in discard-from-self logic for reflected PDUs.
    624  */
    625 int
    626 bcm_common_tdpll_esmc_mac_get(
    627     int unit,
    628     int stack_id,
    629     int dpll_index,
    630     bcm_mac_t *mac)
    631 {
    632 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    633     return bcm_extdpll_esmc_mac_get(unit, stack_id, mac);
    634 #else
    635     int rv;
    636 
    637     uint8 payload[PTP_MGMTMSG_PAYLOAD_INDEXED_PROPRIETARY_MSG_SIZE_OCTETS] = {0};
    638     uint8 resp[PTP_MGMTMSG_PAYLOAD_ESMC_MAC_SIZE_OCTETS] = {0};
    639     int resp_len = PTP_MGMTMSG_PAYLOAD_ESMC_MAC_SIZE_OCTETS;
    640 
    641     bcm_ptp_port_identity_t portid;
    642 
    643     /* Argument checking and error handling. */
    644     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    645         return BCM_E_PARAM;
    646     }
    647 
    648     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, stack_id,
    649             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    650         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
    651         return rv;
    652     }
    653 
    654     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, stack_id,
    655             PTP_CLOCK_NUMBER_DEFAULT, PTP_IEEE1588_ALL_PORTS, &portid))) {
    656         PTP_ERROR_FUNC("bcm_common_ptp_clock_port_identity_get()");
    657         return rv;
    658     }
    659 
    660     /* Make indexed payload to get MAC address for specified DPLL instance. */
    661     sal_memcpy(payload, "BCM\0\0\0", 6);
    662     payload[6] = (uint8)dpll_index;
    663     if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, stack_id, PTP_CLOCK_NUMBER_DEFAULT,
    664             &portid, PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_ESMC_MAC,
    665             payload, PTP_MGMTMSG_PAYLOAD_INDEXED_PROPRIETARY_MSG_SIZE_OCTETS,
    666             resp, &resp_len))) {
    667         PTP_ERROR_FUNC("_bcm_ptp_management_message_send()");
    668         return rv;
    669     }
    670 
    671     /*
    672      * Parse response.
    673      *    Octet 0...5  : Custom management message key/identifier.
    674      *                   BCM<null><null><null>.
    675      *    Octet 6      : DPLL instance number.
    676      *    Octet 7      : Reserved.
    677      *    Octet 8...13 : ESMC MAC address.
    678      */
    679     sal_memcpy(mac, resp + 8, sizeof(bcm_mac_t));
    680 
    681     /* Set host-maintained ESMC MAC address. */
    682     sal_memcpy(objdata.pdu_data[dpll_index].source_mac, resp + 8, sizeof(bcm_mac_t));
    683 
    684     return BCM_E_NONE;
    685 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    686 }
    687 
    688 /*
    689  * Function:
    690  *      bcm_tdpll_esmc_mac_set()
    691  * Purpose:
    692  *      Set MAC address for ESMC.
    693  * Parameters:
    694  *      unit       - (IN) Unit number.
    695  *      stack_id   - (IN) Stack identifier index.
    696  *      dpll_index - (IN) DPLL instance number.
    697  *      mac        - (IN) Local port MAC address.
    698  * Returns:
    699  *      BCM_E_XXX - Function status.
    700  * Notes:
    701  *      MAC address is used as source MAC in Tx'd ESMC info and event PDUs.
    702  *      MAC address is used in discard-from-self logic for reflected PDUs.
    703  */
    704 int
    705 bcm_common_tdpll_esmc_mac_set(
    706     int unit,
    707     int stack_id,
    708     int dpll_index,
    709     bcm_mac_t *mac)
    710 {
    711 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    712     return bcm_extdpll_esmc_mac_set(unit, stack_id, mac);
    713 #else
    714     int rv;
    715     int i;
    716 
    717     uint8 payload[PTP_MGMTMSG_PAYLOAD_ESMC_MAC_SIZE_OCTETS] = {0};
    718     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
    719     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
    720 
    721     bcm_ptp_port_identity_t portid;
    722 
    723     /* Argument checking and error handling. */
    724     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    725         return BCM_E_PARAM;
    726     }
    727 
    728     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, stack_id,
    729             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    730         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
    731         return rv;
    732     }
    733 
    734     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, stack_id,
    735             PTP_CLOCK_NUMBER_DEFAULT, PTP_IEEE1588_ALL_PORTS, &portid))) {
    736         PTP_ERROR_FUNC("bcm_common_ptp_clock_port_identity_get()");
    737         return rv;
    738     }
    739 
    740     /*
    741      * Make payload.
    742      *    Octet 0...5  : Custom management message key/identifier.
    743      *                   BCM<null><null><null>.
    744      *    Octet 6      : DPLL instance number.
    745      *    Octet 7      : Reserved.
    746      *    Octet 8...13 : ESMC MAC address.
    747      */
    748     sal_memcpy(payload, "BCM\0\0\0", 6);
    749     i = 6;
    750     payload[i++] = (uint8)dpll_index;
    751     payload[i++] = 0;
    752     sal_memcpy(payload + i, mac, sizeof(bcm_mac_t));
    753 
    754     if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, stack_id, PTP_CLOCK_NUMBER_DEFAULT,
    755             &portid, PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_ESMC_MAC,
    756             payload, PTP_MGMTMSG_PAYLOAD_ESMC_MAC_SIZE_OCTETS,
    757             resp, &resp_len))) {
    758         PTP_ERROR_FUNC("_bcm_ptp_management_message_send()");
    759         return rv;
    760     }
    761 
    762     /* Set host-maintained ESMC MAC address. */
    763     sal_memcpy(objdata.pdu_data[dpll_index].source_mac, mac, sizeof(bcm_mac_t));
    764 
    765     return BCM_E_NONE;
    766 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    767 }
    768 
    769 /*
    770  * Function:
    771  *      bcm_tdpll_esmc_rx_enable_get()
    772  * Purpose:
    773  *      Get ESMC PDU receive (Rx) enable state.
    774  * Parameters:
    775  *      unit     - (IN) Unit number.
    776  *      stack_id - (IN) Stack identifier index.
    777  *      enable   - (OUT) ESMC PDU receive enable Boolean.
    778  * Returns:
    779  *      BCM_E_XXX - Function status.
    780  * Notes:
    781  */
    782 int
    783 bcm_common_tdpll_esmc_rx_enable_get(
    784     int unit,
    785     int stack_id,
    786     int *enable)
    787 {
    788 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    789     return bcm_extdpll_esmc_rx_enable_get(unit, stack_id, enable);
    790 #else
    791     int rv;
    792 
    793     rv = bcm_esmc_tunnel_get(unit, stack_id, enable);
    794     objdata.rx_enable = *enable ? 1:0;
    795 
    796     return rv;
    797 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    798 }
    799 
    800 /*
    801  * Function:
    802  *      bcm_tdpll_esmc_rx_enable_set()
    803  * Purpose:
    804  *      Set ESMC PDU receive (Rx) enable state.
    805  * Parameters:
    806  *      unit     - (IN) Unit number.
    807  *      stack_id - (IN) Stack identifier index.
    808  *      enable   - (IN) ESMC PDU receive enable Boolean.
    809  * Returns:
    810  *      BCM_E_XXX - Function status.
    811  * Notes:
    812  */
    813 int
    814 bcm_common_tdpll_esmc_rx_enable_set(
    815     int unit,
    816     int stack_id,
    817     int enable)
    818 {
    819 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    820     return bcm_extdpll_esmc_rx_enable_set(unit, stack_id, enable);
    821 #else
    822     int rv;
    823 
    824     rv = bcm_esmc_tunnel_set(unit, stack_id, enable);
    825     objdata.rx_enable = enable ? 1:0;
    826 
    827     return rv;
    828 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    829 }
    830 
    831 /*
    832  * Function:
    833  *      bcm_tdpll_esmc_tx_enable_get()
    834  * Purpose:
    835  *      Get ESMC PDU transmit (Tx) enable state.
    836  * Parameters:
    837  *      unit       - (IN) Unit number.
    838  *      stack_id   - (IN) Stack identifier index.
    839  *      dpll_index - (IN) DPLL instance number.
    840  *      enable     - (OUT) ESMC PDU transmit enable Boolean.
    841  * Returns:
    842  *      BCM_E_XXX - Function status.
    843  * Notes:
    844  */
    845 int
    846 bcm_common_tdpll_esmc_tx_enable_get(
    847     int unit,
    848     int stack_id,
    849     int dpll_index,
    850     int *enable)
    851 {
    852 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    853     return bcm_extdpll_esmc_tx_enable_get(unit, stack_id, enable);
    854 #else
    855     /* Argument checking and error handling. */
    856     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    857         return BCM_E_PARAM;
    858     }
    859 
    860     *enable = objdata.tx_enable[dpll_index] ? 1:0;
    861     return BCM_E_NONE;
    862 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    863 }
    864 
    865 /*
    866  * Function:
    867  *      bcm_tdpll_esmc_tx_enable_set()
    868  * Purpose:
    869  *      Set ESMC PDU transmit (Tx) enable state.
    870  * Parameters:
    871  *      unit       - (IN) Unit number.
    872  *      stack_id   - (IN) Stack identifier index.
    873  *      dpll_index - (IN) DPLL instance number.
    874  *      enable     - (IN) ESMC PDU transmit enable Boolean.
    875  * Returns:
    876  *      BCM_E_XXX - Function status.
    877  * Notes:
    878  */
    879 int
    880 bcm_common_tdpll_esmc_tx_enable_set(
    881     int unit,
    882     int stack_id,
    883     int dpll_index,
    884     int enable)
    885 {
    886 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    887     return bcm_extdpll_esmc_tx_enable_set(unit, stack_id, enable);
    888 #else
    889     int i;
    890     int tx_esmc;
    891 
    892     /* Argument checking and error handling. */
    893     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
    894         return BCM_E_PARAM;
    895     }
    896 
    897     objdata.tx_enable[dpll_index] = enable ? 1:0;
    898 
    899     /*
    900      * Conditionally start DPC for periodic ESMC information PDUs.
    901      * NB: Cancel prior ESMC information DPC process (if any).
    902      */
    903     tx_esmc = 0;
    904     for (i = 0; i < TDPLL_DPLL_INSTANCE_NUM_MAX; ++i) {
    905         if (objdata.tx_enable[i]) {
    906             tx_esmc = 1;
    907             break;
    908         }
    909     }
    910 
    911     if (tx_esmc) {
    912         shr_rdpc_callback_start(&tdpll_tx_rdpc, TDPLL_ESMC_INFO_PDU_DPC_TIME_USEC_DEFAULT,
    913                                 INT_TO_PTR(unit), INT_TO_PTR(stack_id), 0, 0);
    914     } else {
    915         shr_rdpc_callback_stop(&tdpll_tx_rdpc);
    916     }
    917 
    918     return BCM_E_NONE;
    919 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    920 }
    921 
    922 /*
    923  * Function:
    924  *      bcm_tdpll_esmc_rx_portbitmap_get()
    925  * Purpose:
    926  *      Get port bitmap for ESMC Rx.
    927  * Parameters:
    928  *      unit       - (IN) Unit number.
    929  *      stack_id   - (IN) Stack identifier index.
    930  *      dpll_index - (IN) DPLL instance number.
    931  *      pbmp       - (OUT) Rx port bitmap.
    932  * Returns:
    933  *      BCM_E_XXX - Function status.
    934  * Notes:
    935  */
    936 int
    937 bcm_common_tdpll_esmc_rx_portbitmap_get(
    938     int unit,
    939     int stack_id,
    940     int dpll_index,
    941     bcm_pbmp_t *pbmp)
    942 {
    943 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    944     return bcm_extdpll_esmc_rx_portbitmap_get(unit, stack_id, pbmp);
    945 #else
    946     *pbmp = objdata.rx_pbmp[dpll_index];
    947     return BCM_E_NONE;
    948 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    949 }
    950 
    951 /*
    952  * Function:
    953  *      bcm_tdpll_esmc_rx_portbitmap_set()
    954  * Purpose:
    955  *      Set port bitmap for ESMC Rx.
    956  * Parameters:
    957  *      unit       - (IN) Unit number.
    958  *      stack_id   - (IN) Stack identifier index.
    959  *      dpll_index - (IN) DPLL instance number.
    960  *      pbmp       - (IN) Rx port bitmap.
    961  * Returns:
    962  *      BCM_E_XXX - Function status.
    963  * Notes:
    964  */
    965 int
    966 bcm_common_tdpll_esmc_rx_portbitmap_set(
    967     int unit,
    968     int stack_id,
    969     int dpll_index,
    970     bcm_pbmp_t pbmp)
    971 {
    972 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    973     return bcm_extdpll_esmc_rx_portbitmap_set(unit, stack_id, pbmp);
    974 #else
    975     objdata.rx_pbmp[dpll_index] = pbmp;
    976     return BCM_E_NONE;
    977 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    978 }
    979 
    980 /*
    981  * Function:
    982  *      bcm_tdpll_esmc_tx_portbitmap_get()
    983  * Purpose:
    984  *      Get port bitmap for ESMC Tx.
    985  * Parameters:
    986  *      unit       - (IN) Unit number.
    987  *      stack_id   - (IN) Stack identifier index.
    988  *      dpll_index - (IN) DPLL instance number.
    989  *      pbmp       - (OUT) Tx port bitmap.
    990  * Returns:
    991  *      BCM_E_XXX - Function status.
    992  * Notes:
    993  */
    994 int
    995 bcm_common_tdpll_esmc_tx_portbitmap_get(
    996     int unit,
    997     int stack_id,
    998     int dpll_index,
    999     bcm_pbmp_t *pbmp)
   1000 {
   1001 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
   1002     return bcm_extdpll_esmc_tx_portbitmap_get(unit, stack_id, pbmp);
   1003 #else
   1004     *pbmp = objdata.tx_pbmp[dpll_index];
   1005     return BCM_E_NONE;
   1006 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   1007 }
   1008 
   1009 /*
   1010  * Function:
   1011  *      bcm_tdpll_esmc_tx_portbitmap_set()
   1012  * Purpose:
   1013  *      Set port bitmap for ESMC Tx.
   1014  * Parameters:
   1015  *      unit       - (IN) Unit number.
   1016  *      stack_id   - (IN) Stack identifier index.
   1017  *      dpll_index - (IN) DPLL instance number.
   1018  *      pbmp       - (IN) Tx port bitmap.
   1019  * Returns:
   1020  *      BCM_E_XXX - Function status.
   1021  * Notes:
   1022  */
   1023 int
   1024 bcm_common_tdpll_esmc_tx_portbitmap_set(
   1025     int unit,
   1026     int stack_id,
   1027     int dpll_index,
   1028     bcm_pbmp_t pbmp)
   1029 {
   1030 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
   1031     return bcm_extdpll_esmc_tx_portbitmap_set(unit, stack_id, pbmp);
   1032 #else
   1033     objdata.tx_pbmp[dpll_index] = pbmp;
   1034     return BCM_E_NONE;
   1035 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   1036 }
   1037 
   1038 #ifndef BCM_ESMC_EXTDPLL_SUPPORT
   1039 /*
   1040  * Function:
   1041  *      bcm_tdpll_esmc_1588_clock_ql_get
   1042  * Purpose:
   1043  *      Gets clock quality of a PTP clock default dataset.
   1044  * Parameters:
   1045  *      unit      - (IN)  Unit number.
   1046  *      ptp_id    - (IN)  PTP stack ID.
   1047  *      clock_quality - (OUT) PTP clock quality
   1048  * Returns:
   1049  *      BCM_E_XXX
   1050  */
   1051 int
   1052 bcm_tdpll_esmc_1588_clock_ql_get(
   1053     int unit,
   1054     bcm_ptp_stack_id_t ptp_id,
   1055     bcm_esmc_network_option_t network_option,
   1056     bcm_esmc_quality_level_t *ql)
   1057 {
   1058     int rv = BCM_E_PARAM;
   1059     bcm_ptp_parent_dataset_t par_data_set;
   1060 
   1061     if (BCM_FAILURE(rv = bcm_ptp_clock_parent_dataset_get(unit, ptp_id, 0, &par_data_set))) {
   1062         return rv;
   1063     }
   1064     *ql = bcm_esmc_ql_unresolvable;
   1065     switch (par_data_set.grandmaster_clock_quality.clock_class)
   1066     {
   1067         case 6:
   1068         case 7:
   1069         case 135:
   1070         case 140:
   1071             if (network_option == bcm_esmc_network_option_g781_I)
   1072                 *ql = bcm_esmc_g781_I_ql_prc;
   1073             else if (network_option == bcm_esmc_network_option_g781_II)
   1074                 *ql = bcm_esmc_g781_II_ql_prs;
   1075             break;
   1076         case 150:
   1077             if (network_option == bcm_esmc_network_option_g781_I)
   1078                 *ql = bcm_esmc_g781_I_ql_ssua;
   1079             else if (network_option == bcm_esmc_network_option_g781_II)
   1080                 *ql = bcm_esmc_g781_II_ql_st2;
   1081             break;
   1082         case 160:
   1083             if (network_option == bcm_esmc_network_option_g781_I)
   1084                 *ql = bcm_esmc_g781_I_ql_ssub;
   1085             else if (network_option == bcm_esmc_network_option_g781_II)
   1086                 *ql = bcm_esmc_g781_II_ql_st3e;
   1087             break;
   1088         case 165:
   1089         case 248:
   1090         case 255:
   1091         default:
   1092             if (network_option == bcm_esmc_network_option_g781_I)
   1093                 *ql = bcm_esmc_g781_I_ql_sec;
   1094             else if (network_option == bcm_esmc_network_option_g781_II)
   1095                 *ql = bcm_esmc_g781_II_ql_st3;
   1096             break;
   1097     }
   1098 
   1099     return rv;
   1100 }
   1101 
   1102 
   1103 /*
   1104  * Function:
   1105  *      bcm_tdpll_esmc_info_pdu_tx()
   1106  * Purpose:
   1107  *      ESMC information PDU (as DPC).
   1108  * Parameters:
   1109  *      arg_unit       - (IN) Pointer to Unit number (as void*).
   1110  *      arg_stack_id   - (IN) Pointer to Stack identifier index (as void*).
   1111  *      arg_dpll_index - (IN) Pointer to DPLL instance number (as void*).
   1112  *      unused         - (IN) Unused.
   1113  * Returns:
   1114  *      Time interval before next call
   1115  * Notes:
   1116  */
   1117 static sal_usecs_t
   1118 bcm_tdpll_esmc_info_pdu_tx(
   1119     void **arg_unit,
   1120     void **arg_stack_id,
   1121     void **arg_dpll_index,
   1122     void **unused)
   1123 {
   1124     int rv;
   1125     int unit = PTR_TO_INT(*arg_unit);
   1126     int stack_id = PTR_TO_INT(*arg_stack_id);
   1127     bcm_esmc_pdu_data_t pdu_data;
   1128     size_t *dpll_index = (size_t*)arg_dpll_index; /* use as ptr so value can be updated for next call */
   1129     bcm_esmc_quality_level_t ql = bcm_esmc_ql_unresolvable;
   1130     bcm_ptp_clock_info_t *clock_info;
   1131     clock_info = &_bcm_common_ptp_unit_array[0].stack_array[0].clock_array[0].clock_info;
   1132 
   1133     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, stack_id,
   1134             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1135         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
   1136         return TDPLL_ESMC_INFO_PDU_DPC_TIME_USEC_IDLE;
   1137     }
   1138     if (objdata.tx_enable[*dpll_index]
   1139         && SOC_PBMP_NOT_NULL(objdata.tx_pbmp[*dpll_index])) {
   1140         if (PTP_CLOCK_IS_G8275P2_PROF(clock_info)) {
   1141             if (BCM_FAILURE(rv = bcm_tdpll_esmc_1588_clock_ql_get(unit,stack_id,objdata.network_option,&ql))) {
   1142                 PTP_ERROR_FUNC("bcm_tdpll_esmc_1588_clock_ql_get");
   1143             } else {
   1144                 if (objdata.pdu_data[*dpll_index].ql != ql)
   1145                 {
   1146                     bcm_tdpll_esmc_switch_event_send(unit, stack_id, *dpll_index, ql);
   1147                 } else {
   1148                     /* Transmit ESMC information PDU. */
   1149                     objdata.pdu_data[*dpll_index].ql = ql;
   1150                     if (BCM_FAILURE(rv = bcm_esmc_QL_SSM_map(unit, objdata.network_option,
   1151                         objdata.pdu_data[*dpll_index].ql, &objdata.pdu_data[*dpll_index].ssm_code))) {
   1152                         PTP_ERROR_FUNC("bcm_esmc_QL_SSM_map");
   1153                     }
   1154                 }
   1155             }
   1156         }
   1157         /* Transmit ESMC information PDU. */
   1158         pdu_data = objdata.pdu_data[*dpll_index];
   1159         pdu_data.pdu_type = bcm_esmc_pdu_type_info;
   1160 
   1161         if (BCM_FAILURE(rv = bcm_esmc_tx(unit, stack_id, objdata.tx_pbmp[*dpll_index],
   1162                                         &pdu_data))) {
   1163             PTP_ERROR_FUNC("bcm_esmc_tx()");
   1164         }
   1165     }
   1166 
   1167     ++(*dpll_index);
   1168     (*dpll_index) %= TDPLL_DPLL_INSTANCE_NUM_MAX;
   1169 
   1170     return TDPLL_ESMC_INFO_PDU_DPC_TIME_USEC_DEFAULT;
   1171 }
   1172 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   1173 
   1174 /*
   1175  * Function:
   1176  *      bcm_common_tdpll_input_clock_ql_change_callback_register()
   1177  * Purpose:
   1178  *      Register input clock esmc quality change callback.
   1179  * Parameters:
   1180  *      unit        - (IN) Unit number.
   1181  *      stack_id    - (IN) Stack identifier index.
   1182  *      ql_change_cb - (IN) Input clock esmc QL change callback function pointer.
   1183  * Returns:
   1184  *      BCM_E_XXX - Function status.
   1185  * Notes:
   1186  *      QL change callback generates an event to notify user if a
   1187  *      QL level change happens to take necessary action if required.
   1188  */
   1189 int
   1190 bcm_common_tdpll_input_clock_ql_change_callback_register(
   1191     int unit,
   1192     int stack_id,
   1193     bcm_tdpll_input_clock_ql_change_cb ql_change_cb)
   1194 {
   1195 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
   1196     return BCM_E_UNAVAIL;
   1197 #else
   1198     objdata.ql_change_callback = ql_change_cb;
   1199     return BCM_E_NONE;
   1200 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   1201 }
   1202 
   1203 /*
   1204  * Function:
   1205  *      bcm_common_tdpll_input_clock_ql_change_callback_unregister()
   1206  * Purpose:
   1207  *      Un-register input clock esmc quality change callback.
   1208  * Parameters:
   1209  *      unit        - (IN) Unit number.
   1210  *      stack_id    - (IN) Stack identifier index.
   1211  * Returns:
   1212  *      BCM_E_XXX - Function status.
   1213  * Notes:
   1214  *      QL change callback generates an event to notify user if a
   1215  *      QL level change happens to take necessary action if required.
   1216  */
   1217 
   1218 int
   1219 bcm_common_tdpll_input_clock_ql_change_callback_unregister(
   1220     int unit,
   1221     int stack_id)
   1222 {
   1223 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
   1224     return BCM_E_UNAVAIL;
   1225 #else
   1226     objdata.ql_change_callback = NULL;
   1227     return BCM_E_NONE;
   1228 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   1229 }
   1230 
   1231 /*
   1232  * Function:
   1233  *      bcm_common_tdpll_esmc_essm_code_get()
   1234  * Purpose:
   1235  *      Get synce clock type for ESMC.
   1236  * Parameters:
   1237  *      unit       - (IN) Unit number.
   1238  *      stack_id   - (IN) Stack identifier index.
   1239  *      dpll_index - (IN) DPLL instance number.
   1240  *      essm_code - (OUT) essm code as per G.8264 amd2.
   1241  * Returns:
   1242  *      BCM_E_XXX - Function status.
   1243  * Notes:
   1244  */
   1245 int
   1246 bcm_common_tdpll_esmc_essm_code_get(
   1247     int unit,
   1248     int stack_id,
   1249     int dpll_index,
   1250     bcm_esmc_essm_code_t *essm_code)
   1251 {
   1252 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
   1253     return bcm_extdpll_esmc_essm_code_get(unit, stack_id, essm_code);
   1254 #else
   1255     /* Argument checking and error handling. */
   1256     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
   1257         return BCM_E_PARAM;
   1258     }
   1259 
   1260     *essm_code= objdata.pdu_data[dpll_index].essm_code;
   1261     return BCM_E_NONE;
   1262 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   1263 }
   1264 
   1265 /*
   1266  * Function:
   1267  *      bcm_common_tdpll_esmc_essm_code_set()
   1268  * Purpose:
   1269  *      Get synce clock type for ESMC.
   1270  * Parameters:
   1271  *      unit       - (IN) Unit number.
   1272  *      stack_id   - (IN) Stack identifier index.
   1273  *      dpll_index - (IN) DPLL instance number.
   1274  *      essm_code - (IN) essm oode type as per G.8264 amd 2.
   1275  * Returns:
   1276  *      BCM_E_XXX - Function status.
   1277  */
   1278 int
   1279 bcm_common_tdpll_esmc_essm_code_set(
   1280     int unit,
   1281     int stack_id,
   1282     int dpll_index,
   1283     bcm_esmc_essm_code_t essm_code)
   1284 {
   1285 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
   1286     return bcm_extdpll_esmc_essm_code_set(unit, stack_id, essm_code);
   1287 #else
   1288 
   1289     /* Argument checking and error handling. */
   1290     if (dpll_index < 0 || dpll_index >= TDPLL_DPLL_INSTANCE_NUM_MAX) {
   1291         return BCM_E_PARAM;
   1292     }
   1293 
   1294 
   1295     objdata.pdu_data[dpll_index].essm_code = essm_code;
   1296 
   1297     switch (essm_code) {
   1298         case bcmEsmcEssmCodeEEC:
   1299            objdata.pdu_data[dpll_index].essm_eec_count = 1;
   1300            break;
   1301         default:
   1302             break;
   1303     }        
   1304 
   1305     return BCM_E_NONE;
   1306 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   1307 }
   1308 
   1309 /*
   1310  * Function:
   1311  *      bcm_common_tdpll_event_callback_register()
   1312  * Purpose:
   1313  *      Register the event callback handler with ESMC stack.
   1314  * Parameters:
   1315  *      unit       - (IN) Unit number.
   1316  *      stack_id   - (IN) Stack identifier index.
   1317  *      callback   - (IN) callback handler func.
   1318  * Returns:
   1319  *      BCM_E_XXX - Function status.
   1320  */
   1321 int
   1322 bcm_common_tdpll_event_callback_register(
   1323     int unit,
   1324     int stack_id,
   1325     bcm_tdpll_event_cb_f callback)
   1326 {
   1327 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
   1328     return bcm_extdpll_event_callback_register(unit, stack_id, callback);
   1329 #else
   1330     return BCM_E_UNAVAIL;
   1331 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   1332 }
   1333 
   1334 /*
   1335  * Function:
   1336  *      bcm_common_tdpll_event_callback_unregister()
   1337  * Purpose:
   1338  *      Unregister the event callback handler with ESMC stack.
   1339  * Parameters:
   1340  *      unit       - (IN) Unit number.
   1341  *      stack_id   - (IN) Stack identifier index.
   1342  * Returns:
   1343  *      BCM_E_XXX - Function status.
   1344  */
   1345 int
   1346 bcm_common_tdpll_event_callback_unregister(
   1347     int unit,
   1348     int stack_id)
   1349 {
   1350 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
   1351     return bcm_extdpll_event_callback_unregister(unit, stack_id);
   1352 #else
   1353     return BCM_E_UNAVAIL;
   1354 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   1355 }
   1356 
   1357 #endif /* defined(INCLUDE_PTP) */