Skip to content

Commit

Permalink
thunderbolt: Skip discovery also in USB4 v2 host
Browse files Browse the repository at this point in the history
If the host router is reset, there is no point running discovery as the
links are down. Furthermore this prevents CL-state enabling. For this
reason skip discovery in USB4 v2 host the same way we do with USB4 v1.

Reviewed-by: Mario Limonciello <[email protected]>
Signed-off-by: Mika Westerberg <[email protected]>
  • Loading branch information
westeri committed Feb 13, 2024
1 parent 8cf9926 commit 6faa39e
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 17 deletions.
20 changes: 6 additions & 14 deletions drivers/thunderbolt/nhi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1221,19 +1221,19 @@ static void nhi_check_iommu(struct tb_nhi *nhi)
str_enabled_disabled(port_ok));
}

static bool nhi_reset(struct tb_nhi *nhi)
static void nhi_reset(struct tb_nhi *nhi)
{
ktime_t timeout;
u32 val;

val = ioread32(nhi->iobase + REG_CAPS);
/* Reset only v2 and later routers */
if (FIELD_GET(REG_CAPS_VERSION_MASK, val) < REG_CAPS_VERSION_2)
return false;
return;

if (!host_reset) {
dev_dbg(&nhi->pdev->dev, "skipping host router reset\n");
return false;
return;
}

iowrite32(REG_RESET_HRR, nhi->iobase + REG_RESET);
Expand All @@ -1244,14 +1244,12 @@ static bool nhi_reset(struct tb_nhi *nhi)
val = ioread32(nhi->iobase + REG_RESET);
if (!(val & REG_RESET_HRR)) {
dev_warn(&nhi->pdev->dev, "host router reset successful\n");
return true;
return;
}
usleep_range(10, 20);
} while (ktime_before(ktime_get(), timeout));

dev_warn(&nhi->pdev->dev, "timeout resetting host router\n");

return false;
}

static int nhi_init_msi(struct tb_nhi *nhi)
Expand Down Expand Up @@ -1333,7 +1331,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct device *dev = &pdev->dev;
struct tb_nhi *nhi;
struct tb *tb;
bool reset;
int res;

if (!nhi_imr_valid(pdev))
Expand Down Expand Up @@ -1367,12 +1364,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)

nhi_check_quirks(nhi);
nhi_check_iommu(nhi);

/*
* Only USB4 v2 hosts support host reset so if we already did
* that then don't do it again when the domain is initialized.
*/
reset = nhi_reset(nhi) ? false : host_reset;
nhi_reset(nhi);

res = nhi_init_msi(nhi);
if (res)
Expand All @@ -1399,7 +1391,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)

dev_dbg(dev, "NHI initialized, starting thunderbolt\n");

res = tb_domain_add(tb, reset);
res = tb_domain_add(tb, host_reset);
if (res) {
/*
* At this point the RX/TX rings might already have been
Expand Down
11 changes: 8 additions & 3 deletions drivers/thunderbolt/tb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2584,6 +2584,7 @@ static int tb_scan_finalize_switch(struct device *dev, void *data)
static int tb_start(struct tb *tb, bool reset)
{
struct tb_cm *tcm = tb_priv(tb);
bool discover = true;
int ret;

tb->root_switch = tb_switch_alloc(tb, &tb->dev, 0);
Expand Down Expand Up @@ -2629,9 +2630,13 @@ static int tb_start(struct tb *tb, bool reset)
* reset the ports to handle it as new hotplug for USB4 v1
* routers (for USB4 v2 and beyond we already do host reset).
*/
if (reset && usb4_switch_version(tb->root_switch) == 1) {
tb_switch_reset(tb->root_switch);
} else {
if (reset && tb_switch_is_usb4(tb->root_switch)) {
discover = false;
if (usb4_switch_version(tb->root_switch) == 1)
tb_switch_reset(tb->root_switch);
}

if (discover) {
/* Full scan to discover devices added before the driver was loaded. */
tb_scan_switch(tb->root_switch);
/* Find out tunnels created by the boot firmware */
Expand Down

0 comments on commit 6faa39e

Please sign in to comment.