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

slave_config.c (58253B)


      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:    slave_config.c
      8  *
      9  * Purpose: 
     10  *
     11  * Functions:
     12  *      bcm_common_ptp_static_unicast_slave_add
     13  *      bcm_common_ptp_static_unicast_slave_list
     14  *      bcm_common_ptp_static_unicast_slave_remove
     15  *      bcm_common_ptp_static_unicast_slave_table_clear
     16  *      bcm_common_ptp_acceptable_master_add
     17  *      bcm_common_ptp_acceptable_master_enabled_get
     18  *      bcm_common_ptp_acceptable_master_enabled_set
     19  *      bcm_common_ptp_acceptable_master_list
     20  *      bcm_common_ptp_acceptable_master_remove
     21  *      bcm_common_ptp_acceptable_master_table_clear
     22  *      bcm_common_ptp_acceptable_master_table_size_get
     23  *
     24  *      _bcm_ptp_unicast_slave_table_init
     25  *      _bcm_ptp_unicast_slave_table_detach
     26  *      _bcm_ptp_unicast_slave_table_stack_create
     27  *      _bcm_ptp_unicast_slave_table_clock_create
     28  *      _bcm_ptp_acceptable_master_table_init
     29  *      _bcm_ptp_acceptable_master_table_detach
     30  *      _bcm_ptp_acceptable_master_table_stack_create
     31  *      _bcm_ptp_acceptable_master_table_clock_create
     32  *      _bcm_ptp_unicast_slave_host_reset
     33  *      _bcm_ptp_unicast_slave_stack_restore
     34  *      _bcm_ptp_acceptable_master_table_set
     35  *      _bcm_ptp_add_unicast_slave_announce
     36  *      _bcm_ptp_add_unicast_slave_sync
     37  *      _bcm_ptp_add_unicast_slave_delay_response
     38  *      _bcm_ptp_add_unicast_slave_peer_delay_response
     39  *      _bcm_ptp_remove_unicast_slave_announce
     40  *      _bcm_ptp_remove_unicast_slave_sync
     41  *      _bcm_ptp_remove_unicast_slave_delay_response
     42  *      _bcm_ptp_remove_unicast_slave_peer_delay_response
     43  */
     44 
     45 #if defined(INCLUDE_PTP)
     46 
     47 #include <soc/defs.h>
     48 #include <soc/drv.h>
     49 
     50 #include <bcm/ptp.h>
     51 #include <bcm/error.h>
     52 #include <bcm_int/common/ptp.h>
     53 #include <bcm_int/ptp_common.h>
     54 
     55 /* Per-Clock unicast slave table. */
     56 typedef struct _bcm_ptp_unicast_slave_table_s {
     57     uint16 num_entries;
     58     uint16 max_num_entries; /* PTP_MAX_UNICAST_SLAVE_TABLE_ENTRIES for now */
     59     _bcm_ptp_memstate_t memstate;
     60     _bcm_ptp_clock_peer_ext_t *entry;
     61 } _bcm_ptp_unicast_slave_table_t;
     62 
     63 /* Per-Stack array of the per-clock tables */
     64 typedef struct _bcm_ptp_stack_ucs_array_s {
     65     _bcm_ptp_memstate_t memstate;
     66     _bcm_ptp_unicast_slave_table_t *table;
     67 } _bcm_ptp_stack_ucs_array_t;
     68 
     69 /* Per-Unit array of the per-stack array of per-clock tables */
     70 typedef struct _bcm_ptp_unit_ucs_array_s {
     71     _bcm_ptp_memstate_t memstate;
     72     _bcm_ptp_stack_ucs_array_t *stack_array;
     73 } _bcm_ptp_unit_ucs_array_t;
     74 
     75 /*
     76  * PTP clock acceptable master clock.
     77  * Protocol address and alternate Priority1 for an acceptable master table entry.
     78  * Ref. IEEE Std. 1588-2008, Chapter 17.6.
     79  */
     80 typedef struct _bcm_ptp_acceptable_master_s {
     81     bcm_ptp_clock_peer_address_t address;
     82     uint8 alt_priority1;
     83 } _bcm_ptp_acceptable_master_t;
     84 
     85 /* PTP clock acceptable master table. */
     86 typedef struct _bcm_ptp_acceptable_master_table_s {
     87     uint16 num_entries;
     88     _bcm_ptp_acceptable_master_t entry[PTP_MAX_ACCEPTABLE_MASTER_TABLE_ENTRIES];
     89 } _bcm_ptp_acceptable_master_table_t;
     90 
     91 /* PTP stack acceptable master table array. */
     92 typedef struct _bcm_ptp_stack_amt_array_s {
     93     _bcm_ptp_memstate_t memstate;
     94     _bcm_ptp_acceptable_master_table_t *table;
     95 } _bcm_ptp_stack_amt_array_t;
     96 
     97 /* Unit acceptable master table array(s). */
     98 typedef struct _bcm_ptp_unit_amt_array_s {
     99     _bcm_ptp_memstate_t memstate;
    100     _bcm_ptp_stack_amt_array_t *stack_array;
    101 } _bcm_ptp_unit_amt_array_t;
    102 
    103 static const _bcm_ptp_clock_peer_ext_t ucs_entry_default;
    104 static _bcm_ptp_unit_ucs_array_t unit_ucs_array[BCM_MAX_NUM_UNITS];
    105 
    106 static const _bcm_ptp_acceptable_master_t amt_entry_default;
    107 static const _bcm_ptp_acceptable_master_table_t amt_default;
    108 static _bcm_ptp_unit_amt_array_t unit_amt_array[BCM_MAX_NUM_UNITS];
    109 
    110 static int _bcm_ptp_add_unicast_slave_announce(
    111     int unit,
    112     bcm_ptp_stack_id_t ptp_id,
    113     int clock_num,
    114     uint32 clock_port,
    115     _bcm_ptp_clock_peer_ext_t *slave_info);
    116 
    117 static int _bcm_ptp_add_unicast_slave_sync(
    118     int unit,
    119     bcm_ptp_stack_id_t ptp_id,
    120     int clock_num,
    121     uint32 clock_port,
    122     _bcm_ptp_clock_peer_ext_t *slave_info);
    123 
    124 static int _bcm_ptp_add_unicast_slave_delay_response(
    125     int unit,
    126     bcm_ptp_stack_id_t ptp_id,
    127     int clock_num,
    128     uint32 clock_port,
    129     _bcm_ptp_clock_peer_ext_t *slave_info);
    130 
    131 static int
    132 _bcm_ptp_add_unicast_slave_peer_delay_response(
    133     int unit,
    134     bcm_ptp_stack_id_t ptp_id,
    135     int clock_num,
    136     uint32 clock_port,
    137     _bcm_ptp_clock_peer_ext_t *slave_info);
    138 
    139 static int _bcm_ptp_remove_unicast_slave_announce(
    140     int unit,
    141     bcm_ptp_stack_id_t ptp_id,
    142     int clock_num,
    143     uint32 clock_port,
    144     _bcm_ptp_clock_peer_ext_t *slave_info);
    145 
    146 static int _bcm_ptp_remove_unicast_slave_sync(
    147     int unit,
    148     bcm_ptp_stack_id_t ptp_id,
    149     int clock_num,
    150     uint32 clock_port,
    151     _bcm_ptp_clock_peer_ext_t *slave_info);
    152 
    153 static int _bcm_ptp_remove_unicast_slave_delay_response(
    154     int unit,
    155     bcm_ptp_stack_id_t ptp_id,
    156     int clock_num,
    157     uint32 clock_port,
    158     _bcm_ptp_clock_peer_ext_t *slave_info);
    159 
    160 static int _bcm_ptp_remove_unicast_slave_peer_delay_response(
    161     int unit,
    162     bcm_ptp_stack_id_t ptp_id,
    163     int clock_num,
    164     uint32 clock_port,
    165     _bcm_ptp_clock_peer_ext_t *slave_info);
    166 
    167 static int _bcm_ptp_acceptable_master_table_set(
    168     int unit,
    169     bcm_ptp_stack_id_t ptp_id,
    170     int clock_num);
    171 
    172 /*
    173  * Function:
    174  *      _bcm_ptp_unicast_slave_table_init
    175  * Purpose:
    176  *      Initialize the unicast slave table arrays of a unit.
    177  * Parameters:
    178  *      unit - (IN) Unit number.
    179  * Returns:
    180  *      BCM_E_XXX
    181  * Notes:
    182  */
    183 int
    184 _bcm_ptp_unicast_slave_table_init(
    185     int unit)
    186 {
    187     int rv = BCM_E_UNAVAIL;
    188     int i;
    189     _bcm_ptp_stack_ucs_array_t *stack_p;
    190 
    191     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, PTP_STACK_ID_DEFAULT,
    192             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    193         return rv;
    194     }
    195 
    196     if (unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) {
    197         stack_p = sal_alloc(PTP_MAX_STACKS_PER_UNIT*
    198                             sizeof(_bcm_ptp_stack_ucs_array_t),
    199                             "Unit UCS arrays");
    200 
    201         if (!stack_p) {
    202             unit_ucs_array[unit].memstate = PTP_MEMSTATE_FAILURE;
    203             return BCM_E_MEMORY;
    204         }
    205 
    206         for (i = 0; i < PTP_MAX_STACKS_PER_UNIT; ++i) {
    207             stack_p[i].memstate = PTP_MEMSTATE_STARTUP;
    208         }
    209 
    210         unit_ucs_array[unit].stack_array = stack_p;
    211         unit_ucs_array[unit].memstate = PTP_MEMSTATE_INITIALIZED;
    212     }
    213 
    214     return rv;
    215 }
    216 
    217 /*
    218  * Function:
    219  *      _bcm_ptp_unicast_slave_table_detach
    220  * Purpose:
    221  *      Shut down the unicast slave table arrays of a unit.
    222  * Parameters:
    223  *      unit - (IN) Unit number.
    224  * Returns:
    225  *      BCM_E_XXX
    226  * Notes:
    227  */
    228 int
    229 _bcm_ptp_unicast_slave_table_detach(
    230     int unit)
    231 {
    232     int i;
    233 
    234     if(unit_ucs_array[unit].stack_array) {
    235         for (i = 0; i < PTP_MAX_STACKS_PER_UNIT; ++i) {
    236             _bcm_ptp_unicast_slave_table_stack_destroy(unit, i);
    237         }
    238         unit_ucs_array[unit].memstate = PTP_MEMSTATE_STARTUP;
    239         sal_free(unit_ucs_array[unit].stack_array);
    240         unit_ucs_array[unit].stack_array = NULL;
    241     }
    242     return BCM_E_NONE;
    243 }
    244 
    245 /*
    246  * Function:
    247  *      _bcm_ptp_unicast_slave_table_stack_create
    248  * Purpose:
    249  *      Create the unicast slave table array of a PTP stack.
    250  * Parameters:
    251  *      unit    - (IN) Unit number.
    252  *      ptp_id  - (IN) PTP stack ID.
    253  * Returns:
    254  *      BCM_E_XXX
    255  * Notes:
    256  */
    257 int
    258 _bcm_ptp_unicast_slave_table_stack_create(
    259     int unit,
    260     bcm_ptp_stack_id_t ptp_id)
    261 {
    262     int rv = BCM_E_UNAVAIL;
    263 
    264     _bcm_ptp_unicast_slave_table_t *table_p;
    265     int i = 0;
    266 
    267     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
    268             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    269         return rv;
    270     }
    271 
    272     if (unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) {
    273         return BCM_E_UNAVAIL;
    274     }
    275 
    276     if (unit_ucs_array[unit].stack_array[ptp_id].memstate != PTP_MEMSTATE_INITIALIZED) {
    277         table_p = sal_alloc(PTP_MAX_CLOCK_INSTANCES *
    278                             sizeof(_bcm_ptp_unicast_slave_table_t),
    279                             "PTP stack UCS array");
    280 
    281         if (!table_p) {
    282             unit_ucs_array[unit].stack_array[ptp_id].memstate =
    283                 PTP_MEMSTATE_FAILURE;
    284             return BCM_E_MEMORY;
    285         }
    286 
    287         unit_ucs_array[unit].stack_array[ptp_id].table = table_p;
    288         unit_ucs_array[unit].stack_array[ptp_id].memstate =
    289             PTP_MEMSTATE_INITIALIZED;
    290 
    291         for (i = 0; i < PTP_MAX_CLOCK_INSTANCES; ++i) {
    292             unit_ucs_array[unit].stack_array[ptp_id].table[i].memstate = PTP_MEMSTATE_STARTUP;
    293         }
    294     }
    295 
    296     /* Set number of entries. */
    297     for (i = 0; i < PTP_MAX_CLOCK_INSTANCES; ++i) {
    298         unit_ucs_array[unit].stack_array[ptp_id].table[i].num_entries = 0;
    299     }
    300 
    301     return rv;
    302 }
    303 
    304 /*
    305  * Function:
    306  *      _bcm_ptp_unicast_slave_table_stack_destroy
    307  * Purpose:
    308  *      Destroy the unicast slave table array of a PTP stack.
    309  * Parameters:
    310  *      unit    - (IN) Unit number.
    311  *      ptp_id  - (IN) PTP stack ID.
    312  * Returns:
    313  *      BCM_E_XXX
    314  * Notes:
    315  */
    316 int
    317 _bcm_ptp_unicast_slave_table_stack_destroy(
    318     int unit,
    319     bcm_ptp_stack_id_t ptp_id)
    320 {
    321     int rv = BCM_E_NONE;
    322     int i;
    323 
    324     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
    325             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    326         return rv;
    327     }
    328 
    329     if (unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) {
    330         return BCM_E_UNAVAIL;
    331     }
    332 
    333     if (unit_ucs_array[unit].stack_array[ptp_id].memstate == PTP_MEMSTATE_INITIALIZED) {
    334         for (i = 0; i < PTP_MAX_CLOCK_INSTANCES; ++i) {
    335             _bcm_ptp_unicast_slave_table_clock_destroy(unit, ptp_id, i);
    336         }
    337         unit_ucs_array[unit].stack_array[ptp_id].memstate =
    338             PTP_MEMSTATE_STARTUP;
    339         sal_free(unit_ucs_array[unit].stack_array[ptp_id].table);
    340         unit_ucs_array[unit].stack_array[ptp_id].table = 0;
    341     }
    342 
    343     return rv;
    344 }
    345 
    346 /*
    347  * Function:
    348  *      _bcm_ptp_unicast_slave_table_clock_create
    349  * Purpose:
    350  *      Create the unicast slave table array of a PTP clock.
    351  * Parameters:
    352  *      unit      - (IN) Unit number.
    353  *      ptp_id    - (IN) PTP stack ID.
    354  *      clock_num - (IN) PTP clock number.
    355  * Returns:
    356  *      BCM_E_XXX
    357  * Notes:
    358  */
    359 int
    360 _bcm_ptp_unicast_slave_table_clock_create(
    361     int unit,
    362     bcm_ptp_stack_id_t ptp_id,
    363     int clock_num)
    364 {
    365     int rv = BCM_E_UNAVAIL;
    366 
    367     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    368             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    369         return rv;
    370     }
    371 
    372     if ((unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    373             (unit_ucs_array[unit].stack_array[ptp_id].memstate !=
    374             PTP_MEMSTATE_INITIALIZED)) {
    375         return BCM_E_UNAVAIL;
    376     }
    377 
    378     unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].num_entries = 0;
    379     unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].max_num_entries = PTP_MAX_UNICAST_SLAVE_TABLE_ENTRIES;
    380 
    381     if (unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].memstate == PTP_MEMSTATE_STARTUP) {
    382         unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].entry =
    383             sal_alloc(sizeof(_bcm_ptp_clock_peer_ext_t) * PTP_MAX_UNICAST_SLAVE_TABLE_ENTRIES,
    384                       "PTP Slave Table");
    385 
    386         if (unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].entry) {
    387             unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].memstate = PTP_MEMSTATE_INITIALIZED;
    388         } else {
    389             unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].memstate = PTP_MEMSTATE_FAILURE;
    390             rv = BCM_E_MEMORY;
    391         }
    392     }
    393 
    394     return rv;
    395 }
    396 
    397 /*
    398  * Function:
    399  *      _bcm_ptp_unicast_slave_table_clock_destroy
    400  * Purpose:
    401  *      Destroy the unicast slave table array of a PTP clock.
    402  * Parameters:
    403  *      unit      - (IN) Unit number.
    404  *      ptp_id    - (IN) PTP stack ID.
    405  *      clock_num - (IN) PTP clock number.
    406  * Returns:
    407  *      BCM_E_XXX
    408  * Notes:
    409  */
    410 int
    411 _bcm_ptp_unicast_slave_table_clock_destroy(
    412     int unit,
    413     bcm_ptp_stack_id_t ptp_id,
    414     int clock_num)
    415 {
    416     int rv = BCM_E_NONE;
    417 
    418     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    419             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    420         return rv;
    421     }
    422 
    423     if ((unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    424             (unit_ucs_array[unit].stack_array[ptp_id].memstate !=
    425             PTP_MEMSTATE_INITIALIZED)) {
    426         return BCM_E_UNAVAIL;
    427     }
    428 
    429     unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].num_entries = 0;
    430     unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].max_num_entries = PTP_MAX_UNICAST_SLAVE_TABLE_ENTRIES;
    431 
    432     if (unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].memstate == PTP_MEMSTATE_INITIALIZED) {
    433         unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].memstate = PTP_MEMSTATE_STARTUP;
    434         sal_free(unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].entry);
    435         unit_ucs_array[unit].stack_array[ptp_id].table[clock_num].entry = 0;
    436     }
    437 
    438     return rv;
    439 }
    440 
    441 /*
    442  * Function:
    443  *      _bcm_ptp_acceptable_master_table_init
    444  * Purpose:
    445  *      Initialize the acceptable master table arrays of a unit.
    446  * Parameters:
    447  *      unit - (IN) Unit number.
    448  * Returns:
    449  *      BCM_E_XXX
    450  * Notes:
    451  */
    452 int
    453 _bcm_ptp_acceptable_master_table_init(
    454     int unit)
    455 {
    456     int rv = BCM_E_UNAVAIL;
    457     int i;
    458 
    459     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, PTP_STACK_ID_DEFAULT,
    460             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    461         return rv;
    462     }
    463 
    464     
    465     if (unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) {
    466         unit_amt_array[unit].stack_array = sal_alloc(PTP_MAX_STACKS_PER_UNIT*
    467                                                      sizeof(_bcm_ptp_stack_amt_array_t),
    468                                                      "Unit AMT arrays");
    469 
    470         if (unit_amt_array[unit].stack_array) {
    471             unit_amt_array[unit].memstate = PTP_MEMSTATE_INITIALIZED;
    472             for (i = 0; i < PTP_MAX_STACKS_PER_UNIT; ++i) {
    473                 unit_amt_array[unit].stack_array[i].memstate = PTP_MEMSTATE_STARTUP;
    474             }
    475         } else {
    476             unit_amt_array[unit].memstate = PTP_MEMSTATE_FAILURE;
    477             return BCM_E_MEMORY;
    478         }
    479     }
    480 
    481     return rv;
    482 }
    483 
    484 /*
    485  * Function:
    486  *      _bcm_ptp_acceptable_master_table_detach
    487  * Purpose:
    488  *      Shut down the acceptable master table arrays of a unit.
    489  * Parameters:
    490  *      unit - (IN) Unit number.
    491  * Returns:
    492  *      BCM_E_XXX
    493  * Notes:
    494  */
    495 int
    496 _bcm_ptp_acceptable_master_table_detach(
    497     int unit)
    498 {
    499     int i;
    500 
    501     if(unit_amt_array[unit].stack_array) {
    502         for (i = 0; i < PTP_MAX_STACKS_PER_UNIT; ++i) {
    503             _bcm_ptp_acceptable_master_table_stack_destroy(unit, i);
    504         }
    505         unit_amt_array[unit].memstate = PTP_MEMSTATE_STARTUP;
    506         sal_free(unit_amt_array[unit].stack_array);
    507         unit_amt_array[unit].stack_array = NULL;
    508     }
    509     return BCM_E_NONE;
    510 }
    511 
    512 /*
    513  * Function:
    514  *      _bcm_ptp_acceptable_master_table_stack_create
    515  * Purpose:
    516  *      Create the acceptable master table array of a PTP stack.
    517  * Parameters:
    518  *      unit    - (IN) Unit number.
    519  *      ptp_id  - (IN) PTP stack ID.
    520  * Returns:
    521  *      BCM_E_XXX
    522  * Notes:
    523  */
    524 int
    525 _bcm_ptp_acceptable_master_table_stack_create(
    526     int unit,
    527     bcm_ptp_stack_id_t ptp_id)
    528 {
    529     int rv = BCM_E_UNAVAIL;
    530 
    531     int i = 0;
    532 
    533     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
    534             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    535         return rv;
    536     }
    537 
    538     if (unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED)
    539     {
    540         return BCM_E_UNAVAIL;
    541     }
    542 
    543     if (unit_amt_array[unit].stack_array[ptp_id].memstate != PTP_MEMSTATE_INITIALIZED) {
    544         _bcm_ptp_acceptable_master_table_t *table_p;
    545 
    546         table_p = sal_alloc(PTP_MAX_CLOCK_INSTANCES*
    547                             sizeof(_bcm_ptp_acceptable_master_table_t),
    548                             "PTP stack AMT array");
    549 
    550         if (!table_p) {
    551             unit_amt_array[unit].stack_array[ptp_id].memstate =
    552                 PTP_MEMSTATE_FAILURE;
    553             return BCM_E_MEMORY;
    554         }
    555 
    556         unit_amt_array[unit].stack_array[ptp_id].table = table_p;
    557         unit_amt_array[unit].stack_array[ptp_id].memstate =
    558             PTP_MEMSTATE_INITIALIZED;
    559     }
    560 
    561     /* Set number of entries. */
    562     for (i = 0; i < PTP_MAX_CLOCK_INSTANCES; ++i) {
    563         unit_amt_array[unit].stack_array[ptp_id].table[i].num_entries = 0;
    564     }
    565 
    566     return rv;
    567 }
    568 
    569 /*
    570  * Function:
    571  *      _bcm_ptp_acceptable_master_table_stack_destroy
    572  * Purpose:
    573  *      Destroy the acceptable master table array of a PTP stack.
    574  * Parameters:
    575  *      unit    - (IN) Unit number.
    576  *      ptp_id  - (IN) PTP stack ID.
    577  * Returns:
    578  *      BCM_E_XXX
    579  * Notes:
    580  */
    581 int
    582 _bcm_ptp_acceptable_master_table_stack_destroy(
    583     int unit,
    584     bcm_ptp_stack_id_t ptp_id)
    585 {
    586     int rv = BCM_E_NONE;
    587 
    588     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
    589             PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    590         return rv;
    591     }
    592 
    593     if (unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED)
    594     {
    595         return BCM_E_UNAVAIL;
    596     }
    597 
    598     if (unit_amt_array[unit].stack_array[ptp_id].memstate == PTP_MEMSTATE_INITIALIZED) {
    599         unit_amt_array[unit].stack_array[ptp_id].memstate = PTP_MEMSTATE_STARTUP;
    600         sal_free(unit_amt_array[unit].stack_array[ptp_id].table);
    601         unit_amt_array[unit].stack_array[ptp_id].table = 0;
    602     }
    603 
    604     return rv;
    605 }
    606 
    607 /*
    608  * Function:
    609  *      _bcm_ptp_acceptable_master_table_clock_create
    610  * Purpose:
    611  *      Create the acceptable master table array of a PTP clock.
    612  * Parameters:
    613  *      unit      - (IN) Unit number.
    614  *      ptp_id    - (IN) PTP stack ID.
    615  *      clock_num - (IN) PTP clock number.
    616  * Returns:
    617  *      BCM_E_XXX
    618  * Notes:
    619  */
    620 int
    621 _bcm_ptp_acceptable_master_table_clock_create(
    622     int unit,
    623     bcm_ptp_stack_id_t ptp_id,
    624     int clock_num)
    625 {
    626     int rv = BCM_E_UNAVAIL;
    627 
    628     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    629             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
    630         return rv;
    631     }
    632 
    633     if ((unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    634             (unit_amt_array[unit].stack_array[ptp_id].memstate !=
    635             PTP_MEMSTATE_INITIALIZED)) {
    636         return BCM_E_UNAVAIL;
    637     }
    638 
    639     unit_amt_array[unit].stack_array[ptp_id].table[clock_num] = amt_default;
    640 
    641     return rv;
    642 }
    643 
    644 /*
    645  * Function:
    646  *      bcm_common_ptp_static_unicast_slave_add
    647  * Purpose:
    648  *      Add a unicast slave to a PTP clock port.
    649  * Parameters:
    650  *      unit       - (IN) Unit number.
    651  *      ptp_id     - (IN) PTP stack ID.
    652  *      clock_num  - (IN) PTP clock number.
    653  *      port_num   - (IN) PTP clock port number.
    654  *      slave_info - (IN) Unicast slave information.
    655  * Returns:
    656  *      BCM_E_XXX
    657  * Notes:
    658  */
    659 int
    660 bcm_common_ptp_static_unicast_slave_add(
    661     int unit,
    662     bcm_ptp_stack_id_t ptp_id,
    663     int clock_num,
    664     int port_num,
    665     bcm_ptp_clock_peer_t *slave_info)
    666 {
    667     int rv = BCM_E_UNAVAIL;
    668 
    669     _bcm_ptp_port_state_t portState;
    670     _bcm_ptp_unicast_slave_table_t *unicast_slave_table;
    671     int i = 0;
    672 
    673     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    674             (uint32)port_num))) {
    675         return rv;
    676     }
    677 
    678     if (slave_info == NULL) {
    679         return BCM_E_PARAM;
    680     }
    681 
    682     if ((unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    683             (unit_ucs_array[unit].stack_array[ptp_id].memstate !=
    684             PTP_MEMSTATE_INITIALIZED)) {
    685         return BCM_E_UNAVAIL;
    686     }
    687 
    688     /* Do not add unicast slave if portState is DISABLED. */
    689     if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_port_state_get(unit, ptp_id,
    690             clock_num, port_num, &portState))) {
    691         return rv;
    692     } else if (portState == _bcm_ptp_state_disabled) {
    693         return BCM_E_DISABLED;
    694     }
    695 
    696     unicast_slave_table = &unit_ucs_array[unit].stack_array[ptp_id].table[clock_num];
    697 
    698     i = 0;
    699     while (i < unicast_slave_table->num_entries) {
    700         if ((port_num == unicast_slave_table->entry[i].peer.local_port_number) &&
    701             (_bcm_ptp_peer_address_compare(&slave_info->peer_address,
    702                   &unicast_slave_table->entry[i].peer.peer_address))) {
    703             break;
    704         }
    705         ++i;
    706     }
    707 
    708     if (i >= PTP_MAX_UNICAST_SLAVE_TABLE_ENTRIES) {
    709         return BCM_E_FULL;
    710     }
    711 
    712     if (i == unicast_slave_table->num_entries) {
    713         /* New entry. */
    714         ++unicast_slave_table->num_entries;
    715     } else {
    716         /* Replacement entry. */
    717 
    718         /* Cancel unicast transmission services to slave. */
    719         if (BCM_FAILURE(rv = _bcm_ptp_remove_unicast_slave_announce(
    720                 unit, ptp_id, clock_num, (uint32)port_num,
    721                 &unicast_slave_table->entry[i]))) {
    722             return rv;
    723         }
    724 
    725         if (BCM_FAILURE(rv = _bcm_ptp_remove_unicast_slave_sync(
    726                 unit, ptp_id, clock_num, (uint32)port_num,
    727                 &unicast_slave_table->entry[i]))) {
    728             return rv;
    729         }
    730 
    731         switch (unicast_slave_table->entry[i].peer.delay_mechanism) {
    732         case (bcmPTPDelayMechanismEnd2End):
    733             rv = _bcm_ptp_remove_unicast_slave_delay_response(
    734                     unit, ptp_id, clock_num, (uint32)port_num,
    735                     &unicast_slave_table->entry[i]);
    736             break;
    737 
    738         case (bcmPTPDelayMechanismPeer2Peer):
    739             rv = _bcm_ptp_remove_unicast_slave_peer_delay_response(
    740                     unit, ptp_id, clock_num, (uint32)port_num,
    741                     &unicast_slave_table->entry[i]);
    742             break;
    743 
    744         default:
    745             return BCM_E_UNAVAIL;
    746         }
    747     }
    748 
    749     /* Insert new entry. */
    750     unicast_slave_table->entry[i].peer = *slave_info;
    751     unicast_slave_table->entry[i].local_address =
    752         _bcm_common_ptp_unit_array[unit]
    753         .stack_array[ptp_id]
    754         .clock_array[clock_num]
    755         .port_info[port_num-1]
    756         .port_address;
    757 
    758     /* Request unicast transmission services. */
    759     if (BCM_FAILURE(rv = _bcm_ptp_add_unicast_slave_announce(
    760             unit, ptp_id, clock_num, (uint32)port_num, &unicast_slave_table->entry[i]))) {
    761         return rv;
    762     }
    763 
    764     if (BCM_FAILURE(rv = _bcm_ptp_add_unicast_slave_sync(
    765             unit, ptp_id, clock_num, (uint32)port_num, &unicast_slave_table->entry[i]))) {
    766         return rv;
    767     }
    768 
    769     switch (unicast_slave_table->entry[i].peer.delay_mechanism) {
    770     case (bcmPTPDelayMechanismEnd2End):
    771         rv = _bcm_ptp_add_unicast_slave_delay_response(
    772                 unit, ptp_id, clock_num, (uint32)port_num,
    773                 &unicast_slave_table->entry[i]);
    774         break;
    775 
    776     case (bcmPTPDelayMechanismPeer2Peer):
    777         rv = _bcm_ptp_add_unicast_slave_peer_delay_response(
    778                 unit, ptp_id, clock_num, (uint32)port_num,
    779                 &unicast_slave_table->entry[i]);
    780         break;
    781 
    782     default:
    783         return BCM_E_UNAVAIL;
    784     }
    785 
    786     return rv;
    787 }
    788 
    789 /*
    790  * Function:
    791  *      bcm_common_ptp_static_unicast_slave_list
    792  * Purpose:
    793  *      List the unicast slaves of a PTP clock port.
    794  * Parameters:
    795  *      unit       - (IN) Unit number.
    796  *      ptp_id     - (IN) PTP stack ID.
    797  *      clock_num  - (IN) PTP clock number.
    798  *      port_num   - (IN) PTP clock port number.
    799  *      num_slaves - (OUT) Number of unicast slave table entries.
    800  *      slave_info - (OUT) Unicast slave table.
    801  * Returns:
    802  *      BCM_E_XXX
    803  * Notes:
    804  */
    805 int
    806 bcm_common_ptp_static_unicast_slave_list(
    807     int unit,
    808     bcm_ptp_stack_id_t ptp_id,
    809     int clock_num,
    810     int port_num,
    811     int max_num_slaves,
    812     int *num_slaves,
    813     bcm_ptp_clock_peer_t *slave_info)
    814 {
    815     int rv = BCM_E_NONE;
    816 
    817     _bcm_ptp_unicast_slave_table_t *unicast_slave_table;
    818     int i = 0;
    819 
    820     *num_slaves = 0;
    821 
    822     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    823             (uint32)port_num))) {
    824         return rv;
    825     }
    826 
    827     if ((unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    828             (unit_ucs_array[unit].stack_array[ptp_id].memstate !=
    829             PTP_MEMSTATE_INITIALIZED)) {
    830         return BCM_E_UNAVAIL;
    831     }
    832 
    833     unicast_slave_table = &unit_ucs_array[unit].stack_array[ptp_id].table[clock_num];
    834 
    835     /*
    836      * Get PTP clock unicast slave table.
    837      * NOTICE: Returns a local, SDK copy of unicast slave table.
    838      */
    839 
    840     for (i = 0; i < unicast_slave_table->num_entries; ++i) {
    841         if (unicast_slave_table->entry[i].peer.local_port_number == port_num) {
    842             if (*num_slaves == max_num_slaves) {
    843                 /* No more room */
    844                 *num_slaves = 0;
    845                 return BCM_E_RESOURCE;
    846             }
    847             slave_info[*num_slaves] = unicast_slave_table->entry[i].peer;
    848             ++(*num_slaves);
    849         }
    850     }
    851 
    852     return rv;
    853 }
    854 
    855 /*
    856  * Function:
    857  *      bcm_common_ptp_static_unicast_slave_remove
    858  * Purpose:
    859  *      Remove a unicast slave of a PTP clock port.
    860  * Parameters:
    861  *      unit       - (IN) Unit number.
    862  *      ptp_id     - (IN) PTP stack ID.
    863  *      clock_num  - (IN) PTP clock number.
    864  *      port_num   - (IN) PTP clock port number.
    865  *      slave_info - (IN) Unicast slave information.
    866  * Returns:
    867  *      BCM_E_XXX
    868  * Notes:
    869  */
    870 int
    871 bcm_common_ptp_static_unicast_slave_remove(
    872     int unit,
    873     bcm_ptp_stack_id_t ptp_id,
    874     int clock_num,
    875     int port_num,
    876     bcm_ptp_clock_peer_t *slave_info)
    877 {
    878     int rv = BCM_E_UNAVAIL;
    879 
    880     _bcm_ptp_unicast_slave_table_t *unicast_slave_table;
    881     int i = 0;
    882     int k = 0;
    883 
    884     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    885             (uint32)port_num))) {
    886         return rv;
    887     }
    888 
    889     if (slave_info == NULL) {
    890         return BCM_E_PARAM;
    891     }
    892 
    893     if ((unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
    894             (unit_ucs_array[unit].stack_array[ptp_id].memstate !=
    895             PTP_MEMSTATE_INITIALIZED)) {
    896         return BCM_E_UNAVAIL;
    897     }
    898 
    899     unicast_slave_table = &unit_ucs_array[unit].stack_array[ptp_id].table[clock_num];
    900 
    901     if (unicast_slave_table->num_entries == 0) {
    902         return BCM_E_EMPTY;
    903     }
    904 
    905     i = 0;
    906     k = 0;
    907     while (i < unicast_slave_table->num_entries) {
    908         if ((unicast_slave_table->entry[i].peer.local_port_number == port_num) &&
    909             (_bcm_ptp_peer_address_compare(&slave_info->peer_address,
    910                   &unicast_slave_table->entry[i].peer.peer_address))) {
    911             /*
    912              * Remove entry.
    913              * Cancel unicast transmission services to slave.
    914              */
    915             if (BCM_FAILURE(rv = _bcm_ptp_remove_unicast_slave_announce(
    916                     unit, ptp_id, clock_num, (uint32)port_num,
    917                     &unicast_slave_table->entry[i]))) {
    918                 return rv;
    919             }
    920 
    921             if (BCM_FAILURE(rv = _bcm_ptp_remove_unicast_slave_sync(
    922                     unit, ptp_id, clock_num, (uint32)port_num,
    923                     &unicast_slave_table->entry[i]))) {
    924                 return rv;
    925             }
    926 
    927             switch (unicast_slave_table->entry[i].peer.delay_mechanism) {
    928             case (bcmPTPDelayMechanismEnd2End):
    929                 rv = _bcm_ptp_remove_unicast_slave_delay_response(
    930                         unit, ptp_id, clock_num, (uint32)port_num,
    931                         &unicast_slave_table->entry[i]);
    932                 break;
    933 
    934             case (bcmPTPDelayMechanismPeer2Peer):
    935                 rv = _bcm_ptp_remove_unicast_slave_peer_delay_response(
    936                         unit, ptp_id, clock_num, (uint32)port_num,
    937                         &unicast_slave_table->entry[i]);
    938                 break;
    939 
    940             default:
    941                 return BCM_E_UNAVAIL;
    942             }
    943 
    944             /*
    945              * Remove this entry by moving last entry into this slot, and
    946              * decrementing number of entries.
    947              */
    948             unicast_slave_table->entry[i] =
    949                 unicast_slave_table->entry[--unicast_slave_table->num_entries];
    950 
    951             /* Reset unused entry. */
    952             unicast_slave_table->entry[unicast_slave_table->num_entries] =
    953                 ucs_entry_default;
    954 
    955             ++k;
    956         }
    957         else
    958         {
    959             ++i;
    960         }
    961     }
    962 
    963     if (k <= 0) {
    964         /* No matching peer address(es) in unicast slave table. */
    965         return BCM_E_NOT_FOUND;
    966     }
    967 
    968     return rv;
    969 }
    970 
    971 /*
    972  * Function:
    973  *      bcm_common_ptp_static_unicast_slave_table_clear
    974  * Purpose:
    975  *      Clear (i.e. remove all) unicast slaves of a PTP clock port.
    976  * Parameters:
    977  *      unit      - (IN) Unit number.
    978  *      ptp_id    - (IN) PTP stack ID.
    979  *      clock_num - (IN) PTP clock number.
    980  *      port_num  - (IN) PTP clock port number.
    981  * Returns:
    982  *      BCM_E_XXX
    983  * Notes:
    984  */
    985 int
    986 bcm_common_ptp_static_unicast_slave_table_clear(
    987     int unit,
    988     bcm_ptp_stack_id_t ptp_id,
    989     int clock_num,
    990     int port_num)
    991 {
    992     int rv = BCM_E_UNAVAIL;
    993 
    994     _bcm_ptp_unicast_slave_table_t *unicast_slave_table;
    995 
    996     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
    997             (uint32)port_num))) {
    998         return rv;
    999     }
   1000 
   1001     if ((unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1002             (unit_ucs_array[unit].stack_array[ptp_id].memstate !=
   1003             PTP_MEMSTATE_INITIALIZED)) {
   1004         return BCM_E_UNAVAIL;
   1005     }
   1006 
   1007     unicast_slave_table = &unit_ucs_array[unit].stack_array[ptp_id].table[clock_num];
   1008 
   1009     /*
   1010      * Remove all unicast slaves.
   1011      * NOTICE: Pointer to beginning of unicast slave table causes removal function to
   1012      *         recursively collapse table.
   1013      */
   1014     if (BCM_FAILURE(rv = bcm_common_ptp_static_unicast_slave_remove(unit, ptp_id, clock_num,
   1015             port_num, &unicast_slave_table->entry->peer))) {
   1016         return rv;
   1017     }
   1018 
   1019     return rv;
   1020 }
   1021 
   1022 /*
   1023  * Function:
   1024  *      _bcm_ptp_unicast_slave_host_reset
   1025  * Purpose:
   1026  *      Reset host-maintained table of static unicast slaves.
   1027  * Parameters:
   1028  *      unit      - (IN) Unit number.
   1029  *      ptp_id    - (IN) PTP stack ID.
   1030  *      clock_num - (IN) PTP clock number.
   1031  *      port_num  - (IN) PTP clock port number.
   1032  * Returns:
   1033  *      BCM_E_XXX
   1034  * Notes:
   1035  *      bcm_common_ptp_static_unicast_slave_clear() unregisters unicast services on PTP
   1036  *      stack and resets the host-maintained table of static unicast slaves.
   1037  */
   1038 int
   1039 _bcm_ptp_unicast_slave_host_reset(
   1040     int unit,
   1041     bcm_ptp_stack_id_t ptp_id,
   1042     int clock_num,
   1043     int port_num)
   1044 {
   1045     int rv = BCM_E_UNAVAIL;
   1046 
   1047     _bcm_ptp_unicast_slave_table_t *unicast_slave_table;
   1048     int i;
   1049 
   1050     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
   1051             clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1052         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
   1053         return rv;
   1054     }
   1055 
   1056     if ((unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1057             (unit_ucs_array[unit].stack_array[ptp_id].memstate !=
   1058             PTP_MEMSTATE_INITIALIZED)) {
   1059         return BCM_E_UNAVAIL;
   1060     }
   1061 
   1062     unicast_slave_table = &unit_ucs_array[unit].stack_array[ptp_id].table[clock_num];
   1063     i = 0;
   1064     while (i < unicast_slave_table->num_entries) {
   1065         if (port_num == unicast_slave_table->entry[i].peer.local_port_number ||
   1066             port_num == PTP_IEEE1588_ALL_PORTS) {
   1067             /*
   1068              * Remove this entry by moving last entry into this slot, and
   1069              * decrementing number of entries.
   1070              */
   1071             unicast_slave_table->entry[i] =
   1072                 unicast_slave_table->entry[--unicast_slave_table->num_entries];
   1073 
   1074             /* Reset unused entry. */
   1075             unicast_slave_table->entry[unicast_slave_table->num_entries] =
   1076                 ucs_entry_default;
   1077         } else {
   1078             ++i;
   1079         }
   1080     }
   1081 
   1082     return BCM_E_NONE;
   1083 }
   1084 
   1085 /*
   1086  * Function:
   1087  *      _bcm_ptp_unicast_slave_stack_restore
   1088  * Purpose:
   1089  *      Restore/re-subscribe table of static unicast slaves.
   1090  * Parameters:
   1091  *      unit      - (IN) Unit number.
   1092  *      ptp_id    - (IN) PTP stack ID.
   1093  *      clock_num - (IN) PTP clock number.
   1094  *      port_num  - (IN) PTP clock port number.
   1095  * Returns:
   1096  *      BCM_E_XXX
   1097  * Notes:
   1098  */
   1099 int
   1100 _bcm_ptp_unicast_slave_stack_restore(
   1101     int unit,
   1102     bcm_ptp_stack_id_t ptp_id,
   1103     int clock_num,
   1104     int port_num)
   1105 {
   1106     int rv = BCM_E_UNAVAIL;
   1107 
   1108     _bcm_ptp_unicast_slave_table_t *unicast_slave_table;
   1109     int i;
   1110 
   1111     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id,
   1112             clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1113         PTP_ERROR_FUNC("_bcm_ptp_function_precheck()");
   1114         return rv;
   1115     }
   1116 
   1117     if ((unit_ucs_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1118             (unit_ucs_array[unit].stack_array[ptp_id].memstate !=
   1119             PTP_MEMSTATE_INITIALIZED)) {
   1120         return BCM_E_UNAVAIL;
   1121     }
   1122 
   1123     unicast_slave_table = &unit_ucs_array[unit].stack_array[ptp_id].table[clock_num];
   1124     i = 0;
   1125     while (i < unicast_slave_table->num_entries) {
   1126         if (port_num == unicast_slave_table->entry[i].peer.local_port_number ||
   1127             port_num == PTP_IEEE1588_ALL_PORTS) {
   1128             if (BCM_FAILURE(rv = _bcm_ptp_add_unicast_slave_announce(
   1129                     unit, ptp_id, clock_num,
   1130                     (uint32)unicast_slave_table->entry[i].peer.local_port_number,
   1131                     &unicast_slave_table->entry[i]))) {
   1132                 return rv;
   1133             }
   1134 
   1135             if (BCM_FAILURE(rv = _bcm_ptp_add_unicast_slave_sync(
   1136                     unit, ptp_id, clock_num,
   1137                     (uint32)unicast_slave_table->entry[i].peer.local_port_number,
   1138                     &unicast_slave_table->entry[i]))) {
   1139                 return rv;
   1140             }
   1141 
   1142             switch (unicast_slave_table->entry[i].peer.delay_mechanism) {
   1143             case (bcmPTPDelayMechanismEnd2End):
   1144                 rv = _bcm_ptp_add_unicast_slave_delay_response(
   1145                         unit, ptp_id, clock_num,
   1146                         (uint32)unicast_slave_table->entry[i].peer.local_port_number,
   1147                         &unicast_slave_table->entry[i]);
   1148                 break;
   1149 
   1150             case (bcmPTPDelayMechanismPeer2Peer):
   1151                 rv = _bcm_ptp_add_unicast_slave_peer_delay_response(
   1152                         unit, ptp_id, clock_num,
   1153                         (uint32)unicast_slave_table->entry[i].peer.local_port_number,
   1154                         &unicast_slave_table->entry[i]);
   1155                 break;
   1156 
   1157             default:
   1158                 return BCM_E_PARAM;
   1159             }
   1160         }
   1161         ++i;
   1162     }
   1163 
   1164     return BCM_E_NONE;
   1165 }
   1166 
   1167 /*
   1168  * Function:
   1169  *      bcm_common_ptp_acceptable_master_table_size_get
   1170  * Purpose:
   1171  *      Get maximum number of acceptable master table entries of a PTP clock.
   1172  * Parameters:
   1173  *      unit              - (IN)  Unit number.
   1174  *      ptp_id            - (IN)  PTP stack ID.
   1175  *      clock_num         - (IN)  PTP clock number.
   1176  *      port_num          - (IN)  PTP clock port number.
   1177  *      max_table_entries - (OUT) Maximum number of acceptable master table entries.
   1178  * Returns:
   1179  *      BCM_E_XXX
   1180  * Notes:
   1181  *      Ref. IEEE Std. 1588-2008, Chapter 17.6.4.
   1182  */
   1183 int
   1184 bcm_common_ptp_acceptable_master_table_size_get(
   1185     int unit,
   1186     bcm_ptp_stack_id_t ptp_id,
   1187     int clock_num,
   1188     int port_num,
   1189     int *max_table_entries)
   1190 {
   1191     int rv = BCM_E_UNAVAIL;
   1192 
   1193     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1194     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1195 
   1196     bcm_ptp_port_identity_t portid;
   1197 
   1198     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1199             (uint32)port_num))) {
   1200         return rv;
   1201     }
   1202 
   1203     if ((unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1204             (unit_amt_array[unit].stack_array[ptp_id].memstate !=
   1205             PTP_MEMSTATE_INITIALIZED)) {
   1206         return BCM_E_UNAVAIL;
   1207     }
   1208 
   1209     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, clock_num,
   1210             PTP_IEEE1588_ALL_PORTS, &portid))) {
   1211         return rv;
   1212     }
   1213 
   1214     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1215             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_ACCEPTABLE_MASTER_MAX_TABLE_SIZE,
   1216             0, 0, resp, &resp_len);
   1217 
   1218     if (rv == BCM_E_NONE) {
   1219         /*
   1220          * Parse response.
   1221          * Octet 0...1: Acceptable Master table maximum size.
   1222          */
   1223         *max_table_entries= _bcm_ptp_uint16_read(resp);
   1224     }
   1225 
   1226     return rv;
   1227 }
   1228 
   1229 /*
   1230  * Function:
   1231  *      bcm_common_ptp_acceptable_master_add
   1232  * Purpose:
   1233  *      Add an entry to the acceptable master table of a PTP clock.
   1234  * Parameters:
   1235  *      unit          - (IN) Unit number.
   1236  *      ptp_id        - (IN) PTP stack ID.
   1237  *      clock_num     - (IN) PTP clock number.
   1238  *      port_num      - (IN) PTP clock port number.
   1239  *      alt_priority1 - (IN) Alternate priority1.
   1240  *      master_info   - (IN) Acceptable master address.
   1241  * Returns:
   1242  *      BCM_E_XXX
   1243  * Notes:
   1244  */
   1245 int
   1246 bcm_common_ptp_acceptable_master_add(
   1247     int unit,
   1248     bcm_ptp_stack_id_t ptp_id,
   1249     int clock_num,
   1250     int port_num,
   1251     int alt_priority1,
   1252     bcm_ptp_clock_peer_address_t *master_info)
   1253 {
   1254     int rv = BCM_E_UNAVAIL;
   1255 
   1256     _bcm_ptp_acceptable_master_table_t *acceptable_master_table;
   1257     int i = 0;
   1258 
   1259     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1260             (uint32)port_num))) {
   1261         return rv;
   1262     }
   1263 
   1264     if (master_info == NULL) {
   1265         return BCM_E_PARAM;
   1266     }
   1267 
   1268     if ((unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1269             (unit_amt_array[unit].stack_array[ptp_id].memstate !=
   1270             PTP_MEMSTATE_INITIALIZED)) {
   1271         return BCM_E_UNAVAIL;
   1272     }
   1273 
   1274     acceptable_master_table = &unit_amt_array[unit].stack_array[ptp_id]
   1275                                                    .table[clock_num];
   1276 
   1277     i = 0;
   1278     while (i < acceptable_master_table->num_entries) {
   1279         if (_bcm_ptp_peer_address_compare(master_info,
   1280                 &acceptable_master_table->entry[i].address)) {
   1281             break;
   1282         }
   1283         ++i;
   1284     }
   1285 
   1286     if (i >= PTP_MAX_ACCEPTABLE_MASTER_TABLE_ENTRIES) {
   1287         return BCM_E_FULL;
   1288     }
   1289 
   1290     if (i == acceptable_master_table->num_entries) {
   1291         /* New entry. */
   1292         ++acceptable_master_table->num_entries;
   1293     }
   1294 
   1295     acceptable_master_table->entry[i].address =
   1296         *master_info;
   1297     acceptable_master_table->entry[i].alt_priority1 =
   1298         (uint8)alt_priority1;
   1299 
   1300     /* Update PTP stack firmware acceptable master table. */
   1301     rv = _bcm_ptp_acceptable_master_table_set(unit, ptp_id, clock_num);
   1302 
   1303     return rv;
   1304 }
   1305 
   1306 /*
   1307  * Function:
   1308  *      bcm_common_ptp_acceptable_master_list
   1309  * Purpose:
   1310  *      List the acceptable master table of a PTP clock.
   1311  * Parameters:
   1312  *      unit        - (IN)  Unit number.
   1313  *      ptp_id      - (IN)  PTP stack ID.
   1314  *      clock_num   - (IN)  PTP clock number.
   1315  *      port_num    - (IN)  PTP clock port number.
   1316  *      num_masters - (OUT) Number of acceptable master table entries.
   1317  *      master_info - (OUT) Acceptable master table.
   1318  * Returns:
   1319  *      BCM_E_XXX
   1320  * Notes:
   1321  */
   1322 int
   1323 bcm_common_ptp_acceptable_master_list(
   1324     int unit,
   1325     bcm_ptp_stack_id_t ptp_id,
   1326     int clock_num,
   1327     int port_num,
   1328     int max_num_masters,
   1329     int *num_masters,
   1330     bcm_ptp_clock_peer_address_t *master_info)
   1331 {
   1332     int rv = BCM_E_NONE;
   1333 
   1334     _bcm_ptp_acceptable_master_table_t *acceptable_master_table;
   1335     int i = 0;
   1336 
   1337     *num_masters = 0;
   1338 
   1339     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1340             (uint32)port_num))) {
   1341         return rv;
   1342     }
   1343 
   1344     if ((unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1345             (unit_amt_array[unit].stack_array[ptp_id].memstate !=
   1346             PTP_MEMSTATE_INITIALIZED)) {
   1347         return BCM_E_UNAVAIL;
   1348     }
   1349 
   1350     acceptable_master_table = &unit_amt_array[unit].stack_array[ptp_id]
   1351                                                    .table[clock_num];
   1352 
   1353     if (acceptable_master_table->num_entries == 0) {
   1354         *num_masters = 0;
   1355         return rv;
   1356     }
   1357 
   1358     if (acceptable_master_table->num_entries > max_num_masters) {
   1359         *num_masters = 0;
   1360         return BCM_E_RESOURCE;
   1361     }
   1362 
   1363     /*
   1364      * Get PTP clock acceptable master table.
   1365      * NOTICE: Returns a local, SDK copy of acceptable master table
   1366      *         rather than query PTP stack firmware.
   1367      */
   1368     *num_masters = acceptable_master_table->num_entries;
   1369 
   1370     for (i = 0; i < (*num_masters); ++i) {
   1371         master_info[i] = acceptable_master_table->entry[i].address;
   1372     }
   1373 
   1374     return rv;
   1375 }
   1376 
   1377 /*
   1378  * Function:
   1379  *      bcm_common_ptp_acceptable_master_remove
   1380  * Purpose:
   1381  *      Remove an entry from the acceptable master table of a PTP clock.
   1382  * Parameters:
   1383  *      unit        - (IN) Unit number.
   1384  *      ptp_id      - (IN) PTP stack ID.
   1385  *      clock_num   - (IN) PTP clock number.
   1386  *      port_num    - (IN) PTP clock port number.
   1387  *      master_info - (IN) Acceptable master address.
   1388  * Returns:
   1389  *      BCM_E_XXX
   1390  * Notes:
   1391  */
   1392 int
   1393 bcm_common_ptp_acceptable_master_remove(
   1394     int unit,
   1395     bcm_ptp_stack_id_t ptp_id,
   1396     int clock_num,
   1397     int port_num,
   1398     bcm_ptp_clock_peer_address_t *master_info)
   1399 {
   1400     int rv = BCM_E_UNAVAIL;
   1401 
   1402     _bcm_ptp_acceptable_master_table_t *acceptable_master_table;
   1403     int i = 0;
   1404     int k = 0;
   1405 
   1406     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1407             (uint32)port_num))) {
   1408         return rv;
   1409     }
   1410 
   1411     if (master_info == NULL) {
   1412         return BCM_E_PARAM;
   1413     }
   1414 
   1415     if ((unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1416             (unit_amt_array[unit].stack_array[ptp_id].memstate !=
   1417             PTP_MEMSTATE_INITIALIZED)) {
   1418         return BCM_E_UNAVAIL;
   1419     }
   1420 
   1421     acceptable_master_table = &unit_amt_array[unit].stack_array[ptp_id]
   1422                                                    .table[clock_num];
   1423 
   1424     if (acceptable_master_table->num_entries == 0) {
   1425         return BCM_E_EMPTY;
   1426     }
   1427 
   1428     i = 0;
   1429     k = 0;
   1430     while (i < acceptable_master_table->num_entries) {
   1431         if (_bcm_ptp_peer_address_compare(master_info,
   1432                 &acceptable_master_table->entry[i].address)) {
   1433             /*
   1434              * Remove this entry by moving last entry into this slot, and
   1435              * decrementing number of entries.
   1436              */
   1437             acceptable_master_table->entry[i] =
   1438                 acceptable_master_table->entry[--acceptable_master_table->num_entries];
   1439 
   1440             /* Reset unused entry. */
   1441             acceptable_master_table->entry[acceptable_master_table->num_entries] =
   1442                 amt_entry_default;
   1443 
   1444             ++k;
   1445         }
   1446         else
   1447         {
   1448             ++i;
   1449         }
   1450     }
   1451 
   1452     if (k <= 0) {
   1453         /* No matching peer address(es) in acceptable master table. */
   1454         return BCM_E_NOT_FOUND;
   1455     }
   1456 
   1457     /* Update PTP stack firmware acceptable master table. */
   1458     rv = _bcm_ptp_acceptable_master_table_set(unit, ptp_id, clock_num);
   1459 
   1460     return rv;
   1461 }
   1462 
   1463 /*
   1464  * Function:
   1465  *      bcm_common_ptp_acceptable_master_table_clear
   1466  * Purpose:
   1467  *      Clear (i.e. remove all entries from) the acceptable master table
   1468  *      of a PTP clock.
   1469  * Parameters:
   1470  *      unit      - (IN) Unit number.
   1471  *      ptp_id    - (IN) PTP stack ID.
   1472  *      clock_num - (IN) PTP clock number.
   1473  *      port_num  - (IN) PTP clock port number.
   1474  * Returns:
   1475  *      BCM_E_XXX
   1476  * Notes:
   1477  */
   1478 int
   1479 bcm_common_ptp_acceptable_master_table_clear(
   1480     int unit,
   1481     bcm_ptp_stack_id_t ptp_id,
   1482     int clock_num,
   1483     int port_num)
   1484 {
   1485     int rv = BCM_E_UNAVAIL;
   1486 
   1487     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1488             (uint32)port_num))) {
   1489         return rv;
   1490     }
   1491 
   1492     if ((unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1493             (unit_amt_array[unit].stack_array[ptp_id].memstate !=
   1494             PTP_MEMSTATE_INITIALIZED)) {
   1495         return BCM_E_UNAVAIL;
   1496     }
   1497 
   1498     unit_amt_array[unit].stack_array[ptp_id].table[clock_num] = amt_default;
   1499 
   1500     /* Update PTP stack firmware acceptable master table. */
   1501     rv = _bcm_ptp_acceptable_master_table_set(unit, ptp_id, clock_num);
   1502 
   1503     return rv;
   1504 }
   1505 
   1506 /*
   1507  * Function:
   1508  *      bcm_common_ptp_acceptable_master_enabled_get
   1509  * Purpose:
   1510  *      Get acceptable master table enabled Boolean of a PTP clock port.
   1511  * Parameters:
   1512  *      unit      - (IN)  Unit number.
   1513  *      ptp_id    - (IN)  PTP stack ID.
   1514  *      clock_num - (IN)  PTP clock number.
   1515  *      port_num  - (IN)  PTP clock port number.
   1516  *      enabled   - (OUT) Acceptable master table enabled Boolean.
   1517  * Returns:
   1518  *      BCM_E_XXX
   1519  * Notes:
   1520  *      Ref. IEEE Std. 1588-2008, Chapter 17.6.5.
   1521  */
   1522 int
   1523 bcm_common_ptp_acceptable_master_enabled_get(
   1524     int unit,
   1525     bcm_ptp_stack_id_t ptp_id,
   1526     int clock_num,
   1527     int port_num,
   1528     uint8 *enabled)
   1529 {
   1530     int rv = BCM_E_UNAVAIL;
   1531 
   1532     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1533     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1534 
   1535     bcm_ptp_port_identity_t portid;
   1536 
   1537     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1538             (uint32)port_num))) {
   1539         return rv;
   1540     }
   1541 
   1542     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1543             clock_num, port_num, &portid))) {
   1544         return rv;
   1545     }
   1546 
   1547     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1548             PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_ACCEPTABLE_MASTER_TABLE_ENABLED,
   1549             0, 0, resp, &resp_len);
   1550 
   1551     if (rv == BCM_E_NONE) {
   1552         /*
   1553          * Parse response.
   1554          *    Octet 0 : Acceptable Master table enabled (EN) Boolean.
   1555          *              |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|0|0|0|0|0|EN|.
   1556          *    Octet 1 : Reserved.
   1557          */
   1558         *enabled = (0x01 & resp[0]);
   1559     }
   1560 
   1561     return rv;
   1562 }
   1563 
   1564 /*
   1565  * Function:
   1566  *      bcm_common_ptp_acceptable_master_enabled_set
   1567  * Purpose:
   1568  *      Set acceptable master table enabled Boolean of a PTP clock port.
   1569  * Parameters:
   1570  *      unit      - (IN)  Unit number.
   1571  *      ptp_id    - (IN)  PTP stack ID.
   1572  *      clock_num - (IN)  PTP clock number.
   1573  *      port_num  - (IN)  PTP clock port number.
   1574  *      enabled   - (OUT) Acceptable master table enabled Boolean.
   1575  * Returns:
   1576  *      BCM_E_XXX
   1577  * Notes:
   1578  *      Ref. IEEE Std. 1588-2008, Chapter 17.6.5.
   1579  */
   1580 int
   1581 bcm_common_ptp_acceptable_master_enabled_set(
   1582     int unit,
   1583     bcm_ptp_stack_id_t ptp_id,
   1584     int clock_num,
   1585     int port_num,
   1586     uint8 enabled)
   1587 {
   1588     int rv = BCM_E_UNAVAIL;
   1589 
   1590     uint8 payload[PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS] = {0};
   1591     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1592     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1593 
   1594     bcm_ptp_port_identity_t portid;
   1595 
   1596     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1597             (uint32)port_num))) {
   1598         return rv;
   1599     }
   1600 
   1601     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1602             clock_num, port_num, &portid))) {
   1603         return rv;
   1604     }
   1605 
   1606     /*
   1607      * Make payload.
   1608      *    Octet 0 : Acceptable Master table enabled (EN) Boolean.
   1609      *              |B7|B6|B5|B4|B3|B2|B1|B0| = |0|0|0|0|0|0|0|EN|.
   1610      *    Octet 1 : Reserved.
   1611      */
   1612     payload[0] = (uint8)(1 & enabled);
   1613 
   1614     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1615             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_ACCEPTABLE_MASTER_TABLE_ENABLED,
   1616             payload, PTP_MGMTMSG_PAYLOAD_MIN_SIZE_OCTETS,
   1617             resp, &resp_len);
   1618 
   1619     return rv;
   1620 }
   1621 
   1622 /*
   1623  * Function:
   1624  *      _bcm_ptp_acceptable_master_table_set
   1625  * Purpose:
   1626  *      Set acceptable master table of a PTP clock.
   1627  * Parameters:
   1628  *      unit       - (IN)  Unit number.
   1629  *      ptp_id     - (IN)  PTP stack ID.
   1630  *      clock_num  - (IN)  PTP clock number.
   1631  * Returns:
   1632  *      BCM_E_XXX
   1633  * Notes:
   1634  */
   1635 static int
   1636 _bcm_ptp_acceptable_master_table_set(
   1637     int unit,
   1638     bcm_ptp_stack_id_t ptp_id,
   1639     int clock_num)
   1640 {
   1641     int rv = BCM_E_UNAVAIL;
   1642 
   1643     uint8 payload[PTP_MGMTMSG_PAYLOAD_MAX_ACCEPTABLE_MASTER_TABLE_SIZE_OCTETS] = {0};
   1644     uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS];
   1645     int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS;
   1646 
   1647     _bcm_ptp_acceptable_master_table_t *acceptable_master_table;
   1648     bcm_ptp_port_identity_t portid;
   1649     int i = 0;
   1650     int k = 0;
   1651     int el = 0;
   1652 
   1653     if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num,
   1654             PTP_CLOCK_PORT_NUMBER_DEFAULT))) {
   1655         return rv;
   1656     }
   1657 
   1658     if ((unit_amt_array[unit].memstate != PTP_MEMSTATE_INITIALIZED) ||
   1659             (unit_amt_array[unit].stack_array[ptp_id].memstate !=
   1660             PTP_MEMSTATE_INITIALIZED)) {
   1661         return BCM_E_UNAVAIL;
   1662     }
   1663 
   1664     if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id,
   1665             clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) {
   1666         return rv;
   1667     }
   1668 
   1669     acceptable_master_table = &unit_amt_array[unit].stack_array[ptp_id]
   1670                                                    .table[clock_num];
   1671 
   1672     /*
   1673      * Make payload.
   1674      *    Octet 0...1 : Number of acceptable master table entries.
   1675      *    Octet 2...* : Acceptable master table entries.
   1676      *    CONDITIONAL : PTP management message zero-pad.
   1677      *                  See IEEE Std. 1588-2008 ACCEPTABLE_MASTER_TABLE
   1678      *                  management message payload format reqm'ts.
   1679      */
   1680     i = 0;
   1681     _bcm_ptp_uint16_write(payload, acceptable_master_table->num_entries);
   1682     i += sizeof(uint16);
   1683 
   1684     for (el = 0; el < acceptable_master_table->num_entries; ++el) {
   1685         _bcm_ptp_uint16_write(&payload[i],
   1686             acceptable_master_table->entry[el].address.addr_type);
   1687         i += sizeof(uint16);
   1688 
   1689         switch (acceptable_master_table->entry[el].address.addr_type) {
   1690         case bcmPTPUDPIPv4:
   1691             /* Ethernet/UDP/IPv4 address type. */
   1692             _bcm_ptp_uint16_write(&payload[i], PTP_IPV4_ADDR_SIZE_BYTES);
   1693             i += sizeof(uint16);
   1694             _bcm_ptp_uint32_write(&payload[i],
   1695                 acceptable_master_table->entry[el].address.ipv4_addr);
   1696             i += sizeof(uint32);
   1697 
   1698             break;
   1699 
   1700         case bcmPTPUDPIPv6:
   1701             /* Ethernet/UDP/IPv6 address type. */
   1702             _bcm_ptp_uint16_write(&payload[i], PTP_IPV6_ADDR_SIZE_BYTES);
   1703             i += sizeof(uint16);
   1704 
   1705             for (k = 0; k < PTP_IPV6_ADDR_SIZE_BYTES; ++k) {
   1706                 payload[i++] = acceptable_master_table->entry[el]
   1707                                .address.ipv6_addr[k];
   1708             }
   1709 
   1710             break;
   1711 
   1712         default:
   1713             _bcm_ptp_uint16_write(&payload[i], 0);
   1714             i += sizeof(uint16);
   1715         }
   1716 
   1717         payload[i++]= acceptable_master_table->entry[el].alt_priority1;
   1718 
   1719     }
   1720 
   1721     /*
   1722      * Payload padding.
   1723      * NOTICE: IEEE Std. 1588-2008 ACCEPTABLE_MASTER_TABLE PTP management
   1724      *         message expects even number of octets.
   1725      */
   1726     if (i % 2) {
   1727         payload[i++] = 0x00;
   1728     }
   1729 
   1730     rv = _bcm_ptp_management_message_send(unit, ptp_id, clock_num, &portid,
   1731             PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_ACCEPTABLE_MASTER_TABLE,
   1732             payload, i, resp, &resp_len);
   1733 
   1734     return rv;
   1735 }
   1736 
   1737 /*
   1738  * Function:
   1739  *      _bcm_ptp_add_unicast_slave_announce
   1740  * Purpose:
   1741  *      Request unicast transmission of PTP announce messages.
   1742  * Parameters:
   1743  *      unit       - (IN) Unit number.
   1744  *      ptp_id     - (IN) PTP stack ID.
   1745  *      clock_num  - (IN) PTP clock number.
   1746  *      clock_port - (IN) PTP clock port number.
   1747  *      slave_info - (IN) Unicast slave information.
   1748  * Returns:
   1749  *      BCM_E_XXX
   1750  * Notes:
   1751  */
   1752 static int
   1753 _bcm_ptp_add_unicast_slave_announce(
   1754     int unit,
   1755     bcm_ptp_stack_id_t ptp_id,
   1756     int clock_num,
   1757     uint32 clock_port,
   1758     _bcm_ptp_clock_peer_ext_t *slave_info)
   1759 {
   1760     int rv = BCM_E_UNAVAIL;
   1761 
   1762     rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, clock_num, clock_port,
   1763                 slave_info, bcmPTP_MESSAGE_TYPE_ANNOUNCE,
   1764                 bcmPTPTlvTypeRequestUnicastTransmission,
   1765                 slave_info->peer.log_announce_interval);
   1766 
   1767     return rv;
   1768 }
   1769 
   1770 /*
   1771  * Function:
   1772  *      _bcm_ptp_add_unicast_slave_sync
   1773  * Purpose:
   1774  *      Request unicast transmission of PTP sync messages.
   1775  * Parameters:
   1776  *      unit       - (IN) Unit number.
   1777  *      ptp_id     - (IN) PTP stack ID.
   1778  *      clock_num  - (IN) PTP clock number.
   1779  *      clock_port - (IN) PTP clock port number.
   1780  *      slave_info - (IN) Unicast slave information.
   1781  * Returns:
   1782  *      BCM_E_XXX
   1783  * Notes:
   1784  */
   1785 static int
   1786 _bcm_ptp_add_unicast_slave_sync(
   1787     int unit,
   1788     bcm_ptp_stack_id_t ptp_id,
   1789     int clock_num,
   1790     uint32 clock_port,
   1791     _bcm_ptp_clock_peer_ext_t *slave_info)
   1792 {
   1793     int rv = BCM_E_UNAVAIL;
   1794 
   1795     rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, clock_num, clock_port,
   1796                 slave_info, bcmPTP_MESSAGE_TYPE_SYNC,
   1797                 bcmPTPTlvTypeRequestUnicastTransmission,
   1798                 slave_info->peer.log_sync_interval);
   1799 
   1800     return rv;
   1801 }
   1802 
   1803 /*
   1804  * Function:
   1805  *      _bcm_ptp_add_unicast_slave_delay_response
   1806  * Purpose:
   1807  *      Request unicast transmission of PTP delay response messages.
   1808  * Parameters:
   1809  *      unit       - (IN) Unit number.
   1810  *      ptp_id     - (IN) PTP stack ID.
   1811  *      clock_num  - (IN) PTP clock number.
   1812  *      clock_port - (IN) PTP clock port number.
   1813  *      slave_info - (IN) Unicast slave information.
   1814  * Returns:
   1815  *      BCM_E_XXX
   1816  * Notes:
   1817  */
   1818 static int
   1819 _bcm_ptp_add_unicast_slave_delay_response(
   1820     int unit,
   1821     bcm_ptp_stack_id_t ptp_id,
   1822     int clock_num,
   1823     uint32 clock_port,
   1824     _bcm_ptp_clock_peer_ext_t *slave_info)
   1825 {
   1826     int rv = BCM_E_UNAVAIL;
   1827 
   1828     rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, clock_num, clock_port,
   1829                 slave_info, bcmPTP_MESSAGE_TYPE_DELAY_RESP,
   1830                 bcmPTPTlvTypeRequestUnicastTransmission,
   1831                 slave_info->peer.log_delay_request_interval);
   1832 
   1833     return rv;
   1834 }
   1835 
   1836 /*
   1837  * Function:
   1838  *      _bcm_ptp_add_unicast_slave_peer_delay_response
   1839  * Purpose:
   1840  *      Request unicast transmission of PTP peer delay response messages.
   1841  * Parameters:
   1842  *      unit       - (IN) Unit number.
   1843  *      ptp_id     - (IN) PTP stack ID.
   1844  *      clock_num  - (IN) PTP clock number.
   1845  *      clock_port - (IN) PTP clock port number.
   1846  *      slave_info - (IN) Unicast slave information.
   1847  * Returns:
   1848  *      BCM_E_XXX
   1849  * Notes:
   1850  */
   1851 static int
   1852 _bcm_ptp_add_unicast_slave_peer_delay_response(
   1853     int unit,
   1854     bcm_ptp_stack_id_t ptp_id,
   1855     int clock_num,
   1856     uint32 clock_port,
   1857     _bcm_ptp_clock_peer_ext_t *slave_info)
   1858 {
   1859     int rv = BCM_E_UNAVAIL;
   1860 
   1861     rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, clock_num, clock_port,
   1862                 slave_info, bcmPTP_MESSAGE_TYPE_PDELAY_RESP,
   1863                 bcmPTPTlvTypeRequestUnicastTransmission,
   1864                 slave_info->peer.log_peer_delay_request_interval);
   1865 
   1866     return rv;
   1867 }
   1868 
   1869 /*
   1870  * Function:
   1871  *      _bcm_ptp_remove_unicast_slave_announce
   1872  * Purpose:
   1873  *      Cancel unicast transmission of PTP announce messages.
   1874  * Parameters:
   1875  *      unit       - (IN) Unit number.
   1876  *      ptp_id     - (IN) PTP stack ID.
   1877  *      clock_num  - (IN) PTP clock number.
   1878  *      clock_port - (IN) PTP clock port number.
   1879  *      slave_info - (IN) Unicast slave information.
   1880  * Returns:
   1881  *      BCM_E_XXX
   1882  * Notes:
   1883  */
   1884 static int
   1885 _bcm_ptp_remove_unicast_slave_announce(
   1886     int unit,
   1887     bcm_ptp_stack_id_t ptp_id,
   1888     int clock_num,
   1889     uint32 clock_port,
   1890     _bcm_ptp_clock_peer_ext_t *slave_info)
   1891 {
   1892     int rv = BCM_E_UNAVAIL;
   1893 
   1894     rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, clock_num, clock_port,
   1895                 slave_info, bcmPTP_MESSAGE_TYPE_ANNOUNCE,
   1896                 bcmPTPTlvTypeCancelUnicastTransmission,
   1897                 slave_info->peer.log_announce_interval);
   1898 
   1899     return rv;
   1900 }
   1901 
   1902 /*
   1903  * Function:
   1904  *      _bcm_ptp_remove_unicast_slave_sync
   1905  * Purpose:
   1906  *      Cancel unicast transmission of PTP sync messages.
   1907  * Parameters:
   1908  *      unit       - (IN) Unit number.
   1909  *      ptp_id     - (IN) PTP stack ID.
   1910  *      clock_num  - (IN) PTP clock number.
   1911  *      clock_port - (IN) PTP clock port number.
   1912  *      slave_info - (IN) Unicast slave information.
   1913  * Returns:
   1914  *      BCM_E_XXX
   1915  * Notes:
   1916  */
   1917 static int
   1918 _bcm_ptp_remove_unicast_slave_sync(
   1919     int unit,
   1920     bcm_ptp_stack_id_t ptp_id,
   1921     int clock_num,
   1922     uint32 clock_port,
   1923     _bcm_ptp_clock_peer_ext_t *slave_info)
   1924 {
   1925     int rv = BCM_E_UNAVAIL;
   1926 
   1927     rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, clock_num, clock_port,
   1928                 slave_info, bcmPTP_MESSAGE_TYPE_SYNC,
   1929                 bcmPTPTlvTypeCancelUnicastTransmission,
   1930                 slave_info->peer.log_sync_interval);
   1931 
   1932     return rv;
   1933 }
   1934 
   1935 /*
   1936  * Function:
   1937  *      _bcm_ptp_remove_unicast_slave_delay_response
   1938  * Purpose:
   1939  *      Cancel unicast transmission of PTP delay response messages.
   1940  * Parameters:
   1941  *      unit       - (IN) Unit number.
   1942  *      ptp_id     - (IN) PTP stack ID.
   1943  *      clock_num  - (IN) PTP clock number.
   1944  *      clock_port - (IN) PTP clock port number.
   1945  *      slave_info - (IN) Unicast slave information.
   1946  * Returns:
   1947  *      BCM_E_XXX
   1948  * Notes:
   1949  */
   1950 static int
   1951 _bcm_ptp_remove_unicast_slave_delay_response(
   1952     int unit,
   1953     bcm_ptp_stack_id_t ptp_id,
   1954     int clock_num,
   1955     uint32 clock_port,
   1956     _bcm_ptp_clock_peer_ext_t *slave_info)
   1957 {
   1958     int rv = BCM_E_UNAVAIL;
   1959 
   1960     rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, clock_num, clock_port,
   1961                 slave_info, bcmPTP_MESSAGE_TYPE_DELAY_RESP,
   1962                 bcmPTPTlvTypeCancelUnicastTransmission,
   1963                 slave_info->peer.log_delay_request_interval);
   1964 
   1965     return rv;
   1966 }
   1967 
   1968 /*
   1969  * Function:
   1970  *      _bcm_ptp_remove_unicast_slave_peer_delay_response
   1971  * Purpose:
   1972  *      Cancel unicast transmission of PTP peer delay response messages.
   1973  * Parameters:
   1974  *      unit       - (IN) Unit number.
   1975  *      ptp_id     - (IN) PTP stack ID.
   1976  *      clock_num  - (IN) PTP clock number.
   1977  *      clock_port - (IN) PTP clock port number.
   1978  *      slave_info - (IN) Unicast slave information.
   1979  * Returns:
   1980  *      BCM_E_XXX
   1981  * Notes:
   1982  */
   1983 static int
   1984 _bcm_ptp_remove_unicast_slave_peer_delay_response(
   1985     int unit,
   1986     bcm_ptp_stack_id_t ptp_id,
   1987     int clock_num,
   1988     uint32 clock_port,
   1989     _bcm_ptp_clock_peer_ext_t *slave_info)
   1990 {
   1991     int rv = BCM_E_UNAVAIL;
   1992 
   1993     rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, clock_num, clock_port,
   1994                 slave_info, bcmPTP_MESSAGE_TYPE_PDELAY_RESP,
   1995                 bcmPTPTlvTypeCancelUnicastTransmission,
   1996                 slave_info->peer.log_peer_delay_request_interval);
   1997 
   1998     return rv;
   1999 }
   2000 #endif /* defined(INCLUDE_PTP)*/