1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Thunderbolt control channel messages
4 *
5 * Copyright (C) 2014 Andreas Noever <andreas.noever@gmail.com>
6 * Copyright (C) 2017, Intel Corporation
7 */
8
9#ifndef _TB_MSGS
10#define _TB_MSGS
11
12#include <linux/types.h>
13#include <linux/uuid.h>
14
15enum tb_cfg_space {
16	TB_CFG_HOPS = 0,
17	TB_CFG_PORT = 1,
18	TB_CFG_SWITCH = 2,
19	TB_CFG_COUNTERS = 3,
20};
21
22enum tb_cfg_error {
23	TB_CFG_ERROR_PORT_NOT_CONNECTED = 0,
24	TB_CFG_ERROR_LINK_ERROR = 1,
25	TB_CFG_ERROR_INVALID_CONFIG_SPACE = 2,
26	TB_CFG_ERROR_NO_SUCH_PORT = 4,
27	TB_CFG_ERROR_ACK_PLUG_EVENT = 7, /* send as reply to TB_CFG_PKG_EVENT */
28	TB_CFG_ERROR_LOOP = 8,
29	TB_CFG_ERROR_HEC_ERROR_DETECTED = 12,
30	TB_CFG_ERROR_FLOW_CONTROL_ERROR = 13,
31	TB_CFG_ERROR_LOCK = 15,
32	TB_CFG_ERROR_DP_BW = 32,
33	TB_CFG_ERROR_ROP_CMPLT = 33,
34	TB_CFG_ERROR_POP_CMPLT = 34,
35	TB_CFG_ERROR_PCIE_WAKE = 35,
36	TB_CFG_ERROR_DP_CON_CHANGE = 36,
37	TB_CFG_ERROR_DPTX_DISCOVERY = 37,
38	TB_CFG_ERROR_LINK_RECOVERY = 38,
39	TB_CFG_ERROR_ASYM_LINK = 39,
40};
41
42/* common header */
43struct tb_cfg_header {
44	u32 route_hi:22;
45	u32 unknown:10; /* highest order bit is set on replies */
46	u32 route_lo;
47} __packed;
48
49/* additional header for read/write packets */
50struct tb_cfg_address {
51	u32 offset:13; /* in dwords */
52	u32 length:6; /* in dwords */
53	u32 port:6;
54	enum tb_cfg_space space:2;
55	u32 seq:2; /* sequence number  */
56	u32 zero:3;
57} __packed;
58
59/* TB_CFG_PKG_READ, response for TB_CFG_PKG_WRITE */
60struct cfg_read_pkg {
61	struct tb_cfg_header header;
62	struct tb_cfg_address addr;
63} __packed;
64
65/* TB_CFG_PKG_WRITE, response for TB_CFG_PKG_READ */
66struct cfg_write_pkg {
67	struct tb_cfg_header header;
68	struct tb_cfg_address addr;
69	u32 data[64]; /* maximum size, tb_cfg_address.length has 6 bits */
70} __packed;
71
72/* TB_CFG_PKG_ERROR */
73struct cfg_error_pkg {
74	struct tb_cfg_header header;
75	enum tb_cfg_error error:8;
76	u32 port:6;
77	u32 reserved:16;
78	u32 pg:2;
79} __packed;
80
81struct cfg_ack_pkg {
82	struct tb_cfg_header header;
83};
84
85#define TB_CFG_ERROR_PG_HOT_PLUG	0x2
86#define TB_CFG_ERROR_PG_HOT_UNPLUG	0x3
87
88/* TB_CFG_PKG_EVENT */
89struct cfg_event_pkg {
90	struct tb_cfg_header header;
91	u32 port:6;
92	u32 zero:25;
93	bool unplug:1;
94} __packed;
95
96/* TB_CFG_PKG_RESET */
97struct cfg_reset_pkg {
98	struct tb_cfg_header header;
99} __packed;
100
101/* TB_CFG_PKG_PREPARE_TO_SLEEP */
102struct cfg_pts_pkg {
103	struct tb_cfg_header header;
104	u32 data;
105} __packed;
106
107/* ICM messages */
108
109enum icm_pkg_code {
110	ICM_GET_TOPOLOGY = 0x1,
111	ICM_DRIVER_READY = 0x3,
112	ICM_APPROVE_DEVICE = 0x4,
113	ICM_CHALLENGE_DEVICE = 0x5,
114	ICM_ADD_DEVICE_KEY = 0x6,
115	ICM_GET_ROUTE = 0xa,
116	ICM_APPROVE_XDOMAIN = 0x10,
117	ICM_DISCONNECT_XDOMAIN = 0x11,
118	ICM_PREBOOT_ACL = 0x18,
119	ICM_USB4_SWITCH_OP = 0x20,
120};
121
122enum icm_event_code {
123	ICM_EVENT_DEVICE_CONNECTED = 0x3,
124	ICM_EVENT_DEVICE_DISCONNECTED = 0x4,
125	ICM_EVENT_XDOMAIN_CONNECTED = 0x6,
126	ICM_EVENT_XDOMAIN_DISCONNECTED = 0x7,
127	ICM_EVENT_RTD3_VETO = 0xa,
128};
129
130struct icm_pkg_header {
131	u8 code;
132	u8 flags;
133	u8 packet_id;
134	u8 total_packets;
135};
136
137#define ICM_FLAGS_ERROR			BIT(0)
138#define ICM_FLAGS_NO_KEY		BIT(1)
139#define ICM_FLAGS_SLEVEL_SHIFT		3
140#define ICM_FLAGS_SLEVEL_MASK		GENMASK(4, 3)
141#define ICM_FLAGS_DUAL_LANE		BIT(5)
142#define ICM_FLAGS_SPEED_GEN3		BIT(7)
143#define ICM_FLAGS_WRITE			BIT(7)
144
145struct icm_pkg_driver_ready {
146	struct icm_pkg_header hdr;
147};
148
149/* Falcon Ridge only messages */
150
151struct icm_fr_pkg_driver_ready_response {
152	struct icm_pkg_header hdr;
153	u8 romver;
154	u8 ramver;
155	u16 security_level;
156};
157
158#define ICM_FR_SLEVEL_MASK		0xf
159
160/* Falcon Ridge & Alpine Ridge common messages */
161
162struct icm_fr_pkg_get_topology {
163	struct icm_pkg_header hdr;
164};
165
166#define ICM_GET_TOPOLOGY_PACKETS	14
167
168struct icm_fr_pkg_get_topology_response {
169	struct icm_pkg_header hdr;
170	u32 route_lo;
171	u32 route_hi;
172	u8 first_data;
173	u8 second_data;
174	u8 drom_i2c_address_index;
175	u8 switch_index;
176	u32 reserved[2];
177	u32 ports[16];
178	u32 port_hop_info[16];
179};
180
181#define ICM_SWITCH_USED			BIT(0)
182#define ICM_SWITCH_UPSTREAM_PORT_MASK	GENMASK(7, 1)
183#define ICM_SWITCH_UPSTREAM_PORT_SHIFT	1
184
185#define ICM_PORT_TYPE_MASK		GENMASK(23, 0)
186#define ICM_PORT_INDEX_SHIFT		24
187#define ICM_PORT_INDEX_MASK		GENMASK(31, 24)
188
189struct icm_fr_event_device_connected {
190	struct icm_pkg_header hdr;
191	uuid_t ep_uuid;
192	u8 connection_key;
193	u8 connection_id;
194	u16 link_info;
195	u32 ep_name[55];
196};
197
198#define ICM_LINK_INFO_LINK_MASK		0x7
199#define ICM_LINK_INFO_DEPTH_SHIFT	4
200#define ICM_LINK_INFO_DEPTH_MASK	GENMASK(7, 4)
201#define ICM_LINK_INFO_APPROVED		BIT(8)
202#define ICM_LINK_INFO_REJECTED		BIT(9)
203#define ICM_LINK_INFO_BOOT		BIT(10)
204
205struct icm_fr_pkg_approve_device {
206	struct icm_pkg_header hdr;
207	uuid_t ep_uuid;
208	u8 connection_key;
209	u8 connection_id;
210	u16 reserved;
211};
212
213struct icm_fr_event_device_disconnected {
214	struct icm_pkg_header hdr;
215	u16 reserved;
216	u16 link_info;
217};
218
219struct icm_fr_event_xdomain_connected {
220	struct icm_pkg_header hdr;
221	u16 reserved;
222	u16 link_info;
223	uuid_t remote_uuid;
224	uuid_t local_uuid;
225	u32 local_route_hi;
226	u32 local_route_lo;
227	u32 remote_route_hi;
228	u32 remote_route_lo;
229};
230
231struct icm_fr_event_xdomain_disconnected {
232	struct icm_pkg_header hdr;
233	u16 reserved;
234	u16 link_info;
235	uuid_t remote_uuid;
236};
237
238struct icm_fr_pkg_add_device_key {
239	struct icm_pkg_header hdr;
240	uuid_t ep_uuid;
241	u8 connection_key;
242	u8 connection_id;
243	u16 reserved;
244	u32 key[8];
245};
246
247struct icm_fr_pkg_add_device_key_response {
248	struct icm_pkg_header hdr;
249	uuid_t ep_uuid;
250	u8 connection_key;
251	u8 connection_id;
252	u16 reserved;
253};
254
255struct icm_fr_pkg_challenge_device {
256	struct icm_pkg_header hdr;
257	uuid_t ep_uuid;
258	u8 connection_key;
259	u8 connection_id;
260	u16 reserved;
261	u32 challenge[8];
262};
263
264struct icm_fr_pkg_challenge_device_response {
265	struct icm_pkg_header hdr;
266	uuid_t ep_uuid;
267	u8 connection_key;
268	u8 connection_id;
269	u16 reserved;
270	u32 challenge[8];
271	u32 response[8];
272};
273
274struct icm_fr_pkg_approve_xdomain {
275	struct icm_pkg_header hdr;
276	u16 reserved;
277	u16 link_info;
278	uuid_t remote_uuid;
279	u16 transmit_path;
280	u16 transmit_ring;
281	u16 receive_path;
282	u16 receive_ring;
283};
284
285struct icm_fr_pkg_approve_xdomain_response {
286	struct icm_pkg_header hdr;
287	u16 reserved;
288	u16 link_info;
289	uuid_t remote_uuid;
290	u16 transmit_path;
291	u16 transmit_ring;
292	u16 receive_path;
293	u16 receive_ring;
294};
295
296/* Alpine Ridge only messages */
297
298struct icm_ar_pkg_driver_ready_response {
299	struct icm_pkg_header hdr;
300	u8 romver;
301	u8 ramver;
302	u16 info;
303};
304
305#define ICM_AR_FLAGS_RTD3		BIT(6)
306
307#define ICM_AR_INFO_SLEVEL_MASK		GENMASK(3, 0)
308#define ICM_AR_INFO_BOOT_ACL_SHIFT	7
309#define ICM_AR_INFO_BOOT_ACL_MASK	GENMASK(11, 7)
310#define ICM_AR_INFO_BOOT_ACL_SUPPORTED	BIT(13)
311
312struct icm_ar_pkg_get_route {
313	struct icm_pkg_header hdr;
314	u16 reserved;
315	u16 link_info;
316};
317
318struct icm_ar_pkg_get_route_response {
319	struct icm_pkg_header hdr;
320	u16 reserved;
321	u16 link_info;
322	u32 route_hi;
323	u32 route_lo;
324};
325
326struct icm_ar_boot_acl_entry {
327	u32 uuid_lo;
328	u32 uuid_hi;
329};
330
331#define ICM_AR_PREBOOT_ACL_ENTRIES	16
332
333struct icm_ar_pkg_preboot_acl {
334	struct icm_pkg_header hdr;
335	struct icm_ar_boot_acl_entry acl[ICM_AR_PREBOOT_ACL_ENTRIES];
336};
337
338struct icm_ar_pkg_preboot_acl_response {
339	struct icm_pkg_header hdr;
340	struct icm_ar_boot_acl_entry acl[ICM_AR_PREBOOT_ACL_ENTRIES];
341};
342
343/* Titan Ridge messages */
344
345struct icm_tr_pkg_driver_ready_response {
346	struct icm_pkg_header hdr;
347	u16 reserved1;
348	u16 info;
349	u32 nvm_version;
350	u16 device_id;
351	u16 reserved2;
352};
353
354#define ICM_TR_FLAGS_RTD3		BIT(6)
355
356#define ICM_TR_INFO_SLEVEL_MASK		GENMASK(2, 0)
357#define ICM_TR_INFO_PROTO_VERSION_MASK	GENMASK(6, 4)
358#define ICM_TR_INFO_PROTO_VERSION_SHIFT	4
359#define ICM_TR_INFO_BOOT_ACL_SHIFT	7
360#define ICM_TR_INFO_BOOT_ACL_MASK	GENMASK(12, 7)
361
362struct icm_tr_event_device_connected {
363	struct icm_pkg_header hdr;
364	uuid_t ep_uuid;
365	u32 route_hi;
366	u32 route_lo;
367	u8 connection_id;
368	u8 reserved;
369	u16 link_info;
370	u32 ep_name[55];
371};
372
373struct icm_tr_event_device_disconnected {
374	struct icm_pkg_header hdr;
375	u32 route_hi;
376	u32 route_lo;
377};
378
379struct icm_tr_event_xdomain_connected {
380	struct icm_pkg_header hdr;
381	u16 reserved;
382	u16 link_info;
383	uuid_t remote_uuid;
384	uuid_t local_uuid;
385	u32 local_route_hi;
386	u32 local_route_lo;
387	u32 remote_route_hi;
388	u32 remote_route_lo;
389};
390
391struct icm_tr_event_xdomain_disconnected {
392	struct icm_pkg_header hdr;
393	u32 route_hi;
394	u32 route_lo;
395	uuid_t remote_uuid;
396};
397
398struct icm_tr_pkg_approve_device {
399	struct icm_pkg_header hdr;
400	uuid_t ep_uuid;
401	u32 route_hi;
402	u32 route_lo;
403	u8 connection_id;
404	u8 reserved1[3];
405};
406
407struct icm_tr_pkg_add_device_key {
408	struct icm_pkg_header hdr;
409	uuid_t ep_uuid;
410	u32 route_hi;
411	u32 route_lo;
412	u8 connection_id;
413	u8 reserved[3];
414	u32 key[8];
415};
416
417struct icm_tr_pkg_challenge_device {
418	struct icm_pkg_header hdr;
419	uuid_t ep_uuid;
420	u32 route_hi;
421	u32 route_lo;
422	u8 connection_id;
423	u8 reserved[3];
424	u32 challenge[8];
425};
426
427struct icm_tr_pkg_approve_xdomain {
428	struct icm_pkg_header hdr;
429	u32 route_hi;
430	u32 route_lo;
431	uuid_t remote_uuid;
432	u16 transmit_path;
433	u16 transmit_ring;
434	u16 receive_path;
435	u16 receive_ring;
436};
437
438struct icm_tr_pkg_disconnect_xdomain {
439	struct icm_pkg_header hdr;
440	u8 stage;
441	u8 reserved[3];
442	u32 route_hi;
443	u32 route_lo;
444	uuid_t remote_uuid;
445};
446
447struct icm_tr_pkg_challenge_device_response {
448	struct icm_pkg_header hdr;
449	uuid_t ep_uuid;
450	u32 route_hi;
451	u32 route_lo;
452	u8 connection_id;
453	u8 reserved[3];
454	u32 challenge[8];
455	u32 response[8];
456};
457
458struct icm_tr_pkg_add_device_key_response {
459	struct icm_pkg_header hdr;
460	uuid_t ep_uuid;
461	u32 route_hi;
462	u32 route_lo;
463	u8 connection_id;
464	u8 reserved[3];
465};
466
467struct icm_tr_pkg_approve_xdomain_response {
468	struct icm_pkg_header hdr;
469	u32 route_hi;
470	u32 route_lo;
471	uuid_t remote_uuid;
472	u16 transmit_path;
473	u16 transmit_ring;
474	u16 receive_path;
475	u16 receive_ring;
476};
477
478struct icm_tr_pkg_disconnect_xdomain_response {
479	struct icm_pkg_header hdr;
480	u8 stage;
481	u8 reserved[3];
482	u32 route_hi;
483	u32 route_lo;
484	uuid_t remote_uuid;
485};
486
487/* Ice Lake messages */
488
489struct icm_icl_event_rtd3_veto {
490	struct icm_pkg_header hdr;
491	u32 veto_reason;
492};
493
494/* USB4 ICM messages */
495
496struct icm_usb4_switch_op {
497	struct icm_pkg_header hdr;
498	u32 route_hi;
499	u32 route_lo;
500	u32 metadata;
501	u16 opcode;
502	u16 data_len_valid;
503	u32 data[16];
504};
505
506#define ICM_USB4_SWITCH_DATA_LEN_MASK	GENMASK(3, 0)
507#define ICM_USB4_SWITCH_DATA_VALID	BIT(4)
508
509struct icm_usb4_switch_op_response {
510	struct icm_pkg_header hdr;
511	u32 route_hi;
512	u32 route_lo;
513	u32 metadata;
514	u16 opcode;
515	u16 status;
516	u32 data[16];
517};
518
519/* XDomain messages */
520
521struct tb_xdomain_header {
522	u32 route_hi;
523	u32 route_lo;
524	u32 length_sn;
525};
526
527#define TB_XDOMAIN_LENGTH_MASK	GENMASK(5, 0)
528#define TB_XDOMAIN_SN_MASK	GENMASK(28, 27)
529#define TB_XDOMAIN_SN_SHIFT	27
530
531enum tb_xdp_type {
532	UUID_REQUEST_OLD = 1,
533	UUID_RESPONSE = 2,
534	PROPERTIES_REQUEST,
535	PROPERTIES_RESPONSE,
536	PROPERTIES_CHANGED_REQUEST,
537	PROPERTIES_CHANGED_RESPONSE,
538	ERROR_RESPONSE,
539	UUID_REQUEST = 12,
540	LINK_STATE_STATUS_REQUEST = 15,
541	LINK_STATE_STATUS_RESPONSE,
542	LINK_STATE_CHANGE_REQUEST,
543	LINK_STATE_CHANGE_RESPONSE,
544};
545
546struct tb_xdp_header {
547	struct tb_xdomain_header xd_hdr;
548	uuid_t uuid;
549	u32 type;
550};
551
552struct tb_xdp_error_response {
553	struct tb_xdp_header hdr;
554	u32 error;
555};
556
557struct tb_xdp_link_state_status {
558	struct tb_xdp_header hdr;
559};
560
561struct tb_xdp_link_state_status_response {
562	union {
563		struct tb_xdp_error_response err;
564		struct {
565			struct tb_xdp_header hdr;
566			u32 status;
567			u8 slw;
568			u8 tlw;
569			u8 sls;
570			u8 tls;
571		};
572	};
573};
574
575struct tb_xdp_link_state_change {
576	struct tb_xdp_header hdr;
577	u8 tlw;
578	u8 tls;
579	u16 reserved;
580};
581
582struct tb_xdp_link_state_change_response {
583	union {
584		struct tb_xdp_error_response err;
585		struct {
586			struct tb_xdp_header hdr;
587			u32 status;
588		};
589	};
590};
591
592struct tb_xdp_uuid {
593	struct tb_xdp_header hdr;
594};
595
596struct tb_xdp_uuid_response {
597	union {
598		struct tb_xdp_error_response err;
599		struct {
600			struct tb_xdp_header hdr;
601			uuid_t src_uuid;
602			u32 src_route_hi;
603			u32 src_route_lo;
604		};
605	};
606};
607
608struct tb_xdp_properties {
609	struct tb_xdp_header hdr;
610	uuid_t src_uuid;
611	uuid_t dst_uuid;
612	u16 offset;
613	u16 reserved;
614};
615
616struct tb_xdp_properties_response {
617	union {
618		struct tb_xdp_error_response err;
619		struct {
620			struct tb_xdp_header hdr;
621			uuid_t src_uuid;
622			uuid_t dst_uuid;
623			u16 offset;
624			u16 data_length;
625			u32 generation;
626			u32 data[];
627		};
628	};
629};
630
631/*
632 * Max length of data array single XDomain property response is allowed
633 * to carry.
634 */
635#define TB_XDP_PROPERTIES_MAX_DATA_LENGTH	\
636	(((256 - 4 - sizeof(struct tb_xdp_properties_response))) / 4)
637
638/* Maximum size of the total property block in dwords we allow */
639#define TB_XDP_PROPERTIES_MAX_LENGTH		500
640
641struct tb_xdp_properties_changed {
642	struct tb_xdp_header hdr;
643	uuid_t src_uuid;
644};
645
646struct tb_xdp_properties_changed_response {
647	union {
648		struct tb_xdp_error_response err;
649		struct tb_xdp_header hdr;
650	};
651};
652
653enum tb_xdp_error {
654	ERROR_SUCCESS,
655	ERROR_UNKNOWN_PACKET,
656	ERROR_UNKNOWN_DOMAIN,
657	ERROR_NOT_SUPPORTED,
658	ERROR_NOT_READY,
659};
660
661#endif
662