1 /*
2  * Copyright (c) 2017 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /** @file
8  * @brief PTP state machines
9  *
10  * This is not to be included by the application.
11  */
12 
13 #ifndef __GPTP_STATE_H
14 #define __GPTP_STATE_H
15 
16 #include "gptp_mi.h"
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 /* PDelayRequest states. */
23 enum gptp_pdelay_req_states {
24 	GPTP_PDELAY_REQ_NOT_ENABLED,
25 	GPTP_PDELAY_REQ_INITIAL_SEND_REQ,
26 	GPTP_PDELAY_REQ_RESET,
27 	GPTP_PDELAY_REQ_SEND_REQ,
28 	GPTP_PDELAY_REQ_WAIT_RESP,
29 	GPTP_PDELAY_REQ_WAIT_FOLLOW_UP,
30 	GPTP_PDELAY_REQ_WAIT_ITV_TIMER,
31 } __packed;
32 
33 /* Path Delay Response states. */
34 enum gptp_pdelay_resp_states {
35 	GPTP_PDELAY_RESP_NOT_ENABLED,
36 	GPTP_PDELAY_RESP_INITIAL_WAIT_REQ,
37 	GPTP_PDELAY_RESP_WAIT_REQ,
38 	GPTP_PDELAY_RESP_WAIT_TSTAMP,
39 } __packed;
40 
41 /* SyncReceive states. */
42 enum gptp_sync_rcv_states {
43 	GPTP_SYNC_RCV_DISCARD,
44 	GPTP_SYNC_RCV_WAIT_SYNC,
45 	GPTP_SYNC_RCV_WAIT_FOLLOW_UP,
46 } __packed;
47 
48 /* SyncSend states. */
49 enum gptp_sync_send_states {
50 	GPTP_SYNC_SEND_INITIALIZING,
51 	GPTP_SYNC_SEND_SEND_SYNC,
52 	GPTP_SYNC_SEND_SEND_FUP,
53 } __packed;
54 
55 /* PortSyncSyncReceive states. */
56 enum gptp_pss_rcv_states {
57 	GPTP_PSS_RCV_DISCARD,
58 	GPTP_PSS_RCV_RECEIVED_SYNC,
59 } __packed;
60 
61 /* PortSyncSyncSend states. */
62 enum gptp_pss_send_states {
63 	GPTP_PSS_SEND_TRANSMIT_INIT,
64 	GPTP_PSS_SEND_SYNC_RECEIPT_TIMEOUT,
65 	GPTP_PSS_SEND_SEND_MD_SYNC,
66 	GPTP_PSS_SEND_SET_SYNC_RECEIPT_TIMEOUT,
67 } __packed;
68 
69 /* SiteSyncSyncReceive states. */
70 enum gptp_site_sync_sync_states {
71 	GPTP_SSS_INITIALIZING,
72 	GPTP_SSS_RECEIVING_SYNC,
73 } __packed;
74 
75 /* ClockSlaveSync states. */
76 enum gptp_clk_slave_sync_states {
77 	GPTP_CLK_SLAVE_SYNC_INITIALIZING,
78 	GPTP_CLK_SLAVE_SYNC_SEND_SYNC_IND,
79 } __packed;
80 
81 /* PortAnnounceReceive states. */
82 enum gptp_pa_rcv_states {
83 	GPTP_PA_RCV_DISCARD,
84 	GPTP_PA_RCV_RECEIVE,
85 } __packed;
86 
87 /* PortAnnounceInformation states. */
88 enum gptp_pa_info_states {
89 	GPTP_PA_INFO_DISABLED,
90 	/* State to handle the transition after DISABLED state. */
91 	GPTP_PA_INFO_POST_DISABLED,
92 	GPTP_PA_INFO_AGED,
93 	GPTP_PA_INFO_UPDATE,
94 	GPTP_PA_INFO_CURRENT,
95 	GPTP_PA_INFO_RECEIVE,
96 	GPTP_PA_INFO_SUPERIOR_MASTER_PORT,
97 	GPTP_PA_INFO_REPEATED_MASTER_PORT,
98 	GPTP_PA_INFO_INFERIOR_MASTER_OR_OTHER_PORT,
99 } __packed;
100 
101 /* PortRoleSelection states. */
102 enum gptp_pr_selection_states {
103 	GPTP_PR_SELECTION_INIT_BRIDGE,
104 	GPTP_PR_SELECTION_ROLE_SELECTION,
105 } __packed;
106 
107 /* PortAnnounceTransmit states. */
108 enum gptp_pa_transmit_states {
109 	GPTP_PA_TRANSMIT_INIT,
110 	GPTP_PA_TRANSMIT_PERIODIC,
111 	GPTP_PA_TRANSMIT_IDLE,
112 	GPTP_PA_TRANSMIT_POST_IDLE,
113 } __packed;
114 
115 /* ClockMasterSyncOffset states. */
116 enum gptp_cms_offset_states {
117 	GPTP_CMS_OFFSET_INITIALIZING,
118 	GPTP_CMS_OFFSET_INDICATION,
119 } __packed;
120 
121 /* ClockMasterSyncSend states. */
122 enum gptp_cms_snd_states {
123 	GPTP_CMS_SND_INITIALIZING,
124 	GPTP_CMS_SND_INDICATION,
125 } __packed;
126 
127 /* ClockMasterSyncReceive states. */
128 enum gptp_cms_rcv_states {
129 	GPTP_CMS_RCV_INITIALIZING,
130 	GPTP_CMS_RCV_WAITING,
131 	GPTP_CMS_RCV_SOURCE_TIME,
132 } __packed;
133 
134 /* Info_is enumeration2. */
135 enum gptp_info_is {
136 	GPTP_INFO_IS_RECEIVED,
137 	GPTP_INFO_IS_MINE,
138 	GPTP_INFO_IS_AGED,
139 	GPTP_INFO_IS_DISABLED,
140 } __packed;
141 
142 enum gptp_time_source {
143 	GPTP_TS_ATOMIC_CLOCK        = 0x10,
144 	GPTP_TS_GPS                 = 0x20,
145 	GPTP_TS_TERRESTRIAL_AUDIO   = 0x30,
146 	GPTS_TS_PTP                 = 0x40,
147 	GPTP_TS_NTP                 = 0x50,
148 	GPTP_TS_HAND_SET            = 0x60,
149 	GPTP_TS_OTHER               = 0x90,
150 	GPTP_TS_INTERNAL_OSCILLATOR = 0xA0,
151 } __packed;
152 
153 /**
154  * @brief gPTP time-synchronization spanning tree priority vector
155  *
156  * Defines the best master selection information.
157  */
158 struct gptp_priority_vector {
159 	/** Identity of the source clock. */
160 	struct gptp_root_system_identity root_system_id;
161 
162 	/** Steps removed from the announce message transmitter and the
163 	 * master clock. Note that this field must be right after
164 	 * root_system_id as we are comparing root system id and steps
165 	 * removed in one memcmp()
166 	 */
167 	uint16_t steps_removed;
168 
169 	/** Port identity of the transmitting time-aware system. */
170 	struct gptp_port_identity src_port_id;
171 
172 	/** Port number of the receiving port. */
173 	uint16_t port_number;
174 } __packed;
175 
176 /* Pdelay Request state machine variables. */
177 struct gptp_pdelay_req_state {
178 	/** Initial Path Delay Response Peer Timestamp. */
179 	uint64_t ini_resp_evt_tstamp;
180 
181 	/** Initial Path Delay Response Ingress Timestamp. */
182 	uint64_t ini_resp_ingress_tstamp;
183 
184 	/** Timer for the Path Delay Request. */
185 	struct k_timer pdelay_timer;
186 
187 	/** Pointer to the received Path Delay Response. */
188 	struct net_pkt *rcvd_pdelay_resp_ptr;
189 
190 	/** Pointer to the received Path Delay Follow Up. */
191 	struct net_pkt *rcvd_pdelay_follow_up_ptr;
192 
193 	/** Pointer to the Path Delay Request to be transmitted. */
194 	struct net_pkt *tx_pdelay_req_ptr;
195 
196 	/** Path Delay Response messages received. */
197 	uint32_t rcvd_pdelay_resp;
198 
199 	/** Path Delay Follow Up messages received. */
200 	uint32_t rcvd_pdelay_follow_up;
201 
202 	/** Number of lost Path Delay Responses. */
203 	uint16_t lost_responses;
204 
205 	/** Current state of the state machine. */
206 	enum gptp_pdelay_req_states state;
207 
208 	/** Timer expired, a new Path Delay Request needs to be sent. */
209 	bool pdelay_timer_expired;
210 
211 	/** NeighborRateRatio has been computed successfully. */
212 	bool neighbor_rate_ratio_valid;
213 
214 	/** Path Delay has already been computed after initialization. */
215 	bool init_pdelay_compute;
216 
217 	/** Count consecutive Pdelay_req with multiple responses. */
218 	uint8_t multiple_resp_count;
219 };
220 
221 /**
222  * @brief Pdelay Response state machine variables.
223  */
224 struct gptp_pdelay_resp_state {
225 	/** Current state of the state machine. */
226 	enum gptp_pdelay_resp_states state;
227 };
228 
229 /* SyncReceive state machine variables. */
230 struct gptp_sync_rcv_state {
231 	/** Time at which a Sync Message without Follow Up will be discarded. */
232 	uint64_t follow_up_receipt_timeout;
233 
234 	/** Timer for the Follow Up discard. */
235 	struct k_timer follow_up_discard_timer;
236 
237 	/** Pointer to the received Sync message. */
238 	struct net_pkt *rcvd_sync_ptr;
239 
240 	/** Pointer to the received Follow Up message. */
241 	struct net_pkt *rcvd_follow_up_ptr;
242 
243 	/** Current state of the state machine. */
244 	enum gptp_sync_rcv_states state;
245 
246 	/** A Sync Message has been received. */
247 	bool rcvd_sync;
248 
249 	/** A Follow Up Message has been received. */
250 	bool rcvd_follow_up;
251 
252 	/** A Follow Up Message has been received. */
253 	bool follow_up_timeout_expired;
254 };
255 
256 /* SyncSend state machine variables. */
257 struct gptp_sync_send_state {
258 	/** Pointer to the received MDSyncSend structure. */
259 	struct gptp_md_sync_info *sync_send_ptr;
260 
261 	/** Pointer to the sync message to be sent. */
262 	struct net_pkt *sync_ptr;
263 
264 	/** Current state of the state machine. */
265 	enum gptp_sync_send_states state;
266 
267 	/** A MDSyncSend structure has been received. */
268 	bool rcvd_md_sync;
269 
270 	/** The timestamp for the sync message has been received. */
271 	bool md_sync_timestamp_avail;
272 };
273 
274 /* PortSyncSyncReceive state machine variables. */
275 struct gptp_pss_rcv_state {
276 	/** Sync receive provided by the MD Sync Receive State Machine. */
277 	struct gptp_md_sync_info sync_rcv;
278 
279 	/** PortSyncSync structure to be transmitted to the Site Sync Sync. */
280 	struct gptp_mi_port_sync_sync pss;
281 
282 	/** SyncReceiptTimeoutTimer for PortAnnounce state machines. */
283 	struct k_timer rcv_sync_receipt_timeout_timer;
284 
285 	/** Ratio of the Grand Master frequency with the Local Clock. */
286 	double rate_ratio;
287 
288 	/** Current state of the state machine. */
289 	enum gptp_pss_rcv_states state;
290 
291 	/** A MDSyncReceive structure is ready to be processed. */
292 	bool rcvd_md_sync;
293 
294 	/** Expiry of SyncReceiptTimeoutTimer. */
295 	bool rcv_sync_receipt_timeout_timer_expired;
296 };
297 
298 /* PortSyncSyncSend state machine variables. */
299 struct gptp_pss_send_state {
300 	/** Precise Origin Timestamp of the last received PortSyncSync. */
301 	struct net_ptp_time last_precise_orig_ts;
302 
303 	/** Half Sync Interval Timer. */
304 	struct k_timer half_sync_itv_timer;
305 
306 	/** syncReceiptTimeout Timer. */
307 	struct k_timer send_sync_receipt_timeout_timer;
308 
309 	/** GM Phase Change of the last received PortSyncSync. */
310 	struct gptp_scaled_ns last_gm_phase_change;
311 
312 	/** Follow Up Correction Field of the last received PortSyncSync. */
313 	int64_t last_follow_up_correction_field;
314 
315 	/** Upstream Tx Time of the last received PortSyncSync. */
316 	uint64_t last_upstream_tx_time;
317 
318 	/** PortSyncSync structure received from the SiteSyncSync. */
319 	struct gptp_mi_port_sync_sync *pss_sync_ptr;
320 
321 	/** Rate Ratio of the last received PortSyncSync. */
322 	double last_rate_ratio;
323 
324 	/** GM Freq Change of the last received PortSyncSync. */
325 	double last_gm_freq_change;
326 
327 	/** Current state of the state machine. */
328 	enum gptp_pss_send_states state;
329 
330 	/** GM Time Base Indicator of the last received PortSyncSync. */
331 	uint16_t last_gm_time_base_indicator;
332 
333 	/** Received Port Number of the last received PortSyncSync. */
334 	uint16_t last_rcvd_port_num;
335 
336 	/** Sync send to be transmitted to the MD Sync Send State Machine. */
337 	struct gptp_md_sync_info sync_send;
338 
339 	/** A PortSyncSync structure is ready to be processed. */
340 	bool rcvd_pss_sync;
341 
342 	/** Flag when the half_sync_itv_timer has expired. */
343 	bool half_sync_itv_timer_expired;
344 
345 	/** Flag when the half_sync_itv_timer has expired twice. */
346 	bool sync_itv_timer_expired;
347 
348 	/** Source Port Identity of the last received PortSyncSync. */
349 	struct gptp_port_identity last_src_port_id;
350 
351 	/** Flag when the syncReceiptTimeoutTime has expired. */
352 	bool send_sync_receipt_timeout_timer_expired;
353 };
354 
355 /* SiteSyncSync state machine variables. */
356 struct gptp_site_sync_sync_state {
357 	/** PortSyncSync structure to be sent to other ports and to the Slave.
358 	 */
359 	struct gptp_mi_port_sync_sync pss_send;
360 
361 	/** Pointer to the PortSyncSync structure received. */
362 	struct gptp_mi_port_sync_sync *pss_rcv_ptr;
363 
364 	/** Current state of the state machine. */
365 	enum gptp_site_sync_sync_states state;
366 
367 	/** A PortSyncSync structure is ready to be processed. */
368 	bool rcvd_pss;
369 };
370 
371 /* ClockSlaveSync state machine variables. */
372 struct gptp_clk_slave_sync_state {
373 	/** Pointer to the PortSyncSync structure received. */
374 	struct gptp_mi_port_sync_sync *pss_rcv_ptr;
375 
376 	/** Current state of the state machine. */
377 	enum gptp_clk_slave_sync_states state;
378 
379 	/** A PortSyncSync structure is ready to be processed. */
380 	bool rcvd_pss;
381 
382 	/** The local clock has expired. */
383 	bool rcvd_local_clk_tick;
384 };
385 
386 /* ClockMasterSyncOffset state machine variables. */
387 struct gptp_clk_master_sync_offset_state {
388 	/** Current state of the state machine. */
389 	enum gptp_cms_offset_states state;
390 
391 	/** Notifies the state machine when Sync Receipt Time is received. */
392 	bool rcvd_sync_receipt_time;
393 };
394 
395 /* ClockMasterSyncSend state machine variables. */
396 struct gptp_clk_master_sync_snd_state {
397 	/** Time when synchronization info will be sent. */
398 	struct gptp_uscaled_ns sync_send_time;
399 
400 	/** PortSyncSync structure transmitted by the state machine. */
401 	struct gptp_mi_port_sync_sync pss_snd;
402 
403 	/** Current state of the state machine. */
404 	enum gptp_cms_snd_states state;
405 };
406 
407 /* ClockMasterSyncReceive state machine variables. */
408 struct gptp_clk_master_sync_rcv_state {
409 	/** The received ClockSourceTime.invoke parameters. Note that the
410 	 * standard defines this as a pointer, but storing the struct here is
411 	 * more convenient
412 	 */
413 	struct gptp_clk_src_time_invoke_params rcvd_clk_src_req;
414 
415 	/** Current state of the state machine */
416 	enum gptp_cms_rcv_states state;
417 
418 	/** A ClockSourceTime.invoke function is received from the
419 	 * Clock source entity
420 	 */
421 	bool rcvd_clock_source_req;
422 
423 	/** The local clock has expired */
424 	bool rcvd_local_clock_tick;
425 };
426 
427 /* PortAnnounceReceive state machine variables. */
428 struct gptp_port_announce_receive_state {
429 	/** Current state of the state machine. */
430 	enum gptp_pa_rcv_states state;
431 
432 	/** An announce message is ready to be processed. */
433 	bool rcvd_announce;
434 };
435 
436 struct gptp_port_announce_information_state {
437 	/** Timer for the announce expiry. */
438 	struct k_timer ann_rcpt_expiry_timer;
439 
440 	/** PortRoleInformation state machine variables. */
441 	enum gptp_pa_info_states state;
442 
443 	/* Expired announce information. */
444 	bool ann_expired;
445 };
446 
447 /* PortRoleSelection state machine variables. */
448 struct gptp_port_role_selection_state {
449 	enum gptp_pr_selection_states state;
450 };
451 
452 /**
453  * @brief PortAnnounceTransmit state machine variables.
454  */
455 struct gptp_port_announce_transmit_state {
456 	/** Timer for the announce expiry. */
457 	struct k_timer ann_send_periodic_timer;
458 
459 	/** PortRoleTransmit state machine variables. */
460 	enum gptp_pa_transmit_states state;
461 
462 	/** Trigger announce information. */
463 	bool ann_trigger;
464 };
465 
466 /**
467  * @brief Structure maintaining per Time-Aware States.
468  */
469 struct gptp_states {
470 	/** SiteSyncSync state machine variables. */
471 	struct gptp_site_sync_sync_state site_ss;
472 
473 	/** ClockSlaveSync state machine variables. */
474 	struct gptp_clk_slave_sync_state clk_slave_sync;
475 
476 	/** PortRoleSelection state machine variables. */
477 	struct gptp_port_role_selection_state pr_sel;
478 
479 	/** ClockMasterSyncOffset state machine variables. */
480 	struct gptp_clk_master_sync_offset_state clk_master_sync_offset;
481 
482 	/** ClockMasterSyncSend state machine variables. */
483 	struct gptp_clk_master_sync_snd_state clk_master_sync_send;
484 
485 	/** ClockMasterSyncReceive state machine variables. */
486 	struct gptp_clk_master_sync_rcv_state clk_master_sync_receive;
487 };
488 
489 /**
490  * @brief Structure maintaining per Port States.
491  */
492 struct gptp_port_states {
493 	/** PathDelayRequest state machine variables. */
494 	struct gptp_pdelay_req_state pdelay_req;
495 
496 	/** SyncReceive state machine variables. */
497 	struct gptp_sync_rcv_state sync_rcv;
498 
499 	/** SyncSend state machine variables. */
500 	struct gptp_sync_send_state sync_send;
501 
502 	/** PortSyncSyncReceive state machine variables. */
503 	struct gptp_pss_rcv_state pss_rcv;
504 
505 	/** PortSyncSync Send state machine variables. */
506 	struct gptp_pss_send_state pss_send;
507 
508 	/** PortAnnounceInformation state machine variables. */
509 	struct gptp_port_announce_information_state pa_info;
510 
511 	/** PortAnnounceTransmit state machine variables. */
512 	struct gptp_port_announce_transmit_state pa_transmit;
513 
514 	/** PathDelayResponse state machine variables. */
515 	struct gptp_pdelay_resp_state pdelay_resp;
516 
517 	/** PortAnnounceReceive state machine variables. */
518 	struct gptp_port_announce_receive_state pa_rcv;
519 };
520 
521 /**
522  * @brief Structure maintaining per port BMCA state machines variables.
523  */
524 struct gptp_port_bmca_data {
525 	/** Pointer to announce message. */
526 	struct net_pkt *rcvd_announce_ptr;
527 
528 	/** The masterPriorityVector for the port. */
529 	struct gptp_priority_vector master_priority;
530 
531 	/** The portPriorityVector for the port. */
532 	struct gptp_priority_vector port_priority;
533 
534 	/** Announce interval. */
535 	struct gptp_uscaled_ns announce_interval;
536 
537 	/** Announce receipt timeout time interval. */
538 	struct gptp_uscaled_ns ann_rcpt_timeout_time_interval;
539 
540 	/** Origin and state of the port's spanning tree information. */
541 	enum gptp_info_is info_is;
542 
543 	/** Last announce message time source. */
544 	enum gptp_time_source ann_time_source;
545 
546 	/** Last announce message flags. */
547 	struct gptp_flags ann_flags;
548 
549 	/** The value of steps removed for the port. */
550 	uint16_t port_steps_removed;
551 
552 	/** The value of steps removed for the port. */
553 	uint16_t message_steps_removed;
554 
555 	/** Last announce message current UTC offset value. */
556 	int16_t ann_current_utc_offset;
557 
558 	/** A qualified announce message has been received. */
559 	bool rcvd_msg;
560 
561 	/** Indicate if PortAnnounceInformation should copy the newly determined
562 	 * master_priority and master_steps_removed.
563 	 */
564 	bool updt_info;
565 
566 	/** Cause a port to transmit Announce Information. */
567 	bool new_info;
568 };
569 
570 #ifdef __cplusplus
571 }
572 #endif
573 
574 #endif /* __GPTP_STATE_H */
575