summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Herrmann <eherrmann@chromium.org>2020-06-22 18:53:45 -0700
committerCommit Bot <commit-bot@chromium.org>2020-06-24 02:26:00 +0000
commit678a714db346f57757f587f89460846c4ab1d8ad (patch)
tree67da0d47a3a1dc5a1a50d3b1c776ee4b70985518
parent23098b62cb8b0fed0b1ad03328bee907971d233a (diff)
downloadchrome-ec-678a714db346f57757f587f89460846c4ab1d8ad.tar.gz
TCPMv2: Add RCH check to avoid RX packet drops
The chunked message RX state machine can take multiple cycles to process a PD message when the message is received while transmitting. If another message comes in during this, it can overwrite the current PD message since the RCH state machine is before the extended buffer to the PE. This CL checks to make sure the RCH state machine doesn't have a pending message before overwriting pdmsg. This issue only shows up when CONFIG_USB_PD_REV30 is set (since PD20 doesn't use chunked messages). It was seen during fast role swaps on multiple devices. A fast role swap will send an ACCEPT immediately followed by a PS_READY, and the ACCEPT was being dropped. BUG=b:148144711, b:159671235 TEST=make buildall TEST=with an FRS-capable device and host, make sure no packets are dropped in the swap. this is easy to see with PD debug level 2 BRANCH=none Signed-off-by: Eric Herrmann <eherrmann@chromium.org> Change-Id: Ib86fd25a70b42cc14457bcec4261cdb9734fad63 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2259332 Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--common/usbc/usb_prl_sm.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c
index 4fd0a79970..3d2e7a5bc4 100644
--- a/common/usbc/usb_prl_sm.c
+++ b/common/usbc/usb_prl_sm.c
@@ -1963,6 +1963,14 @@ static void prl_rx_wait_for_phy_message(const int port, int evt)
uint8_t cnt;
int8_t msid;
+ /*
+ * If PD3, wait for the RX chunk SM to copy the pdmsg into the extended
+ * buffer before overwriting pdmsg.
+ */
+ if (IS_ENABLED(CONFIG_USB_PD_REV30) &&
+ RCH_CHK_FLAG(port, PRL_FLAGS_MSG_RECEIVED))
+ return;
+
/* If we don't have any message, just stop processing now. */
if (!tcpm_has_pending_message(port) ||
tcpm_dequeue_message(port, pdmsg[port].rx_chk_buf, &header))