xref: /linux/drivers/thunderbolt/tb_regs.h (revision bb1c928df78ee6e3665a0d013e74108cc9abf34b)
1 /*
2  * Thunderbolt Cactus Ridge driver - Port/Switch config area registers
3  *
4  * Every thunderbolt device consists (logically) of a switch with multiple
5  * ports. Every port contains up to four config regions (HOPS, PORT, SWITCH,
6  * COUNTERS) which are used to configure the device.
7  *
8  * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
9  */
10 
11 #ifndef _TB_REGS
12 #define _TB_REGS
13 
14 #include <linux/types.h>
15 
16 
17 #define TB_ROUTE_SHIFT 8  /* number of bits in a port entry of a route */
18 
19 
20 /*
21  * TODO: should be 63? But we do not know how to receive frames larger than 256
22  * bytes at the frame level. (header + checksum = 16, 60*4 = 240)
23  */
24 #define TB_MAX_CONFIG_RW_LENGTH 60
25 
26 enum tb_switch_cap {
27 	TB_SWITCH_CAP_VSE		= 0x05,
28 };
29 
30 enum tb_switch_vse_cap {
31 	TB_VSE_CAP_PLUG_EVENTS		= 0x01, /* also EEPROM */
32 	TB_VSE_CAP_TIME2		= 0x03,
33 	TB_VSE_CAP_IECS			= 0x04,
34 	TB_VSE_CAP_LINK_CONTROLLER	= 0x06, /* also IECS */
35 };
36 
37 enum tb_port_cap {
38 	TB_PORT_CAP_PHY			= 0x01,
39 	TB_PORT_CAP_TIME1		= 0x03,
40 	TB_PORT_CAP_ADAP		= 0x04,
41 	TB_PORT_CAP_VSE			= 0x05,
42 };
43 
44 enum tb_port_state {
45 	TB_PORT_DISABLED	= 0, /* tb_cap_phy.disable == 1 */
46 	TB_PORT_CONNECTING	= 1, /* retry */
47 	TB_PORT_UP		= 2,
48 	TB_PORT_UNPLUGGED	= 7,
49 };
50 
51 /* capability headers */
52 
53 struct tb_cap_basic {
54 	u8 next;
55 	/* enum tb_cap cap:8; prevent "narrower than values of its type" */
56 	u8 cap; /* if cap == 0x05 then we have a extended capability */
57 } __packed;
58 
59 /**
60  * struct tb_cap_extended_short - Switch extended short capability
61  * @next: Pointer to the next capability. If @next and @length are zero
62  *	  then we have a long cap.
63  * @cap: Base capability ID (see &enum tb_switch_cap)
64  * @vsec_id: Vendor specific capability ID (see &enum switch_vse_cap)
65  * @length: Length of this capability
66  */
67 struct tb_cap_extended_short {
68 	u8 next;
69 	u8 cap;
70 	u8 vsec_id;
71 	u8 length;
72 } __packed;
73 
74 /**
75  * struct tb_cap_extended_long - Switch extended long capability
76  * @zero1: This field should be zero
77  * @cap: Base capability ID (see &enum tb_switch_cap)
78  * @vsec_id: Vendor specific capability ID (see &enum switch_vse_cap)
79  * @zero2: This field should be zero
80  * @next: Pointer to the next capability
81  * @length: Length of this capability
82  */
83 struct tb_cap_extended_long {
84 	u8 zero1;
85 	u8 cap;
86 	u8 vsec_id;
87 	u8 zero2;
88 	u16 next;
89 	u16 length;
90 } __packed;
91 
92 /* capabilities */
93 
94 struct tb_cap_link_controller {
95 	struct tb_cap_extended_long cap_header;
96 	u32 count:4; /* number of link controllers */
97 	u32 unknown1:4;
98 	u32 base_offset:8; /*
99 			    * offset (into this capability) of the configuration
100 			    * area of the first link controller
101 			    */
102 	u32 length:12; /* link controller configuration area length */
103 	u32 unknown2:4; /* TODO check that length is correct */
104 } __packed;
105 
106 struct tb_cap_phy {
107 	struct tb_cap_basic cap_header;
108 	u32 unknown1:16;
109 	u32 unknown2:14;
110 	bool disable:1;
111 	u32 unknown3:11;
112 	enum tb_port_state state:4;
113 	u32 unknown4:2;
114 } __packed;
115 
116 struct tb_eeprom_ctl {
117 	bool clock:1; /* send pulse to transfer one bit */
118 	bool access_low:1; /* set to 0 before access */
119 	bool data_out:1; /* to eeprom */
120 	bool data_in:1; /* from eeprom */
121 	bool access_high:1; /* set to 1 before access */
122 	bool not_present:1; /* should be 0 */
123 	bool unknown1:1;
124 	bool present:1; /* should be 1 */
125 	u32 unknown2:24;
126 } __packed;
127 
128 struct tb_cap_plug_events {
129 	struct tb_cap_extended_short cap_header;
130 	u32 __unknown1:2;
131 	u32 plug_events:5;
132 	u32 __unknown2:25;
133 	u32 __unknown3;
134 	u32 __unknown4;
135 	struct tb_eeprom_ctl eeprom_ctl;
136 	u32 __unknown5[7];
137 	u32 drom_offset; /* 32 bit register, but eeprom addresses are 16 bit */
138 } __packed;
139 
140 /* device headers */
141 
142 /* Present on port 0 in TB_CFG_SWITCH at address zero. */
143 struct tb_regs_switch_header {
144 	/* DWORD 0 */
145 	u16 vendor_id;
146 	u16 device_id;
147 	/* DWORD 1 */
148 	u32 first_cap_offset:8;
149 	u32 upstream_port_number:6;
150 	u32 max_port_number:6;
151 	u32 depth:3;
152 	u32 __unknown1:1;
153 	u32 revision:8;
154 	/* DWORD 2 */
155 	u32 route_lo;
156 	/* DWORD 3 */
157 	u32 route_hi:31;
158 	bool enabled:1;
159 	/* DWORD 4 */
160 	u32 plug_events_delay:8; /*
161 				  * RW, pause between plug events in
162 				  * milliseconds. Writing 0x00 is interpreted
163 				  * as 255ms.
164 				  */
165 	u32 __unknown4:16;
166 	u32 thunderbolt_version:8;
167 } __packed;
168 
169 enum tb_port_type {
170 	TB_TYPE_INACTIVE	= 0x000000,
171 	TB_TYPE_PORT		= 0x000001,
172 	TB_TYPE_NHI		= 0x000002,
173 	/* TB_TYPE_ETHERNET	= 0x020000, lower order bits are not known */
174 	/* TB_TYPE_SATA		= 0x080000, lower order bits are not known */
175 	TB_TYPE_DP_HDMI_IN	= 0x0e0101,
176 	TB_TYPE_DP_HDMI_OUT	= 0x0e0102,
177 	TB_TYPE_PCIE_DOWN	= 0x100101,
178 	TB_TYPE_PCIE_UP		= 0x100102,
179 	/* TB_TYPE_USB		= 0x200000, lower order bits are not known */
180 };
181 
182 /* Present on every port in TB_CF_PORT at address zero. */
183 struct tb_regs_port_header {
184 	/* DWORD 0 */
185 	u16 vendor_id;
186 	u16 device_id;
187 	/* DWORD 1 */
188 	u32 first_cap_offset:8;
189 	u32 max_counters:11;
190 	u32 __unknown1:5;
191 	u32 revision:8;
192 	/* DWORD 2 */
193 	enum tb_port_type type:24;
194 	u32 thunderbolt_version:8;
195 	/* DWORD 3 */
196 	u32 __unknown2:20;
197 	u32 port_number:6;
198 	u32 __unknown3:6;
199 	/* DWORD 4 */
200 	u32 nfc_credits;
201 	/* DWORD 5 */
202 	u32 max_in_hop_id:11;
203 	u32 max_out_hop_id:11;
204 	u32 __unkown4:10;
205 	/* DWORD 6 */
206 	u32 __unknown5;
207 	/* DWORD 7 */
208 	u32 __unknown6;
209 
210 } __packed;
211 
212 /* Hop register from TB_CFG_HOPS. 8 byte per entry. */
213 struct tb_regs_hop {
214 	/* DWORD 0 */
215 	u32 next_hop:11; /*
216 			  * hop to take after sending the packet through
217 			  * out_port (on the incoming port of the next switch)
218 			  */
219 	u32 out_port:6; /* next port of the path (on the same switch) */
220 	u32 initial_credits:8;
221 	u32 unknown1:6; /* set to zero */
222 	bool enable:1;
223 
224 	/* DWORD 1 */
225 	u32 weight:4;
226 	u32 unknown2:4; /* set to zero */
227 	u32 priority:3;
228 	bool drop_packages:1;
229 	u32 counter:11; /* index into TB_CFG_COUNTERS on this port */
230 	bool counter_enable:1;
231 	bool ingress_fc:1;
232 	bool egress_fc:1;
233 	bool ingress_shared_buffer:1;
234 	bool egress_shared_buffer:1;
235 	u32 unknown3:4; /* set to zero */
236 } __packed;
237 
238 
239 #endif
240