Skip to content

Commit 6e19d48

Browse files
Memento80westeri
authored andcommitted
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>
1 parent 14200a2 commit 6e19d48

4 files changed

Lines changed: 70 additions & 3 deletions

File tree

drivers/thunderbolt/tb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,8 @@ int usb4_dp_port_allocated_bw(struct tb_port *port);
13011301
int usb4_dp_port_allocate_bw(struct tb_port *port, int bw);
13021302
int usb4_dp_port_requested_bw(struct tb_port *port);
13031303

1304+
int usb4_pci_port_set_ext_encapsulation(struct tb_port *port, bool enable);
1305+
13041306
static inline bool tb_is_usb4_port_device(const struct device *dev)
13051307
{
13061308
return dev->type == &usb4_port_device_type;

drivers/thunderbolt/tb_regs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,8 @@ struct tb_regs_port_header {
451451
/* PCIe adapter registers */
452452
#define ADP_PCIE_CS_0 0x00
453453
#define ADP_PCIE_CS_0_PE BIT(31)
454+
#define ADP_PCIE_CS_1 0x01
455+
#define ADP_PCIE_CS_1_EE BIT(0)
454456

455457
/* USB adapter registers */
456458
#define ADP_USB3_CS_0 0x00

drivers/thunderbolt/tunnel.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/slab.h>
1111
#include <linux/list.h>
1212
#include <linux/ktime.h>
13+
#include <linux/string_helpers.h>
1314

1415
#include "tunnel.h"
1516
#include "tb.h"
@@ -153,18 +154,49 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths,
153154
return tunnel;
154155
}
155156

157+
static int tb_pci_set_ext_encapsulation(struct tb_tunnel *tunnel, bool enable)
158+
{
159+
int ret;
160+
161+
/* Only supported of both routers are at least USB4 v2 */
162+
if (usb4_switch_version(tunnel->src_port->sw) < 2 ||
163+
usb4_switch_version(tunnel->dst_port->sw) < 2)
164+
return 0;
165+
166+
ret = usb4_pci_port_set_ext_encapsulation(tunnel->src_port, enable);
167+
if (ret)
168+
return ret;
169+
170+
ret = usb4_pci_port_set_ext_encapsulation(tunnel->dst_port, enable);
171+
if (ret)
172+
return ret;
173+
174+
tb_tunnel_dbg(tunnel, "extended encapsulation %s\n",
175+
str_enabled_disabled(enable));
176+
return 0;
177+
}
178+
156179
static int tb_pci_activate(struct tb_tunnel *tunnel, bool activate)
157180
{
158181
int res;
159182

183+
if (activate) {
184+
res = tb_pci_set_ext_encapsulation(tunnel, activate);
185+
if (res)
186+
return res;
187+
}
188+
160189
res = tb_pci_port_enable(tunnel->src_port, activate);
161190
if (res)
162191
return res;
163192

164-
if (tb_port_is_pcie_up(tunnel->dst_port))
165-
return tb_pci_port_enable(tunnel->dst_port, activate);
193+
if (tb_port_is_pcie_up(tunnel->dst_port)) {
194+
res = tb_pci_port_enable(tunnel->dst_port, activate);
195+
if (res)
196+
return res;
197+
}
166198

167-
return 0;
199+
return activate ? 0 : tb_pci_set_ext_encapsulation(tunnel, activate);
168200
}
169201

170202
static int tb_pci_init_credits(struct tb_path_hop *hop)

drivers/thunderbolt/usb4.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,3 +2796,34 @@ int usb4_dp_port_requested_bw(struct tb_port *port)
27962796

27972797
return (val & ADP_DP_CS_8_REQUESTED_BW_MASK) * granularity;
27982798
}
2799+
2800+
/**
2801+
* usb4_pci_port_set_ext_encapsulation() - Enable/disable extended encapsulation
2802+
* @port: PCIe adapter
2803+
* @enable: Enable/disable extended encapsulation
2804+
*
2805+
* Enables or disables extended encapsulation used in PCIe tunneling. Caller
2806+
* needs to make sure both adapters support this before enabling. Returns %0 on
2807+
* success and negative errno otherwise.
2808+
*/
2809+
int usb4_pci_port_set_ext_encapsulation(struct tb_port *port, bool enable)
2810+
{
2811+
u32 val;
2812+
int ret;
2813+
2814+
if (!tb_port_is_pcie_up(port) && !tb_port_is_pcie_down(port))
2815+
return -EINVAL;
2816+
2817+
ret = tb_port_read(port, &val, TB_CFG_PORT,
2818+
port->cap_adap + ADP_PCIE_CS_1, 1);
2819+
if (ret)
2820+
return ret;
2821+
2822+
if (enable)
2823+
val |= ADP_PCIE_CS_1_EE;
2824+
else
2825+
val &= ~ADP_PCIE_CS_1_EE;
2826+
2827+
return tb_port_write(port, &val, TB_CFG_PORT,
2828+
port->cap_adap + ADP_PCIE_CS_1, 1);
2829+
}

0 commit comments

Comments
 (0)