diff options
author | Karthikeyan Ramasubramanian <kramasub@chromium.org> | 2019-03-01 16:52:26 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-03-28 14:13:58 -0700 |
commit | 316cf2a3afee7f0ebfa39f32d394220974539c67 (patch) | |
tree | 74928d16435f9f5c7670aec39b8d7b116600c4c3 /common/usb_pd_tcpc.c | |
parent | e3e9d6ab178738f354d4615dab7d28af0b139384 (diff) | |
download | chrome-ec-316cf2a3afee7f0ebfa39f32d394220974539c67.tar.gz |
common/usb_pd_tcpc: Ignore repeat messages
Sometimes messages with the same ID are retransmitted at the physical
layer. Under such scenario do not handle the repeat messages.
BUG=b:129337537
BRANCH=None
TEST=make -j buildall; Ensure that the DUT boots to ChromeOS. Ensure
that the servo_v4 boots fine. Ensure that the DUT boots fine in
normal mode and recovery mode with and without battery. Ensure that the
repeat request messages triggered aritificially are dropped without any
side-effects. Ensure that the DUT is detected in CCD with
pass-through connected after multiple EC reboots, servo_v4 reboots and
USB-C unplug/replug procedure.
Change-Id: I850cd3536ff5e62c34f9dabcc0f8f53bb196ce4c
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1513033
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Karthikeyan Ramasubramanian <kramasub@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Reviewed-by: Diana Z <dzigterman@chromium.org>
Diffstat (limited to 'common/usb_pd_tcpc.c')
-rw-r--r-- | common/usb_pd_tcpc.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/common/usb_pd_tcpc.c b/common/usb_pd_tcpc.c index 0feabb5b10..83a1569223 100644 --- a/common/usb_pd_tcpc.c +++ b/common/usb_pd_tcpc.c @@ -257,6 +257,7 @@ static struct pd_port_controller { int rx_head[RX_BUFFER_SIZE+1]; uint32_t rx_payload[RX_BUFFER_SIZE+1][7]; int rx_buf_head, rx_buf_tail; + uint8_t msg_id_last; /* Next transmit */ enum tcpm_transmit_type tx_type; @@ -265,6 +266,34 @@ static struct pd_port_controller { const uint32_t *tx_data; } pd[CONFIG_USB_PD_PORT_COUNT]; +void invalidate_last_message_id(int port) +{ + /* + * Message id starts from 0 to 7. If msg_id_last is initialized to 0, + * it will lead to repetitive message id with first received packet, + * so initialize it with an invalid value 0xff. + */ + pd[port].msg_id_last = 0xff; +} + +int consume_repeat_message(int port, uint16_t msg_header) +{ + uint8_t msg_id = PD_HEADER_ID(msg_header); + + /* If repeat message ignore, except softreset control request. */ + if (PD_HEADER_TYPE(msg_header) == PD_CTRL_SOFT_RESET && + PD_HEADER_CNT(msg_header) == 0) { + invalidate_last_message_id(port); + } else if (pd[port].msg_id_last != msg_id) { + pd[port].msg_id_last = msg_id; + } else if (pd[port].msg_id_last == msg_id) { + CPRINTF("Repeat msg_id[%d] port[%d]\n", msg_id, port); + return 1; + } + + return 0; +} + static int rx_buf_is_full(int port) { /* @@ -643,6 +672,7 @@ int pd_analyze_rx(int port, uint32_t *payload) bit = pd_find_preamble(port); if (bit == PD_RX_ERR_HARD_RESET || bit == PD_RX_ERR_CABLE_RESET) { /* Hard reset or cable reset */ + invalidate_last_message_id(port); return bit; } else if (bit < 0) { msg = "Preamble"; @@ -1160,6 +1190,7 @@ void tcpc_init(int port) /* make sure PD monitoring is disabled initially */ pd[port].rx_enabled = 0; + invalidate_last_message_id(port); /* make initial readings of CC voltages */ for (i = 0; i < 2; i++) { |