2024-01-06 16:58:21

by Sanath S

[permalink] [raw]
Subject: [Patch v3 0/4] Add support for downstream port reset(DPR)

Tunnels created by boot firmware results in incorrect PCI resource
allocation, which results in failure of extending daisy chain.
This series aims to resolve inconsistent tunnels or paths created
by boot firmware.

Before:
+-03.1-[04-62]----00.0-[05-07]--+-02.0-[06]----00.0
| \-04.0-[07]--
After:
+-03.1-[04-62]----00.0-[05-62]--+-02.0-[06]----00.0
| \-04.0-[07-62]--

This series also aligns with windows behaviour of performing a teardown
of tunnels and resetting the downstream ports using DPR during the init
sequence.

Changes since V3:
- Remove discover_tunnel() api before resetting DPR.
- Add lane and protocol adapters reset in tb_switch_reset()
- Addition of tb_lc_reset_port() for TBT1, TBT2 and TBT3 routers.
- Addition of tb_path_deactivate_hop() api to help suppport path
reset of given hop index.
- Addition on new patch to store and indicate host router reset
status of USB4 v2

Changes since V2:
- Perform DPR only for USB4 routers.
- Update kernel-doc and return value to -EOPNOTSUPP.
- Limit delay range to 10-15ms.

Sanath S (4):
thunderbolt: Introduce usb4_port_reset() and tb_lc_reset_port()
thunderbolt: Extend tb_switch_reset() to support lane and protocol
adapter reset
thunderbolt: Store host router reset status in nhi_probe()
thunderbolt: Teardown tunnels and reset downstream ports created by
boot firmware

drivers/thunderbolt/domain.c | 5 +--
drivers/thunderbolt/icm.c | 2 +-
drivers/thunderbolt/lc.c | 44 +++++++++++++++++++++++++
drivers/thunderbolt/nhi.c | 19 +++++++----
drivers/thunderbolt/path.c | 13 ++++++++
drivers/thunderbolt/switch.c | 61 +++++++++++++++++++++++++++++++++--
drivers/thunderbolt/tb.c | 29 +++++++++++++----
drivers/thunderbolt/tb.h | 7 ++--
drivers/thunderbolt/tb_regs.h | 4 +++
drivers/thunderbolt/usb4.c | 39 ++++++++++++++++++++++
10 files changed, 202 insertions(+), 21 deletions(-)

--
2.34.1



2024-01-06 16:58:31

by Sanath S

[permalink] [raw]
Subject: [Patch v3 1/4] thunderbolt: Introduce usb4_port_reset() and tb_lc_reset_port()

Introduce the usb4_port_reset() function that performs the DPR
of a given port. This function follows the CM guide specification 7.3

Introduce tb_lc_reset_port() function that performs the DPR through
link control registers. Supports non-USB4 routers like TBT2 and TBT3.

Signed-off-by: Mika Westerberg <[email protected]>
Signed-off-by: Sanath S <[email protected]>
---
drivers/thunderbolt/lc.c | 44 +++++++++++++++++++++++++++++++++++
drivers/thunderbolt/tb_regs.h | 4 ++++
drivers/thunderbolt/usb4.c | 39 +++++++++++++++++++++++++++++++
3 files changed, 87 insertions(+)

diff --git a/drivers/thunderbolt/lc.c b/drivers/thunderbolt/lc.c
index 633970fbe9b0..de7276909a42 100644
--- a/drivers/thunderbolt/lc.c
+++ b/drivers/thunderbolt/lc.c
@@ -5,6 +5,7 @@
* Copyright (C) 2019, Intel Corporation
* Author: Mika Westerberg <[email protected]>
*/
+#include <linux/delay.h>

#include "tb.h"

@@ -45,6 +46,49 @@ static int find_port_lc_cap(struct tb_port *port)
return sw->cap_lc + start + phys * size;
}

+/**
+ * tb_lc_reset_port() - Trigger downstream port reset through LC
+ * @port: Port that is reset
+ *
+ * Triggers downstream port reset through link controller registers.
+ * Returns %0 in case of success negative errno otherwise. Only supports
+ * non-USB4 routers with link controller (that's Thunderbolt 2 and
+ * Thunderbolt 3).
+ */
+int tb_lc_reset_port(struct tb_port *port)
+{
+ struct tb_switch *sw = port->sw;
+ int cap, ret;
+ u32 mode;
+
+ if (sw->generation < 2)
+ return -EINVAL;
+
+ cap = find_port_lc_cap(port);
+ if (cap < 0)
+ return cap;
+
+ ret = tb_sw_read(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
+ if (ret)
+ return ret;
+
+ mode |= TB_LC_PORT_MODE_DPR;
+
+ ret = tb_sw_write(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
+ if (ret)
+ return ret;
+
+ fsleep(10000);
+
+ ret = tb_sw_read(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
+ if (ret)
+ return ret;
+
+ mode &= ~TB_LC_PORT_MODE_DPR;
+
+ return tb_sw_write(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
+}
+
static int tb_lc_set_port_configured(struct tb_port *port, bool configured)
{
bool upstream = tb_is_upstream_port(port);
diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
index 87e4795275fe..efcae298b370 100644
--- a/drivers/thunderbolt/tb_regs.h
+++ b/drivers/thunderbolt/tb_regs.h
@@ -389,6 +389,7 @@ struct tb_regs_port_header {
#define PORT_CS_18_CSA BIT(22)
#define PORT_CS_18_TIP BIT(24)
#define PORT_CS_19 0x13
+#define PORT_CS_19_DPR BIT(0)
#define PORT_CS_19_PC BIT(3)
#define PORT_CS_19_PID BIT(4)
#define PORT_CS_19_WOC BIT(16)
@@ -584,6 +585,9 @@ struct tb_regs_hop {
#define TB_LC_POWER 0x740

/* Link controller registers */
+#define TB_LC_PORT_MODE 0x26
+#define TB_LC_PORT_MODE_DPR BIT(0)
+
#define TB_LC_CS_42 0x2a
#define TB_LC_CS_42_USB_PLUGGED BIT(31)

diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
index f8f0d24ff6e4..4b35898aa216 100644
--- a/drivers/thunderbolt/usb4.c
+++ b/drivers/thunderbolt/usb4.c
@@ -1113,6 +1113,45 @@ int usb4_port_hotplug_enable(struct tb_port *port)
return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_5, 1);
}

+/**
+ * usb4_port_reset() - Issue downstream port reset
+ * @port: USB4 port to reset
+ *
+ * Issues downstream port reset to @port.
+ */
+int usb4_port_reset(struct tb_port *port)
+{
+ int ret;
+ u32 val;
+
+ if (!port->cap_usb4)
+ return -EINVAL;
+
+ ret = tb_port_read(port, &val, TB_CFG_PORT,
+ port->cap_usb4 + PORT_CS_19, 1);
+ if (ret)
+ return ret;
+
+ val |= PORT_CS_19_DPR;
+
+ ret = tb_port_write(port, &val, TB_CFG_PORT,
+ port->cap_usb4 + PORT_CS_19, 1);
+ if (ret)
+ return ret;
+
+ fsleep(10000);
+
+ ret = tb_port_read(port, &val, TB_CFG_PORT,
+ port->cap_usb4 + PORT_CS_19, 1);
+ if (ret)
+ return ret;
+
+ val &= ~PORT_CS_19_DPR;
+
+ return tb_port_write(port, &val, TB_CFG_PORT,
+ port->cap_usb4 + PORT_CS_19, 1);
+}
+
static int usb4_port_set_configured(struct tb_port *port, bool configured)
{
int ret;
--
2.34.1


2024-01-06 16:58:48

by Sanath S

[permalink] [raw]
Subject: [Patch v3 2/4] thunderbolt: Extend tb_switch_reset() to support lane and protocol adapter reset

Extend tb_switch_reset() to support resetting lane adapters and
protocol adapters for USB4 routers. Incase of lane adapters it
resets downstream port and its path config spaces and incase of
protocol adapters it disables the path and resets its path config
spaces.

Introduce tb_path_deactivate_hop() to deactivate path for given
hop index and lane/protocol adapter.

Signed-off-by: Mika Westerberg <[email protected]>
Signed-off-by: Sanath S <[email protected]>
---
drivers/thunderbolt/path.c | 13 ++++++++
drivers/thunderbolt/switch.c | 61 ++++++++++++++++++++++++++++++++++--
drivers/thunderbolt/tb.h | 3 ++
3 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c
index 091a81bbdbdc..f760e54cd9bd 100644
--- a/drivers/thunderbolt/path.c
+++ b/drivers/thunderbolt/path.c
@@ -446,6 +446,19 @@ static int __tb_path_deactivate_hop(struct tb_port *port, int hop_index,
return -ETIMEDOUT;
}

+/**
+ * tb_path_deactivate_hop() - Deactivate one path in path config space
+ * @port: Lane or protocol adapter
+ * @hop_index: HopID of the path to be cleared
+ *
+ * This deactivates or clears a single path config space entry at
+ * @hop_index. Returns %0 in success and negative errno otherwise.
+ */
+int tb_path_deactivate_hop(struct tb_port *port, int hop_index)
+{
+ return __tb_path_deactivate_hop(port, hop_index, true);
+}
+
static void __tb_path_deactivate_hops(struct tb_path *path, int first_hop)
{
int i, res;
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 44e9b09de47a..fec0078f15ef 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -676,6 +676,13 @@ int tb_port_disable(struct tb_port *port)
return __tb_port_enable(port, false);
}

+static int tb_port_reset(struct tb_port *port)
+{
+ if (tb_switch_is_usb4(port->sw))
+ return usb4_port_reset(port);
+ return tb_lc_reset_port(port);
+}
+
/*
* tb_init_port() - initialize a port
*
@@ -1550,18 +1557,66 @@ static void tb_dump_switch(const struct tb *tb, const struct tb_switch *sw)
/**
* tb_switch_reset() - reconfigure route, enable and send TB_CFG_PKG_RESET
* @sw: Switch to reset
+ * tb_switch_reset() - Perform reset to the router
+ * @sw: Router to reset
*
* Return: Returns 0 on success or an error code on failure.
+ * Issues reset to the router. Can be used for any router. Returns %0
+ * on success or an error code on failure.
*/
int tb_switch_reset(struct tb_switch *sw)
{
struct tb_cfg_result res;

- if (sw->generation > 1)
- return 0;
+ tb_sw_dbg(sw, "resetting router\n");
+
+ if (sw->generation > 1) {
+ struct tb_port *port;
+
+ tb_sw_dbg(sw, "resetting switch\n");
+ tb_switch_for_each_port(sw, port) {
+ int i, ret;
+
+ /*
+ * For lane adapters we issue downstream port
+ * reset and clear up path config spaces.
+ *
+ * For protocol adapters we disable the path and
+ * clear path config space one by one (from 8 to
+ * Max Input HopID of the adapter).
+ */
+ if (tb_port_is_null(port) && !tb_is_upstream_port(port)) {
+ if (!port->cap_usb4)
+ continue;
+ ret = tb_port_reset(port);
+ if (ret)
+ return ret;
+ } else if (tb_port_is_usb3_down(port) ||
+ tb_port_is_usb3_up(port)) {
+ tb_usb3_port_enable(port, false);
+ } else if (tb_port_is_dpin(port) ||
+ tb_port_is_dpout(port)) {
+ tb_dp_port_enable(port, false);
+ } else if (tb_port_is_pcie_down(port) ||
+ tb_port_is_pcie_up(port)) {
+ tb_pci_port_enable(port, false);
+ } else {
+ continue;
+ }

- tb_sw_dbg(sw, "resetting switch\n");
+ /* Cleanup path config space of protocol adapter */
+ for (i = TB_PATH_MIN_HOPID;
+ i <= port->config.max_in_hop_id; i++) {
+ ret = tb_path_deactivate_hop(port, i);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+ }

+ /* Thunderbolt 1 uses the "reset" config space packet */
res.err = tb_sw_write(sw, ((u32 *) &sw->config) + 2,
TB_CFG_SWITCH, 2, 2);
if (res.err)
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index e299e53473ae..030d6525cbc9 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -1132,6 +1132,7 @@ struct tb_path *tb_path_alloc(struct tb *tb, struct tb_port *src, int src_hopid,
void tb_path_free(struct tb_path *path);
int tb_path_activate(struct tb_path *path);
void tb_path_deactivate(struct tb_path *path);
+int tb_path_deactivate_hop(struct tb_port *port, int hop_index);
bool tb_path_is_invalid(struct tb_path *path);
bool tb_path_port_on_path(const struct tb_path *path,
const struct tb_port *port);
@@ -1151,6 +1152,7 @@ int tb_drom_read(struct tb_switch *sw);
int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid);

int tb_lc_read_uuid(struct tb_switch *sw, u32 *uuid);
+int tb_lc_reset_port(struct tb_port *port);
int tb_lc_configure_port(struct tb_port *port);
void tb_lc_unconfigure_port(struct tb_port *port);
int tb_lc_configure_xdomain(struct tb_port *port);
@@ -1283,6 +1285,7 @@ void usb4_switch_remove_ports(struct tb_switch *sw);

int usb4_port_unlock(struct tb_port *port);
int usb4_port_hotplug_enable(struct tb_port *port);
+int usb4_port_reset(struct tb_port *port);
int usb4_port_configure(struct tb_port *port);
void usb4_port_unconfigure(struct tb_port *port);
int usb4_port_configure_xdomain(struct tb_port *port, struct tb_xdomain *xd);
--
2.34.1


2024-01-06 16:59:19

by Sanath S

[permalink] [raw]
Subject: [Patch v3 4/4] thunderbolt: Teardown tunnels and reset downstream ports created by boot firmware

Boot firmware might have created tunnels of its own. Since we cannot
be sure they are usable for us. Tear them down and reset the ports
to handle it as a new hotplug for USB4 v1 routers.

Suggested-by: Mario Limonciello <[email protected]>
Signed-off-by: Sanath S <[email protected]>
---
drivers/thunderbolt/tb.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 740bf2ff1fcd..462616e3075c 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -2596,12 +2596,27 @@ static int tb_start(struct tb *tb, bool reset)
tb_switch_tmu_configure(tb->root_switch, TB_SWITCH_TMU_MODE_LOWRES);
/* Enable TMU if it is off */
tb_switch_tmu_enable(tb->root_switch);
- /* 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 */
- tb_discover_tunnels(tb);
- /* Add DP resources from the DP tunnels created by the boot firmware */
- tb_discover_dp_resources(tb);
+
+ /*
+ * Boot firmware might have created tunnels of its own. Since we cannot
+ * be sure they are usable for us, Tear them down and reset the ports
+ * to handle it as new hotplug for USB4 routers.
+ */
+ if (reset && usb4_switch_version(tb->root_switch) == 1) {
+ ret = tb_switch_reset(tb->root_switch);
+ if (ret) {
+ tb_sw_warn(tb->root_switch, "failed to reset\n");
+ return ret;
+ }
+ } else {
+ /* 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 */
+ tb_discover_tunnels(tb);
+ /* Add DP resources from the DP tunnels created by the boot firmware */
+ tb_discover_dp_resources(tb);
+ }
+
/*
* If the boot firmware did not create USB 3.x tunnels create them
* now for the whole topology.
--
2.34.1


2024-01-06 16:59:40

by Sanath S

[permalink] [raw]
Subject: [Patch v3 3/4] thunderbolt: Store host router reset status in nhi_probe()

Currently we do host reset of USB4 v2 in nhi_reset().
In prepration to introduce host rest for USB4 v1, pass on the
reset status to tb_domain_add() to avoid resetting the USB4 v2
routers again.

This boolean helps in resetting only USB4 v1 host routers and
skips resetting v2 routers when reset is introduced for v1 routers.

Signed-off-by: Mika Westerberg <[email protected]>
Signed-off-by: Sanath S <[email protected]>
---
drivers/thunderbolt/domain.c | 5 +++--
drivers/thunderbolt/icm.c | 2 +-
drivers/thunderbolt/nhi.c | 19 +++++++++++++------
drivers/thunderbolt/tb.c | 2 +-
drivers/thunderbolt/tb.h | 4 ++--
5 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c
index ec7b5f65804e..31f3da4e6a08 100644
--- a/drivers/thunderbolt/domain.c
+++ b/drivers/thunderbolt/domain.c
@@ -423,6 +423,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize
/**
* tb_domain_add() - Add domain to the system
* @tb: Domain to add
+ * @reset: Issue reset to the host router
*
* Starts the domain and adds it to the system. Hotplugging devices will
* work after this has been returned successfully. In order to remove
@@ -431,7 +432,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize
*
* Return: %0 in case of success and negative errno in case of error
*/
-int tb_domain_add(struct tb *tb)
+int tb_domain_add(struct tb *tb, bool reset)
{
int ret;

@@ -460,7 +461,7 @@ int tb_domain_add(struct tb *tb)

/* Start the domain */
if (tb->cm_ops->start) {
- ret = tb->cm_ops->start(tb);
+ ret = tb->cm_ops->start(tb, reset);
if (ret)
goto err_domain_del;
}
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index d8b9c734abd3..623aa81a8833 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -2144,7 +2144,7 @@ static int icm_runtime_resume(struct tb *tb)
return 0;
}

-static int icm_start(struct tb *tb)
+static int icm_start(struct tb *tb, bool not_used)
{
struct icm *icm = tb_priv(tb);
int ret;
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index 4b7bec74e89f..1ec6f9c82aef 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -1221,7 +1221,7 @@ static void nhi_check_iommu(struct tb_nhi *nhi)
str_enabled_disabled(port_ok));
}

-static void nhi_reset(struct tb_nhi *nhi)
+static bool nhi_reset(struct tb_nhi *nhi)
{
ktime_t timeout;
u32 val;
@@ -1229,11 +1229,11 @@ static void nhi_reset(struct tb_nhi *nhi)
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;
+ return false;

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

iowrite32(REG_RESET_HRR, nhi->iobase + REG_RESET);
@@ -1244,12 +1244,14 @@ static void 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;
+ return true;
}
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)
@@ -1331,6 +1333,7 @@ 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))
@@ -1365,7 +1368,11 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
nhi_check_quirks(nhi);
nhi_check_iommu(nhi);

- nhi_reset(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;

res = nhi_init_msi(nhi);
if (res)
@@ -1392,7 +1399,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);
+ res = tb_domain_add(tb, reset);
if (res) {
/*
* At this point the RX/TX rings might already have been
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index fd49f86e0353..740bf2ff1fcd 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -2555,7 +2555,7 @@ static int tb_scan_finalize_switch(struct device *dev, void *data)
return 0;
}

-static int tb_start(struct tb *tb)
+static int tb_start(struct tb *tb, bool reset)
{
struct tb_cm *tcm = tb_priv(tb);
int ret;
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 030d6525cbc9..be419fc87a21 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -481,7 +481,7 @@ struct tb_path {
*/
struct tb_cm_ops {
int (*driver_ready)(struct tb *tb);
- int (*start)(struct tb *tb);
+ int (*start)(struct tb *tb, bool reset);
void (*stop)(struct tb *tb);
int (*suspend_noirq)(struct tb *tb);
int (*resume_noirq)(struct tb *tb);
@@ -728,7 +728,7 @@ int tb_xdomain_init(void);
void tb_xdomain_exit(void);

struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize);
-int tb_domain_add(struct tb *tb);
+int tb_domain_add(struct tb *tb, bool reset);
void tb_domain_remove(struct tb *tb);
int tb_domain_suspend_noirq(struct tb *tb);
int tb_domain_resume_noirq(struct tb *tb);
--
2.34.1


2024-01-10 14:33:28

by Mika Westerberg

[permalink] [raw]
Subject: Re: [Patch v3 0/4] Add support for downstream port reset(DPR)

Hi,

On Sat, Jan 06, 2024 at 10:27:19PM +0530, Sanath S wrote:
> Tunnels created by boot firmware results in incorrect PCI resource
> allocation, which results in failure of extending daisy chain.
> This series aims to resolve inconsistent tunnels or paths created
> by boot firmware.
>
> Before:
> +-03.1-[04-62]----00.0-[05-07]--+-02.0-[06]----00.0
> | \-04.0-[07]--
> After:
> +-03.1-[04-62]----00.0-[05-62]--+-02.0-[06]----00.0
> | \-04.0-[07-62]--
>
> This series also aligns with windows behaviour of performing a teardown
> of tunnels and resetting the downstream ports using DPR during the init
> sequence.
>
> Changes since V3:
> - Remove discover_tunnel() api before resetting DPR.
> - Add lane and protocol adapters reset in tb_switch_reset()
> - Addition of tb_lc_reset_port() for TBT1, TBT2 and TBT3 routers.
> - Addition of tb_path_deactivate_hop() api to help suppport path
> reset of given hop index.
> - Addition on new patch to store and indicate host router reset
> status of USB4 v2
>
> Changes since V2:
> - Perform DPR only for USB4 routers.
> - Update kernel-doc and return value to -EOPNOTSUPP.
> - Limit delay range to 10-15ms.
>
> Sanath S (4):
> thunderbolt: Introduce usb4_port_reset() and tb_lc_reset_port()
> thunderbolt: Extend tb_switch_reset() to support lane and protocol
> adapter reset
> thunderbolt: Store host router reset status in nhi_probe()
> thunderbolt: Teardown tunnels and reset downstream ports created by
> boot firmware

Thanks for the series!

I will give this a try on our end too to make sure there are no issues.
If things look good I will queue these for v6.9 after v6.8-rc1 is
released.

2024-01-10 15:32:59

by Sanath S

[permalink] [raw]
Subject: Re: [Patch v3 0/4] Add support for downstream port reset(DPR)


On 1/10/2024 8:01 PM, Mika Westerberg wrote:
> Hi,
>
> On Sat, Jan 06, 2024 at 10:27:19PM +0530, Sanath S wrote:
>> Tunnels created by boot firmware results in incorrect PCI resource
>> allocation, which results in failure of extending daisy chain.
>> This series aims to resolve inconsistent tunnels or paths created
>> by boot firmware.
>>
>> Before:
>> +-03.1-[04-62]----00.0-[05-07]--+-02.0-[06]----00.0
>> | \-04.0-[07]--
>> After:
>> +-03.1-[04-62]----00.0-[05-62]--+-02.0-[06]----00.0
>> | \-04.0-[07-62]--
>>
>> This series also aligns with windows behaviour of performing a teardown
>> of tunnels and resetting the downstream ports using DPR during the init
>> sequence.
>>
>> Changes since V3:
>> - Remove discover_tunnel() api before resetting DPR.
>> - Add lane and protocol adapters reset in tb_switch_reset()
>> - Addition of tb_lc_reset_port() for TBT1, TBT2 and TBT3 routers.
>> - Addition of tb_path_deactivate_hop() api to help suppport path
>> reset of given hop index.
>> - Addition on new patch to store and indicate host router reset
>> status of USB4 v2
>>
>> Changes since V2:
>> - Perform DPR only for USB4 routers.
>> - Update kernel-doc and return value to -EOPNOTSUPP.
>> - Limit delay range to 10-15ms.
>>
>> Sanath S (4):
>> thunderbolt: Introduce usb4_port_reset() and tb_lc_reset_port()
>> thunderbolt: Extend tb_switch_reset() to support lane and protocol
>> adapter reset
>> thunderbolt: Store host router reset status in nhi_probe()
>> thunderbolt: Teardown tunnels and reset downstream ports created by
>> boot firmware
> Thanks for the series!
>
> I will give this a try on our end too to make sure there are no issues.
> If things look good I will queue these for v6.9 after v6.8-rc1 is
> released.

Thanks Mika :)
Looking forward for results at your end.


2024-01-22 12:30:49

by Mika Westerberg

[permalink] [raw]
Subject: Re: [Patch v3 0/4] Add support for downstream port reset(DPR)

On Sat, Jan 06, 2024 at 10:27:19PM +0530, Sanath S wrote:
> Tunnels created by boot firmware results in incorrect PCI resource
> allocation, which results in failure of extending daisy chain.
> This series aims to resolve inconsistent tunnels or paths created
> by boot firmware.
>
> Before:
> +-03.1-[04-62]----00.0-[05-07]--+-02.0-[06]----00.0
> | \-04.0-[07]--
> After:
> +-03.1-[04-62]----00.0-[05-62]--+-02.0-[06]----00.0
> | \-04.0-[07-62]--
>
> This series also aligns with windows behaviour of performing a teardown
> of tunnels and resetting the downstream ports using DPR during the init
> sequence.
>
> Changes since V3:
> - Remove discover_tunnel() api before resetting DPR.
> - Add lane and protocol adapters reset in tb_switch_reset()
> - Addition of tb_lc_reset_port() for TBT1, TBT2 and TBT3 routers.
> - Addition of tb_path_deactivate_hop() api to help suppport path
> reset of given hop index.
> - Addition on new patch to store and indicate host router reset
> status of USB4 v2
>
> Changes since V2:
> - Perform DPR only for USB4 routers.
> - Update kernel-doc and return value to -EOPNOTSUPP.
> - Limit delay range to 10-15ms.
>
> Sanath S (4):
> thunderbolt: Introduce usb4_port_reset() and tb_lc_reset_port()
> thunderbolt: Extend tb_switch_reset() to support lane and protocol
> adapter reset
> thunderbolt: Store host router reset status in nhi_probe()
> thunderbolt: Teardown tunnels and reset downstream ports created by
> boot firmware

All applied to thunderbolt.git/next, thanks! I did some tweaking to the
code and the changelogs. Please check and make sure your test cases
still pass.

These have been in our internal validation for a while and no issues
have been reported so far.