diff options
author | Scott Collyer <scollyer@google.com> | 2021-03-11 11:11:14 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-03-31 19:29:58 +0000 |
commit | 7285b915683d22675be649776009cac268182130 (patch) | |
tree | 8f7ba26a544b0439019b9475bec72be52812fb3d /common | |
parent | 3734bffbe0538101dec858b60542a5a40fe2bb81 (diff) | |
download | chrome-ec-7285b915683d22675be649776009cac268182130.tar.gz |
TCPMv2: PRL: Enahnce support for the tx message discard path
This CL modifies the tx message discard path in the PRL. The states
that should have triggered tx message discard events, would only act
on messages pending from PE, but not passed yet to the phy. This
behavior was required to account for the serial nature of the
different PRL state machines and inherent delay in sending/receiving
messages to/from off chip TCPCs via the I2C bus.
This CL adds a new WAIT value to the xmit_status enum so that a
message being sent to the phy but not reponse yet can be known. In
addition, xmit_status == DISCARDED is no longer treated automatically
as a protocol error.
BUG=b:181179550,b:173028144
BRANCH=None
TEST=Running VDMU.E16 compliance test. Validated that the SVDM command
sequence is properly interrupted in most all cases. This test only
fails if collision events are present which is a happening on honybuns
for 2 reasons:
1) GRL test waits too long to interrupt the VDM command (~1 msec)
2) honeybuns ucpd is faster since it doesn't have i2c delays.
Signed-off-by: Scott Collyer <scollyer@google.com>
Change-Id: I2bec09b96d7f6ea6122fcb369246717950987ca8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2752251
Tested-by: Scott Collyer <scollyer@chromium.org>
Reviewed-by: Diana Z <dzigterman@chromium.org>
Commit-Queue: Scott Collyer <scollyer@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/usbc/usb_prl_sm.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c index 34f0ff251d..3ee3615104 100644 --- a/common/usbc/usb_prl_sm.c +++ b/common/usbc/usb_prl_sm.c @@ -844,6 +844,8 @@ static void prl_tx_phy_layer_reset_entry(const int port) static void prl_tx_wait_for_message_request_entry(const int port) { + /* No phy layer response is pending */ + prl_tx[port].xmit_status = TCPC_TX_UNSET; print_current_prl_tx_state(port); } @@ -936,8 +938,17 @@ static void prl_tx_discard_message_entry(const int port) * Discard queued message * Note: We differ from spec here, which allows us to not discard on * incoming SOP' or SOP''. However this would get the TCH out of sync. + * + * prl_tx will be set to this state following message reception in + * prl_rx. So this path will be entered following each rx message. If + * this state is entered, and there is either a message from the PE + * pending, or if a message was passed to the phy and there is either no + * response yet, or it was discarded in the phy layer, then a tx message + * discard event has been detected. */ - if (PRL_TX_CHK_FLAG(port, PRL_FLAGS_MSG_XMIT)) { + if (PRL_TX_CHK_FLAG(port, PRL_FLAGS_MSG_XMIT) || + prl_tx[port].xmit_status == TCPC_TX_WAIT || + prl_tx[port].xmit_status == TCPC_TX_COMPLETE_DISCARDED) { PRL_TX_CLR_FLAG(port, PRL_FLAGS_MSG_XMIT); increment_msgid_counter(port); pe_report_discard(port); @@ -1058,12 +1069,13 @@ static void prl_tx_construct_message(const int port) /* Save SOP* so the correct msg_id_counter can be incremented */ prl_tx[port].last_xmit_type = pdmsg[port].xmit_type; + /* Indicate that a tx message is being passed to the phy layer */ + prl_tx[port].xmit_status = TCPC_TX_WAIT; /* - * These flags could be set if this function is called before the - * Policy Engine is informed of the previous transmission. Clear the - * flags so that this message can be sent. + * PRL_FLAGS_TX_COMPLETE could be set if this function is called before + * the Policy Engine is informed of the previous transmission. Clear the + * flag so that this message can be sent. */ - prl_tx[port].xmit_status = TCPC_TX_UNSET; PDMSG_CLR_FLAG(port, PRL_FLAGS_TX_COMPLETE); /* @@ -1117,8 +1129,7 @@ static void prl_tx_wait_for_phy_response_run(const int port) task_wake(PD_PORT_TO_TASK_ID(port)); set_state_prl_tx(port, PRL_TX_WAIT_FOR_MESSAGE_REQUEST); } else if (pd_timer_is_expired(port, PR_TIMER_TCPC_TX_TIMEOUT) || - prl_tx[port].xmit_status == TCPC_TX_COMPLETE_FAILED || - prl_tx[port].xmit_status == TCPC_TX_COMPLETE_DISCARDED) { + prl_tx[port].xmit_status == TCPC_TX_COMPLETE_FAILED) { /* * NOTE: PRL_Tx_Transmission_Error State embedded * here. @@ -1144,7 +1155,6 @@ static void prl_tx_wait_for_phy_response_run(const int port) static void prl_tx_wait_for_phy_response_exit(const int port) { - prl_tx[port].xmit_status = TCPC_TX_UNSET; pd_timer_disable(port, PR_TIMER_TCPC_TX_TIMEOUT); } @@ -1852,13 +1862,17 @@ static void tch_wait_for_transmission_complete_run(const int port) return; } /* - * Any message received and not in state TCH_Wait_Chunk_Request - * MUST be checked after transmission status due to our TCPC - * architecture, and should not be checked if prl_tx is still waiting on - * the TCPC. + * A message was received while TCH is waiting for the phy to complete + * sending a tx message. + * + * Because of our prl_sm architecture and I2C access delays for TCPCs, + * it's possible to have a message received and the prl_tx state not be + * in its default waiting state. To avoid a false protocol error, only + * jump to TCH_MESSAGE_RECEIVED if the phy layer has not indicated that + * the tx message was sent successfully. */ if (TCH_CHK_FLAG(port, PRL_FLAGS_MSG_RECEIVED) && - prl_tx_get_state(port) != PRL_TX_WAIT_FOR_PHY_RESPONSE) { + prl_tx[port].xmit_status != TCPC_TX_COMPLETE_SUCCESS) { TCH_CLR_FLAG(port, PRL_FLAGS_MSG_RECEIVED); set_state_tch(port, TCH_MESSAGE_RECEIVED); return; @@ -2199,7 +2213,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) * complete at the same time as a response so only do this if a * message is pending. */ - if (prl_tx_get_state(port) != PRL_TX_WAIT_FOR_PHY_RESPONSE || + if (prl_tx[port].xmit_status != TCPC_TX_COMPLETE_SUCCESS || PRL_TX_CHK_FLAG(port, PRL_FLAGS_MSG_XMIT)) set_state_prl_tx(port, PRL_TX_DISCARD_MESSAGE); } |