1 /*
2  * Copyright (c) 2024 BayLibre SAS
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(ptp_clock, CONFIG_PTP_LOG_LEVEL);
9 
10 #include <stdbool.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include <zephyr/zvfs/eventfd.h>
15 
16 #include <zephyr/kernel.h>
17 #include <zephyr/drivers/ptp_clock.h>
18 #include <zephyr/net/ethernet.h>
19 #include <zephyr/net/net_if.h>
20 #include <zephyr/net/socket.h>
21 #include <zephyr/sys/slist.h>
22 
23 #include "btca.h"
24 #include "clock.h"
25 #include "ddt.h"
26 #include "msg.h"
27 #include "port.h"
28 #include "tlv.h"
29 #include "transport.h"
30 
31 #define MIN_NSEC_TO_TIMEINTERVAL (0xFFFF800000000000ULL)
32 #define MAX_NSEC_TO_TIMEINTERVAL (0x00007FFFFFFFFFFFULL)
33 
34 /**
35  * @brief PTP Clock structure.
36  */
37 struct ptp_clock {
38 	const struct device	    *phc;
39 	struct ptp_default_ds	    default_ds;
40 	struct ptp_current_ds	    current_ds;
41 	struct ptp_parent_ds	    parent_ds;
42 	struct ptp_time_prop_ds	    time_prop_ds;
43 	struct ptp_dataset	    dataset;
44 	struct ptp_foreign_tt_clock *best;
45 	sys_slist_t		    ports_list;
46 	struct zsock_pollfd	    pollfd[1 + 2 * CONFIG_PTP_NUM_PORTS];
47 	bool			    pollfd_valid;
48 	bool			    state_decision_event;
49 	uint8_t			    time_src;
50 	struct {
51 		uint64_t	    t1;
52 		uint64_t	    t2;
53 		uint64_t	    t3;
54 		uint64_t	    t4;
55 	} timestamp;			/* latest timestamps in nanoseconds */
56 	double pi_drift;
57 };
58 
59 __maybe_unused static struct ptp_clock ptp_clk = { 0 };
60 char str_clock_id[] = "FF:FF:FF:FF:FF:FF:FF:FF";
61 
clock_generate_id(ptp_clk_id * clock_id,struct net_if * iface)62 static int clock_generate_id(ptp_clk_id *clock_id, struct net_if *iface)
63 {
64 	struct net_linkaddr *addr = net_if_get_link_addr(iface);
65 
66 	if (addr) {
67 		clock_id->id[0] = addr->addr[0];
68 		clock_id->id[1] = addr->addr[1];
69 		clock_id->id[2] = addr->addr[2];
70 		clock_id->id[3] = 0xFF;
71 		clock_id->id[4] = 0xFE;
72 		clock_id->id[5] = addr->addr[3];
73 		clock_id->id[6] = addr->addr[4];
74 		clock_id->id[7] = addr->addr[5];
75 		return 0;
76 	}
77 	return -1;
78 }
79 
clock_id_str(ptp_clk_id * clock_id)80 static const char *clock_id_str(ptp_clk_id *clock_id)
81 {
82 	uint8_t *cid = clock_id->id;
83 
84 	snprintk(str_clock_id, sizeof(str_clock_id), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
85 		 cid[0],
86 		 cid[1],
87 		 cid[2],
88 		 cid[3],
89 		 cid[4],
90 		 cid[5],
91 		 cid[6],
92 		 cid[7]);
93 
94 	return str_clock_id;
95 }
96 
clock_ns_to_timeinterval(int64_t val)97 static ptp_timeinterval clock_ns_to_timeinterval(int64_t val)
98 {
99 	if (val < (int64_t)MIN_NSEC_TO_TIMEINTERVAL) {
100 		val = MIN_NSEC_TO_TIMEINTERVAL;
101 	} else if (val > (int64_t)MAX_NSEC_TO_TIMEINTERVAL) {
102 		val = MAX_NSEC_TO_TIMEINTERVAL;
103 	}
104 
105 	return (uint64_t)val << 16;
106 }
107 
clock_forward_msg(struct ptp_port * ingress,struct ptp_port * port,struct ptp_msg * msg,bool * network_byte_order)108 static int clock_forward_msg(struct ptp_port *ingress,
109 			     struct ptp_port *port,
110 			     struct ptp_msg *msg,
111 			     bool *network_byte_order)
112 {
113 	if (ingress == port) {
114 		return 0;
115 	}
116 
117 	if (*network_byte_order == false) {
118 		ptp_msg_pre_send(msg);
119 		*network_byte_order = true;
120 	}
121 
122 	return ptp_transport_send(port, msg, PTP_SOCKET_GENERAL);
123 }
124 
clock_forward_management_msg(struct ptp_port * port,struct ptp_msg * msg)125 static void clock_forward_management_msg(struct ptp_port *port, struct ptp_msg *msg)
126 {
127 	int length;
128 	struct ptp_port *iter;
129 	bool net_byte_ord = false;
130 	enum ptp_port_state state = ptp_port_state(port);
131 
132 	if (ptp_clock_type() != PTP_CLOCK_TYPE_BOUNDARY) {
133 		/* Clocks other than Boundary Clock shouldn't retransmit messages. */
134 		return;
135 	}
136 
137 	if (msg->header.flags[0] & PTP_MSG_UNICAST_FLAG) {
138 		return;
139 	}
140 
141 	if (msg->management.boundary_hops &&
142 	    (state == PTP_PS_GRAND_MASTER ||
143 	     state == PTP_PS_TIME_TRANSMITTER ||
144 	     state == PTP_PS_PRE_TIME_TRANSMITTER ||
145 	     state == PTP_PS_TIME_RECEIVER ||
146 	     state == PTP_PS_UNCALIBRATED)) {
147 		length = msg->header.msg_length;
148 		msg->management.boundary_hops--;
149 
150 		SYS_SLIST_FOR_EACH_CONTAINER(&ptp_clk.ports_list, iter, node) {
151 			if (clock_forward_msg(port, iter, msg, &net_byte_ord)) {
152 				LOG_ERR("Failed to forward message to %d Port",
153 					iter->port_ds.id.port_number);
154 			}
155 		}
156 
157 		if (net_byte_ord) {
158 			ptp_msg_post_recv(port, msg, length);
159 			msg->management.boundary_hops++;
160 		}
161 	}
162 }
163 
clock_management_set(struct ptp_port * port,struct ptp_msg * req,struct ptp_tlv_mgmt * tlv)164 static int clock_management_set(struct ptp_port *port,
165 				struct ptp_msg *req,
166 				struct ptp_tlv_mgmt *tlv)
167 {
168 	bool send_resp = false;
169 
170 	switch (tlv->id) {
171 	case PTP_MGMT_PRIORITY1:
172 		ptp_clk.default_ds.priority1 = *tlv->data;
173 		send_resp = true;
174 		break;
175 	case PTP_MGMT_PRIORITY2:
176 		ptp_clk.default_ds.priority2 = *tlv->data;
177 		send_resp = true;
178 		break;
179 	default:
180 		break;
181 	}
182 
183 	return send_resp ? ptp_port_management_resp(port, req, tlv) : 0;
184 }
185 
clock_update_grandmaster(void)186 static void clock_update_grandmaster(void)
187 {
188 	memset(&ptp_clk.current_ds, 0, sizeof(struct ptp_current_ds));
189 
190 	memcpy(&ptp_clk.parent_ds.port_id.clk_id,
191 	       &ptp_clk.default_ds.clk_id,
192 	       sizeof(ptp_clk_id));
193 	memcpy(&ptp_clk.parent_ds.gm_id,
194 	       &ptp_clk.default_ds.clk_id,
195 	       sizeof(ptp_clk_id));
196 	ptp_clk.parent_ds.port_id.port_number = 0;
197 	ptp_clk.parent_ds.gm_clk_quality = ptp_clk.default_ds.clk_quality;
198 	ptp_clk.parent_ds.gm_priority1 = ptp_clk.default_ds.priority1;
199 	ptp_clk.parent_ds.gm_priority2 = ptp_clk.default_ds.priority2;
200 
201 	ptp_clk.time_prop_ds.current_utc_offset = 37; /* IEEE 1588-2019 9.4 */
202 	ptp_clk.time_prop_ds.time_src = ptp_clk.time_src;
203 	ptp_clk.time_prop_ds.flags = 0;
204 }
205 
clock_update_time_receiver(void)206 static void clock_update_time_receiver(void)
207 {
208 	struct ptp_msg *best_msg = (struct ptp_msg *)k_fifo_peek_tail(&ptp_clk.best->messages);
209 
210 	ptp_clk.current_ds.steps_rm = 1 + ptp_clk.best->dataset.steps_rm;
211 
212 	memcpy(&ptp_clk.parent_ds.gm_id,
213 	       &best_msg->announce.gm_id,
214 	       sizeof(best_msg->announce.gm_id));
215 	memcpy(&ptp_clk.parent_ds.port_id,
216 	       &ptp_clk.best->dataset.sender,
217 	       sizeof(ptp_clk.best->dataset.sender));
218 	ptp_clk.parent_ds.gm_clk_quality = best_msg->announce.gm_clk_quality;
219 	ptp_clk.parent_ds.gm_priority1 = best_msg->announce.gm_priority1;
220 	ptp_clk.parent_ds.gm_priority2 = best_msg->announce.gm_priority2;
221 
222 	ptp_clk.time_prop_ds.current_utc_offset = best_msg->announce.current_utc_offset;
223 	ptp_clk.time_prop_ds.flags = best_msg->header.flags[1];
224 }
225 
clock_check_pollfd(void)226 static void clock_check_pollfd(void)
227 {
228 	struct ptp_port *port;
229 	struct zsock_pollfd *fd = &ptp_clk.pollfd[1];
230 
231 	if (ptp_clk.pollfd_valid) {
232 		return;
233 	}
234 
235 	SYS_SLIST_FOR_EACH_CONTAINER(&ptp_clk.ports_list, port, node) {
236 		for (int i = 0; i < PTP_SOCKET_CNT; i++) {
237 			fd->fd = port->socket[i];
238 			fd->events = ZSOCK_POLLIN | ZSOCK_POLLPRI;
239 			fd++;
240 		}
241 	}
242 
243 	ptp_clk.pollfd_valid = true;
244 }
245 
ptp_clock_init(void)246 const struct ptp_clock *ptp_clock_init(void)
247 {
248 	struct ptp_default_ds *dds = &ptp_clk.default_ds;
249 	struct ptp_parent_ds *pds  = &ptp_clk.parent_ds;
250 	struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET));
251 
252 	ptp_clk.time_src = (enum ptp_time_src)PTP_TIME_SRC_INTERNAL_OSC;
253 
254 	/* Initialize Default Dataset. */
255 	int ret = clock_generate_id(&dds->clk_id, iface);
256 
257 	if (ret) {
258 		LOG_ERR("Couldn't assign Clock Identity.");
259 		return NULL;
260 	}
261 
262 	dds->type = (enum ptp_clock_type)CONFIG_PTP_CLOCK_TYPE;
263 	dds->n_ports = 0;
264 	dds->time_receiver_only = IS_ENABLED(CONFIG_PTP_TIME_RECEIVER_ONLY) ? true : false;
265 
266 	dds->clk_quality.cls = dds->time_receiver_only ? 255 : 248;
267 	dds->clk_quality.accuracy = CONFIG_PTP_CLOCK_ACCURACY;
268 	/* 0xFFFF means that value has not been computed - IEEE 1588-2019 7.6.3.3 */
269 	dds->clk_quality.offset_scaled_log_variance = 0xFFFF;
270 
271 	dds->max_steps_rm = 255;
272 
273 	dds->priority1 = CONFIG_PTP_PRIORITY1;
274 	dds->priority2 = CONFIG_PTP_PRIORITY2;
275 
276 	/* Initialize Parent Dataset. */
277 	clock_update_grandmaster();
278 	pds->obsreved_parent_offset_scaled_log_variance = 0xFFFF;
279 	pds->obsreved_parent_clk_phase_change_rate = 0x7FFFFFFF;
280 	/* Parent statistics haven't been measured - IEEE 1588-2019 7.6.4.2 */
281 	pds->stats = false;
282 
283 	ptp_clk.phc = net_eth_get_ptp_clock(iface);
284 	if (!ptp_clk.phc) {
285 		LOG_ERR("Couldn't get PTP HW Clock for the interface.");
286 		return NULL;
287 	}
288 
289 	ptp_clk.pollfd[0].fd = zvfs_eventfd(0, ZVFS_EFD_NONBLOCK);
290 	ptp_clk.pollfd[0].events = ZSOCK_POLLIN;
291 
292 	sys_slist_init(&ptp_clk.ports_list);
293 	LOG_DBG("PTP Clock %s initialized", clock_id_str(&dds->clk_id));
294 	return &ptp_clk;
295 }
296 
ptp_clock_poll_sockets(void)297 struct zsock_pollfd *ptp_clock_poll_sockets(void)
298 {
299 	int ret;
300 
301 	clock_check_pollfd();
302 	ret = zsock_poll(ptp_clk.pollfd, PTP_SOCKET_CNT * ptp_clk.default_ds.n_ports + 1, -1);
303 	if (ret > 0 && ptp_clk.pollfd[0].revents) {
304 		zvfs_eventfd_t value;
305 
306 		zvfs_eventfd_read(ptp_clk.pollfd[0].fd, &value);
307 	}
308 
309 	return &ptp_clk.pollfd[1];
310 }
311 
ptp_clock_handle_state_decision_evt(void)312 void ptp_clock_handle_state_decision_evt(void)
313 {
314 	struct ptp_foreign_tt_clock *best = NULL, *foreign;
315 	struct ptp_port *port;
316 	bool tt_changed = false;
317 
318 	if (!ptp_clk.state_decision_event) {
319 		return;
320 	}
321 
322 	SYS_SLIST_FOR_EACH_CONTAINER(&ptp_clk.ports_list, port, node) {
323 		foreign = ptp_port_best_foreign(port);
324 		if (!foreign) {
325 			continue;
326 		}
327 		if (!best || ptp_btca_ds_cmp(&foreign->dataset, &best->dataset)) {
328 			best = foreign;
329 		}
330 	}
331 
332 	ptp_clk.best = best;
333 
334 	SYS_SLIST_FOR_EACH_CONTAINER(&ptp_clk.ports_list, port, node) {
335 		enum ptp_port_state state;
336 		enum ptp_port_event event;
337 
338 		state = ptp_btca_state_decision(port);
339 
340 		switch (state) {
341 		case PTP_PS_LISTENING:
342 			event = PTP_EVT_NONE;
343 			break;
344 		case PTP_PS_GRAND_MASTER:
345 			clock_update_grandmaster();
346 			event = PTP_EVT_RS_GRAND_MASTER;
347 			break;
348 		case PTP_PS_TIME_TRANSMITTER:
349 			event = PTP_EVT_RS_TIME_TRANSMITTER;
350 			break;
351 		case PTP_PS_TIME_RECEIVER:
352 			clock_update_time_receiver();
353 			event = PTP_EVT_RS_TIME_RECEIVER;
354 			break;
355 		case PTP_PS_PASSIVE:
356 			event = PTP_EVT_RS_PASSIVE;
357 			break;
358 		default:
359 			event = PTP_EVT_FAULT_DETECTED;
360 			break;
361 		}
362 
363 		ptp_port_event_handle(port, event, tt_changed);
364 	}
365 
366 	ptp_clk.state_decision_event = false;
367 }
368 
ptp_clock_management_msg_process(struct ptp_port * port,struct ptp_msg * msg)369 int ptp_clock_management_msg_process(struct ptp_port *port, struct ptp_msg *msg)
370 {
371 	static const ptp_clk_id all_ones = {
372 		.id = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
373 	};
374 	int ret;
375 	bool state_decision_required = false;
376 	enum ptp_mgmt_op action = ptp_mgmt_action(msg);
377 	struct ptp_port_id *target_port = &msg->management.target_port_id;
378 	const struct ptp_default_ds *dds = ptp_clock_default_ds();
379 	struct ptp_tlv_mgmt *mgmt = (struct ptp_tlv_mgmt *)msg->management.suffix;
380 	struct ptp_port *iter;
381 
382 	if (!ptp_clock_id_eq(&dds->clk_id, &target_port->clk_id) &&
383 	    !ptp_clock_id_eq(&target_port->clk_id, &all_ones)) {
384 		return state_decision_required;
385 	}
386 
387 	if (sys_slist_len(&msg->tlvs) != 1) {
388 		/* IEEE 1588-2019 15.3.2 - PTP mgmt msg transports single mgmt TLV */
389 		return state_decision_required;
390 	}
391 
392 	clock_forward_management_msg(port, msg);
393 
394 	switch (action) {
395 	case PTP_MGMT_SET:
396 		ret = clock_management_set(port, msg, mgmt);
397 		if (ret < 0) {
398 			return state_decision_required;
399 		}
400 		state_decision_required = ret ? true : false;
401 		break;
402 	case PTP_MGMT_GET:
403 		__fallthrough;
404 	case PTP_MGMT_CMD:
405 		break;
406 	default:
407 		return state_decision_required;
408 	}
409 
410 	switch (mgmt->id) {
411 	case PTP_MGMT_CLOCK_DESCRIPTION:
412 		__fallthrough;
413 	case PTP_MGMT_USER_DESCRIPTION:
414 		__fallthrough;
415 	case PTP_MGMT_SAVE_IN_NON_VOLATILE_STORAGE:
416 		__fallthrough;
417 	case PTP_MGMT_RESET_NON_VOLATILE_STORAGE:
418 		__fallthrough;
419 	case PTP_MGMT_INITIALIZE:
420 		__fallthrough;
421 	case PTP_MGMT_FAULT_LOG:
422 		__fallthrough;
423 	case PTP_MGMT_FAULT_LOG_RESET:
424 		__fallthrough;
425 	case PTP_MGMT_DOMAIN:
426 		__fallthrough;
427 	case PTP_MGMT_TIME_RECEIVER_ONLY:
428 		__fallthrough;
429 	case PTP_MGMT_ANNOUNCE_RECEIPT_TIMEOUT:
430 		__fallthrough;
431 	case PTP_MGMT_VERSION_NUMBER:
432 		__fallthrough;
433 	case PTP_MGMT_ENABLE_PORT:
434 		__fallthrough;
435 	case PTP_MGMT_DISABLE_PORT:
436 		__fallthrough;
437 	case PTP_MGMT_TIME:
438 		__fallthrough;
439 	case PTP_MGMT_CLOCK_ACCURACY:
440 		__fallthrough;
441 	case PTP_MGMT_UTC_PROPERTIES:
442 		__fallthrough;
443 	case PTP_MGMT_TRACEBILITY_PROPERTIES:
444 		__fallthrough;
445 	case PTP_MGMT_TIMESCALE_PROPERTIES:
446 		__fallthrough;
447 	case PTP_MGMT_UNICAST_NEGOTIATION_ENABLE:
448 		__fallthrough;
449 	case PTP_MGMT_PATH_TRACE_LIST:
450 		__fallthrough;
451 	case PTP_MGMT_PATH_TRACE_ENABLE:
452 		__fallthrough;
453 	case PTP_MGMT_GRANDMASTER_CLUSTER_TABLE:
454 		__fallthrough;
455 	case PTP_MGMT_UNICAST_TIME_TRANSMITTER_TABLE:
456 		__fallthrough;
457 	case PTP_MGMT_UNICAST_TIME_TRANSMITTER_MAX_TABLE_SIZE:
458 		__fallthrough;
459 	case PTP_MGMT_ACCEPTABLE_TIME_TRANSMITTER_TABLE:
460 		__fallthrough;
461 	case PTP_MGMT_ACCEPTABLE_TIME_TRANSMITTER_TABLE_ENABLED:
462 		__fallthrough;
463 	case PTP_MGMT_ACCEPTABLE_TIME_TRANSMITTER_MAX_TABLE_SIZE:
464 		__fallthrough;
465 	case PTP_MGMT_ALTERNATE_TIME_TRANSMITTER:
466 		__fallthrough;
467 	case PTP_MGMT_ALTERNATE_TIME_OFFSET_ENABLE:
468 		__fallthrough;
469 	case PTP_MGMT_ALTERNATE_TIME_OFFSET_NAME:
470 		__fallthrough;
471 	case PTP_MGMT_ALTERNATE_TIME_OFFSET_MAX_KEY:
472 		__fallthrough;
473 	case PTP_MGMT_ALTERNATE_TIME_OFFSET_PROPERTIES:
474 		__fallthrough;
475 	case PTP_MGMT_EXTERNAL_PORT_CONFIGURATION_ENABLED:
476 		__fallthrough;
477 	case PTP_MGMT_TIME_TRANSMITTER_ONLY:
478 		__fallthrough;
479 	case PTP_MGMT_HOLDOVER_UPGRADE_ENABLE:
480 		__fallthrough;
481 	case PTP_MGMT_EXT_PORT_CONFIG_PORT_DATA_SET:
482 		__fallthrough;
483 	case PTP_MGMT_TRANSPARENT_CLOCK_DEFAULT_DATA_SET:
484 		__fallthrough;
485 	case PTP_MGMT_TRANSPARENT_CLOCK_PORT_DATA_SET:
486 		__fallthrough;
487 	case PTP_MGMT_PRIMARY_DOMAIN:
488 		__fallthrough;
489 	case PTP_MGMT_DELAY_MECHANISM:
490 		__fallthrough;
491 	case PTP_MGMT_LOG_MIN_PDELAY_REQ_INTERVAL:
492 		ptp_port_management_error(port, msg, PTP_MGMT_ERR_NOT_SUPPORTED);
493 		break;
494 	default:
495 		if (target_port->port_number == port->port_ds.id.port_number) {
496 			ptp_port_management_msg_process(port, port, msg, mgmt);
497 		} else if (target_port->port_number == UINT16_MAX) {
498 			SYS_SLIST_FOR_EACH_CONTAINER(&ptp_clk.ports_list, iter, node) {
499 				if (ptp_port_management_msg_process(iter, port, msg, mgmt)) {
500 					break;
501 				}
502 			}
503 		}
504 		break;
505 	}
506 
507 	return state_decision_required;
508 }
509 
ptp_servo_pi(int64_t nanosecond_diff)510 static double ptp_servo_pi(int64_t nanosecond_diff)
511 {
512 	double kp = 0.7;
513 	double ki = 0.3;
514 	double ppb;
515 
516 	ptp_clk.pi_drift += ki * nanosecond_diff;
517 	ppb = kp * nanosecond_diff + ptp_clk.pi_drift;
518 
519 	return ppb;
520 }
521 
ptp_clock_synchronize(uint64_t ingress,uint64_t egress)522 void ptp_clock_synchronize(uint64_t ingress, uint64_t egress)
523 {
524 	double ppb;
525 	int64_t offset;
526 	int64_t delay = ptp_clk.current_ds.mean_delay >> 16;
527 
528 	ptp_clk.timestamp.t1 = egress;
529 	ptp_clk.timestamp.t2 = ingress;
530 
531 	if (!ptp_clk.current_ds.mean_delay) {
532 		return;
533 	}
534 
535 	offset = (int64_t)(ptp_clk.timestamp.t2 - ptp_clk.timestamp.t1) - delay;
536 
537 	/* If diff is too big, ptp_clk needs to be set first. */
538 	if ((offset > (int64_t)NSEC_PER_SEC) || (offset < -(int64_t)NSEC_PER_SEC)) {
539 		struct net_ptp_time current;
540 		int32_t dest_nsec;
541 
542 		LOG_WRN("Clock offset exceeds 1 second.");
543 
544 		ptp_clock_get(ptp_clk.phc, &current);
545 
546 		current.second = (uint64_t)(current.second - (offset / NSEC_PER_SEC));
547 		dest_nsec = (int32_t)(current.nanosecond - (offset % NSEC_PER_SEC));
548 
549 		if (dest_nsec < 0) {
550 			current.second--;
551 			dest_nsec += NSEC_PER_SEC;
552 		} else if (dest_nsec >= NSEC_PER_SEC) {
553 			current.second++;
554 			dest_nsec -= NSEC_PER_SEC;
555 		}
556 
557 		current.nanosecond = (uint32_t)dest_nsec;
558 
559 		ptp_clock_set(ptp_clk.phc, &current);
560 		LOG_WRN("Set clock time: %"PRIu64".%09u", current.second, current.nanosecond);
561 		return;
562 	}
563 
564 	LOG_DBG("Offset %lldns", offset);
565 	ptp_clk.current_ds.offset_from_tt = clock_ns_to_timeinterval(offset);
566 
567 	ppb = ptp_servo_pi(-offset);
568 	ptp_clock_rate_adjust(ptp_clk.phc, 1.0 + (ppb / 1000000000.0));
569 }
570 
ptp_clock_delay(uint64_t egress,uint64_t ingress)571 void ptp_clock_delay(uint64_t egress, uint64_t ingress)
572 {
573 	int64_t delay;
574 
575 	if (ptp_clk.timestamp.t1 == 0 || ptp_clk.timestamp.t2 == 0) {
576 		return;
577 	}
578 
579 	ptp_clk.timestamp.t3 = egress;
580 	ptp_clk.timestamp.t4 = ingress;
581 
582 	delay = ((int64_t)(ptp_clk.timestamp.t2 - ptp_clk.timestamp.t3) +
583 		 (int64_t)(ptp_clk.timestamp.t4 - ptp_clk.timestamp.t1)) /
584 		2LL;
585 
586 	LOG_DBG("Delay %lldns", delay);
587 	ptp_clk.current_ds.mean_delay = clock_ns_to_timeinterval(delay);
588 }
589 
ptp_clock_ports_list(void)590 sys_slist_t *ptp_clock_ports_list(void)
591 {
592 	return &ptp_clk.ports_list;
593 }
594 
ptp_clock_type(void)595 enum ptp_clock_type ptp_clock_type(void)
596 {
597 	return (enum ptp_clock_type)ptp_clk.default_ds.type;
598 }
599 
ptp_clock_default_ds(void)600 const struct ptp_default_ds *ptp_clock_default_ds(void)
601 {
602 	return &ptp_clk.default_ds;
603 }
604 
ptp_clock_parent_ds(void)605 const struct ptp_parent_ds *ptp_clock_parent_ds(void)
606 {
607 	return &ptp_clk.parent_ds;
608 }
609 
ptp_clock_current_ds(void)610 const struct ptp_current_ds *ptp_clock_current_ds(void)
611 {
612 	return &ptp_clk.current_ds;
613 }
614 
ptp_clock_time_prop_ds(void)615 const struct ptp_time_prop_ds *ptp_clock_time_prop_ds(void)
616 {
617 	return &ptp_clk.time_prop_ds;
618 }
619 
ptp_clock_ds(void)620 const struct ptp_dataset *ptp_clock_ds(void)
621 {
622 	struct ptp_dataset *ds = &ptp_clk.dataset;
623 
624 	ds->priority1		 = ptp_clk.default_ds.priority1;
625 	ds->clk_quality		 = ptp_clk.default_ds.clk_quality;
626 	ds->priority2		 = ptp_clk.default_ds.priority2;
627 	ds->steps_rm		 = 0;
628 	ds->sender.port_number	 = 0;
629 	ds->receiver.port_number = 0;
630 	memcpy(&ds->clk_id, &ptp_clk.default_ds.clk_id, sizeof(ptp_clk_id));
631 	memcpy(&ds->sender.clk_id, &ptp_clk.default_ds.clk_id, sizeof(ptp_clk_id));
632 	memcpy(&ds->receiver.clk_id, &ptp_clk.default_ds.clk_id, sizeof(ptp_clk_id));
633 	return ds;
634 }
635 
ptp_clock_best_foreign_ds(void)636 const struct ptp_dataset *ptp_clock_best_foreign_ds(void)
637 {
638 	return ptp_clk.best ? &ptp_clk.best->dataset : NULL;
639 }
640 
ptp_clock_port_from_iface(struct net_if * iface)641 struct ptp_port *ptp_clock_port_from_iface(struct net_if *iface)
642 {
643 	struct ptp_port *port;
644 
645 	SYS_SLIST_FOR_EACH_CONTAINER(&ptp_clk.ports_list, port, node) {
646 		if (port->iface == iface) {
647 			return port;
648 		}
649 	}
650 
651 	return NULL;
652 }
653 
ptp_clock_pollfd_invalidate(void)654 void ptp_clock_pollfd_invalidate(void)
655 {
656 	ptp_clk.pollfd_valid = false;
657 }
658 
ptp_clock_signal_timeout(void)659 void ptp_clock_signal_timeout(void)
660 {
661 	zvfs_eventfd_write(ptp_clk.pollfd[0].fd, 1);
662 }
663 
ptp_clock_state_decision_req(void)664 void ptp_clock_state_decision_req(void)
665 {
666 	ptp_clk.state_decision_event = true;
667 }
668 
ptp_clock_port_add(struct ptp_port * port)669 void ptp_clock_port_add(struct ptp_port *port)
670 {
671 	ptp_clk.default_ds.n_ports++;
672 	sys_slist_append(&ptp_clk.ports_list, &port->node);
673 }
674 
ptp_clock_best_time_transmitter(void)675 const struct ptp_foreign_tt_clock *ptp_clock_best_time_transmitter(void)
676 {
677 	return ptp_clk.best;
678 }
679 
ptp_clock_id_eq(const ptp_clk_id * c1,const ptp_clk_id * c2)680 bool ptp_clock_id_eq(const ptp_clk_id *c1, const ptp_clk_id *c2)
681 {
682 	return memcmp(c1, c2, sizeof(ptp_clk_id)) == 0;
683 }
684