Skip to content

Commit bbefb7e

Browse files
committed
Merge tag 'thunderbolt-for-v6.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-linus
Mika writes: thunderbolt: Fixes for v6.3-rc4 This includes following fixes and quirks for v6.3-rc: - Quirk to disable CL-states on AMD USB4 host routers - Fix memory leak in lane margining - Correct the retimer access flows - Quirk to limit USB3 bandwidth on certain Intel USB4 host routers - Fix usage of scale field when allocting USB3 bandwidth - Fix interrupt "auto clear" on non-Intel USB4 host routers. There are also two commits that are not fixes themselves but are needed for the USB3 bandwidth quirk and for the interrupt auto clear fix to work. All these have been in linux-next with no reported issues. * tag 'thunderbolt-for-v6.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: thunderbolt: Rename shadowed variables bit to interrupt_bit and auto_clear_bit thunderbolt: Disable interrupt auto clear for rings thunderbolt: Use const qualifier for `ring_interrupt_index` thunderbolt: Use scale field when allocating USB3 bandwidth thunderbolt: Limit USB3 bandwidth of certain Intel USB4 host routers thunderbolt: Call tb_check_quirks() after initializing adapters thunderbolt: Add missing UNSET_INBOUND_SBTX for retimer access thunderbolt: Fix memory leak in margining thunderbolt: Add quirk to disable CLx
2 parents bbf860e + 58cdfe6 commit bbefb7e

File tree

9 files changed

+166
-41
lines changed

9 files changed

+166
-41
lines changed

drivers/thunderbolt/debugfs.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,8 @@ static void margining_port_remove(struct tb_port *port)
942942

943943
snprintf(dir_name, sizeof(dir_name), "port%d", port->port);
944944
parent = debugfs_lookup(dir_name, port->sw->debugfs_dir);
945-
debugfs_remove_recursive(debugfs_lookup("margining", parent));
945+
if (parent)
946+
debugfs_remove_recursive(debugfs_lookup("margining", parent));
946947

947948
kfree(port->usb4->margining);
948949
port->usb4->margining = NULL;
@@ -967,19 +968,18 @@ static void margining_switch_init(struct tb_switch *sw)
967968

968969
static void margining_switch_remove(struct tb_switch *sw)
969970
{
971+
struct tb_port *upstream, *downstream;
970972
struct tb_switch *parent_sw;
971-
struct tb_port *downstream;
972973
u64 route = tb_route(sw);
973974

974975
if (!route)
975976
return;
976977

977-
/*
978-
* Upstream is removed with the router itself but we need to
979-
* remove the downstream port margining directory.
980-
*/
978+
upstream = tb_upstream_port(sw);
981979
parent_sw = tb_switch_parent(sw);
982980
downstream = tb_port_at(route, parent_sw);
981+
982+
margining_port_remove(upstream);
983983
margining_port_remove(downstream);
984984
}
985985

drivers/thunderbolt/nhi.c

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
#define QUIRK_AUTO_CLEAR_INT BIT(0)
4747
#define QUIRK_E2E BIT(1)
4848

49-
static int ring_interrupt_index(struct tb_ring *ring)
49+
static int ring_interrupt_index(const struct tb_ring *ring)
5050
{
5151
int bit = ring->hop;
5252
if (!ring->is_tx)
@@ -63,32 +63,40 @@ static void ring_interrupt_active(struct tb_ring *ring, bool active)
6363
{
6464
int reg = REG_RING_INTERRUPT_BASE +
6565
ring_interrupt_index(ring) / 32 * 4;
66-
int bit = ring_interrupt_index(ring) & 31;
67-
int mask = 1 << bit;
66+
int interrupt_bit = ring_interrupt_index(ring) & 31;
67+
int mask = 1 << interrupt_bit;
6868
u32 old, new;
6969

7070
if (ring->irq > 0) {
7171
u32 step, shift, ivr, misc;
7272
void __iomem *ivr_base;
73+
int auto_clear_bit;
7374
int index;
7475

7576
if (ring->is_tx)
7677
index = ring->hop;
7778
else
7879
index = ring->hop + ring->nhi->hop_count;
7980

80-
if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) {
81-
/*
82-
* Ask the hardware to clear interrupt status
83-
* bits automatically since we already know
84-
* which interrupt was triggered.
85-
*/
86-
misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
87-
if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) {
88-
misc |= REG_DMA_MISC_INT_AUTO_CLEAR;
89-
iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC);
90-
}
91-
}
81+
/*
82+
* Intel routers support a bit that isn't part of
83+
* the USB4 spec to ask the hardware to clear
84+
* interrupt status bits automatically since
85+
* we already know which interrupt was triggered.
86+
*
87+
* Other routers explicitly disable auto-clear
88+
* to prevent conditions that may occur where two
89+
* MSIX interrupts are simultaneously active and
90+
* reading the register clears both of them.
91+
*/
92+
misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
93+
if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
94+
auto_clear_bit = REG_DMA_MISC_INT_AUTO_CLEAR;
95+
else
96+
auto_clear_bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR;
97+
if (!(misc & auto_clear_bit))
98+
iowrite32(misc | auto_clear_bit,
99+
ring->nhi->iobase + REG_DMA_MISC);
92100

93101
ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE;
94102
step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS;
@@ -108,7 +116,7 @@ static void ring_interrupt_active(struct tb_ring *ring, bool active)
108116

109117
dev_dbg(&ring->nhi->pdev->dev,
110118
"%s interrupt at register %#x bit %d (%#x -> %#x)\n",
111-
active ? "enabling" : "disabling", reg, bit, old, new);
119+
active ? "enabling" : "disabling", reg, interrupt_bit, old, new);
112120

113121
if (new == old)
114122
dev_WARN(&ring->nhi->pdev->dev,
@@ -393,14 +401,17 @@ EXPORT_SYMBOL_GPL(tb_ring_poll_complete);
393401

394402
static void ring_clear_msix(const struct tb_ring *ring)
395403
{
404+
int bit;
405+
396406
if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
397407
return;
398408

409+
bit = ring_interrupt_index(ring) & 31;
399410
if (ring->is_tx)
400-
ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE);
411+
iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR);
401412
else
402-
ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE +
403-
4 * (ring->nhi->hop_count / 32));
413+
iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR +
414+
4 * (ring->nhi->hop_count / 32));
404415
}
405416

406417
static irqreturn_t ring_msix(int irq, void *data)

drivers/thunderbolt/nhi_regs.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ struct ring_desc {
7777

7878
/*
7979
* three bitfields: tx, rx, rx overflow
80-
* Every bitfield contains one bit for every hop (REG_HOP_COUNT). Registers are
81-
* cleared on read. New interrupts are fired only after ALL registers have been
80+
* Every bitfield contains one bit for every hop (REG_HOP_COUNT).
81+
* New interrupts are fired only after ALL registers have been
8282
* read (even those containing only disabled rings).
8383
*/
8484
#define REG_RING_NOTIFY_BASE 0x37800
8585
#define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
86+
#define REG_RING_INT_CLEAR 0x37808
8687

8788
/*
8889
* two bitfields: rx, tx
@@ -105,6 +106,7 @@ struct ring_desc {
105106

106107
#define REG_DMA_MISC 0x39864
107108
#define REG_DMA_MISC_INT_AUTO_CLEAR BIT(2)
109+
#define REG_DMA_MISC_DISABLE_AUTO_CLEAR BIT(17)
108110

109111
#define REG_INMAIL_DATA 0x39900
110112

drivers/thunderbolt/quirks.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,25 @@ static void quirk_dp_credit_allocation(struct tb_switch *sw)
2020
}
2121
}
2222

23+
static void quirk_clx_disable(struct tb_switch *sw)
24+
{
25+
sw->quirks |= QUIRK_NO_CLX;
26+
tb_sw_dbg(sw, "disabling CL states\n");
27+
}
28+
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+
2342
struct tb_quirk {
2443
u16 hw_vendor_id;
2544
u16 hw_device_id;
@@ -37,6 +56,31 @@ static const struct tb_quirk tb_quirks[] = {
3756
* DP buffers.
3857
*/
3958
{ 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 },
77+
/*
78+
* CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms.
79+
*/
80+
{ 0x0438, 0x0208, 0x0000, 0x0000, quirk_clx_disable },
81+
{ 0x0438, 0x0209, 0x0000, 0x0000, quirk_clx_disable },
82+
{ 0x0438, 0x020a, 0x0000, 0x0000, quirk_clx_disable },
83+
{ 0x0438, 0x020b, 0x0000, 0x0000, quirk_clx_disable },
4084
};
4185

4286
/**

drivers/thunderbolt/retimer.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,22 @@ static ssize_t nvm_authenticate_show(struct device *dev,
187187
return ret;
188188
}
189189

190+
static void tb_retimer_set_inbound_sbtx(struct tb_port *port)
191+
{
192+
int i;
193+
194+
for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
195+
usb4_port_retimer_set_inbound_sbtx(port, i);
196+
}
197+
198+
static void tb_retimer_unset_inbound_sbtx(struct tb_port *port)
199+
{
200+
int i;
201+
202+
for (i = TB_MAX_RETIMER_INDEX; i >= 1; i--)
203+
usb4_port_retimer_unset_inbound_sbtx(port, i);
204+
}
205+
190206
static ssize_t nvm_authenticate_store(struct device *dev,
191207
struct device_attribute *attr, const char *buf, size_t count)
192208
{
@@ -213,6 +229,7 @@ static ssize_t nvm_authenticate_store(struct device *dev,
213229
rt->auth_status = 0;
214230

215231
if (val) {
232+
tb_retimer_set_inbound_sbtx(rt->port);
216233
if (val == AUTHENTICATE_ONLY) {
217234
ret = tb_retimer_nvm_authenticate(rt, true);
218235
} else {
@@ -232,6 +249,7 @@ static ssize_t nvm_authenticate_store(struct device *dev,
232249
}
233250

234251
exit_unlock:
252+
tb_retimer_unset_inbound_sbtx(rt->port);
235253
mutex_unlock(&rt->tb->lock);
236254
exit_rpm:
237255
pm_runtime_mark_last_busy(&rt->dev);
@@ -440,8 +458,7 @@ int tb_retimer_scan(struct tb_port *port, bool add)
440458
* Enable sideband channel for each retimer. We can do this
441459
* regardless whether there is device connected or not.
442460
*/
443-
for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
444-
usb4_port_retimer_set_inbound_sbtx(port, i);
461+
tb_retimer_set_inbound_sbtx(port);
445462

446463
/*
447464
* Before doing anything else, read the authentication status.
@@ -464,6 +481,8 @@ int tb_retimer_scan(struct tb_port *port, bool add)
464481
break;
465482
}
466483

484+
tb_retimer_unset_inbound_sbtx(port);
485+
467486
if (!last_idx)
468487
return 0;
469488

drivers/thunderbolt/sb_regs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ enum usb4_sb_opcode {
2020
USB4_SB_OPCODE_ROUTER_OFFLINE = 0x4e45534c, /* "LSEN" */
2121
USB4_SB_OPCODE_ENUMERATE_RETIMERS = 0x4d554e45, /* "ENUM" */
2222
USB4_SB_OPCODE_SET_INBOUND_SBTX = 0x5055534c, /* "LSUP" */
23+
USB4_SB_OPCODE_UNSET_INBOUND_SBTX = 0x50555355, /* "USUP" */
2324
USB4_SB_OPCODE_QUERY_LAST_RETIMER = 0x5453414c, /* "LAST" */
2425
USB4_SB_OPCODE_GET_NVM_SECTOR_SIZE = 0x53534e47, /* "GNSS" */
2526
USB4_SB_OPCODE_NVM_SET_OFFSET = 0x53504f42, /* "BOPS" */

drivers/thunderbolt/switch.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2968,8 +2968,6 @@ int tb_switch_add(struct tb_switch *sw)
29682968
dev_warn(&sw->dev, "reading DROM failed: %d\n", ret);
29692969
tb_sw_dbg(sw, "uid: %#llx\n", sw->uid);
29702970

2971-
tb_check_quirks(sw);
2972-
29732971
ret = tb_switch_set_uuid(sw);
29742972
if (ret) {
29752973
dev_err(&sw->dev, "failed to set UUID\n");
@@ -2988,6 +2986,8 @@ int tb_switch_add(struct tb_switch *sw)
29882986
}
29892987
}
29902988

2989+
tb_check_quirks(sw);
2990+
29912991
tb_switch_default_link_ports(sw);
29922992

29932993
ret = tb_switch_update_link_attributes(sw);

drivers/thunderbolt/tb.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
#define NVM_MAX_SIZE SZ_512K
2424
#define NVM_DATA_DWORDS 16
2525

26+
/* Keep link controller awake during update */
27+
#define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0)
28+
/* Disable CLx if not supported */
29+
#define QUIRK_NO_CLX BIT(1)
30+
2631
/**
2732
* struct tb_nvm - Structure holding NVM information
2833
* @dev: Owner of the NVM
@@ -267,6 +272,8 @@ struct tb_bandwidth_group {
267272
* @group: Bandwidth allocation group the adapter is assigned to. Only
268273
* used for DP IN adapters for now.
269274
* @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.
270277
*
271278
* In USB4 terminology this structure represents an adapter (protocol or
272279
* lane adapter).
@@ -294,6 +301,7 @@ struct tb_port {
294301
unsigned int dma_credits;
295302
struct tb_bandwidth_group *group;
296303
struct list_head group_list;
304+
unsigned int max_bw;
297305
};
298306

299307
/**
@@ -1019,6 +1027,9 @@ static inline bool tb_switch_is_clx_enabled(const struct tb_switch *sw,
10191027
*/
10201028
static inline bool tb_switch_is_clx_supported(const struct tb_switch *sw)
10211029
{
1030+
if (sw->quirks & QUIRK_NO_CLX)
1031+
return false;
1032+
10221033
return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw);
10231034
}
10241035

@@ -1234,6 +1245,7 @@ int usb4_port_sw_margin(struct tb_port *port, unsigned int lanes, bool timing,
12341245
int usb4_port_sw_margin_errors(struct tb_port *port, u32 *errors);
12351246

12361247
int usb4_port_retimer_set_inbound_sbtx(struct tb_port *port, u8 index);
1248+
int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index);
12371249
int usb4_port_retimer_read(struct tb_port *port, u8 index, u8 reg, void *buf,
12381250
u8 size);
12391251
int usb4_port_retimer_write(struct tb_port *port, u8 index, u8 reg,
@@ -1291,9 +1303,6 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port);
12911303
void usb4_port_device_remove(struct usb4_port *usb4);
12921304
int usb4_port_device_resume(struct usb4_port *usb4);
12931305

1294-
/* Keep link controller awake during update */
1295-
#define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0)
1296-
12971306
void tb_check_quirks(struct tb_switch *sw);
12981307

12991308
#ifdef CONFIG_ACPI

0 commit comments

Comments
 (0)