xref: /freebsd/sys/dev/thunderbolt/router_var.h (revision efdb82413963bea5f4bf2ae52006cceeb6944a3b)
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  * $FreeBSD$
29  */
30 
31 #ifndef _ROUTER_VAR_H
32 #define _ROUTER_VAR_H
33 
34 struct router_softc;
35 struct router_command;
36 struct router_topo;
37 
38 typedef void (*router_callback_t)(struct router_softc *,
39     struct router_command *, void *);
40 
41 struct router_command {
42 	TAILQ_ENTRY(router_command) link;
43 	struct router_softc	*sc;
44 	struct nhi_cmd_frame	*nhicmd;
45 	u_int			flags;
46 #define RCMD_POLLED		(1 << 0)
47 #define RCMD_POLL_COMPLETE	(1 << 1)
48 	int			resp_len;
49 	router_callback_t	callback;
50 	void			*callback_arg;
51 	u_int			dwlen;
52 	u_int			timeout;
53 	int			retries;
54 	u_int			ev;
55 	uint8_t			resp_buffer[NHI_RING0_FRAME_SIZE];
56 };
57 
58 struct router_softc {
59 	TAILQ_ENTRY(router_softc) link;
60 	u_int			debug;
61 	tb_route_t		route;
62 	device_t		dev;
63 	struct nhi_softc	*nsc;
64 
65 	struct mtx		mtx;
66 	struct nhi_ring_pair	*ring0;
67 	TAILQ_HEAD(,router_command) cmd_queue;
68 
69 	struct router_command	*inflight_cmd;
70 
71 	uint8_t			depth;
72 	uint8_t			max_adap;
73 
74 	struct router_softc	**adapters;
75 
76 	uint32_t		uuid[4];
77 };
78 
79 struct router_cfg_cap {
80 	uint16_t	current_cap;
81 	uint16_t	next_cap;
82 	uint32_t	space;
83 	uint8_t		adap;
84 	uint8_t		cap_id;
85 	uint8_t		vsc_id;
86 	uint8_t		vsc_len;
87 	uint16_t	vsec_len;
88 };
89 
90 /* Router reset registers */
91 #define ROUTER_HRR	0x39898
92 #define ROUTER_HIR	0x39858
93 
94 int tb_router_attach(struct router_softc *, tb_route_t);
95 int tb_router_attach_root(struct nhi_softc *, tb_route_t);
96 int tb_router_detach(struct router_softc *);
97 int tb_config_read(struct router_softc *, u_int, u_int, u_int, u_int,
98     uint32_t *);
99 int tb_config_read_polled(struct router_softc *, u_int, u_int, u_int, u_int,
100     uint32_t *);
101 int tb_config_read_async(struct router_softc *, u_int, u_int, u_int, u_int,
102     uint32_t *, void *);
103 int tb_config_write(struct router_softc *, u_int, u_int, u_int, u_int,
104     uint32_t *);
105 int tb_config_next_cap(struct router_softc *, struct router_cfg_cap *);
106 int tb_config_find_cap(struct router_softc *, struct router_cfg_cap *);
107 int tb_config_find_router_cap(struct router_softc *, u_int, u_int, u_int *);
108 int tb_config_find_router_vsc(struct router_softc *, u_int, u_int *);
109 int tb_config_find_router_vsec(struct router_softc *, u_int, u_int *);
110 int tb_config_find_adapter_cap(struct router_softc *, u_int, u_int, u_int *);
111 int tb_config_get_lc_uuid(struct router_softc *, uint8_t *);
112 
113 #define TB_CONFIG_ADDR(seq, space, adapter, dwlen, offset) \
114     ((seq << TB_CFG_SEQ_SHIFT) | space | \
115     (adapter << TB_CFG_ADAPTER_SHIFT) | (dwlen << TB_CFG_SIZE_SHIFT) | \
116     (offset & TB_CFG_ADDR_MASK))
117 
118 #define TB_ROUTE(router) \
119     ((uint64_t)(router)->route.hi << 32) | (router)->route.lo
120 
121 static __inline void *
router_get_frame_data(struct router_command * cmd)122 router_get_frame_data(struct router_command *cmd)
123 {
124 	return ((void *)cmd->nhicmd->data);
125 }
126 
127 /*
128  * Read the Router config space for the router referred to in the softc.
129  * addr - The dword offset in the config space
130  * dwlen - The number of dwords
131  * buf - must be large enough to hold the number of dwords requested.
132  */
133 static __inline int
tb_config_router_read(struct router_softc * sc,u_int addr,u_int dwlen,uint32_t * buf)134 tb_config_router_read(struct router_softc *sc, u_int addr, u_int dwlen,
135     uint32_t *buf)
136 {
137 	return (tb_config_read(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf));
138 }
139 
140 static __inline int
tb_config_router_read_polled(struct router_softc * sc,u_int addr,u_int dwlen,uint32_t * buf)141 tb_config_router_read_polled(struct router_softc *sc, u_int addr, u_int dwlen,
142     uint32_t *buf)
143 {
144 	return (tb_config_read_polled(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf));
145 }
146 
147 /*
148  * Write the Router config space for the router referred to in the softc.
149  * addr - The dword offset in the config space
150  * dwlen - The number of dwords
151  * buf - must be large enough to hold the number of dwords requested.
152  */
153 static __inline int
tb_config_router_write(struct router_softc * sc,u_int addr,u_int dwlen,uint32_t * buf)154 tb_config_router_write(struct router_softc *sc, u_int addr, u_int dwlen,
155     uint32_t *buf)
156 {
157 	return (tb_config_write(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf));
158 }
159 
160 /*
161  * Read the Adapter config space for the router referred to in the softc.
162  * adap - Adapter number
163  * addr - The dword offset in the config space
164  * dwlen - The number of dwords
165  * buf - must be large enough to hold the number of dwords requested.
166  */
167 static __inline int
tb_config_adapter_read(struct router_softc * sc,u_int adap,u_int addr,u_int dwlen,uint32_t * buf)168 tb_config_adapter_read(struct router_softc *sc, u_int adap, u_int addr,
169     u_int dwlen, uint32_t *buf)
170 {
171 	return (tb_config_read(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf));
172 }
173 
174 /*
175  * Read the Adapter config space for the router referred to in the softc.
176  * adap - Adapter number
177  * addr - The dword offset in the config space
178  * dwlen - The number of dwords
179  * buf - must be large enough to hold the number of dwords requested.
180  */
181 static __inline int
tb_config_adapter_write(struct router_softc * sc,u_int adap,u_int addr,u_int dwlen,uint32_t * buf)182 tb_config_adapter_write(struct router_softc *sc, u_int adap, u_int addr,
183     u_int dwlen, uint32_t *buf)
184 {
185 	return (tb_config_write(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf));
186 }
187 
188 /*
189  * Read the Path config space for the router referred to in the softc.
190  * adap - Adapter number
191  * hopid - HopID of the path
192  * len - The number of adjacent paths
193  * buf - must be large enough to hold the number of dwords requested.
194  */
195 static __inline int
tb_config_path_read(struct router_softc * sc,u_int adap,u_int hopid,u_int num,uint32_t * buf)196 tb_config_path_read(struct router_softc *sc, u_int adap, u_int hopid,
197     u_int num, uint32_t *buf)
198 {
199 	return (tb_config_read(sc, TB_CFG_CS_PATH, adap, hopid * 2,
200 	    num * 2, buf));
201 }
202 
203 /*
204  * Write the Path config space for the router referred to in the softc.
205  * adap - Adapter number
206  * hopid - HopID of the path
207  * len - The number of adjacent paths
208  * buf - must be large enough to hold the number of dwords requested.
209  */
210 static __inline int
tb_config_path_write(struct router_softc * sc,u_int adap,u_int hopid,u_int num,uint32_t * buf)211 tb_config_path_write(struct router_softc *sc, u_int adap, u_int hopid,
212     u_int num, uint32_t *buf)
213 {
214 	return (tb_config_write(sc, TB_CFG_CS_PATH, adap, hopid * 2,
215 	    num * 2, buf));
216 }
217 
218 /*
219  * Read the Counters config space for the router referred to in the softc.
220  * Counters come in sets of 3 dwords.
221  * adap - Adapter number
222  * set - The counter set index
223  * num - The number of adjacent counter sets to read
224  * buf - must be large enough to hold the number of dwords requested.
225  */
226 static __inline int
tb_config_counters_read(struct router_softc * sc,u_int adap,u_int set,u_int num,uint32_t * buf)227 tb_config_counters_read(struct router_softc *sc, u_int adap, u_int set,
228     u_int num, uint32_t *buf)
229 {
230 	return (tb_config_read(sc, TB_CFG_CS_COUNTERS, adap, set * 3,
231 	    num * 3, buf));
232 }
233 
234 static __inline void
tb_config_set_root(struct router_softc * sc)235 tb_config_set_root(struct router_softc *sc)
236 {
237 	sc->nsc->root_rsc = sc;
238 }
239 
240 static __inline void *
tb_config_get_root(struct router_softc * sc)241 tb_config_get_root(struct router_softc *sc)
242 {
243 	return (sc->nsc->root_rsc);
244 }
245 
246 #endif /* _ROUTER_VAR_H */
247