1 /*
2  * Copyright (c) 2024 BayLibre SAS
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 
9 #include "state_machine.h"
10 
ptp_state_machine(enum ptp_port_state state,enum ptp_port_event event,bool tt_diff)11 enum ptp_port_state ptp_state_machine(enum ptp_port_state state,
12 				      enum ptp_port_event event,
13 				      bool tt_diff)
14 {
15 	enum ptp_port_state new_state = state;
16 
17 	if (event == PTP_EVT_INITIALIZE || event == PTP_EVT_POWERUP) {
18 		/* initialize port data sets, HW and communication facilities */
19 		return PTP_PS_INITIALIZING;
20 	}
21 
22 	switch (state) {
23 	case PTP_PS_INITIALIZING:
24 		switch (event) {
25 		case PTP_EVT_FAULT_DETECTED:
26 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
27 					PTP_PS_FAULTY : new_state;
28 			break;
29 		case PTP_EVT_INIT_COMPLETE:
30 			new_state = IS_ENABLED(CONFIG_PTP_LISTENING_PRESENT) ?
31 					PTP_PS_LISTENING : PTP_PS_TIME_TRANSMITTER;
32 			break;
33 		default:
34 			break;
35 		}
36 		break;
37 #if CONFIG_PTP_FAULTY_PRESENT
38 	case PTP_PS_FAULTY:
39 		switch (event) {
40 		case PTP_EVT_DESIGNATED_DISABLED:
41 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
42 					PTP_PS_DISABLED : new_state;
43 			break;
44 		case PTP_EVT_FAULT_CLEARED:
45 			new_state = PTP_PS_INITIALIZING;
46 			break;
47 		default:
48 			break;
49 		}
50 		break;
51 #endif /* CONFIG_PTP_FAULTY_PRESENT */
52 #if CONFIG_PTP_DISABLED_PRESENT
53 	case PTP_PS_DISABLED:
54 		if (event == PTP_EVT_DESIGNATED_ENABLED) {
55 			new_state = PTP_PS_INITIALIZING;
56 		}
57 		break;
58 #endif /* CONFIG_PTP_DISABLED_PRESENT */
59 #if CONFIG_PTP_LISTENING_PRESENT
60 	case PTP_PS_LISTENING:
61 		switch (event) {
62 		case PTP_EVT_DESIGNATED_DISABLED:
63 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
64 					PTP_PS_DISABLED : new_state;
65 			break;
66 		case PTP_EVT_FAULT_DETECTED:
67 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
68 					PTP_PS_FAULTY : new_state;
69 			break;
70 		case PTP_EVT_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
71 			new_state = PTP_PS_TIME_TRANSMITTER;
72 			break;
73 		case PTP_EVT_RS_TIME_TRANSMITTER:
74 			new_state = IS_ENABLED(CONFIG_PTP_PRE_TIME_TRANSMITTER_PRESENT) ?
75 					PTP_PS_PRE_TIME_TRANSMITTER : PTP_PS_TIME_TRANSMITTER;
76 			break;
77 		case PTP_EVT_RS_GRAND_MASTER:
78 			new_state = PTP_PS_GRAND_MASTER;
79 			break;
80 		case PTP_EVT_RS_PASSIVE:
81 			new_state = PTP_PS_PASSIVE;
82 			break;
83 		case PTP_EVT_RS_TIME_RECEIVER:
84 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
85 					PTP_PS_UNCALIBRATED : PTP_PS_TIME_RECEIVER;
86 			break;
87 		default:
88 			break;
89 		}
90 		break;
91 #endif /* CONFIG_PTP_LISTENING_PRESENT */
92 #if CONFIG_PTP_PRE_TIME_TRANSMITTER_PRESENT
93 	case PTP_PS_PRE_TIME_TRANSMITTER:
94 		switch (event) {
95 		case PTP_EVT_DESIGNATED_DISABLED:
96 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
97 					PTP_PS_DISABLED : new_state;
98 			break;
99 		case PTP_EVT_FAULT_DETECTED:
100 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
101 					PTP_PS_FAULTY : new_state;
102 			break;
103 		case PTP_EVT_QUALIFICATION_TIMEOUT_EXPIRES:
104 			new_state = PTP_PS_TIME_TRANSMITTER;
105 			break;
106 		case PTP_EVT_RS_PASSIVE:
107 			new_state = PTP_PS_PASSIVE;
108 			break;
109 		case PTP_EVT_RS_TIME_RECEIVER:
110 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
111 					PTP_PS_UNCALIBRATED : PTP_PS_TIME_RECEIVER;
112 			break;
113 		default:
114 			break;
115 		}
116 		break;
117 #endif /* CONFIG_PTP_PRE_TIME_TRANSMITTER_PRESENT */
118 	case PTP_PS_TIME_TRANSMITTER:
119 		switch (event) {
120 		case PTP_EVT_DESIGNATED_DISABLED:
121 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
122 					PTP_PS_DISABLED : new_state;
123 			break;
124 		case PTP_EVT_FAULT_DETECTED:
125 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
126 					PTP_PS_FAULTY : new_state;
127 			break;
128 		case PTP_EVT_RS_GRAND_MASTER:
129 			new_state = PTP_PS_GRAND_MASTER;
130 			break;
131 		case PTP_EVT_RS_PASSIVE:
132 			new_state = PTP_PS_PASSIVE;
133 			break;
134 		case PTP_EVT_RS_TIME_RECEIVER:
135 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
136 					PTP_PS_UNCALIBRATED : PTP_PS_TIME_RECEIVER;
137 			break;
138 		default:
139 			break;
140 		}
141 		break;
142 	case PTP_PS_PASSIVE:
143 		switch (event) {
144 		case PTP_EVT_DESIGNATED_DISABLED:
145 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
146 					PTP_PS_DISABLED : new_state;
147 			break;
148 		case PTP_EVT_FAULT_DETECTED:
149 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
150 					PTP_PS_FAULTY : new_state;
151 			break;
152 		case PTP_EVT_RS_TIME_TRANSMITTER:
153 			new_state = IS_ENABLED(CONFIG_PTP_PRE_TIME_TRANSMITTER_PRESENT) ?
154 					PTP_PS_PRE_TIME_TRANSMITTER : PTP_PS_TIME_TRANSMITTER;
155 			break;
156 		case PTP_EVT_RS_GRAND_MASTER:
157 			new_state = PTP_PS_GRAND_MASTER;
158 			break;
159 		case PTP_EVT_RS_TIME_RECEIVER:
160 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
161 					PTP_PS_UNCALIBRATED : PTP_PS_TIME_RECEIVER;
162 			break;
163 		default:
164 			break;
165 		}
166 		break;
167 #if CONFIG_PTP_UNCALIBRATED_PRESENT
168 	case PTP_PS_UNCALIBRATED:
169 		switch (event) {
170 		case PTP_EVT_DESIGNATED_DISABLED:
171 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
172 					PTP_PS_DISABLED : new_state;
173 			break;
174 		case PTP_EVT_FAULT_DETECTED:
175 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
176 					PTP_PS_FAULTY : new_state;
177 			break;
178 		case PTP_EVT_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
179 			new_state = PTP_PS_TIME_TRANSMITTER;
180 			break;
181 		case PTP_EVT_TIME_TRANSMITTER_CLOCK_SELECTED:
182 			new_state = PTP_PS_TIME_RECEIVER;
183 			break;
184 		case PTP_EVT_RS_TIME_TRANSMITTER:
185 			new_state = IS_ENABLED(CONFIG_PTP_PRE_TIME_TRANSMITTER_PRESENT) ?
186 					PTP_PS_PRE_TIME_TRANSMITTER : PTP_PS_TIME_TRANSMITTER;
187 			break;
188 		case PTP_EVT_RS_GRAND_MASTER:
189 			new_state = PTP_PS_GRAND_MASTER;
190 			break;
191 		case PTP_EVT_RS_PASSIVE:
192 			new_state = PTP_PS_PASSIVE;
193 			break;
194 		default:
195 			break;
196 		}
197 		break;
198 #endif /* CONFIG_PTP_UNCALIBRATED_PRESENT */
199 	case PTP_PS_TIME_RECEIVER:
200 		switch (event) {
201 		case PTP_EVT_DESIGNATED_DISABLED:
202 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
203 					PTP_PS_DISABLED : new_state;
204 			break;
205 		case PTP_EVT_FAULT_DETECTED:
206 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
207 					PTP_PS_FAULTY : new_state;
208 			break;
209 		case PTP_EVT_SYNCHRONIZATION_FAULT:
210 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
211 					PTP_PS_UNCALIBRATED : new_state;
212 			break;
213 		case PTP_EVT_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
214 			new_state = PTP_PS_TIME_TRANSMITTER;
215 			break;
216 		case PTP_EVT_RS_TIME_TRANSMITTER:
217 			new_state = IS_ENABLED(CONFIG_PTP_PRE_TIME_TRANSMITTER_PRESENT) ?
218 					PTP_PS_PRE_TIME_TRANSMITTER : PTP_PS_TIME_TRANSMITTER;
219 			break;
220 		case PTP_EVT_RS_GRAND_MASTER:
221 			new_state = PTP_PS_GRAND_MASTER;
222 			break;
223 		case PTP_EVT_RS_PASSIVE:
224 			new_state = PTP_PS_PASSIVE;
225 			break;
226 		case PTP_EVT_RS_TIME_RECEIVER:
227 			if (tt_diff) {
228 				new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
229 						PTP_PS_UNCALIBRATED : new_state;
230 			}
231 			break;
232 		default:
233 			break;
234 		}
235 		break;
236 	default:
237 		break;
238 	}
239 
240 	return new_state;
241 }
242 
ptp_tr_state_machine(enum ptp_port_state state,enum ptp_port_event event,bool tt_diff)243 enum ptp_port_state ptp_tr_state_machine(enum ptp_port_state state,
244 					 enum ptp_port_event event,
245 					 bool tt_diff)
246 {
247 	enum ptp_port_state new_state = state;
248 
249 	if (event == PTP_EVT_INITIALIZE || event == PTP_EVT_POWERUP) {
250 		/* initialize port data sets, HW and communication facilities */
251 		return PTP_PS_INITIALIZING;
252 	}
253 
254 	switch (state) {
255 	case PTP_PS_INITIALIZING:
256 		switch (event) {
257 		case PTP_EVT_FAULT_DETECTED:
258 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
259 					PTP_PS_FAULTY : new_state;
260 			break;
261 		case PTP_EVT_INIT_COMPLETE:
262 			new_state = IS_ENABLED(CONFIG_PTP_LISTENING_PRESENT) ?
263 					PTP_PS_LISTENING : PTP_PS_TIME_RECEIVER;
264 			break;
265 		default:
266 			break;
267 		}
268 		break;
269 #if CONFIG_PTP_FAULTY_PRESENT
270 	case PTP_PS_FAULTY:
271 		switch (event) {
272 		case PTP_EVT_DESIGNATED_DISABLED:
273 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
274 					PTP_PS_DISABLED : new_state;
275 			break;
276 		case PTP_EVT_FAULT_CLEARED:
277 			new_state = PTP_PS_INITIALIZING;
278 			break;
279 		default:
280 			break;
281 		}
282 		break;
283 #endif
284 #if CONFIG_PTP_DISABLED_PRESENT
285 	case PTP_PS_DISABLED:
286 		if (event == PTP_EVT_DESIGNATED_ENABLED) {
287 			new_state = PTP_PS_INITIALIZING;
288 		}
289 		break;
290 #endif
291 #if CONFIG_PTP_LISTENING_PRESENT
292 	case PTP_PS_LISTENING:
293 		switch (event) {
294 		case PTP_EVT_DESIGNATED_DISABLED:
295 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
296 					PTP_PS_DISABLED : new_state;
297 			break;
298 		case PTP_EVT_FAULT_DETECTED:
299 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
300 					PTP_PS_FAULTY : new_state;
301 			break;
302 		case PTP_EVT_RS_TIME_RECEIVER:
303 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
304 					PTP_PS_UNCALIBRATED : PTP_PS_TIME_RECEIVER;
305 			break;
306 		default:
307 			break;
308 		}
309 		break;
310 #endif
311 #if CONFIG_PTP_UNCALIBRATED_PRESENT
312 	case PTP_PS_UNCALIBRATED:
313 		switch (event) {
314 		case PTP_EVT_DESIGNATED_DISABLED:
315 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
316 					PTP_PS_DISABLED : new_state;
317 			break;
318 		case PTP_EVT_FAULT_DETECTED:
319 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
320 					PTP_PS_FAULTY : new_state;
321 			break;
322 		case PTP_EVT_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
323 			__fallthrough;
324 		case PTP_EVT_RS_TIME_TRANSMITTER:
325 			__fallthrough;
326 		case PTP_EVT_RS_GRAND_MASTER:
327 			__fallthrough;
328 		case PTP_EVT_RS_PASSIVE:
329 			new_state = IS_ENABLED(CONFIG_PTP_LISTENING_PRESENT) ?
330 					PTP_PS_LISTENING : new_state;
331 			break;
332 		case PTP_EVT_TIME_TRANSMITTER_CLOCK_SELECTED:
333 			new_state = PTP_PS_TIME_RECEIVER;
334 		default:
335 			break;
336 		}
337 		break;
338 #endif
339 	case PTP_PS_TIME_RECEIVER:
340 		switch (event) {
341 		case PTP_EVT_DESIGNATED_DISABLED:
342 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
343 					PTP_PS_DISABLED : new_state;
344 			break;
345 		case PTP_EVT_FAULT_DETECTED:
346 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
347 					PTP_PS_FAULTY : new_state;
348 			break;
349 		case PTP_EVT_SYNCHRONIZATION_FAULT:
350 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
351 					PTP_PS_UNCALIBRATED : new_state;
352 			break;
353 		case PTP_EVT_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
354 			__fallthrough;
355 		case PTP_EVT_RS_TIME_TRANSMITTER:
356 			__fallthrough;
357 		case PTP_EVT_RS_GRAND_MASTER:
358 			__fallthrough;
359 		case PTP_EVT_RS_PASSIVE:
360 			new_state = IS_ENABLED(CONFIG_PTP_LISTENING_PRESENT) ?
361 					PTP_PS_LISTENING : new_state;
362 			break;
363 		case PTP_EVT_RS_TIME_RECEIVER:
364 			if (tt_diff) {
365 				new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
366 						PTP_PS_UNCALIBRATED : new_state;
367 			}
368 			break;
369 		default:
370 			break;
371 		}
372 		break;
373 	default:
374 		break;
375 	}
376 
377 	return new_state;
378 }
379