summaryrefslogtreecommitdiff
path: root/common/usb_pd_tcpc.c
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@chromium.org>2019-03-01 16:52:26 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-03-28 14:13:58 -0700
commit316cf2a3afee7f0ebfa39f32d394220974539c67 (patch)
tree74928d16435f9f5c7670aec39b8d7b116600c4c3 /common/usb_pd_tcpc.c
parente3e9d6ab178738f354d4615dab7d28af0b139384 (diff)
downloadchrome-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.c31
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++) {