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