1 /*
2 * Copyright (c) 2017 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief gPTP message helpers.
10 *
11 * This is not to be included by the application.
12 */
13
14 #ifndef __GPTP_MESSAGES_H
15 #define __GPTP_MESSAGES_H
16
17 #include <zephyr/net/net_pkt.h>
18 #include <zephyr/net/ethernet.h>
19 #include <zephyr/net/gptp.h>
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 /* Helpers to access gPTP messages. */
26 #define GPTP_HDR(pkt) gptp_get_hdr(pkt)
27 #define GPTP_ANNOUNCE(pkt) ((struct gptp_announce *)gptp_data(pkt))
28 #define GPTP_SIGNALING(pkt) ((struct gptp_signaling *)gptp_data(pkt))
29 #define GPTP_SYNC(pkt) ((struct gptp_sync *)gptp_data(pkt))
30 #define GPTP_FOLLOW_UP(pkt) ((struct gptp_follow_up *)gptp_data(pkt))
31 #define GPTP_DELAY_REQ(pkt) \
32 ((struct gptp_delay_req *)gptp_data(pkt))
33 #define GPTP_PDELAY_REQ(pkt) \
34 ((struct gptp_pdelay_req *)gptp_data(pkt))
35 #define GPTP_PDELAY_RESP(pkt) \
36 ((struct gptp_pdelay_resp *)gptp_data(pkt))
37 #define GPTP_PDELAY_RESP_FOLLOWUP(pkt) \
38 ((struct gptp_pdelay_resp_follow_up *)gptp_data(pkt))
39
40 /* Field values. */
41 #define GPTP_TRANSPORT_802_1_AS 0x1
42 #define GPTP_VERSION 0x2
43
44 /* Message Lengths. */
45 #define GPTP_PACKET_LEN(pkt) net_pkt_get_len(pkt)
46 #define GPTP_VALID_LEN(pkt, len) \
47 (len > (NET_ETH_MINIMAL_FRAME_SIZE - GPTP_L2_HDR_LEN(pkt)))
48 #define GPTP_L2_HDR_LEN(pkt) \
49 ((long)GPTP_HDR(pkt) - (long)NET_ETH_HDR(pkt))
50
51 #define GPTP_SYNC_LEN \
52 (sizeof(struct gptp_hdr) + sizeof(struct gptp_sync))
53 #define GPTP_FOLLOW_UP_LEN \
54 (sizeof(struct gptp_hdr) + sizeof(struct gptp_follow_up))
55 #define GPTP_PDELAY_REQ_LEN \
56 (sizeof(struct gptp_hdr) + sizeof(struct gptp_pdelay_req))
57 #define GPTP_PDELAY_RESP_LEN \
58 (sizeof(struct gptp_hdr) + sizeof(struct gptp_pdelay_resp))
59 #define GPTP_PDELAY_RESP_FUP_LEN \
60 (sizeof(struct gptp_hdr) + sizeof(struct gptp_pdelay_resp_follow_up))
61 #define GPTP_SIGNALING_LEN \
62 (sizeof(struct gptp_hdr) + sizeof(struct gptp_signaling))
63
64 /* For the Announce message, the TLV is variable length. The len field
65 * indicates the length of the TLV not accounting for tlvType and lengthField
66 * which are 4 bytes.
67 */
68 #define GPTP_ANNOUNCE_LEN(pkt) \
69 (sizeof(struct gptp_hdr) + sizeof(struct gptp_announce) \
70 + ntohs(GPTP_ANNOUNCE(pkt)->tlv.len) \
71 - sizeof(struct gptp_path_trace_tlv) + 4)
72
73 #define GPTP_CHECK_LEN(pkt, len) \
74 ((GPTP_PACKET_LEN(pkt) != len) && (GPTP_VALID_LEN(pkt, len)))
75 #define GPTP_ANNOUNCE_CHECK_LEN(pkt) \
76 ((GPTP_PACKET_LEN(pkt) != GPTP_ANNOUNCE_LEN(pkt)) && \
77 (GPTP_VALID_LEN(pkt, GPTP_ANNOUNCE_LEN(pkt))))
78
79 /* Header Flags. Byte 0. */
80 #define GPTP_FLAG_ALT_MASTER BIT(0)
81 #define GPTP_FLAG_TWO_STEP BIT(1)
82 #define GPTP_FLAG_UNICAST BIT(2)
83 #define GPTP_FLAG_PROFILE_SPECIFIC1 BIT(5)
84 #define GPTP_FLAG_PROFILE_SPECIFIC2 BIT(6)
85
86 /* Header Flags. Byte 1. */
87 #define GPTP_FLAG_LEAP61 BIT(0)
88 #define GPTP_FLAG_LEAP59 BIT(1)
89 #define GPTP_FLAG_CUR_UTC_OFF_VALID BIT(2)
90 #define GPTP_FLAG_PTP_TIMESCALE BIT(3)
91 #define GPTP_FLAG_TIME_TRACEABLE BIT(4)
92 #define GPTP_FLAG_FREQ_TRACEABLE BIT(5)
93
94 /* Signaling Interval Flags. */
95 #define GPTP_FLAG_COMPUTE_NEIGHBOR_RATE_RATIO 0x1
96 #define GPTP_FLAG_COMPUTE_NEIGHBOR_PROP_DELAY 0x2
97
98 /* Signaling Interval Values. */
99 #define GPTP_ITV_KEEP -128
100 #define GPTP_ITV_SET_TO_INIT 126
101 #define GPTP_ITV_STOP 127
102
103 /* Control. Only set for header compatibility with v1. */
104 #define GPTP_SYNC_CONTROL_VALUE 0x0
105 #define GPTP_FUP_CONTROL_VALUE 0x2
106 #define GPTP_OTHER_CONTROL_VALUE 0x5
107
108 /* Other default values. */
109 #define GPTP_RESP_LOG_MSG_ITV 0x7F
110 #define GPTP_ANNOUNCE_MSG_PATH_SEQ_TYPE htons(0x8)
111
112 /* Organization Id used for TLV. */
113 #define GPTP_FUP_TLV_ORG_ID_BYTE_0 0x00
114 #define GPTP_FUP_TLV_ORG_ID_BYTE_1 0x80
115 #define GPTP_FUP_TLV_ORG_ID_BYTE_2 0xC2
116 #define GPTP_FUP_TLV_ORG_SUB_TYPE 0x01
117
118 /**
119 * @brief gPTP Clock Quality
120 *
121 * Defines the quality of a clock.
122 * This is used by the Best Master Clock Algorithm.
123 */
124 struct gptp_clock_quality {
125 uint8_t clock_class;
126 uint8_t clock_accuracy;
127 uint16_t offset_scaled_log_var;
128 } __packed;
129
130 /**
131 * @brief gPTP Root System Identity
132 *
133 * Defines the Grand Master of a clock.
134 * This is used by the Best Master Clock Algorithm.
135 */
136 struct gptp_root_system_identity {
137 /** Grand Master priority1 component. */
138 uint8_t grand_master_prio1;
139
140 /** Grand Master clock quality. */
141 struct gptp_clock_quality clk_quality;
142
143 /** Grand Master priority2 component. */
144 uint8_t grand_master_prio2;
145
146 /** Grand Master clock identity. */
147 uint8_t grand_master_id[GPTP_CLOCK_ID_LEN];
148 } __packed;
149
150 /* Definition of all message types as defined by IEEE802.1AS. */
151
152 struct gptp_path_trace_tlv {
153 /** TLV type: 0x8. */
154 uint16_t type;
155
156 /** Length. Number of TLVs * 8 bytes. */
157 uint16_t len;
158
159 /** ClockIdentity array of the successive time-aware systems. */
160 uint8_t path_sequence[1][8];
161 } __packed;
162
163 struct gptp_announce {
164 /** Reserved fields. */
165 uint8_t reserved1[10];
166
167 /** Current UTC offset. */
168 int16_t cur_utc_offset;
169
170 /** Reserved field. */
171 uint8_t reserved2;
172
173 /* gmPriorityVector priority 1 of the peer sending the message. */
174 struct gptp_root_system_identity root_system_id;
175
176 /** masterStepsRemoved of the peer sending the message. */
177 uint16_t steps_removed;
178
179 /** timeSource of the peer sending the message. */
180 uint8_t time_source;
181
182 /* Path Trace TLV. This field has a variable length. */
183 struct gptp_path_trace_tlv tlv;
184 } __packed;
185
186 struct gptp_sync {
187 /** Reserved field. This field is used for PTPv2, unused in gPTP. */
188 uint8_t reserved[10];
189 } __packed;
190
191 struct gptp_follow_up_tlv_hdr {
192 /** TLV type: 0x3. */
193 uint16_t type;
194
195 /** Length: 28. */
196 uint16_t len;
197 } __packed;
198
199 struct gptp_follow_up_tlv {
200 /** Organization Id: 00-80-C2. */
201 uint8_t org_id[3];
202
203 /** Organization Sub Type: 1. */
204 uint8_t org_sub_type[3];
205
206 /** Rate ratio relative to the grand master of the peer. */
207 int32_t cumulative_scaled_rate_offset;
208
209 /** Time Base Indicator of the current Grand Master. */
210 uint16_t gm_time_base_indicator;
211
212 /** Difference of the time between the current GM and the previous. */
213 struct gptp_scaled_ns last_gm_phase_change;
214
215 /** Diff of the frequency between the current GM and the previous. */
216 int32_t scaled_last_gm_freq_change;
217 } __packed;
218
219 struct gptp_follow_up {
220 /** Higher 16 bits of the seconds at which the sync was sent. */
221 uint16_t prec_orig_ts_secs_high;
222
223 /** Lower 32 bits of the seconds at which the sync was sent. */
224 uint32_t prec_orig_ts_secs_low;
225
226 /** Nanoseconds at which the sync was sent. */
227 uint32_t prec_orig_ts_nsecs;
228
229 /** Follow up TLV. */
230 struct gptp_follow_up_tlv_hdr tlv_hdr;
231 struct gptp_follow_up_tlv tlv;
232 } __packed;
233
234 struct gptp_pdelay_req {
235 /** Reserved fields. */
236 uint8_t reserved1[10];
237
238 /** Reserved fields. */
239 uint8_t reserved2[10];
240 } __packed;
241
242 struct gptp_pdelay_resp {
243 /** Higher 16 bits of the seconds at which the request was received. */
244 uint16_t req_receipt_ts_secs_high;
245
246 /** Lower 32 bits of the seconds at which the request was received. */
247 uint32_t req_receipt_ts_secs_low;
248
249 /** Nanoseconds at which the pdelay request was received. */
250 uint32_t req_receipt_ts_nsecs;
251
252 /** Source Port Id of the Path Delay Request. */
253 struct gptp_port_identity requesting_port_id;
254 } __packed;
255
256 struct gptp_pdelay_resp_follow_up {
257 /** Higher 16 bits of the seconds at which the response was sent. */
258 uint16_t resp_orig_ts_secs_high;
259
260 /** Lower 32 bits of the seconds at which the response was sent. */
261 uint32_t resp_orig_ts_secs_low;
262
263 /** Nanoseconds at which the response was received. */
264 uint32_t resp_orig_ts_nsecs;
265
266 /** Source Port Id of the Path Delay Request. */
267 struct gptp_port_identity requesting_port_id;
268 } __packed;
269
270 struct gptp_message_itv_req_tlv {
271 /** TLV type: 0x3. */
272 uint16_t type;
273
274 /** Length field: 12. */
275 uint16_t len;
276
277 /** Organization Id: 00-80-C2. */
278 uint8_t org_id[3];
279
280 /** Organization sub type: 0x2. */
281 uint8_t org_sub_type[3];
282
283 /** Log to base 2 of the mean time interval between pdelay requests. */
284 int8_t link_delay_itv;
285
286 /** Log to base 2 of the mean time interval between syncs. */
287 int8_t time_sync_itv;
288
289 /** Log to base 2 of the mean time interval between announces. */
290 int8_t announce_itv;
291
292 /** Flags (computeNeighborRateRatio and computeNeighborPropDelay). */
293 union {
294 struct {
295 uint8_t compute_neighbor_rate_ratio : 1;
296 uint8_t compute_neighbor_prop_delay : 1;
297 };
298 uint8_t flags;
299 };
300 /** Reserved fields. */
301 uint8_t reserved[2];
302 } __packed;
303
304 struct gptp_signaling {
305 /** Target Port Identity , always 0xFF. */
306 struct gptp_port_identity target_port_id;
307
308 /** Message Interval TLV. */
309 struct gptp_message_itv_req_tlv tlv;
310 } __packed;
311
312 /**
313 * @brief Compute gPTP message location.
314 *
315 * @param pkt Network Buffer containing a gPTP message.
316 *
317 * @return Pointer to the start of the gPTP message inside the packet.
318 */
gptp_data(struct net_pkt * pkt)319 static inline uint8_t *gptp_data(struct net_pkt *pkt)
320 {
321 return (uint8_t *)GPTP_HDR(pkt) + sizeof(struct gptp_hdr);
322 }
323
324 /* Functions to prepare messages. */
325
326 /**
327 * @brief Prepare Sync message.
328 *
329 * @param port gPTP port number.
330 *
331 * @return Pointer to the prepared Network Buffer.
332 */
333 struct net_pkt *gptp_prepare_sync(int port);
334
335 /**
336 * @brief Prepare Follow Up message.
337 *
338 * @param port gPTP port number.
339 *
340 * @return Pointer to the prepared Network Buffer.
341 */
342 struct net_pkt *gptp_prepare_follow_up(int port, struct net_pkt *sync);
343
344 /**
345 * @brief Prepare Path Delay Request message.
346 *
347 * @param port gPTP port number.
348 *
349 * @return Pointer to the prepared Network Buffer.
350 */
351 struct net_pkt *gptp_prepare_pdelay_req(int port);
352
353 /**
354 * @brief Prepare Path Delay Response message.
355 *
356 * @param port gPTP port number.
357 * @param req Path Delay Request to reply to.
358 *
359 * @return Pointer to the prepared Network Buffer.
360 */
361 struct net_pkt *gptp_prepare_pdelay_resp(int port,
362 struct net_pkt *req);
363
364 /**
365 * @brief Prepare Announce message.
366 *
367 * @param port gPTP port number.
368 *
369 * @return Pointer to the prepared Network Buffer.
370 */
371 struct net_pkt *gptp_prepare_announce(int port);
372
373 /**
374 * @brief Prepare Path Delay Response message.
375 *
376 * @param port gPTP port number.
377 * @param resp Related Path Delay Follow Up.
378 *
379 * @return Pointer to the prepared Network Buffer.
380 */
381 struct net_pkt *gptp_prepare_pdelay_follow_up(int port,
382 struct net_pkt *resp);
383
384 /* Functions to handle received messages. */
385
386 /**
387 * @brief Handle Sync message.
388 *
389 * @param port gPTP port number.
390 * @param pkt Network Buffer.
391 */
392 void gptp_handle_sync(int port, struct net_pkt *pkt);
393
394 /**
395 * @brief Handle Follow Up message.
396 *
397 * @param port gPTP port number.
398 * @param pkt Network Buffer to parse.
399 *
400 * @return 0 if success, Error Code otherwise.
401 */
402 int gptp_handle_follow_up(int port, struct net_pkt *pkt);
403
404 /**
405 * @brief Handle Path Delay Request message.
406 *
407 * @param port gPTP port number.
408 * @param pkt Network Buffer.
409 */
410 void gptp_handle_pdelay_req(int port, struct net_pkt *pkt);
411
412 /**
413 * @brief Handle Path Delay Response message.
414 *
415 * @param port gPTP port number.
416 * @param pkt Network Buffer to parse.
417 *
418 * @return 0 if success, Error Code otherwise.
419 */
420 int gptp_handle_pdelay_resp(int port, struct net_pkt *pkt);
421
422 /**
423 * @brief Handle Path Delay Follow Up message.
424 *
425 * @param port gPTP port number.
426 * @param pkt Network Buffer to parse.
427 *
428 * @return 0 if success, Error Code otherwise.
429 */
430 int gptp_handle_pdelay_follow_up(int port, struct net_pkt *pkt);
431
432 /**
433 * @brief Handle Signaling message.
434 *
435 * @param port gPTP port number.
436 * @param pkt Network Buffer
437 */
438 void gptp_handle_signaling(int port, struct net_pkt *pkt);
439
440 /* Functions to send messages. */
441
442 /**
443 * @brief Send a Sync message.
444 *
445 * @param port gPTP port number.
446 * @param pkt Sync message.
447 */
448 void gptp_send_sync(int port, struct net_pkt *pkt);
449
450 /**
451 * @brief Send a Follow Up message.
452 *
453 * @param port gPTP port number.
454 * @param pkt Follow Up message.
455 */
456 void gptp_send_follow_up(int port, struct net_pkt *pkt);
457
458 /**
459 * @brief Send an Announce message.
460 *
461 * @param port gPTP port number.
462 * @param pkt Announce message.
463 */
464 void gptp_send_announce(int port, struct net_pkt *pkt);
465
466 /**
467 * @brief Send a Path Delay Request on the given port.
468 *
469 * @param port gPTP port number.
470 */
471 void gptp_send_pdelay_req(int port);
472
473 /**
474 * @brief Send a Path Delay Response for the given Path Delay Request.
475 *
476 * @param port gPTP port number.
477 * @param pkt Network Buffer containing the prepared Path Delay Response.
478 * @param treq Time at which the Path Delay Request was received.
479 */
480 void gptp_send_pdelay_resp(int port, struct net_pkt *pkt,
481 struct net_ptp_time *treq);
482
483 /**
484 * @brief Send a Path Delay Response for the given Path Delay Request.
485 *
486 * @param port gPTP port number.
487 * @param pkt Network Buffer containing the prepared Path Delay Follow Up.
488 * @param tresp Time at which the Path Delay Response was sent.
489 */
490 void gptp_send_pdelay_follow_up(int port, struct net_pkt *pkt,
491 struct net_ptp_time *tresp);
492
493 #ifdef __cplusplus
494 }
495 #endif
496
497 #endif /* __GPTP_MESSAGES_H */
498