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