16 Sep, 2020

1 commit

  • According to the kernel power management documentation freeze phase
    should only quiesce the device, no need to configure wakes or put it to
    low power state. For this reason we simply stop the control channel and
    in case of Software Connection Manager also mark the hotplug disabled.
    This should align the driver better with the PM framework expectations.

    Signed-off-by: Mika Westerberg

    Mika Westerberg
     

03 Sep, 2020

7 commits


23 Jun, 2020

7 commits

  • USB4 spec specifies standard access to retimers (both on-board and
    cable) through USB4 port sideband access. This makes it possible to
    upgrade their firmware in the same way than we already do with the
    routers.

    This enumerates on-board retimers under each USB4 port when the link
    comes up and adds them to the bus under the router the retimer belongs
    to. Retimers are exposed in sysfs with name like :.
    where device is the router the retimer belongs to, port is the USB4 port
    the retimer is connected to and index is the retimer index under that
    port (starting from 1). This applies to the upstream USB4 port as well
    so if there is on-board retimer between the port and the router it is
    also added accordingly.

    At this time we do not add cable retimers but there is no techincal
    restriction to do so in the future if needed. It is not clear whether it
    makes sense to upgrade their firmwares and at least Thunderbolt 3 cables
    it has not been done outside of lab environments.

    The sysfs interface is made to follow the router NVM upgrade to make it
    easy to extend the existing userspace (fwupd) to handle these as well.

    Signed-off-by: Kranthi Kuntala
    Co-developed-by: Mika Westerberg
    Signed-off-by: Mika Westerberg

    Kranthi Kuntala
     
  • 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
     
  • 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
     
  • Just for symmetry with the usb4_switch_map_usb3_down() make this one
    also return ports that are enabled.

    Signed-off-by: Mika Westerberg

    Mika Westerberg
     
  • We need to call this on enabled ports in order to find the mapping from
    host router USB4 port to a USB 3.x downstream adapter, so make the
    function return enabled ports as well.

    While there fix parameter alignment in tb_find_usb3_down().

    Signed-off-by: Mika Westerberg

    Mika Westerberg
     
  • USB3 tunneling is possible only over USB4 link so don't create USB3
    tunnels if that's not the case.

    Signed-off-by: Mika Westerberg

    Mika Westerberg
     
  • USB4 spec allows DP tunneling from any router that has DP IN adapter,
    not just from host router. The driver currently only added the DP IN
    resources for the host router because Thunderbolt 1, 2 and 3 devices do
    not have DP IN adapters. However, USB4 allows device routers to have DP
    IN adapter as well so update the driver to add DP IN resources for each
    device that has one. One example would be an eGPU enclosure where the
    eGPU output is forwarded to DP IN port and then tunneled over the USB4
    fabric.

    Only limitation we add now is that the DP IN and DP OUT that gets paired
    for tunnel creation should both be under the same topology starting from
    host router downstream port. In other words we do not create DP tunnels
    across host router at this time even though that is possible as well but
    it complicates the bandwidth management and there is no real use-case
    for this anyway.

    Signed-off-by: Mika Westerberg

    Mika Westerberg
     

18 Dec, 2019

5 commits

  • 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
    Co-developed-by: Mika Westerberg
    Signed-off-by: Mika Westerberg
    Link: https://lore.kernel.org/r/20191217123345.31850-9-mika.westerberg@linux.intel.com
    Signed-off-by: Greg Kroah-Hartman

    Rajmohan Mani
     
  • Time Management Unit (TMU) is included in each USB4 router. It is used
    to synchronize time across the USB4 fabric. By default when USB4 router
    is plugged to the domain, its TMU is turned off. This differs from
    Thunderbolt (1, 2 and 3) devices whose TMU is by default configured to
    bi-directional HiFi mode. Since time synchronization is needed for
    proper Display Port tunneling this means we need to configure the TMU on
    USB4 compliant devices.

    The USB4 spec allows some flexibility on how the TMU can be configured.
    This makes it possible to enable link power management states (CLx) in
    certain topologies, where for example DP tunneling is not used. TMU can
    also be re-configured dynamicaly depending on types of tunnels created
    over the USB4 fabric.

    In this patch we simply configure the TMU to be in bi-directional HiFi
    mode. This way we can tunnel any kind of traffic without need to perform
    complex steps to re-configure the domain dynamically. We can add more
    fine-grained TMU configuration later on when we start enabling CLx
    states.

    Signed-off-by: Rajmohan Mani
    Co-developed-by: Mika Westerberg
    Signed-off-by: Mika Westerberg
    Link: https://lore.kernel.org/r/20191217123345.31850-8-mika.westerberg@linux.intel.com
    Signed-off-by: Greg Kroah-Hartman

    Rajmohan Mani
     
  • 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
    Signed-off-by: Rajmohan Mani
    Signed-off-by: Mika Westerberg
    Link: https://lore.kernel.org/r/20191217123345.31850-5-mika.westerberg@linux.intel.com
    Signed-off-by: Greg Kroah-Hartman

    Mika Westerberg
     
  • USB4 1.0 section 6.4.2.7 specifies a new field (PG) in notification
    packet that is sent as response of hot plug/unplug events. This field
    tells whether the acknowledgment is for plug or unplug event. This needs
    to be set accordingly in order the router to send further hot plug
    notifications.

    To make it simpler we fill the field unconditionally. Legacy devices do
    not look at this field so there should be no problems with them.

    While there rename tb_cfg_error() to tb_cfg_ack_plug() and update the
    log message accordingly. The function is only used to ack plug/unplug
    events.

    Signed-off-by: Mika Westerberg
    Link: https://lore.kernel.org/r/20191217123345.31850-4-mika.westerberg@linux.intel.com
    Signed-off-by: Greg Kroah-Hartman

    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: Mika Westerberg
    Link: https://lore.kernel.org/r/20191217123345.31850-2-mika.westerberg@linux.intel.com
    Signed-off-by: Greg Kroah-Hartman

    Mika Westerberg
     

02 Nov, 2019

6 commits

  • Since now we can do pretty much the same thing in the software
    connection manager than the firmware would do, there is no point
    starting it by default. Instead we can just continue using the software
    connection manager.

    Make it possible for user to switch between the two by adding a module
    pararameter (start_icm) which is by default false. Having this ability
    to enable the firmware may be useful at least when debugging possible
    issues with the software connection manager implementation.

    Signed-off-by: Mika Westerberg

    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: Mika Westerberg

    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: Mika Westerberg

    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: Mika Westerberg

    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: Mika Westerberg

    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: Mika Westerberg

    Mika Westerberg
     

01 Nov, 2019

1 commit


18 Apr, 2019

13 commits

  • 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
     
  • Two domains (hosts) can be connected through a Thunderbolt cable and in
    that case they can start software services such as networking over the
    high-speed DMA paths. Now that we have all the basic building blocks in
    place to create DMA tunnels over the Thunderbolt fabric we can add this
    support to the software connection manager as well.

    Signed-off-by: Mika Westerberg

    Mika Westerberg
     
  • In order to detect possible connections to other domains we need to be
    able to find out why tb_switch_alloc() fails so make it return ERR_PTR()
    instead. This allows the caller to differentiate between errors such as
    -ENOMEM which comes from the kernel and for instance -EIO which comes
    from the hardware when trying to access the possible switch.

    Convert all the current call sites to handle this properly.

    Signed-off-by: Mika Westerberg

    Mika Westerberg
     
  • 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
     
  • 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
     
  • 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: Mika Westerberg

    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: Mika Westerberg

    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: Mika Westerberg

    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: Mika Westerberg

    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: Mika Westerberg

    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: Mika Westerberg

    Mika Westerberg
     
  • 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
     
  • 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: Mika Westerberg

    Mika Westerberg