1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_DECLARE(net_gptp, CONFIG_NET_GPTP_LOG_LEVEL);
9
10 #include <zephyr/drivers/ptp_clock.h>
11 #include <zephyr/net/gptp.h>
12
13 #include "gptp_messages.h"
14 #include "gptp_data_set.h"
15
16 #include "net_private.h"
17
18 static sys_slist_t phase_dis_callbacks;
19
gptp_register_phase_dis_cb(struct gptp_phase_dis_cb * phase_dis,gptp_phase_dis_callback_t cb)20 void gptp_register_phase_dis_cb(struct gptp_phase_dis_cb *phase_dis,
21 gptp_phase_dis_callback_t cb)
22 {
23 sys_slist_find_and_remove(&phase_dis_callbacks, &phase_dis->node);
24 sys_slist_prepend(&phase_dis_callbacks, &phase_dis->node);
25
26 phase_dis->cb = cb;
27 }
28
gptp_unregister_phase_dis_cb(struct gptp_phase_dis_cb * phase_dis)29 void gptp_unregister_phase_dis_cb(struct gptp_phase_dis_cb *phase_dis)
30 {
31 sys_slist_find_and_remove(&phase_dis_callbacks, &phase_dis->node);
32 }
33
gptp_call_phase_dis_cb(void)34 void gptp_call_phase_dis_cb(void)
35 {
36 struct gptp_global_ds *global_ds;
37 sys_snode_t *sn, *sns;
38 uint8_t *gm_id;
39
40 global_ds = GPTP_GLOBAL_DS();
41 gm_id = &global_ds->gm_priority.root_system_id.grand_master_id[0];
42
43 SYS_SLIST_FOR_EACH_NODE_SAFE(&phase_dis_callbacks, sn, sns) {
44 struct gptp_phase_dis_cb *phase_dis =
45 CONTAINER_OF(sn, struct gptp_phase_dis_cb, node);
46
47 phase_dis->cb(gm_id,
48 &global_ds->gm_time_base_indicator,
49 &global_ds->clk_src_last_gm_phase_change,
50 &global_ds->clk_src_last_gm_freq_change);
51 }
52 }
53
gptp_event_capture(struct net_ptp_time * slave_time,bool * gm_present)54 int gptp_event_capture(struct net_ptp_time *slave_time, bool *gm_present)
55 {
56 int port, key;
57 const struct device *clk;
58
59 key = irq_lock();
60 *gm_present = GPTP_GLOBAL_DS()->gm_present;
61
62 for (port = GPTP_PORT_START; port <= GPTP_PORT_END; port++) {
63 /* Get first available clock, or slave clock if GM present. */
64 if (!*gm_present || (GPTP_GLOBAL_DS()->selected_role[port] ==
65 GPTP_PORT_SLAVE)) {
66 clk = net_eth_get_ptp_clock(GPTP_PORT_IFACE(port));
67 if (clk) {
68 ptp_clock_get(clk, slave_time);
69 irq_unlock(key);
70 return 0;
71 }
72 }
73 }
74
75 irq_unlock(key);
76 return -EAGAIN;
77 }
78
gptp_sprint_clock_id(const uint8_t * clk_id,char * output,size_t output_len)79 char *gptp_sprint_clock_id(const uint8_t *clk_id, char *output, size_t output_len)
80 {
81 return net_sprint_ll_addr_buf(clk_id, 8, output, output_len);
82 }
83
gptp_clk_src_time_invoke(struct gptp_clk_src_time_invoke_params * arg)84 void gptp_clk_src_time_invoke(struct gptp_clk_src_time_invoke_params *arg)
85 {
86 struct gptp_clk_master_sync_rcv_state *state;
87
88 state = &GPTP_STATE()->clk_master_sync_receive;
89
90 memcpy(&state->rcvd_clk_src_req, arg,
91 sizeof(struct gptp_clk_src_time_invoke_params));
92
93 state->rcvd_clock_source_req = true;
94 }
95