From 7f8843dfaa31f3748ba4c5c8be052e2ecdc79f04 Mon Sep 17 00:00:00 2001 From: Diana Z Date: Mon, 2 Mar 2020 16:30:50 -0700 Subject: TCPMv2: Probe cable identity from Ready states Cable identity may be probed from the SRC_Ready and SNK_Ready states when a port is: - Vconn source - DFP (for PD 2.0) This change adds probing to the ready states in these conditions. Additionally, it down-revs the cable revision when sinking and the port partner is PD 2.0. BRANCH=None BUG=b:148834626 TEST=On kindred, verified: 1. When sourcing: a. partner with no e-marker is probed no more than 20 times between discovery probing and ready b. cable which was not probed in discovery is probed in ready 2. When sinking: a. no probing when partner does not allow us to Vconn source b. probing takes place once chromebook is DFP/Vconn source with PD 2.0 partner Signed-off-by: Diana Z Change-Id: I27da70e324d617ad4d30285554a8cd3c0e5db3e5 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2084013 Reviewed-by: Jett Rink --- common/usbc/usb_pe_drp_sm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index f9647f5715..d1e1b6bc56 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -653,6 +653,33 @@ static void pe_invalidate_explicit_contract(int port) PE_CLR_FLAG(port, PE_FLAGS_EXPLICIT_CONTRACT); } +/* + * Determine if this port may communicate with the cable plug. + * + * In both PD 2.0 and 3.0 (2.5.4 SOP'/SOP'' Communication with Cable Plugs): + * + * When no Contract or an Implicit Contract is in place (e.g. after a Power Role + * Swap or Fast Role Swap) only the Source port that is supplying Vconn is + * allowed to send packets to a Cable Plug + * + * When in an explicit contract, PD 3.0 requires that a port be Vconn source to + * communicate with the cable. PD 2.0 requires that a port be DFP to + * communicate with the cable plug, with an implication that it must be Vconn + * source as well (6.3.11 VCONN_Swap Message). + */ +static bool pe_can_send_sop_prime(int port) +{ + if (PE_CHK_FLAG(port, PE_FLAGS_EXPLICIT_CONTRACT)) + if (prl_get_rev(port, TCPC_TX_SOP) == PD_REV20) + return tc_is_vconn_src(port) && + pe[port].data_role == PD_ROLE_DFP; + else + return tc_is_vconn_src(port); + else + return tc_is_vconn_src(port) && + pe[port].power_role == PD_ROLE_SOURCE; +} + void pe_report_error(int port, enum pe_error e) { /* This should only be called from the PD task */ @@ -1226,7 +1253,8 @@ static void pe_src_discovery_run(int port) * requests properly. */ if (pe[port].cable.discovery == PD_DISC_NEEDED && - get_time().val > pe[port].discover_port_identity_timer) { + get_time().val > pe[port].discover_port_identity_timer && + pe_can_send_sop_prime(port)) { set_state_pe(port, PE_VDM_IDENTITY_REQUEST_CBL); return; } @@ -1559,6 +1587,13 @@ static void pe_src_ready_run(int port) PE_CLR_FLAG(port, PE_FLAGS_FIRST_MSG); pe[port].wait_and_add_jitter_timer = TIMER_DISABLED; + if (pe[port].cable.discovery == PD_DISC_NEEDED && + get_time().val > pe[port].discover_port_identity_timer && + pe_can_send_sop_prime(port)) { + set_state_pe(port, PE_VDM_IDENTITY_REQUEST_CBL); + return; + } + /* * Start Port Discovery when: * 1) The DiscoverIdentityTimer times out. @@ -2012,6 +2047,13 @@ static void pe_snk_evaluate_capability_entry(int port) prl_set_rev(port, TCPC_TX_SOP, (PD_HEADER_REV(header) > PD_REV30) ? PD_REV30 : PD_HEADER_REV(header)); + /* + * If port partner runs PD 2.0, cable communication must + * also be PD 2.0 + */ + if (prl_get_rev(port, TCPC_TX_SOP) == PD_REV20) + prl_set_rev(port, TCPC_TX_SOP_PRIME, PD_REV20); + pe[port].src_cap_cnt = num; for (i = 0; i < num; i++) @@ -2282,6 +2324,13 @@ static void pe_snk_ready_run(int port) return; } + if (pe[port].cable.discovery == PD_DISC_NEEDED && + get_time().val > pe[port].discover_port_identity_timer && + pe_can_send_sop_prime(port)) { + set_state_pe(port, PE_VDM_IDENTITY_REQUEST_CBL); + return; + } + /* * Start Port Discovery when: * 1) The PortDiscoverIdentityTimer times out. -- cgit v1.2.1