All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mika Westerberg <mika.westerberg@linux.intel.com>
To: Sven Peter <sven@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Janne Grunau <j@jannau.net>, Neal Gompa <neal@gompa.dev>,
	Andreas Noever <andreas.noever@gmail.com>,
	Mika Westerberg <westeri@kernel.org>,
	Yehezkel Bernat <YehezkelShB@gmail.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	Konrad Dybcio <konradybcio@kernel.org>,
	linux-usb@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, asahi@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 14/19] thunderbolt: Add QUIRK_NO_USB3_BW_ALLOC
Date: Tue, 1 Sep 2026 11:12:05 +0200	[thread overview]
Message-ID: <20260901091205.GE106095@black.igk.intel.com> (raw)
In-Reply-To: <20260830-b4-apple-soc-tbt-v1-14-44bc9348683c@kernel.org>

Hi,

On Sun, Aug 30, 2026 at 10:19:32PM +0200, Sven Peter wrote:
> The host routers on Apple Silicon do not implement USB3 bandwidth
> allocation registers: the CMR bit set in ADP_USB3_CS_2 by
> usb4_usb3_port_cm_request() is never acknowledged and every USB3 tunnel
> bringup fails there after the timeout:
> 
>   [   49.259325] thunderbolt-apple-nhi 501f00000.nhi: 1:16: available bandwidth for new USB3 tunnel 18000/18000 Mb/s
>   [   49.265869] thunderbolt-apple-nhi 501f00000.nhi: 1:16: maximum required bandwidth for USB3 tunnel 9000 Mb/s
>   [   49.267894] thunderbolt-apple-nhi 501f00000.nhi: 0:4 <-> 1:16 (USB3): activating
>   [   49.269410] thunderbolt-apple-nhi 501f00000.nhi: 0:4 <-> 1:16 (USB3): allocating initial bandwidth 9000/9000 Mb/s
>   [   50.771764] thunderbolt-apple-nhi 501f00000.nhi: 1:16: USB3 tunnel activation failed, aborting

Okay this kind of makes sense. Apple is doing this only via software and
this is also what Linux needs to do with USB3 Gen T tunneling so we should
prepare for this.

> Add a quirk to skip bandwidth allocation entirely but keep tracking
> the initial allocation in software for the consumed bandwidth
> calculation. For completeness, discovered tunnels book 90% of the
> maximum link rate in software, matching tb_tunnel_alloc_usb3(), although
> Apple Silicon cannot have any pre-existing tunnels.
> 
> Signed-off-by: Sven Peter <sven@kernel.org>
> ---
>  drivers/thunderbolt/nhi.h    |  1 +
>  drivers/thunderbolt/tb.c     |  8 ++++++
>  drivers/thunderbolt/tb.h     |  3 +++
>  drivers/thunderbolt/tunnel.c | 59 +++++++++++++++++++++++++++++---------------
>  4 files changed, 51 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
> index c2d16ab6994e..afd9a11489a9 100644
> --- a/drivers/thunderbolt/nhi.h
> +++ b/drivers/thunderbolt/nhi.h
> @@ -169,6 +169,7 @@ struct tb_nhi_ops {
>  #define QUIRK_E2E					BIT(1)
>  #define QUIRK_RESET_DMA_ON_TEARDOWN			BIT(2)
>  #define QUIRK_NO_DMA_PORT				BIT(3)
> +#define QUIRK_NO_USB3_BW_ALLOC				BIT(4)

This is not NHI thing but lives inside the USB4 domain so the quirk should
end up in drivers/thunderbolt/quirks.c.

For now I think that's enough but in the future we should provide software
mechanism that takes over the hardware if present, and then get rid of the
quirk alltogether.

>  /*
>   * Minimal number of vectors when we use MSI-X. Two for control channel
> diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
> index c43cdd2c2e2e..7ab53a30fe30 100644
> --- a/drivers/thunderbolt/tb.c
> +++ b/drivers/thunderbolt/tb.c
> @@ -3044,6 +3044,14 @@ static int tb_start(struct tb *tb, bool reset)
>  	 */
>  	tb->root_switch->no_dma_port = tb->nhi->quirks & QUIRK_NO_DMA_PORT;
>  
> +	/*
> +	 * Apple Silicon host routers do not implement the USB3 bandwidth
> +	 * allocation registers: the CMR/HCA handshake is never acked and
> +	 * times out. Bandwidth for USB3 tunnels is only booked in software
> +	 * on these machines.
> +	 */
> +	tb->root_switch->no_usb3_bw_alloc = tb->nhi->quirks & QUIRK_NO_USB3_BW_ALLOC;
> +
>  	ret = tb_switch_configure(tb->root_switch);
>  	if (ret) {
>  		tb_switch_put(tb->root_switch);
> diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
> index 0977cd690d7e..530b0e6c3a11 100644
> --- a/drivers/thunderbolt/tb.h
> +++ b/drivers/thunderbolt/tb.h
> @@ -140,6 +140,8 @@ struct tb_switch_tmu {
>   * @nvm: Pointer to the NVM if the switch has one (%NULL otherwise)
>   * @no_nvm_upgrade: Prevent NVM upgrade of this switch
>   * @no_dma_port: Prevent adding the DMA port of this switch
> + * @no_usb3_bw_alloc: Host router does not implement the USB3 bandwidth
> + *		      allocation registers (ADP_USB3_CS_1..4)
>   * @safe_mode: The switch is in safe-mode
>   * @boot: Whether the switch was already authorized on boot or not
>   * @rpm: The switch supports runtime PM
> @@ -196,6 +198,7 @@ struct tb_switch {
>  	struct tb_nvm *nvm;
>  	bool no_nvm_upgrade;
>  	bool no_dma_port;
> +	bool no_usb3_bw_alloc;
>  	bool safe_mode;
>  	bool boot;
>  	bool rpm;
> diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c
> index 7e8284575dff..9178120a6b66 100644
> --- a/drivers/thunderbolt/tunnel.c
> +++ b/drivers/thunderbolt/tunnel.c
> @@ -2268,24 +2268,40 @@ struct tb_tunnel *tb_tunnel_discover_usb3(struct tb *tb, struct tb_port *down,
>  	if (!tb_route(down->sw)) {
>  		int ret;
>  
> -		/*
> -		 * Read the initial bandwidth allocation for the first
> -		 * hop tunnel.
> -		 */
> -		ret = usb4_usb3_port_allocated_bandwidth(down,
> -			&tunnel->allocated_up, &tunnel->allocated_down);
> -		if (ret)
> -			goto err_deactivate;
> +		tunnel->consumed_bandwidth = tb_usb3_consumed_bandwidth;
> +
> +		if (down->sw->no_usb3_bw_alloc) {
> +			/*
> +			 * The host router does not implement the bandwidth
> +			 * allocation registers and nothing can be read back
> +			 * here. Book 90% of the maximum link rate in software
> +			 * instead.
> +			 */
> +			ret = tb_usb3_max_link_rate(tunnel->dst_port, down);
> +			if (ret < 0)
> +				goto err_deactivate;
> +
> +			tunnel->allocated_up = ret * 90 / 100;
> +			tunnel->allocated_down = tunnel->allocated_up;
> +		} else {
> +			/*
> +			 * Read the initial bandwidth allocation for the first
> +			 * hop tunnel.
> +			 */
> +			ret = usb4_usb3_port_allocated_bandwidth(down,
> +				&tunnel->allocated_up, &tunnel->allocated_down);
> +			if (ret)
> +				goto err_deactivate;
> +
> +			tunnel->pre_activate = tb_usb3_pre_activate;
> +			tunnel->release_unused_bandwidth =
> +				tb_usb3_release_unused_bandwidth;
> +			tunnel->reclaim_available_bandwidth =
> +				tb_usb3_reclaim_available_bandwidth;
> +		}
>  
>  		tb_tunnel_dbg(tunnel, "currently allocated bandwidth %d/%d Mb/s\n",
>  			      tunnel->allocated_up, tunnel->allocated_down);
> -
> -		tunnel->pre_activate = tb_usb3_pre_activate;
> -		tunnel->consumed_bandwidth = tb_usb3_consumed_bandwidth;
> -		tunnel->release_unused_bandwidth =
> -			tb_usb3_release_unused_bandwidth;
> -		tunnel->reclaim_available_bandwidth =
> -			tb_usb3_reclaim_available_bandwidth;
>  	}
>  
>  	tb_tunnel_dbg(tunnel, "discovered\n");
> @@ -2365,12 +2381,15 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up,
>  		tunnel->allocated_up = min(max_rate, max_up);
>  		tunnel->allocated_down = min(max_rate, max_down);
>  
> -		tunnel->pre_activate = tb_usb3_pre_activate;
>  		tunnel->consumed_bandwidth = tb_usb3_consumed_bandwidth;
> -		tunnel->release_unused_bandwidth =
> -			tb_usb3_release_unused_bandwidth;
> -		tunnel->reclaim_available_bandwidth =
> -			tb_usb3_reclaim_available_bandwidth;
> +
> +		if (!down->sw->no_usb3_bw_alloc) {
> +			tunnel->pre_activate = tb_usb3_pre_activate;
> +			tunnel->release_unused_bandwidth =
> +				tb_usb3_release_unused_bandwidth;
> +			tunnel->reclaim_available_bandwidth =
> +				tb_usb3_reclaim_available_bandwidth;
> +		}
>  	}
>  
>  	return tunnel;
> 
> -- 
> 2.55.0
> 

  reply	other threads:[~2026-09-01  9:12 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-30 20:19 [PATCH 00/19] Initial USB4/Thunderbolt support for Apple M1/M2/M3 SoCs Sven Peter
2026-08-30 20:19 ` [PATCH 01/19] dt-bindings: usb: Add thunderbolt-switch property Sven Peter
2026-08-30 20:19 ` [PATCH 02/19] usb: typec: Add thunderbolt switch Sven Peter
2026-08-30 20:30   ` sashiko-bot
2026-09-01 11:17   ` Heikki Krogerus
2026-09-01 18:53     ` Sven Peter
2026-08-30 20:19 ` [PATCH 03/19] usb: typec: tipd: Hook up Thunderbolt switch for CD321x Sven Peter
2026-08-30 20:36   ` sashiko-bot
2026-08-30 20:19 ` [PATCH 04/19] dt-bindings: thunderbolt: Add Apple USB4/Thunderbolt NHI Sven Peter
2026-08-30 20:19 ` [PATCH 05/19] dt-bindings: thunderbolt: Add Apple USB4/Thunderbolt ACIO block Sven Peter
2026-08-30 20:31   ` sashiko-bot
2026-08-30 20:19 ` [PATCH 06/19] thunderbolt: Try reading host DROM from device tree first Sven Peter
2026-08-30 20:33   ` sashiko-bot
2026-09-01  8:48   ` Mika Westerberg
2026-08-30 20:19 ` [PATCH 07/19] thunderbolt: Don't read the UID if we already know it Sven Peter
2026-08-30 20:19 ` [PATCH 08/19] thunderbolt: Allocate ring HopID before requesting the ring interrupt Sven Peter
2026-08-30 20:32   ` sashiko-bot
2026-08-30 20:19 ` [PATCH 09/19] thunderbolt: Add ring_interrupt_active to tb_nhi_ops Sven Peter
2026-08-30 20:19 ` [PATCH 10/19] thunderbolt: Make the ring register layout configurable Sven Peter
2026-09-01  8:58   ` Mika Westerberg
2026-09-01 18:56     ` Sven Peter
2026-08-30 20:19 ` [PATCH 11/19] thunderbolt: Add ring_interrupt_mask to tb_nhi_ops Sven Peter
2026-08-30 20:19 ` [PATCH 12/19] thunderbolt: Add ring_configure " Sven Peter
2026-08-30 20:28   ` sashiko-bot
2026-08-30 20:19 ` [PATCH 13/19] thunderbolt: Add QUIRK_NO_DMA_PORT Sven Peter
2026-09-01  9:04   ` Mika Westerberg
2026-09-01 17:06     ` Sven Peter
2026-08-30 20:19 ` [PATCH 14/19] thunderbolt: Add QUIRK_NO_USB3_BW_ALLOC Sven Peter
2026-09-01  9:12   ` Mika Westerberg [this message]
2026-08-30 20:19 ` [PATCH 15/19] thunderbolt: Export symbols required by the Apple Silicon driver Sven Peter
2026-08-30 20:19 ` [PATCH 16/19] thunderbolt: Add Apple Silicon support Sven Peter
2026-08-30 20:39   ` sashiko-bot
2026-09-01 10:09   ` Mika Westerberg
2026-09-01 19:06     ` Sven Peter
2026-08-30 20:19 ` [PATCH 17/19] arm64: dts: apple: t8103: Add USB4 ACIO and NHI Sven Peter
2026-09-01 10:20   ` Mika Westerberg
2026-08-30 20:19 ` [PATCH 18/19] arm64: dts: apple: t8112: " Sven Peter
2026-08-30 20:39   ` sashiko-bot
2026-08-30 20:19 ` [PATCH 19/19] arm64: dts: apple: t60xx: " Sven Peter
2026-08-31 17:44 ` [PATCH 00/19] Initial USB4/Thunderbolt support for Apple M1/M2/M3 SoCs Joshua Peisach

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260901091205.GE106095@black.igk.intel.com \
    --to=mika.westerberg@linux.intel.com \
    --cc=YehezkelShB@gmail.com \
    --cc=andreas.noever@gmail.com \
    --cc=asahi@lists.linux.dev \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=j@jannau.net \
    --cc=konradybcio@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=neal@gompa.dev \
    --cc=p.zabel@pengutronix.de \
    --cc=robh@kernel.org \
    --cc=sven@kernel.org \
    --cc=westeri@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.