summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorEric Herrmann <eherrmann@chromium.org>2021-01-12 12:41:52 -0800
committerCommit Bot <commit-bot@chromium.org>2021-01-20 21:44:51 +0000
commit2e830d3145fe6b6a9faf377c38a4066a930f23ba (patch)
tree41241a5b7509328aaf658d309805223850c00b07 /common
parent2eae769ad34ceaae5ce770beae546724801f4ef8 (diff)
downloadchrome-ec-2e830d3145fe6b6a9faf377c38a4066a930f23ba.tar.gz
TCPMv2: Do not check for SinkTxOk in FRS-Mode
After an FRS signal, the initial sink will attempt to initiate the FR Swap AMS, and the initial source should apply SinkTxOk. If the initial source is removed entirely, FRS will be triggered butSinkTxOk will never be applied and this will get the initial sink state machine stuck. So, in the case of an FRS ignore the CC voltage. After an FRS signal, the source isn't allowed to initiate an AMS. BUG=b:171740860 TEST=On Volteer with the PS8815, enable FRS and remove the FRS device. Make sure we enter ErrorRecovery instead of hanging in PE_PRS_SNK_SRC_Send_Swap TEST=make buildall BRANCH=none Change-Id: I8373a76c0c19feeb909b0623a1ae2d6b0ad5fa60 Signed-off-by: Eric Herrmann <eherrmann@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2633654 Commit-Queue: Diana Z <dzigterman@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/mock/usb_pe_sm_mock.c5
-rw-r--r--common/usbc/usb_pe_ctvpd_sm.c6
-rw-r--r--common/usbc/usb_pe_drp_sm.c24
-rw-r--r--common/usbc/usb_prl_sm.c10
4 files changed, 33 insertions, 12 deletions
diff --git a/common/mock/usb_pe_sm_mock.c b/common/mock/usb_pe_sm_mock.c
index e7e9230901..150cbb51e6 100644
--- a/common/mock/usb_pe_sm_mock.c
+++ b/common/mock/usb_pe_sm_mock.c
@@ -81,6 +81,11 @@ void pe_got_soft_reset(int port)
mock_pe_port[port].mock_got_soft_reset = 1;
}
+bool pe_in_frs_mode(int port)
+{
+ return false;
+}
+
bool pe_in_local_ams(int port)
{
/* We will probably want to change this in the future */
diff --git a/common/usbc/usb_pe_ctvpd_sm.c b/common/usbc/usb_pe_ctvpd_sm.c
index aec9e80c93..fd1c83a6df 100644
--- a/common/usbc/usb_pe_ctvpd_sm.c
+++ b/common/usbc/usb_pe_ctvpd_sm.c
@@ -53,6 +53,12 @@ static void pe_init(int port)
set_state_pe(port, PE_REQUEST);
}
+bool pe_in_frs_mode(int port)
+{
+ /* Will never be in FRS mode */
+ return false;
+}
+
bool pe_in_local_ams(int port)
{
/* We never start a local AMS */
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index 76bdb82a1a..ce921fdd1b 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -853,6 +853,11 @@ int pe_is_running(int port)
return local_state[port] == SM_RUN;
}
+bool pe_in_frs_mode(int port)
+{
+ return PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH);
+}
+
bool pe_in_local_ams(int port)
{
return !!PE_CHK_FLAG(port, PE_FLAGS_LOCALLY_INITIATED_AMS);
@@ -1263,7 +1268,7 @@ void pe_report_error(int port, enum pe_error e, enum tcpm_transmit_type type)
get_state_pe(port) == PE_SRC_DISCOVERY ||
get_state_pe(port) == PE_VCS_CBL_SEND_SOFT_RESET ||
get_state_pe(port) == PE_VDM_IDENTITY_REQUEST_CBL) ||
- (PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH) &&
+ (pe_in_frs_mode(port) &&
get_state_pe(port) == PE_PRS_SNK_SRC_SEND_SWAP)
) {
PE_SET_FLAG(port, PE_FLAGS_PROTOCOL_ERROR);
@@ -1579,7 +1584,7 @@ static void print_current_state(const int port)
const char *mode = "";
if (IS_ENABLED(CONFIG_USB_PD_REV30) &&
- PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH))
+ pe_in_frs_mode(port))
mode = " FRS-MODE";
if (IS_ENABLED(USB_PD_DEBUG_LABELS))
@@ -4498,7 +4503,7 @@ static void pe_prs_snk_src_transition_to_off_entry(int port)
print_current_state(port);
if (!IS_ENABLED(CONFIG_USB_PD_REV30) ||
- !PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH))
+ !pe_in_frs_mode(port))
tc_snk_power_off(port);
pe[port].ps_source_timer = get_time().val + PD_T_PS_SOURCE_OFF;
@@ -4561,7 +4566,7 @@ static void pe_prs_snk_src_assert_rp_run(int port)
/* Wait until TypeC is in the Attached.SRC state */
if (tc_is_attached_src(port)) {
if (!IS_ENABLED(CONFIG_USB_PD_REV30) ||
- !PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH)) {
+ !pe_in_frs_mode(port)) {
/* Contract is invalid now */
pe_invalidate_explicit_contract(port);
}
@@ -4647,7 +4652,7 @@ static void pe_prs_snk_src_send_swap_entry(int port)
if (IS_ENABLED(CONFIG_USB_PD_REV30)) {
send_ctrl_msg(port,
TCPC_TX_SOP,
- PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH)
+ pe_in_frs_mode(port)
? PD_CTRL_FR_SWAP
: PD_CTRL_PR_SWAP);
} else {
@@ -4672,7 +4677,7 @@ static void pe_prs_snk_src_send_swap_run(int port)
* Handle discarded message
*/
if (msg_check & PE_MSG_DISCARDED) {
- if (PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH))
+ if (pe_in_frs_mode(port))
set_state_pe(port, PE_SNK_HARD_RESET);
else
set_state_pe(port, PE_SNK_READY);
@@ -4705,8 +4710,7 @@ static void pe_prs_snk_src_send_swap_run(int port)
(type == PD_CTRL_WAIT)) {
if (IS_ENABLED(CONFIG_USB_PD_REV30))
set_state_pe(port,
- PE_CHK_FLAG(port,
- PE_FLAGS_FAST_ROLE_SWAP_PATH)
+ pe_in_frs_mode(port)
? PE_WAIT_FOR_ERROR_RECOVERY
: PE_SNK_READY);
else
@@ -4724,7 +4728,7 @@ static void pe_prs_snk_src_send_swap_run(int port)
if (get_time().val > pe[port].sender_response_timer) {
if (IS_ENABLED(CONFIG_USB_PD_REV30))
set_state_pe(port,
- PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH)
+ pe_in_frs_mode(port)
? PE_WAIT_FOR_ERROR_RECOVERY
: PE_SNK_READY);
else
@@ -4738,7 +4742,7 @@ static void pe_prs_snk_src_send_swap_run(int port)
* this case.
*/
if (IS_ENABLED(CONFIG_USB_PD_REV30) &&
- PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH) &&
+ pe_in_frs_mode(port) &&
PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) {
PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR);
set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY);
diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c
index dabc6a269d..20f53ddb96 100644
--- a/common/usbc/usb_prl_sm.c
+++ b/common/usbc/usb_prl_sm.c
@@ -1204,9 +1204,15 @@ static void prl_tx_snk_pending_run(const int port)
{
enum tcpc_cc_voltage_status cc1, cc2;
- /* Wait unit the SRC applies SINK_TX_OK so we can transmit */
+ /*
+ * Wait unit the SRC applies SINK_TX_OK so we can transmit. In FRS mode,
+ * don't wait for SINK_TX_OK since either the source (and Rp) could be
+ * gone or the TCPC CC_STATUS update time could be too long to meet
+ * tFRSwapInit.
+ */
tcpm_get_cc(port, &cc1, &cc2);
- if (cc1 == TYPEC_CC_VOLT_RP_3_0 || cc2 == TYPEC_CC_VOLT_RP_3_0) {
+ if (cc1 == TYPEC_CC_VOLT_RP_3_0 || cc2 == TYPEC_CC_VOLT_RP_3_0 ||
+ pe_in_frs_mode(port)) {
/*
* We clear the pending XMIT flag here right before we send so
* we can detect if we discarded this message or not