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

time-mbox.c (17171B)


      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  * Time - Broadcom Time BroadSync API - shared functionality
      8  */
      9 
     10 #include <shared/util.h>
     11 #include <shared/bsl.h>
     12 
     13 #include <bcm/time.h>
     14 #include <bcm/error.h>
     15 
     16 #include <bcm_int/common/time.h>
     17 #include <bcm_int/common/time-mbox.h>
     18 #include <bcm_int/common/mbox.h>
     19 
     20 #include <bcm_int/esw/mbcm.h>
     21 
     22 
     23 #define FREQ_OFFSET_CMD_LEN  (1 + 4)
     24 #define FREQ_OFFSET_RESP_LEN (1 + 1)
     25 int
     26 _bcm_time_bs_frequency_offset_set(int unit, bcm_time_spec_t new_offset)
     27 {
     28     uint8  command[FREQ_OFFSET_CMD_LEN]  = {_BCM_TIME_FREQ_OFFSET_SET};
     29     int command_len = FREQ_OFFSET_CMD_LEN;
     30 
     31     uint8  response[FREQ_OFFSET_RESP_LEN] = {0};
     32     int response_len = FREQ_OFFSET_RESP_LEN;
     33     int rv;
     34 
     35     int offset = (new_offset.nanoseconds * 1000);
     36 
     37     /* The maximum drift allowed is 1ms per second */
     38     if ( (!COMPILER_64_IS_ZERO(new_offset.seconds)) || (new_offset.nanoseconds > 1000000) ) {
     39         return BCM_E_PARAM;
     40     }
     41                                            
     42     /* units in message to ToP are ppt, nanoseconds per second drift is ppb so convert */
     43     if (new_offset.isnegative) {
     44         offset = -offset;
     45     }
     46 
     47     _shr_uint32_write(&command[1], (uint32) offset);
     48 
     49     rv = _bcm_mbox_txrx(unit, 0, _BCM_MBOX_MESSAGE, command, command_len, response, &response_len);
     50     if (rv != BCM_E_NONE) {
     51         LOG_ERROR(BSL_LS_BCM_COMMON,
     52                     (BSL_META_U(unit,
     53                                 "_bcm_mbox_txrx failed\n")));
     54         return BCM_E_INTERNAL;
     55     }  
     56 
     57     if (response_len != 2) { 
     58         LOG_ERROR(BSL_LS_BCM_COMMON,
     59                     (BSL_META_U(unit,
     60                                 "response_len != 2\n")));
     61         return BCM_E_INTERNAL; 
     62     }
     63     if (response[0] != command[0]) { 
     64         LOG_ERROR(BSL_LS_BCM_COMMON,
     65                     (BSL_META_U(unit,
     66                                 "response[0] != command[0]\n")));
     67         return BCM_E_INTERNAL; 
     68     }
     69     if (response[1] != 0x0) { 
     70         LOG_ERROR(BSL_LS_BCM_COMMON,
     71                     (BSL_META_U(unit,
     72                                 "response[1] != 0x0\n")));
     73         return BCM_E_FAIL; 
     74     }
     75 
     76     return BCM_E_NONE;
     77 }
     78 
     79 
     80 #define PHASE_OFFSET_CMD_LEN  (1 + 1 + 8 + 4)
     81 #define PHASE_OFFSET_RESP_LEN (1 + 1)
     82 int
     83 _bcm_time_bs_phase_offset_set(int unit, bcm_time_spec_t new_offset)
     84 {
     85     uint8  command[PHASE_OFFSET_CMD_LEN]  = {_BCM_TIME_PHASE_OFFSET_SET};
     86     int command_len = PHASE_OFFSET_CMD_LEN;
     87 
     88     uint8  response[PHASE_OFFSET_RESP_LEN] = {0};
     89     int response_len = PHASE_OFFSET_RESP_LEN;
     90     int rv;
     91 
     92     command[1] = new_offset.isnegative;
     93     _shr_uint64_write(&command[2], new_offset.seconds);
     94     _shr_uint32_write(&command[10], new_offset.nanoseconds);
     95 
     96     rv = _bcm_mbox_txrx(unit, 0, _BCM_MBOX_MESSAGE, command, command_len, response, &response_len);
     97     if (rv != BCM_E_NONE) {
     98         LOG_ERROR(BSL_LS_BCM_COMMON,
     99                     (BSL_META_U(unit,
    100                                 "_bcm_mbox_txrx failed\n")));
    101         return BCM_E_INTERNAL;
    102     }  
    103 
    104     if (response_len != 2) { 
    105         LOG_ERROR(BSL_LS_BCM_COMMON,
    106                     (BSL_META_U(unit,
    107                                 "response_len != 2\n")));
    108         return BCM_E_INTERNAL; 
    109     }
    110     if (response[0] != command[0]) { 
    111         LOG_ERROR(BSL_LS_BCM_COMMON,
    112                     (BSL_META_U(unit,
    113                                 "response[0] != command[0]\n")));
    114         return BCM_E_INTERNAL; 
    115     }
    116     if (response[1] != 0x0) { 
    117         LOG_ERROR(BSL_LS_BCM_COMMON,
    118                     (BSL_META_U(unit,
    119                                 "response[1] != 0x0\n")));
    120         return BCM_E_FAIL; 
    121     }
    122 
    123     return BCM_E_NONE;
    124 }
    125 
    126 #define NTP_OFFSET_CMD_LEN  (1 + 1 + 8 + 4)
    127 #define NTP_OFFSET_RESP_LEN (1 + 1)
    128 int
    129 _bcm_time_bs_ntp_offset_set(int unit, bcm_time_spec_t new_offset)
    130 {
    131     uint8  command[NTP_OFFSET_CMD_LEN]  = {_BCM_TIME_NTP_OFFSET_SET};
    132     int command_len = NTP_OFFSET_CMD_LEN;
    133 
    134     uint8  response[NTP_OFFSET_RESP_LEN] = {0};
    135     int response_len = NTP_OFFSET_RESP_LEN;
    136     int rv;
    137 
    138     command[1] = new_offset.isnegative;
    139     _shr_uint64_write(&command[2], new_offset.seconds);
    140     _shr_uint32_write(&command[10], new_offset.nanoseconds);
    141 
    142     rv = _bcm_mbox_txrx(unit, 0, _BCM_MBOX_MESSAGE, command, command_len, response, &response_len);
    143     if (rv != BCM_E_NONE) {
    144         LOG_ERROR(BSL_LS_BCM_COMMON,
    145                     (BSL_META_U(unit,
    146                                 "_bcm_mbox_txrx failed\n")));
    147         return BCM_E_INTERNAL;
    148     }  
    149 
    150     if (response_len != 2) { 
    151         LOG_ERROR(BSL_LS_BCM_COMMON,
    152                     (BSL_META_U(unit,
    153                                 "response_len != 2\n")));
    154         return BCM_E_INTERNAL; 
    155     }
    156     if (response[0] != command[0]) { 
    157         LOG_ERROR(BSL_LS_BCM_COMMON,
    158                     (BSL_META_U(unit,
    159                                 "response[0] != command[0]\n")));
    160         return BCM_E_INTERNAL; 
    161     }
    162     if (response[1] != 0x0) { 
    163         LOG_ERROR(BSL_LS_BCM_COMMON,
    164                     (BSL_META_U(unit,
    165                                 "response[1] != 0x0\n")));
    166         return BCM_E_FAIL; 
    167     }
    168 
    169     return BCM_E_NONE;
    170 }
    171 
    172 
    173 
    174 #define DEBUG_1PPS_CMD_LEN  (1 + 1)
    175 #define DEBUG_1PPS_RESP_LEN (1 + 1)
    176 int
    177 _bcm_time_bs_debug_1pps_set(int unit, uint8 enableOutput)
    178 {
    179     uint8  command[DEBUG_1PPS_CMD_LEN]  = {_BCM_TIME_DEBUG_1PPS_SET};
    180     int command_len = DEBUG_1PPS_CMD_LEN;
    181 
    182     uint8  response[DEBUG_1PPS_RESP_LEN] = {0};
    183     int response_len = DEBUG_1PPS_RESP_LEN;
    184     int rv;
    185 
    186     command[1] = enableOutput;
    187 
    188     rv = _bcm_mbox_txrx(unit, 0, _BCM_MBOX_MESSAGE, command, command_len, response, &response_len);
    189     if (rv != BCM_E_NONE) {
    190         LOG_ERROR(BSL_LS_BCM_COMMON,
    191                     (BSL_META_U(unit,
    192                                 "_bcm_mbox_txrx failed\n")));
    193         return BCM_E_INTERNAL;
    194     }  
    195 
    196     if (response_len != 2) { 
    197         LOG_ERROR(BSL_LS_BCM_COMMON,
    198                     (BSL_META_U(unit,
    199                                 "response_len != 2\n")));
    200         return BCM_E_INTERNAL; 
    201     }
    202     if (response[0] != command[0]) { 
    203         LOG_ERROR(BSL_LS_BCM_COMMON,
    204                     (BSL_META_U(unit,
    205                                 "response[0] != command[0]\n")));
    206         return BCM_E_INTERNAL; 
    207     }
    208     if (response[1] != 0x0) { 
    209         LOG_ERROR(BSL_LS_BCM_COMMON,
    210                     (BSL_META_U(unit,
    211                                 "response[1] != 0x0\n")));
    212         return BCM_E_FAIL;
    213     }
    214 
    215     return BCM_E_NONE;
    216 }
    217 
    218 
    219 #define STATUS_GET_CMD_LEN  (1)
    220 #define STATUS_GET_RESP_LEN (2)
    221 int
    222 _bcm_time_bs_status_get(int unit, int *lock_status)
    223 {
    224     uint8  command[STATUS_GET_CMD_LEN]  = {_BCM_TIME_STATUS_GET};
    225     int command_len = STATUS_GET_CMD_LEN;   
    226     int rv;
    227 
    228     uint8  response[STATUS_GET_RESP_LEN] = {0};
    229     int response_len = STATUS_GET_RESP_LEN;
    230 
    231     rv = _bcm_mbox_txrx(unit, 0, _BCM_MBOX_MESSAGE, command, command_len, response, &response_len);
    232     if (rv != BCM_E_NONE) {
    233         LOG_ERROR(BSL_LS_BCM_COMMON,
    234                     (BSL_META_U(unit,
    235                                 "_bcm_mbox_txrx failed\n")));
    236         return BCM_E_INTERNAL;
    237     }  
    238 
    239     if (response_len != 2) { 
    240         LOG_ERROR(BSL_LS_BCM_COMMON,
    241                     (BSL_META_U(unit,
    242                                 "response_len != 2\n")));
    243         return BCM_E_INTERNAL; 
    244     }
    245     if (response[0] != command[0]) { 
    246         LOG_ERROR(BSL_LS_BCM_COMMON,
    247                     (BSL_META_U(unit,
    248                                 "response[0] != command[0]\n")));
    249         return BCM_E_INTERNAL; 
    250     }
    251 
    252     /* Looks valid, return the second byte */
    253     *lock_status = (int)response[1];
    254 
    255     return BCM_E_NONE;
    256 }
    257 
    258 
    259 int
    260 _bcm_time_bs_debug(uint32 flags)
    261 {
    262     return _bcm_mbox_debug_flag_set(flags);
    263 }
    264 
    265 #define LOG_SET_CMD_LEN  (40)
    266 #define LOG_SET_RESP_LEN (40)
    267 /*
    268  * Function:
    269  *      _bcm_time_bs_log_configure
    270  * Purpose:
    271  *      Set the debug level and UDP log info for the firmware.
    272  * Parameters:
    273  *      unit         - (IN) Unit number.
    274  *      debug_mask   - (IN) bitmask of debug levels (textual debug)
    275  *      udp_log_mask - (IN) bitmask of UDP log levels
    276  *      src_mac      - (IN) SRC MAC for UDP log packets
    277  *      dest_mac     - (IN) DEST MAC for UDP log packets
    278  *      tpid         - (IN) TPID for UDP log packets
    279  *      vid          - (IN) VID for UDP log packets
    280  *      ttl          - (IN) TTL for UDP log packets
    281  *      src_addr     - (IN) IPv4 SRC Address for UDP log packets
    282  *      dest_addr    - (IN) IPv4 DEST Address for UDP log packets
    283  *      udp_port     - (IN) UDP port for UDP log packets
    284  * Returns:
    285  *      BCM_E_XXX
    286  */
    287 int
    288 _bcm_time_bs_log_configure(int unit,
    289                            uint32 debug_mask, uint64 udp_log_mask,
    290                            bcm_mac_t src_mac, bcm_mac_t dest_mac,
    291                            uint16 tpid, uint16 vid, uint8 ttl,
    292                            bcm_ip_t src_addr, bcm_ip_t dest_addr,
    293                            uint16 udp_port)
    294 {
    295     int rv = BCM_E_UNAVAIL;
    296 
    297     uint8 payload[LOG_SET_CMD_LEN] = {0};
    298     uint8 *curs = &payload[0];
    299     uint8 resp[LOG_SET_RESP_LEN];
    300     int resp_len = LOG_SET_RESP_LEN;
    301 
    302 
    303     /*
    304      * Make payload.
    305      *    Octet 0:      command
    306      *    Octet 1..4:   new debug mask level
    307      *    Octet 5..12:  new log mask level
    308      *    Octet 13..18: src_mac for log packets
    309      *    Octet 19..24: dst_mac for log packets
    310      *    Octet 25..26: tpid for log packets
    311      *    Octet 27..28: vid for log packets
    312      *    Octet 29:     TTL for log packets
    313      *    Octet 30..33: src_ip for log packets
    314      *    Octet 34..37: dst_ip for log packets
    315      *    Octet 38..39: UDP port for log packets
    316      */
    317     *curs = _BCM_TIME_LOG_SET; curs++;
    318     soc_htonl_store(curs, debug_mask);   curs += 4;
    319     soc_htonl_store(curs, COMPILER_64_HI(udp_log_mask)); curs += 4;
    320     soc_htonl_store(curs, COMPILER_64_LO(udp_log_mask)); curs += 4;
    321     sal_memcpy(curs, src_mac, 6);        curs += 6;
    322     sal_memcpy(curs, dest_mac, 6);       curs += 6;
    323     soc_htons_store(curs, tpid); curs += 2;
    324     soc_htons_store(curs, vid);  curs += 2;
    325     *curs = ttl;  curs++;
    326     soc_htonl_store(curs, src_addr);  curs += 4;
    327     soc_htonl_store(curs, dest_addr); curs += 4;
    328     soc_htons_store(curs, udp_port);  curs += 2;
    329 
    330     rv = _bcm_mbox_txrx(unit, 0, _BCM_MBOX_MESSAGE, payload, LOG_SET_CMD_LEN, resp, &resp_len);
    331     if (rv != BCM_E_NONE) {
    332         LOG_ERROR(BSL_LS_BCM_COMMON,
    333                     (BSL_META_U(unit,
    334                                 "_bcm_mbox_txrx failed\n")));
    335         return BCM_E_INTERNAL;
    336     } 
    337     
    338     if (resp_len != 2) { 
    339         LOG_ERROR(BSL_LS_BCM_COMMON,
    340                     (BSL_META_U(unit,
    341                                 "resp_len != 2\n")));
    342         return BCM_E_INTERNAL; 
    343     }
    344     if (resp[0] != payload[0]) { 
    345         LOG_ERROR(BSL_LS_BCM_COMMON,
    346                     (BSL_META_U(unit,
    347                                 "resp[0] != payload[0]\n")));
    348         return BCM_E_INTERNAL; 
    349     }
    350     if (resp[1] != 0x0) { 
    351         LOG_ERROR(BSL_LS_BCM_COMMON,
    352                     (BSL_META_U(unit,
    353                                 "resp[1] != 0x0\n")));
    354         return BCM_E_FAIL; 
    355     }
    356 
    357     return rv;
    358 }
    359 
    360 #define LOG_GET_CMD_LEN  (1)
    361 #define LOG_GET_RESP_LEN (44)
    362 /*
    363  * Function:
    364  *      _bcm_time_bs_log_configure_get
    365  * Purpose:
    366  *      Gets the debug level and UDP log info for the firmware.
    367  * Parameters:
    368  *      unit         - (IN) Unit number.
    369  *      bs_log_cfg   - (OUT) BroadSync log configuration.
    370  * Returns:
    371  *      BCM_E_XXX
    372  */
    373 int
    374 _bcm_time_bs_log_configure_get(int unit,
    375                             bcm_time_bs_log_cfg_t *bs_log_cfg)
    376 {
    377     int rv = BCM_E_UNAVAIL;
    378 
    379     uint8  command[LOG_GET_CMD_LEN]  = {_BCM_TIME_LOG_GET};
    380     uint8 resp[LOG_GET_RESP_LEN];
    381     int resp_len = LOG_GET_RESP_LEN;
    382     uint8 *curs = &resp[0];
    383 
    384     rv = _bcm_mbox_txrx(unit, 0, _BCM_MBOX_MESSAGE, command, LOG_GET_CMD_LEN, resp, &resp_len);
    385     if (rv != BCM_E_NONE) {
    386         LOG_ERROR(BSL_LS_BCM_COMMON,
    387                     (BSL_META_U(unit,
    388                                 "_bcm_mbox_txrx failed\n")));
    389         return BCM_E_INTERNAL;
    390     } 
    391 
    392      /*
    393      * Response format:
    394      *    Octet 0:      command
    395      *    Octet 1..4:   new debug mask level
    396      *    Octet 5..12:  new log mask level
    397      *    Octet 13..18: src_mac for log packets
    398      *    Octet 19..24: dst_mac for log packets
    399      *    Octet 25..26: tpid for log packets
    400      *    Octet 27..28: vid for log packets
    401      *    Octet 29:     TTL for log packets
    402      *    Octet 30..33: src_ip for log packets
    403      *    Octet 34..37: dst_ip for log packets
    404      *    Octet 38..39: Src UDP port for log packets
    405      *    Octet 40..41: Dest UDP port for log packets
    406      */
    407     
    408     if (resp_len != 42) { 
    409         LOG_ERROR(BSL_LS_BCM_COMMON,
    410                     (BSL_META_U(unit,
    411                                 "resp_len != 42\n")));
    412         return BCM_E_INTERNAL; 
    413     }
    414     if (resp[0] != command[0]) { 
    415         LOG_ERROR(BSL_LS_BCM_COMMON,
    416                     (BSL_META_U(unit,
    417                                 "resp[0] != command[0]\n")));
    418         return BCM_E_INTERNAL; 
    419     }
    420 
    421     curs += 1;
    422     bs_log_cfg->debug_mask = soc_ntohl_load(curs);
    423     curs += 4;
    424     bs_log_cfg->udp_log_mask = soc_parse_uint64((char *)curs);
    425     curs += 8;
    426     sal_memcpy(bs_log_cfg->dest_mac, curs, 6);
    427     curs += 6;
    428     sal_memcpy(bs_log_cfg->src_mac, curs, 6);
    429     curs += 6;
    430     bs_log_cfg->tpid = soc_ntohs_load(curs);
    431     curs += 2;
    432     bs_log_cfg->vid = soc_ntohs_load(curs);
    433     curs += 2;
    434     bs_log_cfg->ttl = *curs;
    435     curs++;
    436     bs_log_cfg->src_addr = soc_ntohl_load(curs);
    437     curs += 4;
    438     bs_log_cfg->dest_addr = soc_ntohl_load(curs);
    439     curs += 4;
    440     bs_log_cfg->udp_port = soc_ntohs_load(curs);
    441     curs += 2;
    442 
    443     return rv;
    444 }
    445 
    446 /*
    447  * Function:
    448  *     _bcm_time_bs_time_set 
    449  * Purpose:
    450  *      Sets the broadsync time.
    451  * Parameters:
    452  *      unit    - (IN) Unit number.
    453  *      bs_time - (OUT) BroadSync time in seconds and nanoseconds.
    454  * Returns:
    455  *      BCM_E_XXX
    456  */
    457 
    458 #define BROADSYNC_TIME_SET_CMD_LEN  (1 + 1 + 8 + 4)
    459 #define BROADSYNC_TIME_SET_RESP_LEN (1 + 1)
    460 int
    461 _bcm_time_bs_time_set(int unit, bcm_time_spec_t bs_time)
    462 {
    463     uint8  command[BROADSYNC_TIME_SET_CMD_LEN]  = {_BCM_TIME_BS_TIME_SET};
    464     int command_len = BROADSYNC_TIME_SET_CMD_LEN;
    465 
    466     uint8  response[BROADSYNC_TIME_SET_RESP_LEN] = {0};
    467     int response_len = BROADSYNC_TIME_SET_RESP_LEN;
    468     int rv;
    469 
    470     command[1] = 0;
    471     _shr_uint64_write(&command[2], bs_time.seconds);
    472     _shr_uint32_write(&command[10], bs_time.nanoseconds);
    473 
    474     rv = _bcm_mbox_txrx(unit, 0, _BCM_MBOX_MESSAGE, command, command_len, response, &response_len);
    475     if (rv != BCM_E_NONE) {
    476         LOG_ERROR(BSL_LS_BCM_COMMON,
    477                     (BSL_META_U(unit,
    478                                 "_bcm_mbox_txrx failed\n")));
    479         return BCM_E_INTERNAL;
    480     }
    481 
    482     if (response_len != 2) {
    483         LOG_ERROR(BSL_LS_BCM_COMMON,
    484                     (BSL_META_U(unit,
    485                                 "response_len != 2\n")));
    486         return BCM_E_INTERNAL;
    487     }
    488     if (response[0] != command[0]) {
    489         LOG_ERROR(BSL_LS_BCM_COMMON,
    490                     (BSL_META_U(unit,
    491                                 "response[0] != command[0]\n")));
    492         return BCM_E_INTERNAL;
    493     }
    494     if (response[1] != 0x0) {
    495         LOG_ERROR(BSL_LS_BCM_COMMON,
    496                     (BSL_META_U(unit,
    497                                 "response[1] != 0x0\n")));
    498         return BCM_E_FAIL;
    499     }
    500 
    501     return BCM_E_NONE;
    502 }
    503 
    504 #define BROADSYNC_TIME_CMD_LEN  (1)
    505 #define BROADSYNC_TIME_RESP_LEN (1 + 1 + 8 + 4)
    506 /*
    507  * Function:
    508  *     _bcm_time_bs_time_get 
    509  * Purpose:
    510  *      Gets the broadsync time.
    511  * Parameters:
    512  *      unit    - (IN) Unit number.
    513  *      bs_time - (OUT) BroadSync time in seconds and nanoseconds.
    514  * Returns:
    515  *      BCM_E_XXX
    516  */
    517 
    518 int
    519 _bcm_time_bs_time_get(int unit, bcm_time_spec_t* bs_time)
    520 {
    521     uint8  command[BROADSYNC_TIME_CMD_LEN]  = {_BCM_TIME_BS_TIME_GET};
    522     int command_len = BROADSYNC_TIME_CMD_LEN;
    523 
    524     uint8  response[BROADSYNC_TIME_RESP_LEN] = {0};
    525     int response_len = BROADSYNC_TIME_RESP_LEN;
    526     int rv;
    527 
    528     rv = _bcm_mbox_txrx(unit, 0, _BCM_MBOX_MESSAGE, command, command_len, response, &response_len);
    529     if (rv != BCM_E_NONE) {
    530         LOG_ERROR(BSL_LS_BCM_COMMON,
    531                     (BSL_META_U(unit,
    532                                 "_bcm_mbox_txrx failed\n")));
    533         return BCM_E_INTERNAL;
    534     }
    535 
    536     if (response_len != BROADSYNC_TIME_RESP_LEN) {
    537         LOG_ERROR(BSL_LS_BCM_COMMON,
    538                     (BSL_META_U(unit,
    539                                 "response_len != BROADSYNC_TIME_CMD_LEN\n")));
    540         return BCM_E_INTERNAL;
    541     }
    542 
    543     if (response[0] != command[0]) {
    544         LOG_ERROR(BSL_LS_BCM_COMMON,
    545                     (BSL_META_U(unit,
    546                                 "response[0] != command[0]\n")));
    547         return BCM_E_INTERNAL;
    548     }
    549 
    550     bs_time->isnegative = 0;
    551     bs_time->seconds = _shr_uint64_read(&response[2]);
    552     bs_time->nanoseconds = _shr_uint32_read(&response[10]);
    553 
    554     return BCM_E_NONE;
    555 }