stats.c (30902B)
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: stats.c 8 * 9 * Purpose: 10 * 11 * Functions: 12 * bcm_common_ptp_packet_counters_clear 13 * bcm_common_ptp_packet_counters_get 14 * bcm_common_ptp_peer_dataset_get 15 * 16 * _bcm_ptp_packet_counters_msg_get 17 * _bcm_ptp_packet_counters_pci_get 18 * _bcm_ptp_update_peer_counts 19 * _bcm_ptp_update_peer_dataset 20 * _bcm_ptp_peer_dataset_get 21 * _bcm_ptp_clock_description_get 22 * _bcm_ptp_show_system_info 23 */ 24 25 #if defined(INCLUDE_PTP) 26 27 #include <bcm/ptp.h> 28 #include <bcm_int/common/ptp.h> 29 #include <bcm_int/ptp_common.h> 30 #include <bcm/error.h> 31 32 /* Constants and variables. */ 33 static const bcm_ptp_packet_counters_t counters_zero; 34 static const bcm_ptp_clock_port_packet_drop_counters_t drop_counters_zero = {0}; 35 36 37 static const bcm_ptp_port_identity_t portid_all = 38 {{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, PTP_IEEE1588_ALL_PORTS}; 39 40 /* Static functions. */ 41 static int _bcm_ptp_packet_counters_msg_get(int unit, bcm_ptp_stack_id_t ptp_id, 42 int clock_num, bcm_ptp_packet_counters_t *counters); 43 44 /* 45 * Function: 46 * bcm_common_ptp_packet_counters_clear 47 * Purpose: 48 * Reset packet counters. 49 * Parameters: 50 * unit - (IN) Unit number. 51 * ptp_id - (IN) PTP stack ID. 52 * clock_num - (IN) PTP clock number. 53 * port_num - (IN) PTP clock port number (for port-specific stats reset). 54 * counter_bitmap - (IN) counter bitmap 55 * Returns: 56 * BCM_E_XXX - Function status. 57 * Notes: 58 */ 59 int 60 bcm_common_ptp_packet_counters_clear( 61 int unit, 62 bcm_ptp_stack_id_t ptp_id, 63 int clock_num, 64 int port_num, 65 uint32 counter_bitmap) 66 { 67 int rv = BCM_E_UNAVAIL; 68 69 uint8 payload[PTP_MGMTMSG_PAYLOAD_PACKET_STATS_CLEAR_SIZE_OCTETS] = {0}; 70 uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS]; 71 int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 72 73 bcm_ptp_port_identity_t portid; 74 75 /* Mask unused bits */ 76 counter_bitmap &= BCM_PTP_PKT_COUNTER_ALL; 77 78 if (counter_bitmap == BCM_PTP_PKT_COUNTER_ALL || 79 counter_bitmap <= BCM_PTP_PKT_COUNTER_COMMON) { 80 /* To clear any/all common counters or all counters, port_num shall be 0xFFFF */ 81 port_num = PTP_IEEE1588_ALL_PORTS; 82 } 83 84 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, port_num))) { 85 return rv; 86 } 87 88 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 89 clock_num, port_num, &portid))) { 90 return rv; 91 } 92 93 /* 94 * Make payload. 95 * Octet 0-3 : counter_bitmap. 96 * Octet 4-7 : Reserved. 97 */ 98 _bcm_ptp_uint32_write(payload, counter_bitmap); 99 100 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, 101 clock_num, &portid, PTP_MGMTMSG_CMD, PTP_MGMTMSG_ID_PACKET_STATS, 102 payload, PTP_MGMTMSG_PAYLOAD_PACKET_STATS_CLEAR_SIZE_OCTETS, resp, &resp_len))) { 103 return rv; 104 } 105 106 return rv; 107 } 108 109 /* 110 * Function: 111 * bcm_common_ptp_packet_counters_get 112 * Purpose: 113 * Get packet counters. 114 * Parameters: 115 * unit - (IN) Unit number. 116 * ptp_id - (IN) PTP stack ID. 117 * clock_num - (IN) PTP clock number. 118 * counters - (OUT) Packet counts/statistics. 119 * Returns: 120 * BCM_E_XXX - Function status. 121 * Notes: 122 */ 123 int 124 bcm_common_ptp_packet_counters_get( 125 int unit, 126 bcm_ptp_stack_id_t ptp_id, 127 int clock_num, 128 bcm_ptp_packet_counters_t *counters) 129 { 130 return _bcm_ptp_packet_counters_msg_get(unit, ptp_id, clock_num, counters); 131 } 132 133 /* 134 * Function: 135 * _bcm_ptp_packet_counters_msg_get 136 * Purpose: 137 * Get packet counters via custom PTP managment message. 138 * Parameters: 139 * unit - (IN) Unit number. 140 * ptp_id - (IN) PTP stack ID. 141 * clock_num - (IN) PTP clock number. 142 * counters - (OUT) Packet counters. 143 * Returns: 144 * BCM_E_XXX - Function status. 145 * Notes: 146 */ 147 static int 148 _bcm_ptp_packet_counters_msg_get( 149 int unit, 150 bcm_ptp_stack_id_t ptp_id, 151 int clock_num, 152 bcm_ptp_packet_counters_t *counters) 153 { 154 int rv = BCM_E_UNAVAIL; 155 156 uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS]; 157 int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 158 int i = 0; 159 160 bcm_ptp_port_identity_t portid; 161 162 int port; 163 uint16 num_ports; 164 165 *counters = counters_zero; 166 167 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, 168 PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 169 return rv; 170 } 171 172 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 173 clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) { 174 return rv; 175 } 176 177 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, 178 clock_num, &portid, 179 PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_PACKET_STATS, 180 0, 0, resp, &resp_len))) { 181 return rv; 182 } 183 184 if (resp_len < PTP_MGMTMSG_PAYLOAD_PACKET_STATS_MIN_SIZE_OCTETS) { 185 /* Internal error : message too short to contain correct data. */ 186 return BCM_E_INTERNAL; 187 } 188 189 /* 190 * Parse response. 191 * Octet 0...5 : Custom management message key/identifier. 192 * BCM<null><null><null>. 193 * Octet 6...7 : Number of ports. 194 * Octet 8...11 : Packets transmitted. 195 * Octet 12...15 : Packets received. 196 * Octet 16...19 : Packets discarded. 197 * Octet 20...23 : RCPU encapsulated packets received. 198 * Octet 24...27 : IPv4 packets received. 199 * Octet 28...31 : IPv6 packets received. 200 * Octet 32...35 : L2 PTP packets received. 201 * Octet 36...39 : UDP PTP packets received. 202 * Octet 40...43 : Enduro sync packets transmitted. 203 * Octet 44...47 : Enduro sync packets received. 204 * Octet 48...51 : Rx queue overflows. 205 * Per Port: # = Port Number, I = 52 + 12(#-1) 206 * Octet I...I+3 : PTP port # packets transmitted. 207 * Octet I+4...I+7 : PTP port # packets received. 208 * Octet I+8...I+11 : PTP port # packets discarded. 209 */ 210 i = 6; 211 num_ports = _bcm_ptp_uint16_read(resp+i); 212 i += sizeof(uint16); 213 counters->packets_transmitted = _bcm_ptp_uint32_read(resp+i); 214 i += sizeof(uint32); 215 counters->packets_received = _bcm_ptp_uint32_read(resp+i); 216 i += sizeof(uint32); 217 counters->packets_discarded = _bcm_ptp_uint32_read(resp+i); 218 i += sizeof(uint32); 219 counters->rcpu_encap_packets_received = _bcm_ptp_uint32_read(resp+i); 220 i += sizeof(uint32); 221 counters->ipv4_packets_received = _bcm_ptp_uint32_read(resp+i); 222 i += sizeof(uint32); 223 counters->ipv6_packets_received = _bcm_ptp_uint32_read(resp+i); 224 i += sizeof(uint32); 225 counters->l2_ptp_packets_received = _bcm_ptp_uint32_read(resp+i); 226 i += sizeof(uint32); 227 counters->udp_ptp_packets_received = _bcm_ptp_uint32_read(resp+i); 228 i += sizeof(uint32); 229 counters->enduro_sync_packets_transmitted = _bcm_ptp_uint32_read(resp+i); 230 i += sizeof(uint32); 231 counters->enduro_sync_packets_received = _bcm_ptp_uint32_read(resp+i); 232 i += sizeof(uint32); 233 counters->rx_queue_overflows = _bcm_ptp_uint32_read(resp+i); 234 i += sizeof(uint32); 235 236 for (port = 0; port < num_ports; ++port) { 237 counters->port_packets_transmitted[port] = _bcm_ptp_uint32_read(resp+i); 238 i += sizeof(uint32); 239 counters->port_packets_received[port] = _bcm_ptp_uint32_read(resp+i); 240 i += sizeof(uint32); 241 counters->port_packets_discarded[port] = _bcm_ptp_uint32_read(resp+i); 242 i += sizeof(uint32); 243 } 244 245 return rv; 246 } 247 248 249 /* 250 * Function: 251 * _bcm_ptp_update_peer_counts 252 * Purpose: 253 * Update peer message counts. 254 * Parameters: 255 * unit - (IN) Unit number. 256 * ptp_id - (IN) PTP stack id 257 * clock_num - (IN) PTP clock index 258 * localPortNum - (IN) Local PTP clock port number. 259 * clockID - (IN) Peer PTP clock identity. 260 * port_addr - (IN) Peer PTP port address. 261 * isMaster - (IN) Peer-is-master Boolean. 262 * announces - (IN) Number of addt'l announce messages. 263 * syncs - (IN) Number of addt'l sync messages. 264 * delayreqs - (IN) Number of addt'l delay request messages. 265 * delayresps - (IN) Number of addt'l dealy response messages. 266 * mgmts - (IN) Number of addt'l management messages. 267 * signals - (IN) Number of addt'l signaling messages. 268 * rejected - (IN) Number of addt'l rejected messages. 269 * Returns: 270 * BCM_E_XXX - Function status. 271 * Notes: 272 */ 273 int 274 _bcm_ptp_update_peer_counts( 275 int unit, 276 int ptp_id, 277 int clock_num, 278 uint16 localPortNum, 279 bcm_ptp_clock_identity_t *clockID, 280 bcm_ptp_clock_port_address_t *port_addr, 281 int isMaster, 282 unsigned announces, 283 unsigned syncs, 284 unsigned followups, 285 unsigned delayreqs, 286 unsigned delayresps, 287 unsigned mgmts, 288 unsigned signals, 289 unsigned rejected, 290 bcm_gport_t *phy_port) 291 { 292 int rv = BCM_E_NONE; 293 unsigned index; 294 _bcm_ptp_info_t *ptp_info_p; 295 int max_peer_dataset_entries; 296 bcm_ptp_peer_dataset_t *peerTable; 297 298 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 299 return rv; 300 } 301 302 peerTable = &_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num].peerTable; 303 304 sal_mutex_take(peerTable->lock, sal_mutex_FOREVER); 305 306 /* Look in the table for a match */ 307 for (index = 0; index < peerTable->num_peers; index++) { 308 if ((localPortNum == 0xffff) || 309 (peerTable->peer[index].local_port_number == 0xffff) || 310 (localPortNum == peerTable->peer[index].local_port_number)) { 311 if (!_bcm_ptp_port_address_cmp(port_addr, &peerTable->peer[index].port_address)) { 312 /* We have a match, so inc the counts as listed a return */ 313 if (isMaster) { 314 COMPILER_64_ADD_32(peerTable->peer[index].rx_announces, announces); 315 COMPILER_64_ADD_32(peerTable->peer[index].rx_syncs, syncs); 316 COMPILER_64_ADD_32(peerTable->peer[index].rx_followups, followups); 317 COMPILER_64_ADD_32(peerTable->peer[index].tx_delayreqs, delayreqs); 318 COMPILER_64_ADD_32(peerTable->peer[index].rx_delayresps, delayresps); 319 COMPILER_64_ADD_32(peerTable->peer[index].tx_mgmts, mgmts); 320 COMPILER_64_ADD_32(peerTable->peer[index].tx_signals, signals); 321 } else { 322 COMPILER_64_ADD_32(peerTable->peer[index].tx_announces, announces); 323 COMPILER_64_ADD_32(peerTable->peer[index].tx_syncs, syncs); 324 COMPILER_64_ADD_32(peerTable->peer[index].tx_followups, followups); 325 COMPILER_64_ADD_32(peerTable->peer[index].rx_delayreqs, delayreqs); 326 COMPILER_64_ADD_32(peerTable->peer[index].tx_delayresps, delayresps); 327 COMPILER_64_ADD_32(peerTable->peer[index].rx_mgmts, mgmts); 328 COMPILER_64_ADD_32(peerTable->peer[index].rx_signals, signals); 329 } 330 331 if (peerTable->peer[index].local_port_number == 0xffff) { 332 peerTable->peer[index].local_port_number = localPortNum; 333 } 334 335 COMPILER_64_ADD_32(peerTable->peer[index].rejected, rejected); 336 if (clockID) { 337 memcpy(peerTable->peer[index].clock_identity, clockID, BCM_PTP_CLOCK_EUID_IEEE1588_SIZE); 338 } 339 if (SOC_HAS_PTP_INTERNAL_STACK_SUPPORT(unit)) { 340 if (phy_port) { 341 peerTable->peer[index].phy_port = *phy_port; 342 } 343 } 344 sal_mutex_give(peerTable->lock); 345 return rv; 346 } 347 } 348 } 349 350 SET_PTP_INFO; 351 352 max_peer_dataset_entries = ptp_info_p->stack_info->unicast_slave_table_size + 353 PTP_MAX_CLOCK_INSTANCE_PORTS + _PTP_MAX_FOREIGN_MASTER_DATASET_ENTRIES; 354 355 /* Make sure we have room */ 356 if (peerTable->num_peers >= max_peer_dataset_entries) { 357 sal_mutex_give(peerTable->lock); 358 LOG_VERBOSE(BSL_LS_BCM_PTP, 359 (BSL_META_U(unit, 360 "PTP Peer Statistics full, dropping count\n"))); 361 return BCM_E_NONE; 362 } 363 364 /* Add an entry */ 365 index = peerTable->num_peers; 366 367 peerTable->peer[index].local_port_number = localPortNum; 368 if (clockID) { 369 memcpy(peerTable->peer[index].clock_identity, clockID, BCM_PTP_CLOCK_EUID_IEEE1588_SIZE); 370 } else { 371 memset(peerTable->peer[index].clock_identity, 0, BCM_PTP_CLOCK_EUID_IEEE1588_SIZE); 372 } 373 peerTable->peer[index].port_address = *port_addr; 374 375 if (isMaster) { 376 COMPILER_64_SET(peerTable->peer[index].rx_announces, 0, announces); 377 COMPILER_64_SET(peerTable->peer[index].rx_syncs, 0, syncs); 378 COMPILER_64_SET(peerTable->peer[index].rx_followups, 0, followups); 379 COMPILER_64_SET(peerTable->peer[index].tx_delayreqs, 0, delayreqs); 380 COMPILER_64_SET(peerTable->peer[index].rx_delayresps, 0, delayresps); 381 COMPILER_64_SET(peerTable->peer[index].tx_mgmts, 0, mgmts); 382 COMPILER_64_SET(peerTable->peer[index].tx_signals, 0, signals); 383 COMPILER_64_SET(peerTable->peer[index].tx_announces, 0, 0); 384 COMPILER_64_SET(peerTable->peer[index].tx_syncs, 0, 0); 385 COMPILER_64_SET(peerTable->peer[index].tx_followups, 0, 0); 386 COMPILER_64_SET(peerTable->peer[index].rx_delayreqs, 0, 0); 387 COMPILER_64_SET(peerTable->peer[index].tx_delayresps, 0, 0); 388 COMPILER_64_SET(peerTable->peer[index].rx_mgmts, 0, 0); 389 COMPILER_64_SET(peerTable->peer[index].rx_signals, 0, 0); 390 } else { 391 COMPILER_64_SET(peerTable->peer[index].tx_announces, 0, announces); 392 COMPILER_64_SET(peerTable->peer[index].tx_syncs, 0, syncs); 393 COMPILER_64_SET(peerTable->peer[index].tx_followups, 0, followups); 394 COMPILER_64_SET(peerTable->peer[index].rx_delayreqs, 0, delayreqs); 395 COMPILER_64_SET(peerTable->peer[index].tx_delayresps, 0, delayresps); 396 COMPILER_64_SET(peerTable->peer[index].rx_mgmts, 0, mgmts); 397 COMPILER_64_SET(peerTable->peer[index].rx_signals, 0, signals); 398 COMPILER_64_SET(peerTable->peer[index].rx_announces, 0, 0); 399 COMPILER_64_SET(peerTable->peer[index].rx_syncs, 0, 0); 400 COMPILER_64_SET(peerTable->peer[index].rx_followups, 0, 0); 401 COMPILER_64_SET(peerTable->peer[index].tx_delayreqs, 0, 0); 402 COMPILER_64_SET(peerTable->peer[index].rx_delayresps, 0, 0); 403 COMPILER_64_SET(peerTable->peer[index].tx_mgmts, 0, 0); 404 COMPILER_64_SET(peerTable->peer[index].tx_signals, 0, 0); 405 } 406 COMPILER_64_SET(peerTable->peer[index].rejected, 0, rejected); 407 if (SOC_HAS_PTP_INTERNAL_STACK_SUPPORT(unit)) { 408 if (phy_port) { 409 peerTable->peer[index].phy_port = *phy_port; 410 } 411 } 412 413 peerTable->num_peers++; 414 415 sal_mutex_give(peerTable->lock); 416 417 return rv; 418 } 419 420 /* 421 * Function: 422 * _bcm_ptp_update_peer_dataset 423 * Purpose: 424 * Update peer dataset. 425 * Parameters: 426 * unit - (IN) Unit number. 427 * ptp_id - (IN) PTP stack ID. 428 * clock_num - (IN) PTP clock number. 429 * port_num - (IN) PTP clock port number. 430 * Returns: 431 * BCM_E_XXX - Function status. 432 * Notes: 433 */ 434 int 435 _bcm_ptp_update_peer_dataset( 436 int unit, 437 bcm_ptp_stack_id_t ptp_id, 438 int clock_num, 439 int port_num) 440 { 441 int rv = BCM_E_NONE; 442 unsigned firstTime = 1; 443 unsigned index; 444 unsigned module_num = 0; 445 unsigned phy_port_num = 0; 446 bcm_gport_t phy_port; 447 448 bcm_ptp_port_identity_t portid = portid_all; 449 uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS]; 450 int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 451 int expected_per_peerdata_resp_len = 0; 452 _bcm_ptp_clock_cache_t *clock_cache; 453 454 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, port_num))) { 455 return rv; 456 } 457 458 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 459 clock_num, port_num, &portid))) { 460 return rv; 461 } 462 463 clock_cache = &_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num]; 464 if (!clock_cache->in_use) 465 return BCM_E_UNAVAIL; 466 467 while (1) { 468 if (firstTime) { 469 /* Send "first" management message. */ 470 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, 471 clock_num, &portid, PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_PEER_DATASET_FIRST, 472 0, 0, resp, &resp_len))) { 473 return rv; 474 } 475 firstTime = 0; 476 } else { 477 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, 478 clock_num, &portid, PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_PEER_DATASET_NEXT, 479 0, 0, resp, &resp_len))) { 480 return rv; 481 } 482 } 483 484 /* 485 * Parse response. 486 * Octet 0 number of peers in dump set (0 - _PTP_MAX_PEER_DATASET_CHUNK_SIZE) 487 * Octet 1 reserved 488 * Octet 2..3 PEER#0 Local port num 489 * Octet 4..11 PEER#0 Peer clock ID 490 * Octet 12 PEER#0 Peer is master 491 * Octet 13 PEER#0 Peer address type 492 * Octet 14..29 PEER#0 Peer network address 493 * Octet 30..31 PEER#0 Announces 494 * Octet 32..33 PEER#0 Syncs 495 * Octet 34..35 PEER#0 Followups 496 * Octet 36..37 PEER#0 delayreqs 497 * Octet 38..39 PEER#0 delayresps 498 * Octet 40..41 PEER#0 rejected count 499 * Octet 41..42 PEER#0 module number 500 * Octet 43..44 PEER#0 physical port number 501 * Octet 42..81 PEER#1 (as PEER#0) 502 * Octet 82.... 503 */ 504 505 if (resp_len < 1) { 506 return BCM_E_INTERNAL; 507 } 508 509 if (resp[0] > _PTP_MAX_PEER_DATASET_CHUNK_SIZE) { 510 return BCM_E_INTERNAL; 511 } 512 513 if (SOC_HAS_PTP_INTERNAL_STACK_SUPPORT(unit)) { 514 expected_per_peerdata_resp_len = 44; 515 } else { 516 expected_per_peerdata_resp_len = 40; 517 } 518 519 if (resp_len != 2 + resp[0] * expected_per_peerdata_resp_len ) { 520 return BCM_E_INTERNAL; 521 } 522 523 /* return when the ToP doesn't have any more elements to send us */ 524 if (resp[0] == 0) { 525 return (rv); 526 } 527 528 /* Since we have elements update the tables */ 529 for (index = 0; index < resp[0]; index++) { 530 bcm_ptp_clock_identity_t clockIDStorage, *clockID; 531 bcm_ptp_clock_port_address_t port_addr; 532 int addr_len; 533 unsigned localPortNum, announces, syncs, followups, delayreqs, delayresps, mgmts, signals, rejected; 534 int isMaster; 535 536 unsigned offset = 2 + index * expected_per_peerdata_resp_len; 537 538 localPortNum = _bcm_ptp_uint16_read(resp + offset); 539 offset += 2; 540 541 memcpy(clockIDStorage, resp + offset, BCM_PTP_CLOCK_EUID_IEEE1588_SIZE); 542 offset += BCM_PTP_CLOCK_EUID_IEEE1588_SIZE; 543 544 isMaster = resp[offset++]; 545 546 port_addr.addr_type = resp[offset++]; 547 addr_len = _bcm_ptp_addr_len(port_addr.addr_type); 548 if (addr_len) { 549 memcpy(port_addr.address, resp + offset, addr_len); 550 } else { 551 return BCM_E_INTERNAL; 552 } 553 offset += 16; 554 555 announces = _bcm_ptp_uint16_read(resp + offset); 556 offset += 2; 557 558 syncs = _bcm_ptp_uint16_read(resp + offset); 559 offset += 2; 560 561 followups = _bcm_ptp_uint16_read(resp + offset); 562 offset += 2; 563 564 delayreqs = _bcm_ptp_uint16_read(resp + offset); 565 offset += 2; 566 567 delayresps = _bcm_ptp_uint16_read(resp + offset); 568 offset += 2; 569 570 mgmts = 0; 571 signals = 0; 572 573 rejected = _bcm_ptp_uint16_read(resp + offset); 574 offset += 2; 575 576 if (SOC_HAS_PTP_INTERNAL_STACK_SUPPORT(unit)) { 577 module_num = _bcm_ptp_uint16_read(resp + offset); 578 offset += 2; 579 phy_port_num = _bcm_ptp_uint16_read(resp + offset); 580 BCM_GPORT_MODPORT_SET(phy_port, module_num, phy_port_num); 581 } 582 583 if (_bcm_ptp_is_clockid_null(clockIDStorage)) { 584 clockID = 0; 585 } else { 586 clockID = &clockIDStorage; 587 } 588 589 if (BCM_FAILURE(rv = _bcm_ptp_update_peer_counts(unit, ptp_id, clock_num, localPortNum, clockID, 590 &port_addr, isMaster, announces, syncs, followups, delayreqs, 591 delayresps, mgmts, signals, rejected, &phy_port))) { 592 return rv; 593 } 594 } 595 596 /* 597 * Reset response message length. 598 * _bcm_ptp_management_message_send() uses argument as maximum allowable 599 * message length and actual message lengths on function entry and exit, 600 * respectively. 601 */ 602 resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 603 } 604 605 return (rv); 606 } 607 608 /* 609 * Function: 610 * _bcm_ptp_peer_dataset_get 611 * Purpose: 612 * Get peer dataset(s). 613 * Parameters: 614 * unit - (IN) Unit number. 615 * ptp_id - (IN) PTP stack ID. 616 * clock_num - (IN) PTP clock number. 617 * port_num - (IN) PTP clock port number. 618 * max_num_peers - (IN) Maximum number of peer dataset entries. 619 * peers - (OUT) Peers. 620 * num_peers - (OUT) Number of peer dataset entries. 621 * Returns: 622 * BCM_E_XXX - Function status. 623 * Notes: 624 * All-ports identifier (i.e. all-ones port_num) returns all peers. 625 */ 626 int 627 _bcm_ptp_peer_dataset_get( 628 int unit, 629 bcm_ptp_stack_id_t ptp_id, 630 int clock_num, 631 int port_num, 632 int max_num_peers, 633 bcm_ptp_peer_entry_t *peers, 634 int *num_peers) 635 { 636 int rv; 637 static const bcm_ptp_peer_entry_t zero_peer = {0}; 638 bcm_ptp_peer_dataset_t *peerTable; 639 unsigned peer_index; 640 unsigned temp_index; 641 642 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, port_num))) { 643 return rv; 644 } 645 646 if (BCM_FAILURE(rv = _bcm_ptp_update_peer_dataset(unit, ptp_id, clock_num, port_num))) { 647 return rv; 648 } 649 650 peerTable = &_bcm_common_ptp_unit_array[unit].stack_array[ptp_id].clock_array[clock_num].peerTable; 651 652 sal_mutex_take(peerTable->lock, sal_mutex_FOREVER); 653 654 *num_peers = 0; 655 for (peer_index = 0; peer_index < peerTable->num_peers; ) { 656 /* Stop if caller-provided table is full. */ 657 if (*num_peers >= max_num_peers) { 658 break; 659 } 660 661 /* Find peers associated with matching local port number. */ 662 if (port_num == peerTable->peer[peer_index].local_port_number || 663 port_num == PTP_IEEE1588_ALL_PORTS) { 664 /* Get matching peer. */ 665 peers[(*num_peers)++] = peerTable->peer[peer_index]; 666 667 /* Move remaining peers up in list. */ 668 for (temp_index = peer_index + 1; temp_index < peerTable->num_peers; temp_index++) { 669 peerTable->peer[temp_index - 1] = peerTable->peer[temp_index]; 670 } 671 peerTable->peer[--(peerTable->num_peers)] = zero_peer; 672 } else { 673 peer_index++; 674 } 675 } 676 677 sal_mutex_give(peerTable->lock); 678 679 return BCM_E_NONE; 680 } 681 682 /* 683 * Function: 684 * _bcm_ptp_clock_description_get 685 * Purpose: 686 * Get PTP clock description. 687 * Parameters: 688 * unit - (IN) Unit number. 689 * ptp_id - (IN) PTP stack ID. 690 * clock_num - (IN) PTP clock number. 691 * port_num - (IN) PTP clock port number. 692 * description - (OUT) PTP clock description. 693 * Returns: 694 * BCM_E_XXX - Function status. 695 * Notes: 696 */ 697 int 698 _bcm_ptp_clock_description_get( 699 int unit, 700 bcm_ptp_stack_id_t ptp_id, 701 int clock_num, 702 int port_num, 703 _bcm_ptp_clock_description_t *description) 704 { 705 int rv = BCM_E_UNAVAIL; 706 707 uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS]; 708 int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 709 710 bcm_ptp_port_identity_t portid; 711 712 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, port_num))) { 713 return rv; 714 } 715 716 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 717 clock_num, port_num, &portid))) { 718 return rv; 719 } 720 721 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, 722 clock_num, &portid, PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CLOCK_DESCRIPTION, 723 0, 0, resp, &resp_len))) { 724 return rv; 725 } 726 727 description->size = resp_len; 728 description->data = sal_alloc(resp_len,"_bcm_ptp_clock_description_get"); 729 memcpy(description->data,resp,resp_len); 730 return BCM_E_NONE; 731 } 732 733 /* 734 * Function: 735 * _bcm_ptp_show_system_info 736 * Purpose: 737 * Report ToP CPU and memory use information to debug stream. 738 * Parameters: 739 * unit - (IN) Unit number. 740 * ptp_id - (IN) PTP stack ID. 741 * clock_num - (IN) PTP clock number. 742 * Returns: 743 * BCM_E_XXX - Function status. 744 * Notes: 745 */ 746 int 747 _bcm_ptp_show_system_info( 748 int unit, 749 bcm_ptp_stack_id_t ptp_id, 750 int clock_num) 751 { 752 int rv = BCM_E_UNAVAIL; 753 754 uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS]; 755 int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 756 757 bcm_ptp_port_identity_t portid; 758 759 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, 760 PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 761 return rv; 762 } 763 764 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 765 clock_num, PTP_IEEE1588_ALL_PORTS, &portid))) { 766 return rv; 767 } 768 769 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, 770 clock_num, &portid, PTP_MGMTMSG_CMD, PTP_MGMTMSG_ID_SHOW_SYSTEM_INFO, 771 0, 0, resp, &resp_len))) { 772 return rv; 773 } 774 775 return BCM_E_NONE; 776 } 777 778 /* 779 * Function: 780 * bcm_common_ptp_peer_dataset_get 781 * Purpose: 782 * Get Peer Dataset 783 * Parameters: 784 * unit - (IN) Unit number 785 * ptp_id - (IN) PTP stack ID 786 * clock_num - (IN) PTP clock number 787 * port_num - (IN) PTP port number 788 * max_num_peers - (IN) max # of peer entries 789 * peers - (OUT) list of peer entries 790 * *num_peers - (OUT) actual # of peer entries returned in peers 791 * Returns: 792 * int 793 * Notes: 794 */ 795 int 796 bcm_common_ptp_peer_dataset_get( 797 int unit, 798 bcm_ptp_stack_id_t ptp_id, 799 int clock_num, 800 int port_num, 801 int max_num_peers, 802 bcm_ptp_peer_entry_t *peers, 803 int *num_peers) 804 { 805 int rc; 806 807 rc = _bcm_ptp_peer_dataset_get(unit, ptp_id, clock_num, port_num, max_num_peers, peers, num_peers); 808 809 return (rc); 810 } 811 812 int 813 bcm_common_ptp_clock_port_drop_counters_enable_set( 814 int unit, 815 bcm_ptp_stack_id_t ptp_id, 816 int clock_num, 817 uint32 clock_port, 818 int enable) 819 { 820 int rv = BCM_E_UNAVAIL; 821 822 uint8 payload[PTP_MGMTMSG_PAYLOAD_PACKET_DROP_STATS_ENABLE_SIZE_OCTETS] = {0}; 823 uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS]; 824 int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 825 826 bcm_ptp_port_identity_t portid; 827 828 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, clock_port))) { 829 return rv; 830 } 831 832 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 833 clock_num, clock_port, &portid))) { 834 return rv; 835 } 836 837 payload[0] = enable ? 1:0; 838 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, 839 clock_num, &portid, PTP_MGMTMSG_SET, PTP_MGMTMSG_ID_CLOCK_PORTS_DROP_COUNT, 840 payload, PTP_MGMTMSG_PAYLOAD_PACKET_DROP_STATS_ENABLE_SIZE_OCTETS, resp, &resp_len))) { 841 return rv; 842 } 843 844 return rv; 845 } 846 847 int 848 bcm_common_ptp_clock_port_drop_counters_get( 849 int unit, 850 bcm_ptp_stack_id_t ptp_id, 851 int clock_num, 852 uint32 clock_port, 853 bcm_ptp_clock_port_packet_drop_counters_t *counters) 854 { 855 int rv = BCM_E_UNAVAIL; 856 857 uint8 resp[PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS]; 858 int resp_len = PTP_MGMTMSG_RESP_MAX_SIZE_OCTETS; 859 int i = 0; 860 bcm_ptp_port_identity_t portid; 861 862 *counters = drop_counters_zero; 863 864 if (BCM_FAILURE(rv = _bcm_ptp_function_precheck(unit, ptp_id, clock_num, 865 PTP_CLOCK_PORT_NUMBER_DEFAULT))) { 866 return rv; 867 } 868 869 if (BCM_FAILURE(rv = bcm_common_ptp_clock_port_identity_get(unit, ptp_id, 870 clock_num, clock_port, &portid))) { 871 return rv; 872 } 873 874 if (BCM_FAILURE(rv = _bcm_ptp_management_message_send(unit, ptp_id, 875 clock_num, &portid, 876 PTP_MGMTMSG_GET, PTP_MGMTMSG_ID_CLOCK_PORTS_DROP_COUNT, 877 0, 0, resp, &resp_len))) { 878 return rv; 879 } 880 881 if (resp_len < PTP_MGMTMSG_PAYLOAD_PACKET_STATS_MIN_SIZE_OCTETS) { 882 /* Internal error : message too short to contain correct data. */ 883 return BCM_E_INTERNAL; 884 } 885 i = 6; 886 counters->domain_mismatch = _bcm_ptp_uint32_read(resp+i); 887 i += sizeof(uint32); 888 counters->memory_alloc_failure = _bcm_ptp_uint32_read(resp+i); 889 i += sizeof(uint32); 890 counters->pkt_len_too_short = _bcm_ptp_uint32_read(resp+i); 891 i += sizeof(uint32); 892 counters->pkt_rcvd_on_bad_port_state = _bcm_ptp_uint32_read(resp+i); 893 i += sizeof(uint32); 894 counters->ptp_profile_mismatch = _bcm_ptp_uint32_read(resp+i); 895 i += sizeof(uint32); 896 counters->clock_port_mismatch = _bcm_ptp_uint32_read(resp+i); 897 i += sizeof(uint32); 898 counters->ptp_packet_parsing_failure = _bcm_ptp_uint32_read(resp+i); 899 i += sizeof(uint32); 900 counters->unicast_delreq_from_unknown_slave = _bcm_ptp_uint32_read(resp+i); 901 i += sizeof(uint32); 902 903 counters->announce_rcvd_on_master_only_port = _bcm_ptp_uint32_read(resp+i); 904 i += sizeof(uint32); 905 counters->announce_rcvd_with_invalid_steps_removed_field = _bcm_ptp_uint32_read(resp+i); 906 i += sizeof(uint32); 907 counters->announce_from_unknown_unicast_master = _bcm_ptp_uint32_read(resp+i); 908 i += sizeof(uint32); 909 counters->announce_rcvd_on_gps_timesource_ptp_port = _bcm_ptp_uint32_read(resp+i); 910 i += sizeof(uint32); 911 912 counters->sync_rcvd_invalid = _bcm_ptp_uint32_read(resp+i); 913 i += sizeof(uint32); 914 counters->sync_rcvd_on_ptp_port_without_master = _bcm_ptp_uint32_read(resp+i); 915 i += sizeof(uint32); 916 917 return rv; 918 } 919 #endif /* defined(INCLUDE_PTP)*/