diff options
Diffstat (limited to 'drivers/thunderbolt')
-rw-r--r-- | drivers/thunderbolt/tb.c | 9 | ||||
-rw-r--r-- | drivers/thunderbolt/tunnel.c | 47 | ||||
-rw-r--r-- | drivers/thunderbolt/tunnel.h | 6 |
3 files changed, 47 insertions, 15 deletions
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 9dbdb11685fa..53f9673c1395 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -535,7 +535,7 @@ static int tb_available_bw(struct tb_cm *tcm, struct tb_port *in, { struct tb_switch *sw = out->sw; struct tb_tunnel *tunnel; - int bw, available_bw = 40000; + int ret, bw, available_bw = 40000; while (sw && sw != in->sw) { bw = sw->link_speed * sw->link_width * 1000; /* Mb/s */ @@ -553,9 +553,10 @@ static int tb_available_bw(struct tb_cm *tcm, struct tb_port *in, if (!tb_tunnel_switch_on_path(tunnel, sw)) continue; - consumed_bw = tb_tunnel_consumed_bandwidth(tunnel); - if (consumed_bw < 0) - return consumed_bw; + ret = tb_tunnel_consumed_bandwidth(tunnel, NULL, + &consumed_bw); + if (ret) + return ret; bw -= consumed_bw; } diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 5bdb8b11345e..45f7a50a48ff 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -536,7 +536,8 @@ static int tb_dp_activate(struct tb_tunnel *tunnel, bool active) return 0; } -static int tb_dp_consumed_bandwidth(struct tb_tunnel *tunnel) +static int tb_dp_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, + int *consumed_down) { struct tb_port *in = tunnel->src_port; const struct tb_switch *sw = in->sw; @@ -580,10 +581,20 @@ static int tb_dp_consumed_bandwidth(struct tb_tunnel *tunnel) lanes = tb_dp_cap_get_lanes(val); } else { /* No bandwidth management for legacy devices */ + *consumed_up = 0; + *consumed_down = 0; return 0; } - return tb_dp_bandwidth(rate, lanes); + if (in->sw->config.depth < tunnel->dst_port->sw->config.depth) { + *consumed_up = 0; + *consumed_down = tb_dp_bandwidth(rate, lanes); + } else { + *consumed_up = tb_dp_bandwidth(rate, lanes); + *consumed_down = 0; + } + + return 0; } static void tb_dp_init_aux_path(struct tb_path *path) @@ -1174,21 +1185,39 @@ static bool tb_tunnel_is_active(const struct tb_tunnel *tunnel) /** * tb_tunnel_consumed_bandwidth() - Return bandwidth consumed by the tunnel * @tunnel: Tunnel to check + * @consumed_up: Consumed bandwidth in Mb/s from @dst_port to @src_port. + * Can be %NULL. + * @consumed_down: Consumed bandwidth in Mb/s from @src_port to @dst_port. + * Can be %NULL. * - * Returns bandwidth currently consumed by @tunnel and %0 if the @tunnel - * is not active or does consume bandwidth. + * Stores the amount of isochronous bandwidth @tunnel consumes in + * @consumed_up and @consumed_down. In case of success returns %0, + * negative errno otherwise. */ -int tb_tunnel_consumed_bandwidth(struct tb_tunnel *tunnel) +int tb_tunnel_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, + int *consumed_down) { + int up_bw = 0, down_bw = 0; + if (!tb_tunnel_is_active(tunnel)) - return 0; + goto out; if (tunnel->consumed_bandwidth) { - int ret = tunnel->consumed_bandwidth(tunnel); + int ret; - tb_tunnel_dbg(tunnel, "consumed bandwidth %d Mb/s\n", ret); - return ret; + ret = tunnel->consumed_bandwidth(tunnel, &up_bw, &down_bw); + if (ret) + return ret; + + tb_tunnel_dbg(tunnel, "consumed bandwidth %d/%d Mb/s\n", up_bw, + down_bw); } +out: + if (consumed_up) + *consumed_up = up_bw; + if (consumed_down) + *consumed_down = down_bw; + return 0; } diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h index 3f5ba93225e7..cc952b2be792 100644 --- a/drivers/thunderbolt/tunnel.h +++ b/drivers/thunderbolt/tunnel.h @@ -42,7 +42,8 @@ struct tb_tunnel { size_t npaths; int (*init)(struct tb_tunnel *tunnel); int (*activate)(struct tb_tunnel *tunnel, bool activate); - int (*consumed_bandwidth)(struct tb_tunnel *tunnel); + int (*consumed_bandwidth)(struct tb_tunnel *tunnel, int *consumed_up, + int *consumed_down); struct list_head list; enum tb_tunnel_type type; unsigned int max_bw; @@ -69,7 +70,8 @@ void tb_tunnel_deactivate(struct tb_tunnel *tunnel); bool tb_tunnel_is_invalid(struct tb_tunnel *tunnel); bool tb_tunnel_switch_on_path(const struct tb_tunnel *tunnel, const struct tb_switch *sw); -int tb_tunnel_consumed_bandwidth(struct tb_tunnel *tunnel); +int tb_tunnel_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, + int *consumed_down); static inline bool tb_tunnel_is_pci(const struct tb_tunnel *tunnel) { |