* [PATCH] usb: typec: fusb302: Drop unacknowledged Get_Source_Cap_Extended
@ 2026-11-02 13:09 Alexey Charkov
2026-11-06 12:38 ` Heikki Krogerus
0 siblings, 1 reply; 4+ messages in thread
From: Alexey Charkov @ 2026-11-02 13:09 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman
Cc: Sebastian Reichel, linux-usb, linux-kernel, Alexey Charkov
The chip mistakes Get_Source_Cap_Extended for a GoodCRC, as it apparently
decodes only the low four bits of the message type. As a result, it sends
no GoodCRC for it, but still queues it in the RX FIFO. The partner never
sees the message as delivered due to no GoodCRC, so it retries and then
sends a Soft_Reset. When FUSB302 receives the Soft_Reset, it finally
raises its interrupt, at which point TCPM sees Get_Source_Cap_Extended in
the RX FIFO instead of the Soft_Reset it just received, and answers it
Not_Supported, which is not a valid reply to Soft_Reset, so the partner
escalates to a hard reset instead of getting a chance to gracefully handle
a lost Get_Source_Cap_Extended.
Discard Get_Source_Cap_Extended, which FUSB302 can never properly receive
due to its inability to automatically GoodCRC it, and answering it from
the host within the protocol specified 250us window without so much as an
interrupt cannot be made to work.
This way the TCPM view of the PD exchange at least matches what the
partner saw on the wire. This lets the TCPM complete a PD negotiation over
the FUSB302 with e.g. an Apple Studio Display, which otherwise always ends
in hard resets.
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
drivers/usb/typec/tcpm/fusb302.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
index 3319f6a2b0c9..96dc48250d6a 100644
--- a/drivers/usb/typec/tcpm/fusb302.c
+++ b/drivers/usb/typec/tcpm/fusb302.c
@@ -1463,6 +1463,19 @@ static int fusb302_pd_read_message(struct fusb302_chip *chip,
fusb302_log(chip, "PD message header: %x", msg->header);
fusb302_log(chip, "PD message len: %d", len);
+ /*
+ * The chip only decodes the low four bits of the message type, so it
+ * mistakes Get_Source_Cap_Extended (17) for a GoodCRC (1): it neither
+ * acknowledges it nor raises GCRCSENT, yet still queues it in the RX
+ * FIFO. Without a GoodCRC the partner never considers it delivered and
+ * will retry and then soft reset, so it must not be answered.
+ */
+ if ((!len) &&
+ (pd_header_type_le(msg->header) == PD_CTRL_GET_SOURCE_CAP_EXT)) {
+ fusb302_log(chip, "dropping unacknowledged PD message");
+ return ret;
+ }
+
/*
* Check if we've read off a GoodCRC message. If so then indicate to
* TCPM that the previous transmission has completed. Otherwise we pass
---
base-commit: 7649ba73f9e7e1e04d0b46213e39c79ae09dd55c
change-id: 20261102-fusb302-getsourcecap-01c38dccb230
Best regards,
--
Alexey Charkov <alchark@flipper.net>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] usb: typec: fusb302: Drop unacknowledged Get_Source_Cap_Extended
2026-11-02 13:09 [PATCH] usb: typec: fusb302: Drop unacknowledged Get_Source_Cap_Extended Alexey Charkov
@ 2026-11-06 12:38 ` Heikki Krogerus
2026-11-10 6:48 ` Alexey Charkov
0 siblings, 1 reply; 4+ messages in thread
From: Heikki Krogerus @ 2026-11-06 12:38 UTC (permalink / raw)
To: Alexey Charkov
Cc: Greg Kroah-Hartman, Sebastian Reichel, linux-usb, linux-kernel
On Mon, Nov 02, 2026 at 05:09:05PM +0400, Alexey Charkov wrote:
> The chip mistakes Get_Source_Cap_Extended for a GoodCRC, as it apparently
> decodes only the low four bits of the message type. As a result, it sends
> no GoodCRC for it, but still queues it in the RX FIFO. The partner never
> sees the message as delivered due to no GoodCRC, so it retries and then
> sends a Soft_Reset. When FUSB302 receives the Soft_Reset, it finally
> raises its interrupt, at which point TCPM sees Get_Source_Cap_Extended in
> the RX FIFO instead of the Soft_Reset it just received, and answers it
> Not_Supported, which is not a valid reply to Soft_Reset, so the partner
> escalates to a hard reset instead of getting a chance to gracefully handle
> a lost Get_Source_Cap_Extended.
>
> Discard Get_Source_Cap_Extended, which FUSB302 can never properly receive
> due to its inability to automatically GoodCRC it, and answering it from
> the host within the protocol specified 250us window without so much as an
> interrupt cannot be made to work.
>
> This way the TCPM view of the PD exchange at least matches what the
> partner saw on the wire. This lets the TCPM complete a PD negotiation over
> the FUSB302 with e.g. an Apple Studio Display, which otherwise always ends
> in hard resets.
>
> Signed-off-by: Alexey Charkov <alchark@flipper.net>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> ---
> drivers/usb/typec/tcpm/fusb302.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
> index 3319f6a2b0c9..96dc48250d6a 100644
> --- a/drivers/usb/typec/tcpm/fusb302.c
> +++ b/drivers/usb/typec/tcpm/fusb302.c
> @@ -1463,6 +1463,19 @@ static int fusb302_pd_read_message(struct fusb302_chip *chip,
> fusb302_log(chip, "PD message header: %x", msg->header);
> fusb302_log(chip, "PD message len: %d", len);
>
> + /*
> + * The chip only decodes the low four bits of the message type, so it
> + * mistakes Get_Source_Cap_Extended (17) for a GoodCRC (1): it neither
> + * acknowledges it nor raises GCRCSENT, yet still queues it in the RX
> + * FIFO. Without a GoodCRC the partner never considers it delivered and
> + * will retry and then soft reset, so it must not be answered.
> + */
> + if ((!len) &&
> + (pd_header_type_le(msg->header) == PD_CTRL_GET_SOURCE_CAP_EXT)) {
> + fusb302_log(chip, "dropping unacknowledged PD message");
> + return ret;
> + }
> +
> /*
> * Check if we've read off a GoodCRC message. If so then indicate to
> * TCPM that the previous transmission has completed. Otherwise we pass
>
> ---
> base-commit: 7649ba73f9e7e1e04d0b46213e39c79ae09dd55c
> change-id: 20261102-fusb302-getsourcecap-01c38dccb230
>
> Best regards,
> --
> Alexey Charkov <alchark@flipper.net>
--
heikki
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] usb: typec: fusb302: Drop unacknowledged Get_Source_Cap_Extended
2026-11-06 12:38 ` Heikki Krogerus
@ 2026-11-10 6:48 ` Alexey Charkov
2026-11-11 14:37 ` Heikki Krogerus
0 siblings, 1 reply; 4+ messages in thread
From: Alexey Charkov @ 2026-11-10 6:48 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Greg Kroah-Hartman, Sebastian Reichel, linux-usb, linux-kernel
On Fri, Nov 6, 2026 at 4:39 PM Heikki Krogerus
<heikki.krogerus@linux.intel.com> wrote:
>
> On Mon, Nov 02, 2026 at 05:09:05PM +0400, Alexey Charkov wrote:
> > The chip mistakes Get_Source_Cap_Extended for a GoodCRC, as it apparently
> > decodes only the low four bits of the message type. As a result, it sends
> > no GoodCRC for it, but still queues it in the RX FIFO. The partner never
> > sees the message as delivered due to no GoodCRC, so it retries and then
> > sends a Soft_Reset. When FUSB302 receives the Soft_Reset, it finally
> > raises its interrupt, at which point TCPM sees Get_Source_Cap_Extended in
> > the RX FIFO instead of the Soft_Reset it just received, and answers it
> > Not_Supported, which is not a valid reply to Soft_Reset, so the partner
> > escalates to a hard reset instead of getting a chance to gracefully handle
> > a lost Get_Source_Cap_Extended.
> >
> > Discard Get_Source_Cap_Extended, which FUSB302 can never properly receive
> > due to its inability to automatically GoodCRC it, and answering it from
> > the host within the protocol specified 250us window without so much as an
> > interrupt cannot be made to work.
> >
> > This way the TCPM view of the PD exchange at least matches what the
> > partner saw on the wire. This lets the TCPM complete a PD negotiation over
> > the FUSB302 with e.g. an Apple Studio Display, which otherwise always ends
> > in hard resets.
> >
> > Signed-off-by: Alexey Charkov <alchark@flipper.net>
>
> Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Thanks for acking it Heikki, but let's please hold off applying this
patch. My colleagues have done broader testing with Apple hardware.
While this patch prevents hard reset loops and lets TCPM negotiate a
PD contract, it can't yet complete Alt Modes negotiation in PD 3.0.
I've done another attempt locally to send GoodCRC from the driver
instead of discarding Get_Source_Cap_Extended altogether. It lands
wildly out of spec timing wise (close to 2ms vs. the spec-prescribed
250us to start transmitting GoodCRC on the wire). However, it works by
sheer luck because the partner waits up to 1ms for a GoodCRC and
retries the message with the same ID up to 3 times, so the first
GoodCRC lands in the window of the second or third retry and gets
accepted. Everyone is happy, and the negotiation completes just fine.
It's a bit more invasive for the driver, though (as can be expected),
and relies heavily on the bus speed being at least 400 kHz (FUSB302
can do up to 1 MHz) and not a single extra I2C transaction being added
in the timing-critical path before the GoodCRC goes out. I'll send it
for review separately, and if it proves palatable, it will supersede
this patch.
Best regards,
Alexey
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] usb: typec: fusb302: Drop unacknowledged Get_Source_Cap_Extended
2026-11-10 6:48 ` Alexey Charkov
@ 2026-11-11 14:37 ` Heikki Krogerus
0 siblings, 0 replies; 4+ messages in thread
From: Heikki Krogerus @ 2026-11-11 14:37 UTC (permalink / raw)
To: Alexey Charkov
Cc: Greg Kroah-Hartman, Sebastian Reichel, linux-usb, linux-kernel
On Tue, Nov 10, 2026 at 10:48:46AM +0400, Alexey Charkov wrote:
> On Fri, Nov 6, 2026 at 4:39 PM Heikki Krogerus
> <heikki.krogerus@linux.intel.com> wrote:
> >
> > On Mon, Nov 02, 2026 at 05:09:05PM +0400, Alexey Charkov wrote:
> > > The chip mistakes Get_Source_Cap_Extended for a GoodCRC, as it apparently
> > > decodes only the low four bits of the message type. As a result, it sends
> > > no GoodCRC for it, but still queues it in the RX FIFO. The partner never
> > > sees the message as delivered due to no GoodCRC, so it retries and then
> > > sends a Soft_Reset. When FUSB302 receives the Soft_Reset, it finally
> > > raises its interrupt, at which point TCPM sees Get_Source_Cap_Extended in
> > > the RX FIFO instead of the Soft_Reset it just received, and answers it
> > > Not_Supported, which is not a valid reply to Soft_Reset, so the partner
> > > escalates to a hard reset instead of getting a chance to gracefully handle
> > > a lost Get_Source_Cap_Extended.
> > >
> > > Discard Get_Source_Cap_Extended, which FUSB302 can never properly receive
> > > due to its inability to automatically GoodCRC it, and answering it from
> > > the host within the protocol specified 250us window without so much as an
> > > interrupt cannot be made to work.
> > >
> > > This way the TCPM view of the PD exchange at least matches what the
> > > partner saw on the wire. This lets the TCPM complete a PD negotiation over
> > > the FUSB302 with e.g. an Apple Studio Display, which otherwise always ends
> > > in hard resets.
> > >
> > > Signed-off-by: Alexey Charkov <alchark@flipper.net>
> >
> > Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
>
> Thanks for acking it Heikki, but let's please hold off applying this
> patch. My colleagues have done broader testing with Apple hardware.
> While this patch prevents hard reset loops and lets TCPM negotiate a
> PD contract, it can't yet complete Alt Modes negotiation in PD 3.0.
>
> I've done another attempt locally to send GoodCRC from the driver
> instead of discarding Get_Source_Cap_Extended altogether. It lands
> wildly out of spec timing wise (close to 2ms vs. the spec-prescribed
> 250us to start transmitting GoodCRC on the wire). However, it works by
> sheer luck because the partner waits up to 1ms for a GoodCRC and
> retries the message with the same ID up to 3 times, so the first
> GoodCRC lands in the window of the second or third retry and gets
> accepted. Everyone is happy, and the negotiation completes just fine.
>
> It's a bit more invasive for the driver, though (as can be expected),
> and relies heavily on the bus speed being at least 400 kHz (FUSB302
> can do up to 1 MHz) and not a single extra I2C transaction being added
> in the timing-critical path before the GoodCRC goes out. I'll send it
> for review separately, and if it proves palatable, it will supersede
> this patch.
Okay, thanks for the explanation.
--
heikki
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-11 14:37 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-02 13:09 [PATCH] usb: typec: fusb302: Drop unacknowledged Get_Source_Cap_Extended Alexey Charkov
2026-11-06 12:38 ` Heikki Krogerus
2026-11-10 6:48 ` Alexey Charkov
2026-11-11 14:37 ` Heikki Krogerus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®