- 18 12月, 2019 2 次提交
-
-
由 Mika Westerberg 提交于
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: NRajmohan Mani <rajmohan.mani@intel.com> Signed-off-by: NRajmohan Mani <rajmohan.mani@intel.com> Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com> Link: https://lore.kernel.org/r/20191217123345.31850-5-mika.westerberg@linux.intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
-
由 Mika Westerberg 提交于
We will be needing this when adding initial USB4 support so make it available to other files in the driver as well. We also rename it to tb_switch_find_port() to follow conventions used in switch.c. No functional changes. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com> Link: https://lore.kernel.org/r/20191217123345.31850-2-mika.westerberg@linux.intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- 02 11月, 2019 5 次提交
-
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
To perform proper Display Port tunneling for Thunderbolt 3 devices we need to allocate DP resources for DP IN port before they can be used. The reason for this is that the user can also connect a monitor directly to the Type-C ports in which case the Thunderbolt controller acts as re-driver for Display Port (no tunneling takes place) taking the DP sinks away from the connection manager. This allocation is done using special sink allocation registers available through the link controller. We can pair DP IN to DP OUT only if * DP IN has sink allocated via link controller * DP OUT port receives hotplug event For DP IN adapters (only for the host router) we first query whether there is DP resource available (it may be the previous instance of the driver for example already allocated it) and if it is we add it to the list. We then update the list when after each plug/unplug event to a DP IN/OUT adapter. Each time the list is updated we try to find additional DP IN <-> DP OUT pairs for tunnel establishment. This strategy also makes it possible to establish another tunnel in case there are 3 monitors connected and one gets unplugged releasing the DP IN adapter for the new tunnel. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
In order to keep PCIe hierarchies consistent across hotplugs, add hard-coded PCIe downstream port to Thunderbolt port for Alpine Ridge and Titan Ridge as well. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
For a casual reader tb_switch_is_cr() does not tell much so instead spell out the full controller name in the function name. For example tb_switch_is_cr() becomes tb_switch_is_cactus_ridge() which is easier to understand. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
- 01 11月, 2019 3 次提交
-
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
The function does not modify the argument in any way so make it const. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
We currently differentiate between SW CM (Software Connection Manager, sometimes also called External Connection Manager) and ICM (Firmware based Connection Manager, Internal Connection Manager) by looking directly at the sw->config.enabled field which may be rather hard to understand for the casual reader. For this reason introduce a wrapper function with documentation that should make the intention more clear. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
- 12 6月, 2019 1 次提交
-
-
由 Mika Westerberg 提交于
When a device is authorized from userspace by writing to authorized attribute we first take the domain lock and then runtime resume the device in question. There are two issues with this. First is that the device connected notifications are blocked during this time which means we get them only after the authorization operation is complete. Because of this the authorization needed flag from the firmware notification is not reflecting the real authorization status anymore. So what happens is that the "authorized" keeps returning 0 even if the device was already authorized properly. Second issue is that each time the controller is runtime resumed the connection_id field of device connected notification may be different than in the previous resume. We need to use the latest connection_id otherwise the firmware rejects the authorization command. Fix these by moving runtime resume operations to happen before the domain lock is taken, and waiting for the updated device connected notification from the firmware before we allow runtime resume of a device to complete. While there add missing locking to tb_switch_nvm_read(). Fixes: 09f11b6c ("thunderbolt: Take domain lock in switch sysfs attribute callbacks") Reported-by: NPengfei Xu <pengfei.xu@intel.com> Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
- 25 4月, 2019 1 次提交
-
-
由 Nathan Chancellor 提交于
Clang warns: drivers/thunderbolt/tunnel.c:504:17: warning: implicit truncation from 'int' to bit-field changes value from 5 to -3 [-Wbitfield-constant-conversion] path->priority = 5; ^ ~ 1 warning generated. The priority member in struct tb_path is only ever assigned a positive number: $ rg -n priority drivers/thunderbolt/path.c drivers/thunderbolt/tunnel.c:99: path->priority = 3; drivers/thunderbolt/tunnel.c:308: path->priority = 2; drivers/thunderbolt/tunnel.c:323: path->priority = 1; drivers/thunderbolt/tunnel.c:504: path->priority = 5; Furthermore, that value is only assigned to an unsigned integer in tb_path_activate (the priority member in struct tb_regs_hop). Fixes: 44242d6c ("thunderbolt: Add support for DMA tunnels") Link: https://github.com/ClangBuiltLinux/linux/issues/454Signed-off-by: NNathan Chancellor <natechancellor@gmail.com> Reviewed-by: NNick Desaulniers <ndesaulniers@google.com> Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
- 18 4月, 2019 23 次提交
-
-
由 Mika Westerberg 提交于
The printing macros do not modify the passed object so make them const. While there make tb_route() to take const parameter as well. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
We will be needing these routines to find Display Port adapters as well so modify them to take port type as the second parameter. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
The only way to expand Thunderbolt topology is through the NULL adapter ports (typically ports 1, 2, 3 and 4). There is no point handling Thunderbolt hotplug events on any other port. Add a helper function (tb_port_is_null()) that can be used to determine if the port is NULL port, and use it in software connection manager code when hotplug event is handled. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
Currently the software connection manager (tb.c) has only supported creating a single PCIe tunnel, no PCIe device daisy chaining has been supported so far. This updates the software connection manager so that it now can create PCIe tunnels for full chain of six devices. Because PCIe allows DMA and opens possibility for DMA attacks we change security level to "user" meaning that PCIe tunneling requires that the userspace authorizes the devices first. This makes it possible to block PCIe tunneling completely while still allowing other types of tunnels to be automatically created. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
We need to be able to walk from one port to another when we are creating paths where there are multiple switches between two ports. For this reason introduce a new function tb_next_port_on_path(). Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: NLukas Wunner <lukas@wunner.de>
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
Each port has a separate path configuration space that is used for finding the next hop (switch) in the path. HopID is an index to this configuration space. HopIDs 0 - 7 are reserved by the protocol. In order to get next available HopID for each direction we provide two pairs of helper functions that can be used to allocate and release HopIDs for a given port. While there remove obsolete TODO comment. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
The adapter specific capability either is there or not if the port does not hold an adapter. Instead of always finding it on-demand we read the offset just once when the port is initialized. While there we update the struct port documentation to follow kernel-doc format. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
Thunderbolt 2 devices and beyond link controller needs to be notified when a switch is going to be suspended by setting bit 31 in LC_SX_CTRL register. Add this functionality to the software connection manager. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
Thunderbolt 2 devices and beyond need to have additional bits set in link controller specific registers. This includes two bits in LC_SX_CTRL that tell the link controller which lane is connected and whether it is upstream facing or not. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
We will be adding more link controller functionality in subsequent patches and it does not make sense to keep all that in switch.c, so separate LC functionality into its own file. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
Light Ridge and Eagle Ridge both need to have TMU access enabled before port space can be fully accessed so make sure it happens on those. This allows us to get rid of the offset quirk in tb_port_find_cap(). Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
Maximum depth in Thunderbolt topology is 6 so make sure it is not possible to allocate switches that exceed the depth limit. While at it update tb_switch_alloc() to use upper/lower_32_bits() following tb_switch_alloc_safe_mode(). Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
switch_lock was introduced because it allowed serialization of device authorization requests from userspace without need to take the big domain lock (tb->lock). This was fine because device authorization with ICM is just one command that is sent to the firmware. Now that we start to handle all tunneling in the driver switch_lock is not enough because we need to walk over the topology to establish paths. For this reason drop switch_lock from the driver completely in favour of big domain lock. There is one complication, though. If userspace is waiting for the lock in tb_switch_set_authorized(), it keeps the device_del() from removing the sysfs attribute because it waits for active users to release the attribute first which leads into following splat: INFO: task kworker/u8:3:73 blocked for more than 61 seconds. Tainted: G W 5.1.0-rc1+ #244 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. kworker/u8:3 D12976 73 2 0x80000000 Workqueue: thunderbolt0 tb_handle_hotplug [thunderbolt] Call Trace: ? __schedule+0x2e5/0x740 ? _raw_spin_lock_irqsave+0x12/0x40 ? prepare_to_wait_event+0xc5/0x160 schedule+0x2d/0x80 __kernfs_remove.part.17+0x183/0x1f0 ? finish_wait+0x80/0x80 kernfs_remove_by_name_ns+0x4a/0x90 remove_files.isra.1+0x2b/0x60 sysfs_remove_group+0x38/0x80 sysfs_remove_groups+0x24/0x40 device_remove_attrs+0x3d/0x70 device_del+0x14c/0x360 device_unregister+0x15/0x50 tb_switch_remove+0x9e/0x1d0 [thunderbolt] tb_handle_hotplug+0x119/0x5a0 [thunderbolt] ? process_one_work+0x1b7/0x420 process_one_work+0x1b7/0x420 worker_thread+0x37/0x380 ? _raw_spin_unlock_irqrestore+0xf/0x30 ? process_one_work+0x420/0x420 kthread+0x118/0x130 ? kthread_create_on_node+0x60/0x60 ret_from_fork+0x35/0x40 We deal this by following what network stack did for some of their attributes and use mutex_trylock() with restart_syscall(). This makes userspace release the attribute allowing sysfs attribute removal to progress before the write is restarted and eventually fail when the attribute is removed. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
If switch is already disconnected there is no point sending it commands and waiting for timeout. Instead in that case return error immediately. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
由 Mika Westerberg 提交于
tb_switch_find_by_route() does the same already so use it instead and remove duplicated get_switch_at_route(). Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: NLukas Wunner <lukas@wunner.de>
-
由 Mika Westerberg 提交于
This field is not used anywhere so remove it. Reported-by: NLukas Wunner <lukas@wunner.de> Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
-
- 03 10月, 2018 2 次提交
-
-
由 Mika Westerberg 提交于
Intel has done pretty major changes to the driver and we continue to do so in the future as well. Add Intel as copyright holder of the files we have done changes. While there drop "Cactus Ridge" from the headers because this driver works also with other Thunderbolt controllers. No functional changes intended. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com> Acked-by: NYehezkel Bernat <yehezkelshb@gmail.com> Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
-
由 Mika Westerberg 提交于
Currently the driver logs quite a lot to the system message buffer even when doing normal operations. This information is not useful for ordinary users and might even annoy some. For this reason convert most of the logs at info level to happen at debug level instead. The nice output formatting is untouched. Logging can be easily re-enabled by passing "thunderbolt.dyndbg" in the kernel command line (or using the corresponding control file runtime). Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com> Acked-by: NYehezkel Bernat <yehezkelshb@gmail.com> Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- 25 7月, 2018 1 次提交
-
-
由 Mika Westerberg 提交于
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: NMika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- 09 3月, 2018 2 次提交
-
-
由 Mika Westerberg 提交于
Preboot ACL is a mechanism that allows connecting Thunderbolt devices boot time in more secure way than the legacy Thunderbolt boot support. As with the legacy boot option, this also needs to be enabled from the BIOS before booting is allowed. Difference to the legacy mode is that the userspace software explicitly adds device UUIDs by sending a special message to the ICM firmware. Only the devices listed in the boot ACL are connected automatically during the boot. This works in both "user" and "secure" security levels. We implement this in Linux by exposing a new sysfs attribute (boot_acl) below each Thunderbolt domain. The userspace software can then update the full list as needed. Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: NAndy Shevchenko <andy.shevchenko@gmail.com>
-
由 Yehezkel Bernat 提交于
In various cases, Thunderbolt device can be connected by ICM on boot without waiting for approval from user. Most cases are related to OEM-specific BIOS configurations. This information is interesting for user-space as if the device isn't in SW ACL, it may create a friction in the user experience where the device is automatically authorized if it's connected on boot but requires an explicit user action if connected after OS is up. User-space can use this information to suggest adding the device to SW ACL for auto-authorization on later connections. Signed-off-by: NYehezkel Bernat <yehezkel.bernat@intel.com> Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: NAndy Shevchenko <andy.shevchenko@gmail.com>
-