Commit dacb1287 authored by Kranthi Kuntala's avatar Kranthi Kuntala Committed by Mika Westerberg

thunderbolt: Add support for on-board retimers

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 <device>:<port>.<index>
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: default avatarKranthi Kuntala <kranthi.kuntala@intel.com>
Co-developed-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 02d12855
......@@ -236,3 +236,36 @@ KernelVersion: 4.15
Contact: thunderbolt-software@lists.01.org
Description: This contains XDomain service specific settings as
bitmask. Format: %x
What: /sys/bus/thunderbolt/devices/<device>:<port>.<index>/device
Date: Oct 2020
KernelVersion: v5.9
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
Description: Retimer device identifier read from the hardware.
What: /sys/bus/thunderbolt/devices/<device>:<port>.<index>/nvm_authenticate
Date: Oct 2020
KernelVersion: v5.9
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
Description: When new NVM image is written to the non-active NVM
area (through non_activeX NVMem device), the
authentication procedure is started by writing 1 to
this file. If everything goes well, the device is
restarted with the new NVM firmware. If the image
verification fails an error code is returned instead.
When read holds status of the last authentication
operation if an error occurred during the process.
Format: %x.
What: /sys/bus/thunderbolt/devices/<device>:<port>.<index>/nvm_version
Date: Oct 2020
KernelVersion: v5.9
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
Description: Holds retimer NVM version number. Format: %x.%x, major.minor.
What: /sys/bus/thunderbolt/devices/<device>:<port>.<index>/vendor
Date: Oct 2020
KernelVersion: v5.9
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
Description: Retimer vendor identifier read from the hardware.
......@@ -173,8 +173,8 @@ following ``udev`` rule::
ACTION=="add", SUBSYSTEM=="thunderbolt", ATTRS{iommu_dma_protection}=="1", ATTR{authorized}=="0", ATTR{authorized}="1"
Upgrading NVM on Thunderbolt device or host
-------------------------------------------
Upgrading NVM on Thunderbolt device, host or retimer
----------------------------------------------------
Since most of the functionality is handled in firmware running on a
host controller or a device, it is important that the firmware can be
upgraded to the latest where possible bugs in it have been fixed.
......@@ -185,9 +185,10 @@ for some machines:
`Thunderbolt Updates <https://thunderbolttechnology.net/updates>`_
Before you upgrade firmware on a device or host, please make sure it is a
suitable upgrade. Failing to do that may render the device (or host) in a
state where it cannot be used properly anymore without special tools!
Before you upgrade firmware on a device, host or retimer, please make
sure it is a suitable upgrade. Failing to do that may render the device
in a state where it cannot be used properly anymore without special
tools!
Host NVM upgrade on Apple Macs is not supported.
......
......@@ -2,6 +2,6 @@
obj-${CONFIG_USB4} := thunderbolt.o
thunderbolt-objs := nhi.o nhi_ops.o ctl.o tb.o switch.o cap.o path.o tunnel.o eeprom.o
thunderbolt-objs += domain.o dma_port.o icm.o property.o xdomain.o lc.o tmu.o usb4.o
thunderbolt-objs += nvm.o
thunderbolt-objs += nvm.o retimer.o
obj-${CONFIG_USB4_KUNIT_TEST} += test.o
This diff is collapsed.
......@@ -10,6 +10,8 @@
#ifndef _SB_REGS
#define _SB_REGS
#define USB4_SB_VENDOR_ID 0x00
#define USB4_SB_PRODUCT_ID 0x01
#define USB4_SB_OPCODE 0x08
enum usb4_sb_opcode {
......
......@@ -2392,6 +2392,9 @@ void tb_switch_remove(struct tb_switch *sw)
tb_xdomain_remove(port->xdomain);
port->xdomain = NULL;
}
/* Remove any downstream retimers */
tb_retimer_remove_all(port);
}
if (!sw->is_unplugged)
......
......@@ -539,6 +539,9 @@ static void tb_scan_port(struct tb_port *port)
tb_port_dbg(port, "port already has a remote\n");
return;
}
tb_retimer_scan(port);
sw = tb_switch_alloc(port->sw->tb, &port->sw->dev,
tb_downstream_route(port));
if (IS_ERR(sw)) {
......@@ -595,6 +598,9 @@ static void tb_scan_port(struct tb_port *port)
if (tb_enable_tmu(sw))
tb_sw_warn(sw, "failed to enable TMU\n");
/* Scan upstream retimers */
tb_retimer_scan(upstream_port);
/*
* Create USB 3.x tunnels only when the switch is plugged to the
* domain. This is because we scan the domain also during discovery
......@@ -674,6 +680,7 @@ static void tb_free_unplugged_children(struct tb_switch *sw)
continue;
if (port->remote->sw->is_unplugged) {
tb_retimer_remove_all(port);
tb_remove_dp_resources(port->remote->sw);
tb_switch_lane_bonding_disable(port->remote->sw);
tb_switch_remove(port->remote->sw);
......@@ -1039,6 +1046,8 @@ static void tb_handle_hotplug(struct work_struct *work)
goto put_sw;
}
if (ev->unplug) {
tb_retimer_remove_all(port);
if (tb_port_has_remote(port)) {
tb_port_dbg(port, "switch unplugged\n");
tb_sw_set_unplugged(port->remote->sw);
......@@ -1283,6 +1292,7 @@ static int tb_free_unplugged_xdomains(struct tb_switch *sw)
if (tb_is_upstream_port(port))
continue;
if (port->xdomain && port->xdomain->is_unplugged) {
tb_retimer_remove_all(port);
tb_xdomain_remove(port->xdomain);
port->xdomain = NULL;
ret++;
......
......@@ -210,6 +210,28 @@ struct tb_port {
struct list_head list;
};
/**
* tb_retimer: Thunderbolt retimer
* @dev: Device for the retimer
* @tb: Pointer to the domain the retimer belongs to
* @index: Retimer index facing the router USB4 port
* @vendor: Vendor ID of the retimer
* @device: Device ID of the retimer
* @port: Pointer to the lane 0 adapter
* @nvm: Pointer to the NVM if the retimer has one (%NULL otherwise)
* @auth_status: Status of last NVM authentication
*/
struct tb_retimer {
struct device dev;
struct tb *tb;
u8 index;
u32 vendor;
u32 device;
struct tb_port *port;
struct tb_nvm *nvm;
u32 auth_status;
};
/**
* struct tb_path_hop - routing information for a tb_path
* @in_port: Ingress port of a switch
......@@ -553,6 +575,7 @@ struct tb *icm_probe(struct tb_nhi *nhi);
struct tb *tb_probe(struct tb_nhi *nhi);
extern struct device_type tb_domain_type;
extern struct device_type tb_retimer_type;
extern struct device_type tb_switch_type;
int tb_domain_init(void);
......@@ -853,6 +876,21 @@ void tb_xdomain_remove(struct tb_xdomain *xd);
struct tb_xdomain *tb_xdomain_find_by_link_depth(struct tb *tb, u8 link,
u8 depth);
int tb_retimer_scan(struct tb_port *port);
void tb_retimer_remove_all(struct tb_port *port);
static inline bool tb_is_retimer(const struct device *dev)
{
return dev->type == &tb_retimer_type;
}
static inline struct tb_retimer *tb_to_retimer(struct device *dev)
{
if (tb_is_retimer(dev))
return container_of(dev, struct tb_retimer, dev);
return NULL;
}
int usb4_switch_setup(struct tb_switch *sw);
int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid);
int usb4_switch_drom_read(struct tb_switch *sw, unsigned int address, void *buf,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment