Skip to content

Commit 582e70b

Browse files
Gil Finewesteri
Gil Fine
authored andcommitted
thunderbolt: Change bandwidth reservations to comply USB4 v2
USB4 v2 Connection Manager guide (section 6.1.2.3) suggests to reserve bandwidth in a sligthly different manner. It suggests to keep minimum of 1500 Mb/s for each path that carry a bulk traffic. Here we change the bandwidth reservations to comply to the above for USB 3.x and PCIe protocols over Gen 4 link, taking weights into account (that's 1500 Mb/s for PCIe and 3000 Mb/s for USB 3.x). For Gen 3 and below we use the existing reservation. Signed-off-by: Gil Fine <gil.fine@linux.intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
1 parent aa673d6 commit 582e70b

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed

drivers/thunderbolt/tb.c

+11
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ static int tb_available_bandwidth(struct tb *tb, struct tb_port *src_port,
602602
/* Find the minimum available bandwidth over all links */
603603
tb_for_each_port_on_path(src_port, dst_port, port) {
604604
int link_speed, link_width, up_bw, down_bw;
605+
int pci_reserved_up, pci_reserved_down;
605606

606607
if (!tb_port_is_null(port))
607608
continue;
@@ -695,6 +696,16 @@ static int tb_available_bandwidth(struct tb *tb, struct tb_port *src_port,
695696
up_bw -= usb3_consumed_up;
696697
down_bw -= usb3_consumed_down;
697698

699+
/*
700+
* If there is anything reserved for PCIe bulk traffic
701+
* take it into account here too.
702+
*/
703+
if (tb_tunnel_reserved_pci(port, &pci_reserved_up,
704+
&pci_reserved_down)) {
705+
up_bw -= pci_reserved_up;
706+
down_bw -= pci_reserved_down;
707+
}
708+
698709
if (up_bw < *available_up)
699710
*available_up = up_bw;
700711
if (down_bw < *available_down)

drivers/thunderbolt/tunnel.c

+63-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#define TB_USB3_PATH_UP 1
3232

3333
#define TB_USB3_PRIORITY 3
34-
#define TB_USB3_WEIGHT 3
34+
#define TB_USB3_WEIGHT 2
3535

3636
/* DP adapters use HopID 8 for AUX and 9 for Video */
3737
#define TB_DP_AUX_TX_HOPID 8
@@ -61,6 +61,15 @@
6161
#define TB_DMA_PRIORITY 5
6262
#define TB_DMA_WEIGHT 1
6363

64+
/*
65+
* Reserve additional bandwidth for USB 3.x and PCIe bulk traffic
66+
* according to USB4 v2 Connection Manager guide. This ends up reserving
67+
* 1500 Mb/s for PCIe and 3000 Mb/s for USB 3.x taking weights into
68+
* account.
69+
*/
70+
#define USB4_V2_PCI_MIN_BANDWIDTH (1500 * TB_PCI_WEIGHT)
71+
#define USB4_V2_USB3_MIN_BANDWIDTH (1500 * TB_USB3_WEIGHT)
72+
6473
static unsigned int dma_credits = TB_DMA_CREDITS;
6574
module_param(dma_credits, uint, 0444);
6675
MODULE_PARM_DESC(dma_credits, "specify custom credits for DMA tunnels (default: "
@@ -150,11 +159,11 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths,
150159

151160
static int tb_pci_set_ext_encapsulation(struct tb_tunnel *tunnel, bool enable)
152161
{
162+
struct tb_port *port = tb_upstream_port(tunnel->dst_port->sw);
153163
int ret;
154164

155165
/* Only supported of both routers are at least USB4 v2 */
156-
if (usb4_switch_version(tunnel->src_port->sw) < 2 ||
157-
usb4_switch_version(tunnel->dst_port->sw) < 2)
166+
if (tb_port_get_link_generation(port) < 4)
158167
return 0;
159168

160169
ret = usb4_pci_port_set_ext_encapsulation(tunnel->src_port, enable);
@@ -370,6 +379,51 @@ struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up,
370379
return NULL;
371380
}
372381

382+
/**
383+
* tb_tunnel_reserved_pci() - Amount of bandwidth to reserve for PCIe
384+
* @port: Lane 0 adapter
385+
* @reserved_up: Upstream bandwidth in Mb/s to reserve
386+
* @reserved_down: Downstream bandwidth in Mb/s to reserve
387+
*
388+
* Can be called to any connected lane 0 adapter to find out how much
389+
* bandwidth needs to be left in reserve for possible PCIe bulk traffic.
390+
* Returns true if there is something to be reserved and writes the
391+
* amount to @reserved_down/@reserved_up. Otherwise returns false and
392+
* does not touch the parameters.
393+
*/
394+
bool tb_tunnel_reserved_pci(struct tb_port *port, int *reserved_up,
395+
int *reserved_down)
396+
{
397+
if (WARN_ON_ONCE(!port->remote))
398+
return false;
399+
400+
if (!tb_acpi_may_tunnel_pcie())
401+
return false;
402+
403+
if (tb_port_get_link_generation(port) < 4)
404+
return false;
405+
406+
/* Must have PCIe adapters */
407+
if (tb_is_upstream_port(port)) {
408+
if (!tb_switch_find_port(port->sw, TB_TYPE_PCIE_UP))
409+
return false;
410+
if (!tb_switch_find_port(port->remote->sw, TB_TYPE_PCIE_DOWN))
411+
return false;
412+
} else {
413+
if (!tb_switch_find_port(port->sw, TB_TYPE_PCIE_DOWN))
414+
return false;
415+
if (!tb_switch_find_port(port->remote->sw, TB_TYPE_PCIE_UP))
416+
return false;
417+
}
418+
419+
*reserved_up = USB4_V2_PCI_MIN_BANDWIDTH;
420+
*reserved_down = USB4_V2_PCI_MIN_BANDWIDTH;
421+
422+
tb_port_dbg(port, "reserving %u/%u Mb/s for PCIe\n", *reserved_up,
423+
*reserved_down);
424+
return true;
425+
}
426+
373427
static bool tb_dp_is_usb4(const struct tb_switch *sw)
374428
{
375429
/* Titan Ridge DP adapters need the same treatment as USB4 */
@@ -1747,6 +1801,7 @@ static int tb_usb3_activate(struct tb_tunnel *tunnel, bool activate)
17471801
static int tb_usb3_consumed_bandwidth(struct tb_tunnel *tunnel,
17481802
int *consumed_up, int *consumed_down)
17491803
{
1804+
struct tb_port *port = tb_upstream_port(tunnel->dst_port->sw);
17501805
int pcie_weight = tb_acpi_may_tunnel_pcie() ? TB_PCI_WEIGHT : 0;
17511806

17521807
/*
@@ -1758,6 +1813,11 @@ static int tb_usb3_consumed_bandwidth(struct tb_tunnel *tunnel,
17581813
*consumed_down = tunnel->allocated_down *
17591814
(TB_USB3_WEIGHT + pcie_weight) / TB_USB3_WEIGHT;
17601815

1816+
if (tb_port_get_link_generation(port) >= 4) {
1817+
*consumed_up = max(*consumed_up, USB4_V2_USB3_MIN_BANDWIDTH);
1818+
*consumed_down = max(*consumed_down, USB4_V2_USB3_MIN_BANDWIDTH);
1819+
}
1820+
17611821
return 0;
17621822
}
17631823

drivers/thunderbolt/tunnel.h

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ struct tb_tunnel *tb_tunnel_discover_pci(struct tb *tb, struct tb_port *down,
8080
bool alloc_hopid);
8181
struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up,
8282
struct tb_port *down);
83+
bool tb_tunnel_reserved_pci(struct tb_port *port, int *reserved_up,
84+
int *reserved_down);
8385
struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in,
8486
bool alloc_hopid);
8587
struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in,

0 commit comments

Comments
 (0)