signaling.c (129128B)
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: signaling.c 8 * 9 * Purpose: 10 * 11 * Functions: 12 * bcm_common_ptp_signaled_unicast_master_add 13 * bcm_common_ptp_signaled_unicast_master_remove 14 * bcm_common_ptp_signaled_unicast_slave_list 15 * bcm_common_ptp_signaled_unicast_slave_table_clear 16 * bcm_common_ptp_unicast_request_duration_get 17 * bcm_common_ptp_unicast_request_duration_set 18 * bcm_common_ptp_unicast_request_duration_min_get 19 * bcm_common_ptp_unicast_request_duration_min_set 20 * bcm_common_ptp_unicast_request_duration_max_get 21 * bcm_common_ptp_unicast_request_duration_max_set 22 * 23 * _bcm_ptp_register_signaling_arbiter 24 * _bcm_ptp_unregister_signaling_arbiter 25 * _bcm_ptp_signaling_init 26 * _bcm_ptp_signaling_manager 27 * _bcm_ptp_signaled_unicast_master_table_init 28 * _bcm_ptp_signaled_unicast_master_table_reset 29 * _bcm_ptp_signaled_unicast_slave_table_init 30 * _bcm_ptp_signaled_unicast_slave_table_reset 31 * _bcm_ptp_signaled_unicast_slave_exists 32 * _bcm_ptp_signaled_unicast_slave_add 33 * _bcm_ptp_signaled_unicast_slave_remove 34 * _bcm_ptp_signaled_unicast_slave_expire 35 * _bcm_ptp_signaled_unicast_slave_table_update 36 * send_unicast_request 37 * _bcm_ptp_master_active_service_cancel 38 * _bcm_ptp_master_active_service_ack_cancel 39 * _bcm_ptp_slave_signaling_send 40 * send_pending_signaling_to_masters 41 * _bcm_ptp_slave_signaling_request_deny 42 * _bcm_ptp_slave_signaling_gateway 43 * _bcm_ptp_parse_signaling_message 44 * _bcm_ptp_make_peer_from_signaling_msg 45 * _bcm_ptp_process_incoming_signaling_msg 46 * delayed_master_table_update 47 */ 48 49 #if defined(INCLUDE_PTP) 50 51 #ifdef BCM_HIDE_DISPATCHABLE 52 #undef BCM_HIDE_DISPATCHABLE 53 #endif 54 55 #include <shared/bsl.h> 56 #include <shared/util.h> 57 58 #include <soc/defs.h> 59 #include <soc/drv.h> 60 61 #include <sal/appl/io.h> 62 #include <sal/core/libc.h> 63 #include <sal/core/alloc.h> 64 #include <sal/core/time.h> 65 #include <shared/bitop.h> 66 #include <bcm/ptp.h> 67 #include <bcm_int/common/ptp.h> 68 #include <bcm_int/ptp_common.h> 69 70 /* Parameters and constants. */ 71 #define BCM_PTP_SIGNAL_LOGINTERMSG_PERIOD_NONGRANT (0x7f) 72 #define BCM_PTP_SIGNAL_REQUEST_DENY_DURATION_SEC (0) 73 74 #define BCM_PTP_SIGNAL_GRANT_UNICAST_RENEWAL_INVITED (1) 75 #define BCM_PTP_SIGNAL_TELECOM_GRANT_UNICAST_RENEWAL_INVITED (0) 76 77 #define BCM_PTP_SIGNAL_MIN_SLAVE_DPC_TIME_USEC (50) 78 #define BCM_PTP_SIGNAL_DEFAULT_SLAVE_DPC_TIME_USEC (1000000) 79 #define BCM_PTP_SIGNAL_SLAVE_MUTEX_TIMEOUT_USEC (50000) 80 81 #define BCM_PTP_SIGNAL_REQUEST_UC_MINIMUM_DURATION_SEC (10) 82 #define BCM_PTP_SIGNAL_REQUEST_UC_DEFAULT_DURATION_SEC (300) 83 #define BCM_PTP_SIGNAL_REQUEST_UC_MAXIMUM_DURATION_SEC (1000) 84 85 #define BCM_PTP_SIGNAL_TELECOM_REQUEST_UC_MINIMUM_DURATION_SEC (60) 86 #define BCM_PTP_SIGNAL_TELECOM_REQUEST_UC_DEFAULT_DURATION_SEC (300) 87 #define BCM_PTP_SIGNAL_TELECOM_REQUEST_UC_MAXIMUM_DURATION_SEC (1000) 88 89 #define BCM_PTP_SIGNAL_TELECOM_UNMET_REQUEST_MAX (3) 90 #define BCM_PTP_SIGNAL_TELECOM_UNMET_REQUEST_QUERY_INTERVAL_SEC (60) 91 92 #define BCM_PTP_SIGNAL_MIN_MASTER_DPC_TIME_USEC (50) 93 #define BCM_PTP_SIGNAL_DEFAULT_MASTER_DPC_TIME_USEC (1000000) 94 95 #define BCM_PTP_UDP_HEADER_LENGTH_BYTES (8) 96 #define BCM_PTP_SIGNAL_TLV_OFFSET_OCTETS (44) 97 #define BCM_PTP_SIGNAL_MIN_TLV_SIZE_OCTETS (6) 98 #define BCM_PTP_SIGNAL_MAX_TLV_SIZE_OCTETS (12) 99 100 #define BCM_PTP_SIGNAL_MAX_TLV_PER_MESSAGE (3) 101 #define BCM_PTP_SIGNAL_MAX_MULTI_TLV_SIZE_OCTETS (BCM_PTP_SIGNAL_MAX_TLV_SIZE_OCTETS * \ 102 BCM_PTP_SIGNAL_MAX_TLV_PER_MESSAGE) 103 104 #define BCM_PTP_SIGNAL_MIN_UDP_PAYLOAD_SIZE_OCTETS (BCM_PTP_SIGNAL_TLV_OFFSET_OCTETS + \ 105 BCM_PTP_SIGNAL_MIN_TLV_SIZE_OCTETS) 106 #define BCM_PTP_SIGNAL_MAX_UDP_PAYLOAD_SIZE_OCTETS (BCM_PTP_SIGNAL_TLV_OFFSET_OCTETS + \ 107 BCM_PTP_SIGNAL_MAX_MULTI_TLV_SIZE_OCTETS) 108 #define BCM_PTP_SIGNAL_MAX_PKT_SIZE_OCTETS (PTP_MSG_L2_HEADER_LENGTH + 40 + \ 109 PTP_UDPHDR_SIZE_OCTETS + \ 110 BCM_PTP_SIGNAL_MAX_UDP_PAYLOAD_SIZE_OCTETS) 111 112 /* Macros. */ 113 #define BCM_PTP_SLAVETABLE_MUTEX_TAKE() \ 114 PTP_MUTEX_TAKE(slaveTable_mutex, BCM_PTP_SIGNAL_SLAVE_MUTEX_TIMEOUT_USEC) 115 116 #define BCM_PTP_SLAVETABLE_MUTEX_RELEASE_RETURN(__rv__) \ 117 PTP_MUTEX_RELEASE_RETURN(slaveTable_mutex, __rv__) 118 119 /* Types. */ 120 typedef struct _bcm_ptp_msg_services_s { 121 uint8 announce; 122 uint8 sync; 123 uint8 delayresp; 124 } _bcm_ptp_msg_services_t; 125 126 typedef struct signaled_master_s { 127 sal_time_t announce_refresh_time, sync_refresh_time, delay_refresh_time; 128 int8 log_announce_interval, log_sync_interval, log_delay_interval; 129 int8 granted_log_sync_interval, granted_log_delay_interval; 130 uint32 query_interval_sec; 131 uint32 durationField; 132 uint16 sequenceId; 133 134 _bcm_ptp_msg_services_t service_enable; 135 _bcm_ptp_msg_services_t service_grants; 136 _bcm_ptp_msg_services_t to_ack_cancel; 137 _bcm_ptp_msg_services_t unmet_requests; 138 139 bcm_ptp_clock_peer_t master; 140 #ifdef BCM_PTP_EXT_SERVO_SUPPORT 141 int8 update_servo; 142 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */ 143 } signaled_master_t; 144 145 typedef struct _bcm_ptp_signaled_slave_s { 146 sal_time_t announce_request_time; 147 sal_time_t sync_request_time; 148 sal_time_t delay_request_time; 149 150 sal_time_t announce_grant_time; 151 sal_time_t sync_grant_time; 152 sal_time_t delay_grant_time; 153 154 sal_time_t announce_cancel_time; 155 sal_time_t sync_cancel_time; 156 sal_time_t delay_cancel_time; 157 158 #if defined(BCM_PTP_SIGNAL_TIMESTAMP) 159 sal_time_t announce_ack_time; 160 sal_time_t sync_ack_time; 161 sal_time_t delay_ack_time; 162 163 sal_time_t announce_expire_time; 164 sal_time_t sync_expire_time; 165 sal_time_t delay_expire_time; 166 #endif 167 168 uint8 announce_service_active; 169 uint8 sync_service_active; 170 uint8 delay_service_active; 171 172 uint8 queue_announce_grant; 173 uint8 queue_sync_grant; 174 uint8 queue_delay_grant; 175 176 uint8 announce_service_changed; 177 uint8 sync_service_changed; 178 uint8 delay_service_changed; 179 180 uint8 queue_announce_cancel; 181 uint8 queue_sync_cancel; 182 uint8 queue_delay_cancel; 183 184 uint8 queue_announce_expire; 185 uint8 queue_sync_expire; 186 uint8 queue_delay_expire; 187 188 uint32 announce_duration; 189 uint32 sync_duration; 190 uint32 delay_duration; 191 192 uint16 sequenceId; 193 194 _bcm_ptp_clock_peer_ext_t slave; 195 } _bcm_ptp_signaled_slave_t; 196 197 typedef struct _bcm_ptp_signaled_slave_table_s { 198 uint16 num_entries; 199 _bcm_ptp_signaled_slave_t entry[PTP_MAX_UNICAST_SLAVE_TABLE_ENTRIES]; 200 } _bcm_ptp_signaled_slave_table_t; 201 202 typedef struct unit_sig_info_s { 203 bcm_ptp_signaling_arbiter_t arbiter; 204 void * arbiter_user_data; 205 206 shr_rdpc_t send_pending_signaling_to_masters_rdpc; 207 shr_rdpc_t send_pending_signaling_to_slaves_rdpc; 208 } unit_sig_info_t; 209 210 /* Variables. */ 211 static int signaling_initialized = 0; 212 static int signaling_initialized_slave = 0; 213 static unit_sig_info_t unit_sig_array[BCM_MAX_NUM_UNITS] = {{0}}; 214 215 static signaled_master_t signaled_master[PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES] = {{0}}; 216 static volatile int num_signaled_masters = 0; 217 218 static _bcm_ptp_signaled_slave_t signaled_slave_entry_default = {0}; 219 static _bcm_ptp_signaled_slave_table_t signaled_slave_table; 220 static _bcm_ptp_mutex_t slaveTable_mutex = 0x0; 221 222 static bcm_ptp_clock_identity_t BCM_PTP_ALL_CLOCKS = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 223 static uint16 BCM_PTP_ANY_PORT = 0xFFFF; /* From the standard: port 65535 => any/every port */ 224 225 static uint32 request_uc_durationField = BCM_PTP_SIGNAL_REQUEST_UC_DEFAULT_DURATION_SEC; 226 static uint32 request_uc_durationField_min = BCM_PTP_SIGNAL_REQUEST_UC_MINIMUM_DURATION_SEC; 227 static uint32 request_uc_durationField_max = BCM_PTP_SIGNAL_REQUEST_UC_MAXIMUM_DURATION_SEC; 228 229 static int renewal_invited = BCM_PTP_SIGNAL_GRANT_UNICAST_RENEWAL_INVITED; 230 231 /* Static functions. */ 232 static int send_unicast_request(int unit, bcm_ptp_stack_id_t ptp_id, int clock_num, 233 int num_tlvs, int *type, int8 *log_inter_message_period, uint32 durationField, 234 uint16 sequenceId, bcm_ptp_clock_peer_t *master); 235 static int _bcm_ptp_master_active_service_cancel(int unit, bcm_ptp_stack_id_t ptp_id, 236 int clock_num, signaled_master_t *entry, bcm_ptp_message_type_t messageType); 237 static int _bcm_ptp_master_active_service_ack_cancel(int unit, bcm_ptp_stack_id_t ptp_id, 238 int clock_num, signaled_master_t *entry, bcm_ptp_message_type_t messageType); 239 static sal_usecs_t send_pending_signaling_to_masters(void **arg_unit, void **arg_ptp_id, 240 void **arg_clock_num, void **unused); 241 static void delayed_master_table_update(void *owner, void *arg_unit, void *arg_ptp_id, 242 void *arg_clock_num, void *unused); 243 244 static int _bcm_ptp_slave_signaling_send(int unit, bcm_ptp_stack_id_t ptp_id, 245 int clock_num, bcm_ptp_tlv_type_t tlv_type, bcm_ptp_message_type_t msg_type, 246 int8 log_intermessage_period, uint32 duration, uint16 sequenceId, _bcm_ptp_clock_peer_ext_t *slave, int async); 247 static int _bcm_ptp_slave_signaling_request_deny(int unit, bcm_ptp_stack_id_t ptp_id, 248 int clock_num, bcm_ptp_message_type_t msg_type, int8 log_intermessage_period, 249 _bcm_ptp_clock_peer_ext_t *slave); 250 static sal_usecs_t send_pending_signaling_to_slaves(void **arg_unit, void **arg_ptp_id, 251 void **arg_clock_num, void **unused); 252 253 static int _bcm_ptp_signaled_unicast_master_table_init(int unit, bcm_ptp_stack_id_t ptp_id); 254 static int _bcm_ptp_signaled_unicast_master_table_cleanup(int unit, bcm_ptp_stack_id_t ptp_id); 255 static int _bcm_ptp_signaled_unicast_slave_table_init(int unit, bcm_ptp_stack_id_t ptp_id); 256 static int _bcm_ptp_signaled_unicast_slave_table_cleanup(int unit, bcm_ptp_stack_id_t ptp_id); 257 258 /* 259 * Function: 260 * _bcm_ptp_register_signaling_arbiter 261 * Purpose: 262 * Register a callback function to accept or reject PTP signaling messages. 263 * Parameters: 264 * unit - (IN) Unit number. 265 * arb - (IN) PTP signaling message arbiter function pointer. 266 * user_data - (IN) User data. 267 * Returns: 268 * BCM_E_XXX - Function status. 269 */ 270 int 271 _bcm_ptp_register_signaling_arbiter( 272 int unit, 273 bcm_ptp_signaling_arbiter_t arb, 274 void *user_data) 275 { 276 int rv = BCM_E_NONE; 277 unit_sig_array[unit].arbiter = arb; 278 unit_sig_array[unit].arbiter_user_data = user_data; 279 280 return rv; 281 } 282 283 /* 284 * Function: 285 * _bcm_ptp_unregister_signaling_arbiter 286 * Purpose: 287 * Unregister a PTP signaling message arbiter. 288 * Parameters: 289 * unit - (IN) Unit number. 290 * Returns: 291 * BCM_E_XXX - Function status. 292 */ 293 int 294 _bcm_ptp_unregister_signaling_arbiter( 295 int unit) 296 { 297 int rv = BCM_E_NONE; 298 unit_sig_array[unit].arbiter = NULL; 299 unit_sig_array[unit].arbiter_user_data = NULL; 300 301 return rv; 302 } 303 304 305 /* 306 * Function: 307 * _bcm_ptp_signaling_init 308 * Purpose: 309 * Initialize the BCM PTP signaling message framework. 310 * Parameters: 311 * unit - (IN) Unit number. 312 * ptp_id - (IN) PTP stack ID. 313 * Returns: 314 * BCM_E_XXX - Function status. 315 * Notes: 316 */ 317 int 318 _bcm_ptp_signaling_init( 319 int unit, 320 bcm_ptp_stack_id_t ptp_id) 321 { 322 int rv; 323 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 324 PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 325 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 326 return rv; 327 } 328 329 if (shr_rdpc_callback_created(&unit_sig_array[unit].send_pending_signaling_to_masters_rdpc) == BCM_E_INIT) { 330 /* RDPC (and associated lock) is left in place on cleanup, so only create it once */ 331 shr_rdpc_callback_create(&unit_sig_array[unit].send_pending_signaling_to_masters_rdpc, &send_pending_signaling_to_masters); 332 } 333 334 if (shr_rdpc_callback_created(&unit_sig_array[unit].send_pending_signaling_to_slaves_rdpc) == BCM_E_INIT) { 335 /* RDPC (and associated lock) is left in place on cleanup, so only create it once */ 336 shr_rdpc_callback_create(&unit_sig_array[unit].send_pending_signaling_to_slaves_rdpc, &send_pending_signaling_to_slaves); 337 } 338 339 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_master_table_init(unit, ptp_id))) { 340 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_master_table_init()"); 341 return rv; 342 } 343 344 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_master_table_reset(unit, ptp_id))) { 345 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_master_table_reset()"); 346 return rv; 347 } 348 349 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_table_init(unit, ptp_id))) { 350 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_slave_table_init()"); 351 return rv; 352 } 353 354 return BCM_E_NONE; 355 } 356 357 /* 358 * Function: 359 * _bcm_ptp_signaling_cleanup 360 * Purpose: 361 * Uninitializes signaling framework 362 * Parameters: 363 * unit - (IN) Unit number. 364 * ptp_id - (IN) PTP stack ID. 365 */ 366 int _bcm_ptp_signaling_cleanup(int unit, bcm_ptp_stack_id_t ptp_id) 367 { 368 int rv = BCM_E_NONE; 369 370 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_master_table_cleanup(unit, ptp_id))) { 371 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_master_table_cleanup()"); 372 return rv; 373 } 374 375 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_table_cleanup(unit, ptp_id))) { 376 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_master_table_cleanup()"); 377 return rv; 378 } 379 380 return BCM_E_NONE; 381 } 382 383 /* 384 * Function: 385 * _bcm_ptp_signaling_manager 386 * Purpose: 387 * Manage configurable attributes based on active PTP profile. 388 * Parameters: 389 * unit - (IN) Unit number. 390 * ptp_id - (IN) PTP stack ID. 391 * clock_num - (IN) PTP clock number. 392 * en_telecom - (IN) Telecom profile enabled Boolean. 393 * Returns: 394 * BCM_E_XXX - Function status. 395 */ 396 int 397 _bcm_ptp_signaling_manager( 398 int unit, 399 bcm_ptp_stack_id_t ptp_id, 400 int clock_num, 401 int en_telecom) 402 { 403 int rv; 404 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 405 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 406 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 407 return rv; 408 } 409 410 411 if (0 == en_telecom) { 412 /* Standard profile. */ 413 request_uc_durationField = BCM_PTP_SIGNAL_REQUEST_UC_DEFAULT_DURATION_SEC; 414 request_uc_durationField_min = BCM_PTP_SIGNAL_REQUEST_UC_MINIMUM_DURATION_SEC; 415 request_uc_durationField_max = BCM_PTP_SIGNAL_REQUEST_UC_MAXIMUM_DURATION_SEC; 416 417 renewal_invited = BCM_PTP_SIGNAL_GRANT_UNICAST_RENEWAL_INVITED; 418 } else { 419 /* Telecom profile. */ 420 request_uc_durationField = BCM_PTP_SIGNAL_TELECOM_REQUEST_UC_DEFAULT_DURATION_SEC; 421 request_uc_durationField_min = BCM_PTP_SIGNAL_TELECOM_REQUEST_UC_MINIMUM_DURATION_SEC; 422 request_uc_durationField_max = BCM_PTP_SIGNAL_TELECOM_REQUEST_UC_MAXIMUM_DURATION_SEC; 423 424 renewal_invited = BCM_PTP_SIGNAL_TELECOM_GRANT_UNICAST_RENEWAL_INVITED; 425 } 426 427 return BCM_E_NONE; 428 } 429 430 /* 431 * Function: 432 * _bcm_ptp_signaled_unicast_master_table_init 433 * Purpose: 434 * Initialize the periodic check to see if signaling messages need to be sent to masters 435 * Parameters: 436 * unit - (IN) Unit number. 437 * ptp_id - (IN) PTP stack ID. 438 * Returns: 439 * BCM_E_XXX - Function status. 440 * Notes: 441 */ 442 int 443 _bcm_ptp_signaled_unicast_master_table_init( 444 int unit, 445 bcm_ptp_stack_id_t ptp_id) 446 { 447 int rv; 448 449 request_uc_durationField = BCM_PTP_SIGNAL_REQUEST_UC_DEFAULT_DURATION_SEC; 450 request_uc_durationField_min = BCM_PTP_SIGNAL_REQUEST_UC_MINIMUM_DURATION_SEC; 451 request_uc_durationField_max = BCM_PTP_SIGNAL_REQUEST_UC_MAXIMUM_DURATION_SEC; 452 453 renewal_invited = BCM_PTP_SIGNAL_GRANT_UNICAST_RENEWAL_INVITED; 454 455 signaling_initialized = 1; 456 457 rv = shr_rdpc_callback_start(&unit_sig_array[unit].send_pending_signaling_to_masters_rdpc, 458 BCM_PTP_SIGNAL_DEFAULT_MASTER_DPC_TIME_USEC, 459 INT_TO_PTR(unit), INT_TO_PTR(ptp_id), INT_TO_PTR(PTP_CLOCK_NUMBER_DEFAULT), INT_TO_PTR(0)); 460 return rv; 461 } 462 463 /* 464 * Function: 465 * _bcm_ptp_signaled_unicast_master_table_reset 466 * Purpose: 467 * Reset signaled unicast master table. 468 * Parameters: 469 * unit - (IN) Unit number. 470 * ptp_id - (IN) PTP stack ID. 471 * Returns: 472 * BCM_E_XXX - Function status. 473 * Notes: 474 */ 475 int 476 _bcm_ptp_signaled_unicast_master_table_reset( 477 int unit, 478 bcm_ptp_stack_id_t ptp_id) 479 { 480 num_signaled_masters = 0; 481 return BCM_E_NONE; 482 } 483 484 /* 485 * Function: 486 * _bcm_ptp_signaled_unicast_master_table_cleanup 487 * Purpose: 488 * Uninitialize signaled master table in preparation for stack deletion 489 * Parameters: 490 * unit - (IN) Unit number. 491 * ptp_id - (IN) PTP stack ID. 492 */ 493 494 int _bcm_ptp_signaled_unicast_master_table_cleanup( 495 int unit, 496 bcm_ptp_stack_id_t ptp_id) 497 { 498 return shr_rdpc_callback_stop(&unit_sig_array[unit].send_pending_signaling_to_masters_rdpc); 499 } 500 501 502 /* 503 * Function: 504 * _bcm_ptp_signaled_unicast_slave_table_init 505 * Purpose: 506 * Initialize the signaled unicast slave table and framework to manage 507 * signaling messages sent to slaves. 508 * Parameters: 509 * unit - (IN) Unit number. 510 * ptp_id - (IN) PTP stack ID. 511 * Returns: 512 * BCM_E_XXX - Function status. 513 * Notes: 514 */ 515 int 516 _bcm_ptp_signaled_unicast_slave_table_init( 517 int unit, 518 bcm_ptp_stack_id_t ptp_id) 519 { 520 int rv; 521 522 if (!slaveTable_mutex) { 523 slaveTable_mutex = _bcm_ptp_mutex_create("signaled_slave_table"); 524 if (!slaveTable_mutex) { 525 return BCM_E_MEMORY; 526 } 527 } 528 529 if (signaling_initialized_slave) { 530 /* Reset signaled unicast slave table. */ 531 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_table_reset(unit, ptp_id))) { 532 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_slave_table_reset()"); 533 return rv; 534 } 535 } 536 537 signaling_initialized_slave = 1; 538 539 rv = shr_rdpc_callback_start(&unit_sig_array[unit].send_pending_signaling_to_slaves_rdpc, 540 BCM_PTP_SIGNAL_DEFAULT_SLAVE_DPC_TIME_USEC, 541 INT_TO_PTR(unit), INT_TO_PTR(ptp_id), INT_TO_PTR(PTP_CLOCK_NUMBER_DEFAULT), INT_TO_PTR(0)); 542 543 return rv; 544 } 545 546 /* 547 * Function: 548 * _bcm_ptp_signaled_unicast_slave_table_reset 549 * Purpose: 550 * Reset signaled unicast slave table. 551 * Parameters: 552 * unit - (IN) Unit number. 553 * ptp_id - (IN) PTP stack ID. 554 * Returns: 555 * BCM_E_XXX - Function status. 556 * Notes: 557 */ 558 int 559 _bcm_ptp_signaled_unicast_slave_table_reset( 560 int unit, 561 bcm_ptp_stack_id_t ptp_id) 562 { 563 int i; 564 565 signaled_slave_table.num_entries = 0; 566 for (i = 0; i < PTP_MAX_UNICAST_SLAVE_TABLE_ENTRIES; ++i) { 567 signaled_slave_table.entry[i] = signaled_slave_entry_default; 568 } 569 570 return BCM_E_NONE; 571 } 572 573 /* 574 * Function: 575 * _bcm_ptp_signaled_unicast_slave_table_cleanup 576 * Purpose: 577 * Uninitialize signaled slave table in preparation for stack deletion 578 * Parameters: 579 * unit - (IN) Unit number. 580 * ptp_id - (IN) PTP stack ID. 581 */ 582 int 583 _bcm_ptp_signaled_unicast_slave_table_cleanup( 584 int unit, 585 bcm_ptp_stack_id_t ptp_id) 586 { 587 int rv; 588 rv = shr_rdpc_callback_stop(&unit_sig_array[unit].send_pending_signaling_to_slaves_rdpc); 589 590 if (BCM_FAILURE(rv)) { 591 PTP_ERROR_FUNC("Failed to stop Slave Signaling DPC"); 592 return rv; 593 } 594 595 _bcm_ptp_mutex_destroy(slaveTable_mutex); 596 slaveTable_mutex = 0; 597 signaling_initialized_slave = 0; 598 599 return BCM_E_NONE; 600 } 601 602 #ifdef BCM_PTP_EXT_SERVO_SUPPORT 603 int 604 _bcm_ptp_signaled_unicast_master_index_get( 605 int unit, 606 bcm_ptp_stack_id_t ptp_id, 607 int clock_num, 608 bcm_ptp_port_identity_t *master_portId, 609 int *inst_num) 610 { 611 int idx; 612 613 for (idx = 0; idx < num_signaled_masters; ++idx) { 614 if (_bcm_ptp_peer_portid_compare((bcm_ptp_port_identity_t *)&signaled_master[idx].master, 615 master_portId)) { 616 *inst_num = idx; 617 return BCM_E_NONE; 618 } 619 } 620 621 return BCM_E_NOT_FOUND; 622 } 623 624 #if 0 625 int _bcm_ptp_signaled_unicast_master_log_sync_int_get( 626 int unit, 627 bcm_ptp_stack_id_t ptp_id, 628 int clock_num, 629 int idx, 630 int8 *log_sync_int) 631 { 632 if ((idx < PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES) && (idx < num_signaled_masters)) 633 *log_sync_int = signaled_master[idx].granted_log_sync_interval; 634 return BCM_E_NONE; 635 636 return BCM_E_BADID; 637 } 638 639 int _bcm_ptp_signaled_unicast_master_log_delay_int_get( 640 int unit, 641 bcm_ptp_stack_id_t ptp_id, 642 int clock_num, 643 int idx, 644 int8 *log_delay_int) 645 { 646 if ((idx < PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES) && (idx < num_signaled_masters)) 647 *log_delay_int = signaled_master[idx].granted_log_delay_interval; 648 return BCM_E_NONE; 649 650 return BCM_E_BADID; 651 } 652 653 int 654 _bcm_ptp_signaled_unicast_master_log_int_get( 655 int unit, 656 bcm_ptp_stack_id_t ptp_id, 657 int clock_num, 658 bcm_ptp_port_identity_t *master_portId, 659 int *inst_num, 660 int8 *log_sync_int, 661 int8 *log_delay_int) 662 { 663 int idx; 664 665 for (idx = 0; idx < num_signaled_masters; ++idx) { 666 if (_bcm_ptp_peer_portid_compare((bcm_ptp_port_identity_t *)&signaled_master[idx].master, 667 master_portId)) { 668 *inst_num = idx; 669 *log_sync_int = signaled_master[idx].granted_log_sync_interval; 670 *log_delay_int = signaled_master[idx].granted_log_delay_interval; 671 return BCM_E_NONE; 672 } 673 } 674 675 return BCM_E_NOT_FOUND; 676 } 677 #endif 678 679 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */ 680 681 /* 682 * Function: 683 * bcm_common_ptp_signaled_unicast_master_add 684 * Purpose: 685 * Add an entry to the signaled unicast master table. 686 * Parameters: 687 * unit - (IN) Unit number. 688 * ptp_id - (IN) PTP stack ID. 689 * clock_num - (IN) PTP clock number. 690 * port_num - (IN) PTP clock port number. 691 * master_info - (IN) Unicast master. 692 * flags - (IN) Signaled unicast master configuration flags. 693 * Returns: 694 * BCM_E_XXX - Function status. 695 * Notes: 696 */ 697 int 698 bcm_common_ptp_signaled_unicast_master_add( 699 int unit, 700 bcm_ptp_stack_id_t ptp_id, 701 int clock_num, 702 int port_num, 703 bcm_ptp_clock_unicast_master_t *master_info, 704 uint32 flags) 705 { 706 int rv; 707 int idx; 708 sal_time_t t; 709 710 _bcm_ptp_port_state_t portState; 711 712 SHR_BITDCL reqmask = flags; 713 714 /* Telecom profile support. */ 715 bcm_ptp_clock_port_address_t address; 716 717 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 718 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 719 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 720 return rv; 721 } 722 723 if (!signaling_initialized) { 724 _bcm_ptp_signaled_unicast_master_table_init(unit, ptp_id); 725 } 726 727 /* Do not add unicast master if portState is DISABLED. */ 728 if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_port_state_get(unit, 729 ptp_id, clock_num, port_num, &portState))) { 730 return rv; 731 } else if (portState == _bcm_ptp_state_disabled) { 732 return BCM_E_DISABLED; 733 } 734 735 /* 736 * Scan signaled unicast master table for an entry with matching address. 737 * If match found, indexing logic shall replace existing entry. 738 * Otherwise, indexing logic shall append a new entry to table. 739 */ 740 for (idx = 0; idx < num_signaled_masters; ++idx) { 741 if (_bcm_ptp_peer_address_compare(&signaled_master[idx].master.peer_address, 742 &master_info->address)) { 743 break; 744 } 745 } 746 747 if (idx == PTP_MAX_UNICAST_MASTER_TABLE_ENTRIES) { 748 return BCM_E_FULL; 749 } 750 751 signaled_master[idx].master.peer_address = master_info->address; 752 signaled_master[idx].master.local_port_number = port_num; 753 signaled_master[idx].master.remote_port_number = BCM_PTP_ANY_PORT; 754 sal_memcpy(signaled_master[idx].master.clock_identity, 755 BCM_PTP_ALL_CLOCKS, sizeof(bcm_ptp_clock_identity_t)); 756 757 signaled_master[idx].log_announce_interval = master_info->log_announce_interval; 758 signaled_master[idx].log_sync_interval = master_info->log_sync_interval; 759 signaled_master[idx].log_delay_interval = master_info->log_min_delay_request_interval; 760 761 /* Before telling firmware to add the master, indicate that DelReqs are not yet allowed */ 762 master_info->log_min_delay_request_interval = BCM_PTP_SIGNAL_LOGINTERMSG_PERIOD_NONGRANT; 763 764 if (BCM_FAILURE(rv = bcm_ptp_static_unicast_master_add(unit, ptp_id, clock_num, 765 port_num, master_info))) { 766 return rv; 767 } 768 769 /* Register PTP message services. */ 770 if (SHR_BITGET(&reqmask, PTP_SIGNALING_ANNOUNCE_SERVICE_BIT)) { 771 signaled_master[idx].service_enable.announce = 1; 772 } else { 773 signaled_master[idx].service_enable.announce = 0; 774 } 775 if (SHR_BITGET(&reqmask, PTP_SIGNALING_SYNC_SERVICE_BIT)) { 776 signaled_master[idx].service_enable.sync = 1; 777 } else { 778 signaled_master[idx].service_enable.sync = 0; 779 } 780 if (SHR_BITGET(&reqmask, PTP_SIGNALING_DELAYRESP_SERVICE_BIT)) { 781 signaled_master[idx].service_enable.delayresp = 1; 782 } else { 783 signaled_master[idx].service_enable.delayresp = 0; 784 } 785 786 signaled_master[idx].service_grants.announce = 0; 787 signaled_master[idx].service_grants.sync = 0; 788 signaled_master[idx].service_grants.delayresp = 0; 789 790 signaled_master[idx].to_ack_cancel.announce = 0; 791 signaled_master[idx].to_ack_cancel.sync = 0; 792 signaled_master[idx].to_ack_cancel.delayresp = 0; 793 794 signaled_master[idx].unmet_requests.announce = 0; 795 signaled_master[idx].unmet_requests.sync = 0; 796 signaled_master[idx].unmet_requests.delayresp = 0; 797 798 /* 2 seconds: plenty long to get signaling response */ 799 signaled_master[idx].granted_log_sync_interval = 1; 800 signaled_master[idx].granted_log_delay_interval = BCM_PTP_SIGNAL_LOGINTERMSG_PERIOD_NONGRANT; 801 802 t = _bcm_ptp_monotonic_time(); 803 signaled_master[idx].announce_refresh_time = t; 804 signaled_master[idx].sync_refresh_time = t; 805 signaled_master[idx].delay_refresh_time = t; 806 807 if (master_info->log_query_interval < 0) { 808 signaled_master[idx].query_interval_sec = 1; 809 } else { 810 signaled_master[idx].query_interval_sec = (1 << master_info->log_query_interval); 811 } 812 813 signaled_master[idx].durationField = request_uc_durationField; 814 signaled_master[idx].sequenceId = 0; 815 816 if (idx == num_signaled_masters) { 817 num_signaled_masters++; 818 } 819 820 /* 821 * Telecom profile support. 822 * Register signaled unicast master in packet master array. 823 */ 824 _bcm_ptp_peer_address_convert(&master_info->address, &address); 825 if (BCM_FAILURE(rv = bcm_ptp_telecom_g8265_packet_master_add(unit, ptp_id, 826 clock_num, port_num, &address))) { 827 return rv; 828 } 829 830 #ifdef BCM_PTP_EXT_SERVO_SUPPORT 831 signaled_master[idx].update_servo = 1; 832 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */ 833 834 return BCM_E_NONE; 835 } 836 837 838 /* 839 * Function: 840 * bcm_common_ptp_signaled_unicast_master_remove 841 * Purpose: 842 * Remove an entry from the signaled unicast master table. 843 * Parameters: 844 * unit - (IN) Unit number. 845 * ptp_id - (IN) PTP stack ID. 846 * clock_num - (IN) PTP clock number. 847 * port_num - (IN) PTP clock port number. 848 * master_info - (IN) Unicast master. 849 * Returns: 850 * BCM_E_XXX - Function status. 851 * Notes: 852 */ 853 int 854 bcm_common_ptp_signaled_unicast_master_remove( 855 int unit, 856 bcm_ptp_stack_id_t ptp_id, 857 int clock_num, 858 int port_num, 859 bcm_ptp_clock_peer_address_t *address) 860 { 861 int status; 862 int idx = 0; 863 int rv; 864 865 /* Telecom profile support. */ 866 bcm_ptp_clock_port_address_t profile_address; 867 #ifdef BCM_PTP_EXT_SERVO_SUPPORT 868 bcm_ptp_port_identity_t mstr_portId; 869 int inst_num; 870 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */ 871 872 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 873 clock_num, port_num))) { 874 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 875 return rv; 876 } 877 878 status = bcm_ptp_static_unicast_master_remove(unit, ptp_id, clock_num, port_num, address); 879 if (status != BCM_E_NONE) { 880 return status; 881 } 882 883 _bcm_ptp_peer_address_convert(address, &profile_address); 884 885 while (idx < num_signaled_masters) { 886 if (_bcm_ptp_peer_address_compare(&signaled_master[idx].master.peer_address, 887 address)) { 888 /* Cancel active unicast message services. */ 889 _bcm_ptp_master_active_service_cancel(unit, ptp_id, clock_num, 890 &signaled_master[idx], bcmPTP_MESSAGE_TYPE_ANNOUNCE); 891 _bcm_ptp_master_active_service_cancel(unit, ptp_id, clock_num, 892 &signaled_master[idx], bcmPTP_MESSAGE_TYPE_SYNC); 893 _bcm_ptp_master_active_service_cancel(unit, ptp_id, clock_num, 894 &signaled_master[idx], bcmPTP_MESSAGE_TYPE_DELAY_RESP); 895 896 #ifdef BCM_PTP_EXT_SERVO_SUPPORT 897 sal_memcpy(mstr_portId.clock_identity, &signaled_master[idx].master.clock_identity, sizeof(bcm_ptp_clock_identity_t)); 898 mstr_portId.port_number= signaled_master[idx].master.remote_port_number; 899 900 if (BCM_FAILURE(rv = _bcm_ptp_ext_servo_master_table_entry_delete(unit, ptp_id, clock_num, &mstr_portId, &profile_address, 1, &inst_num))) { 901 PTP_ERROR_FUNC("_bcm_ptp_ext_servo_master_table_entry_delete()"); 902 inst_num = idx; 903 } 904 905 if (BCM_FAILURE(rv = _bcm_ptp_servo_master_remove(unit, ptp_id, clock_num, inst_num, 1, &mstr_portId, NULL, &profile_address))) { 906 PTP_ERROR_FUNC("_bcm_ptp_servo_master_remove()"); 907 } 908 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */ 909 910 /* Swap the last entry into this place, then decrement total number. Could be in place... */ 911 signaled_master[idx] = signaled_master[--num_signaled_masters]; 912 } else { 913 ++idx; 914 } 915 } 916 917 if (BCM_FAILURE(rv = bcm_ptp_telecom_g8265_packet_master_remove(unit, ptp_id, 918 clock_num, port_num, &profile_address))) { 919 return rv; 920 } 921 922 return BCM_E_NONE; 923 } 924 925 926 /* 927 * Function: 928 * bcm_ptp_signaled_unicast_slave_list 929 * Purpose: 930 * List the signaled unicast slaves. 931 * Parameters: 932 * unit - (IN) Unit number. 933 * ptp_id - (IN) PTP stack ID. 934 * clock_num - (IN) PTP clock number. 935 * port_num - (IN) PTP clock port number. 936 * max_num_slaves - (IN) Maximum number of signaled unicast slaves. 937 * num_slaves - (OUT) Number of signaled unicast slaves. 938 * slave_table - (OUT) Signaled unicast slave table. 939 * Returns: 940 * BCM_E_XXX - Function status. 941 * Notes: 942 */ 943 int 944 bcm_common_ptp_signaled_unicast_slave_list ( 945 int unit, 946 bcm_ptp_stack_id_t ptp_id, 947 int clock_num, 948 int port_num, 949 int max_num_slaves, 950 int *num_slaves, 951 bcm_ptp_clock_peer_t *slave_table) 952 { 953 int i; 954 int rv; 955 956 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 957 clock_num, port_num))) { 958 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 959 return rv; 960 } 961 962 BCM_PTP_SLAVETABLE_MUTEX_TAKE(); 963 964 if (signaled_slave_table.num_entries > max_num_slaves) { 965 /* Insufficient caller-provided table size for result. */ 966 *num_slaves = 0; 967 968 BCM_PTP_SLAVETABLE_MUTEX_RELEASE_RETURN(BCM_E_RESOURCE); 969 } 970 971 *num_slaves = signaled_slave_table.num_entries; 972 973 for (i = 0; i < (*num_slaves); ++i) { 974 slave_table[i] = signaled_slave_table.entry[i].slave.peer; 975 } 976 977 BCM_PTP_SLAVETABLE_MUTEX_RELEASE_RETURN(rv); 978 } 979 980 981 /* 982 * Function: 983 */ 984 static int 985 _bcm_ptp_signaled_unicast_slave_exists( 986 int unit, 987 bcm_ptp_stack_id_t ptp_id, 988 _bcm_ptp_clock_peer_ext_t *slave, 989 int *index) 990 { 991 int i; 992 for (i = 0; i < signaled_slave_table.num_entries; ++i) { 993 if (_bcm_ptp_peer_address_compare(&signaled_slave_table.entry[i].slave.peer.peer_address, 994 &slave->peer.peer_address)) { 995 /* Entry exists. */ 996 *index = i; 997 return BCM_E_NONE; 998 } 999 } 1000 1001 *index = -1; 1002 return BCM_E_NOT_FOUND; 1003 } 1004 1005 /* 1006 * Function: 1007 */ 1008 static int 1009 _bcm_ptp_signaled_unicast_slave_add( 1010 int unit, 1011 bcm_ptp_stack_id_t ptp_id, 1012 _bcm_ptp_clock_peer_ext_t *slave) 1013 { 1014 int i; 1015 int rv; 1016 _bcm_ptp_info_t *ptp_info_p; 1017 1018 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1019 PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1020 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1021 return rv; 1022 } 1023 1024 SET_PTP_INFO; 1025 1026 if (signaled_slave_table.num_entries >= ptp_info_p->stack_info->unicast_slave_table_size) { 1027 /* Signaled unicast slave table full. */ 1028 return BCM_E_FULL; 1029 } 1030 1031 /* Add entry. */ 1032 i = signaled_slave_table.num_entries++; 1033 signaled_slave_table.entry[i] = signaled_slave_entry_default; 1034 signaled_slave_table.entry[i].slave = *slave; 1035 1036 return BCM_E_NONE; 1037 } 1038 1039 /* 1040 * Function: 1041 */ 1042 static int 1043 _bcm_ptp_signaled_unicast_slave_remove( 1044 int unit, 1045 bcm_ptp_stack_id_t ptp_id, 1046 _bcm_ptp_clock_peer_ext_t *slave) 1047 { 1048 int i = 0; 1049 int k = 0; 1050 int rv; 1051 1052 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1053 PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1054 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1055 return rv; 1056 } 1057 1058 while (i < signaled_slave_table.num_entries) { 1059 if (_bcm_ptp_peer_address_compare(&slave->peer.peer_address, 1060 &signaled_slave_table.entry[i].slave.peer.peer_address)) { 1061 /* 1062 * Remove entry. 1063 * Move last entry into this slot, and decrement number of entries. 1064 */ 1065 signaled_slave_table.entry[i] = 1066 signaled_slave_table.entry[--signaled_slave_table.num_entries]; 1067 1068 /* Reset unused entry. */ 1069 signaled_slave_table.entry[signaled_slave_table.num_entries] = 1070 signaled_slave_entry_default; 1071 1072 ++k; 1073 } else { 1074 ++i; 1075 } 1076 } 1077 1078 if (k > 0) { 1079 return BCM_E_NONE; 1080 } else { 1081 /* No matching peer address(es) in signaled unicast slave table. */ 1082 return BCM_E_NOT_FOUND; 1083 } 1084 } 1085 1086 /* 1087 * Function: 1088 */ 1089 static int 1090 _bcm_ptp_signaled_unicast_slave_expire( 1091 int unit, 1092 bcm_ptp_stack_id_t ptp_id) 1093 { 1094 int i; 1095 int rv; 1096 sal_time_t t = _bcm_ptp_monotonic_time(); 1097 1098 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1099 PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1100 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1101 return rv; 1102 } 1103 1104 /* 1105 * Tag signaled slave announce, sync, and delay response services that 1106 * are to expire. 1107 */ 1108 for (i = 0; i < signaled_slave_table.num_entries; ++i) { 1109 if ((!signaled_slave_table.entry[i].announce_service_active) || 1110 (signaled_slave_table.entry[i].queue_announce_grant) || 1111 (signaled_slave_table.entry[i].announce_grant_time + 1112 signaled_slave_table.entry[i].announce_duration >= t)) { 1113 signaled_slave_table.entry[i].queue_announce_expire = 0; 1114 } else { 1115 signaled_slave_table.entry[i].queue_announce_expire = 1; 1116 } 1117 1118 if ((!signaled_slave_table.entry[i].sync_service_active) || 1119 (signaled_slave_table.entry[i].queue_sync_grant) || 1120 (signaled_slave_table.entry[i].sync_grant_time + 1121 signaled_slave_table.entry[i].sync_duration >= t)) { 1122 signaled_slave_table.entry[i].queue_sync_expire = 0; 1123 } else { 1124 signaled_slave_table.entry[i].queue_sync_expire = 1; 1125 } 1126 1127 if ((!signaled_slave_table.entry[i].delay_service_active) || 1128 (signaled_slave_table.entry[i].queue_delay_grant) || 1129 (signaled_slave_table.entry[i].delay_grant_time + 1130 signaled_slave_table.entry[i].delay_duration >= t)) { 1131 signaled_slave_table.entry[i].queue_delay_expire = 0; 1132 } else { 1133 signaled_slave_table.entry[i].queue_delay_expire = 1; 1134 } 1135 } 1136 1137 return BCM_E_NONE; 1138 } 1139 1140 /* 1141 * Function: 1142 */ 1143 static int 1144 _bcm_ptp_signaled_unicast_slave_table_update( 1145 int unit, 1146 bcm_ptp_stack_id_t ptp_id) 1147 { 1148 int i; 1149 int rv; 1150 int num_entries; 1151 1152 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1153 PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1154 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1155 return rv; 1156 } 1157 /* 1158 * Remove inactive/expired slaves from signaled unicast slave table. 1159 * NOTICE: Process table in reverse given logic in removal function 1160 * _bcm_ptp_signaled_unicast_slave_remove() to reorder entries. 1161 */ 1162 num_entries = signaled_slave_table.num_entries; 1163 for (i = (num_entries-1); i >= 0; --i) { 1164 if ((signaled_slave_table.entry[i].queue_announce_grant == 0) && 1165 (signaled_slave_table.entry[i].queue_sync_grant == 0) && 1166 (signaled_slave_table.entry[i].queue_delay_grant == 0) && 1167 (signaled_slave_table.entry[i].queue_announce_cancel == 0) && 1168 (signaled_slave_table.entry[i].queue_sync_cancel == 0) && 1169 (signaled_slave_table.entry[i].queue_delay_cancel == 0) && 1170 (signaled_slave_table.entry[i].queue_announce_expire == 0) && 1171 (signaled_slave_table.entry[i].queue_sync_expire == 0) && 1172 (signaled_slave_table.entry[i].queue_delay_expire == 0) && 1173 (signaled_slave_table.entry[i].announce_service_active == 0) && 1174 (signaled_slave_table.entry[i].sync_service_active == 0) && 1175 (signaled_slave_table.entry[i].delay_service_active == 0)) { 1176 /* 1177 * Remove slave. 1178 * No pending unicast grant, cancel, or acknowledge cancel TLVs to send. 1179 * All slave announce, sync, and delay services are inactive or expired. 1180 */ 1181 _bcm_ptp_clock_peer_ext_t slave = signaled_slave_table.entry[i].slave; 1182 _bcm_ptp_signaled_unicast_slave_remove(unit, ptp_id, &slave); 1183 } 1184 } 1185 1186 return BCM_E_NONE; 1187 } 1188 1189 /* 1190 * Function: 1191 */ 1192 static int 1193 send_unicast_request( 1194 int unit, 1195 bcm_ptp_stack_id_t ptp_id, 1196 int clock_num, 1197 int num_tlvs, 1198 int *type, 1199 int8 *log_inter_message_period, 1200 uint32 durationField, 1201 uint16 sequenceId, 1202 bcm_ptp_clock_peer_t *master) 1203 { 1204 int rv = BCM_E_NONE; 1205 int i; 1206 1207 bcm_ptp_port_identity_t local_port; 1208 bcm_ptp_clock_port_address_t master_addr; 1209 bcm_ptp_clock_info_t ci; 1210 bcm_ptp_clock_port_info_t pi; 1211 1212 int tlvLen; 1213 int udpLen; 1214 int packet_len; 1215 uint8 udp[BCM_PTP_SIGNAL_MAX_UDP_PAYLOAD_SIZE_OCTETS] = {0}; 1216 uint8 packet[BCM_PTP_SIGNAL_MAX_PKT_SIZE_OCTETS] = {0}; 1217 uint8 tlv[BCM_PTP_SIGNAL_MAX_TLV_SIZE_OCTETS] = {0}; 1218 uint8 multi_tlv_en = 0; 1219 uint8 domain; 1220 1221 static int failure_count = 0; 1222 static const int failure_log_threshold = 10; 1223 1224 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1225 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1226 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1227 return rv; 1228 } 1229 1230 if (BCM_SUCCESS(rv = bcm_ptp_clock_get(unit, ptp_id, clock_num, &ci))) { 1231 multi_tlv_en = (SHR_BITGET(&ci.flags, PTP_CLOCK_FLAGS_SIGNALING_MULTI_TLV_BIT) || 1232 SHR_BITGET(&ci.flags, PTP_CLOCK_FLAGS_TELECOM_PROFILE_BIT)); 1233 } 1234 1235 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 1236 clock_num, master->local_port_number, &local_port))) { 1237 PTP_ERROR_FUNC("bcm_common_ptp_clock_port_identity_get()"); 1238 return rv; 1239 } 1240 1241 if (BCM_FAILURE(rv = bcm_ptp_clock_port_info_get(unit, ptp_id, clock_num, 1242 local_port.port_number, &pi))) { 1243 PTP_ERROR_FUNC("bcm_ptp_clock_port_info_get()"); 1244 return rv; 1245 } 1246 1247 if (BCM_FAILURE(rv = _bcm_ptp_management_domain_get(unit, ptp_id, clock_num, 1248 &domain))) { 1249 PTP_ERROR_FUNC("_bcm_ptp_management_domain_get()"); 1250 return rv; 1251 } 1252 1253 if (BCM_FAILURE(rv = _bcm_ptp_construct_signaling_msg(&local_port, 1254 master->clock_identity, master->remote_port_number, 1255 domain, sequenceId, 0, 0, udp, &udpLen))) { 1256 PTP_ERROR_FUNC("_bcm_ptp_construct_signaling_msg()"); 1257 return rv; 1258 } 1259 1260 if (num_tlvs > 1 && multi_tlv_en == 0) { 1261 LOG_VERBOSE(BSL_LS_BCM_COMMON, 1262 (BSL_META_U(unit, 1263 "Multiple TLV support not enabled\n"))); 1264 return BCM_E_CONFIG; 1265 } 1266 1267 for (i = 0; i < num_tlvs; ++i) { 1268 if (BCM_FAILURE(rv = _bcm_ptp_construct_signaling_request_tlv(type[i], 1269 log_inter_message_period[i], durationField, tlv, &tlvLen))) { 1270 PTP_ERROR_FUNC("_bcm_ptp_construct_signaling_request_tlv()"); 1271 return rv; 1272 } 1273 1274 if (BCM_FAILURE(rv = _bcm_ptp_signaling_message_append_tlv(udp, &udpLen, 1275 tlv, tlvLen))) { 1276 PTP_ERROR_FUNC("_bcm_ptp_signaling_message_append_tlv()"); 1277 return rv; 1278 } 1279 } 1280 1281 if (BCM_FAILURE(rv = _bcm_ptp_construct_udp_packet(master, &pi.port_address, 1282 udp, udpLen, packet, &packet_len))) { 1283 PTP_ERROR_FUNC("_bcm_ptp_construct_udp_packet()"); 1284 return rv; 1285 } 1286 1287 if (BCM_FAILURE(rv = _bcm_ptp_peer_address_convert(&master->peer_address, &master_addr))) { 1288 PTP_ERROR_FUNC("_bcm_ptp_peer_address_convert()"); 1289 return rv; 1290 } 1291 if (BCM_FAILURE(rv = _bcm_ptp_update_peer_counts(unit, ptp_id, clock_num, 1292 master->local_port_number, 0, &master_addr, 1293 1, 0, 0, 0, 0, 0, 0, 1, 0, NULL))) { 1294 PTP_ERROR_FUNC("_bcm_ptp_update_peer_counts()"); 1295 return rv; 1296 } 1297 if (BCM_FAILURE(rv = _bcm_ptp_tunnel_message_to_world(unit, ptp_id, clock_num, 1298 packet_len, packet, 0))) { 1299 if (++failure_count > failure_log_threshold) { 1300 LOG_ERROR(BSL_LS_BCM_PTP, 1301 (BSL_META_U(unit, 1302 "Repeated PTP failures sending signaling message\n"))); 1303 } else { 1304 LOG_VERBOSE(BSL_LS_BCM_PTP, 1305 (BSL_META_U(unit, 1306 "PTP failed sending signaling message\n"))); 1307 } 1308 return rv; 1309 } else { 1310 failure_count = 0; 1311 } 1312 1313 return BCM_E_NONE; 1314 } 1315 1316 /* 1317 * Function: 1318 * _bcm_ptp_master_active_service_cancel 1319 * Purpose: 1320 * Cancel unicast message service (|Announce|Sync|Delay_Resp|) of unicast master. 1321 * Parameters: 1322 * unit - (IN) Unit number. 1323 * ptp_id - (IN) PTP stack ID. 1324 * clock_num - (IN) PTP clock number. 1325 * entry - (IN/OUT) Signaled unicast master table entry. 1326 * messageType - (IN) Unicast message service to cancel. 1327 * Returns: 1328 * BCM_E_XXX - Function status. 1329 * Notes: 1330 */ 1331 static int 1332 _bcm_ptp_master_active_service_cancel( 1333 int unit, 1334 bcm_ptp_stack_id_t ptp_id, 1335 int clock_num, 1336 signaled_master_t *entry, 1337 bcm_ptp_message_type_t messageType) 1338 { 1339 int rv; 1340 1341 bcm_ptp_port_identity_t local_port; 1342 bcm_ptp_clock_port_address_t master_addr; 1343 bcm_ptp_clock_port_info_t pi; 1344 uint8 domainNumber; 1345 1346 uint8 tlv[BCM_PTP_SIGNAL_MAX_TLV_SIZE_OCTETS] = {0}; 1347 uint8 udp[BCM_PTP_SIGNAL_MAX_UDP_PAYLOAD_SIZE_OCTETS] = {0}; 1348 uint8 packet[BCM_PTP_SIGNAL_MAX_PKT_SIZE_OCTETS] = {0}; 1349 int tlvLen; 1350 int udpLen; 1351 int packet_len; 1352 1353 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1354 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1355 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1356 return rv; 1357 } 1358 1359 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 1360 clock_num, entry->master.local_port_number, &local_port))) { 1361 PTP_ERROR_FUNC("bcm_common_ptp_clock_port_identity_get()"); 1362 return rv; 1363 } 1364 1365 if (BCM_FAILURE(rv = bcm_ptp_clock_port_info_get(unit, ptp_id, clock_num, 1366 local_port.port_number, &pi))) { 1367 PTP_ERROR_FUNC("bcm_ptp_clock_port_info_get()"); 1368 return rv; 1369 } 1370 1371 if (BCM_FAILURE(rv = _bcm_ptp_management_domain_get(unit, ptp_id, clock_num, 1372 &domainNumber))) { 1373 PTP_ERROR_FUNC("_bcm_ptp_management_domain_get()"); 1374 return rv; 1375 } 1376 1377 switch (messageType) { 1378 case bcmPTP_MESSAGE_TYPE_ANNOUNCE: 1379 if (0 == entry->service_grants.announce) { 1380 /* Do nothing. Announce service is not active. */ 1381 return BCM_E_NONE; 1382 } 1383 entry->service_grants.announce = 0; 1384 break; 1385 case bcmPTP_MESSAGE_TYPE_SYNC: 1386 if (0 == entry->service_grants.sync) { 1387 /* Do nothing. Sync service is not active. */ 1388 return BCM_E_NONE; 1389 } 1390 entry->service_grants.sync = 0; 1391 break; 1392 case bcmPTP_MESSAGE_TYPE_DELAY_RESP: 1393 if (0 == entry->service_grants.delayresp) { 1394 /* Do nothing. Delay_Resp service is not active. */ 1395 return BCM_E_NONE; 1396 } 1397 entry->service_grants.delayresp = 0; 1398 break; 1399 default: 1400 return BCM_E_PARAM; 1401 } 1402 1403 if (BCM_FAILURE(rv = _bcm_ptp_construct_signaling_cancel_tlv(messageType, 1404 tlv, &tlvLen))) { 1405 PTP_ERROR_FUNC("_bcm_ptp_construct_signaling_cancel_tlv()"); 1406 return rv; 1407 } 1408 1409 if (BCM_FAILURE(rv = _bcm_ptp_construct_signaling_msg(&local_port, 1410 entry->master.clock_identity, entry->master.remote_port_number, 1411 domainNumber, ++entry->sequenceId, tlv, tlvLen, udp, &udpLen))) { 1412 PTP_ERROR_FUNC("_bcm_ptp_construct_signaling_msg()"); 1413 return rv; 1414 } 1415 1416 if (BCM_FAILURE(rv = _bcm_ptp_construct_udp_packet(&entry->master, &pi.port_address, 1417 udp, udpLen, packet, &packet_len))) { 1418 PTP_ERROR_FUNC("_bcm_ptp_construct_udp_packet()"); 1419 return rv; 1420 } 1421 1422 if (BCM_FAILURE(rv = _bcm_ptp_peer_address_convert(&entry->master.peer_address, &master_addr))) { 1423 PTP_ERROR_FUNC("_bcm_ptp_peer_address_convert()"); 1424 return rv; 1425 } 1426 if (BCM_FAILURE(rv = _bcm_ptp_update_peer_counts(unit, ptp_id, clock_num, 1427 entry->master.local_port_number, 0, &master_addr, 1428 1, 0, 0, 0, 0, 0, 0, 1, 0, NULL))) { 1429 PTP_ERROR_FUNC("_bcm_ptp_update_peer_counts()"); 1430 return rv; 1431 } 1432 1433 if (BCM_FAILURE(rv = _bcm_ptp_tunnel_message_to_world(unit, ptp_id, clock_num, 1434 packet_len, packet, 0))) { 1435 PTP_ERROR_FUNC("_bcm_ptp_tunnel_message_to_world()"); 1436 return rv; 1437 } 1438 1439 return BCM_E_NONE; 1440 } 1441 1442 /* 1443 * Function: 1444 * _bcm_ptp_master_active_service_ack_cancel 1445 * Purpose: 1446 * Acknowledge cancellation of (|Announce|Sync|Delay_Resp|) message service by unicast master. 1447 * Parameters: 1448 * unit - (IN) Unit number. 1449 * ptp_id - (IN) PTP stack ID. 1450 * clock_num - (IN) PTP clock number. 1451 * entry - (IN/OUT) Signaled unicast master table entry. 1452 * messageType - (IN) Unicast message service to acknowledge cancellation. 1453 * Returns: 1454 * BCM_E_XXX - Function status. 1455 * Notes: 1456 */ 1457 static int 1458 _bcm_ptp_master_active_service_ack_cancel( 1459 int unit, 1460 bcm_ptp_stack_id_t ptp_id, 1461 int clock_num, 1462 signaled_master_t *entry, 1463 bcm_ptp_message_type_t messageType) 1464 { 1465 int rv; 1466 1467 bcm_ptp_port_identity_t local_port; 1468 bcm_ptp_clock_port_address_t master_addr; 1469 bcm_ptp_clock_port_info_t pi; 1470 uint8 domainNumber; 1471 1472 uint8 tlv[BCM_PTP_SIGNAL_MAX_TLV_SIZE_OCTETS] = {0}; 1473 uint8 udp[BCM_PTP_SIGNAL_MAX_UDP_PAYLOAD_SIZE_OCTETS] = {0}; 1474 uint8 packet[BCM_PTP_SIGNAL_MAX_PKT_SIZE_OCTETS] = {0}; 1475 int tlvLen; 1476 int udpLen; 1477 int packet_len; 1478 1479 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1480 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1481 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1482 return rv; 1483 } 1484 1485 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 1486 clock_num, entry->master.local_port_number, &local_port))) { 1487 PTP_ERROR_FUNC("bcm_common_ptp_clock_port_identity_get()"); 1488 return rv; 1489 } 1490 1491 if (BCM_FAILURE(rv = bcm_ptp_clock_port_info_get(unit, ptp_id, clock_num, 1492 local_port.port_number, &pi))) { 1493 PTP_ERROR_FUNC("bcm_ptp_clock_port_info_get()"); 1494 return rv; 1495 } 1496 1497 if (BCM_FAILURE(rv = _bcm_ptp_management_domain_get(unit, ptp_id, clock_num, 1498 &domainNumber))) { 1499 PTP_ERROR_FUNC("_bcm_ptp_management_domain_get()"); 1500 return rv; 1501 } 1502 1503 switch (messageType) { 1504 case bcmPTP_MESSAGE_TYPE_ANNOUNCE: 1505 if (0 == entry->to_ack_cancel.announce) { 1506 /* Do nothing. Announce service was not cancelled by master. */ 1507 return BCM_E_NONE; 1508 } 1509 entry->to_ack_cancel.announce = 0; 1510 break; 1511 case bcmPTP_MESSAGE_TYPE_SYNC: 1512 if (0 == entry->to_ack_cancel.sync) { 1513 /* Do nothing. Sync service was not cancelled by master. */ 1514 return BCM_E_NONE; 1515 } 1516 entry->to_ack_cancel.sync = 0; 1517 break; 1518 case bcmPTP_MESSAGE_TYPE_DELAY_RESP: 1519 if (0 == entry->to_ack_cancel.delayresp) { 1520 /* Do nothing. Delay_Resp service was not cancelled by master. */ 1521 return BCM_E_NONE; 1522 } 1523 entry->to_ack_cancel.delayresp = 0; 1524 break; 1525 default: 1526 return BCM_E_PARAM; 1527 } 1528 1529 if (BCM_FAILURE(rv = _bcm_ptp_construct_signaling_ack_cancel_tlv(messageType, 1530 tlv, &tlvLen))) { 1531 PTP_ERROR_FUNC("_bcm_ptp_construct_signaling_ack_cancel_tlv()"); 1532 return rv; 1533 } 1534 1535 if (BCM_FAILURE(rv = _bcm_ptp_construct_signaling_msg(&local_port, 1536 entry->master.clock_identity, entry->master.remote_port_number, 1537 domainNumber, ++entry->sequenceId, tlv, tlvLen, udp, &udpLen))) { 1538 PTP_ERROR_FUNC("_bcm_ptp_construct_signaling_msg()"); 1539 return rv; 1540 } 1541 1542 if (BCM_FAILURE(rv = _bcm_ptp_construct_udp_packet(&entry->master, &pi.port_address, 1543 udp, udpLen, packet, &packet_len))) { 1544 PTP_ERROR_FUNC("_bcm_ptp_construct_udp_packet()"); 1545 return rv; 1546 } 1547 1548 if (BCM_FAILURE(rv = _bcm_ptp_peer_address_convert(&entry->master.peer_address, &master_addr))) { 1549 PTP_ERROR_FUNC("_bcm_ptp_peer_address_convert()"); 1550 return rv; 1551 } 1552 if (BCM_FAILURE(rv = _bcm_ptp_update_peer_counts(unit, ptp_id, clock_num, 1553 entry->master.local_port_number, 0, &master_addr, 1554 1, 0, 0, 0, 0, 0, 0, 1, 0, NULL))) { 1555 PTP_ERROR_FUNC("_bcm_ptp_update_peer_counts()"); 1556 return rv; 1557 } 1558 1559 if (BCM_FAILURE(rv = _bcm_ptp_tunnel_message_to_world(unit, ptp_id, clock_num, 1560 packet_len, packet, 1))) { 1561 PTP_ERROR_FUNC("_bcm_ptp_tunnel_message_to_world()"); 1562 return rv; 1563 } 1564 1565 return BCM_E_NONE; 1566 } 1567 1568 /* 1569 * Function: 1570 */ 1571 static int 1572 _bcm_ptp_slave_signaling_send( 1573 int unit, 1574 bcm_ptp_stack_id_t ptp_id, 1575 int clock_num, 1576 bcm_ptp_tlv_type_t tlv_type, 1577 bcm_ptp_message_type_t msg_type, 1578 int8 log_intermessage_period, 1579 uint32 duration, 1580 uint16 sequenceId, 1581 _bcm_ptp_clock_peer_ext_t *slave, 1582 int async) 1583 { 1584 bcm_ptp_port_identity_t local_port_id; 1585 bcm_ptp_clock_port_address_t slave_addr; 1586 uint8 tlv[BCM_PTP_SIGNAL_MAX_TLV_SIZE_OCTETS]; 1587 uint8 udp[BCM_PTP_SIGNAL_MAX_UDP_PAYLOAD_SIZE_OCTETS]; 1588 uint8 packet[BCM_PTP_SIGNAL_MAX_PKT_SIZE_OCTETS]; 1589 int packet_len; 1590 int udpLen; 1591 int tlvLen; 1592 int rv; 1593 uint8 domain; 1594 1595 static int failure_count = 0; 1596 static const int failure_log_threshold = 10; 1597 1598 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1599 clock_num, slave->peer.local_port_number))) { 1600 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1601 return rv; 1602 } 1603 1604 if (BCM_FAILURE(bcm_common_ptp_clock_port_identity_get(unit, ptp_id, clock_num, 1605 slave->peer.local_port_number, &local_port_id))) { 1606 return BCM_E_PARAM; 1607 } 1608 1609 switch (tlv_type) { 1610 case bcmPTPTlvTypeGrantUnicastTransmission: 1611 _bcm_ptp_construct_signaling_grant_tlv(msg_type, log_intermessage_period, 1612 duration, renewal_invited, tlv, &tlvLen); 1613 break; 1614 1615 case bcmPTPTlvTypeCancelUnicastTransmission: 1616 _bcm_ptp_construct_signaling_cancel_tlv(msg_type, tlv, &tlvLen); 1617 break; 1618 1619 case bcmPTPTlvTypeAckCancelUnicastTransmission: 1620 _bcm_ptp_construct_signaling_ack_cancel_tlv(msg_type, tlv, &tlvLen); 1621 break; 1622 1623 default: 1624 LOG_VERBOSE(BSL_LS_BCM_COMMON, 1625 (BSL_META_U(unit, 1626 "Unknown or unsupported TLV type\n"))); 1627 return BCM_E_PARAM; 1628 } 1629 1630 _bcm_ptp_management_domain_get(unit, ptp_id, clock_num, &domain); 1631 _bcm_ptp_construct_signaling_msg(&local_port_id, slave->peer.clock_identity, 1632 slave->peer.remote_port_number, domain, sequenceId, tlv, tlvLen, udp, &udpLen); 1633 1634 _bcm_ptp_construct_udp_packet(&slave->peer, &slave->local_address, udp, udpLen, packet, &packet_len); 1635 1636 #if 0 1637 bsl_printf(" _bcm_ptp_construct_signaling_msg: UDP payload len[%d]\n", udpLen); 1638 _bcm_ptp_dump_hex(udp, udpLen, 0); 1639 bsl_printf(" _bcm_ptp_construct_signaling_msg: packet: len[%d]\n", packet_len); 1640 _bcm_ptp_dump_hex(packet, packet_len, 0); 1641 #endif 1642 1643 if (BCM_FAILURE(rv = _bcm_ptp_peer_address_convert(&slave->peer.peer_address, &slave_addr))) { 1644 PTP_ERROR_FUNC("_bcm_ptp_peer_address_convert()"); 1645 return rv; 1646 } 1647 if (BCM_FAILURE(rv = _bcm_ptp_update_peer_counts(unit, ptp_id, clock_num, 1648 slave->peer.local_port_number, 0, &slave_addr, 1649 1, 0, 0, 0, 0, 0, 0, 1, 0, NULL))) { 1650 PTP_ERROR_FUNC("_bcm_ptp_update_peer_counts()"); 1651 return rv; 1652 } 1653 1654 if (BCM_FAILURE(rv = _bcm_ptp_tunnel_message_to_world(unit, ptp_id, clock_num, 1655 packet_len, packet, async))) 1656 { 1657 if (++failure_count > failure_log_threshold) { 1658 LOG_ERROR(BSL_LS_BCM_COMMON, 1659 (BSL_META_U(unit, 1660 "Repeated PTP failures sending signaling message to %s slave\n"), 1661 (async) ? "async" : "")); 1662 } else { 1663 LOG_VERBOSE(BSL_LS_BCM_COMMON, 1664 (BSL_META_U(unit, 1665 "PTP failure sending signaling message to %s slave\n"), 1666 (async) ? "async" : "")); 1667 } 1668 } else { 1669 failure_count = 0; 1670 } 1671 1672 return BCM_E_NONE; 1673 } 1674 1675 /* 1676 * Function: 1677 * send_pending_signaling_to_masters 1678 * Purpose: 1679 * Send any necessary signaling messages to masters (as DPC). 1680 * Parameters: 1681 * arg_unit - (IN) Unit number (as void**). 1682 * arg_ptp_id - (IN) PTP stack ID (as void**). 1683 * arg_clock_num - (IN) PTP clock number (as void**). 1684 * unused - (IN) Unused. 1685 * Returns: 1686 * time interval before next call 1687 * Notes: 1688 */ 1689 static sal_usecs_t 1690 send_pending_signaling_to_masters( 1691 void **arg_unit, 1692 void **arg_ptp_id, 1693 void **arg_clock_num, 1694 void **unused) 1695 { 1696 int i; 1697 int rv; 1698 1699 int unit = PTR_TO_INT(*arg_unit); 1700 bcm_ptp_stack_id_t ptp_id = (bcm_ptp_stack_id_t)PTR_TO_INT(*arg_ptp_id); 1701 int clock_num = PTR_TO_INT(*arg_clock_num); 1702 1703 sal_time_t ref_time; 1704 int messageType[BCM_PTP_SIGNAL_MAX_TLV_PER_MESSAGE] = {0}; 1705 int8 logInterMessagePeriod[BCM_PTP_SIGNAL_MAX_TLV_PER_MESSAGE] = {0}; 1706 int num_tlvs = 0; 1707 uint8 multi_tlv_en = 0; 1708 uint8 telecom_en = 0; 1709 1710 bcm_ptp_clock_info_t ci; 1711 _bcm_ptp_port_state_t portState; 1712 1713 /* Note: to prevent flooding, the DPC sends only one message per call, but will reschedule for a short 1714 interval later if it does send something */ 1715 1716 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 1717 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 1718 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 1719 return BCM_PTP_SIGNAL_DEFAULT_MASTER_DPC_TIME_USEC; /* retry at default interval */ 1720 } 1721 1722 if (BCM_FAILURE(rv = bcm_ptp_clock_get(unit, ptp_id, clock_num, &ci))) { 1723 return BCM_PTP_SIGNAL_DEFAULT_MASTER_DPC_TIME_USEC; /* retry at default interval */ 1724 } 1725 1726 telecom_en = SHR_BITGET(&ci.flags, PTP_CLOCK_FLAGS_TELECOM_PROFILE_BIT); 1727 multi_tlv_en = (SHR_BITGET(&ci.flags, PTP_CLOCK_FLAGS_SIGNALING_MULTI_TLV_BIT) || 1728 telecom_en); 1729 1730 /* Acknowledge any unanswered cancellations from master(s). */ 1731 for (i = 0; i < num_signaled_masters; ++i) { 1732 if (signaled_master[i].to_ack_cancel.announce) { 1733 _bcm_ptp_master_active_service_ack_cancel(unit, ptp_id, clock_num, 1734 &signaled_master[i], bcmPTP_MESSAGE_TYPE_ANNOUNCE); 1735 return BCM_PTP_SIGNAL_MIN_MASTER_DPC_TIME_USEC; 1736 } else if (signaled_master[i].to_ack_cancel.sync) { 1737 _bcm_ptp_master_active_service_ack_cancel(unit, ptp_id, clock_num, 1738 &signaled_master[i], bcmPTP_MESSAGE_TYPE_SYNC); 1739 return BCM_PTP_SIGNAL_MIN_MASTER_DPC_TIME_USEC; 1740 } else if (signaled_master[i].to_ack_cancel.delayresp) { 1741 _bcm_ptp_master_active_service_ack_cancel(unit, ptp_id, clock_num, 1742 &signaled_master[i], bcmPTP_MESSAGE_TYPE_DELAY_RESP); 1743 return BCM_PTP_SIGNAL_MIN_MASTER_DPC_TIME_USEC; 1744 } 1745 } 1746 1747 /* we haven't sent anything yet, so loop through masters to find something to send */ 1748 for (i = 0; i < num_signaled_masters; ++i) { 1749 ref_time = _bcm_ptp_monotonic_time(); 1750 1751 if (signaled_master[i].master.local_port_number == 0) { 1752 continue; 1753 } 1754 /* Check local port state; do not send signaling messages if portState is DISABLED. */ 1755 if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_port_state_get(unit, ptp_id, clock_num, 1756 signaled_master[i].master.local_port_number, &portState)) || 1757 portState == _bcm_ptp_state_disabled) { 1758 continue; 1759 } 1760 1761 if (signaled_master[i].service_enable.announce && 1762 signaled_master[i].announce_refresh_time && 1763 signaled_master[i].announce_refresh_time < ref_time) { 1764 messageType[num_tlvs] = bcmPTP_MESSAGE_TYPE_ANNOUNCE; 1765 logInterMessagePeriod[num_tlvs++] = signaled_master[i].log_announce_interval; 1766 1767 /* 1768 * Increment counter of unanswered/denied Announce service requests. 1769 * Do not rollover. 1770 */ 1771 if (signaled_master[i].unmet_requests.announce < ((uint8)-1)) { 1772 ++signaled_master[i].unmet_requests.announce; 1773 } 1774 1775 /* 1776 * Set the time to send the next signaling message. 1777 * Will be overwritten if we get a master response. 1778 */ 1779 if ((telecom_en == 0) || 1780 (signaled_master[i].unmet_requests.announce < 1781 BCM_PTP_SIGNAL_TELECOM_UNMET_REQUEST_MAX)) { 1782 signaled_master[i].announce_refresh_time = ref_time + 1783 signaled_master[i].query_interval_sec; 1784 } else { 1785 /* 1786 * Telecom profile support. 1787 * Retry at 60 sec. intervals if three (3) unanswered or denied requests. 1788 * Ref. ITU-T G.8265.1, Clause 6.6. 1789 */ 1790 signaled_master[i].announce_refresh_time = ref_time + 1791 BCM_PTP_SIGNAL_TELECOM_UNMET_REQUEST_QUERY_INTERVAL_SEC; 1792 } 1793 1794 if (multi_tlv_en == 0) { 1795 break; 1796 } 1797 } 1798 1799 if (signaled_master[i].service_grants.announce && 1800 signaled_master[i].service_enable.sync && 1801 signaled_master[i].sync_refresh_time && 1802 signaled_master[i].sync_refresh_time < ref_time) { 1803 messageType[num_tlvs] = bcmPTP_MESSAGE_TYPE_SYNC; 1804 logInterMessagePeriod[num_tlvs++] = signaled_master[i].log_sync_interval; 1805 1806 /* 1807 * Increment counter of unanswered/denied Sync service requests. 1808 * Do not rollover. 1809 */ 1810 if (signaled_master[i].unmet_requests.sync < ((uint8)-1)) { 1811 ++signaled_master[i].unmet_requests.sync; 1812 } 1813 1814 /* 1815 * Set the time to send the next signaling message. 1816 * Will be overwritten if we get a master response. 1817 */ 1818 if ((telecom_en == 0) || 1819 (signaled_master[i].unmet_requests.sync < 1820 BCM_PTP_SIGNAL_TELECOM_UNMET_REQUEST_MAX)) { 1821 signaled_master[i].sync_refresh_time = ref_time + 1822 signaled_master[i].query_interval_sec; 1823 } else { 1824 /* 1825 * Telecom profile support. 1826 * Retry at 60 sec. intervals if three (3) unanswered or denied requests. 1827 * Ref. ITU-T G.8265.1, Clause 6.6. 1828 */ 1829 signaled_master[i].sync_refresh_time = ref_time + 1830 BCM_PTP_SIGNAL_TELECOM_UNMET_REQUEST_QUERY_INTERVAL_SEC; 1831 } 1832 1833 if (multi_tlv_en == 0) { 1834 break; 1835 } 1836 } 1837 1838 if (signaled_master[i].service_grants.announce && 1839 signaled_master[i].service_enable.delayresp && 1840 signaled_master[i].delay_refresh_time && 1841 signaled_master[i].delay_refresh_time < ref_time) { 1842 messageType[num_tlvs] = bcmPTP_MESSAGE_TYPE_DELAY_RESP; 1843 logInterMessagePeriod[num_tlvs++] = signaled_master[i].log_delay_interval; 1844 1845 /* 1846 * Increment counter of unanswered/denied Delay_Resp service requests. 1847 * Do not rollover. 1848 */ 1849 if (signaled_master[i].unmet_requests.delayresp < ((uint8)-1)) { 1850 ++signaled_master[i].unmet_requests.delayresp; 1851 } 1852 1853 /* 1854 * Set the time to send the next signaling message. 1855 * Will be overwritten if we get a master response. 1856 */ 1857 if ((telecom_en == 0) || 1858 (signaled_master[i].unmet_requests.delayresp < 1859 BCM_PTP_SIGNAL_TELECOM_UNMET_REQUEST_MAX)) { 1860 signaled_master[i].delay_refresh_time = ref_time + 1861 signaled_master[i].query_interval_sec; 1862 } else { 1863 /* 1864 * Telecom profile support. 1865 * Retry at 60 sec. intervals if three (3) unanswered or denied requests. 1866 * Ref. ITU-T G.8265.1, Clause 6.6. 1867 */ 1868 signaled_master[i].delay_refresh_time = ref_time + 1869 BCM_PTP_SIGNAL_TELECOM_UNMET_REQUEST_QUERY_INTERVAL_SEC; 1870 } 1871 } 1872 /* We only will send TLVs to a single master, so if we have some, break out of the loop over masters */ 1873 if (num_tlvs) { 1874 break; 1875 } 1876 } 1877 1878 if (num_tlvs) { 1879 /* Pending signaling message(s) to send to a master. */ 1880 send_unicast_request(unit, ptp_id, clock_num, num_tlvs, messageType, 1881 logInterMessagePeriod, signaled_master[i].durationField, 1882 ++signaled_master[i].sequenceId, &signaled_master[i].master); 1883 return BCM_PTP_SIGNAL_MIN_MASTER_DPC_TIME_USEC; 1884 } 1885 1886 /* nothing to send, so we don't need to be re-called immediately */ 1887 return BCM_PTP_SIGNAL_DEFAULT_MASTER_DPC_TIME_USEC; 1888 } 1889 1890 /* 1891 * Function: 1892 * _bcm_ptp_slave_signaling_request_deny 1893 * Purpose: 1894 * Encapsulate system behavior to deny slave's request for PTP message 1895 * services. 1896 * Parameters: 1897 * unit - (IN) Unit number. 1898 * ptp_id - (IN) PTP stack ID. 1899 * clock_num - (IN) PTP clock number. 1900 * msg_type - (IN) PTP message type (|Announce|Sync|DelayResp|). 1901 * log_intermessage_period - (IN) logInterMessagePeriod. 1902 * slave - (IN) Slave data. 1903 * Returns: 1904 * BCM_E_XXX - Function status. 1905 */ 1906 static int 1907 _bcm_ptp_slave_signaling_request_deny( 1908 int unit, 1909 bcm_ptp_stack_id_t ptp_id, 1910 int clock_num, 1911 bcm_ptp_message_type_t msg_type, 1912 int8 log_intermessage_period, 1913 _bcm_ptp_clock_peer_ext_t *slave) 1914 { 1915 int rv; 1916 int i; 1917 1918 BCM_PTP_SLAVETABLE_MUTEX_TAKE(); 1919 /* Signaled unicast slave lookup. */ 1920 if (BCM_FAILURE(_bcm_ptp_signaled_unicast_slave_exists(unit, ptp_id, slave, &i))) { 1921 /* 1922 * Unknown slave. 1923 * Send zero duration GRANT_UNICAST_TRANSMISSION to deny request. 1924 * Ref. IEEE Std. 1588-2008, Sect. 16.1.4.2.5. 1925 */ 1926 if (BCM_FAILURE(rv = _bcm_ptp_slave_signaling_send(unit, ptp_id, clock_num, 1927 bcmPTPTlvTypeGrantUnicastTransmission, msg_type, 1928 log_intermessage_period, BCM_PTP_SIGNAL_REQUEST_DENY_DURATION_SEC, 1929 1, slave, 1))) { 1930 LOG_VERBOSE(BSL_LS_BCM_COMMON, 1931 (BSL_META_U(unit, 1932 "Zero duration GRANT_UNICAST_TRANSMISSION error\n"))); 1933 BCM_PTP_SLAVETABLE_MUTEX_RELEASE_RETURN(rv); 1934 } 1935 1936 /* Return. No matching entry in signaled unicast slave table. */ 1937 BCM_PTP_SLAVETABLE_MUTEX_RELEASE_RETURN(BCM_E_NONE); 1938 } 1939 1940 /* 1941 * Send zero duration GRANT_UNICAST_TRANSMISSION to deny request. 1942 * Ref. IEEE Std. 1588-2008, Sect. 16.1.4.2.5. 1943 */ 1944 if (BCM_FAILURE(rv = _bcm_ptp_slave_signaling_send(unit, ptp_id, clock_num, 1945 bcmPTPTlvTypeGrantUnicastTransmission, msg_type, 1946 log_intermessage_period, BCM_PTP_SIGNAL_REQUEST_DENY_DURATION_SEC, 1947 ++signaled_slave_table.entry[i].sequenceId, slave, 1))) { 1948 LOG_VERBOSE(BSL_LS_BCM_COMMON, 1949 (BSL_META_U(unit, 1950 "Zero duration GRANT_UNICAST_TRANSMISSION error\n"))); 1951 BCM_PTP_SLAVETABLE_MUTEX_RELEASE_RETURN(rv); 1952 } 1953 1954 /* 1955 * Signaled unicast slave table management. 1956 * Configure table to cancel corresponding PTP message service if slave 1957 * is currently subscribed to the service. 1958 */ 1959 switch (msg_type) { 1960 case bcmPTP_MESSAGE_TYPE_ANNOUNCE: 1961 if (signaled_slave_table.entry[i].announce_service_active) { 1962 signaled_slave_table.entry[i].queue_announce_grant = 0; 1963 signaled_slave_table.entry[i].queue_announce_expire = 1; 1964 } 1965 if (signaled_slave_table.entry[i].sync_service_active) { 1966 signaled_slave_table.entry[i].queue_sync_grant = 0; 1967 signaled_slave_table.entry[i].queue_sync_expire = 1; 1968 } 1969 if (signaled_slave_table.entry[i].delay_service_active) { 1970 signaled_slave_table.entry[i].queue_delay_grant = 0; 1971 signaled_slave_table.entry[i].queue_delay_expire = 1; 1972 } 1973 break; 1974 1975 case bcmPTP_MESSAGE_TYPE_SYNC: 1976 if (signaled_slave_table.entry[i].sync_service_active) { 1977 signaled_slave_table.entry[i].queue_sync_grant = 0; 1978 signaled_slave_table.entry[i].queue_sync_expire = 1; 1979 } 1980 break; 1981 1982 case bcmPTP_MESSAGE_TYPE_DELAY_RESP: 1983 if (signaled_slave_table.entry[i].delay_service_active) { 1984 signaled_slave_table.entry[i].queue_delay_grant = 0; 1985 signaled_slave_table.entry[i].queue_delay_expire = 1; 1986 } 1987 break; 1988 1989 default: 1990 ; 1991 } 1992 1993 _bcm_ptp_mutex_give(slaveTable_mutex); 1994 1995 /* reschedule the gateway RDPC to run immediately */ 1996 rv = shr_rdpc_callback_start(&unit_sig_array[unit].send_pending_signaling_to_slaves_rdpc, 1997 (sal_usecs_t)0, 1998 INT_TO_PTR(unit), INT_TO_PTR(ptp_id), INT_TO_PTR(PTP_CLOCK_NUMBER_DEFAULT), INT_TO_PTR(0)); 1999 return rv; 2000 } 2001 2002 /* 2003 * Function: 2004 */ 2005 static sal_usecs_t 2006 send_pending_signaling_to_slaves( 2007 void **arg_unit, 2008 void **arg_ptp_id, 2009 void **arg_clock_num, 2010 void **unused) 2011 { 2012 int rv = BCM_E_NONE; 2013 int i; 2014 int isqueued = 0; 2015 bcm_ptp_tlv_type_t tlvType = 0; 2016 bcm_ptp_tlv_type_t tlvTypeResp = 0; 2017 bcm_ptp_message_type_t messageType = 0; 2018 int8 logInterMessagePeriod = 0; 2019 uint32 durationField = 0; 2020 _bcm_ptp_clock_peer_ext_t slave; 2021 int top_needs_updating = 0; 2022 int unit = PTR_TO_INT(*arg_unit); 2023 int clock_num = PTR_TO_INT(*arg_clock_num); 2024 bcm_ptp_stack_id_t ptp_id = (bcm_ptp_stack_id_t)PTR_TO_INT(*arg_ptp_id); 2025 2026 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 2027 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 2028 PTP_ERROR_FUNC("_bcm_ptp_function_precheck"); 2029 return BCM_PTP_SIGNAL_DEFAULT_SLAVE_DPC_TIME_USEC; 2030 } 2031 2032 if ((rv = _bcm_ptp_mutex_take(slaveTable_mutex, BCM_PTP_SIGNAL_SLAVE_MUTEX_TIMEOUT_USEC))) { 2033 PTP_ERROR_FUNC("_bcm_ptp_mutex_take of slaveTable_mutex"); 2034 return BCM_PTP_SIGNAL_DEFAULT_SLAVE_DPC_TIME_USEC; 2035 } 2036 2037 for (i = 0; i < signaled_slave_table.num_entries; ++i) { 2038 /* We service one signaling message per DPC call to avoid flooding */ 2039 if (signaled_slave_table.entry[i].queue_announce_grant) { 2040 /* 2041 * Defer processing of announce grant iff pending cancel 2042 * announce TLV precedes request announce TLV. 2043 */ 2044 if ((signaled_slave_table.entry[i].announce_request_time <= 2045 signaled_slave_table.entry[i].announce_cancel_time) || 2046 (!signaled_slave_table.entry[i].queue_announce_cancel)) { 2047 2048 top_needs_updating = signaled_slave_table.entry[i].announce_service_changed; 2049 signaled_slave_table.entry[i].announce_service_changed = 0; 2050 2051 signaled_slave_table.entry[i].queue_announce_grant = 0; 2052 signaled_slave_table.entry[i].announce_service_active = 1; 2053 signaled_slave_table.entry[i].announce_grant_time = _bcm_ptp_monotonic_time(); 2054 2055 /* Select message to service. */ 2056 tlvType = bcmPTPTlvTypeRequestUnicastTransmission; 2057 tlvTypeResp = bcmPTPTlvTypeGrantUnicastTransmission; 2058 messageType = bcmPTP_MESSAGE_TYPE_ANNOUNCE; 2059 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_announce_interval; 2060 durationField = signaled_slave_table.entry[i].announce_duration; 2061 slave = signaled_slave_table.entry[i].slave; 2062 2063 isqueued = 1; 2064 break; 2065 } 2066 } 2067 2068 if (signaled_slave_table.entry[i].queue_sync_grant) { 2069 /* Defer processing of sync grant iff pending cancel sync TLV precedes it */ 2070 if ((signaled_slave_table.entry[i].sync_request_time <= 2071 signaled_slave_table.entry[i].sync_cancel_time) || 2072 (!signaled_slave_table.entry[i].queue_sync_cancel)) { 2073 2074 top_needs_updating = signaled_slave_table.entry[i].sync_service_changed; 2075 signaled_slave_table.entry[i].sync_service_changed = 0; 2076 2077 signaled_slave_table.entry[i].queue_sync_grant = 0; 2078 signaled_slave_table.entry[i].sync_service_active = 1; 2079 signaled_slave_table.entry[i].sync_grant_time = _bcm_ptp_monotonic_time(); 2080 2081 /* Select message to service. */ 2082 tlvType = bcmPTPTlvTypeRequestUnicastTransmission; 2083 tlvTypeResp = bcmPTPTlvTypeGrantUnicastTransmission; 2084 messageType = bcmPTP_MESSAGE_TYPE_SYNC; 2085 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_sync_interval; 2086 durationField = signaled_slave_table.entry[i].sync_duration; 2087 slave = signaled_slave_table.entry[i].slave; 2088 2089 isqueued = 1; 2090 break; 2091 } 2092 } 2093 2094 if (signaled_slave_table.entry[i].queue_delay_grant) { 2095 /* Defer processing of delay response grant iff pending cancel TLV preceeds it */ 2096 if ((signaled_slave_table.entry[i].delay_request_time <= 2097 signaled_slave_table.entry[i].delay_cancel_time) || 2098 (!signaled_slave_table.entry[i].queue_delay_cancel)) { 2099 2100 top_needs_updating = signaled_slave_table.entry[i].delay_service_changed; 2101 signaled_slave_table.entry[i].delay_service_changed = 0; 2102 2103 signaled_slave_table.entry[i].queue_delay_grant = 0; 2104 signaled_slave_table.entry[i].delay_service_active = 1; 2105 signaled_slave_table.entry[i].delay_grant_time = _bcm_ptp_monotonic_time(); 2106 2107 /* Select message to service. */ 2108 tlvType = bcmPTPTlvTypeRequestUnicastTransmission; 2109 tlvTypeResp = bcmPTPTlvTypeGrantUnicastTransmission; 2110 messageType = bcmPTP_MESSAGE_TYPE_DELAY_RESP; 2111 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_delay_request_interval; 2112 durationField = signaled_slave_table.entry[i].delay_duration; 2113 slave = signaled_slave_table.entry[i].slave; 2114 2115 isqueued = 1; 2116 break; 2117 } 2118 } 2119 2120 if (signaled_slave_table.entry[i].queue_announce_cancel) { 2121 signaled_slave_table.entry[i].queue_announce_cancel = 0; 2122 signaled_slave_table.entry[i].announce_service_active = 0; 2123 signaled_slave_table.entry[i].slave.peer.log_announce_interval = 99; 2124 #if defined(BCM_PTP_SIGNAL_TIMESTAMP) 2125 signaled_slave_table.entry[i].announce_ack_time = _bcm_ptp_monotonic_time(); 2126 #endif 2127 top_needs_updating = 1; 2128 2129 /* Select message to service. */ 2130 tlvType = bcmPTPTlvTypeCancelUnicastTransmission; 2131 tlvTypeResp = bcmPTPTlvTypeAckCancelUnicastTransmission; 2132 messageType = bcmPTP_MESSAGE_TYPE_ANNOUNCE; 2133 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_announce_interval; 2134 durationField = signaled_slave_table.entry[i].announce_duration; 2135 slave = signaled_slave_table.entry[i].slave; 2136 2137 isqueued = 1; 2138 break; 2139 } 2140 2141 if (signaled_slave_table.entry[i].queue_sync_cancel) { 2142 signaled_slave_table.entry[i].queue_sync_cancel = 0; 2143 signaled_slave_table.entry[i].sync_service_active = 0; 2144 signaled_slave_table.entry[i].slave.peer.log_sync_interval = 99; 2145 #if defined(BCM_PTP_SIGNAL_TIMESTAMP) 2146 signaled_slave_table.entry[i].sync_ack_time = _bcm_ptp_monotonic_time(); 2147 #endif 2148 top_needs_updating = 1; 2149 2150 /* Select message to service. */ 2151 tlvType = bcmPTPTlvTypeCancelUnicastTransmission; 2152 tlvTypeResp = bcmPTPTlvTypeAckCancelUnicastTransmission; 2153 messageType = bcmPTP_MESSAGE_TYPE_SYNC; 2154 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_sync_interval; 2155 durationField = signaled_slave_table.entry[i].sync_duration; 2156 slave = signaled_slave_table.entry[i].slave; 2157 2158 isqueued = 1; 2159 break; 2160 } 2161 2162 if (signaled_slave_table.entry[i].queue_delay_cancel) { 2163 signaled_slave_table.entry[i].queue_delay_cancel = 0; 2164 signaled_slave_table.entry[i].delay_service_active = 0; 2165 signaled_slave_table.entry[i].slave.peer.log_delay_request_interval = 99; 2166 #if defined(BCM_PTP_SIGNAL_TIMESTAMP) 2167 signaled_slave_table.entry[i].delay_ack_time = _bcm_ptp_monotonic_time(); 2168 #endif 2169 top_needs_updating = 1; 2170 2171 /* Select message to service. */ 2172 tlvType = bcmPTPTlvTypeCancelUnicastTransmission; 2173 tlvTypeResp = bcmPTPTlvTypeAckCancelUnicastTransmission; 2174 messageType = bcmPTP_MESSAGE_TYPE_DELAY_RESP; 2175 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_delay_request_interval; 2176 durationField = signaled_slave_table.entry[i].delay_duration; 2177 slave = signaled_slave_table.entry[i].slave; 2178 2179 isqueued = 1; 2180 break; 2181 } 2182 2183 if (signaled_slave_table.entry[i].queue_announce_expire) { 2184 signaled_slave_table.entry[i].queue_announce_expire = 0; 2185 signaled_slave_table.entry[i].announce_service_active = 0; 2186 signaled_slave_table.entry[i].slave.peer.log_announce_interval = 99; 2187 #if defined(BCM_PTP_SIGNAL_TIMESTAMP) 2188 signaled_slave_table.entry[i].announce_expire_time = _bcm_ptp_monotonic_time(); 2189 #endif 2190 top_needs_updating = 1; 2191 2192 /* Select message to service. */ 2193 tlvType = bcmPTPTlvTypeCancelUnicastTransmission; 2194 tlvTypeResp = bcmPTPTlvTypeCancelUnicastTransmission; 2195 messageType = bcmPTP_MESSAGE_TYPE_ANNOUNCE; 2196 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_announce_interval; 2197 durationField = signaled_slave_table.entry[i].announce_duration; 2198 slave = signaled_slave_table.entry[i].slave; 2199 2200 isqueued = 1; 2201 break; 2202 } 2203 2204 if (signaled_slave_table.entry[i].queue_sync_expire) { 2205 signaled_slave_table.entry[i].queue_sync_expire = 0; 2206 signaled_slave_table.entry[i].sync_service_active = 0; 2207 signaled_slave_table.entry[i].slave.peer.log_sync_interval = 99; 2208 #if defined(BCM_PTP_SIGNAL_TIMESTAMP) 2209 signaled_slave_table.entry[i].sync_expire_time = _bcm_ptp_monotonic_time(); 2210 #endif 2211 top_needs_updating = 1; 2212 2213 /* Select message to service. */ 2214 tlvType = bcmPTPTlvTypeCancelUnicastTransmission; 2215 tlvTypeResp = bcmPTPTlvTypeCancelUnicastTransmission; 2216 messageType = bcmPTP_MESSAGE_TYPE_SYNC; 2217 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_sync_interval; 2218 durationField = signaled_slave_table.entry[i].sync_duration; 2219 slave = signaled_slave_table.entry[i].slave; 2220 2221 isqueued = 1; 2222 break; 2223 } 2224 2225 if (signaled_slave_table.entry[i].queue_delay_expire) { 2226 signaled_slave_table.entry[i].queue_delay_expire = 0; 2227 signaled_slave_table.entry[i].delay_service_active = 0; 2228 signaled_slave_table.entry[i].slave.peer.log_delay_request_interval = 99; 2229 #if defined(BCM_PTP_SIGNAL_TIMESTAMP) 2230 signaled_slave_table.entry[i].delay_expire_time = _bcm_ptp_monotonic_time(); 2231 #endif 2232 top_needs_updating = 1; 2233 2234 /* Select message to service. */ 2235 tlvType = bcmPTPTlvTypeCancelUnicastTransmission; 2236 tlvTypeResp = bcmPTPTlvTypeCancelUnicastTransmission; 2237 messageType = bcmPTP_MESSAGE_TYPE_DELAY_RESP; 2238 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_delay_request_interval; 2239 durationField = signaled_slave_table.entry[i].delay_duration; 2240 slave = signaled_slave_table.entry[i].slave; 2241 2242 isqueued = 1; 2243 break; 2244 } 2245 } 2246 2247 if (isqueued) { 2248 /* Queued signaling message(s). */ 2249 2250 /* Done with slave table update, release mutex */ 2251 _bcm_ptp_mutex_give(slaveTable_mutex); 2252 2253 /* Respond to (grant, cancel, acknowledge cancel) selected message. */ 2254 if (BCM_FAILURE(rv = _bcm_ptp_slave_signaling_send(unit, ptp_id, clock_num, tlvTypeResp, 2255 messageType, logInterMessagePeriod, durationField, 2256 ++signaled_slave_table.entry[i].sequenceId,&slave, 0))) { 2257 PTP_ERROR_FUNC("_bcm_ptp_slave_signaling_send()"); 2258 } 2259 if (top_needs_updating) { 2260 /* Subscribe slave. */ 2261 if (BCM_FAILURE(rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, clock_num, 2262 BCM_PTP_ANY_PORT, &slave, messageType, tlvType, logInterMessagePeriod))) { 2263 PTP_ERROR_FUNC("_bcm_ptp_unicast_slave_subscribe()"); 2264 } 2265 } 2266 2267 return BCM_PTP_SIGNAL_MIN_SLAVE_DPC_TIME_USEC; 2268 } else { 2269 /* No queued signaling messages. Update expiration / slave table while we have the lock */ 2270 2271 /* Update indicators of expired slave services. */ 2272 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_expire(unit, ptp_id))) { 2273 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_slave_expire()"); 2274 } 2275 2276 /* Update signaled unicast slave table to remove inactive/expired slaves. */ 2277 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_table_update(unit, ptp_id))) { 2278 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_slave_table_update()"); 2279 } 2280 2281 /* Done with slave table update, release mutex */ 2282 _bcm_ptp_mutex_give(slaveTable_mutex); 2283 2284 return BCM_PTP_SIGNAL_DEFAULT_SLAVE_DPC_TIME_USEC; 2285 } 2286 } 2287 2288 2289 /* 2290 * Function: 2291 * bcm_common_ptp_signaled_unicast_slave_table_clear() 2292 * Purpose: 2293 * Cancel active unicast services for slaves and clear signaled unicast 2294 * slave table entries that correspond to caller-specified master port. 2295 * Parameters: 2296 * unit - (IN) Unit number. 2297 * ptp_id - (IN) PTP stack ID. 2298 * clock_num - (IN) PTP clock number. 2299 * port_num - (IN) Local (master) PTP clock port number. 2300 * callstack - (IN) Boolean to unsubscribe/unregister unicast services. 2301 * TRUE : Cancellation message to slave and PTP stack. 2302 * FALSE: Cancellation message tunneled to slave only. 2303 * Returns: 2304 * BCM_E_XXX - Function status. 2305 */ 2306 int 2307 bcm_common_ptp_signaled_unicast_slave_table_clear( 2308 int unit, 2309 bcm_ptp_stack_id_t ptp_id, 2310 int clock_num, 2311 int port_num, 2312 int callstack) 2313 { 2314 int rv = BCM_E_NONE; 2315 int i; 2316 bcm_ptp_tlv_type_t tlvType; 2317 bcm_ptp_message_type_t messageType; 2318 int8 logInterMessagePeriod; 2319 uint32 durationField; 2320 _bcm_ptp_clock_peer_ext_t slave; 2321 2322 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 2323 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 2324 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 2325 return rv; 2326 } 2327 2328 BCM_PTP_SLAVETABLE_MUTEX_TAKE(); 2329 2330 for (i = 0; i < signaled_slave_table.num_entries; ++i) 2331 { 2332 tlvType = bcmPTPTlvTypeCancelUnicastTransmission; 2333 slave = signaled_slave_table.entry[i].slave; 2334 2335 /* Remove slaves associated with specified master port. */ 2336 if (port_num == slave.peer.local_port_number || 2337 port_num == PTP_IEEE1588_ALL_PORTS) { 2338 if (signaled_slave_table.entry[i].announce_service_active) { 2339 /* Select message to service. */ 2340 messageType = bcmPTP_MESSAGE_TYPE_ANNOUNCE; 2341 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_announce_interval; 2342 durationField = signaled_slave_table.entry[i].announce_duration; 2343 2344 /* Cancel message. */ 2345 if (BCM_FAILURE(rv = _bcm_ptp_slave_signaling_send(unit, ptp_id, clock_num, tlvType, 2346 messageType, logInterMessagePeriod, durationField, 2347 ++signaled_slave_table.entry[i].sequenceId, &slave, 0))) { 2348 PTP_ERROR_FUNC("_bcm_ptp_slave_signaling_send()"); 2349 } 2350 2351 /* Unsubscribe slave. */ 2352 if (callstack && 2353 BCM_FAILURE(rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, 2354 clock_num, slave.peer.local_port_number, &slave, messageType, tlvType, 2355 logInterMessagePeriod))) { 2356 PTP_ERROR_FUNC("_bcm_ptp_unicast_slave_subscribe()"); 2357 } 2358 } 2359 2360 if (signaled_slave_table.entry[i].sync_service_active) { 2361 /* Select message to service. */ 2362 messageType = bcmPTP_MESSAGE_TYPE_SYNC; 2363 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_sync_interval; 2364 durationField = signaled_slave_table.entry[i].sync_duration; 2365 2366 /* Cancel message. */ 2367 if (BCM_FAILURE(rv = _bcm_ptp_slave_signaling_send(unit, ptp_id, clock_num, tlvType, 2368 messageType, logInterMessagePeriod, durationField, 2369 ++signaled_slave_table.entry[i].sequenceId, &slave, 0))) { 2370 PTP_ERROR_FUNC("_bcm_ptp_slave_signaling_send()"); 2371 } 2372 2373 /* Unsubscribe slave. */ 2374 if (callstack && 2375 BCM_FAILURE(rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, 2376 clock_num, slave.peer.local_port_number, &slave, messageType, tlvType, 2377 logInterMessagePeriod))) { 2378 PTP_ERROR_FUNC("_bcm_ptp_unicast_slave_subscribe()"); 2379 } 2380 } 2381 2382 if (signaled_slave_table.entry[i].delay_service_active) { 2383 /* Select message to service. */ 2384 messageType = bcmPTP_MESSAGE_TYPE_DELAY_RESP; 2385 logInterMessagePeriod = signaled_slave_table.entry[i].slave.peer.log_delay_request_interval; 2386 durationField = signaled_slave_table.entry[i].delay_duration; 2387 2388 /* Cancel message. */ 2389 if (BCM_FAILURE(rv = _bcm_ptp_slave_signaling_send(unit, ptp_id, clock_num, tlvType, 2390 messageType, logInterMessagePeriod, durationField, 2391 ++signaled_slave_table.entry[i].sequenceId, &slave, 0))) { 2392 PTP_ERROR_FUNC("_bcm_ptp_slave_signaling_send()"); 2393 } 2394 2395 /* Unsubscribe slave. */ 2396 if (callstack && 2397 BCM_FAILURE(rv = _bcm_ptp_unicast_slave_subscribe(unit, ptp_id, 2398 clock_num, slave.peer.local_port_number, &slave, messageType, tlvType, 2399 logInterMessagePeriod))) { 2400 PTP_ERROR_FUNC("_bcm_ptp_unicast_slave_subscribe()"); 2401 } 2402 } 2403 2404 /* 2405 * Set slave entry. 2406 * Reset message attributes to defaults to render inactive/expired. 2407 * Preserve slave address. 2408 */ 2409 signaled_slave_table.entry[i] = signaled_slave_entry_default; 2410 signaled_slave_table.entry[i].slave = slave; 2411 2412 } 2413 } 2414 2415 /* Update unicast slave table to remove inactive/expired slaves. */ 2416 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_table_update(unit, ptp_id))) { 2417 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_slave_table_update()"); 2418 } 2419 2420 BCM_PTP_SLAVETABLE_MUTEX_RELEASE_RETURN(rv); 2421 } 2422 2423 /* Basic parsing of a signaling message: checks clock/port numbers and gets TLV info */ 2424 2425 int _bcm_ptp_parse_signaling_message( 2426 int unit, 2427 bcm_ptp_stack_id_t ptp_id, 2428 int clock_num, 2429 int port_num, 2430 unsigned data_length, 2431 uint8 * data, 2432 int ptp_msg_offset, 2433 bcm_ptp_tlv_type_t *tlvType, 2434 bcm_ptp_message_type_t *messageType, 2435 int8 *logInterMessagePeriod, 2436 uint32 *durationField, 2437 int *num_tlvs) 2438 { 2439 int rv; 2440 uint8 *targetClock; 2441 int cursor = 0; 2442 uint8 *ptp_tlv; 2443 uint8 *udp; 2444 int udp_payload_len; 2445 uint16 lengthField; 2446 int lengthRemaining; 2447 bcm_ptp_clock_info_t ci; 2448 2449 /* Initialize number of TLVs processed. */ 2450 *num_tlvs = 0; 2451 2452 /* Retrieve clock instance create-time data and metadata. */ 2453 if (BCM_FAILURE(rv = bcm_ptp_clock_get(unit, ptp_id, clock_num, &ci))) { 2454 PTP_ERROR_FUNC("_bcm_ptp_clock_get()"); 2455 /* Reject signaling messages if a PTP clock is not available. */ 2456 return BCM_E_FAIL; 2457 } 2458 2459 /* Check target clock identity. Either broadcast, or must match that of clock_num */ 2460 targetClock = data + ptp_msg_offset + PTP_PTPHDR_SIZE_OCTETS; 2461 if (sal_memcmp(targetClock, BCM_PTP_ALL_CLOCKS, sizeof(bcm_ptp_clock_identity_t)) != 0) { 2462 if (sal_memcmp(targetClock, ci.clock_identity, sizeof(bcm_ptp_clock_identity_t)) != 0) { 2463 return BCM_E_FAIL; 2464 } 2465 } 2466 2467 /* 2468 * Dimension consistency check(s). 2469 * Ensure bogus or malformed messages do not cause range errors. 2470 */ 2471 if (data_length - ptp_msg_offset < 2472 BCM_PTP_SIGNAL_MIN_UDP_PAYLOAD_SIZE_OCTETS) { 2473 return BCM_E_FAIL; 2474 } 2475 2476 #if 0 2477 bsl_printf(" Signaling Msg recvd:: \n"); 2478 _bcm_ptp_dump_hex(data, data_length, 0); 2479 #endif 2480 2481 ptp_tlv = data + ptp_msg_offset + BCM_PTP_SIGNAL_TLV_OFFSET_OCTETS; 2482 lengthRemaining = data_length - ptp_msg_offset - BCM_PTP_SIGNAL_TLV_OFFSET_OCTETS; 2483 2484 udp = data + ptp_msg_offset - BCM_PTP_UDP_HEADER_LENGTH_BYTES; 2485 udp_payload_len = _bcm_ptp_uint16_read(udp+4); 2486 lengthRemaining = udp_payload_len - BCM_PTP_UDP_HEADER_LENGTH_BYTES - BCM_PTP_SIGNAL_TLV_OFFSET_OCTETS; 2487 2488 LOG_DEBUG(BSL_LS_BCM_PTP, 2489 (BSL_META_U(unit, "UDP payload len[%d] Remaining Length[%d]\n"), udp_payload_len, lengthRemaining)); 2490 2491 /* A 4-byte FCS can be present. 2492 TlvType(2B) and TlvLength(2B) together constitutes 4Bytes. 2493 So, continue parsing ONLY if the length remaining is > 4bytes */ 2494 2495 while (lengthRemaining > 4) { 2496 2497 tlvType[*num_tlvs] = _bcm_ptp_uint16_read(ptp_tlv); 2498 cursor += sizeof(uint16); 2499 2500 lengthField = _bcm_ptp_uint16_read(ptp_tlv + cursor); 2501 cursor += sizeof(uint16); 2502 2503 LOG_DEBUG(BSL_LS_BCM_PTP, 2504 (BSL_META_U(unit, "tlv type[0x%04x] tlv length[0x%04x]\n"), tlvType[*num_tlvs], lengthField)); 2505 2506 /* Get message type from TLV. */ 2507 if (lengthField < 1) { 2508 return BCM_E_FAIL; 2509 } 2510 messageType[*num_tlvs] = (ptp_tlv[cursor++] >> 4); 2511 2512 /* If the message has space for them, parse the interval and duration */ 2513 if (lengthField >= 5) { 2514 logInterMessagePeriod[*num_tlvs] = ptp_tlv[cursor++]; 2515 durationField[*num_tlvs] = _bcm_ptp_uint32_read(ptp_tlv + cursor); 2516 } else { 2517 logInterMessagePeriod[*num_tlvs] = 0; 2518 durationField[*num_tlvs] = 0; 2519 } 2520 2521 /* Advance to next TLV, if any. */ 2522 ++(*num_tlvs); 2523 ptp_tlv += lengthField + 4; 2524 cursor = 0; 2525 2526 /* Adjust remaining length. */ 2527 lengthRemaining -= (lengthField + 4); 2528 2529 LOG_DEBUG(BSL_LS_BCM_PTP, 2530 (BSL_META_U(unit, "length remaining[%d] num_tlvs[%d]\n"), lengthRemaining, *num_tlvs)); 2531 2532 /* Exit if maximum number of TLVs has been processed. */ 2533 if (*num_tlvs >= BCM_PTP_SIGNAL_MAX_TLV_PER_MESSAGE) { 2534 lengthRemaining = 0; 2535 } 2536 } 2537 2538 return BCM_E_NONE; 2539 } 2540 2541 STATIC int 2542 _bcm_ptp_make_peer_from_signaling_msg( 2543 int unit, 2544 bcm_ptp_stack_id_t ptp_id, 2545 int clock_num, 2546 unsigned data_length, 2547 uint8 *data, 2548 bcm_ptp_protocol_t protocol, 2549 int src_addr_offset, 2550 int ptp_msg_offset, 2551 _bcm_ptp_clock_peer_ext_t *peer_ext) 2552 { 2553 int any_port = 0xffff; 2554 int rv = BCM_E_NONE; 2555 int cursor; 2556 2557 int port_num; 2558 bcm_ptp_clock_info_t ci; 2559 bcm_ptp_clock_port_info_t pi; 2560 2561 bcm_mac_t src_mac; 2562 bcm_mac_t dest_mac; 2563 bcm_ptp_clock_peer_t *peer = &peer_ext->peer; 2564 2565 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 2566 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 2567 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 2568 return rv; 2569 } 2570 2571 /* Parse signaling message to construct peer data structure. */ 2572 switch ((bcm_ptp_protocol_t)protocol) { 2573 case bcmPTPUDPIPv4: 2574 /* Ethernet/UDP/IPv4 address. */ 2575 peer->peer_address.raw_l2_header_length = src_addr_offset - 2576 PTP_IPV4HDR_SRC_IPADDR_OFFSET_OCTETS; 2577 2578 if (peer->peer_address.raw_l2_header_length > PTP_MAX_L2_HEADER_LENGTH) { 2579 peer->peer_address.raw_l2_header_length = 0; 2580 LOG_VERBOSE(BSL_LS_BCM_COMMON, 2581 (BSL_META_U(unit, 2582 "Incompatible L2 header size\n"))); 2583 return BCM_E_CONFIG; 2584 } 2585 2586 /* 2587 * Configure raw L2 header. 2588 * Reference implementation: Swap source and destination MACs from 2589 * incoming signaling message. 2590 */ 2591 sal_memcpy(dest_mac, data, sizeof(bcm_mac_t)); 2592 sal_memcpy(src_mac, data + sizeof(bcm_mac_t), sizeof(bcm_mac_t)); 2593 2594 sal_memset(peer->peer_address.raw_l2_header, 0, PTP_MSG_L2_HEADER_LENGTH); 2595 sal_memcpy(peer->peer_address.raw_l2_header, data, 2596 peer->peer_address.raw_l2_header_length); 2597 2598 sal_memcpy(peer->peer_address.raw_l2_header, src_mac, sizeof(bcm_mac_t)); 2599 sal_memcpy(peer->peer_address.raw_l2_header + sizeof(bcm_mac_t), dest_mac, 2600 sizeof(bcm_mac_t)); 2601 2602 /* Set address. */ 2603 peer->peer_address.addr_type = bcmPTPUDPIPv4; 2604 peer->peer_address.ipv4_addr = _bcm_ptp_uint32_read(data + src_addr_offset); 2605 sal_memset(peer->peer_address.ipv6_addr, 0, PTP_IPV6_ADDR_SIZE_BYTES); 2606 2607 peer_ext->local_address.addr_type = bcmPTPUDPIPv4; 2608 sal_memcpy(peer_ext->local_address.address, data + src_addr_offset + PTP_IPV4_ADDR_SIZE_BYTES, PTP_IPV4_ADDR_SIZE_BYTES); 2609 2610 /* Extract req'd remote (source) port information. */ 2611 cursor = ptp_msg_offset + PTP_PTPHDR_SRCPORT_OFFSET_OCTETS; 2612 sal_memcpy(peer->clock_identity, 2613 data + cursor, sizeof(bcm_ptp_clock_identity_t)); 2614 2615 cursor += sizeof(bcm_ptp_clock_identity_t); 2616 peer->remote_port_number = _bcm_ptp_uint16_read(data + cursor); 2617 2618 /* Extract req'd local (target) port information. */ 2619 cursor = ptp_msg_offset + PTP_PTPHDR_SIZE_OCTETS + sizeof(bcm_ptp_clock_identity_t); 2620 peer->local_port_number = _bcm_ptp_uint16_read(data + cursor); 2621 2622 /* 2623 * Process target port. 2624 * Reference implementation: Assign "all ports" target to port with 2625 * matching protocol address. 2626 * Reference implementation: Reject message if associated port is 2627 * unavailable as determined by the port 2628 * address accessor. 2629 * Reference implementation: Reject message if destination address 2630 * does not match local port address. 2631 */ 2632 if (peer->local_port_number == any_port) { 2633 if (BCM_FAILURE(rv = bcm_ptp_clock_get(unit, ptp_id, clock_num, &ci))) { 2634 PTP_ERROR_FUNC("_bcm_ptp_clock_get()"); 2635 return BCM_E_FAIL; 2636 } 2637 2638 for (port_num = 1; port_num <= ci.num_ports; ++port_num) { 2639 if (BCM_FAILURE(bcm_ptp_clock_port_info_get(unit, ptp_id, clock_num, port_num, &pi))) { 2640 PTP_ERROR_FUNC("_bcm_ptp_clock_port_info_get()"); 2641 return BCM_E_FAIL; 2642 } 2643 2644 if (protocol == pi.port_address.addr_type) { 2645 /* See if the address matches, or if the port will accept any incoming address */ 2646 if (!sal_memcmp(data + src_addr_offset + PTP_IPV4_ADDR_SIZE_BYTES, 2647 pi.port_address.address, PTP_IPV4_ADDR_SIZE_BYTES) || 2648 (pi.rx_packets_criteria_mask & BCM_PTP_RXMAP_MATCH_ANY_ADDR)) { 2649 break; 2650 } 2651 } 2652 } 2653 2654 peer->local_port_number = port_num; 2655 if (peer->local_port_number > ci.num_ports) { 2656 peer->local_port_number = 1; 2657 PTP_WARN("Destination IP address not found (IPv4).\n"); 2658 2659 return BCM_E_PARAM; 2660 } 2661 } else { 2662 if (BCM_FAILURE(rv = bcm_ptp_clock_get(unit, ptp_id, clock_num, &ci))) { 2663 PTP_ERROR_FUNC("_bcm_ptp_clock_get()"); 2664 return BCM_E_FAIL; 2665 } 2666 2667 if (BCM_FAILURE(bcm_ptp_clock_port_info_get(unit, ptp_id, clock_num, 2668 peer->local_port_number, &pi))) { 2669 PTP_ERROR_FUNC("_bcm_ptp_clock_port_info_get()"); 2670 return BCM_E_FAIL; 2671 } 2672 2673 if (protocol != pi.port_address.addr_type || 2674 sal_memcmp(data + src_addr_offset + PTP_IPV4_ADDR_SIZE_BYTES, 2675 pi.port_address.address, PTP_IPV4_ADDR_SIZE_BYTES)) { 2676 PTP_WARN("Destination IP address mismatch (IPv4).\n"); 2677 return BCM_E_PARAM; 2678 } 2679 } 2680 2681 break; 2682 2683 case bcmPTPUDPIPv6: 2684 /* Ethernet/UDP/IPv6 address. */ 2685 peer->peer_address.raw_l2_header_length = src_addr_offset - 8; 2686 2687 if (peer->peer_address.raw_l2_header_length > PTP_MAX_L2_HEADER_LENGTH) { 2688 peer->peer_address.raw_l2_header_length = 0; 2689 LOG_VERBOSE(BSL_LS_BCM_COMMON, 2690 (BSL_META_U(unit, 2691 "Incompatible L2 header size\n"))); 2692 return BCM_E_CONFIG; 2693 } 2694 2695 /* 2696 * Configure raw L2 header. 2697 * Reference implementation: Swap source and destination MACs from 2698 * incoming signaling message. 2699 */ 2700 sal_memcpy(dest_mac, data, sizeof(bcm_mac_t)); 2701 sal_memcpy(src_mac, data + sizeof(bcm_mac_t), sizeof(bcm_mac_t)); 2702 2703 sal_memset(peer->peer_address.raw_l2_header, 0, PTP_MSG_L2_HEADER_LENGTH); 2704 sal_memcpy(peer->peer_address.raw_l2_header, data, 2705 peer->peer_address.raw_l2_header_length); 2706 2707 sal_memcpy(peer->peer_address.raw_l2_header, src_mac, sizeof(bcm_mac_t)); 2708 sal_memcpy(peer->peer_address.raw_l2_header + sizeof(bcm_mac_t), dest_mac, 2709 sizeof(bcm_mac_t)); 2710 2711 /* Set address. */ 2712 peer->peer_address.addr_type = bcmPTPUDPIPv6; 2713 peer->peer_address.ipv4_addr = 0; 2714 sal_memcpy(peer->peer_address.ipv6_addr, data + src_addr_offset, 2715 PTP_IPV6_ADDR_SIZE_BYTES); 2716 2717 peer_ext->local_address.addr_type = bcmPTPUDPIPv6; 2718 sal_memcpy(peer_ext->local_address.address, data + src_addr_offset + PTP_IPV6_ADDR_SIZE_BYTES, PTP_IPV6_ADDR_SIZE_BYTES); 2719 2720 /* Extract req'd remote (source) port information. */ 2721 cursor = ptp_msg_offset + PTP_PTPHDR_SRCPORT_OFFSET_OCTETS; 2722 sal_memcpy(peer->clock_identity, 2723 data + cursor, sizeof(bcm_ptp_clock_identity_t)); 2724 2725 cursor += sizeof(bcm_ptp_clock_identity_t); 2726 peer->remote_port_number = _bcm_ptp_uint16_read(data + cursor); 2727 2728 /* Extract req'd local (target) port information. */ 2729 cursor = ptp_msg_offset + PTP_PTPHDR_SIZE_OCTETS + sizeof(bcm_ptp_clock_identity_t); 2730 peer->local_port_number = _bcm_ptp_uint16_read(data + cursor); 2731 2732 /* 2733 * Process target port. 2734 * Reference implementation: Assign "all ports" target to port with 2735 * matching protocol address. 2736 * Reference implementation: Reject message if associated port is 2737 * unavailable as determined by the port 2738 * address accessor. 2739 * Reference implementation: Reject message if destination address 2740 * does not match local port address. 2741 */ 2742 if (peer->local_port_number == any_port) { 2743 if (BCM_FAILURE(rv = bcm_ptp_clock_get(unit, ptp_id, clock_num, &ci))) { 2744 PTP_ERROR_FUNC("_bcm_ptp_clock_get()"); 2745 return BCM_E_FAIL; 2746 } 2747 2748 for (port_num = 1; port_num <= ci.num_ports; ++port_num) { 2749 if (BCM_FAILURE(bcm_ptp_clock_port_info_get(unit, ptp_id, clock_num, port_num, &pi))) { 2750 PTP_ERROR_FUNC("_bcm_ptp_clock_port_info_get()"); 2751 return BCM_E_FAIL; 2752 } 2753 2754 if (protocol == pi.port_address.addr_type && 2755 !sal_memcmp(data + src_addr_offset + PTP_IPV6_ADDR_SIZE_BYTES, 2756 pi.port_address.address, PTP_IPV6_ADDR_SIZE_BYTES)) { 2757 break; 2758 } 2759 } 2760 2761 peer->local_port_number = port_num; 2762 if (peer->local_port_number > ci.num_ports) { 2763 peer->local_port_number = 1; 2764 PTP_WARN("Destination IP address mismatch (IPv6).\n"); 2765 return BCM_E_PARAM; 2766 } 2767 } else { 2768 if (BCM_FAILURE(bcm_ptp_clock_port_info_get(unit, ptp_id, clock_num, 2769 peer->local_port_number, &pi))) { 2770 PTP_ERROR_FUNC("_bcm_ptp_clock_port_info_get()"); 2771 return BCM_E_FAIL; 2772 } 2773 2774 if (protocol != pi.port_address.addr_type || 2775 sal_memcmp(data + src_addr_offset + PTP_IPV6_ADDR_SIZE_BYTES, 2776 pi.port_address.address, PTP_IPV6_ADDR_SIZE_BYTES)) { 2777 PTP_WARN("Destination IP address mismatch (IPv6).\n"); 2778 return BCM_E_PARAM; 2779 } 2780 } 2781 2782 break; 2783 2784 default: 2785 /* Unknown or unsupported address type. */ 2786 LOG_VERBOSE(BSL_LS_BCM_COMMON, 2787 (BSL_META_U(unit, 2788 "Unknown or unsupported address type\n"))); 2789 return BCM_E_PARAM; 2790 } 2791 2792 return BCM_E_NONE; 2793 } 2794 2795 /* 2796 * Function: 2797 * _bcm_ptp_process_incoming_signaling_msg() 2798 * Purpose: 2799 * Reference implementation to process an incoming PTP signaling message. 2800 * Parameters: 2801 * unit - (IN) Unit number. 2802 * ptp_id - (IN) PTP stack ID. 2803 * clock_num - (IN) PTP clock number. 2804 * port_num - (IN) PTP clock port number. 2805 * protocol - (IN) Network protocol. 2806 * src_addr_offset - (IN) Source address offset in message. 2807 * ptp_msg_offset - (IN) PTP offset (PTP common header) in message. 2808 * data_length - (IN) Signaling message size. 2809 * data - (IN) Signaling message data. 2810 * Returns: 2811 * bcmPTPCallbackAccept - Criteria met; accept PTP signaling message. 2812 * bcmPTPCallbackReject - Criteria not met; reject PTP signaling message. 2813 */ 2814 bcm_ptp_callback_t 2815 _bcm_ptp_process_incoming_signaling_msg( 2816 int unit, 2817 bcm_ptp_stack_id_t ptp_id, 2818 int clock_num, 2819 int port_num, 2820 bcm_ptp_protocol_t protocol, 2821 int src_addr_offset, 2822 int ptp_msg_offset, 2823 unsigned data_length, 2824 uint8 *data) 2825 { 2826 int rv; 2827 2828 int num_tlvs; 2829 int tlv_num; 2830 2831 bcm_ptp_tlv_type_t tlvType; 2832 bcm_ptp_tlv_type_t tlvTypes[BCM_PTP_SIGNAL_MAX_TLV_PER_MESSAGE]; 2833 2834 bcm_ptp_message_type_t messageType; 2835 bcm_ptp_message_type_t messageTypes[BCM_PTP_SIGNAL_MAX_TLV_PER_MESSAGE]; 2836 2837 int logInterMessagePeriodAsInt; 2838 int8 logInterMessagePeriod; 2839 int8 logInterMessagePeriods[BCM_PTP_SIGNAL_MAX_TLV_PER_MESSAGE]; 2840 2841 uint32 durationField; 2842 uint32 durationFields[BCM_PTP_SIGNAL_MAX_TLV_PER_MESSAGE]; 2843 2844 _bcm_ptp_clock_peer_ext_t peer_ext; 2845 bcm_ptp_callback_t rvcb; 2846 bcm_ptp_cb_msg_t msg; 2847 _bcm_ptp_clock_cache_t *clock; 2848 _bcm_ptp_port_state_t portState; 2849 2850 bcm_ptp_clock_info_t ci; 2851 uint8 domainNumber; 2852 2853 bcm_ptp_signaling_arbiter_t arbiter = unit_sig_array[unit].arbiter; 2854 bcm_ptp_cb_signaling_arbiter_msg_t amsg; 2855 void *user_data = unit_sig_array[unit].arbiter_user_data; 2856 2857 2858 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 2859 PTP_CLOCK_NUMBER_DEFAULT, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 2860 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 2861 return bcmPTPCallbackReject; 2862 } 2863 2864 /* 2865 * Check domainNumber in message common header against local clock instance. 2866 * Reference implementation: Reject (ignore) PTP signaling messages that are 2867 * not in local clock's domain. 2868 */ 2869 domainNumber = *(data + ptp_msg_offset + PTP_PTPHDR_DOMAIN_OFFSET_OCTETS); 2870 2871 if (BCM_FAILURE(_bcm_ptp_clock_cache_info_get(unit, ptp_id, clock_num, &ci)) || 2872 domainNumber != ci.domain_number) { 2873 return bcmPTPCallbackReject; 2874 } 2875 2876 if (BCM_FAILURE(rv = _bcm_ptp_parse_signaling_message(unit, ptp_id, clock_num, 2877 port_num, data_length, data, ptp_msg_offset, tlvTypes, messageTypes, 2878 logInterMessagePeriods, durationFields, &num_tlvs))) { 2879 PTP_ERROR_FUNC("_bcm_ptp_parse_signaling_message()"); 2880 return bcmPTPCallbackReject; 2881 } 2882 2883 if (BCM_FAILURE(rv = _bcm_ptp_make_peer_from_signaling_msg(unit, ptp_id, clock_num, 2884 data_length, data, protocol, src_addr_offset, ptp_msg_offset, &peer_ext))) { 2885 return bcmPTPCallbackReject; 2886 } 2887 2888 /* 2889 * Check portState of target port. 2890 * Reference implementation: Reject (ignore) PTP signaling messages if 2891 * the portState of target port is DISABLED. 2892 */ 2893 if (BCM_FAILURE(rv = _bcm_ptp_clock_cache_port_state_get(unit, 2894 ptp_id, clock_num, peer_ext.peer.local_port_number, &portState)) || 2895 portState == _bcm_ptp_state_disabled) { 2896 return bcmPTPCallbackReject; 2897 } 2898 2899 for (tlv_num = 0; tlv_num < num_tlvs; ++tlv_num) { 2900 tlvType = tlvTypes[tlv_num]; 2901 messageType = messageTypes[tlv_num]; 2902 logInterMessagePeriod = logInterMessagePeriods[tlv_num]; 2903 logInterMessagePeriodAsInt = (int)logInterMessagePeriod; 2904 durationField = durationFields[tlv_num]; 2905 2906 if (tlvType == bcmPTPTlvTypeRequestUnicastTransmission) { 2907 if (!arbiter) { 2908 return bcmPTPCallbackReject; 2909 } 2910 /* 2911 * Use caller-provided, application-specific registered interpreter/arbiter 2912 * callback to determine whether to accept or reject PTP signaling message. 2913 */ 2914 clock = &_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num]; 2915 2916 sal_memset(&amsg, 0, sizeof(bcm_ptp_cb_signaling_arbiter_msg_t)); 2917 sal_memset(&msg, 0, sizeof(bcm_ptp_cb_msg_t)); 2918 2919 amsg.ptp_id = ptp_id; 2920 amsg.clock_num = clock_num; 2921 amsg.port_num = port_num; 2922 msg.length = data_length; 2923 msg.data = data; 2924 msg.protocol = protocol; 2925 msg.src_addr_offset = src_addr_offset; 2926 msg.msg_offset = ptp_msg_offset; 2927 amsg.clock_info = &clock->clock_info; 2928 amsg.tlv_type = &tlvType; 2929 amsg.messageType = &messageType; 2930 amsg.logInterMessagePeriod = &logInterMessagePeriodAsInt; 2931 amsg.durationField = &durationField; 2932 amsg.msg = &msg; 2933 amsg.slave = &peer_ext.peer; 2934 2935 rvcb = arbiter(unit, &amsg, user_data); 2936 2937 if (bcmPTPCallbackReject == rvcb) { 2938 /* 2939 * Deny request for PTP message service. 2940 * NOTE : Use as-provided messageType and logInterMessagePeriod 2941 * in the event a custom arbiter modifies the parameters. 2942 */ 2943 if (BCM_FAILURE(rv = _bcm_ptp_slave_signaling_request_deny( 2944 unit, ptp_id, clock_num, messageTypes[tlv_num], 2945 logInterMessagePeriods[tlv_num], &peer_ext))) { 2946 PTP_ERROR_FUNC("_bcm_ptp_slave_signaling_request_deny()"); 2947 } 2948 continue; 2949 } 2950 } 2951 2952 if ((rv = _bcm_ptp_mutex_take(slaveTable_mutex, BCM_PTP_SIGNAL_SLAVE_MUTEX_TIMEOUT_USEC))) { 2953 PTP_ERROR_FUNC("_bcm_ptp_mutex_take()"); 2954 return bcmPTPCallbackReject; 2955 } 2956 2957 switch (tlvType) { 2958 case bcmPTPTlvTypeRequestUnicastTransmission: 2959 { 2960 /* 2961 * Signaled unicast slave table management. 2962 * Locate slave in signaled unicast slave table. 2963 * Add an entry if corresponding slave does not exist yet. 2964 */ 2965 int rv; 2966 int i; 2967 2968 if (BCM_SUCCESS(rv = _bcm_ptp_signaled_unicast_slave_exists(unit, ptp_id, &peer_ext, &i))) { 2969 if ((sal_memcmp(&signaled_slave_table.entry[i].slave.peer.peer_address.raw_l2_header[0], &peer_ext.peer.peer_address.raw_l2_header[0], peer_ext.peer.peer_address.raw_l2_header_length) == 0) && 2970 (sal_memcmp(&signaled_slave_table.entry[i].slave.peer.clock_identity, &peer_ext.peer.clock_identity, sizeof(bcm_ptp_clock_identity_t)) == 0)) { 2971 /* Slave with that address already exists, update clock info if necessary */ 2972 signaled_slave_table.entry[i].slave.peer.remote_port_number = peer_ext.peer.remote_port_number; 2973 } else { 2974 /* slave's MAC address has changed, remove the slave entry, add a new entry and notify R5 to update Slave's mac address */ 2975 signaled_slave_table.entry[i].queue_announce_grant = 0; 2976 signaled_slave_table.entry[i].queue_sync_grant = 0; 2977 signaled_slave_table.entry[i].queue_delay_grant = 0; 2978 signaled_slave_table.entry[i].queue_announce_cancel = 0; 2979 signaled_slave_table.entry[i].queue_sync_cancel = 0; 2980 signaled_slave_table.entry[i].queue_delay_cancel = 0; 2981 signaled_slave_table.entry[i].queue_announce_expire = 0; 2982 signaled_slave_table.entry[i].queue_sync_expire = 0; 2983 signaled_slave_table.entry[i].queue_delay_expire = 0; 2984 signaled_slave_table.entry[i].announce_service_active = 0; 2985 signaled_slave_table.entry[i].sync_service_active = 0; 2986 signaled_slave_table.entry[i].delay_service_active = 0; 2987 /* Update unicast slave table to remove inactive/expired slaves. */ 2988 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_table_update(unit, ptp_id))) { 2989 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_slave_table_update()"); 2990 } 2991 2992 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_add(unit, ptp_id, &peer_ext))) { 2993 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_slave_add()"); 2994 goto release_return; 2995 } 2996 i = signaled_slave_table.num_entries - 1; 2997 signaled_slave_table.entry[i].slave.peer.log_announce_interval = 99; 2998 signaled_slave_table.entry[i].slave.peer.log_sync_interval = 99; 2999 signaled_slave_table.entry[i].slave.peer.log_delay_request_interval = 99; 3000 3001 signaled_slave_table.entry[i].slave.peer.announce_receive_timeout = 3002 PTP_CLOCK_PRESETS_ANNOUNCE_RECEIPT_TIMEOUT_DEFAULT; 3003 signaled_slave_table.entry[i].slave.peer.delay_mechanism = 3004 bcmPTPDelayMechanismEnd2End; 3005 signaled_slave_table.entry[i].slave.peer.tx_timestamp_mech = 3006 peer_ext.peer.tx_timestamp_mech; 3007 } 3008 } else { 3009 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_add(unit, ptp_id, &peer_ext))) { 3010 PTP_ERROR_FUNC("_bcm_ptp_signaled_unicast_slave_add()"); 3011 goto release_return; 3012 } 3013 i = signaled_slave_table.num_entries - 1; 3014 signaled_slave_table.entry[i].slave.peer.log_announce_interval = 99; 3015 signaled_slave_table.entry[i].slave.peer.log_sync_interval = 99; 3016 signaled_slave_table.entry[i].slave.peer.log_delay_request_interval = 99; 3017 3018 signaled_slave_table.entry[i].slave.peer.announce_receive_timeout = 3019 PTP_CLOCK_PRESETS_ANNOUNCE_RECEIPT_TIMEOUT_DEFAULT; 3020 signaled_slave_table.entry[i].slave.peer.delay_mechanism = 3021 bcmPTPDelayMechanismEnd2End; 3022 signaled_slave_table.entry[i].slave.peer.tx_timestamp_mech = 3023 peer_ext.peer.tx_timestamp_mech; 3024 } 3025 3026 switch (messageType) { 3027 case bcmPTP_MESSAGE_TYPE_ANNOUNCE: 3028 if ((signaled_slave_table.entry[i].slave.peer.log_announce_interval != logInterMessagePeriod) || 3029 (signaled_slave_table.entry[i].announce_service_active == 0)) { 3030 signaled_slave_table.entry[i].announce_service_changed = 1; 3031 } 3032 3033 signaled_slave_table.entry[i].slave.peer.log_announce_interval = logInterMessagePeriod; 3034 signaled_slave_table.entry[i].queue_announce_grant = 1; 3035 signaled_slave_table.entry[i].announce_duration = durationField; 3036 signaled_slave_table.entry[i].announce_request_time = _bcm_ptp_monotonic_time(); 3037 3038 goto release_return; 3039 3040 case bcmPTP_MESSAGE_TYPE_SYNC: 3041 if ((signaled_slave_table.entry[i].slave.peer.log_sync_interval != logInterMessagePeriod) || 3042 (signaled_slave_table.entry[i].sync_service_active == 0)) { 3043 signaled_slave_table.entry[i].sync_service_changed = 1; 3044 } 3045 3046 signaled_slave_table.entry[i].slave.peer.log_sync_interval = logInterMessagePeriod; 3047 signaled_slave_table.entry[i].queue_sync_grant = 1; 3048 signaled_slave_table.entry[i].sync_duration = durationField; 3049 signaled_slave_table.entry[i].sync_request_time = _bcm_ptp_monotonic_time(); 3050 3051 goto release_return; 3052 3053 case bcmPTP_MESSAGE_TYPE_DELAY_RESP: 3054 if ((signaled_slave_table.entry[i].slave.peer.log_delay_request_interval != logInterMessagePeriod) || 3055 (signaled_slave_table.entry[i].delay_service_active == 0)) { 3056 signaled_slave_table.entry[i].delay_service_changed = 1; 3057 } 3058 3059 signaled_slave_table.entry[i].slave.peer.log_delay_request_interval = logInterMessagePeriod; 3060 signaled_slave_table.entry[i].queue_delay_grant = 1; 3061 signaled_slave_table.entry[i].delay_duration = durationField; 3062 signaled_slave_table.entry[i].delay_request_time = _bcm_ptp_monotonic_time(); 3063 3064 goto release_return; 3065 3066 default: 3067 goto release_return; 3068 } 3069 } 3070 3071 break; 3072 3073 case bcmPTPTlvTypeGrantUnicastTransmission: 3074 { 3075 /* find the index of the master in our list: */ 3076 int idx; 3077 3078 for (idx = 0; idx < num_signaled_masters; ++idx) { 3079 if (_bcm_ptp_peer_address_raw_compare(&signaled_master[idx].master.peer_address, 3080 data + src_addr_offset, protocol)) { 3081 3082 #ifdef BCM_PTP_EXT_SERVO_SUPPORT 3083 if (signaled_master[idx].update_servo) { 3084 sal_memcpy(&signaled_master[idx].master.clock_identity, peer_ext.peer.clock_identity, sizeof(bcm_ptp_clock_identity_t)); 3085 signaled_master[idx].master.remote_port_number = peer_ext.peer.remote_port_number; 3086 signaled_master[idx].update_servo = 0; 3087 } 3088 #endif /* BCM_PTP_EXT_SERVO_SUPPORT */ 3089 3090 switch (messageType) { 3091 case bcmPTP_MESSAGE_TYPE_ANNOUNCE: 3092 if (durationField) { 3093 signaled_master[idx].announce_refresh_time = _bcm_ptp_monotonic_time() + durationField / 2 + 1; 3094 signaled_master[idx].service_grants.announce = 1; 3095 signaled_master[idx].unmet_requests.announce = 0; 3096 } else { 3097 /* Zero duration GRANT_UNICAST_TRANSMISSION equals request denial. */ 3098 signaled_master[idx].service_grants.announce = 0; 3099 } 3100 goto release_return; 3101 3102 case bcmPTP_MESSAGE_TYPE_SYNC: 3103 if (durationField) { 3104 signaled_master[idx].sync_refresh_time = _bcm_ptp_monotonic_time() + durationField / 2 + 1; 3105 signaled_master[idx].service_grants.sync = 1; 3106 signaled_master[idx].unmet_requests.sync = 0; 3107 3108 if (signaled_master[idx].granted_log_sync_interval != logInterMessagePeriod) { 3109 signaled_master[idx].granted_log_sync_interval = logInterMessagePeriod; 3110 sal_dpc(delayed_master_table_update, INT_TO_PTR(delayed_master_table_update), 3111 INT_TO_PTR(idx), INT_TO_PTR(unit), INT_TO_PTR(ptp_id),0); 3112 } 3113 } else { 3114 /* Zero duration GRANT_UNICAST_TRANSMISSION equals request denial. */ 3115 signaled_master[idx].service_grants.sync = 0; 3116 } 3117 3118 goto release_return; 3119 3120 case bcmPTP_MESSAGE_TYPE_DELAY_RESP: 3121 if (durationField) { 3122 signaled_master[idx].delay_refresh_time = _bcm_ptp_monotonic_time() + durationField / 2 + 1; 3123 signaled_master[idx].service_grants.delayresp = 1; 3124 signaled_master[idx].unmet_requests.delayresp = 0; 3125 3126 if (signaled_master[idx].granted_log_delay_interval != logInterMessagePeriod) { 3127 signaled_master[idx].granted_log_delay_interval = logInterMessagePeriod; 3128 sal_dpc(delayed_master_table_update, INT_TO_PTR(delayed_master_table_update), 3129 INT_TO_PTR(idx), INT_TO_PTR(unit), INT_TO_PTR(ptp_id),0); 3130 } 3131 } else { 3132 /* Zero duration GRANT_UNICAST_TRANSMISSION equals request denial. */ 3133 signaled_master[idx].service_grants.delayresp = 0; 3134 } 3135 3136 goto release_return; 3137 3138 default: 3139 goto release_return; 3140 } 3141 } 3142 } 3143 } 3144 break; 3145 3146 case bcmPTPTlvTypeCancelUnicastTransmission: 3147 { 3148 /* This could either be from a slave, indicating that we can stop sending 3149 * or from a master, indicating that we no longer have a grant 3150 * See if it matches a master from our list: */ 3151 int idx; 3152 int rv; 3153 int i; 3154 3155 for (idx = 0; idx < num_signaled_masters; ++idx) { 3156 if (_bcm_ptp_peer_address_raw_compare(&signaled_master[idx].master.peer_address, 3157 data + src_addr_offset, protocol)) { 3158 switch (messageType) { 3159 case bcmPTP_MESSAGE_TYPE_ANNOUNCE: 3160 signaled_master[idx].announce_refresh_time = 3161 _bcm_ptp_monotonic_time() + signaled_master[idx].query_interval_sec; 3162 signaled_master[idx].service_grants.announce = 0; 3163 signaled_master[idx].to_ack_cancel.announce = 1; 3164 goto release_return; 3165 3166 case bcmPTP_MESSAGE_TYPE_SYNC: 3167 signaled_master[idx].sync_refresh_time = 3168 _bcm_ptp_monotonic_time() + signaled_master[idx].query_interval_sec; 3169 signaled_master[idx].service_grants.sync = 0; 3170 signaled_master[idx].to_ack_cancel.sync = 1; 3171 goto release_return; 3172 3173 case bcmPTP_MESSAGE_TYPE_DELAY_RESP: 3174 signaled_master[idx].delay_refresh_time = 3175 _bcm_ptp_monotonic_time() + signaled_master[idx].query_interval_sec; 3176 signaled_master[idx].service_grants.delayresp = 0; 3177 signaled_master[idx].to_ack_cancel.delayresp = 1; 3178 3179 signaled_master[idx].granted_log_delay_interval = BCM_PTP_SIGNAL_LOGINTERMSG_PERIOD_NONGRANT; 3180 sal_dpc(delayed_master_table_update, INT_TO_PTR(delayed_master_table_update), 3181 INT_TO_PTR(idx), INT_TO_PTR(unit), INT_TO_PTR(ptp_id),0); 3182 goto release_return; 3183 3184 default: 3185 goto release_return; 3186 } 3187 } 3188 } 3189 3190 /* Signaled unicast slave lookup. */ 3191 if (BCM_FAILURE(rv = _bcm_ptp_signaled_unicast_slave_exists(unit, ptp_id, &peer_ext, &i))) { 3192 /* No matching entry in signaled unicast slave table. */ 3193 goto release_return; 3194 } 3195 3196 switch (messageType) { 3197 case bcmPTP_MESSAGE_TYPE_ANNOUNCE: 3198 signaled_slave_table.entry[i].announce_cancel_time = _bcm_ptp_monotonic_time(); 3199 signaled_slave_table.entry[i].queue_announce_cancel = 1; 3200 goto release_return; 3201 3202 case bcmPTP_MESSAGE_TYPE_SYNC: 3203 signaled_slave_table.entry[i].sync_cancel_time = _bcm_ptp_monotonic_time(); 3204 signaled_slave_table.entry[i].queue_sync_cancel = 1; 3205 goto release_return; 3206 3207 case bcmPTP_MESSAGE_TYPE_DELAY_RESP: 3208 signaled_slave_table.entry[i].delay_cancel_time = _bcm_ptp_monotonic_time(); 3209 signaled_slave_table.entry[i].queue_delay_cancel = 1; 3210 goto release_return; 3211 3212 default: 3213 goto release_return; 3214 } 3215 } 3216 break; 3217 3218 case bcmPTPTlvTypeAckCancelUnicastTransmission: 3219 /* Do nothing. */ 3220 break; 3221 default: 3222 ; 3223 } 3224 3225 release_return: 3226 _bcm_ptp_mutex_give(slaveTable_mutex); 3227 } 3228 3229 return bcmPTPCallbackAccept; 3230 } 3231 3232 3233 /* 3234 * Function: 3235 * bcm_common_ptp_unicast_request_duration_get 3236 * Purpose: 3237 * Get durationField of REQUEST_UNICAST_TRANSMISSION TLV. 3238 * Parameters: 3239 * unit - (IN) Unit number. 3240 * ptp_id - (IN) PTP stack ID. 3241 * clock_num - (IN) PTP clock number. 3242 * port_num - (IN) PTP clock port number. 3243 * duration - (OUT) durationField (sec.) 3244 * Returns: 3245 * BCM_E_XXX - Function status. 3246 */ 3247 int 3248 bcm_common_ptp_unicast_request_duration_get( 3249 int unit, 3250 bcm_ptp_stack_id_t ptp_id, 3251 int clock_num, 3252 int port_num, 3253 uint32 *duration) 3254 { 3255 *duration = request_uc_durationField; 3256 3257 return BCM_E_NONE; 3258 } 3259 3260 /* 3261 * Function: 3262 * bcm_common_ptp_unicast_request_duration_set 3263 * Purpose: 3264 * Set durationField of REQUEST_UNICAST_TRANSMISSION TLV. 3265 * Parameters: 3266 * unit - (IN) Unit number. 3267 * ptp_id - (IN) PTP stack ID. 3268 * clock_num - (IN) PTP clock number. 3269 * port_num - (IN) PTP clock port number. 3270 * duration - (IN) durationField (sec.) 3271 * Returns: 3272 * BCM_E_XXX - Function status. 3273 */ 3274 int 3275 bcm_common_ptp_unicast_request_duration_set( 3276 int unit, 3277 bcm_ptp_stack_id_t ptp_id, 3278 int clock_num, 3279 int port_num, 3280 uint32 duration) 3281 { 3282 if (duration < request_uc_durationField_min) { 3283 request_uc_durationField = request_uc_durationField_min; 3284 } else if (duration > request_uc_durationField_max) { 3285 request_uc_durationField = request_uc_durationField_max; 3286 } else { 3287 request_uc_durationField = duration; 3288 } 3289 3290 return BCM_E_NONE; 3291 } 3292 3293 /* 3294 * Function: 3295 * bcm_common_ptp_unicast_request_duration_min_get 3296 * Purpose: 3297 * Get minimum durationField of REQUEST_UNICAST_TRANSMISSION TLV. 3298 * Parameters: 3299 * unit - (IN) Unit number. 3300 * ptp_id - (IN) PTP stack ID. 3301 * clock_num - (IN) PTP clock number. 3302 * port_num - (IN) PTP clock port number. 3303 * duration_min - (OUT) minimum durationField (sec.) 3304 * Returns: 3305 * BCM_E_XXX - Function status. 3306 */ 3307 int 3308 bcm_common_ptp_unicast_request_duration_min_get( 3309 int unit, 3310 bcm_ptp_stack_id_t ptp_id, 3311 int clock_num, 3312 int port_num, 3313 uint32 *duration_min) 3314 { 3315 *duration_min = request_uc_durationField_min; 3316 3317 return BCM_E_NONE; 3318 } 3319 3320 /* 3321 * Function: 3322 * bcm_common_ptp_unicast_request_duration_min_set 3323 * Purpose: 3324 * Set minimum durationField of REQUEST_UNICAST_TRANSMISSION TLV. 3325 * Parameters: 3326 * unit - (IN) Unit number. 3327 * ptp_id - (IN) PTP stack ID. 3328 * clock_num - (IN) PTP clock number. 3329 * port_num - (IN) PTP clock port number. 3330 * duration_min - (IN) minimum durationField (sec.) 3331 * Returns: 3332 * BCM_E_XXX - Function status. 3333 */ 3334 int 3335 bcm_common_ptp_unicast_request_duration_min_set( 3336 int unit, 3337 bcm_ptp_stack_id_t ptp_id, 3338 int clock_num, 3339 int port_num, 3340 uint32 duration_min) 3341 { 3342 if (duration_min > request_uc_durationField_max) { 3343 return BCM_E_PARAM; 3344 } 3345 3346 request_uc_durationField_min = duration_min; 3347 3348 /* durationField in-range enforcement. */ 3349 if (request_uc_durationField < duration_min) { 3350 request_uc_durationField = duration_min; 3351 } 3352 3353 return BCM_E_NONE; 3354 } 3355 3356 /* 3357 * Function: 3358 * bcm_common_ptp_unicast_request_duration_max_get 3359 * Purpose: 3360 * Get maximum durationField of REQUEST_UNICAST_TRANSMISSION TLV. 3361 * Parameters: 3362 * unit - (IN) Unit number. 3363 * ptp_id - (IN) PTP stack ID. 3364 * clock_num - (IN) PTP clock number. 3365 * port_num - (IN) PTP clock port number. 3366 * duration_max - (OUT) maximum durationField (sec.) 3367 * Returns: 3368 * BCM_E_XXX - Function status. 3369 */ 3370 int 3371 bcm_common_ptp_unicast_request_duration_max_get( 3372 int unit, 3373 bcm_ptp_stack_id_t ptp_id, 3374 int clock_num, 3375 int port_num, 3376 uint32 *duration_max) 3377 { 3378 *duration_max = request_uc_durationField_max; 3379 3380 return BCM_E_NONE; 3381 } 3382 3383 /* 3384 * Function: 3385 * bcm_common_ptp_unicast_request_duration_max_set 3386 * Purpose: 3387 * Set maximum durationField of REQUEST_UNICAST_TRANSMISSION TLV. 3388 * Parameters: 3389 * unit - (IN) Unit number. 3390 * ptp_id - (IN) PTP stack ID. 3391 * clock_num - (IN) PTP clock number. 3392 * port_num - (IN) PTP clock port number. 3393 * duration_max - (IN) maximum durationField (sec.) 3394 * Returns: 3395 * BCM_E_XXX - Function status. 3396 */ 3397 int 3398 bcm_common_ptp_unicast_request_duration_max_set( 3399 int unit, 3400 bcm_ptp_stack_id_t ptp_id, 3401 int clock_num, 3402 int port_num, 3403 uint32 duration_max) 3404 { 3405 if (duration_max < request_uc_durationField_min) { 3406 return BCM_E_PARAM; 3407 } 3408 3409 request_uc_durationField_max = duration_max; 3410 3411 /* durationField in-range enforcement. */ 3412 if (request_uc_durationField > duration_max) { 3413 request_uc_durationField = duration_max; 3414 } 3415 3416 return BCM_E_NONE; 3417 } 3418 3419 /* 3420 * Function: 3421 * delayed_master_table_update 3422 * Purpose: 3423 * DPC-called function to update the ToP's master table 3424 */ 3425 static void 3426 delayed_master_table_update( 3427 void *owner, 3428 void *arg_idx, 3429 void *arg_unit, 3430 void *arg_ptp_id, 3431 void *arg_clock_num) 3432 { 3433 int idx = PTR_TO_INT(arg_idx); 3434 int unit = PTR_TO_INT(arg_unit); 3435 bcm_ptp_stack_id_t ptp_id = (bcm_ptp_stack_id_t)PTR_TO_INT(arg_ptp_id); 3436 int clock_num = PTR_TO_INT(arg_clock_num); 3437 bcm_ptp_clock_unicast_master_t master_info; 3438 int rv; 3439 3440 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, 3441 clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 3442 PTP_ERROR_FUNC("_bcm_ptp_function_precheck()"); 3443 return; 3444 } 3445 3446 master_info.address = signaled_master[idx].master.peer_address; 3447 master_info.log_sync_interval = signaled_master[idx].log_sync_interval; 3448 master_info.log_min_delay_request_interval = signaled_master[idx].log_delay_interval; 3449 3450 bcm_ptp_static_unicast_master_add(unit, ptp_id, clock_num, 3451 signaled_master[idx].master.local_port_number, 3452 &master_info); 3453 } 3454 3455 #endif /* INCLUDE_PTP */