diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-04-13 12:17:14 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-04-13 12:17:14 +0200 |
commit | 5367f82a212305c35b35303a8a21ca348f653ca3 (patch) | |
tree | 98e88cbd6f40762b11802624022eaccf08051c39 /drivers/thunderbolt/switch.c | |
parent | Merge tag 'usb-v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pe... (diff) | |
parent | thunderbolt: Hide authorized attribute if router does not support PCIe tunnels (diff) | |
download | linux-5367f82a212305c35b35303a8a21ca348f653ca3.tar.xz linux-5367f82a212305c35b35303a8a21ca348f653ca3.zip |
Merge tag 'thunderbolt-for-v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-next
Mika writes:
thunderbolt: Changes for v5.13 merge window
This includes following Thunderbolt/USB4 changes for v5.13 merge window:
* Debugfs improvements
* Align the inter-domain (peer-to-peer) support with the USB4
inter-domain spec for better interoperability
* Add support for USB4 DROM and the new product descriptor
* More KUnit tests
* Detailed uevent for routers
* Few miscellaneous improvements
All these have been in linux-next without reported issues.
* tag 'thunderbolt-for-v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: (24 commits)
thunderbolt: Hide authorized attribute if router does not support PCIe tunnels
thunderbolt: Add details to router uevent
thunderbolt: Unlock on error path in tb_domain_add()
thunderbolt: Add support for USB4 DROM
thunderbolt: Check quirks in tb_switch_add()
thunderbolt: Add KUnit tests for DMA tunnels
thunderbolt: Add KUnit tests for XDomain properties
net: thunderbolt: Align the driver to the USB4 networking spec
thunderbolt: Allow multiple DMA tunnels over a single XDomain connection
thunderbolt: Drop unused tb_port_set_initial_credits()
thunderbolt: Use dedicated flow control for DMA tunnels
thunderbolt: Add support for maxhopid XDomain property
thunderbolt: Add tb_property_copy_dir()
thunderbolt: Align XDomain protocol timeouts with the spec
thunderbolt: Use pseudo-random number as initial property block generation
thunderbolt: Do not re-establish XDomain DMA paths automatically
thunderbolt: Add more logging to XDomain connections
Documentation / thunderbolt: Drop speed/lanes entries for XDomain
thunderbolt: Decrease control channel timeout for software connection manager
thunderbolt: Do not pass timeout for tb_cfg_reset()
...
Diffstat (limited to 'drivers/thunderbolt/switch.c')
-rw-r--r-- | drivers/thunderbolt/switch.c | 75 |
1 files changed, 51 insertions, 24 deletions
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 2a95b4ce06c0..e73cd296db7e 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -627,28 +627,6 @@ int tb_port_add_nfc_credits(struct tb_port *port, int credits) } /** - * tb_port_set_initial_credits() - Set initial port link credits allocated - * @port: Port to set the initial credits - * @credits: Number of credits to to allocate - * - * Set initial credits value to be used for ingress shared buffering. - */ -int tb_port_set_initial_credits(struct tb_port *port, u32 credits) -{ - u32 data; - int ret; - - ret = tb_port_read(port, &data, TB_CFG_PORT, ADP_CS_5, 1); - if (ret) - return ret; - - data &= ~ADP_CS_5_LCA_MASK; - data |= (credits << ADP_CS_5_LCA_SHIFT) & ADP_CS_5_LCA_MASK; - - return tb_port_write(port, &data, TB_CFG_PORT, ADP_CS_5, 1); -} - -/** * tb_port_clear_counter() - clear a counter in TB_CFG_COUNTER * @port: Port whose counters to clear * @counter: Counter index to clear @@ -1331,7 +1309,7 @@ int tb_switch_reset(struct tb_switch *sw) TB_CFG_SWITCH, 2, 2); if (res.err) return res.err; - res = tb_cfg_reset(sw->tb->ctl, tb_route(sw), TB_CFG_DEFAULT_TIMEOUT); + res = tb_cfg_reset(sw->tb->ctl, tb_route(sw)); if (res.err > 0) return -EIO; return res.err; @@ -1762,6 +1740,18 @@ static struct attribute *switch_attrs[] = { NULL, }; +static bool has_port(const struct tb_switch *sw, enum tb_port_type type) +{ + const struct tb_port *port; + + tb_switch_for_each_port(sw, port) { + if (!port->disabled && port->config.type == type) + return true; + } + + return false; +} + static umode_t switch_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { @@ -1770,7 +1760,8 @@ static umode_t switch_attr_is_visible(struct kobject *kobj, if (attr == &dev_attr_authorized.attr) { if (sw->tb->security_level == TB_SECURITY_NOPCIE || - sw->tb->security_level == TB_SECURITY_DPONLY) + sw->tb->security_level == TB_SECURITY_DPONLY || + !has_port(sw, TB_TYPE_PCIE_UP)) return 0; } else if (attr == &dev_attr_device.attr) { if (!sw->device) @@ -1849,6 +1840,39 @@ static void tb_switch_release(struct device *dev) kfree(sw); } +static int tb_switch_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct tb_switch *sw = tb_to_switch(dev); + const char *type; + + if (sw->config.thunderbolt_version == USB4_VERSION_1_0) { + if (add_uevent_var(env, "USB4_VERSION=1.0")) + return -ENOMEM; + } + + if (!tb_route(sw)) { + type = "host"; + } else { + const struct tb_port *port; + bool hub = false; + + /* Device is hub if it has any downstream ports */ + tb_switch_for_each_port(sw, port) { + if (!port->disabled && !tb_is_upstream_port(port) && + tb_port_is_null(port)) { + hub = true; + break; + } + } + + type = hub ? "hub" : "device"; + } + + if (add_uevent_var(env, "USB4_TYPE=%s", type)) + return -ENOMEM; + return 0; +} + /* * Currently only need to provide the callbacks. Everything else is handled * in the connection manager. @@ -1882,6 +1906,7 @@ static const struct dev_pm_ops tb_switch_pm_ops = { struct device_type tb_switch_type = { .name = "thunderbolt_device", .release = tb_switch_release, + .uevent = tb_switch_uevent, .pm = &tb_switch_pm_ops, }; @@ -2542,6 +2567,8 @@ int tb_switch_add(struct tb_switch *sw) } tb_sw_dbg(sw, "uid: %#llx\n", sw->uid); + tb_check_quirks(sw); + ret = tb_switch_set_uuid(sw); if (ret) { dev_err(&sw->dev, "failed to set UUID\n"); |