When a currently active SLAVE port recognizes a temporary fault (and
enters FAULTY state, while port remains available), the redundancy port
does not enter SLAVE state but remains PASSIVE.
Instead, force the PASSIVE port to step in as SLAVE for the FAULTY port.
When the previously FAULTY port is recovering, it does not need to go
through UNCALIBRATED state, but it can instantly replace the redundant
port as SLAVE again.

Signed-off-by: Stephan Wurm <stephan.w...@a-eberle.de>
---
 port.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/port.c b/port.c
index d05797e..c70e5b4 100644
--- a/port.c
+++ b/port.c
@@ -3516,6 +3516,7 @@ enum delay_mechanism port_delay_mechanism(struct port 
*port)
 int port_state_update(struct port *p, enum fsm_event event, int mdiff)
 {
        enum port_state next = p->state_machine(p->state, event, mdiff);
+       struct port *o = port_paired_port(p);
 
        if (PS_FAULTY == next) {
                struct fault_interval i;
@@ -3543,6 +3544,28 @@ int port_state_update(struct port *p, enum fsm_event 
event, int mdiff)
                next = p->state_machine(next, event, 0);
        }
 
+       if (o && !mdiff) {
+               /*
+                * This is a special case for doubly attached clocks, where
+                * the current SLAVE port temporarily enters the FAULTY state.
+                * This forces the redundant port being selected as SLAVE
+                * port instead.
+                */
+               if ((next == PS_PASSIVE_SLAVE) && (o->state == PS_FAULTY)) {
+                       next = PS_SLAVE;
+               }
+
+               /*
+                * This is a special case for doubly attached clocks, where
+                * the best clock recovers from FAULTY state and takes over
+                * the SLAVE role from the redundant port without the need
+                * to go through UNCALIBRATED state.
+                */
+               if ((next == PS_UNCALIBRATED) && (o->state == PS_SLAVE)) {
+                       next = PS_SLAVE;
+               }
+       }
+
        if (mdiff) {
                p->unicast_state_dirty = true;
        }

-- 
2.34.1



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to