serial: Recover the state machine when a request's bytes are dropped

Today we use the byte 0x7e to indicate serial framing flag and
serial trailing flag as well. In cases, when a request fails
due to certain bytes getting dropped, the libmctp serial state
machine never recovers and all the subsequent requests fail.
This is happens because the serial trailing flag is same as the
framing flag.

Assuming an example packet

7e 01 04 ff ff ff ff 85 72 7e
where
7e -> MCTP Serial Framing Flag
01 -> MCTP Serial Revision
04 -> Length of the Data bytes
Next 4 bytes -> Data Bytes
85 -> fcs1
72 -> fcs2
7e -> MCTP Serial Trailing Flag

If some bytes are dropped (say 1st 4 bytes 7e 01 04 ff) in hardware
or on the requester driver, then the libmctp responder state machine
will catch this and drop all the packets until it gets the next MCTP
Serial Framing Byte. However since the MCTP Serial Trailing byte of
the current request is also 0x7e, the state machine would assume this
to be start of the packet for next request and will soon realize
that the next byte 0x7e (next request's MCTP Serial Framing Byte) is not
MCTP_SERIAL_REVISION i.e. 0x01. So it will start dropping bytes
for the next request too.

We can recover from this scenario, as here the
failed request's trailer flag would take us to STATE_WAIT_REVISION,
where we will receive 0x7e (next request's framing flag)

Tested:
Verified the fix on a real scenario where bytes get dropped in
USB hardware. The state machine responds with failure for the
current request, but is able to process the next requests fine.

Change-Id: I9d853876a9765671d0067df21aab006bcf116dbc
Signed-off-by: Nikhil Namjoshi <nikhilnamjoshi@google.com>
diff --git a/serial.c b/serial.c
index d08dbac..8ac4468 100644
--- a/serial.c
+++ b/serial.c
@@ -218,6 +218,18 @@
 	case STATE_WAIT_REVISION:
 		if (c == MCTP_SERIAL_REVISION) {
 			serial->rx_state = STATE_WAIT_LEN;
+		} else if (c == MCTP_SERIAL_FRAMING_FLAG) {
+			/* Handle the case where there are bytes dropped in request,
+			 * and the state machine is out of sync. The failed request's
+			 * trailing footer i.e. 0x7e would be interpreted as next
+			 * request's framing footer. So if we are in STATE_WAIT_REVISION
+			 * and receive 0x7e byte, then contine to stay in
+			 * STATE_WAIT_REVISION
+			 */
+			mctp_prdebug(
+				"Received serial framing flag 0x%02x while waiting"
+				" for serial revision 0x%02x.",
+				c, MCTP_SERIAL_REVISION);
 		} else {
 			mctp_prdebug("invalid revision 0x%02x", c);
 			serial->rx_state = STATE_WAIT_SYNC_START;