summaryrefslogtreecommitdiffstats
path: root/drivers/thunderbolt
diff options
context:
space:
mode:
authorGil Fine <gil.fine@linux.intel.com>2023-11-15 12:09:53 +0200
committerMika Westerberg <mika.westerberg@linux.intel.com>2023-12-14 08:07:45 +0200
commit3c052ec6f4f866163573445a02d60b629805a6e7 (patch)
tree92d859b560adbfda1ecc6dc98abb154f4b4782c6 /drivers/thunderbolt
parentea20adddd6c154e9e107c47fbf1b4697e68180df (diff)
downloadlinux-stable-3c052ec6f4f866163573445a02d60b629805a6e7.tar.gz
linux-stable-3c052ec6f4f866163573445a02d60b629805a6e7.tar.bz2
linux-stable-3c052ec6f4f866163573445a02d60b629805a6e7.zip
thunderbolt: Transition link to asymmetric only when both sides support it
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>
Diffstat (limited to 'drivers/thunderbolt')
-rw-r--r--drivers/thunderbolt/tb.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 6ff3e9624301..f81e7cf53d69 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -1094,8 +1094,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);
@@ -1116,7 +1117,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) {
@@ -1126,13 +1128,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");
@@ -1141,7 +1145,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;