diff mbox series

[05/11] thunderbolt: Transition link to asymmetric only when both sides support it

Message ID 20231204103828.1635531-6-mika.westerberg@linux.intel.com (mailing list archive)
State Accepted
Commit 3c052ec6f4f866163573445a02d60b629805a6e7
Headers show
Series Improvements and Lunar Lake support | expand

Commit Message

Mika Westerberg Dec. 4, 2023, 10:38 a.m. UTC
From: Gil Fine <gil.fine@linux.intel.com>

We can transition Gen 4 link to asymmetric only when both sides of the
link support it in the required direction. For this reason make sure
that the downstream adapter also supports asymmetric link before
starting the transition.

Signed-off-by: Gil Fine <gil.fine@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/tb.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 3dabc1ac9ab3..6c5e8ce95f8d 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -1104,8 +1104,9 @@  static int tb_configure_asym(struct tb *tb, struct tb_port *src_port,
 	clx = tb_disable_clx(sw);
 
 	tb_for_each_upstream_port_on_path(src_port, dst_port, up) {
+		struct tb_port *down = tb_switch_downstream_port(up->sw);
+		enum tb_link_width width_up, width_down;
 		int consumed_up, consumed_down;
-		enum tb_link_width width;
 
 		ret = tb_consumed_dp_bandwidth(tb, src_port, dst_port, up,
 					       &consumed_up, &consumed_down);
@@ -1126,7 +1127,8 @@  static int tb_configure_asym(struct tb *tb, struct tb_port *src_port,
 			if (consumed_down + requested_down < asym_threshold)
 				continue;
 
-			width = TB_LINK_WIDTH_ASYM_RX;
+			width_up = TB_LINK_WIDTH_ASYM_RX;
+			width_down = TB_LINK_WIDTH_ASYM_TX;
 		} else {
 			/* Upstream, the opposite of above */
 			if (consumed_down + requested_down >= TB_ASYM_MIN) {
@@ -1136,13 +1138,15 @@  static int tb_configure_asym(struct tb *tb, struct tb_port *src_port,
 			if (consumed_up + requested_up < asym_threshold)
 				continue;
 
-			width = TB_LINK_WIDTH_ASYM_TX;
+			width_up = TB_LINK_WIDTH_ASYM_TX;
+			width_down = TB_LINK_WIDTH_ASYM_RX;
 		}
 
-		if (up->sw->link_width == width)
+		if (up->sw->link_width == width_up)
 			continue;
 
-		if (!tb_port_width_supported(up, width))
+		if (!tb_port_width_supported(up, width_up) ||
+		    !tb_port_width_supported(down, width_down))
 			continue;
 
 		tb_sw_dbg(up->sw, "configuring asymmetric link\n");
@@ -1151,7 +1155,7 @@  static int tb_configure_asym(struct tb *tb, struct tb_port *src_port,
 		 * Here requested + consumed > threshold so we need to
 		 * transtion the link into asymmetric now.
 		 */
-		ret = tb_switch_set_link_width(up->sw, width);
+		ret = tb_switch_set_link_width(up->sw, width_up);
 		if (ret) {
 			tb_sw_warn(up->sw, "failed to set link width\n");
 			break;