Brad reported that on Apple hardware with Light Ridge or Falcon Ridge
controller, plugging in a chain of Thunderbolt displays (Light Ridge
based controllers) causes all kinds of tearing and flickering. The
reason for this is that on Thunderbolt 1 hardware there is no lane
bonding so we have two independent 10 Gb/s lanes, and currently Linux
tunnels both displays through the lane 1. This makes the displays to
share the 10 Gb/s bandwidth which may not be enough for higher
resolutions.
For this reason make the second tunnel go through the lane 0 instead.
This seems to match what the macOS connection manager is also doing.
Reported-by: Brad Campbell <lists2009@fnarfbargle.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Brad Campbell <lists2009@fnarfbargle.com>
Intel Titan Ridge does not disable AUX timers when it gets SET_CONFIG
with SET_LTTPR_MODE set which makes DP tunneling to fail. For this
reason disable LTTPR on Titan Ridge device side.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
If the boot firmware implements connection manager of its own it may not
create the paths in the same way or order we do. For example it may
create first PCIe tunnel and then USB3 tunnel. When we restore our
tunnels (first de-activating them) we may be doing that over completely
different tunnels and that leaves them possibly non-functional. For this
reason we re-use the tunnel discovery functionality and find out all the
existing tunnels, and tear them down. Once that is done we can restore
our tunnels.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
The USB4 Connection Manager guide provides detailed information how the
USB4 router buffer (credit) allocation information should be used by the
connection manager when it allocates buffers for different paths. This
patch implements it for Linux. For USB 3.x and DisplayPort we use
directly the router preferences. The rest of the buffer space is then
used for PCIe and DMA (peer-to-peer, XDomain) traffic. DMA tunnels
require at least one buffer and PCIe six, so if there is not enough
buffers we fail the tunnel creation.
For the legacy Thunderbolt 1-3 devices we use the existing hard-coded
scheme except for DMA where we use the values suggested by the USB4 spec
chapter 13.
Co-developed-by: Gil Fine <gil.fine@intel.com>
Signed-off-by: Gil Fine <gil.fine@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
With the USB4 buffer allocation the number of credits (and non-flow
credits) may be different depending on the router buffer allocation
preferences. To allow this move the nfc_credits field to struct
tb_path_hop.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Currently we have had an artificial limitation of a single DMA tunnel
per XDomain connection. However, hardware wise there is no such limit
and software based connection manager can take advantage of all the DMA
rings available on the host to establish tunnels.
For this reason make the tb_xdomain_[enable|disable]_paths() to take the
DMA ring and HopID as parameter instead of storing them in the struct
tb_xdomain. We also add API functions to allocate input and output
HopIDs of the XDomain connection that the service drivers can use
instead of hard-coding.
Also convert the two existing service drivers over to this API.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
The USB4 inter-domain service spec recommends using dedicated flow
control scheme so update the driver accordingly.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
ACPI 6.4 introduced a new _OSC capability used to negotiate whether the
OS is supposed to use Software (native) or Firmware based Connection
Manager. If the native support is granted then there are set of bits
that enable/disable different tunnel types that the Software Connection
Manager is allowed to tunnel.
This adds support for this new USB4 _OSC accordingly. When PCIe
tunneling is disabled then the driver switches security level to be
"nopcie" following the security level 5 used in Firmware based
Connection Manager.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Yehezkel Bernat <YehezkelShB@gmail.com>
Fixes the following W=1 kernel build warning(s):
drivers/thunderbolt/tunnel.c:841: warning: Function parameter or member 'receive_path' not described in 'tb_tunnel_alloc_dma'
drivers/thunderbolt/tunnel.c:841: warning: Excess function parameter 'reveive_path' description in 'tb_tunnel_alloc_dma'
Cc: Andreas Noever <andreas.noever@gmail.com>
Cc: Michael Jamet <michael.jamet@intel.com>
Cc: Yehezkel Bernat <YehezkelShB@gmail.com>
Cc: linux-usb@vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
With DMA tunnels it is possible that the service using it does not
require bi-directional paths so make RX and TX optional (but of course
one of them needs to be set).
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Yehezkel Bernat <YehezkelShB@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This includes two fixes, one that fixes a regression around reboot and
other that uses a correct link rate when USB3 bandwidth is reclaimed
when the link is not up.
Both have been in linux-next with no reported issues.
-----BEGIN PGP SIGNATURE-----
iQJUBAABCgA+FiEEVTdhRGBbNzLrSUBaAP2fSd+ZWKAFAl9N9lMgHG1pa2Eud2Vz
dGVyYmVyZ0BsaW51eC5pbnRlbC5jb20ACgkQAP2fSd+ZWKDqFg//Rm8xBbFp+DFF
LysW8K6ZCEbwUVZa0CvrDv2fSG/E//yYKstMOIuIZBs49LENNEGtQeyPwRkZmeyk
LA1n6lxOefyLDHw/7Q4pd6mrxFTUBQoLYrTofuTck5b7HVABv1CpyhWjBmEijTy0
wKcSEE2LWDJ4e6ROMrk6X6hYSYAIgfjWyjiiswqETuPB7s62Nnpv14cLc6//2thc
OzRaa5qKJ3ldwswJZzjFDWriDIyIBQiEHHP8YM+QfiMNs+Fb/pP1Uxyg0OJSk6g3
1qMV8b2VmSXdnT0APF0oyxkkB3zELvJo33RhRKgW9OTAhFkPSeqdxbydAe//MdVo
AWjJ8hvRcFCxnXF9cKzA3HagUX4CVP/IXSH3L8kWR9PprRJvsGXKNA4Xna9Cx4FI
qfPatQ73ATIBM2iwsFiYweawuO0Ti5JcPpRBfm1D4rG0yv/r7rN+3fBatHsrdYi4
FMT+kRZI/GUi5LQFXLcG6UE8BesGipJJvGJTIkuKu7GQJ3RlLrZRLMkmM/wTx6be
aahVT25OXUeZJ77y+RhgVQuikSWDTLS4TjXBa7/t0y+JuEkBjtoPlDbWn3IFGaRr
oPnCkNnpFvTA8pnv7KWt9X8J5pZW3WNd35OmPlTilXBz1gbrH6+U0sSE5KsC6ii1
EYewgZI+e8qZXGcwDw0qBBXJ8RqFWPI=
=vxwa
-----END PGP SIGNATURE-----
Merge tag 'thunderbolt-for-v5.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-linus
Mika writes:
thunderbolt: Fixes for v5.9-rc4
This includes two fixes, one that fixes a regression around reboot and
other that uses a correct link rate when USB3 bandwidth is reclaimed
when the link is not up.
Both have been in linux-next with no reported issues.
* tag 'thunderbolt-for-v5.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt:
thunderbolt: Use maximum USB3 link rate when reclaiming if link is not up
thunderbolt: Disable ports that are not implemented
If the USB3 link is not up the actual link rate is 0 so when reclaiming
bandwidth we should look at maximum supported link rate instead.
Cc: stable@vger.kernel.org
Fixes: 0bd680cd90 ("thunderbolt: Add USB3 bandwidth management")
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
USB3 supports both isochronous and non-isochronous traffic. The former
requires guaranteed bandwidth and can take up to 90% of the total
bandwidth. With USB4 USB3 is tunneled over USB4 fabric which means that
we need to make sure there is enough bandwidth allocated for the USB3
tunnels in addition to DisplayPort tunnels.
Whereas DisplayPort bandwidth management is static and done before the
DP tunnel is established, the USB3 bandwidth management is dynamic and
allows increasing and decreasing the allocated bandwidth according to
what is currently consumed. This is done through host router USB3
downstream adapter registers.
This adds USB3 bandwidth management to the software connection manager
so that we always try to allocate maximum bandwidth for DP tunnels and
what is left is allocated for USB3.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Sometimes it takes longer for DPRX to be set so increase the timeout to
cope with this.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Whereas DisplayPort bandwidth is consumed only in one direction (from DP
IN adapter to DP OUT adapter), USB3 adds separate bandwidth for both
upstream and downstream directions.
For this reason extend the tunnel consumed bandwidth routines to support
both directions and implement this for DP.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
If the path is not complete when we do discovery the number of hops may
be less than with the full path. As an example when this can happen is
that user unloads the driver, disconnects the topology, and loads the
driver back. If there is PCIe or USB3 tunnel involved this may happen.
Take this into account in tb_pcie_init_path() and tb_usb3_init_path()
and prevent potential access over array limits.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
The USB3 discovery used wrong indices when tunnel is discovered. It
should use TB_USB3_PATH_DOWN for path that flows downstream and
TB_USB3_PATH_UP when it flows upstream. This should not affect the
functionality but better to fix it.
Fixes: e6f8185857 ("thunderbolt: Add support for USB 3.x tunnels")
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: stable@vger.kernel.org # v5.6+
USB4 added a capability to tunnel USB 3.x protocol over the USB4
fabric. USB4 device routers may include integrated SuperSpeed HUB or a
function or both. USB tunneling follows PCIe so that the tunnel is
created between the parent and the child router from USB3 downstream
adapter port to USB3 upstream adapter port over a single USB4 link.
This adds support for USB 3.x tunneling and also capability to discover
existing USB 3.x tunnels (for example created by connection manager in
boot firmware).
Signed-off-by: Rajmohan Mani <rajmohan.mani@intel.com>
Co-developed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Link: https://lore.kernel.org/r/20191217123345.31850-9-mika.westerberg@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
USB4 is the public specification based on Thunderbolt 3 protocol. There
are some differences in register layouts and flows. In addition to PCIe
and DP tunneling, USB4 supports tunneling of USB 3.x. USB4 is also
backward compatible with Thunderbolt 3 (and older generations but the
spec only talks about 3rd generation). USB4 compliant devices can be
identified by checking USB4 version field in router configuration space.
This patch adds initial support for USB4 compliant hosts and devices
which enables following features provided by the existing functionality
in the driver:
- PCIe tunneling
- Display Port tunneling
- Host and device NVM firmware upgrade
- P2P networking
This brings the USB4 support to the same level that we already have for
Thunderbolt 1, 2 and 3 devices.
Note the spec talks about host and device "routers" but in the driver we
still use term "switch" in most places. Both can be used interchangeably.
Co-developed-by: Rajmohan Mani <rajmohan.mani@intel.com>
Signed-off-by: Rajmohan Mani <rajmohan.mani@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Link: https://lore.kernel.org/r/20191217123345.31850-5-mika.westerberg@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Titan Ridge supports Display Port 1.4 which adds HBR3 (High Bit Rate)
rates that may be up to 8.1 Gb/s over 4 lanes. This translates to
effective data bandwidth of 25.92 Gb/s (as 8/10 encoding is removed by
the DP adapters when going over Thunderbolt fabric). If another high
rate monitor is connected we may need to reduce the bandwidth it
consumes so that it fits into the total 40 Gb/s available on the
Thunderbolt fabric.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Titan Ridge needs an additional connection manager handshake in order to
do proper Display Port tunneling so implement it here.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Lane bonding allows aggregating two 10/20 Gb/s (depending on the
generation) lanes into a single 20/40 Gb/s bonded link. This allows
sharing the full bandwidth more efficiently. In order to establish lane
bonding we need to check that lane bonding is possible through link
controller and that both ends of the link actually supports 2x widths.
This also means that all the paths should be established through the
primary port so update tb_path_alloc() to handle this as well.
Lane bonding is supported starting from Falcon Ridge (2nd generation)
controllers.
We also expose the current speed and number of lanes under each device
except the host router following similar attribute naming than USB bus.
Expose speed and number of lanes for both directions to allow possibility
of asymmetric link in the future.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Now that USB4 spec has names for these DP adapter registers we can use
them instead. This makes it easier to match certain register to the spec.
No functional changes.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Now that USB4 spec has names for these basic registers we can use them
instead. This makes it easier to match certain register to the spec.
No functional changes.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
PCIe tunnel path indices got mixed up when we added support for tunnels
between switches that are not adjacent. This did not affect the
functionality as it is just an index but fix it now nevertheless to make
the code easier to understand.
Reported-by: Rajmohan Mani <rajmohan.mani@intel.com>
Fixes: 8c7acaaf02 ("thunderbolt: Extend tunnel creation to more than 2 adjacent switches")
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Yehezkel Bernat <YehezkelShB@gmail.com>
Now that the driver can handle every possible tunnel types there is no
point to log everything as info level so turn these to happen at debug
level instead.
While at it remove duplicated tunnel activation log message
(tb_tunnel_activate() calls tb_tunnel_restart() which print the same
message) and add one missing '\n' termination.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
In addition to PCIe and Display Port tunnels it is also possible to
create tunnels that forward DMA traffic from the host interface adapter
(NHI) to a NULL port that is connected to another domain through a
Thunderbolt cable. These tunnels can be used to carry software messages
such as networking packets.
To support this we introduce another tunnel type (TB_TUNNEL_DMA) that
supports paths from NHI to NULL port and back.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Now that we have capability to discover existing tunnels during driver
load there is no point tearing down tunnels when the driver gets
unloaded. Instead we can just leave them running. If user disconnects
devices while there is no Thunderbolt driver loaded, tunneled protocol
hotplug happens and is handled by the corresponding driver (pciehp in
case of PCIe tunnel, GFX driver in case of DP tunnel).
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Display Port tunnels are somewhat more complex than PCIe tunnels as it
requires 3 tunnels (AUX Rx/Tx and Video). In addition we are not
supposed to create the tunnels immediately when a DP OUT is enumerated.
Instead we need to wait until we get hotplug event to that adapter port
or check if the port has HPD set before tunnels can be established. This
adds Display Port tunneling support to the software connection manager.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
In Apple Macs the boot firmware (EFI) connects all devices automatically
when the system is started, before it hands over to the OS. Instead of
ignoring we discover all those PCIe tunnels and record them using our
internal structures, just like we do when a device is connected after
the OS is already up.
By doing this we can properly tear down tunnels when devices are
disconnected. Also this allows us to resume the existing tunnels after
system suspend/resume cycle.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
State of the connected devices and tunnel configuration is not known
during resume. For example some paths may not be complete anymore if the
user has unplugged the related devices. So instead of marking all paths
as inactive we go ahead and deactivate them explicitly before we restart
them.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Now that we can allocate hop IDs per port on a path, we can take
advantage of this and create tunnels covering longer paths than just
between two adjacent switches. PCIe actually does not need this as it
is typically a daisy chain between two adjacent switches but this way we
do not need to hard-code creation of the tunnel.
While there add name to struct tb_path to make debugging easier, and
update kernel-doc comments.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
To be able to tunnel non-PCIe traffic, separate tunnel functionality
into generic and PCIe specific parts. Rename struct tb_pci_tunnel to
tb_tunnel, and make it hold an array of paths instead of just two.
Update all the tunneling functions to take this structure as parameter.
We also move tb_pci_port_active() to switch.c (and rename it) where we
will be keeping all port and switch related functions.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
In order to tunnel non-PCIe traffic as well rename tunnel_pci.[ch] to
tunnel.[ch] to reflect this fact. No functional changes.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>