162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Thunderbolt driver - Tunneling support
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
662306a36Sopenharmony_ci * Copyright (C) 2019, Intel Corporation
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef TB_TUNNEL_H_
1062306a36Sopenharmony_ci#define TB_TUNNEL_H_
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include "tb.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cienum tb_tunnel_type {
1562306a36Sopenharmony_ci	TB_TUNNEL_PCI,
1662306a36Sopenharmony_ci	TB_TUNNEL_DP,
1762306a36Sopenharmony_ci	TB_TUNNEL_DMA,
1862306a36Sopenharmony_ci	TB_TUNNEL_USB3,
1962306a36Sopenharmony_ci};
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/**
2262306a36Sopenharmony_ci * struct tb_tunnel - Tunnel between two ports
2362306a36Sopenharmony_ci * @tb: Pointer to the domain
2462306a36Sopenharmony_ci * @src_port: Source port of the tunnel
2562306a36Sopenharmony_ci * @dst_port: Destination port of the tunnel. For discovered incomplete
2662306a36Sopenharmony_ci *	      tunnels may be %NULL or null adapter port instead.
2762306a36Sopenharmony_ci * @paths: All paths required by the tunnel
2862306a36Sopenharmony_ci * @npaths: Number of paths in @paths
2962306a36Sopenharmony_ci * @init: Optional tunnel specific initialization
3062306a36Sopenharmony_ci * @deinit: Optional tunnel specific de-initialization
3162306a36Sopenharmony_ci * @activate: Optional tunnel specific activation/deactivation
3262306a36Sopenharmony_ci * @maximum_bandwidth: Returns maximum possible bandwidth for this tunnel
3362306a36Sopenharmony_ci * @allocated_bandwidth: Return how much bandwidth is allocated for the tunnel
3462306a36Sopenharmony_ci * @alloc_bandwidth: Change tunnel bandwidth allocation
3562306a36Sopenharmony_ci * @consumed_bandwidth: Return how much bandwidth the tunnel consumes
3662306a36Sopenharmony_ci * @release_unused_bandwidth: Release all unused bandwidth
3762306a36Sopenharmony_ci * @reclaim_available_bandwidth: Reclaim back available bandwidth
3862306a36Sopenharmony_ci * @list: Tunnels are linked using this field
3962306a36Sopenharmony_ci * @type: Type of the tunnel
4062306a36Sopenharmony_ci * @max_up: Maximum upstream bandwidth (Mb/s) available for the tunnel.
4162306a36Sopenharmony_ci *	    Only set if the bandwidth needs to be limited.
4262306a36Sopenharmony_ci * @max_down: Maximum downstream bandwidth (Mb/s) available for the tunnel.
4362306a36Sopenharmony_ci *	      Only set if the bandwidth needs to be limited.
4462306a36Sopenharmony_ci * @allocated_up: Allocated upstream bandwidth (only for USB3)
4562306a36Sopenharmony_ci * @allocated_down: Allocated downstream bandwidth (only for USB3)
4662306a36Sopenharmony_ci * @bw_mode: DP bandwidth allocation mode registers can be used to
4762306a36Sopenharmony_ci *	     determine consumed and allocated bandwidth
4862306a36Sopenharmony_ci */
4962306a36Sopenharmony_cistruct tb_tunnel {
5062306a36Sopenharmony_ci	struct tb *tb;
5162306a36Sopenharmony_ci	struct tb_port *src_port;
5262306a36Sopenharmony_ci	struct tb_port *dst_port;
5362306a36Sopenharmony_ci	struct tb_path **paths;
5462306a36Sopenharmony_ci	size_t npaths;
5562306a36Sopenharmony_ci	int (*init)(struct tb_tunnel *tunnel);
5662306a36Sopenharmony_ci	void (*deinit)(struct tb_tunnel *tunnel);
5762306a36Sopenharmony_ci	int (*activate)(struct tb_tunnel *tunnel, bool activate);
5862306a36Sopenharmony_ci	int (*maximum_bandwidth)(struct tb_tunnel *tunnel, int *max_up,
5962306a36Sopenharmony_ci				 int *max_down);
6062306a36Sopenharmony_ci	int (*allocated_bandwidth)(struct tb_tunnel *tunnel, int *allocated_up,
6162306a36Sopenharmony_ci				   int *allocated_down);
6262306a36Sopenharmony_ci	int (*alloc_bandwidth)(struct tb_tunnel *tunnel, int *alloc_up,
6362306a36Sopenharmony_ci			       int *alloc_down);
6462306a36Sopenharmony_ci	int (*consumed_bandwidth)(struct tb_tunnel *tunnel, int *consumed_up,
6562306a36Sopenharmony_ci				  int *consumed_down);
6662306a36Sopenharmony_ci	int (*release_unused_bandwidth)(struct tb_tunnel *tunnel);
6762306a36Sopenharmony_ci	void (*reclaim_available_bandwidth)(struct tb_tunnel *tunnel,
6862306a36Sopenharmony_ci					    int *available_up,
6962306a36Sopenharmony_ci					    int *available_down);
7062306a36Sopenharmony_ci	struct list_head list;
7162306a36Sopenharmony_ci	enum tb_tunnel_type type;
7262306a36Sopenharmony_ci	int max_up;
7362306a36Sopenharmony_ci	int max_down;
7462306a36Sopenharmony_ci	int allocated_up;
7562306a36Sopenharmony_ci	int allocated_down;
7662306a36Sopenharmony_ci	bool bw_mode;
7762306a36Sopenharmony_ci};
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistruct tb_tunnel *tb_tunnel_discover_pci(struct tb *tb, struct tb_port *down,
8062306a36Sopenharmony_ci					 bool alloc_hopid);
8162306a36Sopenharmony_cistruct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up,
8262306a36Sopenharmony_ci				      struct tb_port *down);
8362306a36Sopenharmony_cistruct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in,
8462306a36Sopenharmony_ci					bool alloc_hopid);
8562306a36Sopenharmony_cistruct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in,
8662306a36Sopenharmony_ci				     struct tb_port *out, int link_nr,
8762306a36Sopenharmony_ci				     int max_up, int max_down);
8862306a36Sopenharmony_cistruct tb_tunnel *tb_tunnel_alloc_dma(struct tb *tb, struct tb_port *nhi,
8962306a36Sopenharmony_ci				      struct tb_port *dst, int transmit_path,
9062306a36Sopenharmony_ci				      int transmit_ring, int receive_path,
9162306a36Sopenharmony_ci				      int receive_ring);
9262306a36Sopenharmony_cibool tb_tunnel_match_dma(const struct tb_tunnel *tunnel, int transmit_path,
9362306a36Sopenharmony_ci			 int transmit_ring, int receive_path, int receive_ring);
9462306a36Sopenharmony_cistruct tb_tunnel *tb_tunnel_discover_usb3(struct tb *tb, struct tb_port *down,
9562306a36Sopenharmony_ci					  bool alloc_hopid);
9662306a36Sopenharmony_cistruct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up,
9762306a36Sopenharmony_ci				       struct tb_port *down, int max_up,
9862306a36Sopenharmony_ci				       int max_down);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_civoid tb_tunnel_free(struct tb_tunnel *tunnel);
10162306a36Sopenharmony_ciint tb_tunnel_activate(struct tb_tunnel *tunnel);
10262306a36Sopenharmony_ciint tb_tunnel_restart(struct tb_tunnel *tunnel);
10362306a36Sopenharmony_civoid tb_tunnel_deactivate(struct tb_tunnel *tunnel);
10462306a36Sopenharmony_cibool tb_tunnel_is_invalid(struct tb_tunnel *tunnel);
10562306a36Sopenharmony_cibool tb_tunnel_port_on_path(const struct tb_tunnel *tunnel,
10662306a36Sopenharmony_ci			    const struct tb_port *port);
10762306a36Sopenharmony_ciint tb_tunnel_maximum_bandwidth(struct tb_tunnel *tunnel, int *max_up,
10862306a36Sopenharmony_ci				int *max_down);
10962306a36Sopenharmony_ciint tb_tunnel_allocated_bandwidth(struct tb_tunnel *tunnel, int *allocated_up,
11062306a36Sopenharmony_ci				  int *allocated_down);
11162306a36Sopenharmony_ciint tb_tunnel_alloc_bandwidth(struct tb_tunnel *tunnel, int *alloc_up,
11262306a36Sopenharmony_ci			      int *alloc_down);
11362306a36Sopenharmony_ciint tb_tunnel_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up,
11462306a36Sopenharmony_ci				 int *consumed_down);
11562306a36Sopenharmony_ciint tb_tunnel_release_unused_bandwidth(struct tb_tunnel *tunnel);
11662306a36Sopenharmony_civoid tb_tunnel_reclaim_available_bandwidth(struct tb_tunnel *tunnel,
11762306a36Sopenharmony_ci					   int *available_up,
11862306a36Sopenharmony_ci					   int *available_down);
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cistatic inline bool tb_tunnel_is_pci(const struct tb_tunnel *tunnel)
12162306a36Sopenharmony_ci{
12262306a36Sopenharmony_ci	return tunnel->type == TB_TUNNEL_PCI;
12362306a36Sopenharmony_ci}
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_cistatic inline bool tb_tunnel_is_dp(const struct tb_tunnel *tunnel)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	return tunnel->type == TB_TUNNEL_DP;
12862306a36Sopenharmony_ci}
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_cistatic inline bool tb_tunnel_is_dma(const struct tb_tunnel *tunnel)
13162306a36Sopenharmony_ci{
13262306a36Sopenharmony_ci	return tunnel->type == TB_TUNNEL_DMA;
13362306a36Sopenharmony_ci}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic inline bool tb_tunnel_is_usb3(const struct tb_tunnel *tunnel)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	return tunnel->type == TB_TUNNEL_USB3;
13862306a36Sopenharmony_ci}
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci#endif
14162306a36Sopenharmony_ci
142