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 }