]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - include/linux/thunderbolt.h
thunderbolt: Add support for frame mode
[mirror_ubuntu-bionic-kernel.git] / include / linux / thunderbolt.h
CommitLineData
cdae7c07
MW
1/*
2 * Thunderbolt service API
3 *
eaf8ff35 4 * Copyright (C) 2014 Andreas Noever <andreas.noever@gmail.com>
cdae7c07
MW
5 * Copyright (C) 2017, Intel Corporation
6 * Authors: Michael Jamet <michael.jamet@intel.com>
7 * Mika Westerberg <mika.westerberg@linux.intel.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#ifndef THUNDERBOLT_H_
15#define THUNDERBOLT_H_
16
9e99b9f4 17#include <linux/device.h>
cdae7c07 18#include <linux/list.h>
9e99b9f4 19#include <linux/mutex.h>
d1ff7024 20#include <linux/mod_devicetable.h>
cdae7c07
MW
21#include <linux/uuid.h>
22
eaf8ff35
MW
23enum tb_cfg_pkg_type {
24 TB_CFG_PKG_READ = 1,
25 TB_CFG_PKG_WRITE = 2,
26 TB_CFG_PKG_ERROR = 3,
27 TB_CFG_PKG_NOTIFY_ACK = 4,
28 TB_CFG_PKG_EVENT = 5,
29 TB_CFG_PKG_XDOMAIN_REQ = 6,
30 TB_CFG_PKG_XDOMAIN_RESP = 7,
31 TB_CFG_PKG_OVERRIDE = 8,
32 TB_CFG_PKG_RESET = 9,
33 TB_CFG_PKG_ICM_EVENT = 10,
34 TB_CFG_PKG_ICM_CMD = 11,
35 TB_CFG_PKG_ICM_RESP = 12,
36 TB_CFG_PKG_PREPARE_TO_SLEEP = 13,
37};
38
9e99b9f4
MW
39/**
40 * enum tb_security_level - Thunderbolt security level
41 * @TB_SECURITY_NONE: No security, legacy mode
42 * @TB_SECURITY_USER: User approval required at minimum
43 * @TB_SECURITY_SECURE: One time saved key required at minimum
44 * @TB_SECURITY_DPONLY: Only tunnel Display port (and USB)
45 */
46enum tb_security_level {
47 TB_SECURITY_NONE,
48 TB_SECURITY_USER,
49 TB_SECURITY_SECURE,
50 TB_SECURITY_DPONLY,
51};
52
53/**
54 * struct tb - main thunderbolt bus structure
55 * @dev: Domain device
56 * @lock: Big lock. Must be held when accessing any struct
57 * tb_switch / struct tb_port.
58 * @nhi: Pointer to the NHI structure
59 * @ctl: Control channel for this domain
60 * @wq: Ordered workqueue for all domain specific work
61 * @root_switch: Root switch of this domain
62 * @cm_ops: Connection manager specific operations vector
63 * @index: Linux assigned domain number
64 * @security_level: Current security level
65 * @privdata: Private connection manager specific data
66 */
67struct tb {
68 struct device dev;
69 struct mutex lock;
70 struct tb_nhi *nhi;
71 struct tb_ctl *ctl;
72 struct workqueue_struct *wq;
73 struct tb_switch *root_switch;
74 const struct tb_cm_ops *cm_ops;
75 int index;
76 enum tb_security_level security_level;
77 unsigned long privdata[0];
78};
79
80extern struct bus_type tb_bus_type;
d1ff7024
MW
81extern struct device_type tb_service_type;
82extern struct device_type tb_xdomain_type;
9e99b9f4 83
e69b71f8
MW
84#define TB_LINKS_PER_PHY_PORT 2
85
86static inline unsigned int tb_phy_port_from_link(unsigned int link)
87{
88 return (link - 1) / TB_LINKS_PER_PHY_PORT;
89}
90
cdae7c07
MW
91/**
92 * struct tb_property_dir - XDomain property directory
93 * @uuid: Directory UUID or %NULL if root directory
94 * @properties: List of properties in this directory
95 *
96 * User needs to provide serialization if needed.
97 */
98struct tb_property_dir {
99 const uuid_t *uuid;
100 struct list_head properties;
101};
102
103enum tb_property_type {
104 TB_PROPERTY_TYPE_UNKNOWN = 0x00,
105 TB_PROPERTY_TYPE_DIRECTORY = 0x44,
106 TB_PROPERTY_TYPE_DATA = 0x64,
107 TB_PROPERTY_TYPE_TEXT = 0x74,
108 TB_PROPERTY_TYPE_VALUE = 0x76,
109};
110
111#define TB_PROPERTY_KEY_SIZE 8
112
113/**
114 * struct tb_property - XDomain property
115 * @list: Used to link properties together in a directory
116 * @key: Key for the property (always terminated).
117 * @type: Type of the property
118 * @length: Length of the property data in dwords
119 * @value: Property value
120 *
121 * Users use @type to determine which field in @value is filled.
122 */
123struct tb_property {
124 struct list_head list;
125 char key[TB_PROPERTY_KEY_SIZE + 1];
126 enum tb_property_type type;
127 size_t length;
128 union {
129 struct tb_property_dir *dir;
130 u8 *data;
131 char *text;
132 u32 immediate;
133 } value;
134};
135
136struct tb_property_dir *tb_property_parse_dir(const u32 *block,
137 size_t block_len);
138ssize_t tb_property_format_dir(const struct tb_property_dir *dir, u32 *block,
139 size_t block_len);
140struct tb_property_dir *tb_property_create_dir(const uuid_t *uuid);
141void tb_property_free_dir(struct tb_property_dir *dir);
142int tb_property_add_immediate(struct tb_property_dir *parent, const char *key,
143 u32 value);
144int tb_property_add_data(struct tb_property_dir *parent, const char *key,
145 const void *buf, size_t buflen);
146int tb_property_add_text(struct tb_property_dir *parent, const char *key,
147 const char *text);
148int tb_property_add_dir(struct tb_property_dir *parent, const char *key,
149 struct tb_property_dir *dir);
150void tb_property_remove(struct tb_property *tb_property);
151struct tb_property *tb_property_find(struct tb_property_dir *dir,
152 const char *key, enum tb_property_type type);
153struct tb_property *tb_property_get_next(struct tb_property_dir *dir,
154 struct tb_property *prev);
155
156#define tb_property_for_each(dir, property) \
157 for (property = tb_property_get_next(dir, NULL); \
158 property; \
159 property = tb_property_get_next(dir, property))
160
d1ff7024
MW
161int tb_register_property_dir(const char *key, struct tb_property_dir *dir);
162void tb_unregister_property_dir(const char *key, struct tb_property_dir *dir);
163
164/**
165 * struct tb_xdomain - Cross-domain (XDomain) connection
166 * @dev: XDomain device
167 * @tb: Pointer to the domain
168 * @remote_uuid: UUID of the remote domain (host)
169 * @local_uuid: Cached local UUID
170 * @route: Route string the other domain can be reached
171 * @vendor: Vendor ID of the remote domain
172 * @device: Device ID of the demote domain
173 * @lock: Lock to serialize access to the following fields of this structure
174 * @vendor_name: Name of the vendor (or %NULL if not known)
175 * @device_name: Name of the device (or %NULL if not known)
176 * @is_unplugged: The XDomain is unplugged
177 * @resume: The XDomain is being resumed
178 * @transmit_path: HopID which the remote end expects us to transmit
179 * @transmit_ring: Local ring (hop) where outgoing packets are pushed
180 * @receive_path: HopID which we expect the remote end to transmit
181 * @receive_ring: Local ring (hop) where incoming packets arrive
182 * @service_ids: Used to generate IDs for the services
183 * @properties: Properties exported by the remote domain
184 * @property_block_gen: Generation of @properties
185 * @properties_lock: Lock protecting @properties.
186 * @get_properties_work: Work used to get remote domain properties
187 * @properties_retries: Number of times left to read properties
188 * @properties_changed_work: Work used to notify the remote domain that
189 * our properties have changed
190 * @properties_changed_retries: Number of times left to send properties
191 * changed notification
192 * @link: Root switch link the remote domain is connected (ICM only)
193 * @depth: Depth in the chain the remote domain is connected (ICM only)
194 *
195 * This structure represents connection across two domains (hosts).
196 * Each XDomain contains zero or more services which are exposed as
197 * &struct tb_service objects.
198 *
199 * Service drivers may access this structure if they need to enumerate
200 * non-standard properties but they need hold @lock when doing so
201 * because properties can be changed asynchronously in response to
202 * changes in the remote domain.
203 */
204struct tb_xdomain {
205 struct device dev;
206 struct tb *tb;
207 uuid_t *remote_uuid;
208 const uuid_t *local_uuid;
209 u64 route;
210 u16 vendor;
211 u16 device;
212 struct mutex lock;
213 const char *vendor_name;
214 const char *device_name;
215 bool is_unplugged;
216 bool resume;
217 u16 transmit_path;
218 u16 transmit_ring;
219 u16 receive_path;
220 u16 receive_ring;
221 struct ida service_ids;
222 struct tb_property_dir *properties;
223 u32 property_block_gen;
224 struct delayed_work get_properties_work;
225 int properties_retries;
226 struct delayed_work properties_changed_work;
227 int properties_changed_retries;
228 u8 link;
229 u8 depth;
230};
231
232int tb_xdomain_enable_paths(struct tb_xdomain *xd, u16 transmit_path,
233 u16 transmit_ring, u16 receive_path,
234 u16 receive_ring);
235int tb_xdomain_disable_paths(struct tb_xdomain *xd);
236struct tb_xdomain *tb_xdomain_find_by_uuid(struct tb *tb, const uuid_t *uuid);
237
238static inline struct tb_xdomain *
239tb_xdomain_find_by_uuid_locked(struct tb *tb, const uuid_t *uuid)
240{
241 struct tb_xdomain *xd;
242
243 mutex_lock(&tb->lock);
244 xd = tb_xdomain_find_by_uuid(tb, uuid);
245 mutex_unlock(&tb->lock);
246
247 return xd;
248}
249
250static inline struct tb_xdomain *tb_xdomain_get(struct tb_xdomain *xd)
251{
252 if (xd)
253 get_device(&xd->dev);
254 return xd;
255}
256
257static inline void tb_xdomain_put(struct tb_xdomain *xd)
258{
259 if (xd)
260 put_device(&xd->dev);
261}
262
263static inline bool tb_is_xdomain(const struct device *dev)
264{
265 return dev->type == &tb_xdomain_type;
266}
267
268static inline struct tb_xdomain *tb_to_xdomain(struct device *dev)
269{
270 if (tb_is_xdomain(dev))
271 return container_of(dev, struct tb_xdomain, dev);
272 return NULL;
273}
274
275int tb_xdomain_response(struct tb_xdomain *xd, const void *response,
276 size_t size, enum tb_cfg_pkg_type type);
277int tb_xdomain_request(struct tb_xdomain *xd, const void *request,
278 size_t request_size, enum tb_cfg_pkg_type request_type,
279 void *response, size_t response_size,
280 enum tb_cfg_pkg_type response_type,
281 unsigned int timeout_msec);
282
283/**
284 * tb_protocol_handler - Protocol specific handler
285 * @uuid: XDomain messages with this UUID are dispatched to this handler
286 * @callback: Callback called with the XDomain message. Returning %1
287 * here tells the XDomain core that the message was handled
288 * by this handler and should not be forwared to other
289 * handlers.
290 * @data: Data passed with the callback
291 * @list: Handlers are linked using this
292 *
293 * Thunderbolt services can hook into incoming XDomain requests by
294 * registering protocol handler. Only limitation is that the XDomain
295 * discovery protocol UUID cannot be registered since it is handled by
296 * the core XDomain code.
297 *
298 * The @callback must check that the message is really directed to the
299 * service the driver implements.
300 */
301struct tb_protocol_handler {
302 const uuid_t *uuid;
303 int (*callback)(const void *buf, size_t size, void *data);
304 void *data;
305 struct list_head list;
306};
307
308int tb_register_protocol_handler(struct tb_protocol_handler *handler);
309void tb_unregister_protocol_handler(struct tb_protocol_handler *handler);
310
311/**
312 * struct tb_service - Thunderbolt service
313 * @dev: XDomain device
314 * @id: ID of the service (shown in sysfs)
315 * @key: Protocol key from the properties directory
316 * @prtcid: Protocol ID from the properties directory
317 * @prtcvers: Protocol version from the properties directory
318 * @prtcrevs: Protocol software revision from the properties directory
319 * @prtcstns: Protocol settings mask from the properties directory
320 *
321 * Each domain exposes set of services it supports as collection of
322 * properties. For each service there will be one corresponding
323 * &struct tb_service. Service drivers are bound to these.
324 */
325struct tb_service {
326 struct device dev;
327 int id;
328 const char *key;
329 u32 prtcid;
330 u32 prtcvers;
331 u32 prtcrevs;
332 u32 prtcstns;
333};
334
335static inline struct tb_service *tb_service_get(struct tb_service *svc)
336{
337 if (svc)
338 get_device(&svc->dev);
339 return svc;
340}
341
342static inline void tb_service_put(struct tb_service *svc)
343{
344 if (svc)
345 put_device(&svc->dev);
346}
347
348static inline bool tb_is_service(const struct device *dev)
349{
350 return dev->type == &tb_service_type;
351}
352
353static inline struct tb_service *tb_to_service(struct device *dev)
354{
355 if (tb_is_service(dev))
356 return container_of(dev, struct tb_service, dev);
357 return NULL;
358}
359
360/**
361 * tb_service_driver - Thunderbolt service driver
362 * @driver: Driver structure
363 * @probe: Called when the driver is probed
364 * @remove: Called when the driver is removed (optional)
365 * @shutdown: Called at shutdown time to stop the service (optional)
366 * @id_table: Table of service identifiers the driver supports
367 */
368struct tb_service_driver {
369 struct device_driver driver;
370 int (*probe)(struct tb_service *svc, const struct tb_service_id *id);
371 void (*remove)(struct tb_service *svc);
372 void (*shutdown)(struct tb_service *svc);
373 const struct tb_service_id *id_table;
374};
375
376#define TB_SERVICE(key, id) \
377 .match_flags = TBSVC_MATCH_PROTOCOL_KEY | \
378 TBSVC_MATCH_PROTOCOL_ID, \
379 .protocol_key = (key), \
380 .protocol_id = (id)
381
382int tb_register_service_driver(struct tb_service_driver *drv);
383void tb_unregister_service_driver(struct tb_service_driver *drv);
384
385static inline void *tb_service_get_drvdata(const struct tb_service *svc)
386{
387 return dev_get_drvdata(&svc->dev);
388}
389
390static inline void tb_service_set_drvdata(struct tb_service *svc, void *data)
391{
392 dev_set_drvdata(&svc->dev, data);
393}
394
395static inline struct tb_xdomain *tb_service_parent(struct tb_service *svc)
396{
397 return tb_to_xdomain(svc->dev.parent);
398}
399
cdae7c07 400#endif /* THUNDERBOLT_H_ */