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