blob: 79498a2cdee8979e34c8a16c754b38359c841c46 [file] [log] [blame]
Jukka Rissanen45b06a22018-01-24 14:33:35 +02001/*
2 * Copyright (c) 2017 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7/**
8 * @file
9 * @brief Public functions for the Precision Time Protocol Stack.
10 *
11 */
12
Flavio Ceolin67ca1762018-09-14 10:43:44 -070013#ifndef ZEPHYR_INCLUDE_NET_GPTP_H_
14#define ZEPHYR_INCLUDE_NET_GPTP_H_
Jukka Rissanen45b06a22018-01-24 14:33:35 +020015
16/**
17 * @brief generic Precision Time Protocol (gPTP) support
18 * @defgroup gptp gPTP support
19 * @ingroup networking
20 * @{
21 */
22
23#include <net/net_core.h>
24#include <net/ptp_time.h>
Flavio Ceolin6fdc56d2018-09-18 12:32:27 -070025#include <stdbool.h>
Jukka Rissanen45b06a22018-01-24 14:33:35 +020026
27#ifdef __cplusplus
28extern "C" {
29#endif
30
Jukka Rissanen45b06a22018-01-24 14:33:35 +020031#define GPTP_OFFSET_SCALED_LOG_VAR_UNKNOWN 0x436A
32
33#define GPTP_PRIORITY1_NON_GM_CAPABLE 255
Tomasz Gorochowik68127a32018-08-29 15:29:46 +020034#define GPTP_PRIORITY1_GM_CAPABLE 248
Jukka Rissanen45b06a22018-01-24 14:33:35 +020035#define GPTP_PRIORITY2_DEFAULT 248
36
37/**
38 * @brief Scaled Nanoseconds.
39 */
40struct gptp_scaled_ns {
41 /** High half. */
42 s32_t high;
43
44 /** Low half. */
45 s64_t low;
46} __packed;
47
48/**
49 * @brief UScaled Nanoseconds.
50 */
51struct gptp_uscaled_ns {
52 /** High half. */
53 u32_t high;
54
55 /** Low half. */
56 u64_t low;
57} __packed;
58
59#if defined(CONFIG_NEWLIB_LIBC)
60#include <math.h>
61
62#define GPTP_POW2(exp) pow(2, exp)
63#else
64
65static inline double _gptp_pow2(int exp)
66{
67 double res;
68
69 if (exp >= 0) {
70 res = 1 << exp;
71 } else {
72 res = 1.0;
73
74 while (exp++) {
75 res /= 2;
76 }
77 }
78
79 return res;
80}
81
82#define GPTP_POW2(exp) _gptp_pow2(exp)
83#endif
84
85/* Message types. Event messages have BIT(3) set to 0, and general messages
86 * have that bit set to 1. IEEE 802.1AS chapter 10.5.2.2.2
87 */
88#define GPTP_SYNC_MESSAGE 0x00
89#define GPTP_DELAY_REQ_MESSAGE 0x01
90#define GPTP_PATH_DELAY_REQ_MESSAGE 0x02
91#define GPTP_PATH_DELAY_RESP_MESSAGE 0x03
92#define GPTP_FOLLOWUP_MESSAGE 0x08
93#define GPTP_DELAY_RESP_MESSAGE 0x09
94#define GPTP_PATH_DELAY_FOLLOWUP_MESSAGE 0x0a
95#define GPTP_ANNOUNCE_MESSAGE 0x0b
96#define GPTP_SIGNALING_MESSAGE 0x0c
97#define GPTP_MANAGEMENT_MESSAGE 0x0d
98
99#define GPTP_IS_EVENT_MSG(msg_type) (!((msg_type) & BIT(3)))
100
101#define GPTP_CLOCK_ID_LEN 8
102
103/**
104 * @brief Port Identity.
105 */
106struct gptp_port_identity {
107 /** Clock identity of the port. */
108 u8_t clk_id[GPTP_CLOCK_ID_LEN];
109
110 /** Number of the port. */
111 u16_t port_number;
112} __packed;
113
114struct gptp_flags {
115 union {
116 /** Byte access. */
117 u8_t octets[2];
118
119 /** Whole field access. */
120 u16_t all;
121 };
122} __packed;
123
124struct gptp_hdr {
125 /** Type of the message. */
126 u8_t message_type:4;
127
128 /** Transport specific, always 1. */
129 u8_t transport_specific:4;
130
131 /** Version of the PTP, always 2. */
132 u8_t ptp_version:4;
133
134 /** Reserved field. */
135 u8_t reserved0:4;
136
137 /** Total length of the message from the header to the last TLV. */
138 u16_t message_length;
139
140 /** Domain number, always 0. */
141 u8_t domain_number;
142
143 /** Reserved field. */
144 u8_t reserved1;
145
146 /** Message flags. */
147 struct gptp_flags flags;
148
149 /** Correction Field. The content depends of the message type. */
150 s64_t correction_field;
151
152 /** Reserved field. */
153 u32_t reserved2;
154
155 /** Port Identity of the sender. */
156 struct gptp_port_identity port_id;
157
158 /** Sequence Id. */
159 u16_t sequence_id;
160
161 /** Control value. Sync: 0, Follow-up: 2, Others: 5. */
162 u8_t control;
163
164 /** Message Interval in Log2 for Sync and Announce messages. */
165 s8_t log_msg_interval;
166} __packed;
167
Jukka Rissanencf272e62018-04-20 13:58:10 +0300168#define GPTP_GET_CURRENT_TIME_USCALED_NS(port, uscaled_ns_ptr) \
Jukka Rissanen45b06a22018-01-24 14:33:35 +0200169 do { \
170 (uscaled_ns_ptr)->low = \
Jukka Rissanencf272e62018-04-20 13:58:10 +0300171 gptp_get_current_time_nanosecond(port) << 16; \
Jukka Rissanen45b06a22018-01-24 14:33:35 +0200172 (uscaled_ns_ptr)->high = 0; \
Flavio Ceolin6fdc56d2018-09-18 12:32:27 -0700173 } while (false)
Jukka Rissanen45b06a22018-01-24 14:33:35 +0200174
175/**
176 * @typedef gptp_phase_dis_callback_t
177 * @brief Define callback that is called after a phase discontinuity has been
178 * sent by the grandmaster.
179 * @param "u8_t *gm_identity" A pointer to first element of a
180 * ClockIdentity array. The size of the array is GPTP_CLOCK_ID_LEN.
181 * @param "u16_t *gm_time_base" A pointer to the value of timeBaseIndicator
182 * of the current grandmaster.
183 * @param "struct scaled_ns *last_gm_ph_change" A pointer to the value of
184 * lastGmPhaseChange received from grandmaster.
185 * @param "double *last_gm_freq_change" A pointer to the value of
186 * lastGmFreqChange received from the grandmaster.
187 */
188typedef void (*gptp_phase_dis_callback_t)(
189 u8_t *gm_identity,
190 u16_t *time_base,
191 struct gptp_scaled_ns *last_gm_ph_change,
192 double *last_gm_freq_change);
193
194/**
195 * @brief Phase discontinuity callback structure.
196 *
197 * Stores the phase discontinuity callback information. Caller must make sure
198 * that the variable pointed by this is valid during the lifetime of
199 * registration. Typically this means that the variable cannot be
200 * allocated from stack.
201 */
202struct gptp_phase_dis_cb {
203 /** Node information for the slist. */
204 sys_snode_t node;
205
206 /** Phase discontinuity callback. */
207 gptp_phase_dis_callback_t cb;
208};
209
210/**
Tomasz Gorochowik68127a32018-08-29 15:29:46 +0200211 * @brief ClockSourceTime.invoke function parameters
212 *
213 * Parameters passed by ClockSourceTime.invoke function.
214 */
215struct gptp_clk_src_time_invoke_params {
216 /** Frequency change on the last Time Base Indicator Change. */
217 double last_gm_freq_change;
218
219 /** The time this function is invoked. */
220 struct net_ptp_extended_time src_time;
221
222 /** Phase change on the last Time Base Indicator Change. */
223 struct gptp_scaled_ns last_gm_phase_change;
224
225 /** Time Base - changed only if Phase or Frequency changes. */
226 u16_t time_base_indicator;
227};
228
229/**
Jukka Rissanen45b06a22018-01-24 14:33:35 +0200230 * @brief Register a phase discontinuity callback.
231 *
232 * @param phase_dis Caller specified handler for the callback.
233 * @param cb Callback to register.
234 */
235void gptp_register_phase_dis_cb(struct gptp_phase_dis_cb *phase_dis,
236 gptp_phase_dis_callback_t cb);
237
238/**
239 * @brief Unregister a phase discontinuity callback.
240 *
241 * @param phase_dis Caller specified handler for the callback.
242 */
243void gptp_unregister_phase_dis_cb(struct gptp_phase_dis_cb *phase_dis);
244
245/**
246 * @brief Call a phase discontinuity callback function.
247 */
248void gptp_call_phase_dis_cb(void);
249
250/**
251 * @brief Get gPTP time.
252 *
253 * @param slave_time A pointer to structure where timestamp will be saved.
254 * @param gm_present A pointer to a boolean where status of the
255 * presence of a grand master will be saved.
256 *
257 * @return Error code. 0 if no error.
258 */
259int gptp_event_capture(struct net_ptp_time *slave_time, bool *gm_present);
260
261/**
262 * @brief Utility function to print clock id to a user supplied buffer.
263 *
264 * @param clk_id Clock id
265 * @param output Output buffer
266 * @param output_len Output buffer len
267 *
268 * @return Pointer to output buffer
269 */
270char *gptp_sprint_clock_id(const u8_t *clk_id, char *output,
271 size_t output_len);
272
273/**
274 * @typedef gptp_port_cb_t
275 * @brief Callback used while iterating over gPTP ports
276 *
277 * @param port Port number
278 * @param iface Pointer to network interface
279 * @param user_data A valid pointer to user data or NULL
280 */
281typedef void (*gptp_port_cb_t)(int port, struct net_if *iface,
282 void *user_data);
283
284/**
285 * @brief Go through all the gPTP ports and call callback for each of them.
286 *
287 * @param cb User-supplied callback function to call
288 * @param user_data User specified data
289 */
290void gptp_foreach_port(gptp_port_cb_t cb, void *user_data);
291
292/**
293 * @brief Get gPTP domain.
294 * @details This contains all the configuration / status of the gPTP domain.
295 *
296 * @return Pointer to domain or NULL if not found.
297 */
298struct gptp_domain *gptp_get_domain(void);
299
Tomasz Gorochowik68127a32018-08-29 15:29:46 +0200300/**
301 * @brief This interface is used by the ClockSource entity to provide time to
302 * the ClockMaster entity of a time-aware system.
303 *
304 * @param arg Current state and parameters of the ClockSource entity.
305 */
306void gptp_clk_src_time_invoke(struct gptp_clk_src_time_invoke_params *arg);
307
Jukka Rissanen45b06a22018-01-24 14:33:35 +0200308#ifdef __cplusplus
309}
310#endif
311
312/**
313 * @}
314 */
315
Flavio Ceolin67ca1762018-09-14 10:43:44 -0700316#endif /* ZEPHYR_INCLUDE_NET_GPTP_H_ */