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