summaryrefslogtreecommitdiff
path: root/include/linux/thunderbolt.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/thunderbolt.h')
-rw-r--r--include/linux/thunderbolt.h91
1 files changed, 65 insertions, 26 deletions
diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h
index 124e13cb1469..0ba112175bb3 100644
--- a/include/linux/thunderbolt.h
+++ b/include/linux/thunderbolt.h
@@ -11,6 +11,13 @@
#ifndef THUNDERBOLT_H_
#define THUNDERBOLT_H_
+#include <linux/types.h>
+
+struct fwnode_handle;
+struct device;
+
+#if IS_REACHABLE(CONFIG_USB4)
+
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/list.h>
@@ -33,7 +40,6 @@ enum tb_cfg_pkg_type {
TB_CFG_PKG_ICM_EVENT = 10,
TB_CFG_PKG_ICM_CMD = 11,
TB_CFG_PKG_ICM_RESP = 12,
- TB_CFG_PKG_PREPARE_TO_SLEEP = 13,
};
/**
@@ -86,9 +92,9 @@ struct tb {
unsigned long privdata[];
};
-extern struct bus_type tb_bus_type;
-extern struct device_type tb_service_type;
-extern struct device_type tb_xdomain_type;
+extern const struct bus_type tb_bus_type;
+extern const struct device_type tb_service_type;
+extern const struct device_type tb_xdomain_type;
#define TB_LINKS_PER_PHY_PORT 2
@@ -172,6 +178,20 @@ int tb_register_property_dir(const char *key, struct tb_property_dir *dir);
void tb_unregister_property_dir(const char *key, struct tb_property_dir *dir);
/**
+ * enum tb_link_width - Thunderbolt/USB4 link width
+ * @TB_LINK_WIDTH_SINGLE: Single lane link
+ * @TB_LINK_WIDTH_DUAL: Dual lane symmetric link
+ * @TB_LINK_WIDTH_ASYM_TX: Dual lane asymmetric Gen 4 link with 3 transmitters
+ * @TB_LINK_WIDTH_ASYM_RX: Dual lane asymmetric Gen 4 link with 3 receivers
+ */
+enum tb_link_width {
+ TB_LINK_WIDTH_SINGLE = BIT(0),
+ TB_LINK_WIDTH_DUAL = BIT(1),
+ TB_LINK_WIDTH_ASYM_TX = BIT(2),
+ TB_LINK_WIDTH_ASYM_RX = BIT(3),
+};
+
+/**
* struct tb_xdomain - Cross-domain (XDomain) connection
* @dev: XDomain device
* @tb: Pointer to the domain
@@ -186,27 +206,28 @@ void tb_unregister_property_dir(const char *key, struct tb_property_dir *dir);
* @vendor_name: Name of the vendor (or %NULL if not known)
* @device_name: Name of the device (or %NULL if not known)
* @link_speed: Speed of the link in Gb/s
- * @link_width: Width of the link (1 or 2)
+ * @link_width: Width of the downstream facing link
+ * @link_usb4: Downstream link is USB4
* @is_unplugged: The XDomain is unplugged
* @needs_uuid: If the XDomain does not have @remote_uuid it will be
* queried first
* @service_ids: Used to generate IDs for the services
* @in_hopids: Input HopIDs for DMA tunneling
- * @out_hopids; Output HopIDs for DMA tunneling
+ * @out_hopids: Output HopIDs for DMA tunneling
* @local_property_block: Local block of properties
* @local_property_block_gen: Generation of @local_property_block
* @local_property_block_len: Length of the @local_property_block in dwords
* @remote_properties: Properties exported by the remote domain
* @remote_property_block_gen: Generation of @remote_properties
- * @get_uuid_work: Work used to retrieve @remote_uuid
- * @uuid_retries: Number of times left @remote_uuid is requested before
- * giving up
- * @get_properties_work: Work used to get remote domain properties
- * @properties_retries: Number of times left to read properties
+ * @state: Next XDomain discovery state to run
+ * @state_work: Work used to run the next state
+ * @state_retries: Number of retries remain for the state
* @properties_changed_work: Work used to notify the remote domain that
* our properties have changed
* @properties_changed_retries: Number of times left to send properties
* changed notification
+ * @bonding_possible: True if lane bonding is possible on local side
+ * @target_link_width: Target link width from the remote host
* @link: Root switch link the remote domain is connected (ICM only)
* @depth: Depth in the chain the remote domain is connected (ICM only)
*
@@ -233,7 +254,8 @@ struct tb_xdomain {
const char *vendor_name;
const char *device_name;
unsigned int link_speed;
- unsigned int link_width;
+ enum tb_link_width link_width;
+ bool link_usb4;
bool is_unplugged;
bool needs_uuid;
struct ida service_ids;
@@ -244,12 +266,13 @@ struct tb_xdomain {
u32 local_property_block_len;
struct tb_property_dir *remote_properties;
u32 remote_property_block_gen;
- struct delayed_work get_uuid_work;
- int uuid_retries;
- struct delayed_work get_properties_work;
- int properties_retries;
+ int state;
+ struct delayed_work state_work;
+ int state_retries;
struct delayed_work properties_changed_work;
int properties_changed_retries;
+ bool bonding_possible;
+ u8 target_link_width;
u8 link;
u8 depth;
};
@@ -333,7 +356,7 @@ int tb_xdomain_request(struct tb_xdomain *xd, const void *request,
unsigned int timeout_msec);
/**
- * tb_protocol_handler - Protocol specific handler
+ * struct tb_protocol_handler - Protocol specific handler
* @uuid: XDomain messages with this UUID are dispatched to this handler
* @callback: Callback called with the XDomain message. Returning %1
* here tells the XDomain core that the message was handled
@@ -414,7 +437,7 @@ static inline struct tb_service *tb_to_service(struct device *dev)
}
/**
- * tb_service_driver - Thunderbolt service driver
+ * struct tb_service_driver - Thunderbolt service driver
* @driver: Driver structure
* @probe: Called when the driver is probed
* @remove: Called when the driver is removed (optional)
@@ -465,6 +488,7 @@ static inline struct tb_xdomain *tb_service_parent(struct tb_service *svc)
* @msix_ida: Used to allocate MSI-X vectors for rings
* @going_away: The host controller device is about to disappear so when
* this flag is set, avoid touching the hardware anymore.
+ * @iommu_dma_protection: An IOMMU will isolate external-facing ports.
* @interrupt_work: Work scheduled to handle ring interrupt when no
* MSI-X is used.
* @hop_count: Number of rings (end point hops) supported by NHI.
@@ -479,6 +503,7 @@ struct tb_nhi {
struct tb_ring **rx_rings;
struct ida msix_ida;
bool going_away;
+ bool iommu_dma_protection;
struct work_struct interrupt_work;
u32 hop_count;
unsigned long quirks;
@@ -494,6 +519,7 @@ struct tb_nhi {
* @head: Head of the ring (write next descriptor here)
* @tail: Tail of the ring (complete next descriptor here)
* @descriptors: Allocated descriptors for this ring
+ * @descriptors_dma: DMA address of descriptors for this ring
* @queue: Queue holding frames to be transferred over this ring
* @in_flight: Queue holding frames that are currently in flight
* @work: Interrupt work structure
@@ -546,12 +572,12 @@ typedef void (*ring_cb)(struct tb_ring *, struct ring_frame *, bool canceled);
/**
* enum ring_desc_flags - Flags for DMA ring descriptor
- * %RING_DESC_ISOCH: Enable isonchronous DMA (Tx only)
- * %RING_DESC_CRC_ERROR: In frame mode CRC check failed for the frame (Rx only)
- * %RING_DESC_COMPLETED: Descriptor completed (set by NHI)
- * %RING_DESC_POSTED: Always set this
- * %RING_DESC_BUFFER_OVERRUN: RX buffer overrun
- * %RING_DESC_INTERRUPT: Request an interrupt on completion
+ * @RING_DESC_ISOCH: Enable isonchronous DMA (Tx only)
+ * @RING_DESC_CRC_ERROR: In frame mode CRC check failed for the frame (Rx only)
+ * @RING_DESC_COMPLETED: Descriptor completed (set by NHI)
+ * @RING_DESC_POSTED: Always set this
+ * @RING_DESC_BUFFER_OVERRUN: RX buffer overrun
+ * @RING_DESC_INTERRUPT: Request an interrupt on completion
*/
enum ring_desc_flags {
RING_DESC_ISOCH = 0x1,
@@ -611,7 +637,7 @@ int __tb_ring_enqueue(struct tb_ring *ring, struct ring_frame *frame);
* If ring_stop() is called after the packet has been enqueued
* @frame->callback will be called with canceled set to true.
*
- * Return: Returns %-ESHUTDOWN if ring_stop has been called. Zero otherwise.
+ * Return: %-ESHUTDOWN if ring_stop() has been called, %0 otherwise.
*/
static inline int tb_ring_rx(struct tb_ring *ring, struct ring_frame *frame)
{
@@ -632,7 +658,7 @@ static inline int tb_ring_rx(struct tb_ring *ring, struct ring_frame *frame)
* If ring_stop() is called after the packet has been enqueued @frame->callback
* will be called with canceled set to true.
*
- * Return: Returns %-ESHUTDOWN if ring_stop has been called. Zero otherwise.
+ * Return: %-ESHUTDOWN if ring_stop has been called, %0 otherwise.
*/
static inline int tb_ring_tx(struct tb_ring *ring, struct ring_frame *frame)
{
@@ -650,10 +676,23 @@ void tb_ring_poll_complete(struct tb_ring *ring);
*
* Use this function when you are mapping DMA for buffers that are
* passed to the ring for sending/receiving.
+ *
+ * Return: Pointer to device used for DMA mapping.
*/
static inline struct device *tb_ring_dma_device(struct tb_ring *ring)
{
return &ring->nhi->pdev->dev;
}
+bool usb4_usb3_port_match(struct device *usb4_port_dev,
+ const struct fwnode_handle *usb3_port_fwnode);
+
+#else /* CONFIG_USB4 */
+static inline bool usb4_usb3_port_match(struct device *usb4_port_dev,
+ const struct fwnode_handle *usb3_port_fwnode)
+{
+ return false;
+}
+#endif /* CONFIG_USB4 */
+
#endif /* THUNDERBOLT_H_ */