Skip to content

Commit f0a57dd

Browse files
Gil Finewesteri
authored andcommitted
thunderbolt: Limit USB3 bandwidth of certain Intel USB4 host routers
Current Intel USB4 host routers have hardware limitation that the USB3 bandwidth cannot go higher than 16376 Mb/s. Work this around by adding a new quirk that limits the bandwidth for the affected host routers. Cc: [email protected] Signed-off-by: Gil Fine <[email protected]> Signed-off-by: Mika Westerberg <[email protected]>
1 parent d2d6ddf commit f0a57dd

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

drivers/thunderbolt/quirks.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,19 @@ static void quirk_clx_disable(struct tb_switch *sw)
2626
tb_sw_dbg(sw, "disabling CL states\n");
2727
}
2828

29+
static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw)
30+
{
31+
struct tb_port *port;
32+
33+
tb_switch_for_each_port(sw, port) {
34+
if (!tb_port_is_usb3_down(port))
35+
continue;
36+
port->max_bw = 16376;
37+
tb_port_dbg(port, "USB3 maximum bandwidth limited to %u Mb/s\n",
38+
port->max_bw);
39+
}
40+
}
41+
2942
struct tb_quirk {
3043
u16 hw_vendor_id;
3144
u16 hw_device_id;
@@ -43,6 +56,24 @@ static const struct tb_quirk tb_quirks[] = {
4356
* DP buffers.
4457
*/
4558
{ 0x8087, 0x0b26, 0x0000, 0x0000, quirk_dp_credit_allocation },
59+
/*
60+
* Limit the maximum USB3 bandwidth for the following Intel USB4
61+
* host routers due to a hardware issue.
62+
*/
63+
{ 0x8087, PCI_DEVICE_ID_INTEL_ADL_NHI0, 0x0000, 0x0000,
64+
quirk_usb3_maximum_bandwidth },
65+
{ 0x8087, PCI_DEVICE_ID_INTEL_ADL_NHI1, 0x0000, 0x0000,
66+
quirk_usb3_maximum_bandwidth },
67+
{ 0x8087, PCI_DEVICE_ID_INTEL_RPL_NHI0, 0x0000, 0x0000,
68+
quirk_usb3_maximum_bandwidth },
69+
{ 0x8087, PCI_DEVICE_ID_INTEL_RPL_NHI1, 0x0000, 0x0000,
70+
quirk_usb3_maximum_bandwidth },
71+
{ 0x8087, PCI_DEVICE_ID_INTEL_MTL_M_NHI0, 0x0000, 0x0000,
72+
quirk_usb3_maximum_bandwidth },
73+
{ 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI0, 0x0000, 0x0000,
74+
quirk_usb3_maximum_bandwidth },
75+
{ 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI1, 0x0000, 0x0000,
76+
quirk_usb3_maximum_bandwidth },
4677
/*
4778
* CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms.
4879
*/

drivers/thunderbolt/tb.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ struct tb_bandwidth_group {
272272
* @group: Bandwidth allocation group the adapter is assigned to. Only
273273
* used for DP IN adapters for now.
274274
* @group_list: The adapter is linked to the group's list of ports through this
275+
* @max_bw: Maximum possible bandwidth through this adapter if set to
276+
* non-zero.
275277
*
276278
* In USB4 terminology this structure represents an adapter (protocol or
277279
* lane adapter).
@@ -299,6 +301,7 @@ struct tb_port {
299301
unsigned int dma_credits;
300302
struct tb_bandwidth_group *group;
301303
struct list_head group_list;
304+
unsigned int max_bw;
302305
};
303306

304307
/**

drivers/thunderbolt/usb4.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,15 @@ int usb4_port_retimer_nvm_read(struct tb_port *port, u8 index,
18821882
usb4_port_retimer_nvm_read_block, &info);
18831883
}
18841884

1885+
static inline unsigned int
1886+
usb4_usb3_port_max_bandwidth(const struct tb_port *port, unsigned int bw)
1887+
{
1888+
/* Take the possible bandwidth limitation into account */
1889+
if (port->max_bw)
1890+
return min(bw, port->max_bw);
1891+
return bw;
1892+
}
1893+
18851894
/**
18861895
* usb4_usb3_port_max_link_rate() - Maximum support USB3 link rate
18871896
* @port: USB3 adapter port
@@ -1903,7 +1912,9 @@ int usb4_usb3_port_max_link_rate(struct tb_port *port)
19031912
return ret;
19041913

19051914
lr = (val & ADP_USB3_CS_4_MSLR_MASK) >> ADP_USB3_CS_4_MSLR_SHIFT;
1906-
return lr == ADP_USB3_CS_4_MSLR_20G ? 20000 : 10000;
1915+
ret = lr == ADP_USB3_CS_4_MSLR_20G ? 20000 : 10000;
1916+
1917+
return usb4_usb3_port_max_bandwidth(port, ret);
19071918
}
19081919

19091920
/**
@@ -1930,7 +1941,9 @@ int usb4_usb3_port_actual_link_rate(struct tb_port *port)
19301941
return 0;
19311942

19321943
lr = val & ADP_USB3_CS_4_ALR_MASK;
1933-
return lr == ADP_USB3_CS_4_ALR_20G ? 20000 : 10000;
1944+
ret = lr == ADP_USB3_CS_4_ALR_20G ? 20000 : 10000;
1945+
1946+
return usb4_usb3_port_max_bandwidth(port, ret);
19341947
}
19351948

19361949
static int usb4_usb3_port_cm_request(struct tb_port *port, bool request)

0 commit comments

Comments
 (0)