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_PASSIVE:
129 			new_state = PTP_PS_PASSIVE;
130 			break;
131 		case PTP_EVT_RS_TIME_RECEIVER:
132 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
133 					PTP_PS_UNCALIBRATED : PTP_PS_TIME_RECEIVER;
134 			break;
135 		default:
136 			break;
137 		}
138 		break;
139 	case PTP_PS_PASSIVE:
140 		switch (event) {
141 		case PTP_EVT_DESIGNATED_DISABLED:
142 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
143 					PTP_PS_DISABLED : new_state;
144 			break;
145 		case PTP_EVT_FAULT_DETECTED:
146 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
147 					PTP_PS_FAULTY : new_state;
148 			break;
149 		case PTP_EVT_RS_TIME_TRANSMITTER:
150 			new_state = IS_ENABLED(CONFIG_PTP_PRE_TIME_TRANSMITTER_PRESENT) ?
151 					PTP_PS_PRE_TIME_TRANSMITTER : PTP_PS_TIME_TRANSMITTER;
152 			break;
153 		case PTP_EVT_RS_GRAND_MASTER:
154 			new_state = PTP_PS_GRAND_MASTER;
155 			break;
156 		case PTP_EVT_RS_TIME_RECEIVER:
157 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
158 					PTP_PS_UNCALIBRATED : PTP_PS_TIME_RECEIVER;
159 			break;
160 		default:
161 			break;
162 		}
163 		break;
164 #if CONFIG_PTP_UNCALIBRATED_PRESENT
165 	case PTP_PS_UNCALIBRATED:
166 		switch (event) {
167 		case PTP_EVT_DESIGNATED_DISABLED:
168 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
169 					PTP_PS_DISABLED : new_state;
170 			break;
171 		case PTP_EVT_FAULT_DETECTED:
172 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
173 					PTP_PS_FAULTY : new_state;
174 			break;
175 		case PTP_EVT_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
176 			new_state = PTP_PS_TIME_TRANSMITTER;
177 			break;
178 		case PTP_EVT_TIME_TRANSMITTER_CLOCK_SELECTED:
179 			new_state = PTP_PS_TIME_RECEIVER;
180 			break;
181 		case PTP_EVT_RS_TIME_TRANSMITTER:
182 			new_state = IS_ENABLED(CONFIG_PTP_PRE_TIME_TRANSMITTER_PRESENT) ?
183 					PTP_PS_PRE_TIME_TRANSMITTER : PTP_PS_TIME_TRANSMITTER;
184 			break;
185 		case PTP_EVT_RS_GRAND_MASTER:
186 			new_state = PTP_PS_GRAND_MASTER;
187 			break;
188 		case PTP_EVT_RS_PASSIVE:
189 			new_state = PTP_PS_PASSIVE;
190 			break;
191 		default:
192 			break;
193 		}
194 		break;
195 #endif /* CONFIG_PTP_UNCALIBRATED_PRESENT */
196 	case PTP_PS_TIME_RECEIVER:
197 		switch (event) {
198 		case PTP_EVT_DESIGNATED_DISABLED:
199 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
200 					PTP_PS_DISABLED : new_state;
201 			break;
202 		case PTP_EVT_FAULT_DETECTED:
203 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
204 					PTP_PS_FAULTY : new_state;
205 			break;
206 		case PTP_EVT_SYNCHRONIZATION_FAULT:
207 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
208 					PTP_PS_UNCALIBRATED : new_state;
209 			break;
210 		case PTP_EVT_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
211 			new_state = PTP_PS_TIME_TRANSMITTER;
212 			break;
213 		case PTP_EVT_RS_TIME_TRANSMITTER:
214 			new_state = IS_ENABLED(CONFIG_PTP_PRE_TIME_TRANSMITTER_PRESENT) ?
215 					PTP_PS_PRE_TIME_TRANSMITTER : PTP_PS_TIME_TRANSMITTER;
216 			break;
217 		case PTP_EVT_RS_GRAND_MASTER:
218 			new_state = PTP_PS_GRAND_MASTER;
219 			break;
220 		case PTP_EVT_RS_PASSIVE:
221 			new_state = PTP_PS_PASSIVE;
222 			break;
223 		case PTP_EVT_RS_TIME_RECEIVER:
224 			if (tt_diff) {
225 				new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
226 						PTP_PS_UNCALIBRATED : new_state;
227 			}
228 			break;
229 		default:
230 			break;
231 		}
232 		break;
233 	default:
234 		break;
235 	}
236 
237 	return new_state;
238 }
239 
ptp_tr_state_machine(enum ptp_port_state state,enum ptp_port_event event,bool tt_diff)240 enum ptp_port_state ptp_tr_state_machine(enum ptp_port_state state,
241 					 enum ptp_port_event event,
242 					 bool tt_diff)
243 {
244 	enum ptp_port_state new_state = state;
245 
246 	if (event == PTP_EVT_INITIALIZE || event == PTP_EVT_POWERUP) {
247 		/* initialize port data sets, HW and communication facilities */
248 		return PTP_PS_INITIALIZING;
249 	}
250 
251 	switch (state) {
252 	case PTP_PS_INITIALIZING:
253 		switch (event) {
254 		case PTP_EVT_FAULT_DETECTED:
255 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
256 					PTP_PS_FAULTY : new_state;
257 			break;
258 		case PTP_EVT_INIT_COMPLETE:
259 			new_state = IS_ENABLED(CONFIG_PTP_LISTENING_PRESENT) ?
260 					PTP_PS_LISTENING : PTP_PS_TIME_RECEIVER;
261 			break;
262 		default:
263 			break;
264 		}
265 		break;
266 #if CONFIG_PTP_FAULTY_PRESENT
267 	case PTP_PS_FAULTY:
268 		switch (event) {
269 		case PTP_EVT_DESIGNATED_DISABLED:
270 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
271 					PTP_PS_DISABLED : new_state;
272 			break;
273 		case PTP_EVT_FAULT_CLEARED:
274 			new_state = PTP_PS_INITIALIZING;
275 			break;
276 		default:
277 			break;
278 		}
279 		break;
280 #endif
281 #if CONFIG_PTP_DISABLED_PRESENT
282 	case PTP_PS_DISABLED:
283 		if (event == PTP_EVT_DESIGNATED_ENABLED) {
284 			new_state = PTP_PS_INITIALIZING;
285 		}
286 		break;
287 #endif
288 #if CONFIG_PTP_LISTENING_PRESENT
289 	case PTP_PS_LISTENING:
290 		switch (event) {
291 		case PTP_EVT_DESIGNATED_DISABLED:
292 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
293 					PTP_PS_DISABLED : new_state;
294 			break;
295 		case PTP_EVT_FAULT_DETECTED:
296 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
297 					PTP_PS_FAULTY : new_state;
298 			break;
299 		case PTP_EVT_RS_TIME_RECEIVER:
300 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
301 					PTP_PS_UNCALIBRATED : PTP_PS_TIME_RECEIVER;
302 			break;
303 		default:
304 			break;
305 		}
306 		break;
307 #endif
308 #if CONFIG_PTP_UNCALIBRATED_PRESENT
309 	case PTP_PS_UNCALIBRATED:
310 		switch (event) {
311 		case PTP_EVT_DESIGNATED_DISABLED:
312 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
313 					PTP_PS_DISABLED : new_state;
314 			break;
315 		case PTP_EVT_FAULT_DETECTED:
316 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
317 					PTP_PS_FAULTY : new_state;
318 			break;
319 		case PTP_EVT_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
320 			__fallthrough;
321 		case PTP_EVT_RS_TIME_TRANSMITTER:
322 			__fallthrough;
323 		case PTP_EVT_RS_GRAND_MASTER:
324 			__fallthrough;
325 		case PTP_EVT_RS_PASSIVE:
326 			new_state = IS_ENABLED(CONFIG_PTP_LISTENING_PRESENT) ?
327 					PTP_PS_LISTENING : new_state;
328 			break;
329 		case PTP_EVT_TIME_TRANSMITTER_CLOCK_SELECTED:
330 			new_state = PTP_PS_TIME_RECEIVER;
331 		default:
332 			break;
333 		}
334 		break;
335 #endif
336 	case PTP_PS_TIME_RECEIVER:
337 		switch (event) {
338 		case PTP_EVT_DESIGNATED_DISABLED:
339 			new_state = IS_ENABLED(CONFIG_PTP_DISABLED_PRESENT) ?
340 					PTP_PS_DISABLED : new_state;
341 			break;
342 		case PTP_EVT_FAULT_DETECTED:
343 			new_state = IS_ENABLED(CONFIG_PTP_FAULTY_PRESENT) ?
344 					PTP_PS_FAULTY : new_state;
345 			break;
346 		case PTP_EVT_SYNCHRONIZATION_FAULT:
347 			new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
348 					PTP_PS_UNCALIBRATED : new_state;
349 			break;
350 		case PTP_EVT_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
351 			__fallthrough;
352 		case PTP_EVT_RS_TIME_TRANSMITTER:
353 			__fallthrough;
354 		case PTP_EVT_RS_GRAND_MASTER:
355 			__fallthrough;
356 		case PTP_EVT_RS_PASSIVE:
357 			new_state = IS_ENABLED(CONFIG_PTP_LISTENING_PRESENT) ?
358 					PTP_PS_LISTENING : new_state;
359 			break;
360 		case PTP_EVT_RS_TIME_RECEIVER:
361 			if (tt_diff) {
362 				new_state = IS_ENABLED(CONFIG_PTP_UNCALIBRATED_PRESENT) ?
363 						PTP_PS_UNCALIBRATED : new_state;
364 			}
365 			break;
366 		default:
367 			break;
368 		}
369 		break;
370 	default:
371 		break;
372 	}
373 
374 	return new_state;
375 }
376