Skip to content

Commit c82510b

Browse files
committed
thunderbolt: Use scale field when allocating USB3 bandwidth
When tunneling aggregated USB3 (20 Gb/s) the bandwidth values that are programmed to the ADP_USB3_CS_2 go higher than 4096 and that does not fit anymore to the 12-bit field. Fix this by scaling the value using the scale field accordingly. Fixes: 3b1d8d5 ("thunderbolt: Implement USB3 bandwidth negotiation routines") Cc: [email protected] Signed-off-by: Mika Westerberg <[email protected]>
1 parent f0a57dd commit c82510b

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

drivers/thunderbolt/usb4.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,18 +2094,30 @@ static int usb4_usb3_port_write_allocated_bandwidth(struct tb_port *port,
20942094
int downstream_bw)
20952095
{
20962096
u32 val, ubw, dbw, scale;
2097-
int ret;
2097+
int ret, max_bw;
20982098

2099-
/* Read the used scale, hardware default is 0 */
2100-
ret = tb_port_read(port, &scale, TB_CFG_PORT,
2101-
port->cap_adap + ADP_USB3_CS_3, 1);
2099+
/* Figure out suitable scale */
2100+
scale = 0;
2101+
max_bw = max(upstream_bw, downstream_bw);
2102+
while (scale < 64) {
2103+
if (mbps_to_usb3_bw(max_bw, scale) < 4096)
2104+
break;
2105+
scale++;
2106+
}
2107+
2108+
if (WARN_ON(scale >= 64))
2109+
return -EINVAL;
2110+
2111+
ret = tb_port_write(port, &scale, TB_CFG_PORT,
2112+
port->cap_adap + ADP_USB3_CS_3, 1);
21022113
if (ret)
21032114
return ret;
21042115

2105-
scale &= ADP_USB3_CS_3_SCALE_MASK;
21062116
ubw = mbps_to_usb3_bw(upstream_bw, scale);
21072117
dbw = mbps_to_usb3_bw(downstream_bw, scale);
21082118

2119+
tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale);
2120+
21092121
ret = tb_port_read(port, &val, TB_CFG_PORT,
21102122
port->cap_adap + ADP_USB3_CS_2, 1);
21112123
if (ret)

0 commit comments

Comments
 (0)