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