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