diff options
author | Sam Hurst <shurst@google.com> | 2019-11-08 17:54:13 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-11-24 22:33:49 +0000 |
commit | 012e3706620949ce8ccca234c5fe8083715d3ee3 (patch) | |
tree | 79459a77207eed6ff8ec4f815bee3c6f2bb78006 | |
parent | 7adfccc97d0b7f03f9feb6702078d4bfd14f5918 (diff) | |
download | chrome-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.c | 116 | ||||
-rw-r--r-- | common/usbc/usb_prl_sm.c | 50 |
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); } } |