]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/thunderbolt/switch.c
2 * Thunderbolt Cactus Ridge driver - switch/port utility functions
4 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
7 #include <linux/delay.h>
11 /* port utility functions */
13 static const char *tb_port_type(struct tb_regs_port_header
*port
)
15 switch (port
->type
>> 16) {
17 switch ((u8
) port
->type
) {
42 static void tb_dump_port(struct tb
*tb
, struct tb_regs_port_header
*port
)
45 " Port %d: %x:%x (Revision: %d, TB Version: %d, Type: %s (%#x))\n",
46 port
->port_number
, port
->vendor_id
, port
->device_id
,
47 port
->revision
, port
->thunderbolt_version
, tb_port_type(port
),
49 tb_info(tb
, " Max hop id (in/out): %d/%d\n",
50 port
->max_in_hop_id
, port
->max_out_hop_id
);
51 tb_info(tb
, " Max counters: %d\n", port
->max_counters
);
52 tb_info(tb
, " NFC Credits: %#x\n", port
->nfc_credits
);
56 * tb_port_state() - get connectedness state of a port
58 * The port must have a TB_CAP_PHY (i.e. it should be a real port).
60 * Return: Returns an enum tb_port_state on success or an error code on failure.
62 static int tb_port_state(struct tb_port
*port
)
64 struct tb_cap_phy phy
;
66 if (port
->cap_phy
== 0) {
67 tb_port_WARN(port
, "does not have a PHY\n");
70 res
= tb_port_read(port
, &phy
, TB_CFG_PORT
, port
->cap_phy
, 2);
77 * tb_wait_for_port() - wait for a port to become ready
79 * Wait up to 1 second for a port to reach state TB_PORT_UP. If
80 * wait_if_unplugged is set then we also wait if the port is in state
81 * TB_PORT_UNPLUGGED (it takes a while for the device to be registered after
82 * switch resume). Otherwise we only wait if a device is registered but the link
83 * has not yet been established.
85 * Return: Returns an error code on failure. Returns 0 if the port is not
86 * connected or failed to reach state TB_PORT_UP within one second. Returns 1
87 * if the port is connected and in state TB_PORT_UP.
89 int tb_wait_for_port(struct tb_port
*port
, bool wait_if_unplugged
)
94 tb_port_WARN(port
, "does not have PHY\n");
97 if (tb_is_upstream_port(port
)) {
98 tb_port_WARN(port
, "is the upstream port\n");
103 state
= tb_port_state(port
);
106 if (state
== TB_PORT_DISABLED
) {
107 tb_port_info(port
, "is disabled (state: 0)\n");
110 if (state
== TB_PORT_UNPLUGGED
) {
111 if (wait_if_unplugged
) {
112 /* used during resume */
114 "is unplugged (state: 7), retrying...\n");
118 tb_port_info(port
, "is unplugged (state: 7)\n");
121 if (state
== TB_PORT_UP
) {
123 "is connected, link is up (state: 2)\n");
128 * After plug-in the state is TB_PORT_CONNECTING. Give it some
132 "is connected, link is not up (state: %d), retrying...\n",
137 "failed to reach state TB_PORT_UP. Ignoring port...\n");
142 * tb_init_port() - initialize a port
144 * This is a helper method for tb_switch_alloc. Does not check or initialize
145 * any downstream switches.
147 * Return: Returns 0 on success or an error code on failure.
149 static int tb_init_port(struct tb_switch
*sw
, u8 port_nr
)
153 struct tb_port
*port
= &sw
->ports
[port_nr
];
155 port
->port
= port_nr
;
157 res
= tb_port_read(port
, &port
->config
, TB_CFG_PORT
, 0, 8);
161 /* Port 0 is the switch itself and has no PHY. */
162 if (port
->config
.type
== TB_TYPE_PORT
&& port_nr
!= 0) {
163 cap
= tb_find_cap(port
, TB_CFG_PORT
, TB_CAP_PHY
);
168 tb_port_WARN(port
, "non switch port without a PHY\n");
171 tb_dump_port(sw
->tb
, &port
->config
);
173 /* TODO: Read dual link port, DP port and more from EEPROM. */
178 /* switch utility functions */
180 static void tb_dump_switch(struct tb
*tb
, struct tb_regs_switch_header
*sw
)
183 " Switch: %x:%x (Revision: %d, TB Version: %d)\n",
184 sw
->vendor_id
, sw
->device_id
, sw
->revision
,
185 sw
->thunderbolt_version
);
186 tb_info(tb
, " Max Port Number: %d\n", sw
->max_port_number
);
187 tb_info(tb
, " Config:\n");
189 " Upstream Port Number: %d Depth: %d Route String: %#llx Enabled: %d, PlugEventsDelay: %dms\n",
190 sw
->upstream_port_number
, sw
->depth
,
191 (((u64
) sw
->route_hi
) << 32) | sw
->route_lo
,
192 sw
->enabled
, sw
->plug_events_delay
);
194 " unknown1: %#x unknown4: %#x\n",
195 sw
->__unknown1
, sw
->__unknown4
);
199 * tb_plug_events_active() - enable/disable plug events on a switch
201 * Also configures a sane plug_events_delay of 255ms.
203 * Return: Returns 0 on success or an error code on failure.
205 static int tb_plug_events_active(struct tb_switch
*sw
, bool active
)
210 sw
->config
.plug_events_delay
= 0xff;
211 res
= tb_sw_write(sw
, ((u32
*) &sw
->config
) + 4, TB_CFG_SWITCH
, 4, 1);
215 res
= tb_sw_read(sw
, &data
, TB_CFG_SWITCH
, sw
->cap_plug_events
+ 1, 1);
220 data
= data
& 0xFFFFFF83;
221 switch (sw
->config
.device_id
) {
232 return tb_sw_write(sw
, &data
, TB_CFG_SWITCH
,
233 sw
->cap_plug_events
+ 1, 1);
238 * tb_switch_free() - free a tb_switch and all downstream switches
240 void tb_switch_free(struct tb_switch
*sw
)
243 /* port 0 is the switch itself and never has a remote */
244 for (i
= 1; i
<= sw
->config
.max_port_number
; i
++) {
245 if (tb_is_upstream_port(&sw
->ports
[i
]))
247 if (sw
->ports
[i
].remote
)
248 tb_switch_free(sw
->ports
[i
].remote
->sw
);
249 sw
->ports
[i
].remote
= NULL
;
252 tb_plug_events_active(sw
, false);
259 * tb_switch_alloc() - allocate and initialize a switch
261 * Return: Returns a NULL on failure.
263 struct tb_switch
*tb_switch_alloc(struct tb
*tb
, u64 route
)
267 struct tb_switch
*sw
;
268 int upstream_port
= tb_cfg_get_upstream_port(tb
->ctl
, route
);
269 if (upstream_port
< 0)
272 sw
= kzalloc(sizeof(*sw
), GFP_KERNEL
);
277 if (tb_cfg_read(tb
->ctl
, &sw
->config
, route
, 0, 2, 0, 5))
280 "initializing Switch at %#llx (depth: %d, up port: %d)\n",
281 route
, tb_route_length(route
), upstream_port
);
282 tb_info(tb
, "old switch config:\n");
283 tb_dump_switch(tb
, &sw
->config
);
285 /* configure switch */
286 sw
->config
.upstream_port_number
= upstream_port
;
287 sw
->config
.depth
= tb_route_length(route
);
288 sw
->config
.route_lo
= route
;
289 sw
->config
.route_hi
= route
>> 32;
290 sw
->config
.enabled
= 1;
291 /* from here on we may use the tb_sw_* functions & macros */
293 if (sw
->config
.vendor_id
!= 0x8086)
294 tb_sw_warn(sw
, "unknown switch vendor id %#x\n",
295 sw
->config
.vendor_id
);
297 if (sw
->config
.device_id
!= 0x1547 && sw
->config
.device_id
!= 0x1549)
298 tb_sw_warn(sw
, "unsupported switch device id %#x\n",
299 sw
->config
.device_id
);
301 /* upload configuration */
302 if (tb_sw_write(sw
, 1 + (u32
*) &sw
->config
, TB_CFG_SWITCH
, 1, 3))
305 /* initialize ports */
306 sw
->ports
= kcalloc(sw
->config
.max_port_number
+ 1, sizeof(*sw
->ports
),
311 for (i
= 0; i
<= sw
->config
.max_port_number
; i
++) {
312 if (tb_init_port(sw
, i
))
314 /* TODO: check if port is disabled (EEPROM) */
317 /* TODO: I2C, IECS, EEPROM, link controller */
319 cap
= tb_find_cap(&sw
->ports
[0], TB_CFG_SWITCH
, TB_CAP_PLUG_EVENTS
);
321 tb_sw_warn(sw
, "cannot find TB_CAP_PLUG_EVENTS aborting\n");
324 sw
->cap_plug_events
= cap
;
326 if (tb_plug_events_active(sw
, true))