On a systems where the Thunderbolt controller is present all the time
the kernel nodename may not yet set by the userspace when the driver is
loaded. This means when another host is connected it may see the default
"(none)" hostname instead of the system real hostname.
For this reason build the initial XDomain property block only upon first
connect. This should make sure the userspace has had chance to set it up.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
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>
There are quite many places in the driver where we iterate over each
port in the switch. To make it bit more convenient, add a macro that can
be used to iterate over each port and convert existing call sites to use it.
This is based on code by Lukas Wunner.
No functional changes.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
%*pEp (without "h" or "o") is a no-op. This string could contain
arbitrary (non-NULL) characters, so we do want escaping. Use %*pE like
every other caller.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Currently ICM has been handling XDomain UUID exchange so there was no
need to have it in the driver yet. However, since now we are going to
add the same capabilities to the software connection manager it needs to
be handled properly.
For this reason modify the driver XDomain protocol handling so that if
the remote domain UUID is not filled in the core will query it first and
only then start the normal property exchange flow.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
We run all XDomain requests during discovery in tb->wq and since it only
runs one work at the time it means that sending back reply to the other
domain may be delayed too much depending whether there is an active
XDomain discovery request running.
To make sure we can send reply to the other domain as soon as possible
run tb_xdp_handle_request() in system workqueue instead. Since the
device can be hot-removed in the middle we need to make sure the domain
structure is still around when the function is run so increase reference
count before we schedule the reply work.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Currently the driver only assigns remote port for the primary port if in
case of dual link. This makes things such as walking from one port to
another more complex than necessary because the code needs to change
from secondary to primary port if the path that is established is
created using secondary links.
In order to always assign both remote pointers we need to prevent the
scanning code from following the secondary link. Failing to do that
might cause problems as the same switch may be enumerated twice (or
removed in case of unplug). Handle that properly by introducing a new
function tb_port_has_remote() that returns true only for the primary
port. We also update tb_is_upstream_port() to support both dual link
ports, make it take const port pointer and move it below
tb_upstream_port() to keep similar functions close.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
kmemdup can fail and return a NULL pointer. The patch modifies the
signature of tb_xdp_schedule_request and passes the failure error upstream.
Signed-off-by: Aditya Pakki <pakki001@umn.edu>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
In enumerate_services, ida_simple_get on failure can return an error and
leaks memory. The patch ensures that the dev_set_name is set on non
failure cases, and releases memory during failure.
Signed-off-by: Aditya Pakki <pakki001@umn.edu>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This gets rid of the licence boilerplate duplicated in each file. While
there fix doubled space in domain.c author line.
No functional changes intended.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Yehezkel Bernat <yehezkelshb@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
When Thunderbolt host controller is set to RTD3 mode (Runtime D3) it is
present all the time. Because of this it is important to runtime suspend
the controller whenever possible. In case of ICM we have following rules
which all needs to be true before the host controller can be put to D3:
- The controller firmware reports to support RTD3
- All the connected devices announce support for RTD3
- There is no active XDomain connection
Implement this using standard Linux runtime PM APIs so that when all the
children devices are runtime suspended, the Thunderbolt host controller
PCI device is runtime suspended as well. The ICM firmware then starts
powering down power domains towards RTD3 but it can prevent this if it
detects that there is an active Display Port stream (this is not visible
to the software, though).
The Thunderbolt host controller will be runtime resumed either when
there is a remote wake event (device is connected or disconnected), or
when there is access from userspace that requires hardware access.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This is needed by the new ICM interface to find xdomains by route string
instead of link and depth.
While there update existing tb_xdomain_find_* functions to use
tb_xdomain_get() instead of open-coding the same.
Signed-off-by: Radion Mirchevsky <radion.mirchevsky@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Commit 9a03c3d398 ("thunderbolt: Fix a couple right shifting to zero
bugs") revealed an issue that was previously hidden because we never
actually compared received XDomain message sequence numbers properly.
The idea with these sequence numbers is that the responding host uses
the same sequence number that was in the request packet which we can
then check at the requesting host.
However, testing against macOS it looks like it does not follow this but
instead uses some other logic. Windows driver on the other hand handles
it the same way than Linux.
In order to be able to talk to macOS again, fix this so that we drop the
whole sequence number check. This effectively works exactly the same
than it worked before the aforementioned commit. This also follows the
logic the original P2P networking code used.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
The problematic code looks like this:
res_seq = res_hdr->xd_hdr.length_sn & TB_XDOMAIN_SN_MASK;
res_seq >>= TB_XDOMAIN_SN_SHIFT;
TB_XDOMAIN_SN_SHIFT is 27, and right shifting a u8 27 bits is always
going to result in zero. The fix is to declare these variables as u32.
Fixes: d1ff70241a ("thunderbolt: Add support for XDomain discovery protocol")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
The 0day kbuild robot reports following crash:
BUG: unable to handle kernel NULL pointer dereference at 00000004
IP: tb_property_find+0xe/0x41
*pde = 00000000
Oops: 0000 [#1]
CPU: 0 PID: 1 Comm: swapper Not tainted 4.14.0-rc1-00741-ge69b6c0 #412
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
task: 89c80000 task.stack: 89c7c000
EIP: tb_property_find+0xe/0x41
EFLAGS: 00210246 CPU: 0
EAX: 00000000 EBX: 7a368f47 ECX: 00000044 EDX: 7a368f47
ESI: 8851d340 EDI: 7a368f47 EBP: 89c7df0c ESP: 89c7defc
DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
CR0: 80050033 CR2: 00000004 CR3: 027a2000 CR4: 00000690
Call Trace:
tb_register_property_dir+0x49/0xb9
? cdc_mbim_driver_init+0x1b/0x1b
tbnet_init+0x77/0x9f
? cdc_mbim_driver_init+0x1b/0x1b
do_one_initcall+0x7e/0x145
? parse_args+0x10c/0x1b3
? kernel_init_freeable+0xbe/0x159
kernel_init_freeable+0xd1/0x159
? rest_init+0x110/0x110
kernel_init+0xd/0xd0
ret_from_fork+0x19/0x30
The reason is that both Thunderbolt bus and thunderbolt-net are build
into the kernel image, and the latter is linked first because
drivers/net comes before drivers/thunderbolt. Since both use
module_init() thunderbolt-net ends up calling Thunderbolt bus functions
too early triggering the above crash.
Fix this by moving Thunderbolt bus initialization to happen earlier to
make sure all the data structures are ready when Thunderbolt service
drivers are initialized. To be on the safe side also add a check for
properly initialized xdomain_property_dir to tb_register_property_dir().
Reported-by: kernel test robot <fengguang.wu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
When two hosts are connected over a Thunderbolt cable, there is a
protocol they can use to communicate capabilities supported by the host.
The discovery protocol uses automatically configured control channel
(ring 0) and is build on top of request/response transactions using
special XDomain primitives provided by the Thunderbolt base protocol.
The capabilities consists of a root directory block of basic properties
used for identification of the host, and then there can be zero or more
directories each describing a Thunderbolt service and its capabilities.
Once both sides have discovered what is supported the two hosts can
setup high-speed DMA paths and transfer data to the other side using
whatever protocol was agreed based on the properties. The software
protocol used to communicate which DMA paths to enable is service
specific.
This patch adds support for the XDomain discovery protocol to the
Thunderbolt bus. We model each remote host connection as a Linux XDomain
device. For each Thunderbolt service found supported on the XDomain
device, we create Linux Thunderbolt service device which Thunderbolt
service drivers can then bind to based on the protocol identification
information retrieved from the property directory describing the
service.
This code is based on the work done by Amir Levy and Michael Jamet.
Signed-off-by: Michael Jamet <michael.jamet@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>