xref: /freebsd/sys/dev/thunderbolt/router_var.h (revision c4fde87a3236b500246d4fce76dbca2a3d64f73a)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2022 Scott Long
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #ifndef _ROUTER_VAR_H
30 #define _ROUTER_VAR_H
31 
32 struct router_softc;
33 struct router_command;
34 struct router_topo;
35 
36 typedef void (*router_callback_t)(struct router_softc *,
37     struct router_command *, void *);
38 
39 struct router_command {
40 	TAILQ_ENTRY(router_command) link;
41 	struct router_softc	*sc;
42 	struct nhi_cmd_frame	*nhicmd;
43 	u_int			flags;
44 #define RCMD_POLLED		(1 << 0)
45 #define RCMD_POLL_COMPLETE	(1 << 1)
46 	int			resp_len;
47 	router_callback_t	callback;
48 	void			*callback_arg;
49 	u_int			dwlen;
50 	u_int			timeout;
51 	int			retries;
52 	u_int			ev;
53 	uint8_t			resp_buffer[NHI_RING0_FRAME_SIZE];
54 };
55 
56 struct router_softc {
57 	TAILQ_ENTRY(router_softc) link;
58 	u_int			debug;
59 	tb_route_t		route;
60 	device_t		dev;
61 	struct nhi_softc	*nsc;
62 	bool			suspended;
63 
64 	struct mtx		mtx;
65 	struct nhi_ring_pair	*ring0;
66 	TAILQ_HEAD(,router_command) cmd_queue;
67 
68 	struct router_command	*inflight_cmd;
69 
70 	uint8_t			depth;
71 	uint8_t			max_adap;
72 
73 	struct router_softc	**adapters;
74 
75 	uint32_t		uuid[4];
76 };
77 
78 struct router_cfg_cap {
79 	uint16_t	current_cap;
80 	uint16_t	next_cap;
81 	uint32_t	space;
82 	uint8_t		adap;
83 	uint8_t		cap_id;
84 	uint8_t		vsc_id;
85 	uint8_t		vsc_len;
86 	uint16_t	vsec_len;
87 };
88 
89 /* Router reset registers */
90 #define ROUTER_HRR	0x39898
91 #define ROUTER_HIR	0x39858
92 
93 /* Router config space registers */
94 #define ROUTER_CS_5	5
95 #define ROUTER_SLP	(1<<0)	/* Enter sleep (CS5). */
96 #define ROUTER_WOP	(1<<1)	/* Wake on PCIe (CS5). */
97 #define ROUTER_WOU	(1<<2)	/* Wake on USB3 (CS5). */
98 #define ROUTER_WOD	(1<<3)	/* Wake on DP (CS5). */
99 #define ROUTER_CS_6	6
100 #define ROUTER_SLPR	(1<<0)	/* Sleep ready (CS6). */
101 
102 int tb_router_attach(struct router_softc *, tb_route_t);
103 int tb_router_attach_root(struct nhi_softc *, tb_route_t);
104 int tb_router_detach(struct router_softc *);
105 int tb_router_suspend(struct router_softc *);
106 int tb_config_read(struct router_softc *, u_int, u_int, u_int, u_int,
107     uint32_t *);
108 int tb_config_read_polled(struct router_softc *, u_int, u_int, u_int, u_int,
109     uint32_t *);
110 int tb_config_read_async(struct router_softc *, u_int, u_int, u_int, u_int,
111     uint32_t *, void *);
112 int tb_config_write(struct router_softc *, u_int, u_int, u_int, u_int,
113     uint32_t *);
114 int tb_config_next_cap(struct router_softc *, struct router_cfg_cap *);
115 int tb_config_find_cap(struct router_softc *, struct router_cfg_cap *);
116 int tb_config_find_router_cap(struct router_softc *, u_int, u_int, u_int *);
117 int tb_config_find_router_vsc(struct router_softc *, u_int, u_int *);
118 int tb_config_find_router_vsec(struct router_softc *, u_int, u_int *);
119 int tb_config_find_adapter_cap(struct router_softc *, u_int, u_int, u_int *);
120 int tb_config_get_lc_uuid(struct router_softc *, uint8_t *);
121 
122 #define TB_CONFIG_ADDR(seq, space, adapter, dwlen, offset) \
123     ((seq << TB_CFG_SEQ_SHIFT) | space | \
124     (adapter << TB_CFG_ADAPTER_SHIFT) | (dwlen << TB_CFG_SIZE_SHIFT) | \
125     (offset & TB_CFG_ADDR_MASK))
126 
127 #define TB_ROUTE(router) \
128     ((uint64_t)(router)->route.hi << 32) | (router)->route.lo
129 
130 static __inline void *
131 router_get_frame_data(struct router_command *cmd)
132 {
133 	return ((void *)cmd->nhicmd->data);
134 }
135 
136 /*
137  * Read the Router config space for the router referred to in the softc.
138  * addr - The dword offset in the config space
139  * dwlen - The number of dwords
140  * buf - must be large enough to hold the number of dwords requested.
141  */
142 static __inline int
143 tb_config_router_read(struct router_softc *sc, u_int addr, u_int dwlen,
144     uint32_t *buf)
145 {
146 	return (tb_config_read(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf));
147 }
148 
149 static __inline int
150 tb_config_router_read_polled(struct router_softc *sc, u_int addr, u_int dwlen,
151     uint32_t *buf)
152 {
153 	return (tb_config_read_polled(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf));
154 }
155 
156 /*
157  * Write the Router config space for the router referred to in the softc.
158  * addr - The dword offset in the config space
159  * dwlen - The number of dwords
160  * buf - must be large enough to hold the number of dwords requested.
161  */
162 static __inline int
163 tb_config_router_write(struct router_softc *sc, u_int addr, u_int dwlen,
164     uint32_t *buf)
165 {
166 	return (tb_config_write(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf));
167 }
168 
169 /*
170  * Read the Adapter config space for the router referred to in the softc.
171  * adap - Adapter number
172  * addr - The dword offset in the config space
173  * dwlen - The number of dwords
174  * buf - must be large enough to hold the number of dwords requested.
175  */
176 static __inline int
177 tb_config_adapter_read(struct router_softc *sc, u_int adap, u_int addr,
178     u_int dwlen, uint32_t *buf)
179 {
180 	return (tb_config_read(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf));
181 }
182 
183 /*
184  * Read the Adapter config space for the router referred to in the softc.
185  * adap - Adapter number
186  * addr - The dword offset in the config space
187  * dwlen - The number of dwords
188  * buf - must be large enough to hold the number of dwords requested.
189  */
190 static __inline int
191 tb_config_adapter_write(struct router_softc *sc, u_int adap, u_int addr,
192     u_int dwlen, uint32_t *buf)
193 {
194 	return (tb_config_write(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf));
195 }
196 
197 /*
198  * Read the Path config space for the router referred to in the softc.
199  * adap - Adapter number
200  * hopid - HopID of the path
201  * len - The number of adjacent paths
202  * buf - must be large enough to hold the number of dwords requested.
203  */
204 static __inline int
205 tb_config_path_read(struct router_softc *sc, u_int adap, u_int hopid,
206     u_int num, uint32_t *buf)
207 {
208 	return (tb_config_read(sc, TB_CFG_CS_PATH, adap, hopid * 2,
209 	    num * 2, buf));
210 }
211 
212 /*
213  * Write the Path config space for the router referred to in the softc.
214  * adap - Adapter number
215  * hopid - HopID of the path
216  * len - The number of adjacent paths
217  * buf - must be large enough to hold the number of dwords requested.
218  */
219 static __inline int
220 tb_config_path_write(struct router_softc *sc, u_int adap, u_int hopid,
221     u_int num, uint32_t *buf)
222 {
223 	return (tb_config_write(sc, TB_CFG_CS_PATH, adap, hopid * 2,
224 	    num * 2, buf));
225 }
226 
227 /*
228  * Read the Counters config space for the router referred to in the softc.
229  * Counters come in sets of 3 dwords.
230  * adap - Adapter number
231  * set - The counter set index
232  * num - The number of adjacent counter sets to read
233  * buf - must be large enough to hold the number of dwords requested.
234  */
235 static __inline int
236 tb_config_counters_read(struct router_softc *sc, u_int adap, u_int set,
237     u_int num, uint32_t *buf)
238 {
239 	return (tb_config_read(sc, TB_CFG_CS_COUNTERS, adap, set * 3,
240 	    num * 3, buf));
241 }
242 
243 static __inline void
244 tb_config_set_root(struct router_softc *sc)
245 {
246 	sc->nsc->root_rsc = sc;
247 }
248 
249 static __inline void *
250 tb_config_get_root(struct router_softc *sc)
251 {
252 	return (sc->nsc->root_rsc);
253 }
254 
255 #endif /* _ROUTER_VAR_H */
256