1 /*
2  * Copyright (c) 2016 Intel Corporation
3  * Copyright (c) 2023 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/logging/log.h>
9 LOG_MODULE_DECLARE(net_shell);
10 
11 #include <stdlib.h>
12 
13 #if defined(CONFIG_NET_GPTP)
14 #include <zephyr/net/gptp.h>
15 #include "ethernet/gptp/gptp_messages.h"
16 #include "ethernet/gptp/gptp_md.h"
17 #include "ethernet/gptp/gptp_state.h"
18 #include "ethernet/gptp/gptp_data_set.h"
19 #include "ethernet/gptp/gptp_private.h"
20 #endif
21 
22 #include "net_shell_private.h"
23 
24 #if defined(CONFIG_NET_GPTP)
25 static const char *selected_role_str(int port);
26 
gptp_port_cb(int port,struct net_if * iface,void * user_data)27 static void gptp_port_cb(int port, struct net_if *iface, void *user_data)
28 {
29 	struct net_shell_user_data *data = user_data;
30 	const struct shell *sh = data->sh;
31 	int *count = data->user_data;
32 
33 	if (*count == 0) {
34 		PR("Port Interface  \tRole\n");
35 	}
36 
37 	(*count)++;
38 
39 	PR("%2d   %p [%d]  \t%s\n", port, iface, net_if_get_by_iface(iface),
40 	   selected_role_str(port));
41 }
42 
pdelay_req2str(enum gptp_pdelay_req_states state)43 static const char *pdelay_req2str(enum gptp_pdelay_req_states state)
44 {
45 	switch (state) {
46 	case GPTP_PDELAY_REQ_NOT_ENABLED:
47 		return "REQ_NOT_ENABLED";
48 	case GPTP_PDELAY_REQ_INITIAL_SEND_REQ:
49 		return "INITIAL_SEND_REQ";
50 	case GPTP_PDELAY_REQ_RESET:
51 		return "REQ_RESET";
52 	case GPTP_PDELAY_REQ_SEND_REQ:
53 		return "SEND_REQ";
54 	case GPTP_PDELAY_REQ_WAIT_RESP:
55 		return "WAIT_RESP";
56 	case GPTP_PDELAY_REQ_WAIT_FOLLOW_UP:
57 		return "WAIT_FOLLOW_UP";
58 	case GPTP_PDELAY_REQ_WAIT_ITV_TIMER:
59 		return "WAIT_ITV_TIMER";
60 	}
61 
62 	return "<unknown>";
63 };
64 
pdelay_resp2str(enum gptp_pdelay_resp_states state)65 static const char *pdelay_resp2str(enum gptp_pdelay_resp_states state)
66 {
67 	switch (state) {
68 	case GPTP_PDELAY_RESP_NOT_ENABLED:
69 		return "RESP_NOT_ENABLED";
70 	case GPTP_PDELAY_RESP_INITIAL_WAIT_REQ:
71 		return "INITIAL_WAIT_REQ";
72 	case GPTP_PDELAY_RESP_WAIT_REQ:
73 		return "WAIT_REQ";
74 	case GPTP_PDELAY_RESP_WAIT_TSTAMP:
75 		return "WAIT_TSTAMP";
76 	}
77 
78 	return "<unknown>";
79 }
80 
sync_rcv2str(enum gptp_sync_rcv_states state)81 static const char *sync_rcv2str(enum gptp_sync_rcv_states state)
82 {
83 	switch (state) {
84 	case GPTP_SYNC_RCV_DISCARD:
85 		return "DISCARD";
86 	case GPTP_SYNC_RCV_WAIT_SYNC:
87 		return "WAIT_SYNC";
88 	case GPTP_SYNC_RCV_WAIT_FOLLOW_UP:
89 		return "WAIT_FOLLOW_UP";
90 	}
91 
92 	return "<unknown>";
93 }
94 
sync_send2str(enum gptp_sync_send_states state)95 static const char *sync_send2str(enum gptp_sync_send_states state)
96 {
97 	switch (state) {
98 	case GPTP_SYNC_SEND_INITIALIZING:
99 		return "INITIALIZING";
100 	case GPTP_SYNC_SEND_SEND_SYNC:
101 		return "SEND_SYNC";
102 	case GPTP_SYNC_SEND_SEND_FUP:
103 		return "SEND_FUP";
104 	}
105 
106 	return "<unknown>";
107 }
108 
pss_rcv2str(enum gptp_pss_rcv_states state)109 static const char *pss_rcv2str(enum gptp_pss_rcv_states state)
110 {
111 	switch (state) {
112 	case GPTP_PSS_RCV_DISCARD:
113 		return "DISCARD";
114 	case GPTP_PSS_RCV_RECEIVED_SYNC:
115 		return "RECEIVED_SYNC";
116 	}
117 
118 	return "<unknown>";
119 }
120 
pss_send2str(enum gptp_pss_send_states state)121 static const char *pss_send2str(enum gptp_pss_send_states state)
122 {
123 	switch (state) {
124 	case GPTP_PSS_SEND_TRANSMIT_INIT:
125 		return "TRANSMIT_INIT";
126 	case GPTP_PSS_SEND_SYNC_RECEIPT_TIMEOUT:
127 		return "SYNC_RECEIPT_TIMEOUT";
128 	case GPTP_PSS_SEND_SEND_MD_SYNC:
129 		return "SEND_MD_SYNC";
130 	case GPTP_PSS_SEND_SET_SYNC_RECEIPT_TIMEOUT:
131 		return "SET_SYNC_RECEIPT_TIMEOUT";
132 	}
133 
134 	return "<unknown>";
135 }
136 
pa_rcv2str(enum gptp_pa_rcv_states state)137 static const char *pa_rcv2str(enum gptp_pa_rcv_states state)
138 {
139 	switch (state) {
140 	case GPTP_PA_RCV_DISCARD:
141 		return "DISCARD";
142 	case GPTP_PA_RCV_RECEIVE:
143 		return "RECEIVE";
144 	}
145 
146 	return "<unknown>";
147 };
148 
pa_info2str(enum gptp_pa_info_states state)149 static const char *pa_info2str(enum gptp_pa_info_states state)
150 {
151 	switch (state) {
152 	case GPTP_PA_INFO_DISABLED:
153 		return "DISABLED";
154 	case GPTP_PA_INFO_POST_DISABLED:
155 		return "POST_DISABLED";
156 	case GPTP_PA_INFO_AGED:
157 		return "AGED";
158 	case GPTP_PA_INFO_UPDATE:
159 		return "UPDATE";
160 	case GPTP_PA_INFO_CURRENT:
161 		return "CURRENT";
162 	case GPTP_PA_INFO_RECEIVE:
163 		return "RECEIVE";
164 	case GPTP_PA_INFO_SUPERIOR_MASTER_PORT:
165 		return "SUPERIOR_MASTER_PORT";
166 	case GPTP_PA_INFO_REPEATED_MASTER_PORT:
167 		return "REPEATED_MASTER_PORT";
168 	case GPTP_PA_INFO_INFERIOR_MASTER_OR_OTHER_PORT:
169 		return "INFERIOR_MASTER_OR_OTHER_PORT";
170 	}
171 
172 	return "<unknown>";
173 };
174 
pa_transmit2str(enum gptp_pa_transmit_states state)175 static const char *pa_transmit2str(enum gptp_pa_transmit_states state)
176 {
177 	switch (state) {
178 	case GPTP_PA_TRANSMIT_INIT:
179 		return "INIT";
180 	case GPTP_PA_TRANSMIT_PERIODIC:
181 		return "PERIODIC";
182 	case GPTP_PA_TRANSMIT_IDLE:
183 		return "IDLE";
184 	case GPTP_PA_TRANSMIT_POST_IDLE:
185 		return "POST_IDLE";
186 	}
187 
188 	return "<unknown>";
189 };
190 
site_sync2str(enum gptp_site_sync_sync_states state)191 static const char *site_sync2str(enum gptp_site_sync_sync_states state)
192 {
193 	switch (state) {
194 	case GPTP_SSS_INITIALIZING:
195 		return "INITIALIZING";
196 	case GPTP_SSS_RECEIVING_SYNC:
197 		return "RECEIVING_SYNC";
198 	}
199 
200 	return "<unknown>";
201 }
202 
clk_slave2str(enum gptp_clk_slave_sync_states state)203 static const char *clk_slave2str(enum gptp_clk_slave_sync_states state)
204 {
205 	switch (state) {
206 	case GPTP_CLK_SLAVE_SYNC_INITIALIZING:
207 		return "INITIALIZING";
208 	case GPTP_CLK_SLAVE_SYNC_SEND_SYNC_IND:
209 		return "SEND_SYNC_IND";
210 	}
211 
212 	return "<unknown>";
213 };
214 
pr_selection2str(enum gptp_pr_selection_states state)215 static const char *pr_selection2str(enum gptp_pr_selection_states state)
216 {
217 	switch (state) {
218 	case GPTP_PR_SELECTION_INIT_BRIDGE:
219 		return "INIT_BRIDGE";
220 	case GPTP_PR_SELECTION_ROLE_SELECTION:
221 		return "ROLE_SELECTION";
222 	}
223 
224 	return "<unknown>";
225 };
226 
cms_rcv2str(enum gptp_cms_rcv_states state)227 static const char *cms_rcv2str(enum gptp_cms_rcv_states state)
228 {
229 	switch (state) {
230 	case GPTP_CMS_RCV_INITIALIZING:
231 		return "INITIALIZING";
232 	case GPTP_CMS_RCV_WAITING:
233 		return "WAITING";
234 	case GPTP_CMS_RCV_SOURCE_TIME:
235 		return "SOURCE_TIME";
236 	}
237 
238 	return "<unknown>";
239 };
240 
241 #if !defined(USCALED_NS_TO_NS)
242 #define USCALED_NS_TO_NS(val) (val >> 16)
243 #endif
244 
selected_role_str(int port)245 static const char *selected_role_str(int port)
246 {
247 	switch (GPTP_GLOBAL_DS()->selected_role[port]) {
248 	case GPTP_PORT_INITIALIZING:
249 		return "INITIALIZING";
250 	case GPTP_PORT_FAULTY:
251 		return "FAULTY";
252 	case GPTP_PORT_DISABLED:
253 		return "DISABLED";
254 	case GPTP_PORT_LISTENING:
255 		return "LISTENING";
256 	case GPTP_PORT_PRE_MASTER:
257 		return "PRE-MASTER";
258 	case GPTP_PORT_MASTER:
259 		return "MASTER";
260 	case GPTP_PORT_PASSIVE:
261 		return "PASSIVE";
262 	case GPTP_PORT_UNCALIBRATED:
263 		return "UNCALIBRATED";
264 	case GPTP_PORT_SLAVE:
265 		return "SLAVE";
266 	}
267 
268 	return "<unknown>";
269 }
270 
gptp_print_port_info(const struct shell * sh,int port)271 static void gptp_print_port_info(const struct shell *sh, int port)
272 {
273 	struct gptp_port_bmca_data *port_bmca_data;
274 	struct gptp_port_param_ds *port_param_ds;
275 	struct gptp_port_states *port_state;
276 	struct gptp_domain *domain;
277 	struct gptp_port_ds *port_ds;
278 	struct net_if *iface;
279 	int ret, i;
280 
281 	domain = gptp_get_domain();
282 
283 	ret = gptp_get_port_data(domain,
284 				 port,
285 				 &port_ds,
286 				 &port_param_ds,
287 				 &port_state,
288 				 &port_bmca_data,
289 				 &iface);
290 	if (ret < 0) {
291 		PR_WARNING("Cannot get gPTP information for port %d (%d)\n",
292 			   port, ret);
293 		return;
294 	}
295 
296 	NET_ASSERT(port == port_ds->port_id.port_number,
297 		   "Port number mismatch! (%d vs %d)", port,
298 		   port_ds->port_id.port_number);
299 
300 	PR("Port id    : %d (%s)\n", port_ds->port_id.port_number,
301 	   selected_role_str(port_ds->port_id.port_number));
302 	PR("Interface  : %p [%d]\n", iface, net_if_get_by_iface(iface));
303 	PR("Clock id   : ");
304 	for (i = 0; i < sizeof(port_ds->port_id.clk_id); i++) {
305 		PR("%02x", port_ds->port_id.clk_id[i]);
306 
307 		if (i != (sizeof(port_ds->port_id.clk_id) - 1)) {
308 			PR(":");
309 		}
310 	}
311 	PR("\n");
312 
313 	PR("Version    : %d\n", port_ds->version);
314 	PR("AS capable : %s\n", port_ds->as_capable ? "yes" : "no");
315 
316 	PR("\nConfiguration:\n");
317 	PR("Time synchronization and Best Master Selection enabled        "
318 	   ": %s\n", port_ds->ptt_port_enabled ? "yes" : "no");
319 	PR("The port is measuring the path delay                          "
320 	   ": %s\n", port_ds->is_measuring_delay ? "yes" : "no");
321 	PR("One way propagation time on %s    : %u ns\n",
322 	   "the link attached to this port",
323 	   (uint32_t)port_ds->neighbor_prop_delay);
324 	PR("Propagation time threshold for %s : %u ns\n",
325 	   "the link attached to this port",
326 	   (uint32_t)port_ds->neighbor_prop_delay_thresh);
327 	PR("Estimate of the ratio of the frequency with the peer          "
328 	   ": %u\n", (uint32_t)port_ds->neighbor_rate_ratio);
329 	PR("Asymmetry on the link relative to the grand master time base  "
330 	   ": %" PRId64 "\n", port_ds->delay_asymmetry);
331 	PR("Maximum interval between sync %s                        "
332 	   ": %" PRIu64 "\n", "messages",
333 	   port_ds->sync_receipt_timeout_time_itv);
334 	PR("Maximum number of Path Delay Requests without a response      "
335 	   ": %d\n", port_ds->allowed_lost_responses);
336 	PR("Current Sync %s                        : %d\n",
337 	   "sequence id for this port", port_ds->sync_seq_id);
338 	PR("Current Path Delay Request %s          : %d\n",
339 	   "sequence id for this port", port_ds->pdelay_req_seq_id);
340 	PR("Current Announce %s                    : %d\n",
341 	   "sequence id for this port", port_ds->announce_seq_id);
342 	PR("Current Signaling %s                   : %d\n",
343 	   "sequence id for this port", port_ds->signaling_seq_id);
344 	PR("Whether neighborRateRatio %s  : %s\n",
345 	   "needs to be computed for this port",
346 	   port_ds->compute_neighbor_rate_ratio ? "yes" : "no");
347 	PR("Whether neighborPropDelay %s  : %s\n",
348 	   "needs to be computed for this port",
349 	   port_ds->compute_neighbor_prop_delay ? "yes" : "no");
350 	PR("Initial Announce Interval %s            : %d\n",
351 	   "as a Logarithm to base 2", port_ds->ini_log_announce_itv);
352 	PR("Current Announce Interval %s            : %d\n",
353 	   "as a Logarithm to base 2", port_ds->cur_log_announce_itv);
354 	PR("Initial Sync Interval %s                : %d\n",
355 	   "as a Logarithm to base 2", port_ds->ini_log_half_sync_itv);
356 	PR("Current Sync Interval %s                : %d\n",
357 	   "as a Logarithm to base 2", port_ds->cur_log_half_sync_itv);
358 	PR("Initial Path Delay Request Interval %s  : %d\n",
359 	   "as a Logarithm to base 2", port_ds->ini_log_pdelay_req_itv);
360 	PR("Current Path Delay Request Interval %s  : %d\n",
361 	   "as a Logarithm to base 2", port_ds->cur_log_pdelay_req_itv);
362 	PR("Time without receiving announce %s %s  : %d ms (%d)\n",
363 	   "messages", "before running BMCA",
364 	   gptp_uscaled_ns_to_timer_ms(
365 		   &port_bmca_data->ann_rcpt_timeout_time_interval),
366 	   port_ds->announce_receipt_timeout);
367 	PR("Time without receiving sync %s %s      : %" PRIu64 " ms (%d)\n",
368 	   "messages", "before running BMCA",
369 	   (port_ds->sync_receipt_timeout_time_itv >> 16) /
370 					(NSEC_PER_SEC / MSEC_PER_SEC),
371 	   port_ds->sync_receipt_timeout);
372 	PR("Sync event %s                 : %" PRIu64 " ms\n",
373 	   "transmission interval for the port",
374 	   USCALED_NS_TO_NS(port_ds->half_sync_itv.low) /
375 					(NSEC_PER_USEC * USEC_PER_MSEC));
376 	PR("Path Delay Request %s         : %" PRIu64 " ms\n",
377 	   "transmission interval for the port",
378 	   USCALED_NS_TO_NS(port_ds->pdelay_req_itv.low) /
379 					(NSEC_PER_USEC * USEC_PER_MSEC));
380 	PR("BMCA %s %s%d%s: %d\n", "default", "priority", 1,
381 	   "                                        ",
382 	   domain->default_ds.priority1);
383 	PR("BMCA %s %s%d%s: %d\n", "default", "priority", 2,
384 	   "                                        ",
385 	   domain->default_ds.priority2);
386 
387 	PR("\nRuntime status:\n");
388 	PR("Current global port state                          "
389 	   "      : %s\n", selected_role_str(port));
390 	PR("Path Delay Request state machine variables:\n");
391 	PR("\tCurrent state                                    "
392 	   ": %s\n", pdelay_req2str(port_state->pdelay_req.state));
393 	PR("\tInitial Path Delay Response Peer Timestamp       "
394 	   ": %" PRIu64 "\n", port_state->pdelay_req.ini_resp_evt_tstamp);
395 	PR("\tInitial Path Delay Response Ingress Timestamp    "
396 	   ": %" PRIu64 "\n", port_state->pdelay_req.ini_resp_ingress_tstamp);
397 	PR("\tPath Delay Response %s %s            : %u\n",
398 	   "messages", "received",
399 	   port_state->pdelay_req.rcvd_pdelay_resp);
400 	PR("\tPath Delay Follow Up %s %s           : %u\n",
401 	   "messages", "received",
402 	   port_state->pdelay_req.rcvd_pdelay_follow_up);
403 	PR("\tNumber of lost Path Delay Responses              "
404 	   ": %u\n", port_state->pdelay_req.lost_responses);
405 	PR("\tTimer expired send a new Path Delay Request      "
406 	   ": %u\n", port_state->pdelay_req.pdelay_timer_expired);
407 	PR("\tNeighborRateRatio has been computed successfully "
408 	   ": %u\n", port_state->pdelay_req.neighbor_rate_ratio_valid);
409 	PR("\tPath Delay has already been computed after init  "
410 	   ": %u\n", port_state->pdelay_req.init_pdelay_compute);
411 	PR("\tCount consecutive reqs with multiple responses   "
412 	   ": %u\n", port_state->pdelay_req.multiple_resp_count);
413 
414 	PR("Path Delay Response state machine variables:\n");
415 	PR("\tCurrent state                                    "
416 	   ": %s\n", pdelay_resp2str(port_state->pdelay_resp.state));
417 
418 	PR("SyncReceive state machine variables:\n");
419 	PR("\tCurrent state                                    "
420 	   ": %s\n", sync_rcv2str(port_state->sync_rcv.state));
421 	PR("\tA Sync %s %s                 : %s\n",
422 	   "Message", "has been received",
423 	   port_state->sync_rcv.rcvd_sync ? "yes" : "no");
424 	PR("\tA Follow Up %s %s            : %s\n",
425 	   "Message", "has been received",
426 	   port_state->sync_rcv.rcvd_follow_up ? "yes" : "no");
427 	PR("\tA Follow Up %s %s                      : %s\n",
428 	   "Message", "timeout",
429 	   port_state->sync_rcv.follow_up_timeout_expired ? "yes" : "no");
430 	PR("\tTime at which a Sync %s without Follow Up\n"
431 	   "\t                             will be discarded   "
432 	   ": %" PRIu64 "\n", "Message",
433 	   port_state->sync_rcv.follow_up_receipt_timeout);
434 
435 	PR("SyncSend state machine variables:\n");
436 	PR("\tCurrent state                                    "
437 	   ": %s\n", sync_send2str(port_state->sync_send.state));
438 	PR("\tA MDSyncSend structure %s         : %s\n",
439 	   "has been received",
440 	   port_state->sync_send.rcvd_md_sync ? "yes" : "no");
441 	PR("\tThe timestamp for the sync msg %s : %s\n",
442 	   "has been received",
443 	   port_state->sync_send.md_sync_timestamp_avail ? "yes" : "no");
444 
445 	PR("PortSyncSyncReceive state machine variables:\n");
446 	PR("\tCurrent state                                    "
447 	   ": %s\n", pss_rcv2str(port_state->pss_rcv.state));
448 	PR("\tGrand Master / Local Clock frequency ratio       "
449 	   ": %f\n", port_state->pss_rcv.rate_ratio);
450 	PR("\tA MDSyncReceive struct is ready to be processed  "
451 	   ": %s\n", port_state->pss_rcv.rcvd_md_sync ? "yes" : "no");
452 	PR("\tExpiry of SyncReceiptTimeoutTimer                : %s\n",
453 	   port_state->pss_rcv.rcv_sync_receipt_timeout_timer_expired ?
454 	   "yes" : "no");
455 
456 	PR("PortSyncSyncSend state machine variables:\n");
457 	PR("\tCurrent state                                    "
458 	   ": %s\n", pss_send2str(port_state->pss_send.state));
459 	PR("\tFollow Up Correction Field of last recv PSS      "
460 	   ": %" PRId64 "\n",
461 	   port_state->pss_send.last_follow_up_correction_field);
462 	PR("\tUpstream Tx Time of the last recv PortSyncSync   "
463 	   ": %" PRIu64 "\n", port_state->pss_send.last_upstream_tx_time);
464 	PR("\tRate Ratio of the last received PortSyncSync     "
465 	   ": %f\n",
466 	   port_state->pss_send.last_rate_ratio);
467 	PR("\tGM Freq Change of the last received PortSyncSync "
468 	   ": %f\n", port_state->pss_send.last_gm_freq_change);
469 	PR("\tGM Time Base Indicator of last recv PortSyncSync "
470 	   ": %d\n", port_state->pss_send.last_gm_time_base_indicator);
471 	PR("\tReceived Port Number of last recv PortSyncSync   "
472 	   ": %d\n",
473 	   port_state->pss_send.last_rcvd_port_num);
474 	PR("\tPortSyncSync structure is ready to be processed  "
475 	   ": %s\n", port_state->pss_send.rcvd_pss_sync ? "yes" : "no");
476 	PR("\tFlag when the %s has expired    : %s\n",
477 	   "half_sync_itv_timer",
478 	   port_state->pss_send.half_sync_itv_timer_expired ? "yes" : "no");
479 	PR("\tHas %s expired twice            : %s\n",
480 	   "half_sync_itv_timer",
481 	   port_state->pss_send.sync_itv_timer_expired ? "yes" : "no");
482 	PR("\tHas syncReceiptTimeoutTime expired               "
483 	   ": %s\n",
484 	   port_state->pss_send.send_sync_receipt_timeout_timer_expired ?
485 	   "yes" : "no");
486 
487 	PR("PortAnnounceReceive state machine variables:\n");
488 	PR("\tCurrent state                                    "
489 	   ": %s\n", pa_rcv2str(port_state->pa_rcv.state));
490 	PR("\tAn announce message is ready to be processed     "
491 	   ": %s\n",
492 	   port_state->pa_rcv.rcvd_announce ? "yes" : "no");
493 
494 	PR("PortAnnounceInformation state machine variables:\n");
495 	PR("\tCurrent state                                    "
496 	   ": %s\n", pa_info2str(port_state->pa_info.state));
497 	PR("\tExpired announce information                     "
498 	   ": %s\n", port_state->pa_info.ann_expired ? "yes" : "no");
499 
500 	PR("PortAnnounceTransmit state machine variables:\n");
501 	PR("\tCurrent state                                    "
502 	   ": %s\n", pa_transmit2str(port_state->pa_transmit.state));
503 	PR("\tTrigger announce information                     "
504 	   ": %s\n", port_state->pa_transmit.ann_trigger ? "yes" : "no");
505 
506 #if defined(CONFIG_NET_GPTP_STATISTICS)
507 	PR("\nStatistics:\n");
508 	PR("Sync %s %s                 : %u\n",
509 	   "messages", "received", port_param_ds->rx_sync_count);
510 	PR("Follow Up %s %s            : %u\n",
511 	   "messages", "received", port_param_ds->rx_fup_count);
512 	PR("Path Delay Request %s %s   : %u\n",
513 	   "messages", "received", port_param_ds->rx_pdelay_req_count);
514 	PR("Path Delay Response %s %s  : %u\n",
515 	   "messages", "received", port_param_ds->rx_pdelay_resp_count);
516 	PR("Path Delay %s threshold %s : %u\n",
517 	   "messages", "exceeded",
518 	   port_param_ds->neighbor_prop_delay_exceeded);
519 	PR("Path Delay Follow Up %s %s : %u\n",
520 	   "messages", "received", port_param_ds->rx_pdelay_resp_fup_count);
521 	PR("Announce %s %s             : %u\n",
522 	   "messages", "received", port_param_ds->rx_announce_count);
523 	PR("ptp %s discarded                 : %u\n",
524 	   "messages", port_param_ds->rx_ptp_packet_discard_count);
525 	PR("Sync %s %s                 : %u\n",
526 	   "reception", "timeout",
527 	   port_param_ds->sync_receipt_timeout_count);
528 	PR("Announce %s %s             : %u\n",
529 	   "reception", "timeout",
530 	   port_param_ds->announce_receipt_timeout_count);
531 	PR("Path Delay Requests without a response "
532 	   ": %u\n",
533 	   port_param_ds->pdelay_allowed_lost_resp_exceed_count);
534 	PR("Sync %s %s                     : %u\n",
535 	   "messages", "sent", port_param_ds->tx_sync_count);
536 	PR("Follow Up %s %s                : %u\n",
537 	   "messages", "sent", port_param_ds->tx_fup_count);
538 	PR("Path Delay Request %s %s       : %u\n",
539 	   "messages", "sent", port_param_ds->tx_pdelay_req_count);
540 	PR("Path Delay Response %s %s      : %u\n",
541 	   "messages", "sent", port_param_ds->tx_pdelay_resp_count);
542 	PR("Path Delay Response FUP %s %s  : %u\n",
543 	   "messages", "sent", port_param_ds->tx_pdelay_resp_fup_count);
544 	PR("Announce %s %s                 : %u\n",
545 	   "messages", "sent", port_param_ds->tx_announce_count);
546 #endif /* CONFIG_NET_GPTP_STATISTICS */
547 }
548 #endif /* CONFIG_NET_GPTP */
549 
cmd_net_gptp_port(const struct shell * sh,size_t argc,char * argv[])550 static int cmd_net_gptp_port(const struct shell *sh, size_t argc, char *argv[])
551 {
552 #if defined(CONFIG_NET_GPTP)
553 	int arg = 1;
554 	char *endptr;
555 	int port;
556 #endif
557 
558 #if defined(CONFIG_NET_GPTP)
559 	if (!argv[arg]) {
560 		PR_WARNING("Port number must be given.\n");
561 		return -ENOEXEC;
562 	}
563 
564 	port = strtol(argv[arg], &endptr, 10);
565 
566 	if (*endptr == '\0') {
567 		gptp_print_port_info(sh, port);
568 	} else {
569 		PR_WARNING("Not a valid gPTP port number: %s\n", argv[arg]);
570 	}
571 #else
572 	ARG_UNUSED(argc);
573 	ARG_UNUSED(argv);
574 
575 	PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_GPTP", "gPTP");
576 #endif
577 
578 	return 0;
579 }
580 
cmd_net_gptp(const struct shell * sh,size_t argc,char * argv[])581 static int cmd_net_gptp(const struct shell *sh, size_t argc, char *argv[])
582 {
583 #if defined(CONFIG_NET_GPTP)
584 	/* gPTP status */
585 	struct gptp_domain *domain = gptp_get_domain();
586 	int count = 0;
587 	int arg = 1;
588 #endif
589 
590 #if defined(CONFIG_NET_GPTP)
591 	if (argv[arg]) {
592 		cmd_net_gptp_port(sh, argc, argv);
593 	} else {
594 		struct net_shell_user_data user_data;
595 
596 		user_data.sh = sh;
597 		user_data.user_data = &count;
598 
599 		gptp_foreach_port(gptp_port_cb, &user_data);
600 
601 		PR("\n");
602 
603 		PR("SiteSyncSync state machine variables:\n");
604 		PR("\tCurrent state                  : %s\n",
605 		   site_sync2str(domain->state.site_ss.state));
606 		PR("\tA PortSyncSync struct is ready : %s\n",
607 		   domain->state.site_ss.rcvd_pss ? "yes" : "no");
608 
609 		PR("ClockSlaveSync state machine variables:\n");
610 		PR("\tCurrent state                  : %s\n",
611 		   clk_slave2str(domain->state.clk_slave_sync.state));
612 		PR("\tA PortSyncSync struct is ready : %s\n",
613 		   domain->state.clk_slave_sync.rcvd_pss ? "yes" : "no");
614 		PR("\tThe local clock has expired    : %s\n",
615 		   domain->state.clk_slave_sync.rcvd_local_clk_tick ?
616 							   "yes" : "no");
617 
618 		PR("PortRoleSelection state machine variables:\n");
619 		PR("\tCurrent state                  : %s\n",
620 		   pr_selection2str(domain->state.pr_sel.state));
621 
622 		PR("ClockMasterSyncReceive state machine variables:\n");
623 		PR("\tCurrent state                  : %s\n",
624 		   cms_rcv2str(domain->state.clk_master_sync_receive.state));
625 		PR("\tA ClockSourceTime              : %s\n",
626 		   domain->state.clk_master_sync_receive.rcvd_clock_source_req
627 							       ? "yes" : "no");
628 		PR("\tThe local clock has expired    : %s\n",
629 		   domain->state.clk_master_sync_receive.rcvd_local_clock_tick
630 							       ? "yes" : "no");
631 	}
632 #else
633 	ARG_UNUSED(argc);
634 	ARG_UNUSED(argv);
635 
636 	PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_GPTP", "gPTP");
637 #endif
638 
639 	return 0;
640 }
641 
642 SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_gptp,
643 	SHELL_CMD(port, NULL,
644 		  "'net gptp [<port>]' prints detailed information about "
645 		  "gPTP port.",
646 		  cmd_net_gptp_port),
647 	SHELL_SUBCMD_SET_END
648 );
649 
650 SHELL_SUBCMD_ADD((net), gptp, &net_cmd_gptp,
651 		 "Print information about gPTP support.",
652 		 cmd_net_gptp, 1, 1);
653