diff options
author | Eric Herrmann <eherrmann@chromium.org> | 2020-06-22 18:53:45 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-06-24 02:26:00 +0000 |
commit | 678a714db346f57757f587f89460846c4ab1d8ad (patch) | |
tree | 67da0d47a3a1dc5a1a50d3b1c776ee4b70985518 | |
parent | 23098b62cb8b0fed0b1ad03328bee907971d233a (diff) | |
download | chrome-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.c | 8 |
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)) |