653 lines
21 KiB
C
653 lines
21 KiB
C
/*
|
|
* Copyright (c) 2016 Intel Corporation
|
|
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_DECLARE(net_shell);
|
|
|
|
#include <stdlib.h>
|
|
|
|
#if defined(CONFIG_NET_GPTP)
|
|
#include <zephyr/net/gptp.h>
|
|
#include "ethernet/gptp/gptp_messages.h"
|
|
#include "ethernet/gptp/gptp_md.h"
|
|
#include "ethernet/gptp/gptp_state.h"
|
|
#include "ethernet/gptp/gptp_data_set.h"
|
|
#include "ethernet/gptp/gptp_private.h"
|
|
#endif
|
|
|
|
#include "net_shell_private.h"
|
|
|
|
#if defined(CONFIG_NET_GPTP)
|
|
static const char *selected_role_str(int port);
|
|
|
|
static void gptp_port_cb(int port, struct net_if *iface, void *user_data)
|
|
{
|
|
struct net_shell_user_data *data = user_data;
|
|
const struct shell *sh = data->sh;
|
|
int *count = data->user_data;
|
|
|
|
if (*count == 0) {
|
|
PR("Port Interface \tRole\n");
|
|
}
|
|
|
|
(*count)++;
|
|
|
|
PR("%2d %p [%d] \t%s\n", port, iface, net_if_get_by_iface(iface),
|
|
selected_role_str(port));
|
|
}
|
|
|
|
static const char *pdelay_req2str(enum gptp_pdelay_req_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_PDELAY_REQ_NOT_ENABLED:
|
|
return "REQ_NOT_ENABLED";
|
|
case GPTP_PDELAY_REQ_INITIAL_SEND_REQ:
|
|
return "INITIAL_SEND_REQ";
|
|
case GPTP_PDELAY_REQ_RESET:
|
|
return "REQ_RESET";
|
|
case GPTP_PDELAY_REQ_SEND_REQ:
|
|
return "SEND_REQ";
|
|
case GPTP_PDELAY_REQ_WAIT_RESP:
|
|
return "WAIT_RESP";
|
|
case GPTP_PDELAY_REQ_WAIT_FOLLOW_UP:
|
|
return "WAIT_FOLLOW_UP";
|
|
case GPTP_PDELAY_REQ_WAIT_ITV_TIMER:
|
|
return "WAIT_ITV_TIMER";
|
|
}
|
|
|
|
return "<unknown>";
|
|
};
|
|
|
|
static const char *pdelay_resp2str(enum gptp_pdelay_resp_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_PDELAY_RESP_NOT_ENABLED:
|
|
return "RESP_NOT_ENABLED";
|
|
case GPTP_PDELAY_RESP_INITIAL_WAIT_REQ:
|
|
return "INITIAL_WAIT_REQ";
|
|
case GPTP_PDELAY_RESP_WAIT_REQ:
|
|
return "WAIT_REQ";
|
|
case GPTP_PDELAY_RESP_WAIT_TSTAMP:
|
|
return "WAIT_TSTAMP";
|
|
}
|
|
|
|
return "<unknown>";
|
|
}
|
|
|
|
static const char *sync_rcv2str(enum gptp_sync_rcv_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_SYNC_RCV_DISCARD:
|
|
return "DISCARD";
|
|
case GPTP_SYNC_RCV_WAIT_SYNC:
|
|
return "WAIT_SYNC";
|
|
case GPTP_SYNC_RCV_WAIT_FOLLOW_UP:
|
|
return "WAIT_FOLLOW_UP";
|
|
}
|
|
|
|
return "<unknown>";
|
|
}
|
|
|
|
static const char *sync_send2str(enum gptp_sync_send_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_SYNC_SEND_INITIALIZING:
|
|
return "INITIALIZING";
|
|
case GPTP_SYNC_SEND_SEND_SYNC:
|
|
return "SEND_SYNC";
|
|
case GPTP_SYNC_SEND_SEND_FUP:
|
|
return "SEND_FUP";
|
|
}
|
|
|
|
return "<unknown>";
|
|
}
|
|
|
|
static const char *pss_rcv2str(enum gptp_pss_rcv_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_PSS_RCV_DISCARD:
|
|
return "DISCARD";
|
|
case GPTP_PSS_RCV_RECEIVED_SYNC:
|
|
return "RECEIVED_SYNC";
|
|
}
|
|
|
|
return "<unknown>";
|
|
}
|
|
|
|
static const char *pss_send2str(enum gptp_pss_send_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_PSS_SEND_TRANSMIT_INIT:
|
|
return "TRANSMIT_INIT";
|
|
case GPTP_PSS_SEND_SYNC_RECEIPT_TIMEOUT:
|
|
return "SYNC_RECEIPT_TIMEOUT";
|
|
case GPTP_PSS_SEND_SEND_MD_SYNC:
|
|
return "SEND_MD_SYNC";
|
|
case GPTP_PSS_SEND_SET_SYNC_RECEIPT_TIMEOUT:
|
|
return "SET_SYNC_RECEIPT_TIMEOUT";
|
|
}
|
|
|
|
return "<unknown>";
|
|
}
|
|
|
|
static const char *pa_rcv2str(enum gptp_pa_rcv_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_PA_RCV_DISCARD:
|
|
return "DISCARD";
|
|
case GPTP_PA_RCV_RECEIVE:
|
|
return "RECEIVE";
|
|
}
|
|
|
|
return "<unknown>";
|
|
};
|
|
|
|
static const char *pa_info2str(enum gptp_pa_info_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_PA_INFO_DISABLED:
|
|
return "DISABLED";
|
|
case GPTP_PA_INFO_POST_DISABLED:
|
|
return "POST_DISABLED";
|
|
case GPTP_PA_INFO_AGED:
|
|
return "AGED";
|
|
case GPTP_PA_INFO_UPDATE:
|
|
return "UPDATE";
|
|
case GPTP_PA_INFO_CURRENT:
|
|
return "CURRENT";
|
|
case GPTP_PA_INFO_RECEIVE:
|
|
return "RECEIVE";
|
|
case GPTP_PA_INFO_SUPERIOR_MASTER_PORT:
|
|
return "SUPERIOR_MASTER_PORT";
|
|
case GPTP_PA_INFO_REPEATED_MASTER_PORT:
|
|
return "REPEATED_MASTER_PORT";
|
|
case GPTP_PA_INFO_INFERIOR_MASTER_OR_OTHER_PORT:
|
|
return "INFERIOR_MASTER_OR_OTHER_PORT";
|
|
}
|
|
|
|
return "<unknown>";
|
|
};
|
|
|
|
static const char *pa_transmit2str(enum gptp_pa_transmit_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_PA_TRANSMIT_INIT:
|
|
return "INIT";
|
|
case GPTP_PA_TRANSMIT_PERIODIC:
|
|
return "PERIODIC";
|
|
case GPTP_PA_TRANSMIT_IDLE:
|
|
return "IDLE";
|
|
case GPTP_PA_TRANSMIT_POST_IDLE:
|
|
return "POST_IDLE";
|
|
}
|
|
|
|
return "<unknown>";
|
|
};
|
|
|
|
static const char *site_sync2str(enum gptp_site_sync_sync_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_SSS_INITIALIZING:
|
|
return "INITIALIZING";
|
|
case GPTP_SSS_RECEIVING_SYNC:
|
|
return "RECEIVING_SYNC";
|
|
}
|
|
|
|
return "<unknown>";
|
|
}
|
|
|
|
static const char *clk_slave2str(enum gptp_clk_slave_sync_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_CLK_SLAVE_SYNC_INITIALIZING:
|
|
return "INITIALIZING";
|
|
case GPTP_CLK_SLAVE_SYNC_SEND_SYNC_IND:
|
|
return "SEND_SYNC_IND";
|
|
}
|
|
|
|
return "<unknown>";
|
|
};
|
|
|
|
static const char *pr_selection2str(enum gptp_pr_selection_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_PR_SELECTION_INIT_BRIDGE:
|
|
return "INIT_BRIDGE";
|
|
case GPTP_PR_SELECTION_ROLE_SELECTION:
|
|
return "ROLE_SELECTION";
|
|
}
|
|
|
|
return "<unknown>";
|
|
};
|
|
|
|
static const char *cms_rcv2str(enum gptp_cms_rcv_states state)
|
|
{
|
|
switch (state) {
|
|
case GPTP_CMS_RCV_INITIALIZING:
|
|
return "INITIALIZING";
|
|
case GPTP_CMS_RCV_WAITING:
|
|
return "WAITING";
|
|
case GPTP_CMS_RCV_SOURCE_TIME:
|
|
return "SOURCE_TIME";
|
|
}
|
|
|
|
return "<unknown>";
|
|
};
|
|
|
|
#if !defined(USCALED_NS_TO_NS)
|
|
#define USCALED_NS_TO_NS(val) (val >> 16)
|
|
#endif
|
|
|
|
static const char *selected_role_str(int port)
|
|
{
|
|
switch (GPTP_GLOBAL_DS()->selected_role[port]) {
|
|
case GPTP_PORT_INITIALIZING:
|
|
return "INITIALIZING";
|
|
case GPTP_PORT_FAULTY:
|
|
return "FAULTY";
|
|
case GPTP_PORT_DISABLED:
|
|
return "DISABLED";
|
|
case GPTP_PORT_LISTENING:
|
|
return "LISTENING";
|
|
case GPTP_PORT_PRE_MASTER:
|
|
return "PRE-MASTER";
|
|
case GPTP_PORT_MASTER:
|
|
return "MASTER";
|
|
case GPTP_PORT_PASSIVE:
|
|
return "PASSIVE";
|
|
case GPTP_PORT_UNCALIBRATED:
|
|
return "UNCALIBRATED";
|
|
case GPTP_PORT_SLAVE:
|
|
return "SLAVE";
|
|
}
|
|
|
|
return "<unknown>";
|
|
}
|
|
|
|
static void gptp_print_port_info(const struct shell *sh, int port)
|
|
{
|
|
struct gptp_port_bmca_data *port_bmca_data;
|
|
struct gptp_port_param_ds *port_param_ds;
|
|
struct gptp_port_states *port_state;
|
|
struct gptp_domain *domain;
|
|
struct gptp_port_ds *port_ds;
|
|
struct net_if *iface;
|
|
int ret, i;
|
|
|
|
domain = gptp_get_domain();
|
|
|
|
ret = gptp_get_port_data(domain,
|
|
port,
|
|
&port_ds,
|
|
&port_param_ds,
|
|
&port_state,
|
|
&port_bmca_data,
|
|
&iface);
|
|
if (ret < 0) {
|
|
PR_WARNING("Cannot get gPTP information for port %d (%d)\n",
|
|
port, ret);
|
|
return;
|
|
}
|
|
|
|
NET_ASSERT(port == port_ds->port_id.port_number,
|
|
"Port number mismatch! (%d vs %d)", port,
|
|
port_ds->port_id.port_number);
|
|
|
|
PR("Port id : %d (%s)\n", port_ds->port_id.port_number,
|
|
selected_role_str(port_ds->port_id.port_number));
|
|
PR("Interface : %p [%d]\n", iface, net_if_get_by_iface(iface));
|
|
PR("Clock id : ");
|
|
for (i = 0; i < sizeof(port_ds->port_id.clk_id); i++) {
|
|
PR("%02x", port_ds->port_id.clk_id[i]);
|
|
|
|
if (i != (sizeof(port_ds->port_id.clk_id) - 1)) {
|
|
PR(":");
|
|
}
|
|
}
|
|
PR("\n");
|
|
|
|
PR("Version : %d\n", port_ds->version);
|
|
PR("AS capable : %s\n", port_ds->as_capable ? "yes" : "no");
|
|
|
|
PR("\nConfiguration:\n");
|
|
PR("Time synchronization and Best Master Selection enabled "
|
|
": %s\n", port_ds->ptt_port_enabled ? "yes" : "no");
|
|
PR("The port is measuring the path delay "
|
|
": %s\n", port_ds->is_measuring_delay ? "yes" : "no");
|
|
PR("One way propagation time on %s : %u ns\n",
|
|
"the link attached to this port",
|
|
(uint32_t)port_ds->neighbor_prop_delay);
|
|
PR("Propagation time threshold for %s : %u ns\n",
|
|
"the link attached to this port",
|
|
(uint32_t)port_ds->neighbor_prop_delay_thresh);
|
|
PR("Estimate of the ratio of the frequency with the peer "
|
|
": %u\n", (uint32_t)port_ds->neighbor_rate_ratio);
|
|
PR("Asymmetry on the link relative to the grand master time base "
|
|
": %" PRId64 "\n", port_ds->delay_asymmetry);
|
|
PR("Maximum interval between sync %s "
|
|
": %" PRIu64 "\n", "messages",
|
|
port_ds->sync_receipt_timeout_time_itv);
|
|
PR("Maximum number of Path Delay Requests without a response "
|
|
": %d\n", port_ds->allowed_lost_responses);
|
|
PR("Current Sync %s : %d\n",
|
|
"sequence id for this port", port_ds->sync_seq_id);
|
|
PR("Current Path Delay Request %s : %d\n",
|
|
"sequence id for this port", port_ds->pdelay_req_seq_id);
|
|
PR("Current Announce %s : %d\n",
|
|
"sequence id for this port", port_ds->announce_seq_id);
|
|
PR("Current Signaling %s : %d\n",
|
|
"sequence id for this port", port_ds->signaling_seq_id);
|
|
PR("Whether neighborRateRatio %s : %s\n",
|
|
"needs to be computed for this port",
|
|
port_ds->compute_neighbor_rate_ratio ? "yes" : "no");
|
|
PR("Whether neighborPropDelay %s : %s\n",
|
|
"needs to be computed for this port",
|
|
port_ds->compute_neighbor_prop_delay ? "yes" : "no");
|
|
PR("Initial Announce Interval %s : %d\n",
|
|
"as a Logarithm to base 2", port_ds->ini_log_announce_itv);
|
|
PR("Current Announce Interval %s : %d\n",
|
|
"as a Logarithm to base 2", port_ds->cur_log_announce_itv);
|
|
PR("Initial Sync Interval %s : %d\n",
|
|
"as a Logarithm to base 2", port_ds->ini_log_half_sync_itv);
|
|
PR("Current Sync Interval %s : %d\n",
|
|
"as a Logarithm to base 2", port_ds->cur_log_half_sync_itv);
|
|
PR("Initial Path Delay Request Interval %s : %d\n",
|
|
"as a Logarithm to base 2", port_ds->ini_log_pdelay_req_itv);
|
|
PR("Current Path Delay Request Interval %s : %d\n",
|
|
"as a Logarithm to base 2", port_ds->cur_log_pdelay_req_itv);
|
|
PR("Time without receiving announce %s %s : %d ms (%d)\n",
|
|
"messages", "before running BMCA",
|
|
gptp_uscaled_ns_to_timer_ms(
|
|
&port_bmca_data->ann_rcpt_timeout_time_interval),
|
|
port_ds->announce_receipt_timeout);
|
|
PR("Time without receiving sync %s %s : %" PRIu64 " ms (%d)\n",
|
|
"messages", "before running BMCA",
|
|
(port_ds->sync_receipt_timeout_time_itv >> 16) /
|
|
(NSEC_PER_SEC / MSEC_PER_SEC),
|
|
port_ds->sync_receipt_timeout);
|
|
PR("Sync event %s : %" PRIu64 " ms\n",
|
|
"transmission interval for the port",
|
|
USCALED_NS_TO_NS(port_ds->half_sync_itv.low) /
|
|
(NSEC_PER_USEC * USEC_PER_MSEC));
|
|
PR("Path Delay Request %s : %" PRIu64 " ms\n",
|
|
"transmission interval for the port",
|
|
USCALED_NS_TO_NS(port_ds->pdelay_req_itv.low) /
|
|
(NSEC_PER_USEC * USEC_PER_MSEC));
|
|
PR("BMCA %s %s%d%s: %d\n", "default", "priority", 1,
|
|
" ",
|
|
domain->default_ds.priority1);
|
|
PR("BMCA %s %s%d%s: %d\n", "default", "priority", 2,
|
|
" ",
|
|
domain->default_ds.priority2);
|
|
|
|
PR("\nRuntime status:\n");
|
|
PR("Current global port state "
|
|
" : %s\n", selected_role_str(port));
|
|
PR("Path Delay Request state machine variables:\n");
|
|
PR("\tCurrent state "
|
|
": %s\n", pdelay_req2str(port_state->pdelay_req.state));
|
|
PR("\tInitial Path Delay Response Peer Timestamp "
|
|
": %" PRIu64 "\n", port_state->pdelay_req.ini_resp_evt_tstamp);
|
|
PR("\tInitial Path Delay Response Ingress Timestamp "
|
|
": %" PRIu64 "\n", port_state->pdelay_req.ini_resp_ingress_tstamp);
|
|
PR("\tPath Delay Response %s %s : %u\n",
|
|
"messages", "received",
|
|
port_state->pdelay_req.rcvd_pdelay_resp);
|
|
PR("\tPath Delay Follow Up %s %s : %u\n",
|
|
"messages", "received",
|
|
port_state->pdelay_req.rcvd_pdelay_follow_up);
|
|
PR("\tNumber of lost Path Delay Responses "
|
|
": %u\n", port_state->pdelay_req.lost_responses);
|
|
PR("\tTimer expired send a new Path Delay Request "
|
|
": %u\n", port_state->pdelay_req.pdelay_timer_expired);
|
|
PR("\tNeighborRateRatio has been computed successfully "
|
|
": %u\n", port_state->pdelay_req.neighbor_rate_ratio_valid);
|
|
PR("\tPath Delay has already been computed after init "
|
|
": %u\n", port_state->pdelay_req.init_pdelay_compute);
|
|
PR("\tCount consecutive reqs with multiple responses "
|
|
": %u\n", port_state->pdelay_req.multiple_resp_count);
|
|
|
|
PR("Path Delay Response state machine variables:\n");
|
|
PR("\tCurrent state "
|
|
": %s\n", pdelay_resp2str(port_state->pdelay_resp.state));
|
|
|
|
PR("SyncReceive state machine variables:\n");
|
|
PR("\tCurrent state "
|
|
": %s\n", sync_rcv2str(port_state->sync_rcv.state));
|
|
PR("\tA Sync %s %s : %s\n",
|
|
"Message", "has been received",
|
|
port_state->sync_rcv.rcvd_sync ? "yes" : "no");
|
|
PR("\tA Follow Up %s %s : %s\n",
|
|
"Message", "has been received",
|
|
port_state->sync_rcv.rcvd_follow_up ? "yes" : "no");
|
|
PR("\tA Follow Up %s %s : %s\n",
|
|
"Message", "timeout",
|
|
port_state->sync_rcv.follow_up_timeout_expired ? "yes" : "no");
|
|
PR("\tTime at which a Sync %s without Follow Up\n"
|
|
"\t will be discarded "
|
|
": %" PRIu64 "\n", "Message",
|
|
port_state->sync_rcv.follow_up_receipt_timeout);
|
|
|
|
PR("SyncSend state machine variables:\n");
|
|
PR("\tCurrent state "
|
|
": %s\n", sync_send2str(port_state->sync_send.state));
|
|
PR("\tA MDSyncSend structure %s : %s\n",
|
|
"has been received",
|
|
port_state->sync_send.rcvd_md_sync ? "yes" : "no");
|
|
PR("\tThe timestamp for the sync msg %s : %s\n",
|
|
"has been received",
|
|
port_state->sync_send.md_sync_timestamp_avail ? "yes" : "no");
|
|
|
|
PR("PortSyncSyncReceive state machine variables:\n");
|
|
PR("\tCurrent state "
|
|
": %s\n", pss_rcv2str(port_state->pss_rcv.state));
|
|
PR("\tGrand Master / Local Clock frequency ratio "
|
|
": %f\n", port_state->pss_rcv.rate_ratio);
|
|
PR("\tA MDSyncReceive struct is ready to be processed "
|
|
": %s\n", port_state->pss_rcv.rcvd_md_sync ? "yes" : "no");
|
|
PR("\tExpiry of SyncReceiptTimeoutTimer : %s\n",
|
|
port_state->pss_rcv.rcv_sync_receipt_timeout_timer_expired ?
|
|
"yes" : "no");
|
|
|
|
PR("PortSyncSyncSend state machine variables:\n");
|
|
PR("\tCurrent state "
|
|
": %s\n", pss_send2str(port_state->pss_send.state));
|
|
PR("\tFollow Up Correction Field of last recv PSS "
|
|
": %" PRId64 "\n",
|
|
port_state->pss_send.last_follow_up_correction_field);
|
|
PR("\tUpstream Tx Time of the last recv PortSyncSync "
|
|
": %" PRIu64 "\n", port_state->pss_send.last_upstream_tx_time);
|
|
PR("\tRate Ratio of the last received PortSyncSync "
|
|
": %f\n",
|
|
port_state->pss_send.last_rate_ratio);
|
|
PR("\tGM Freq Change of the last received PortSyncSync "
|
|
": %f\n", port_state->pss_send.last_gm_freq_change);
|
|
PR("\tGM Time Base Indicator of last recv PortSyncSync "
|
|
": %d\n", port_state->pss_send.last_gm_time_base_indicator);
|
|
PR("\tReceived Port Number of last recv PortSyncSync "
|
|
": %d\n",
|
|
port_state->pss_send.last_rcvd_port_num);
|
|
PR("\tPortSyncSync structure is ready to be processed "
|
|
": %s\n", port_state->pss_send.rcvd_pss_sync ? "yes" : "no");
|
|
PR("\tFlag when the %s has expired : %s\n",
|
|
"half_sync_itv_timer",
|
|
port_state->pss_send.half_sync_itv_timer_expired ? "yes" : "no");
|
|
PR("\tHas %s expired twice : %s\n",
|
|
"half_sync_itv_timer",
|
|
port_state->pss_send.sync_itv_timer_expired ? "yes" : "no");
|
|
PR("\tHas syncReceiptTimeoutTime expired "
|
|
": %s\n",
|
|
port_state->pss_send.send_sync_receipt_timeout_timer_expired ?
|
|
"yes" : "no");
|
|
|
|
PR("PortAnnounceReceive state machine variables:\n");
|
|
PR("\tCurrent state "
|
|
": %s\n", pa_rcv2str(port_state->pa_rcv.state));
|
|
PR("\tAn announce message is ready to be processed "
|
|
": %s\n",
|
|
port_state->pa_rcv.rcvd_announce ? "yes" : "no");
|
|
|
|
PR("PortAnnounceInformation state machine variables:\n");
|
|
PR("\tCurrent state "
|
|
": %s\n", pa_info2str(port_state->pa_info.state));
|
|
PR("\tExpired announce information "
|
|
": %s\n", port_state->pa_info.ann_expired ? "yes" : "no");
|
|
|
|
PR("PortAnnounceTransmit state machine variables:\n");
|
|
PR("\tCurrent state "
|
|
": %s\n", pa_transmit2str(port_state->pa_transmit.state));
|
|
PR("\tTrigger announce information "
|
|
": %s\n", port_state->pa_transmit.ann_trigger ? "yes" : "no");
|
|
|
|
#if defined(CONFIG_NET_GPTP_STATISTICS)
|
|
PR("\nStatistics:\n");
|
|
PR("Sync %s %s : %u\n",
|
|
"messages", "received", port_param_ds->rx_sync_count);
|
|
PR("Follow Up %s %s : %u\n",
|
|
"messages", "received", port_param_ds->rx_fup_count);
|
|
PR("Path Delay Request %s %s : %u\n",
|
|
"messages", "received", port_param_ds->rx_pdelay_req_count);
|
|
PR("Path Delay Response %s %s : %u\n",
|
|
"messages", "received", port_param_ds->rx_pdelay_resp_count);
|
|
PR("Path Delay %s threshold %s : %u\n",
|
|
"messages", "exceeded",
|
|
port_param_ds->neighbor_prop_delay_exceeded);
|
|
PR("Path Delay Follow Up %s %s : %u\n",
|
|
"messages", "received", port_param_ds->rx_pdelay_resp_fup_count);
|
|
PR("Announce %s %s : %u\n",
|
|
"messages", "received", port_param_ds->rx_announce_count);
|
|
PR("ptp %s discarded : %u\n",
|
|
"messages", port_param_ds->rx_ptp_packet_discard_count);
|
|
PR("Sync %s %s : %u\n",
|
|
"reception", "timeout",
|
|
port_param_ds->sync_receipt_timeout_count);
|
|
PR("Announce %s %s : %u\n",
|
|
"reception", "timeout",
|
|
port_param_ds->announce_receipt_timeout_count);
|
|
PR("Path Delay Requests without a response "
|
|
": %u\n",
|
|
port_param_ds->pdelay_allowed_lost_resp_exceed_count);
|
|
PR("Sync %s %s : %u\n",
|
|
"messages", "sent", port_param_ds->tx_sync_count);
|
|
PR("Follow Up %s %s : %u\n",
|
|
"messages", "sent", port_param_ds->tx_fup_count);
|
|
PR("Path Delay Request %s %s : %u\n",
|
|
"messages", "sent", port_param_ds->tx_pdelay_req_count);
|
|
PR("Path Delay Response %s %s : %u\n",
|
|
"messages", "sent", port_param_ds->tx_pdelay_resp_count);
|
|
PR("Path Delay Response FUP %s %s : %u\n",
|
|
"messages", "sent", port_param_ds->tx_pdelay_resp_fup_count);
|
|
PR("Announce %s %s : %u\n",
|
|
"messages", "sent", port_param_ds->tx_announce_count);
|
|
#endif /* CONFIG_NET_GPTP_STATISTICS */
|
|
}
|
|
#endif /* CONFIG_NET_GPTP */
|
|
|
|
static int cmd_net_gptp_port(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
#if defined(CONFIG_NET_GPTP)
|
|
int arg = 1;
|
|
char *endptr;
|
|
int port;
|
|
#endif
|
|
|
|
#if defined(CONFIG_NET_GPTP)
|
|
if (!argv[arg]) {
|
|
PR_WARNING("Port number must be given.\n");
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
port = strtol(argv[arg], &endptr, 10);
|
|
|
|
if (*endptr == '\0') {
|
|
gptp_print_port_info(sh, port);
|
|
} else {
|
|
PR_WARNING("Not a valid gPTP port number: %s\n", argv[arg]);
|
|
}
|
|
#else
|
|
ARG_UNUSED(argc);
|
|
ARG_UNUSED(argv);
|
|
|
|
PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_GPTP", "gPTP");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_net_gptp(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
#if defined(CONFIG_NET_GPTP)
|
|
/* gPTP status */
|
|
struct gptp_domain *domain = gptp_get_domain();
|
|
int count = 0;
|
|
int arg = 1;
|
|
#endif
|
|
|
|
#if defined(CONFIG_NET_GPTP)
|
|
if (argv[arg]) {
|
|
cmd_net_gptp_port(sh, argc, argv);
|
|
} else {
|
|
struct net_shell_user_data user_data;
|
|
|
|
user_data.sh = sh;
|
|
user_data.user_data = &count;
|
|
|
|
gptp_foreach_port(gptp_port_cb, &user_data);
|
|
|
|
PR("\n");
|
|
|
|
PR("SiteSyncSync state machine variables:\n");
|
|
PR("\tCurrent state : %s\n",
|
|
site_sync2str(domain->state.site_ss.state));
|
|
PR("\tA PortSyncSync struct is ready : %s\n",
|
|
domain->state.site_ss.rcvd_pss ? "yes" : "no");
|
|
|
|
PR("ClockSlaveSync state machine variables:\n");
|
|
PR("\tCurrent state : %s\n",
|
|
clk_slave2str(domain->state.clk_slave_sync.state));
|
|
PR("\tA PortSyncSync struct is ready : %s\n",
|
|
domain->state.clk_slave_sync.rcvd_pss ? "yes" : "no");
|
|
PR("\tThe local clock has expired : %s\n",
|
|
domain->state.clk_slave_sync.rcvd_local_clk_tick ?
|
|
"yes" : "no");
|
|
|
|
PR("PortRoleSelection state machine variables:\n");
|
|
PR("\tCurrent state : %s\n",
|
|
pr_selection2str(domain->state.pr_sel.state));
|
|
|
|
PR("ClockMasterSyncReceive state machine variables:\n");
|
|
PR("\tCurrent state : %s\n",
|
|
cms_rcv2str(domain->state.clk_master_sync_receive.state));
|
|
PR("\tA ClockSourceTime : %s\n",
|
|
domain->state.clk_master_sync_receive.rcvd_clock_source_req
|
|
? "yes" : "no");
|
|
PR("\tThe local clock has expired : %s\n",
|
|
domain->state.clk_master_sync_receive.rcvd_local_clock_tick
|
|
? "yes" : "no");
|
|
}
|
|
#else
|
|
ARG_UNUSED(argc);
|
|
ARG_UNUSED(argv);
|
|
|
|
PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_GPTP", "gPTP");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_gptp,
|
|
SHELL_CMD(port, NULL,
|
|
"'net gptp [<port>]' prints detailed information about "
|
|
"gPTP port.",
|
|
cmd_net_gptp_port),
|
|
SHELL_SUBCMD_SET_END
|
|
);
|
|
|
|
SHELL_SUBCMD_ADD((net), gptp, &net_cmd_gptp,
|
|
"Print information about gPTP support.",
|
|
cmd_net_gptp, 1, 1);
|