summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/tunnel.c
diff options
context:
space:
mode:
authorGil Fine <gil.fine@intel.com>2022-09-29 12:49:48 +0300
committerMika Westerberg <mika.westerberg@linux.intel.com>2023-06-16 09:53:28 +0300
commit6e19d48ea0d8aeee5688e5718cf2143d281864f3 (patch)
treed72c64c3b5923c8bdde45dd1bd0adfa2d71066e3 /drivers/thunderbolt/tunnel.c
parent14200a2631dd1f041201985e2a757d2d06ba2524 (diff)
downloadlinux-6e19d48ea0d8aeee5688e5718cf2143d281864f3.tar.xz
thunderbolt: Enable USB4 v2 PCIe TLP/DLLP extended encapsulation
USB4 v2 spec introduces modified encapsulation of PCIe TLP and DLLP packets. This improves the PCIe tunneled traffic usage by reducing overhead. Enable this if both sides of the link support it. Signed-off-by: Gil Fine <gil.fine@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/thunderbolt/tunnel.c')
-rw-r--r--drivers/thunderbolt/tunnel.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c
index 7df5f90e21d4..c8ca0a41dac8 100644
--- a/drivers/thunderbolt/tunnel.c
+++ b/drivers/thunderbolt/tunnel.c
@@ -10,6 +10,7 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/ktime.h>
+#include <linux/string_helpers.h>
#include "tunnel.h"
#include "tb.h"
@@ -153,18 +154,49 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths,
return tunnel;
}
+static int tb_pci_set_ext_encapsulation(struct tb_tunnel *tunnel, bool enable)
+{
+ int ret;
+
+ /* Only supported of both routers are at least USB4 v2 */
+ if (usb4_switch_version(tunnel->src_port->sw) < 2 ||
+ usb4_switch_version(tunnel->dst_port->sw) < 2)
+ return 0;
+
+ ret = usb4_pci_port_set_ext_encapsulation(tunnel->src_port, enable);
+ if (ret)
+ return ret;
+
+ ret = usb4_pci_port_set_ext_encapsulation(tunnel->dst_port, enable);
+ if (ret)
+ return ret;
+
+ tb_tunnel_dbg(tunnel, "extended encapsulation %s\n",
+ str_enabled_disabled(enable));
+ return 0;
+}
+
static int tb_pci_activate(struct tb_tunnel *tunnel, bool activate)
{
int res;
+ if (activate) {
+ res = tb_pci_set_ext_encapsulation(tunnel, activate);
+ if (res)
+ return res;
+ }
+
res = tb_pci_port_enable(tunnel->src_port, activate);
if (res)
return res;
- if (tb_port_is_pcie_up(tunnel->dst_port))
- return tb_pci_port_enable(tunnel->dst_port, activate);
+ if (tb_port_is_pcie_up(tunnel->dst_port)) {
+ res = tb_pci_port_enable(tunnel->dst_port, activate);
+ if (res)
+ return res;
+ }
- return 0;
+ return activate ? 0 : tb_pci_set_ext_encapsulation(tunnel, activate);
}
static int tb_pci_init_credits(struct tb_path_hop *hop)