1 From afb92ad8733ef0a2843cc229e4d96aead80bc429 Mon Sep 17 00:00:00 2001
2 From: Amit Sunil Dhamne <amitsd@google.com>
3 Date: Wed, 23 Oct 2024 19:22:30 -0700
4 Subject: usb: typec: tcpm: restrict SNK_WAIT_CAPABILITIES_TIMEOUT transitions to non self-powered devices
6 From: Amit Sunil Dhamne <amitsd@google.com>
8 commit afb92ad8733ef0a2843cc229e4d96aead80bc429 upstream.
10 PD3.1 spec ("8.3.3.3.3 PE_SNK_Wait_for_Capabilities State") mandates
11 that the policy engine perform a hard reset when SinkWaitCapTimer
12 expires. Instead the code explicitly does a GET_SOURCE_CAP when the
13 timer expires as part of SNK_WAIT_CAPABILITIES_TIMEOUT. Due to this the
14 following compliance test failures are reported by the compliance tester
15 (added excerpts from the PD Test Spec):
18 The Tester receives a Get_Source_Cap Message from the UUT. This
19 message is valid except the following conditions: [COMMON.PROC.PD.2#1]
20 a. The check fails if the UUT sends this message before the Tester
21 has established an Explicit Contract
26 4. The check fails if the UUT does not send a Hard Reset between
27 tTypeCSinkWaitCap min and max. [TEST.PD.PROT.SNK.4#1] The delay is
28 between the VBUS present vSafe5V min and the time of the first bit
29 of Preamble of the Hard Reset sent by the UUT.
31 For the purpose of interoperability, restrict the quirk introduced in
32 https://lore.kernel.org/all/20240523171806.223727-1-sebastian.reichel@collabora.com/
33 to only non self-powered devices as battery powered devices will not
34 have the issue mentioned in that commit.
36 Cc: stable@vger.kernel.org
37 Fixes: 122968f8dda8 ("usb: typec: tcpm: avoid resets for missing source capability messages")
38 Reported-by: Badhri Jagan Sridharan <badhri@google.com>
39 Closes: https://lore.kernel.org/all/CAPTae5LAwsVugb0dxuKLHFqncjeZeJ785nkY4Jfd+M-tCjHSnQ@mail.gmail.com/
40 Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
41 Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
42 Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
43 Tested-by: Xu Yang <xu.yang_2@nxp.com>
44 Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
45 Link: https://lore.kernel.org/r/20241024022233.3276995-1-amitsd@google.com
46 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
48 drivers/usb/typec/tcpm/tcpm.c | 10 +++++++---
49 1 file changed, 7 insertions(+), 3 deletions(-)
51 diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
52 index fc619478200f..7ae341a40342 100644
53 --- a/drivers/usb/typec/tcpm/tcpm.c
54 +++ b/drivers/usb/typec/tcpm/tcpm.c
55 @@ -4515,7 +4515,8 @@ static inline enum tcpm_state hard_reset_state(struct tcpm_port *port)
56 return ERROR_RECOVERY;
57 if (port->pwr_role == TYPEC_SOURCE)
58 return SRC_UNATTACHED;
59 - if (port->state == SNK_WAIT_CAPABILITIES_TIMEOUT)
60 + if (port->state == SNK_WAIT_CAPABILITIES ||
61 + port->state == SNK_WAIT_CAPABILITIES_TIMEOUT)
63 return SNK_UNATTACHED;
65 @@ -5043,8 +5044,11 @@ static void run_state_machine(struct tcpm_port *port)
66 tcpm_set_state(port, SNK_SOFT_RESET,
69 - tcpm_set_state(port, SNK_WAIT_CAPABILITIES_TIMEOUT,
70 - PD_T_SINK_WAIT_CAP);
71 + if (!port->self_powered)
72 + upcoming_state = SNK_WAIT_CAPABILITIES_TIMEOUT;
74 + upcoming_state = hard_reset_state(port);
75 + tcpm_set_state(port, upcoming_state, PD_T_SINK_WAIT_CAP);
78 case SNK_WAIT_CAPABILITIES_TIMEOUT: