From f420b2073e02a2e745bb4c43f4144cf60045b7be Mon Sep 17 00:00:00 2001 From: Abe Levkoy Date: Mon, 19 Oct 2020 17:32:48 -0600 Subject: TCPMv2: Avoid VCONN-Source discovery failure Remove redundant checks for VCONN Source in pe_attempt_port_discovery (which prevent discovery from running). Allow pe_vdm_send_request to attempt to become VCONN Source if necessary. Make the checks in the VDM request child states more complete (not just checking for VCONN Source). BUG=b:170662791 TEST=Attach Tapex Creek board; observed successful discovery BRANCH=none Signed-off-by: Abe Levkoy Change-Id: Id7d3a1b82d1029f69b3e05b845632e7237524bc6 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2486303 Tested-by: Li1 Feng Reviewed-by: Diana Z --- common/mock/usb_tc_sm_mock.c | 3 ++- common/usbc/usb_pe_drp_sm.c | 32 +++++++++++++++++++++++--------- include/mock/usb_tc_sm_mock.h | 1 + test/usb_pe_drp.c | 1 + 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/common/mock/usb_tc_sm_mock.c b/common/mock/usb_tc_sm_mock.c index dfe8eeef48..7679cae260 100644 --- a/common/mock/usb_tc_sm_mock.c +++ b/common/mock/usb_tc_sm_mock.c @@ -30,6 +30,7 @@ void mock_tc_port_reset(void) mock_tc_port[port].lcl_rp = TYPEC_RP_RESERVED; mock_tc_port[port].attached_snk = 0; mock_tc_port[port].attached_src = 0; + mock_tc_port[port].vconn_src = false; } } @@ -85,7 +86,7 @@ void tc_ctvpd_detected(int port) int tc_is_vconn_src(int port) { - return 0; + return mock_tc_port[port].vconn_src; } void tc_hard_reset_request(int port) diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index e599097f43..655bae4599 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -1580,7 +1580,7 @@ static bool pe_attempt_port_discovery(int port) */ if (get_time().val > pe[port].discover_identity_timer) { if (pd_get_identity_discovery(port, TCPC_TX_SOP_PRIME) == - PD_DISC_NEEDED && pe_can_send_sop_prime(port)) { + PD_DISC_NEEDED) { pe[port].tx_type = TCPC_TX_SOP_PRIME; set_state_pe(port, PE_VDM_IDENTITY_REQUEST_CBL); return true; @@ -1604,14 +1604,12 @@ static bool pe_attempt_port_discovery(int port) set_state_pe(port, PE_INIT_VDM_MODES_REQUEST); return true; } else if (pd_get_svids_discovery(port, TCPC_TX_SOP_PRIME) - == PD_DISC_NEEDED && - pe_can_send_sop_prime(port)) { + == PD_DISC_NEEDED) { pe[port].tx_type = TCPC_TX_SOP_PRIME; set_state_pe(port, PE_INIT_VDM_SVIDS_REQUEST); return true; } else if (pd_get_modes_discovery(port, TCPC_TX_SOP_PRIME) == - PD_DISC_NEEDED && - pe_can_send_sop_prime(port)) { + PD_DISC_NEEDED) { pe[port].tx_type = TCPC_TX_SOP_PRIME; set_state_pe(port, PE_INIT_VDM_MODES_REQUEST); return true; @@ -4767,7 +4765,11 @@ static void pe_vdm_identity_request_cbl_entry(int port) print_current_state(port); - if (!tc_is_vconn_src(port)) { + if (!pe_can_send_sop_prime(port)) { + /* + * The parent state already tried to enable SOP' traffic. If it + * is still disabled, there's nothing left to try. + */ pd_set_identity_discovery(port, pe[port].tx_type, PD_DISC_FAIL); set_state_pe(port, get_last_state_pe(port)); return; @@ -5035,7 +5037,11 @@ static void pe_init_vdm_svids_request_entry(int port) print_current_state(port); if (pe[port].tx_type == TCPC_TX_SOP_PRIME && - !tc_is_vconn_src(port)) { + !pe_can_send_sop_prime(port)) { + /* + * The parent state already tried to enable SOP' traffic. If it + * is still disabled, there's nothing left to try. + */ pd_set_svids_discovery(port, pe[port].tx_type, PD_DISC_FAIL); set_state_pe(port, get_last_state_pe(port)); return; @@ -5133,7 +5139,11 @@ static void pe_init_vdm_modes_request_entry(int port) print_current_state(port); if (pe[port].tx_type == TCPC_TX_SOP_PRIME && - !tc_is_vconn_src(port)) { + !pe_can_send_sop_prime(port)) { + /* + * The parent state already tried to enable SOP' traffic. If it + * is still disabled, there's nothing left to try. + */ pd_set_modes_discovery(port, pe[port].tx_type, svid, PD_DISC_FAIL); set_state_pe(port, get_last_state_pe(port)); @@ -5230,7 +5240,11 @@ static void pe_vdm_request_dpm_entry(int port) if ((pe[port].tx_type == TCPC_TX_SOP_PRIME || pe[port].tx_type == TCPC_TX_SOP_PRIME_PRIME) && - !tc_is_vconn_src(port)) { + !pe_can_send_sop_prime(port)) { + /* + * The parent state already tried to enable SOP' traffic. If it + * is still disabled, there's nothing left to try. + */ dpm_vdm_naked(port, pe[port].tx_type, PD_VDO_VID(pe[port].vdm_data[0]), PD_VDO_CMD(pe[port].vdm_data[0])); diff --git a/include/mock/usb_tc_sm_mock.h b/include/mock/usb_tc_sm_mock.h index beefa40c74..f5c599ca1f 100644 --- a/include/mock/usb_tc_sm_mock.h +++ b/include/mock/usb_tc_sm_mock.h @@ -19,6 +19,7 @@ struct mock_tc_port_t { enum tcpc_rp_value lcl_rp; int attached_snk; int attached_src; + bool vconn_src; }; extern struct mock_tc_port_t mock_tc_port[CONFIG_USB_PD_PORT_MAX_COUNT]; diff --git a/test/usb_pe_drp.c b/test/usb_pe_drp.c index 8c59dcf180..f780834612 100644 --- a/test/usb_pe_drp.c +++ b/test/usb_pe_drp.c @@ -54,6 +54,7 @@ test_static int test_send_caps_error(void) /* Enable PE as source, expect SOURCE_CAP. */ mock_pd_port[PORT0].power_role = PD_ROLE_SOURCE; mock_tc_port[PORT0].pd_enable = 1; + mock_tc_port[PORT0].vconn_src = true; task_wait_event(10 * MSEC); TEST_EQ(fake_prl_get_last_sent_data_msg_type(PORT0), PD_DATA_SOURCE_CAP, "%d"); -- cgit v1.2.1