summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/tb.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thunderbolt/tb.h')
-rw-r--r--drivers/thunderbolt/tb.h96
1 files changed, 68 insertions, 28 deletions
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 6737188f2581..e96474f17067 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -9,6 +9,7 @@
#ifndef TB_H_
#define TB_H_
+#include <linux/debugfs.h>
#include <linux/nvmem-provider.h>
#include <linux/pci.h>
#include <linux/thunderbolt.h>
@@ -160,6 +161,7 @@ struct tb_switch_tmu {
* @max_pcie_credits: Router preferred number of buffers for PCIe
* @max_dma_credits: Router preferred number of buffers for DMA/P2P
* @clx: CLx states on the upstream link of the router
+ * @drom_blob: DROM debugfs blob wrapper
*
* When the switch is being added or removed to the domain (other
* switches) you need to have domain lock held.
@@ -212,6 +214,9 @@ struct tb_switch {
unsigned int max_pcie_credits;
unsigned int max_dma_credits;
unsigned int clx;
+#ifdef CONFIG_DEBUG_FS
+ struct debugfs_blob_wrapper drom_blob;
+#endif
};
/**
@@ -303,7 +308,7 @@ struct tb_port {
* struct usb4_port - USB4 port device
* @dev: Device for the port
* @port: Pointer to the lane 0 adapter
- * @can_offline: Does the port have necessary platform support to moved
+ * @can_offline: Does the port have necessary platform support to move
* it into offline mode and back
* @offline: The port is currently in offline mode
* @margining: Pointer to margining structure if enabled
@@ -319,7 +324,7 @@ struct usb4_port {
};
/**
- * tb_retimer: Thunderbolt retimer
+ * struct tb_retimer - Thunderbolt retimer
* @dev: Device for the retimer
* @tb: Pointer to the domain the retimer belongs to
* @index: Retimer index facing the router USB4 port
@@ -350,7 +355,7 @@ struct tb_retimer {
* struct tb_path_hop - routing information for a tb_path
* @in_port: Ingress port of a switch
* @out_port: Egress port of a switch where the packet is routed out
- * (must be on the same switch than @in_port)
+ * (must be on the same switch as @in_port)
* @in_hop_index: HopID where the path configuration entry is placed in
* the path config space of @in_port.
* @in_counter_index: Used counter index (not used in the driver
@@ -494,9 +499,9 @@ struct tb_path {
* performed. If this returns %-EOPNOTSUPP then the
* native USB4 router operation is called.
* @usb4_switch_nvm_authenticate_status: Optional callback that the CM
- * implementation can be used to
- * return status of USB4 NVM_AUTH
- * router operation.
+ * implementation can use to return
+ * status of USB4 NVM_AUTH router
+ * operation.
*/
struct tb_cm_ops {
int (*driver_ready)(struct tb *tb);
@@ -547,13 +552,14 @@ static inline void *tb_priv(struct tb *tb)
/**
* tb_upstream_port() - return the upstream port of a switch
+ * @sw: Router
*
* Every switch has an upstream port (for the root switch it is the NHI).
*
* During switch alloc/init tb_upstream_port()->remote may be NULL, even for
* non root switches (on the NHI port remote is always NULL).
*
- * Return: Returns the upstream port of the switch.
+ * Return: Pointer to &struct tb_port.
*/
static inline struct tb_port *tb_upstream_port(struct tb_switch *sw)
{
@@ -564,8 +570,8 @@ static inline struct tb_port *tb_upstream_port(struct tb_switch *sw)
* tb_is_upstream_port() - Is the port upstream facing
* @port: Port to check
*
- * Returns true if @port is upstream facing port. In case of dual link
- * ports both return true.
+ * Return: %true if @port is upstream facing port. In case of dual link
+ * ports, both return %true.
*/
static inline bool tb_is_upstream_port(const struct tb_port *port)
{
@@ -608,7 +614,7 @@ static inline const char *tb_width_name(enum tb_link_width width)
* tb_port_has_remote() - Does the port have switch connected downstream
* @port: Port to check
*
- * Returns true only when the port is primary port and has remote set.
+ * Return: %true only when the port is primary port and has remote set.
*/
static inline bool tb_port_has_remote(const struct tb_port *port)
{
@@ -799,6 +805,19 @@ static inline void tb_domain_put(struct tb *tb)
put_device(&tb->dev);
}
+/**
+ * tb_domain_event() - Notify userspace about an event in domain
+ * @tb: Domain where event occurred
+ * @envp: Array of uevent environment strings (can be %NULL)
+ *
+ * This function provides a way to notify userspace about any events
+ * that take place in the domain.
+ */
+static inline void tb_domain_event(struct tb *tb, char *envp[])
+{
+ kobject_uevent_env(&tb->dev.kobj, KOBJ_CHANGE, envp);
+}
+
struct tb_nvm *tb_nvm_alloc(struct device *dev);
int tb_nvm_read_version(struct tb_nvm *nvm);
int tb_nvm_validate(struct tb_nvm *nvm);
@@ -887,8 +906,9 @@ static inline struct tb_switch *tb_switch_parent(struct tb_switch *sw)
* tb_switch_downstream_port() - Return downstream facing port of parent router
* @sw: Device router pointer
*
- * Only call for device routers. Returns the downstream facing port of
- * the parent router.
+ * Call only for device routers.
+ *
+ * Return: Pointer to &struct tb_port or %NULL in case of failure.
*/
static inline struct tb_port *tb_switch_downstream_port(struct tb_switch *sw)
{
@@ -900,6 +920,8 @@ static inline struct tb_port *tb_switch_downstream_port(struct tb_switch *sw)
/**
* tb_switch_depth() - Returns depth of the connected router
* @sw: Router
+ *
+ * Return: Router depth level as a number.
*/
static inline int tb_switch_depth(const struct tb_switch *sw)
{
@@ -992,6 +1014,9 @@ static inline bool tb_switch_is_tiger_lake(const struct tb_switch *sw)
* is handling @sw this function can be called. It is valid to call this
* after tb_switch_alloc() and tb_switch_configure() has been called
* (latter only for SW CM case).
+ *
+ * Return: %true if switch is handled by ICM, %false if handled by
+ * software CM.
*/
static inline bool tb_switch_is_icm(const struct tb_switch *sw)
{
@@ -1019,6 +1044,8 @@ int tb_switch_tmu_configure(struct tb_switch *sw, enum tb_switch_tmu_mode mode);
*
* Checks if given router TMU mode is configured to @mode. Note the
* router TMU might not be enabled to this mode.
+ *
+ * Return: %true if TMU mode is equal to @mode, %false otherwise.
*/
static inline bool tb_switch_tmu_is_configured(const struct tb_switch *sw,
enum tb_switch_tmu_mode mode)
@@ -1030,8 +1057,8 @@ static inline bool tb_switch_tmu_is_configured(const struct tb_switch *sw,
* tb_switch_tmu_is_enabled() - Checks if the specified TMU mode is enabled
* @sw: Router whose TMU mode to check
*
- * Return true if hardware TMU configuration matches the requested
- * configuration (and is not %TB_SWITCH_TMU_MODE_OFF).
+ * Return: %true if hardware TMU configuration matches the requested
+ * configuration (and is not %TB_SWITCH_TMU_MODE_OFF), %false otherwise.
*/
static inline bool tb_switch_tmu_is_enabled(const struct tb_switch *sw)
{
@@ -1051,9 +1078,10 @@ int tb_switch_clx_disable(struct tb_switch *sw);
* @clx: The CLx states to check for
*
* Checks if the specified CLx is enabled on the router upstream link.
- * Returns true if any of the given states is enabled.
*
* Not applicable for a host router.
+ *
+ * Return: %true if any of the given states is enabled, %false otherwise.
*/
static inline bool tb_switch_clx_is_enabled(const struct tb_switch *sw,
unsigned int clx)
@@ -1081,11 +1109,11 @@ struct tb_port *tb_next_port_on_path(struct tb_port *start, struct tb_port *end,
struct tb_port *prev);
/**
- * tb_port_path_direction_downstream() - Checks if path directed downstream
+ * tb_port_path_direction_downstream() - Checks if path is directed downstream
* @src: Source adapter
* @dst: Destination adapter
*
- * Returns %true only if the specified path from source adapter (@src)
+ * Return: %true only if the specified path from source adapter (@src)
* to destination adapter (@dst) is directed downstream.
*/
static inline bool
@@ -1113,7 +1141,7 @@ static inline bool tb_port_use_credit_allocation(const struct tb_port *port)
(p) = tb_next_port_on_path((src), (dst), (p)))
/**
- * tb_for_each_upstream_port_on_path() - Iterate over each upstreamm port on path
+ * tb_for_each_upstream_port_on_path() - Iterate over each upstream port on path
* @src: Source port
* @dst: Destination port
* @p: Port used as iterator
@@ -1214,10 +1242,11 @@ static inline int tb_route_length(u64 route)
/**
* tb_downstream_route() - get route to downstream switch
+ * @port: Port to check
*
* Port must not be the upstream port (otherwise a loop is created).
*
- * Return: Returns a route to the switch behind @port.
+ * Return: Route to the switch behind @port.
*/
static inline u64 tb_downstream_route(struct tb_port *port)
{
@@ -1245,7 +1274,7 @@ static inline struct tb_switch *tb_xdomain_parent(struct tb_xdomain *xd)
* tb_xdomain_downstream_port() - Return downstream facing port of parent router
* @xd: Xdomain pointer
*
- * Returns the downstream port the XDomain is connected to.
+ * Return: Pointer to &struct tb_port or %NULL in case of failure.
*/
static inline struct tb_port *tb_xdomain_downstream_port(struct tb_xdomain *xd)
{
@@ -1273,7 +1302,7 @@ static inline struct tb_retimer *tb_to_retimer(struct device *dev)
* usb4_switch_version() - Returns USB4 version of the router
* @sw: Router to check
*
- * Returns major version of USB4 router (%1 for v1, %2 for v2 and so
+ * Return: Major version of USB4 router (%1 for v1, %2 for v2 and so
* on). Can be called to pre-USB4 router too and in that case returns %0.
*/
static inline unsigned int usb4_switch_version(const struct tb_switch *sw)
@@ -1285,7 +1314,7 @@ static inline unsigned int usb4_switch_version(const struct tb_switch *sw)
* tb_switch_is_usb4() - Is the switch USB4 compliant
* @sw: Switch to check
*
- * Returns true if the @sw is USB4 compliant router, false otherwise.
+ * Return: %true if the @sw is USB4 compliant router, %false otherwise.
*/
static inline bool tb_switch_is_usb4(const struct tb_switch *sw)
{
@@ -1299,7 +1328,7 @@ int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid);
int usb4_switch_drom_read(struct tb_switch *sw, unsigned int address, void *buf,
size_t size);
bool usb4_switch_lane_bonding_possible(struct tb_switch *sw);
-int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags);
+int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags, bool runtime);
int usb4_switch_set_sleep(struct tb_switch *sw);
int usb4_switch_nvm_sector_size(struct tb_switch *sw);
int usb4_switch_nvm_read(struct tb_switch *sw, unsigned int address, void *buf,
@@ -1337,7 +1366,7 @@ int usb4_port_asym_set_link_width(struct tb_port *port, enum tb_link_width width
int usb4_port_asym_start(struct tb_port *port);
/**
- * enum tb_sb_target - Sideband transaction target
+ * enum usb4_sb_target - Sideband transaction target
* @USB4_SB_TARGET_ROUTER: Target is the router itself
* @USB4_SB_TARGET_PARTNER: Target is partner
* @USB4_SB_TARGET_RETIMER: Target is retimer
@@ -1367,31 +1396,41 @@ enum usb4_margin_sw_error_counter {
USB4_MARGIN_SW_ERROR_COUNTER_STOP,
};
+enum usb4_margining_lane {
+ USB4_MARGINING_LANE_RX0 = 0,
+ USB4_MARGINING_LANE_RX1 = 1,
+ USB4_MARGINING_LANE_RX2 = 2,
+ USB4_MARGINING_LANE_ALL = 7,
+};
+
/**
* struct usb4_port_margining_params - USB4 margining parameters
* @error_counter: Error counter operation for software margining
* @ber_level: Current BER level contour value
- * @lanes: %0, %1 or %7 (all)
+ * @lanes: Lanes to enable for the margining operation
* @voltage_time_offset: Offset for voltage / time for software margining
* @optional_voltage_offset_range: Enable optional extended voltage range
* @right_high: %false if left/low margin test is performed, %true if right/high
+ * @upper_eye: %true if margin test is done on upper eye, %false if done on
+ * lower eye
* @time: %true if time margining is used instead of voltage
*/
struct usb4_port_margining_params {
enum usb4_margin_sw_error_counter error_counter;
u32 ber_level;
- u32 lanes;
+ enum usb4_margining_lane lanes;
u32 voltage_time_offset;
bool optional_voltage_offset_range;
bool right_high;
+ bool upper_eye;
bool time;
};
int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target,
- u8 index, u32 *caps);
+ u8 index, u32 *caps, size_t ncaps);
int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target,
u8 index, const struct usb4_port_margining_params *params,
- u32 *results);
+ u32 *results, size_t nresults);
int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target,
u8 index, const struct usb4_port_margining_params *params,
u32 *results);
@@ -1455,6 +1494,7 @@ static inline struct usb4_port *tb_to_usb4_port_device(struct device *dev)
struct usb4_port *usb4_port_device_add(struct tb_port *port);
void usb4_port_device_remove(struct usb4_port *usb4);
int usb4_port_device_resume(struct usb4_port *usb4);
+int usb4_port_index(const struct tb_switch *sw, const struct tb_port *port);
static inline bool usb4_port_device_is_offline(const struct usb4_port *usb4)
{