Blame view

drivers/thunderbolt/tb.h 34.4 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  /* SPDX-License-Identifier: GPL-2.0 */
d6cc51cd1   Andreas Noever   thunderbolt: Setu...
2
  /*
15c6784c7   Mika Westerberg   thunderbolt: Add ...
3
   * Thunderbolt driver - bus logic (NHI independent)
d6cc51cd1   Andreas Noever   thunderbolt: Setu...
4
5
   *
   * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
15c6784c7   Mika Westerberg   thunderbolt: Add ...
6
   * Copyright (C) 2018, Intel Corporation
d6cc51cd1   Andreas Noever   thunderbolt: Setu...
7
8
9
10
   */
  
  #ifndef TB_H_
  #define TB_H_
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
11
  #include <linux/nvmem-provider.h>
a25c8b2fc   Andreas Noever   thunderbolt: Init...
12
  #include <linux/pci.h>
d1ff70241   Mika Westerberg   thunderbolt: Add ...
13
  #include <linux/thunderbolt.h>
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
14
  #include <linux/uuid.h>
a25c8b2fc   Andreas Noever   thunderbolt: Init...
15
16
  
  #include "tb_regs.h"
d6cc51cd1   Andreas Noever   thunderbolt: Setu...
17
  #include "ctl.h"
3e1367686   Mika Westerberg   thunderbolt: Add ...
18
  #include "dma_port.h"
d6cc51cd1   Andreas Noever   thunderbolt: Setu...
19

719a5fe87   Mika Westerberg   thunderbolt: Spli...
20
21
22
23
24
25
26
  #define NVM_MIN_SIZE		SZ_32K
  #define NVM_MAX_SIZE		SZ_512K
  
  /* Intel specific NVM offsets */
  #define NVM_DEVID		0x05
  #define NVM_VERSION		0x08
  #define NVM_FLASH_SIZE		0x45
d6cc51cd1   Andreas Noever   thunderbolt: Setu...
27
  /**
719a5fe87   Mika Westerberg   thunderbolt: Spli...
28
29
   * struct tb_nvm - Structure holding NVM information
   * @dev: Owner of the NVM
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
30
31
32
33
34
35
36
37
38
   * @major: Major version number of the active NVM portion
   * @minor: Minor version number of the active NVM portion
   * @id: Identifier used with both NVM portions
   * @active: Active portion NVMem device
   * @non_active: Non-active portion NVMem device
   * @buf: Buffer where the NVM image is stored before it is written to
   *	 the actual NVM flash device
   * @buf_data_size: Number of bytes actually consumed by the new NVM
   *		   image
719a5fe87   Mika Westerberg   thunderbolt: Spli...
39
   * @authenticating: The device is authenticating the new NVM
4b794f806   Mario Limonciello   thunderbolt: Add ...
40
   * @flushed: The image has been flushed to the storage area
719a5fe87   Mika Westerberg   thunderbolt: Spli...
41
42
43
   *
   * The user of this structure needs to handle serialization of possible
   * concurrent access.
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
44
   */
719a5fe87   Mika Westerberg   thunderbolt: Spli...
45
46
  struct tb_nvm {
  	struct device *dev;
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
47
48
49
50
51
52
53
54
  	u8 major;
  	u8 minor;
  	int id;
  	struct nvmem_device *active;
  	struct nvmem_device *non_active;
  	void *buf;
  	size_t buf_data_size;
  	bool authenticating;
4b794f806   Mario Limonciello   thunderbolt: Add ...
55
  	bool flushed;
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
56
  };
f67cf4911   Mika Westerberg   thunderbolt: Add ...
57
  #define TB_SWITCH_KEY_SIZE		32
f0342e757   Mika Westerberg   thunderbolt: Do n...
58
  #define TB_SWITCH_MAX_DEPTH		6
b04079837   Mika Westerberg   thunderbolt: Add ...
59
  #define USB4_SWITCH_MAX_DEPTH		5
f67cf4911   Mika Westerberg   thunderbolt: Add ...
60
61
  
  /**
cf29b9afb   Rajmohan Mani   thunderbolt: Add ...
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
   * enum tb_switch_tmu_rate - TMU refresh rate
   * @TB_SWITCH_TMU_RATE_OFF: %0 (Disable Time Sync handshake)
   * @TB_SWITCH_TMU_RATE_HIFI: %16 us time interval between successive
   *			     transmission of the Delay Request TSNOS
   *			     (Time Sync Notification Ordered Set) on a Link
   * @TB_SWITCH_TMU_RATE_NORMAL: %1 ms time interval between successive
   *			       transmission of the Delay Request TSNOS on
   *			       a Link
   */
  enum tb_switch_tmu_rate {
  	TB_SWITCH_TMU_RATE_OFF = 0,
  	TB_SWITCH_TMU_RATE_HIFI = 16,
  	TB_SWITCH_TMU_RATE_NORMAL = 1000,
  };
  
  /**
   * struct tb_switch_tmu - Structure holding switch TMU configuration
   * @cap: Offset to the TMU capability (%0 if not found)
   * @has_ucap: Does the switch support uni-directional mode
   * @rate: TMU refresh rate related to upstream switch. In case of root
   *	  switch this holds the domain rate.
   * @unidirectional: Is the TMU in uni-directional or bi-directional mode
   *		    related to upstream switch. Don't case for root switch.
   */
  struct tb_switch_tmu {
  	int cap;
  	bool has_ucap;
  	enum tb_switch_tmu_rate rate;
  	bool unidirectional;
  };
  
  /**
a25c8b2fc   Andreas Noever   thunderbolt: Init...
94
   * struct tb_switch - a thunderbolt switch
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
95
96
97
   * @dev: Device for the switch
   * @config: Switch configuration
   * @ports: Ports in this switch
3e1367686   Mika Westerberg   thunderbolt: Add ...
98
99
   * @dma_port: If the switch has port supporting DMA configuration based
   *	      mailbox this will hold the pointer to that (%NULL
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
100
101
   *	      otherwise). If set it also means the switch has
   *	      upgradeable NVM.
cf29b9afb   Rajmohan Mani   thunderbolt: Add ...
102
   * @tmu: The switch TMU configuration
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
103
104
105
106
107
   * @tb: Pointer to the domain the switch belongs to
   * @uid: Unique ID of the switch
   * @uuid: UUID of the switch (or %NULL if not supported)
   * @vendor: Vendor ID of the switch
   * @device: Device ID of the switch
72ee33907   Mika Westerberg   thunderbolt: Read...
108
109
   * @vendor_name: Name of the vendor (or %NULL if not known)
   * @device_name: Name of the device (or %NULL if not known)
91c0c1208   Mika Westerberg   thunderbolt: Add ...
110
111
   * @link_speed: Speed of the link in Gb/s
   * @link_width: Width of the link (1 or 2)
bbcf40b39   Mika Westerberg   thunderbolt: Do n...
112
   * @link_usb4: Upstream link is USB4
2c3c4197c   Mika Westerberg   thunderbolt: Stor...
113
   * @generation: Switch Thunderbolt generation
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
114
   * @cap_plug_events: Offset to the plug events capability (%0 if not found)
a9be55824   Mika Westerberg   thunderbolt: Move...
115
   * @cap_lc: Offset to the link controller capability (%0 if not found)
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
116
117
   * @is_unplugged: The switch is going away
   * @drom: DROM of the switch (%NULL if not found)
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
118
119
120
   * @nvm: Pointer to the NVM if the switch has one (%NULL otherwise)
   * @no_nvm_upgrade: Prevent NVM upgrade of this switch
   * @safe_mode: The switch is in safe-mode
14862ee30   Yehezkel Bernat   thunderbolt: Add ...
121
   * @boot: Whether the switch was already authorized on boot or not
2d8ff0b58   Mika Westerberg   thunderbolt: Add ...
122
   * @rpm: The switch supports runtime PM
f67cf4911   Mika Westerberg   thunderbolt: Add ...
123
   * @authorized: Whether the switch is authorized by user or policy
f67cf4911   Mika Westerberg   thunderbolt: Add ...
124
   * @security_level: Switch supported security level
54e418106   Gil Fine   thunderbolt: Add ...
125
   * @debugfs_dir: Pointer to the debugfs structure
f67cf4911   Mika Westerberg   thunderbolt: Add ...
126
127
128
129
130
131
   * @key: Contains the key used to challenge the device or %NULL if not
   *	 supported. Size of the key is %TB_SWITCH_KEY_SIZE.
   * @connection_id: Connection ID used with ICM messaging
   * @connection_key: Connection key used with ICM messaging
   * @link: Root switch link this switch is connected (ICM only)
   * @depth: Depth in the chain this switch is connected (ICM only)
4f7c2e0d8   Mika Westerberg   thunderbolt: Make...
132
133
   * @rpm_complete: Completion used to wait for runtime resume to
   *		  complete (ICM only)
1cb362938   Mario Limonciello   thunderbolt: Add ...
134
   * @quirks: Quirks used for this Thunderbolt switch
f67cf4911   Mika Westerberg   thunderbolt: Add ...
135
136
   *
   * When the switch is being added or removed to the domain (other
09f11b6c9   Mika Westerberg   thunderbolt: Take...
137
   * switches) you need to have domain lock held.
a25c8b2fc   Andreas Noever   thunderbolt: Init...
138
139
   */
  struct tb_switch {
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
140
  	struct device dev;
a25c8b2fc   Andreas Noever   thunderbolt: Init...
141
142
  	struct tb_regs_switch_header config;
  	struct tb_port *ports;
3e1367686   Mika Westerberg   thunderbolt: Add ...
143
  	struct tb_dma_port *dma_port;
cf29b9afb   Rajmohan Mani   thunderbolt: Add ...
144
  	struct tb_switch_tmu tmu;
a25c8b2fc   Andreas Noever   thunderbolt: Init...
145
  	struct tb *tb;
c90553b3c   Andreas Noever   thunderbolt: Read...
146
  	u64 uid;
7c39ffe7a   Christoph Hellwig   thunderbolt: use ...
147
  	uuid_t *uuid;
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
148
149
  	u16 vendor;
  	u16 device;
72ee33907   Mika Westerberg   thunderbolt: Read...
150
151
  	const char *vendor_name;
  	const char *device_name;
91c0c1208   Mika Westerberg   thunderbolt: Add ...
152
153
  	unsigned int link_speed;
  	unsigned int link_width;
bbcf40b39   Mika Westerberg   thunderbolt: Do n...
154
  	bool link_usb4;
2c3c4197c   Mika Westerberg   thunderbolt: Stor...
155
  	unsigned int generation;
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
156
  	int cap_plug_events;
a9be55824   Mika Westerberg   thunderbolt: Move...
157
  	int cap_lc;
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
158
  	bool is_unplugged;
cd22e73bd   Andreas Noever   thunderbolt: Read...
159
  	u8 *drom;
719a5fe87   Mika Westerberg   thunderbolt: Spli...
160
  	struct tb_nvm *nvm;
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
161
162
  	bool no_nvm_upgrade;
  	bool safe_mode;
14862ee30   Yehezkel Bernat   thunderbolt: Add ...
163
  	bool boot;
2d8ff0b58   Mika Westerberg   thunderbolt: Add ...
164
  	bool rpm;
f67cf4911   Mika Westerberg   thunderbolt: Add ...
165
  	unsigned int authorized;
f67cf4911   Mika Westerberg   thunderbolt: Add ...
166
  	enum tb_security_level security_level;
54e418106   Gil Fine   thunderbolt: Add ...
167
  	struct dentry *debugfs_dir;
f67cf4911   Mika Westerberg   thunderbolt: Add ...
168
169
170
171
172
  	u8 *key;
  	u8 connection_id;
  	u8 connection_key;
  	u8 link;
  	u8 depth;
4f7c2e0d8   Mika Westerberg   thunderbolt: Make...
173
  	struct completion rpm_complete;
1cb362938   Mario Limonciello   thunderbolt: Add ...
174
  	unsigned long quirks;
a25c8b2fc   Andreas Noever   thunderbolt: Init...
175
176
177
178
  };
  
  /**
   * struct tb_port - a thunderbolt port, part of a tb_switch
d1ff70241   Mika Westerberg   thunderbolt: Add ...
179
180
181
182
183
   * @config: Cached port configuration read from registers
   * @sw: Switch the port belongs to
   * @remote: Remote port (%NULL if not connected)
   * @xdomain: Remote host (%NULL if not connected)
   * @cap_phy: Offset, zero if not found
cf29b9afb   Rajmohan Mani   thunderbolt: Add ...
184
   * @cap_tmu: Offset of the adapter specific TMU capability (%0 if not present)
56183c88f   Mika Westerberg   thunderbolt: Cach...
185
   * @cap_adap: Offset of the adapter specific capability (%0 if not present)
b04079837   Mika Westerberg   thunderbolt: Add ...
186
   * @cap_usb4: Offset to the USB4 port capability (%0 if not present)
d1ff70241   Mika Westerberg   thunderbolt: Add ...
187
   * @port: Port number on switch
8824d19b4   Nikunj A. Dadhania   thunderbolt: Disa...
188
   * @disabled: Disabled by eeprom or enabled but not implemented
91c0c1208   Mika Westerberg   thunderbolt: Add ...
189
   * @bonded: true if the port is bonded (two lanes combined as one)
d1ff70241   Mika Westerberg   thunderbolt: Add ...
190
191
192
   * @dual_link_port: If the switch is connected using two ports, points
   *		    to the other port.
   * @link_nr: Is this primary or secondary port on the dual_link.
0b2863ac3   Mika Westerberg   thunderbolt: Add ...
193
194
   * @in_hopids: Currently allocated input HopIDs
   * @out_hopids: Currently allocated output HopIDs
8afe909b7   Mika Westerberg   thunderbolt: Add ...
195
   * @list: Used to link ports to DP resources list
a25c8b2fc   Andreas Noever   thunderbolt: Init...
196
197
198
199
   */
  struct tb_port {
  	struct tb_regs_port_header config;
  	struct tb_switch *sw;
d1ff70241   Mika Westerberg   thunderbolt: Add ...
200
201
202
  	struct tb_port *remote;
  	struct tb_xdomain *xdomain;
  	int cap_phy;
cf29b9afb   Rajmohan Mani   thunderbolt: Add ...
203
  	int cap_tmu;
56183c88f   Mika Westerberg   thunderbolt: Cach...
204
  	int cap_adap;
b04079837   Mika Westerberg   thunderbolt: Add ...
205
  	int cap_usb4;
d1ff70241   Mika Westerberg   thunderbolt: Add ...
206
207
  	u8 port;
  	bool disabled;
91c0c1208   Mika Westerberg   thunderbolt: Add ...
208
  	bool bonded;
cd22e73bd   Andreas Noever   thunderbolt: Read...
209
210
  	struct tb_port *dual_link_port;
  	u8 link_nr:1;
0b2863ac3   Mika Westerberg   thunderbolt: Add ...
211
212
  	struct ida in_hopids;
  	struct ida out_hopids;
8afe909b7   Mika Westerberg   thunderbolt: Add ...
213
  	struct list_head list;
a25c8b2fc   Andreas Noever   thunderbolt: Init...
214
215
216
  };
  
  /**
dacb12877   Kranthi Kuntala   thunderbolt: Add ...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
   * 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
   * @vendor: Vendor ID of the retimer
   * @device: Device ID of the retimer
   * @port: Pointer to the lane 0 adapter
   * @nvm: Pointer to the NVM if the retimer has one (%NULL otherwise)
   * @auth_status: Status of last NVM authentication
   */
  struct tb_retimer {
  	struct device dev;
  	struct tb *tb;
  	u8 index;
  	u32 vendor;
  	u32 device;
  	struct tb_port *port;
  	struct tb_nvm *nvm;
  	u32 auth_status;
  };
  
  /**
520b67021   Andreas Noever   thunderbolt: Add ...
239
   * struct tb_path_hop - routing information for a tb_path
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
240
241
242
243
244
245
246
247
   * @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)
   * @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
   *		      currently, %-1 to disable)
   * @next_hop_index: HopID of the packet when it is routed out from @out_port
0414bec5f   Mika Westerberg   thunderbolt: Disc...
248
249
   * @initial_credits: Number of initial flow control credits allocated for
   *		     the path
520b67021   Andreas Noever   thunderbolt: Add ...
250
251
252
253
   *
   * Hop configuration is always done on the IN port of a switch.
   * in_port and out_port have to be on the same switch. Packets arriving on
   * in_port with "hop" = in_hop_index will get routed to through out_port. The
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
254
255
256
257
   * next hop to take (on out_port->remote) is determined by
   * next_hop_index. When routing packet to another switch (out->remote is
   * set) the @next_hop_index must match the @in_hop_index of that next
   * hop to make routing possible.
520b67021   Andreas Noever   thunderbolt: Add ...
258
259
260
261
262
263
264
265
   *
   * in_counter_index is the index of a counter (in TB_CFG_COUNTERS) on the in
   * port.
   */
  struct tb_path_hop {
  	struct tb_port *in_port;
  	struct tb_port *out_port;
  	int in_hop_index;
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
266
  	int in_counter_index;
520b67021   Andreas Noever   thunderbolt: Add ...
267
  	int next_hop_index;
0414bec5f   Mika Westerberg   thunderbolt: Disc...
268
  	unsigned int initial_credits;
520b67021   Andreas Noever   thunderbolt: Add ...
269
270
271
272
  };
  
  /**
   * enum tb_path_port - path options mask
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
273
274
275
276
277
   * @TB_PATH_NONE: Do not activate on any hop on path
   * @TB_PATH_SOURCE: Activate on the first hop (out of src)
   * @TB_PATH_INTERNAL: Activate on the intermediate hops (not the first/last)
   * @TB_PATH_DESTINATION: Activate on the last hop (into dst)
   * @TB_PATH_ALL: Activate on all hops on the path
520b67021   Andreas Noever   thunderbolt: Add ...
278
279
280
   */
  enum tb_path_port {
  	TB_PATH_NONE = 0,
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
281
282
283
  	TB_PATH_SOURCE = 1,
  	TB_PATH_INTERNAL = 2,
  	TB_PATH_DESTINATION = 4,
520b67021   Andreas Noever   thunderbolt: Add ...
284
285
286
287
288
  	TB_PATH_ALL = 7,
  };
  
  /**
   * struct tb_path - a unidirectional path between two ports
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
289
290
291
292
293
294
295
296
297
298
299
   * @tb: Pointer to the domain structure
   * @name: Name of the path (used for debugging)
   * @nfc_credits: Number of non flow controlled credits allocated for the path
   * @ingress_shared_buffer: Shared buffering used for ingress ports on the path
   * @egress_shared_buffer: Shared buffering used for egress ports on the path
   * @ingress_fc_enable: Flow control for ingress ports on the path
   * @egress_fc_enable: Flow control for egress ports on the path
   * @priority: Priority group if the path
   * @weight: Weight of the path inside the priority group
   * @drop_packages: Drop packages from queue tail or head
   * @activated: Is the path active
44242d6c9   Mika Westerberg   thunderbolt: Add ...
300
301
   * @clear_fc: Clear all flow control from the path config space entries
   *	      when deactivating this path
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
302
303
   * @hops: Path hops
   * @path_length: How many hops the path uses
520b67021   Andreas Noever   thunderbolt: Add ...
304
   *
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
305
306
307
   * A path consists of a number of hops (see &struct tb_path_hop). To
   * establish a PCIe tunnel two paths have to be created between the two
   * PCIe ports.
520b67021   Andreas Noever   thunderbolt: Add ...
308
309
310
   */
  struct tb_path {
  	struct tb *tb;
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
311
312
  	const char *name;
  	int nfc_credits;
520b67021   Andreas Noever   thunderbolt: Add ...
313
314
315
316
  	enum tb_path_port ingress_shared_buffer;
  	enum tb_path_port egress_shared_buffer;
  	enum tb_path_port ingress_fc_enable;
  	enum tb_path_port egress_fc_enable;
37209783c   Nathan Chancellor   thunderbolt: Make...
317
  	unsigned int priority:3;
520b67021   Andreas Noever   thunderbolt: Add ...
318
319
320
  	int weight:4;
  	bool drop_packages;
  	bool activated;
44242d6c9   Mika Westerberg   thunderbolt: Add ...
321
  	bool clear_fc;
520b67021   Andreas Noever   thunderbolt: Add ...
322
  	struct tb_path_hop *hops;
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
323
  	int path_length;
520b67021   Andreas Noever   thunderbolt: Add ...
324
  };
0b2863ac3   Mika Westerberg   thunderbolt: Add ...
325
326
  /* HopIDs 0-7 are reserved by the Thunderbolt protocol */
  #define TB_PATH_MIN_HOPID	8
c738a794e   Mika Westerberg   thunderbolt: Incr...
327
328
329
330
331
  /*
   * Support paths from the farthest (depth 6) router to the host and back
   * to the same level (not necessarily to the same router).
   */
  #define TB_PATH_MAX_HOPS	(7 * 2)
0b2863ac3   Mika Westerberg   thunderbolt: Add ...
332

b2911a593   Mika Westerberg   thunderbolt: Enab...
333
334
335
336
337
338
  /* Possible wake types */
  #define TB_WAKE_ON_CONNECT	BIT(0)
  #define TB_WAKE_ON_DISCONNECT	BIT(1)
  #define TB_WAKE_ON_USB4		BIT(2)
  #define TB_WAKE_ON_USB3		BIT(3)
  #define TB_WAKE_ON_PCIE		BIT(4)
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
339
340
  /**
   * struct tb_cm_ops - Connection manager specific operations vector
f67cf4911   Mika Westerberg   thunderbolt: Add ...
341
342
   * @driver_ready: Called right after control channel is started. Used by
   *		  ICM to send driver ready message to the firmware.
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
343
344
345
346
   * @start: Starts the domain
   * @stop: Stops the domain
   * @suspend_noirq: Connection manager specific suspend_noirq
   * @resume_noirq: Connection manager specific resume_noirq
f67cf4911   Mika Westerberg   thunderbolt: Add ...
347
   * @suspend: Connection manager specific suspend
884e4d576   Mika Westerberg   thunderbolt: Only...
348
349
   * @freeze_noirq: Connection manager specific freeze_noirq
   * @thaw_noirq: Connection manager specific thaw_noirq
f67cf4911   Mika Westerberg   thunderbolt: Add ...
350
   * @complete: Connection manager specific complete
2d8ff0b58   Mika Westerberg   thunderbolt: Add ...
351
352
   * @runtime_suspend: Connection manager specific runtime_suspend
   * @runtime_resume: Connection manager specific runtime_resume
4f7c2e0d8   Mika Westerberg   thunderbolt: Make...
353
354
   * @runtime_suspend_switch: Runtime suspend a switch
   * @runtime_resume_switch: Runtime resume a switch
81a54b5e1   Mika Westerberg   thunderbolt: Let ...
355
   * @handle_event: Handle thunderbolt event
9aaa3b8b4   Mika Westerberg   thunderbolt: Add ...
356
357
   * @get_boot_acl: Get boot ACL list
   * @set_boot_acl: Set boot ACL list
f67cf4911   Mika Westerberg   thunderbolt: Add ...
358
359
360
   * @approve_switch: Approve switch
   * @add_switch_key: Add key to switch
   * @challenge_switch_key: Challenge switch using key
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
361
   * @disconnect_pcie_paths: Disconnects PCIe paths before NVM update
d1ff70241   Mika Westerberg   thunderbolt: Add ...
362
363
   * @approve_xdomain_paths: Approve (establish) XDomain DMA paths
   * @disconnect_xdomain_paths: Disconnect XDomain DMA paths
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
364
365
   */
  struct tb_cm_ops {
f67cf4911   Mika Westerberg   thunderbolt: Add ...
366
  	int (*driver_ready)(struct tb *tb);
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
367
368
369
370
  	int (*start)(struct tb *tb);
  	void (*stop)(struct tb *tb);
  	int (*suspend_noirq)(struct tb *tb);
  	int (*resume_noirq)(struct tb *tb);
f67cf4911   Mika Westerberg   thunderbolt: Add ...
371
  	int (*suspend)(struct tb *tb);
884e4d576   Mika Westerberg   thunderbolt: Only...
372
373
  	int (*freeze_noirq)(struct tb *tb);
  	int (*thaw_noirq)(struct tb *tb);
f67cf4911   Mika Westerberg   thunderbolt: Add ...
374
  	void (*complete)(struct tb *tb);
2d8ff0b58   Mika Westerberg   thunderbolt: Add ...
375
376
  	int (*runtime_suspend)(struct tb *tb);
  	int (*runtime_resume)(struct tb *tb);
4f7c2e0d8   Mika Westerberg   thunderbolt: Make...
377
378
  	int (*runtime_suspend_switch)(struct tb_switch *sw);
  	int (*runtime_resume_switch)(struct tb_switch *sw);
81a54b5e1   Mika Westerberg   thunderbolt: Let ...
379
380
  	void (*handle_event)(struct tb *tb, enum tb_cfg_pkg_type,
  			     const void *buf, size_t size);
9aaa3b8b4   Mika Westerberg   thunderbolt: Add ...
381
382
  	int (*get_boot_acl)(struct tb *tb, uuid_t *uuids, size_t nuuids);
  	int (*set_boot_acl)(struct tb *tb, const uuid_t *uuids, size_t nuuids);
f67cf4911   Mika Westerberg   thunderbolt: Add ...
383
384
385
386
  	int (*approve_switch)(struct tb *tb, struct tb_switch *sw);
  	int (*add_switch_key)(struct tb *tb, struct tb_switch *sw);
  	int (*challenge_switch_key)(struct tb *tb, struct tb_switch *sw,
  				    const u8 *challenge, u8 *response);
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
387
  	int (*disconnect_pcie_paths)(struct tb *tb);
d1ff70241   Mika Westerberg   thunderbolt: Add ...
388
389
  	int (*approve_xdomain_paths)(struct tb *tb, struct tb_xdomain *xd);
  	int (*disconnect_xdomain_paths)(struct tb *tb, struct tb_xdomain *xd);
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
390
  };
520b67021   Andreas Noever   thunderbolt: Add ...
391

9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
392
393
394
395
  static inline void *tb_priv(struct tb *tb)
  {
  	return (void *)tb->privdata;
  }
2d8ff0b58   Mika Westerberg   thunderbolt: Add ...
396
  #define TB_AUTOSUSPEND_DELAY		15000 /* ms */
a25c8b2fc   Andreas Noever   thunderbolt: Init...
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
  /* helper functions & macros */
  
  /**
   * tb_upstream_port() - return the upstream port of a switch
   *
   * 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.
   */
  static inline struct tb_port *tb_upstream_port(struct tb_switch *sw)
  {
  	return &sw->ports[sw->config.upstream_port_number];
  }
dfe40ca48   Mika Westerberg   thunderbolt: Assi...
413
414
415
416
417
418
419
420
421
422
423
424
  /**
   * 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.
   */
  static inline bool tb_is_upstream_port(const struct tb_port *port)
  {
  	const struct tb_port *upstream_port = tb_upstream_port(port->sw);
  	return port == upstream_port || port->dual_link_port == upstream_port;
  }
b323a98f9   Mika Westerberg   thunderbolt: Make...
425
  static inline u64 tb_route(const struct tb_switch *sw)
a25c8b2fc   Andreas Noever   thunderbolt: Init...
426
427
428
  {
  	return ((u64) sw->config.route_hi) << 32 | sw->config.route_lo;
  }
f67cf4911   Mika Westerberg   thunderbolt: Add ...
429
430
431
432
433
434
435
436
437
  static inline struct tb_port *tb_port_at(u64 route, struct tb_switch *sw)
  {
  	u8 port;
  
  	port = route >> (sw->config.depth * 8);
  	if (WARN_ON(port > sw->config.max_port_number))
  		return NULL;
  	return &sw->ports[port];
  }
dfe40ca48   Mika Westerberg   thunderbolt: Assi...
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  /**
   * 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.
   */
  static inline bool tb_port_has_remote(const struct tb_port *port)
  {
  	if (tb_is_upstream_port(port))
  		return false;
  	if (!port->remote)
  		return false;
  	if (port->dual_link_port && port->link_nr)
  		return false;
  
  	return true;
  }
344e06430   Mika Westerberg   thunderbolt: Scan...
455
456
457
458
  static inline bool tb_port_is_null(const struct tb_port *port)
  {
  	return port && port->port && port->config.type == TB_TYPE_PORT;
  }
a3cfebdc1   Mika Westerberg   thunderbolt: Intr...
459
460
461
462
  static inline bool tb_port_is_nhi(const struct tb_port *port)
  {
  	return port && port->config.type == TB_TYPE_NHI;
  }
99cabbb00   Mika Westerberg   thunderbolt: Add ...
463
464
465
466
  static inline bool tb_port_is_pcie_down(const struct tb_port *port)
  {
  	return port && port->config.type == TB_TYPE_PCIE_DOWN;
  }
0414bec5f   Mika Westerberg   thunderbolt: Disc...
467
468
469
470
  static inline bool tb_port_is_pcie_up(const struct tb_port *port)
  {
  	return port && port->config.type == TB_TYPE_PCIE_UP;
  }
4f807e47e   Mika Westerberg   thunderbolt: Add ...
471
472
473
474
475
476
477
478
479
  static inline bool tb_port_is_dpin(const struct tb_port *port)
  {
  	return port && port->config.type == TB_TYPE_DP_HDMI_IN;
  }
  
  static inline bool tb_port_is_dpout(const struct tb_port *port)
  {
  	return port && port->config.type == TB_TYPE_DP_HDMI_OUT;
  }
e6f818585   Rajmohan Mani   thunderbolt: Add ...
480
481
482
483
484
485
486
487
488
  static inline bool tb_port_is_usb3_down(const struct tb_port *port)
  {
  	return port && port->config.type == TB_TYPE_USB3_DOWN;
  }
  
  static inline bool tb_port_is_usb3_up(const struct tb_port *port)
  {
  	return port && port->config.type == TB_TYPE_USB3_UP;
  }
a25c8b2fc   Andreas Noever   thunderbolt: Init...
489
490
491
  static inline int tb_sw_read(struct tb_switch *sw, void *buffer,
  			     enum tb_cfg_space space, u32 offset, u32 length)
  {
4708384f3   Mika Westerberg   thunderbolt: Bloc...
492
493
  	if (sw->is_unplugged)
  		return -ENODEV;
a25c8b2fc   Andreas Noever   thunderbolt: Init...
494
495
496
497
498
499
500
501
  	return tb_cfg_read(sw->tb->ctl,
  			   buffer,
  			   tb_route(sw),
  			   0,
  			   space,
  			   offset,
  			   length);
  }
826c6a177   Mika Westerberg   thunderbolt: Make...
502
  static inline int tb_sw_write(struct tb_switch *sw, const void *buffer,
a25c8b2fc   Andreas Noever   thunderbolt: Init...
503
504
  			      enum tb_cfg_space space, u32 offset, u32 length)
  {
4708384f3   Mika Westerberg   thunderbolt: Bloc...
505
506
  	if (sw->is_unplugged)
  		return -ENODEV;
a25c8b2fc   Andreas Noever   thunderbolt: Init...
507
508
509
510
511
512
513
514
515
516
517
518
  	return tb_cfg_write(sw->tb->ctl,
  			    buffer,
  			    tb_route(sw),
  			    0,
  			    space,
  			    offset,
  			    length);
  }
  
  static inline int tb_port_read(struct tb_port *port, void *buffer,
  			       enum tb_cfg_space space, u32 offset, u32 length)
  {
4708384f3   Mika Westerberg   thunderbolt: Bloc...
519
520
  	if (port->sw->is_unplugged)
  		return -ENODEV;
a25c8b2fc   Andreas Noever   thunderbolt: Init...
521
522
523
524
525
526
527
528
  	return tb_cfg_read(port->sw->tb->ctl,
  			   buffer,
  			   tb_route(port->sw),
  			   port->port,
  			   space,
  			   offset,
  			   length);
  }
16a1258af   Mika Westerberg   thunderbolt: Use ...
529
  static inline int tb_port_write(struct tb_port *port, const void *buffer,
a25c8b2fc   Andreas Noever   thunderbolt: Init...
530
531
  				enum tb_cfg_space space, u32 offset, u32 length)
  {
4708384f3   Mika Westerberg   thunderbolt: Bloc...
532
533
  	if (port->sw->is_unplugged)
  		return -ENODEV;
a25c8b2fc   Andreas Noever   thunderbolt: Init...
534
535
536
537
538
539
540
541
542
543
544
545
546
  	return tb_cfg_write(port->sw->tb->ctl,
  			    buffer,
  			    tb_route(port->sw),
  			    port->port,
  			    space,
  			    offset,
  			    length);
  }
  
  #define tb_err(tb, fmt, arg...) dev_err(&(tb)->nhi->pdev->dev, fmt, ## arg)
  #define tb_WARN(tb, fmt, arg...) dev_WARN(&(tb)->nhi->pdev->dev, fmt, ## arg)
  #define tb_warn(tb, fmt, arg...) dev_warn(&(tb)->nhi->pdev->dev, fmt, ## arg)
  #define tb_info(tb, fmt, arg...) dev_info(&(tb)->nhi->pdev->dev, fmt, ## arg)
daa5140f7   Mika Westerberg   thunderbolt: Make...
547
  #define tb_dbg(tb, fmt, arg...) dev_dbg(&(tb)->nhi->pdev->dev, fmt, ## arg)
a25c8b2fc   Andreas Noever   thunderbolt: Init...
548
549
550
  
  #define __TB_SW_PRINT(level, sw, fmt, arg...)           \
  	do {                                            \
b323a98f9   Mika Westerberg   thunderbolt: Make...
551
  		const struct tb_switch *__sw = (sw);    \
a25c8b2fc   Andreas Noever   thunderbolt: Init...
552
553
554
555
556
557
  		level(__sw->tb, "%llx: " fmt,           \
  		      tb_route(__sw), ## arg);          \
  	} while (0)
  #define tb_sw_WARN(sw, fmt, arg...) __TB_SW_PRINT(tb_WARN, sw, fmt, ##arg)
  #define tb_sw_warn(sw, fmt, arg...) __TB_SW_PRINT(tb_warn, sw, fmt, ##arg)
  #define tb_sw_info(sw, fmt, arg...) __TB_SW_PRINT(tb_info, sw, fmt, ##arg)
daa5140f7   Mika Westerberg   thunderbolt: Make...
558
  #define tb_sw_dbg(sw, fmt, arg...) __TB_SW_PRINT(tb_dbg, sw, fmt, ##arg)
a25c8b2fc   Andreas Noever   thunderbolt: Init...
559
560
561
  
  #define __TB_PORT_PRINT(level, _port, fmt, arg...)                      \
  	do {                                                            \
b323a98f9   Mika Westerberg   thunderbolt: Make...
562
  		const struct tb_port *__port = (_port);                 \
a25c8b2fc   Andreas Noever   thunderbolt: Init...
563
564
565
566
567
568
569
570
571
  		level(__port->sw->tb, "%llx:%x: " fmt,                  \
  		      tb_route(__port->sw), __port->port, ## arg);      \
  	} while (0)
  #define tb_port_WARN(port, fmt, arg...) \
  	__TB_PORT_PRINT(tb_WARN, port, fmt, ##arg)
  #define tb_port_warn(port, fmt, arg...) \
  	__TB_PORT_PRINT(tb_warn, port, fmt, ##arg)
  #define tb_port_info(port, fmt, arg...) \
  	__TB_PORT_PRINT(tb_info, port, fmt, ##arg)
daa5140f7   Mika Westerberg   thunderbolt: Make...
572
573
  #define tb_port_dbg(port, fmt, arg...) \
  	__TB_PORT_PRINT(tb_dbg, port, fmt, ##arg)
a25c8b2fc   Andreas Noever   thunderbolt: Init...
574

f67cf4911   Mika Westerberg   thunderbolt: Add ...
575
  struct tb *icm_probe(struct tb_nhi *nhi);
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
576
  struct tb *tb_probe(struct tb_nhi *nhi);
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
577
  extern struct device_type tb_domain_type;
dacb12877   Kranthi Kuntala   thunderbolt: Add ...
578
  extern struct device_type tb_retimer_type;
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
579
  extern struct device_type tb_switch_type;
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
580
581
582
  
  int tb_domain_init(void);
  void tb_domain_exit(void);
d1ff70241   Mika Westerberg   thunderbolt: Add ...
583
584
  int tb_xdomain_init(void);
  void tb_xdomain_exit(void);
a25c8b2fc   Andreas Noever   thunderbolt: Init...
585

9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
586
587
588
589
590
  struct tb *tb_domain_alloc(struct tb_nhi *nhi, size_t privsize);
  int tb_domain_add(struct tb *tb);
  void tb_domain_remove(struct tb *tb);
  int tb_domain_suspend_noirq(struct tb *tb);
  int tb_domain_resume_noirq(struct tb *tb);
f67cf4911   Mika Westerberg   thunderbolt: Add ...
591
  int tb_domain_suspend(struct tb *tb);
884e4d576   Mika Westerberg   thunderbolt: Only...
592
593
  int tb_domain_freeze_noirq(struct tb *tb);
  int tb_domain_thaw_noirq(struct tb *tb);
f67cf4911   Mika Westerberg   thunderbolt: Add ...
594
  void tb_domain_complete(struct tb *tb);
2d8ff0b58   Mika Westerberg   thunderbolt: Add ...
595
596
  int tb_domain_runtime_suspend(struct tb *tb);
  int tb_domain_runtime_resume(struct tb *tb);
f67cf4911   Mika Westerberg   thunderbolt: Add ...
597
598
599
  int tb_domain_approve_switch(struct tb *tb, struct tb_switch *sw);
  int tb_domain_approve_switch_key(struct tb *tb, struct tb_switch *sw);
  int tb_domain_challenge_switch_key(struct tb *tb, struct tb_switch *sw);
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
600
  int tb_domain_disconnect_pcie_paths(struct tb *tb);
d1ff70241   Mika Westerberg   thunderbolt: Add ...
601
602
603
  int tb_domain_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd);
  int tb_domain_disconnect_xdomain_paths(struct tb *tb, struct tb_xdomain *xd);
  int tb_domain_disconnect_all_paths(struct tb *tb);
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
604

559c1e1e0   Mika Westerberg   thunderbolt: Run ...
605
606
607
608
609
610
  static inline struct tb *tb_domain_get(struct tb *tb)
  {
  	if (tb)
  		get_device(&tb->dev);
  	return tb;
  }
9d3cce0b6   Mika Westerberg   thunderbolt: Intr...
611
612
613
614
  static inline void tb_domain_put(struct tb *tb)
  {
  	put_device(&tb->dev);
  }
d6cc51cd1   Andreas Noever   thunderbolt: Setu...
615

719a5fe87   Mika Westerberg   thunderbolt: Spli...
616
617
618
619
620
621
622
623
  struct tb_nvm *tb_nvm_alloc(struct device *dev);
  int tb_nvm_add_active(struct tb_nvm *nvm, size_t size, nvmem_reg_read_t reg_read);
  int tb_nvm_write_buf(struct tb_nvm *nvm, unsigned int offset, void *val,
  		     size_t bytes);
  int tb_nvm_add_non_active(struct tb_nvm *nvm, size_t size,
  			  nvmem_reg_write_t reg_write);
  void tb_nvm_free(struct tb_nvm *nvm);
  void tb_nvm_exit(void);
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
624
625
  struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
  				  u64 route);
e6b245ccd   Mika Westerberg   thunderbolt: Add ...
626
627
  struct tb_switch *tb_switch_alloc_safe_mode(struct tb *tb,
  			struct device *parent, u64 route);
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
628
629
630
  int tb_switch_configure(struct tb_switch *sw);
  int tb_switch_add(struct tb_switch *sw);
  void tb_switch_remove(struct tb_switch *sw);
6ac6faee5   Mika Westerberg   thunderbolt: Add ...
631
  void tb_switch_suspend(struct tb_switch *sw, bool runtime);
23dd5bb49   Andreas Noever   thunderbolt: Add ...
632
  int tb_switch_resume(struct tb_switch *sw);
356b6c4ef   Mika Westerberg   thunderbolt: Send...
633
  int tb_switch_reset(struct tb_switch *sw);
aae20bb6b   Lukas Wunner   thunderbolt: Fix ...
634
  void tb_sw_set_unplugged(struct tb_switch *sw);
386e5e29d   Mika Westerberg   thunderbolt: Make...
635
636
  struct tb_port *tb_switch_find_port(struct tb_switch *sw,
  				    enum tb_port_type type);
f67cf4911   Mika Westerberg   thunderbolt: Add ...
637
638
  struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link,
  					       u8 depth);
7c39ffe7a   Christoph Hellwig   thunderbolt: use ...
639
  struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid);
8e9267bb3   Radion Mirchevsky   thunderbolt: Add ...
640
  struct tb_switch *tb_switch_find_by_route(struct tb *tb, u64 route);
f67cf4911   Mika Westerberg   thunderbolt: Add ...
641

b433d0100   Mika Westerberg   thunderbolt: Add ...
642
643
644
645
646
647
648
649
650
651
  /**
   * tb_switch_for_each_port() - Iterate over each switch port
   * @sw: Switch whose ports to iterate
   * @p: Port used as iterator
   *
   * Iterates over each switch port skipping the control port (port %0).
   */
  #define tb_switch_for_each_port(sw, p)					\
  	for ((p) = &(sw)->ports[1];					\
  	     (p) <= &(sw)->ports[(sw)->config.max_port_number]; (p)++)
b6b0ea70f   Mika Westerberg   thunderbolt: Add ...
652
653
654
655
656
657
  static inline struct tb_switch *tb_switch_get(struct tb_switch *sw)
  {
  	if (sw)
  		get_device(&sw->dev);
  	return sw;
  }
bfe778ac4   Mika Westerberg   thunderbolt: Conv...
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
  static inline void tb_switch_put(struct tb_switch *sw)
  {
  	put_device(&sw->dev);
  }
  
  static inline bool tb_is_switch(const struct device *dev)
  {
  	return dev->type == &tb_switch_type;
  }
  
  static inline struct tb_switch *tb_to_switch(struct device *dev)
  {
  	if (tb_is_switch(dev))
  		return container_of(dev, struct tb_switch, dev);
  	return NULL;
  }
0414bec5f   Mika Westerberg   thunderbolt: Disc...
674
675
676
677
  static inline struct tb_switch *tb_switch_parent(struct tb_switch *sw)
  {
  	return tb_to_switch(sw->dev.parent);
  }
17a8f815a   Mika Westerberg   thunderbolt: Expa...
678
  static inline bool tb_switch_is_light_ridge(const struct tb_switch *sw)
8b0110d9d   Mika Westerberg   thunderbolt: Enab...
679
  {
35ee69e94   Mika Westerberg   thunderbolt: Chec...
680
681
  	return sw->config.vendor_id == PCI_VENDOR_ID_INTEL &&
  	       sw->config.device_id == PCI_DEVICE_ID_INTEL_LIGHT_RIDGE;
8b0110d9d   Mika Westerberg   thunderbolt: Enab...
682
  }
17a8f815a   Mika Westerberg   thunderbolt: Expa...
683
  static inline bool tb_switch_is_eagle_ridge(const struct tb_switch *sw)
8b0110d9d   Mika Westerberg   thunderbolt: Enab...
684
  {
35ee69e94   Mika Westerberg   thunderbolt: Chec...
685
686
  	return sw->config.vendor_id == PCI_VENDOR_ID_INTEL &&
  	       sw->config.device_id == PCI_DEVICE_ID_INTEL_EAGLE_RIDGE;
8b0110d9d   Mika Westerberg   thunderbolt: Enab...
687
  }
17a8f815a   Mika Westerberg   thunderbolt: Expa...
688
  static inline bool tb_switch_is_cactus_ridge(const struct tb_switch *sw)
99cabbb00   Mika Westerberg   thunderbolt: Add ...
689
  {
35ee69e94   Mika Westerberg   thunderbolt: Chec...
690
691
692
693
694
695
  	if (sw->config.vendor_id == PCI_VENDOR_ID_INTEL) {
  		switch (sw->config.device_id) {
  		case PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C:
  		case PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C:
  			return true;
  		}
99cabbb00   Mika Westerberg   thunderbolt: Add ...
696
  	}
35ee69e94   Mika Westerberg   thunderbolt: Chec...
697
  	return false;
99cabbb00   Mika Westerberg   thunderbolt: Add ...
698
  }
17a8f815a   Mika Westerberg   thunderbolt: Expa...
699
  static inline bool tb_switch_is_falcon_ridge(const struct tb_switch *sw)
99cabbb00   Mika Westerberg   thunderbolt: Add ...
700
  {
35ee69e94   Mika Westerberg   thunderbolt: Chec...
701
702
703
704
705
706
  	if (sw->config.vendor_id == PCI_VENDOR_ID_INTEL) {
  		switch (sw->config.device_id) {
  		case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE:
  		case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE:
  			return true;
  		}
99cabbb00   Mika Westerberg   thunderbolt: Add ...
707
  	}
35ee69e94   Mika Westerberg   thunderbolt: Chec...
708
  	return false;
99cabbb00   Mika Westerberg   thunderbolt: Add ...
709
  }
7bffd97eb   Mika Westerberg   thunderbolt: Add ...
710
711
  static inline bool tb_switch_is_alpine_ridge(const struct tb_switch *sw)
  {
35ee69e94   Mika Westerberg   thunderbolt: Chec...
712
713
714
715
716
717
718
719
  	if (sw->config.vendor_id == PCI_VENDOR_ID_INTEL) {
  		switch (sw->config.device_id) {
  		case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE:
  		case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_BRIDGE:
  		case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE:
  		case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE:
  			return true;
  		}
7bffd97eb   Mika Westerberg   thunderbolt: Add ...
720
  	}
35ee69e94   Mika Westerberg   thunderbolt: Chec...
721
  	return false;
7bffd97eb   Mika Westerberg   thunderbolt: Add ...
722
723
724
725
  }
  
  static inline bool tb_switch_is_titan_ridge(const struct tb_switch *sw)
  {
35ee69e94   Mika Westerberg   thunderbolt: Chec...
726
727
728
729
730
731
732
  	if (sw->config.vendor_id == PCI_VENDOR_ID_INTEL) {
  		switch (sw->config.device_id) {
  		case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_BRIDGE:
  		case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_BRIDGE:
  		case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE:
  			return true;
  		}
7bffd97eb   Mika Westerberg   thunderbolt: Add ...
733
  	}
35ee69e94   Mika Westerberg   thunderbolt: Chec...
734
  	return false;
7bffd97eb   Mika Westerberg   thunderbolt: Add ...
735
  }
8c3b15a60   Mika Westerberg   thunderbolt: Intr...
736
737
738
739
740
741
742
743
744
745
746
  static inline bool tb_switch_is_ice_lake(const struct tb_switch *sw)
  {
  	if (sw->config.vendor_id == PCI_VENDOR_ID_INTEL) {
  		switch (sw->config.device_id) {
  		case PCI_DEVICE_ID_INTEL_ICL_NHI0:
  		case PCI_DEVICE_ID_INTEL_ICL_NHI1:
  			return true;
  		}
  	}
  	return false;
  }
0637e3df1   Gil Fine   thunderbolt: Intr...
747
748
749
750
751
752
  static inline bool tb_switch_is_tiger_lake(const struct tb_switch *sw)
  {
  	if (sw->config.vendor_id == PCI_VENDOR_ID_INTEL) {
  		switch (sw->config.device_id) {
  		case PCI_DEVICE_ID_INTEL_TGL_NHI0:
  		case PCI_DEVICE_ID_INTEL_TGL_NHI1:
f6439c531   Mika Westerberg   thunderbolt: Add ...
753
754
  		case PCI_DEVICE_ID_INTEL_TGL_H_NHI0:
  		case PCI_DEVICE_ID_INTEL_TGL_H_NHI1:
0637e3df1   Gil Fine   thunderbolt: Intr...
755
756
  			return true;
  		}
7bffd97eb   Mika Westerberg   thunderbolt: Add ...
757
  	}
0637e3df1   Gil Fine   thunderbolt: Intr...
758
  	return false;
7bffd97eb   Mika Westerberg   thunderbolt: Add ...
759
  }
f07a36081   Mika Westerberg   thunderbolt: Intr...
760
  /**
b04079837   Mika Westerberg   thunderbolt: Add ...
761
762
763
764
765
766
767
768
769
770
771
   * tb_switch_is_usb4() - Is the switch USB4 compliant
   * @sw: Switch to check
   *
   * Returns true if the @sw is USB4 compliant router, false otherwise.
   */
  static inline bool tb_switch_is_usb4(const struct tb_switch *sw)
  {
  	return sw->config.thunderbolt_version == USB4_VERSION_1_0;
  }
  
  /**
f07a36081   Mika Westerberg   thunderbolt: Intr...
772
773
774
775
776
777
778
779
780
781
782
783
   * tb_switch_is_icm() - Is the switch handled by ICM firmware
   * @sw: Switch to check
   *
   * In case there is a need to differentiate whether ICM firmware or SW CM
   * 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).
   */
  static inline bool tb_switch_is_icm(const struct tb_switch *sw)
  {
  	return !sw->config.enabled;
  }
91c0c1208   Mika Westerberg   thunderbolt: Add ...
784
785
  int tb_switch_lane_bonding_enable(struct tb_switch *sw);
  void tb_switch_lane_bonding_disable(struct tb_switch *sw);
de4620391   Mika Westerberg   thunderbolt: Conf...
786
787
  int tb_switch_configure_link(struct tb_switch *sw);
  void tb_switch_unconfigure_link(struct tb_switch *sw);
91c0c1208   Mika Westerberg   thunderbolt: Add ...
788

8afe909b7   Mika Westerberg   thunderbolt: Add ...
789
790
791
  bool tb_switch_query_dp_resource(struct tb_switch *sw, struct tb_port *in);
  int tb_switch_alloc_dp_resource(struct tb_switch *sw, struct tb_port *in);
  void tb_switch_dealloc_dp_resource(struct tb_switch *sw, struct tb_port *in);
cf29b9afb   Rajmohan Mani   thunderbolt: Add ...
792
793
794
795
796
797
798
799
800
801
  int tb_switch_tmu_init(struct tb_switch *sw);
  int tb_switch_tmu_post_time(struct tb_switch *sw);
  int tb_switch_tmu_disable(struct tb_switch *sw);
  int tb_switch_tmu_enable(struct tb_switch *sw);
  
  static inline bool tb_switch_tmu_is_enabled(const struct tb_switch *sw)
  {
  	return sw->tmu.rate == TB_SWITCH_TMU_RATE_HIFI &&
  	       !sw->tmu.unidirectional;
  }
9da672a42   Andreas Noever   thunderbolt: Scan...
802
  int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged);
520b67021   Andreas Noever   thunderbolt: Add ...
803
  int tb_port_add_nfc_credits(struct tb_port *port, int credits);
44242d6c9   Mika Westerberg   thunderbolt: Add ...
804
  int tb_port_set_initial_credits(struct tb_port *port, u32 credits);
520b67021   Andreas Noever   thunderbolt: Add ...
805
  int tb_port_clear_counter(struct tb_port *port, int counter);
b04079837   Mika Westerberg   thunderbolt: Add ...
806
  int tb_port_unlock(struct tb_port *port);
341d45188   Mika Westerberg   thunderbolt: Disa...
807
808
  int tb_port_enable(struct tb_port *port);
  int tb_port_disable(struct tb_port *port);
0b2863ac3   Mika Westerberg   thunderbolt: Add ...
809
810
811
812
  int tb_port_alloc_in_hopid(struct tb_port *port, int hopid, int max_hopid);
  void tb_port_release_in_hopid(struct tb_port *port, int hopid);
  int tb_port_alloc_out_hopid(struct tb_port *port, int hopid, int max_hopid);
  void tb_port_release_out_hopid(struct tb_port *port, int hopid);
fb19fac1d   Mika Westerberg   thunderbolt: Add ...
813
814
  struct tb_port *tb_next_port_on_path(struct tb_port *start, struct tb_port *end,
  				     struct tb_port *prev);
9da672a42   Andreas Noever   thunderbolt: Scan...
815

c64c3f3ac   Mika Westerberg   thunderbolt: Make...
816
817
818
819
820
821
822
823
824
825
826
  /**
   * tb_for_each_port_on_path() - Iterate over each port on path
   * @src: Source port
   * @dst: Destination port
   * @p: Port used as iterator
   *
   * Walks over each port on path from @src to @dst.
   */
  #define tb_for_each_port_on_path(src, dst, p)				\
  	for ((p) = tb_next_port_on_path((src), (dst), NULL); (p);	\
  	     (p) = tb_next_port_on_path((src), (dst), (p)))
5b7b8c0af   Mika Westerberg   thunderbolt: Make...
827
  int tb_port_get_link_speed(struct tb_port *port);
da2da04b8   Mika Westerberg   thunderbolt: Rewo...
828
  int tb_switch_find_vse_cap(struct tb_switch *sw, enum tb_switch_vse_cap vsec);
aa43a9dcf   Rajmohan Mani   thunderbolt: Make...
829
  int tb_switch_find_cap(struct tb_switch *sw, enum tb_switch_cap cap);
6de057ef9   Mika Westerberg   thunderbolt: Intr...
830
  int tb_switch_next_cap(struct tb_switch *sw, unsigned int offset);
da2da04b8   Mika Westerberg   thunderbolt: Rewo...
831
  int tb_port_find_cap(struct tb_port *port, enum tb_port_cap cap);
3c8b228d4   Mika Westerberg   thunderbolt: Intr...
832
  int tb_port_next_cap(struct tb_port *port, unsigned int offset);
e78db6f08   Mika Westerberg   thunderbolt: Gene...
833
  bool tb_port_is_enabled(struct tb_port *port);
e2b8785ed   Andreas Noever   thunderbolt: Add ...
834

e6f818585   Rajmohan Mani   thunderbolt: Add ...
835
836
  bool tb_usb3_port_is_enabled(struct tb_port *port);
  int tb_usb3_port_enable(struct tb_port *port, bool enable);
0414bec5f   Mika Westerberg   thunderbolt: Disc...
837
  bool tb_pci_port_is_enabled(struct tb_port *port);
93f36ade5   Mika Westerberg   thunderbolt: Gene...
838
  int tb_pci_port_enable(struct tb_port *port, bool enable);
4f807e47e   Mika Westerberg   thunderbolt: Add ...
839
840
841
842
843
844
  int tb_dp_port_hpd_is_active(struct tb_port *port);
  int tb_dp_port_hpd_clear(struct tb_port *port);
  int tb_dp_port_set_hops(struct tb_port *port, unsigned int video,
  			unsigned int aux_tx, unsigned int aux_rx);
  bool tb_dp_port_is_enabled(struct tb_port *port);
  int tb_dp_port_enable(struct tb_port *port, bool enable);
0414bec5f   Mika Westerberg   thunderbolt: Disc...
845
846
847
  struct tb_path *tb_path_discover(struct tb_port *src, int src_hopid,
  				 struct tb_port *dst, int dst_hopid,
  				 struct tb_port **last, const char *name);
8c7acaaf0   Mika Westerberg   thunderbolt: Exte...
848
849
850
  struct tb_path *tb_path_alloc(struct tb *tb, struct tb_port *src, int src_hopid,
  			      struct tb_port *dst, int dst_hopid, int link_nr,
  			      const char *name);
520b67021   Andreas Noever   thunderbolt: Add ...
851
852
853
854
  void tb_path_free(struct tb_path *path);
  int tb_path_activate(struct tb_path *path);
  void tb_path_deactivate(struct tb_path *path);
  bool tb_path_is_invalid(struct tb_path *path);
0bd680cd9   Mika Westerberg   thunderbolt: Add ...
855
856
  bool tb_path_port_on_path(const struct tb_path *path,
  			  const struct tb_port *port);
520b67021   Andreas Noever   thunderbolt: Add ...
857

cd22e73bd   Andreas Noever   thunderbolt: Read...
858
859
  int tb_drom_read(struct tb_switch *sw);
  int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid);
c90553b3c   Andreas Noever   thunderbolt: Read...
860

a9be55824   Mika Westerberg   thunderbolt: Move...
861
  int tb_lc_read_uuid(struct tb_switch *sw, u32 *uuid);
e28178bf5   Mika Westerberg   thunderbolt: Set ...
862
863
  int tb_lc_configure_port(struct tb_port *port);
  void tb_lc_unconfigure_port(struct tb_port *port);
284652a4a   Mika Westerberg   thunderbolt: Conf...
864
865
  int tb_lc_configure_xdomain(struct tb_port *port);
  void tb_lc_unconfigure_xdomain(struct tb_port *port);
b2911a593   Mika Westerberg   thunderbolt: Enab...
866
  int tb_lc_set_wake(struct tb_switch *sw, unsigned int flags);
5480dfc27   Mika Westerberg   thunderbolt: Set ...
867
  int tb_lc_set_sleep(struct tb_switch *sw);
91c0c1208   Mika Westerberg   thunderbolt: Add ...
868
  bool tb_lc_lane_bonding_possible(struct tb_switch *sw);
8afe909b7   Mika Westerberg   thunderbolt: Add ...
869
870
871
  bool tb_lc_dp_sink_query(struct tb_switch *sw, struct tb_port *in);
  int tb_lc_dp_sink_alloc(struct tb_switch *sw, struct tb_port *in);
  int tb_lc_dp_sink_dealloc(struct tb_switch *sw, struct tb_port *in);
1cb362938   Mario Limonciello   thunderbolt: Add ...
872
  int tb_lc_force_power(struct tb_switch *sw);
a25c8b2fc   Andreas Noever   thunderbolt: Init...
873
874
875
876
877
  
  static inline int tb_route_length(u64 route)
  {
  	return (fls64(route) + TB_ROUTE_SHIFT - 1) / TB_ROUTE_SHIFT;
  }
9da672a42   Andreas Noever   thunderbolt: Scan...
878
879
880
881
882
883
884
885
886
887
888
889
  /**
   * tb_downstream_route() - get route to downstream switch
   *
   * Port must not be the upstream port (otherwise a loop is created).
   *
   * Return: Returns a route to the switch behind @port.
   */
  static inline u64 tb_downstream_route(struct tb_port *port)
  {
  	return tb_route(port->sw)
  	       | ((u64) port->port << (port->sw->config.depth * 8));
  }
d1ff70241   Mika Westerberg   thunderbolt: Add ...
890
891
892
893
894
895
896
897
898
  bool tb_xdomain_handle_request(struct tb *tb, enum tb_cfg_pkg_type type,
  			       const void *buf, size_t size);
  struct tb_xdomain *tb_xdomain_alloc(struct tb *tb, struct device *parent,
  				    u64 route, const uuid_t *local_uuid,
  				    const uuid_t *remote_uuid);
  void tb_xdomain_add(struct tb_xdomain *xd);
  void tb_xdomain_remove(struct tb_xdomain *xd);
  struct tb_xdomain *tb_xdomain_find_by_link_depth(struct tb *tb, u8 link,
  						 u8 depth);
dacb12877   Kranthi Kuntala   thunderbolt: Add ...
899
900
901
902
903
904
905
906
907
908
909
910
911
912
  int tb_retimer_scan(struct tb_port *port);
  void tb_retimer_remove_all(struct tb_port *port);
  
  static inline bool tb_is_retimer(const struct device *dev)
  {
  	return dev->type == &tb_retimer_type;
  }
  
  static inline struct tb_retimer *tb_to_retimer(struct device *dev)
  {
  	if (tb_is_retimer(dev))
  		return container_of(dev, struct tb_retimer, dev);
  	return NULL;
  }
b04079837   Mika Westerberg   thunderbolt: Add ...
913
914
915
916
  int usb4_switch_setup(struct tb_switch *sw);
  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);
b04079837   Mika Westerberg   thunderbolt: Add ...
917
  bool usb4_switch_lane_bonding_possible(struct tb_switch *sw);
b2911a593   Mika Westerberg   thunderbolt: Enab...
918
  int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags);
b04079837   Mika Westerberg   thunderbolt: Add ...
919
920
921
922
923
924
925
926
927
928
929
930
  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,
  			 size_t size);
  int usb4_switch_nvm_write(struct tb_switch *sw, unsigned int address,
  			  const void *buf, size_t size);
  int usb4_switch_nvm_authenticate(struct tb_switch *sw);
  bool usb4_switch_query_dp_resource(struct tb_switch *sw, struct tb_port *in);
  int usb4_switch_alloc_dp_resource(struct tb_switch *sw, struct tb_port *in);
  int usb4_switch_dealloc_dp_resource(struct tb_switch *sw, struct tb_port *in);
  struct tb_port *usb4_switch_map_pcie_down(struct tb_switch *sw,
  					  const struct tb_port *port);
e6f818585   Rajmohan Mani   thunderbolt: Add ...
931
932
  struct tb_port *usb4_switch_map_usb3_down(struct tb_switch *sw,
  					  const struct tb_port *port);
b04079837   Mika Westerberg   thunderbolt: Add ...
933
934
  
  int usb4_port_unlock(struct tb_port *port);
e28178bf5   Mika Westerberg   thunderbolt: Set ...
935
936
  int usb4_port_configure(struct tb_port *port);
  void usb4_port_unconfigure(struct tb_port *port);
284652a4a   Mika Westerberg   thunderbolt: Conf...
937
938
  int usb4_port_configure_xdomain(struct tb_port *port);
  void usb4_port_unconfigure_xdomain(struct tb_port *port);
02d12855f   Rajmohan Mani   thunderbolt: Impl...
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
  int usb4_port_enumerate_retimers(struct tb_port *port);
  
  int usb4_port_retimer_read(struct tb_port *port, u8 index, u8 reg, void *buf,
  			   u8 size);
  int usb4_port_retimer_write(struct tb_port *port, u8 index, u8 reg,
  			    const void *buf, u8 size);
  int usb4_port_retimer_is_last(struct tb_port *port, u8 index);
  int usb4_port_retimer_nvm_sector_size(struct tb_port *port, u8 index);
  int usb4_port_retimer_nvm_write(struct tb_port *port, u8 index,
  				unsigned int address, const void *buf,
  				size_t size);
  int usb4_port_retimer_nvm_authenticate(struct tb_port *port, u8 index);
  int usb4_port_retimer_nvm_authenticate_status(struct tb_port *port, u8 index,
  					      u32 *status);
  int usb4_port_retimer_nvm_read(struct tb_port *port, u8 index,
  			       unsigned int address, void *buf, size_t size);
3b1d8d577   Mika Westerberg   thunderbolt: Impl...
955
956
957
958
959
960
961
962
963
  
  int usb4_usb3_port_max_link_rate(struct tb_port *port);
  int usb4_usb3_port_actual_link_rate(struct tb_port *port);
  int usb4_usb3_port_allocated_bandwidth(struct tb_port *port, int *upstream_bw,
  				       int *downstream_bw);
  int usb4_usb3_port_allocate_bandwidth(struct tb_port *port, int *upstream_bw,
  				      int *downstream_bw);
  int usb4_usb3_port_release_bandwidth(struct tb_port *port, int *upstream_bw,
  				     int *downstream_bw);
1cb362938   Mario Limonciello   thunderbolt: Add ...
964

810278da9   Mika Westerberg   thunderbolt: Capi...
965
  /* Keep link controller awake during update */
1cb362938   Mario Limonciello   thunderbolt: Add ...
966
967
968
  #define QUIRK_FORCE_POWER_LINK_CONTROLLER		BIT(0)
  
  void tb_check_quirks(struct tb_switch *sw);
b2be2b05c   Mika Westerberg   thunderbolt: Crea...
969
970
971
972
973
  #ifdef CONFIG_ACPI
  void tb_acpi_add_links(struct tb_nhi *nhi);
  #else
  static inline void tb_acpi_add_links(struct tb_nhi *nhi) { }
  #endif
54e418106   Gil Fine   thunderbolt: Add ...
974
975
976
977
978
979
980
981
982
983
984
  #ifdef CONFIG_DEBUG_FS
  void tb_debugfs_init(void);
  void tb_debugfs_exit(void);
  void tb_switch_debugfs_init(struct tb_switch *sw);
  void tb_switch_debugfs_remove(struct tb_switch *sw);
  #else
  static inline void tb_debugfs_init(void) { }
  static inline void tb_debugfs_exit(void) { }
  static inline void tb_switch_debugfs_init(struct tb_switch *sw) { }
  static inline void tb_switch_debugfs_remove(struct tb_switch *sw) { }
  #endif
2c6ea4e2c   Mika Westerberg   thunderbolt: Allo...
985
986
987
988
989
990
991
  #ifdef CONFIG_USB4_KUNIT_TEST
  int tb_test_init(void);
  void tb_test_exit(void);
  #else
  static inline int tb_test_init(void) { return 0; }
  static inline void tb_test_exit(void) { }
  #endif
d6cc51cd1   Andreas Noever   thunderbolt: Setu...
992
  #endif