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

util.c (20775B)


      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:    util.c
      8  *
      9  * Purpose: 
     10  *
     11  * Functions:
     12  *      _bcm_ptp_uint16_read
     13  *      _bcm_ptp_uint32_read
     14  *      _bcm_ptp_uint64_read
     15  *      _bcm_ptp_uint16_write
     16  *      _bcm_ptp_uint32_write
     17  *      _bcm_ptp_uint64_write
     18  *      _bcm_ptp_int64_read
     19  *      _bcm_ptp_function_precheck
     20  *      _bcm_ptp_clock_lookup
     21  *      _bcm_ptp_peer_address_convert
     22  *      _bcm_ptp_port_address_convert
     23  *      _bcm_ptp_peer_address_raw_compare
     24  *      _bcm_ptp_peer_address_compare
     25  *      _bcm_ptp_port_address_compare
     26  *      _bcm_ptp_addr_len
     27  *      _bcm_ptp_is_clockid_null
     28  *      _bcm_ptp_port_address_cmp
     29  *      _bcm_ptp_dump_hex
     30  */
     31 
     32 #if defined(INCLUDE_PTP)
     33 
     34 #include <shared/bsl.h>
     35 
     36 #include <soc/defs.h>
     37 #include <soc/drv.h>
     38 #include <shared/bsl.h>
     39 #include <sal/core/time.h>
     40 #include <sal/core/dpc.h>
     41 #include <shared/bsl.h>
     42 #include <bcm/ptp.h>
     43 #include <bcm_int/common/ptp.h>
     44 #include <bcm/error.h>
     45 
     46 #if defined(BCM_PTP_INTERNAL_STACK_SUPPORT)
     47 #ifdef NO_SAL_APPL
     48 #include <string.h>
     49 #else
     50 #include <sal/appl/sal.h>
     51 #endif
     52 #include <include/soc/uc.h>
     53 #endif /* BCM_PTP_INTERNAL_STACK_SUPPORT */
     54 #include <bcm_int/control.h>
     55 
     56 #define PTP_UTIL_HEXDUMP_LINE_WIDTH_OCTETS                            (100)
     57 
     58 
     59 static const bcm_ptp_clock_identity_t BCM_PTP_ALL_CLOCKS = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
     60 
     61 /*
     62  * Function:
     63  *      _bcm_ptp_uint16_read
     64  * Purpose:
     65  *      Read a 16-bit unsigned integer from a buffer in network byte order.
     66  * Parameters:
     67  *      buffer - (IN) Data buffer.
     68  * Returns:
     69  *      Result.
     70  * Notes:
     71  */
     72 uint16 
     73 _bcm_ptp_uint16_read(
     74         uint8* buffer)
     75 {   
     76     return ((((uint16)(buffer[0])) << 8) + (((uint16)(buffer[1]))));
     77 }
     78 
     79 /*
     80  * Function:
     81  *      _bcm_ptp_uint32_read
     82  * Purpose:
     83  *      Read a 32-bit unsigned integer from a buffer in network byte order.
     84  * Parameters:
     85  *      buffer - (IN) Data buffer.
     86  * Returns:
     87  *      Result.
     88  * Notes:
     89  */
     90 uint32 
     91 _bcm_ptp_uint32_read(
     92     uint8* buffer)
     93 {
     94     return ((((uint32)(buffer[0])) << 24) + 
     95             (((uint32)(buffer[1])) << 16) +
     96             (((uint32)(buffer[2])) << 8)  +
     97             (((uint32)(buffer[3]))));
     98 }
     99 
    100 /*
    101  * Function:
    102  *      _bcm_ptp_uint64_read
    103  * Purpose:
    104  *      Read a 64-bit unsigned integer from a buffer in network byte order.
    105  * Parameters:
    106  *      buffer - (IN) Data buffer.
    107  * Returns:
    108  *      Result.
    109  * Notes:
    110  */
    111 uint64 
    112 _bcm_ptp_uint64_read(uint8* buffer)
    113 {
    114     uint64 val64;
    115 
    116     COMPILER_64_SET(val64,
    117              (buffer[0] << 24) + (buffer[1] << 16) +
    118              (buffer[2] << 8)  + buffer[3],
    119              (buffer[4] << 24) + (buffer[5] << 16) + 
    120              (buffer[6] << 8)  + buffer[7]);
    121     return val64;
    122 }
    123 
    124 /*
    125  * Function:
    126  *      _bcm_ptp_uint16_write
    127  * Purpose:
    128  *      Write a 16-bit unsigned integer to a buffer in network byte order.
    129  * Parameters:
    130  *      value  - (IN)  Data.
    131  *      buffer - (OUT) Data buffer.
    132  * Returns:
    133  *      None.
    134  * Notes:
    135  */
    136 void 
    137 _bcm_ptp_uint16_write(
    138     uint8* buffer, 
    139     const uint16 value)
    140 {
    141     buffer[0] = ((value >> 8) & 0xff);
    142     buffer[1] = ((value) & 0xff);
    143 }
    144 
    145 /*
    146  * Function:
    147  *      _bcm_ptp_uint32_write
    148  * Purpose:
    149  *      Write a 32-bit unsigned integer to a buffer in network byte order.
    150  * Parameters:
    151  *      value  - (IN)  Data.
    152  *      buffer - (OUT) Data buffer.
    153  * Returns:
    154  *      None.
    155  * Notes:
    156  */
    157 void
    158 _bcm_ptp_uint32_write(
    159     uint8* buffer, 
    160     const uint32 value)
    161 {
    162     buffer[0] = ((value >> 24) & 0xff);
    163     buffer[1] = ((value >> 16) & 0xff);
    164     buffer[2] = ((value >> 8) & 0xff);
    165     buffer[3] = ((value) & 0xff);
    166 }
    167 
    168 /*
    169  * Function:
    170  *      _bcm_ptp_uint64_write
    171  * Purpose:
    172  *      Write a 64-bit unsigned integer to a buffer in network byte order.
    173  * Parameters:
    174  *      value  - (IN)  Data.
    175  *      buffer - (OUT) Data buffer.
    176  * Returns:
    177  *      None.
    178  * Notes:
    179  */
    180 void 
    181 _bcm_ptp_uint64_write(
    182     uint8* buffer, 
    183     const uint64 value)
    184 {
    185     uint32 low;
    186     uint32 high;
    187 
    188     COMPILER_64_TO_32_LO(low,value);
    189     COMPILER_64_TO_32_HI(high,value);
    190 
    191     buffer[0] = ((high >> 24) & 0xff);
    192     buffer[1] = ((high >> 16) & 0xff);
    193     buffer[2] = ((high >> 8) & 0xff);
    194     buffer[3] = ((high) & 0xff);
    195     buffer[4] = ((low >> 24) & 0xff);
    196     buffer[5] = ((low >> 16) & 0xff);
    197     buffer[6] = ((low >> 8) & 0xff);
    198     buffer[7] = ((low) & 0xff);
    199 }
    200 
    201 /*
    202  * Function:
    203  *      _bcm_ptp_int64_write
    204  * Purpose:
    205  *      Write a 64-bit signed integer to a buffer in network byte order.
    206  * Parameters:
    207  *      value  - (IN)  Data.
    208  *      buffer - (OUT) Data buffer.
    209  * Returns:
    210  *      None.
    211  * Notes:
    212  *      Casting to and from int64_t is not available on some platforms
    213  */
    214 void
    215 _bcm_ptp_int64_write(
    216     uint8* buffer,
    217     const int64 value)
    218 {
    219     buffer[0] = (COMPILER_64_HI(value) >> 24) & 0xff;
    220     buffer[1] = (COMPILER_64_HI(value) >> 16) & 0xff;
    221     buffer[2] = (COMPILER_64_HI(value) >> 8) & 0xff;
    222     buffer[3] = (COMPILER_64_HI(value) & 0xff);
    223     buffer[4] = (COMPILER_64_LO(value) >> 24) & 0xff;
    224     buffer[5] = (COMPILER_64_LO(value) >> 16) & 0xff;
    225     buffer[6] = (COMPILER_64_LO(value) >> 8) & 0xff;
    226     buffer[7] = (COMPILER_64_LO(value) & 0xff);
    227 }
    228 
    229 
    230 /*
    231  * Function:
    232  *      _bcm_ptp_int64_read
    233  * Purpose:
    234  *      Read a 64-bit signed integer from a buffer in network byte order.
    235  * Parameters:
    236  *      buffer - (IN) Data buffer.
    237  * Returns:
    238  *      Result.
    239  * Notes:
    240  *      Casting to and from int64_t is not available on some platforms
    241  */
    242 int64
    243 _bcm_ptp_int64_read(uint8* buffer)
    244 {
    245     int64 val;
    246     int64 temp;
    247 
    248     COMPILER_64_SET(temp, buffer[0] << 24, 0);
    249     val = temp;
    250     COMPILER_64_SET(temp, buffer[1] << 16, 0);
    251     COMPILER_64_ADD_64(val, temp);
    252     COMPILER_64_SET(temp, buffer[2] << 8, 0);
    253     COMPILER_64_ADD_64(val, temp);
    254     COMPILER_64_SET(temp, buffer[3], 0);
    255     COMPILER_64_ADD_64(val, temp);
    256     COMPILER_64_SET(temp, 0, buffer[4] << 24);
    257     COMPILER_64_ADD_64(val, temp);
    258     COMPILER_64_SET(temp, 0, buffer[5] << 16);
    259     COMPILER_64_ADD_64(val, temp);
    260     COMPILER_64_SET(temp, 0, buffer[6] << 8);
    261     COMPILER_64_ADD_64(val, temp);
    262     COMPILER_64_SET(temp, 0, buffer[7]);
    263     COMPILER_64_ADD_64(val, temp);
    264 
    265     return val;
    266 }
    267 
    268 
    269 /*
    270  * Function:
    271  *      _bcm_ptp_function_precheck
    272  * Purpose:
    273  *      Perform basic argument and PTP module prechecks on a function.
    274  * Parameters:
    275  *      unit       - (IN) Unit number.
    276  *      ptp_id     - (IN) PTP stack ID.
    277  *      clock_num  - (IN) PTP clock number.
    278  *      clock_port - (IN) PTP clock port number.
    279  * Returns:
    280  *      BCM_E_XXX
    281  * Notes:
    282  */
    283 int 
    284 _bcm_ptp_function_precheck(
    285     int unit, 
    286     bcm_ptp_stack_id_t ptp_id, 
    287     int clock_num, 
    288     uint32 clock_port)
    289 {
    290     int rv = BCM_E_UNAVAIL;
    291    
    292     _bcm_ptp_info_t *ptp_info_p;
    293     bcm_ptp_clock_info_t ci;    
    294  
    295     if ((unit < PTP_UNIT_NUMBER_DEFAULT) ||
    296         (unit >= BCM_MAX_NUM_UNITS)) {
    297         return BCM_E_PARAM;
    298     }
    299     
    300     if (soc_feature(unit, soc_feature_ptp)) {                
    301         SET_PTP_INFO;
    302      
    303         if (ptp_info_p->memstate != PTP_MEMSTATE_INITIALIZED) {
    304             return BCM_E_UNAVAIL;
    305         }
    306         
    307         /* Argument checking and error handling. */
    308         if ((ptp_id < PTP_STACK_ID_DEFAULT) ||
    309             (ptp_id >= PTP_MAX_STACKS_PER_UNIT) ||
    310             (clock_num < PTP_CLOCK_NUMBER_DEFAULT) ||
    311             (clock_num >= PTP_MAX_CLOCK_INSTANCES)) {
    312             return BCM_E_PARAM;
    313         }
    314         
    315         if ((clock_port == PTP_IEEE1588_ALL_PORTS) ||
    316                 (clock_port == PTP_CLOCK_PORT_NUMBER_DEFAULT)) {
    317             return BCM_E_NONE;
    318         } else {
    319             if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_info_get(unit, ptp_id, 
    320                     clock_num, &ci))) {
    321                 return rv;
    322             }
    323 
    324             if ((clock_port < PTP_CLOCK_PORT_NUMBER_DEFAULT) || 
    325                     (clock_port > ci.num_ports)) {
    326                 return BCM_E_PORT; 
    327             }
    328 
    329             switch (ci.type) {
    330             case bcmPTPClockTypeOrdinary:
    331             case bcmPTPClockTypeBoundary:
    332             case bcmPTPClockTypeTransparent:
    333                 break;
    334             default:
    335                 return BCM_E_PARAM;
    336             }
    337         }
    338         
    339     }
    340     
    341     return rv;
    342 }
    343 
    344 /*
    345  * Function:
    346  *      _bcm_ptp_clock_lookup
    347  * Purpose:
    348  *      Lookup the PTP clock number of a PTP clock for a given unit / PTP stack ID
    349  *      based on caller-provided clock identity.
    350  * Parameters:
    351  *      clock_identity - (IN)  PTP clock identity to lookup.
    352  *      unit           - (IN) Unit number.
    353  *      ptp_id         - (IN) PTP stack ID.
    354  *      clock_num      - (OUT) PTP clock number.
    355  * Returns:
    356  *      BCM_E_XXX
    357  * Notes:
    358  */
    359 int _bcm_ptp_clock_lookup(
    360     const bcm_ptp_clock_identity_t clock_identity,
    361     int unit,
    362     bcm_ptp_stack_id_t ptp_id,
    363     int *clock_num)
    364 {
    365     bcm_ptp_clock_info_t ci;
    366     int i;
    367     
    368     /* Affiliate "all-clocks" clockIdentity with default stack, unit, and clock number. */
    369     if (!memcmp(BCM_PTP_ALL_CLOCKS, clock_identity, sizeof(bcm_ptp_clock_identity_t))) {
    370         /* this should only match if the unit/ptp_id match the defaults */
    371         if (unit == PTP_UNIT_NUMBER_DEFAULT && ptp_id == PTP_STACK_ID_DEFAULT) {
    372             *clock_num = PTP_CLOCK_NUMBER_DEFAULT;
    373             return BCM_E_NONE;
    374         } else {
    375             return BCM_E_NOT_FOUND;
    376         }
    377     }
    378             
    379     if (!BCM_UNIT_VALID(unit)) {
    380         return BCM_E_NOT_FOUND;
    381     }
    382 
    383     if ((unit < PTP_UNIT_NUMBER_DEFAULT) ||
    384         (unit >= BCM_MAX_NUM_UNITS))
    385     {
    386        return BCM_E_PARAM;
    387     }
    388 
    389     for (i = PTP_CLOCK_NUMBER_DEFAULT; i < PTP_MAX_CLOCK_INSTANCES; ++i) {
    390         if (BCM_FAILURE(_bcm_ptp_clock_cache_info_get(unit, ptp_id, i, &ci))) {
    391             continue;
    392         }
    393 
    394         if (!memcmp(ci.clock_identity, clock_identity, sizeof(bcm_ptp_clock_identity_t))) {
    395             *clock_num = i;
    396             return BCM_E_NONE;
    397         }
    398     }
    399 
    400     return BCM_E_NOT_FOUND;
    401 }
    402 
    403 /* Function:
    404  *      _bcm_ptp_peer_address_convert
    405  * Purpose:
    406  *      Convert address from peer format to clock-port format.
    407  * Parameters:
    408  *      peer_addr - (IN)  Address (peer format).
    409  *      port_addr - (OUT) Address (clock-port format).
    410  * Returns:
    411  *      BCM_E_XXX - Function status.
    412  * Notes:
    413  */
    414 int
    415 _bcm_ptp_peer_address_convert(
    416     bcm_ptp_clock_peer_address_t *peer_addr,
    417     bcm_ptp_clock_port_address_t *port_addr)
    418 {
    419     port_addr->addr_type = peer_addr->addr_type;
    420 
    421     memset(port_addr->address, 0, BCM_PTP_MAX_NETW_ADDR_SIZE);
    422     switch (peer_addr->addr_type) {
    423     case bcmPTPUDPIPv4:
    424         _bcm_ptp_uint32_write(port_addr->address, peer_addr->ipv4_addr);
    425         break;
    426 
    427     case bcmPTPUDPIPv6:
    428         memcpy(port_addr->address, peer_addr->ipv6_addr, PTP_IPV6_ADDR_SIZE_BYTES);
    429         break;
    430 
    431     default:
    432         return BCM_E_PARAM;
    433 
    434     }
    435 
    436     return BCM_E_NONE;
    437 }
    438 
    439 /*
    440  * Function:
    441  *      _bcm_ptp_port_address_convert
    442  * Purpose:
    443  *      Convert address from clock-port format to peer format.
    444  * Parameters:
    445  *      port_addr - (IN)  Address (clock-port format).
    446  *      peer_addr - (OUT) Address (peer format).
    447  * Returns:
    448  *      BCM_E_XXX - Function status.
    449  * Notes:
    450  */
    451 int
    452 _bcm_ptp_port_address_convert(
    453      bcm_ptp_clock_port_address_t *port_addr,
    454      bcm_ptp_clock_peer_address_t *peer_addr)
    455 {
    456     peer_addr->addr_type = port_addr->addr_type;
    457 
    458     switch (port_addr->addr_type) {
    459     case bcmPTPUDPIPv4:
    460         peer_addr->ipv4_addr = _bcm_ptp_uint32_read(port_addr->address);
    461         break;
    462 
    463     case bcmPTPUDPIPv6:
    464         memcpy(peer_addr->ipv6_addr, port_addr->address, PTP_IPV6_ADDR_SIZE_BYTES);
    465         break;
    466 
    467     default:
    468         return BCM_E_PARAM;
    469 
    470     }
    471 
    472     return BCM_E_NONE;
    473 }
    474 
    475 /*
    476  * Function:
    477  *      _bcm_ptp_peer_address_raw_compare
    478  * Purpose:
    479  *      Compare addresses.
    480  *      Address "A" is a peer-address type.
    481  *      Address "B" is a raw multi-octet buffer.
    482  * Parameters:
    483  *      a        - (IN) Address "A".
    484  *      b        - (IN) Address "B".
    485  *      protocol - (IN) Address "B" network protocol.
    486  * Returns:
    487  *      0: Addresses do not match.
    488  *      1: Addresses match.
    489  * Notes:
    490  */
    491 int 
    492 _bcm_ptp_peer_address_raw_compare(
    493     const bcm_ptp_clock_peer_address_t *a,
    494     uint8 *b,
    495     bcm_ptp_protocol_t protocol)
    496 {
    497     if (a->addr_type != protocol) {
    498         return 0;
    499     }
    500 
    501     switch (protocol) {
    502     case bcmPTPUDPIPv4:
    503         return (a->ipv4_addr == _bcm_ptp_uint32_read(b));
    504     case bcmPTPUDPIPv6:
    505         return !memcmp(a->ipv6_addr, b, PTP_IPV6_ADDR_SIZE_BYTES);
    506     default:
    507         return 0;
    508     }
    509 }
    510 
    511 /*
    512  * Function:
    513  *      _bcm_ptp_peer_address_compare
    514  * Purpose:
    515  *      Compare addresses.
    516  * Parameters:
    517  *      a - (IN) Address "A".
    518  *      b - (IN) Address "B".
    519  * Returns:
    520  *      0: Addresses do not match.
    521  *      1: Addresses match.
    522  * Notes:
    523  */
    524 int 
    525 _bcm_ptp_peer_address_compare(
    526     const bcm_ptp_clock_peer_address_t *a, 
    527     const bcm_ptp_clock_peer_address_t *b) 
    528 {
    529     if (a->addr_type != b->addr_type) {
    530         return 0;
    531     }
    532 
    533     switch (a->addr_type) {
    534     case bcmPTPUDPIPv4:
    535         return (a->ipv4_addr == b->ipv4_addr);
    536     case bcmPTPUDPIPv6:
    537         return !memcmp(a->ipv6_addr, b->ipv6_addr, PTP_IPV6_ADDR_SIZE_BYTES);
    538     default:
    539         return 0;
    540     }
    541 }
    542 
    543 /*
    544  * Function:
    545  *      _bcm_ptp_peer_portid_compare
    546  * Purpose:
    547  *      Compare port Identity.
    548  * Parameters:
    549  *      a - (IN) ClockId "A".
    550  *      b - (IN) ClockId "B".
    551  * Returns:
    552  *      0: Not match.
    553  *      1: Match.
    554  * Notes:
    555  */
    556 int
    557 _bcm_ptp_peer_portid_compare(
    558     const bcm_ptp_port_identity_t *a,
    559     const bcm_ptp_port_identity_t *b)
    560 {
    561 
    562 /*
    563     LOG_VERBOSE(BSL_LS_BCM_PTP,
    564             (BSL_META_U(0, " PortId_A[%0x %0x %0x %0x %0x %0x %0x %0x : %d] PortId_B[%0x %0x %0x %0x %0x %0x %0x %0x : %d] \n"),
    565 							 a->clock_identity[0],a->clock_identity[1],a->clock_identity[2],
    566 							 a->clock_identity[3],a->clock_identity[4],a->clock_identity[5],
    567                              a->clock_identity[6],a->clock_identity[7],
    568 							 a->port_number,
    569 							 b->clock_identity[0],b->clock_identity[1],b->clock_identity[2],
    570 							 b->clock_identity[3],b->clock_identity[4],b->clock_identity[5],
    571                              b->clock_identity[6],b->clock_identity[7],
    572 							 b->port_number));
    573 */
    574 
    575     if (a->port_number != b->port_number) {
    576         return 0;
    577     }
    578 
    579     return !memcmp(a->clock_identity, b->clock_identity, sizeof(bcm_ptp_clock_identity_t));
    580 }
    581 
    582 /*
    583  * Function:
    584  *      _bcm_ptp_port_address_compare
    585  * Purpose:
    586  *      Compare addresses (clock-port address format).
    587  * Parameters:
    588  *      a - (IN) Address "A".
    589  *      b - (IN) Address "B".
    590  * Returns:
    591  *      0: Addresses do not match.
    592  *      1: Addresses match.
    593  * Notes:
    594  */
    595 int
    596 _bcm_ptp_port_address_compare(
    597      const bcm_ptp_clock_port_address_t *a,
    598      const bcm_ptp_clock_port_address_t *b)
    599 {
    600     if (a->addr_type != b->addr_type) {
    601         return 0;
    602     }
    603 
    604     return !memcmp(a->address, b->address, _bcm_ptp_addr_len((int)a->addr_type));
    605 }
    606 
    607 /*
    608  * Function:
    609  *      _bcm_ptp_addr_len
    610  * Purpose:
    611  *      Determine address length.
    612  * Parameters:
    613  *      addr_type - (IN) Address Type
    614  * Returns:
    615  *      0               : Invalid Address Type.
    616  *      Address Length  : Valid Address Type
    617  *      
    618  * Notes:
    619  */
    620 int _bcm_ptp_addr_len(int addr_type) {
    621     switch (addr_type) {
    622     case bcmPTPUDPIPv4:
    623         return PTP_IPV4_ADDR_SIZE_BYTES;
    624     case bcmPTPUDPIPv6:
    625         return PTP_IPV6_ADDR_SIZE_BYTES;
    626     case bcmPTPIEEE8023:
    627         return 6;
    628     default:
    629         return 0;
    630     }
    631 }
    632 
    633 /*
    634  * Function:
    635  *      _bcm_ptp_is_clock_id_null
    636  * Purpose:
    637  *      Check if PTP clock identity is all zeros.
    638  * Parameters:
    639  *      clockID - (IN) PTP Clock Identity.
    640  * Returns:
    641  *      0: Clock Identity is not NULL 
    642  *      1: Clock Identity is NULL
    643  * Notes:
    644  */
    645 int _bcm_ptp_is_clockid_null(bcm_ptp_clock_identity_t clockID)
    646 {
    647     int i;
    648     for (i = 0; i < BCM_PTP_CLOCK_EUID_IEEE1588_SIZE; ++i) {
    649         if (clockID[i] != 0) {
    650             return 0;
    651         }
    652     }
    653     return 1;
    654 }
    655 
    656 /*
    657  * Function:
    658  *      _bcm_ptp_port_address_cmp
    659  * Purpose:
    660  *      Compare addresses.
    661  * Parameters:
    662  *      a - (IN) Address "A".
    663  *      b - (IN) Address "B".
    664  * Returns:
    665  *      0: Addresses match.
    666  *      Nonzero: Addresses do not match.
    667  * Notes:
    668  */
    669 int _bcm_ptp_port_address_cmp(bcm_ptp_clock_port_address_t *a, bcm_ptp_clock_port_address_t *b)
    670 {
    671     if (a->addr_type > b->addr_type) {
    672         return 1;
    673     }
    674     if (a->addr_type < b->addr_type) {
    675         return -1;
    676     }
    677     return memcmp(a->address, b->address, _bcm_ptp_addr_len(a->addr_type));
    678 }
    679 
    680 /*
    681  * Function:
    682  *      _bcm_ptp_dump_hex
    683  * Purpose:
    684  *      Print hexadecimal buffer.
    685  * Parameters:
    686  *      buf - (IN) buffer to be printed
    687  *      len - (IN) message length
    688  *      indent - (IN) number of spaces to indent
    689  * Returns:
    690  *      none
    691  * Notes:
    692  */
    693 void _bcm_ptp_dump_hex(uint8 *buf, int len, int indent)
    694 {
    695     char line[PTP_UTIL_HEXDUMP_LINE_WIDTH_OCTETS];
    696     int i,j;
    697     int linepos = 0;
    698 
    699     /*
    700      * Limit number of spaces to indent based on line width and the
    701      * maximum hexadecimal data width (32 x 3 + 1 null terminator).
    702      */
    703     indent = indent > (PTP_UTIL_HEXDUMP_LINE_WIDTH_OCTETS - 97) ?
    704              (PTP_UTIL_HEXDUMP_LINE_WIDTH_OCTETS - 97) : indent;
    705 
    706     for (j = 0; j < indent; j++) {
    707         sal_sprintf(line+linepos++," ");
    708     }
    709     for (i = 0; i < len; ++i) {
    710         sal_sprintf(line + linepos, "%02x", *buf++);
    711         linepos += 2;
    712         sal_sprintf(line + linepos, " ");
    713         ++linepos;
    714 
    715         if ((i & 0x1f) == 0x1f) {
    716             LOG_CLI((BSL_META("%s\n"), line));
    717             line[0] = 0;
    718             linepos = 0;
    719             for (j = 0; j < indent; j++) {
    720                 sal_sprintf(line+linepos++," ");
    721             }
    722         }
    723     }
    724 
    725     /* output last line if it wasn't complete */
    726     if (len & 0x1f) {
    727         LOG_CLI((BSL_META("%s\n"), line));
    728     }
    729 }
    730 
    731 sal_time_t _bcm_ptp_monotonic_time()
    732 {
    733     static _bcm_ptp_mutex_t mutex = 0;
    734     static int32 time_offset = 0;
    735     static sal_time_t last_time;
    736     static sal_usecs_t last_usecs;
    737     sal_time_t this_time = sal_time(), offset_time;
    738     sal_usecs_t this_usecs = sal_time_usecs();
    739     int32 usecs_diff, time_diff, time_jump;
    740     int rv;
    741 
    742     if (!mutex) {
    743         mutex = _bcm_ptp_mutex_create("ptp_monotonic_time");
    744 
    745         last_time = this_time;
    746         last_usecs = this_usecs;
    747     }
    748 
    749     rv = _bcm_ptp_mutex_take(mutex, 1000000); /* one second timeout */
    750 
    751     if (rv != BCM_E_NONE) {
    752         LOG_ERROR(BSL_LS_BCM_COMMON,
    753                   (BSL_META("Failed to get PTP monotonic_time mutex: %d (%s)\n"), rv, bcm_errmsg(rv)));
    754         return this_time + time_offset;
    755     }
    756 
    757     time_diff = (int32)(this_time - last_time);
    758     usecs_diff = (int32)(this_usecs - last_usecs);
    759 
    760     /* if the clock hasn't been adjusted, the difference between these two differences
    761        should be zero.  If it has been adjusted, the difference is the magnitude of the
    762        "time jump"
    763     */
    764     time_jump = time_diff - (usecs_diff / 1000000);
    765 
    766     if (time_jump < -2 || time_jump > 2) {
    767         LOG_INFO(BSL_LS_BCM_PTP,
    768                   (BSL_META("Time jumped by %d seconds \n"), (int)time_jump));
    769 
    770         /* the output of sal_time() evidently jumped, so incorporate that jump into future output */
    771         time_offset -= time_jump;
    772     }
    773 
    774     last_time = this_time;
    775     last_usecs = this_usecs;
    776 
    777     offset_time = this_time + time_offset;
    778 
    779     _bcm_ptp_mutex_give(mutex);
    780 
    781     return offset_time;
    782 }
    783 
    784 #if defined(BCM_PTP_INTERNAL_STACK_SUPPORT)
    785 /*
    786  * Function:
    787  *      _bcm_ptp_check_firmware_exist
    788  * Purpose:
    789  *      Check if the system is running provided firmware
    790  * Parameters:
    791  *      fw_str - (IN) firmware string
    792  * Returns:
    793  *      BCM_E_XXX;
    794  * Notes:
    795  *      Function tells whether the provided firmware
    796  *      is running on the system, return unavail if not
    797  */
    798 
    799 int
    800 _bcm_ptp_check_firmware_exist (char* fw_str)
    801 {
    802     int uc;
    803     char *version = NULL;
    804     int firmware = 0;
    805     int unit = 0;
    806 
    807     for(uc=0; uc<SOC_INFO(unit).num_ucs; uc++) {
    808         if (!soc_uc_in_reset(unit, uc)) {
    809             version = soc_uc_firmware_version(unit, uc);
    810             if (version) {
    811 #ifdef NO_SAL_APPL
    812                 if (strstr((char *)version,(char *)fw_str)) {
    813 #else
    814                 if (sal_strcasestr((char *)version,(char *)fw_str)) {
    815 #endif
    816                     firmware = 1;
    817                 }
    818                 soc_cm_sfree(unit, version);
    819                 if (1 == firmware) {
    820                     break;
    821                 }
    822             }
    823         }
    824     }
    825     if (firmware == 0) {
    826         return BCM_E_UNAVAIL;
    827     }
    828     return BCM_E_NONE;
    829 }
    830 #endif /* BCM_PTP_INTERNAL_STACK_SUPPORT */
    831 #endif /* defined(INCLUDE_PTP)*/