summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Hurst <shurst@google.com>2019-11-08 17:54:13 -0800
committerCommit Bot <commit-bot@chromium.org>2019-11-24 22:33:49 +0000
commit012e3706620949ce8ccca234c5fe8083715d3ee3 (patch)
tree79459a77207eed6ff8ec4f815bee3c6f2bb78006
parent7adfccc97d0b7f03f9feb6702078d4bfd14f5918 (diff)
downloadchrome-ec-012e3706620949ce8ccca234c5fe8083715d3ee3.tar.gz
TCPMv2: Keep message transmission and reception synchronized
If a message is expected after a transmit, hold off on checking for that until the sender response timer is set. BUG=chromium:1022715 BRANCH=none TEST=make -j buildall manual tests: Connect StarTech CDP2DP USB-C to DP dongle Observe REQUEST send less than 1ms after SRC_CAP Look for ACCEPT message sent by PE and PD Change-Id: I1d155ead698ac39172c604cc3f656631565855d5 Signed-off-by: Sam Hurst <shurst@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1907807 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--common/usbc/usb_pe_drp_sm.c116
-rw-r--r--common/usbc/usb_prl_sm.c50
2 files changed, 114 insertions, 52 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index f44a03abff..7521db7edb 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -1179,7 +1179,8 @@ static void pe_src_send_capabilities_run(int port)
* 2) Reset the HardResetCounter and CapsCounter to zero.
* 3) Initialize and run the SenderResponseTimer.
*/
- if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
+ if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE) &&
+ pe[port].sender_response_timer == TIMER_DISABLED) {
PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE);
/* Stop the NoResponseTimer */
@@ -1200,7 +1201,8 @@ static void pe_src_send_capabilities_run(int port)
* Transition to the PE_SRC_Negotiate_Capability state when:
* 1) A Request Message is received from the Sink
*/
- if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) {
+ if (pe[port].sender_response_timer != TIMER_DISABLED &&
+ PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) {
PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED);
/*
@@ -1917,12 +1919,15 @@ static void pe_snk_select_capability_run(int port)
uint8_t cnt;
/* Wait until message is sent */
- if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
- PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE);
-
- /* Initialize and run SenderResponseTimer */
- pe[port].sender_response_timer =
+ if (pe[port].sender_response_timer == TIMER_DISABLED) {
+ if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
+ PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE);
+ /* Initialize and run SenderResponseTimer */
+ pe[port].sender_response_timer =
get_time().val + PD_T_SENDER_RESPONSE;
+ } else {
+ return;
+ }
}
if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) {
@@ -1989,6 +1994,22 @@ static void pe_snk_select_capability_run(int port)
PE_SNK_WAIT_FOR_CAPABILITIES);
return;
}
+ /*
+ * Unexpected Control Message Received
+ */
+ else {
+ /* Send Soft Reset */
+ set_state_pe(port, PE_SEND_SOFT_RESET);
+ return;
+ }
+ }
+ /*
+ * Unexpected Data Message
+ */
+ else {
+ /* Send Soft Reset */
+ set_state_pe(port, PE_SEND_SOFT_RESET);
+ return;
}
}
@@ -2790,11 +2811,27 @@ static void pe_drs_send_swap_run(int port)
int ext;
/* Wait until message is sent */
- if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
- PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE);
- /* start the SenderResponseTimer */
- pe[port].sender_response_timer =
- get_time().val + PD_T_SENDER_RESPONSE;
+ if (pe[port].sender_response_timer == TIMER_DISABLED) {
+ if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
+ PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE);
+ /* Initialize and run SenderResponseTimer */
+ pe[port].sender_response_timer =
+ get_time().val + PD_T_SENDER_RESPONSE;
+ } else {
+ return;
+ }
+ }
+
+ /*
+ * Transition to PE_SRC_Ready or PE_SNK_Ready state when:
+ * 1) Or the SenderResponseTimer times out.
+ */
+ if (get_time().val > pe[port].sender_response_timer) {
+ if (pe[port].power_role == PD_ROLE_SINK)
+ set_state_pe(port, PE_SNK_READY);
+ else
+ set_state_pe(port, PE_SRC_READY);
+ return;
}
/*
@@ -2925,7 +2962,8 @@ static void pe_prs_src_snk_wait_source_on_run(int port)
int cnt;
int ext;
- if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
+ if (pe[port].ps_source_timer != TIMER_DISABLED &&
+ PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE);
/* Update pe power role */
@@ -3168,13 +3206,14 @@ static void pe_prs_snk_src_source_on_run(int port)
{
/* Wait until power supply turns on */
if (pe[port].ps_source_timer != TIMER_DISABLED) {
- if (get_time().val >= pe[port].ps_source_timer) {
- /* update pe power role */
- pe[port].power_role = tc_get_power_role(port);
- prl_send_ctrl_msg(port, TCPC_TX_SOP, PD_CTRL_PS_RDY);
- /* reset timer so PD_CTRL_PS_RDY isn't sent again */
- pe[port].ps_source_timer = TIMER_DISABLED;
- }
+ if (get_time().val < pe[port].ps_source_timer)
+ return;
+
+ /* update pe power role */
+ pe[port].power_role = tc_get_power_role(port);
+ prl_send_ctrl_msg(port, TCPC_TX_SOP, PD_CTRL_PS_RDY);
+ /* reset timer so PD_CTRL_PS_RDY isn't sent again */
+ pe[port].ps_source_timer = TIMER_DISABLED;
}
/*
@@ -3611,16 +3650,11 @@ static void pe_vdm_request_entry(int port)
static void pe_vdm_request_run(int port)
{
- if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
+ if (pe[port].vdm_response_timer == TIMER_DISABLED &&
+ PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
/* Message was sent */
PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE);
- if (pe[port].partner_type) {
- /* Restore power and data roles */
- tc_set_power_role(port, pe[port].saved_power_role);
- tc_set_data_role(port, pe[port].saved_data_role);
- }
-
/* Start no response timer */
pe[port].vdm_response_timer =
get_time().val + PD_T_VDM_SNDR_RSP;
@@ -3644,7 +3678,8 @@ static void pe_vdm_request_run(int port)
ext = PD_HEADER_EXT(emsg[port].header);
if ((sop == TCPC_TX_SOP || sop == TCPC_TX_SOP_PRIME) &&
- type == PD_DATA_VENDOR_DEF && cnt > 0 && ext == 0) {
+ type == PD_DATA_VENDOR_DEF && cnt > 0 &&
+ ext == 0) {
if (PD_VDO_CMDT(payload[0]) == CMDT_RSP_ACK) {
set_state_pe(port, PE_VDM_ACKED);
return;
@@ -3657,6 +3692,16 @@ static void pe_vdm_request_run(int port)
PE_SET_FLAG(port,
PE_FLAGS_VDM_REQUEST_BUSY);
}
+ } else {
+ /*
+ * Unexpected Message Received.
+ * Return to Src.Ready or Snk.Ready to
+ * handle it.
+ */
+ if (pe[port].power_role == PD_ROLE_SOURCE)
+ set_state_pe(port, PE_SRC_READY);
+ else
+ set_state_pe(port, PE_SNK_READY);
}
}
@@ -3995,13 +4040,17 @@ static void pe_vcs_send_swap_run(int port)
uint8_t cnt;
/* Wait until message is sent */
- if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
+ if (pe[port].sender_response_timer == TIMER_DISABLED &&
+ PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE);
/* Start the SenderResponseTimer */
pe[port].sender_response_timer = get_time().val +
PD_T_SENDER_RESPONSE;
}
+ if (pe[port].sender_response_timer == TIMER_DISABLED)
+ return;
+
if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) {
PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED);
@@ -4028,7 +4077,6 @@ static void pe_vcs_send_swap_run(int port)
PE_VCS_TURN_ON_VCONN_SWAP);
return;
}
-
/*
* Transition back to either the PE_SRC_Ready or
* PE_SNK_Ready state when:
@@ -4045,6 +4093,14 @@ static void pe_vcs_send_swap_run(int port)
set_state_pe(port, PE_SNK_READY);
}
}
+ /*
+ * Unexpected Data Message Received
+ */
+ else {
+ /* Send Soft Reset */
+ set_state_pe(port, PE_SEND_SOFT_RESET);
+ return;
+ }
}
}
diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c
index de4dda7db1..9a78b59474 100644
--- a/common/usbc/usb_prl_sm.c
+++ b/common/usbc/usb_prl_sm.c
@@ -472,6 +472,7 @@ static void prl_tx_phy_layer_reset_entry(const int port)
vpd_rx_enable(1);
} else {
tcpm_init(port);
+ tcpm_clear_pending_messages(port);
tcpm_set_rx_enable(port, 1);
}
}
@@ -489,28 +490,9 @@ static void prl_tx_wait_for_message_request_entry(const int port)
static void prl_tx_wait_for_message_request_run(const int port)
{
- if (PRL_TX_CHK_FLAG(port, PRL_FLAGS_MSG_XMIT)) {
- PRL_TX_CLR_FLAG(port, PRL_FLAGS_MSG_XMIT);
- /*
- * Soft Reset Message Message pending
- */
- if ((pdmsg[port].msg_type == PD_CTRL_SOFT_RESET) &&
- (emsg[port].len == 0)) {
- set_state_prl_tx(port, PRL_TX_LAYER_RESET_FOR_TRANSMIT);
- }
- /*
- * Message pending (except Soft Reset)
- */
- else {
- /* NOTE: PRL_TX_Construct_Message State embedded here */
- prl_tx_construct_message(port);
- set_state_prl_tx(port, PRL_TX_WAIT_FOR_PHY_RESPONSE);
- }
-
- return;
- } else if ((prl_get_rev(port, pdmsg[port].xmit_type) == PD_REV30) &&
- PRL_TX_CHK_FLAG(port, (PRL_FLAGS_START_AMS |
- PRL_FLAGS_END_AMS))) {
+ if ((prl_get_rev(port, pdmsg[port].xmit_type) == PD_REV30) &&
+ PRL_TX_CHK_FLAG(port,
+ (PRL_FLAGS_START_AMS | PRL_FLAGS_END_AMS))) {
if (tc_get_power_role(port) == PD_ROLE_SOURCE) {
/*
* Start of AMS notification received from
@@ -544,6 +526,25 @@ static void prl_tx_wait_for_message_request_run(const int port)
return;
}
}
+ } else if (PRL_TX_CHK_FLAG(port, PRL_FLAGS_MSG_XMIT)) {
+ PRL_TX_CLR_FLAG(port, PRL_FLAGS_MSG_XMIT);
+ /*
+ * Soft Reset Message Message pending
+ */
+ if ((pdmsg[port].msg_type == PD_CTRL_SOFT_RESET) &&
+ (emsg[port].len == 0)) {
+ set_state_prl_tx(port, PRL_TX_LAYER_RESET_FOR_TRANSMIT);
+ }
+ /*
+ * Message pending (except Soft Reset)
+ */
+ else {
+ /* NOTE: PRL_TX_Construct_Message State embedded here */
+ prl_tx_construct_message(port);
+ set_state_prl_tx(port, PRL_TX_WAIT_FOR_PHY_RESPONSE);
+ }
+
+ return;
}
}
@@ -722,6 +723,11 @@ static void prl_tx_wait_for_phy_response_run(const int port)
increment_msgid_counter(port);
/* Inform Policy Engine Message was sent */
PDMSG_SET_FLAG(port, PRL_FLAGS_TX_COMPLETE);
+ /*
+ * This event reduces the time of informing the policy engine of
+ * the transmission by one state machine cycle
+ */
+ task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_SM, 0);
set_state_prl_tx(port, PRL_TX_WAIT_FOR_MESSAGE_REQUEST);
}
}