thunderbolt: Allocate credits according to router preferences

The USB4 Connection Manager guide provides detailed information how the
USB4 router buffer (credit) allocation information should be used by the
connection manager when it allocates buffers for different paths. This
patch implements it for Linux. For USB 3.x and DisplayPort we use
directly the router preferences. The rest of the buffer space is then
used for PCIe and DMA (peer-to-peer, XDomain) traffic. DMA tunnels
require at least one buffer and PCIe six, so if there is not enough
buffers we fail the tunnel creation.

For the legacy Thunderbolt 1-3 devices we use the existing hard-coded
scheme except for DMA where we use the values suggested by the USB4 spec
chapter 13.

Co-developed-by: Gil Fine <gil.fine@intel.com>
Signed-off-by: Gil Fine <gil.fine@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This commit is contained in:
Mika Westerberg
2021-03-22 18:09:35 +02:00
parent 69fea377e6
commit 6ed541c53e
3 changed files with 346 additions and 74 deletions

View File

@@ -213,6 +213,8 @@ struct tb_switch {
* @list: Used to link ports to DP resources list
* @total_credits: Total number of buffers available for this port
* @ctl_credits: Buffers reserved for control path
* @dma_credits: Number of credits allocated for DMA tunneling for all
* DMA paths through this port.
*
* In USB4 terminology this structure represents an adapter (protocol or
* lane adapter).
@@ -236,6 +238,7 @@ struct tb_port {
struct list_head list;
unsigned int total_credits;
unsigned int ctl_credits;
unsigned int dma_credits;
};
/**
@@ -941,6 +944,17 @@ 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);
/**
* tb_path_for_each_hop() - Iterate over each hop on path
* @path: Path whose hops to iterate
* @hop: Hop used as iterator
*
* Iterates over each hop on path.
*/
#define tb_path_for_each_hop(path, hop) \
for ((hop) = &(path)->hops[0]; \
(hop) <= &(path)->hops[(path)->path_length - 1]; (hop)++)
int tb_drom_read(struct tb_switch *sw);
int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid);

File diff suppressed because it is too large Load Diff

View File

@@ -27,6 +27,7 @@ enum tb_tunnel_type {
* @paths: All paths required by the tunnel
* @npaths: Number of paths in @paths
* @init: Optional tunnel specific initialization
* @deinit: Optional tunnel specific de-initialization
* @activate: Optional tunnel specific activation/deactivation
* @consumed_bandwidth: Return how much bandwidth the tunnel consumes
* @release_unused_bandwidth: Release all unused bandwidth
@@ -47,6 +48,7 @@ struct tb_tunnel {
struct tb_path **paths;
size_t npaths;
int (*init)(struct tb_tunnel *tunnel);
void (*deinit)(struct tb_tunnel *tunnel);
int (*activate)(struct tb_tunnel *tunnel, bool activate);
int (*consumed_bandwidth)(struct tb_tunnel *tunnel, int *consumed_up,
int *consumed_down);