xref: /freebsd/sys/dev/ntb/ntb.c (revision 4490696b3edf3ed9be81e695fb9dba03c94f89c8)
19a5325c2SAlexander Motin /*-
29a5325c2SAlexander Motin  * Copyright (c) 2016 Alexander Motin <mav@FreeBSD.org>
39a5325c2SAlexander Motin  * All rights reserved.
49a5325c2SAlexander Motin  *
59a5325c2SAlexander Motin  * Redistribution and use in source and binary forms, with or without
69a5325c2SAlexander Motin  * modification, are permitted provided that the following conditions
79a5325c2SAlexander Motin  * are met:
89a5325c2SAlexander Motin  * 1. Redistributions of source code must retain the above copyright
99a5325c2SAlexander Motin  *    notice, this list of conditions and the following disclaimer.
109a5325c2SAlexander Motin  * 2. Redistributions in binary form must reproduce the above copyright
119a5325c2SAlexander Motin  *    notice, this list of conditions and the following disclaimer in the
129a5325c2SAlexander Motin  *    documentation and/or other materials provided with the distribution.
139a5325c2SAlexander Motin  *
149a5325c2SAlexander Motin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
159a5325c2SAlexander Motin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
169a5325c2SAlexander Motin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
179a5325c2SAlexander Motin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
189a5325c2SAlexander Motin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199a5325c2SAlexander Motin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
209a5325c2SAlexander Motin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
219a5325c2SAlexander Motin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
229a5325c2SAlexander Motin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
239a5325c2SAlexander Motin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
249a5325c2SAlexander Motin  * SUCH DAMAGE.
259a5325c2SAlexander Motin  */
269a5325c2SAlexander Motin 
279a5325c2SAlexander Motin #include <sys/cdefs.h>
289a5325c2SAlexander Motin __FBSDID("$FreeBSD$");
299a5325c2SAlexander Motin 
309a5325c2SAlexander Motin #include <sys/param.h>
319a5325c2SAlexander Motin #include <sys/kernel.h>
329a5325c2SAlexander Motin #include <sys/systm.h>
339a5325c2SAlexander Motin #include <sys/bus.h>
34*4490696bSAlexander Motin #include <sys/rmlock.h>
35*4490696bSAlexander Motin #include <sys/malloc.h>
369a5325c2SAlexander Motin #include <sys/module.h>
379a5325c2SAlexander Motin #include <sys/sysctl.h>
389a5325c2SAlexander Motin 
399a5325c2SAlexander Motin #include "ntb.h"
409a5325c2SAlexander Motin 
419a5325c2SAlexander Motin devclass_t ntb_hw_devclass;
429a5325c2SAlexander Motin SYSCTL_NODE(_hw, OID_AUTO, ntb, CTLFLAG_RW, 0, "NTB sysctls");
439a5325c2SAlexander Motin 
44*4490696bSAlexander Motin struct ntb_child {
45*4490696bSAlexander Motin 	device_t	dev;
46*4490696bSAlexander Motin 	int		enabled;
47*4490696bSAlexander Motin 	int		mwoff;
48*4490696bSAlexander Motin 	int		mwcnt;
49*4490696bSAlexander Motin 	int		spadoff;
50*4490696bSAlexander Motin 	int		spadcnt;
51*4490696bSAlexander Motin 	int		dboff;
52*4490696bSAlexander Motin 	int		dbmask;
53*4490696bSAlexander Motin 	void		*ctx;
54*4490696bSAlexander Motin 	const struct ntb_ctx_ops *ctx_ops;
55*4490696bSAlexander Motin 	struct rmlock	ctx_lock;
56*4490696bSAlexander Motin 	struct ntb_child *next;
57*4490696bSAlexander Motin };
58*4490696bSAlexander Motin 
59*4490696bSAlexander Motin int
60*4490696bSAlexander Motin ntb_register_device(device_t dev)
61*4490696bSAlexander Motin {
62*4490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
63*4490696bSAlexander Motin 	struct ntb_child *nc;
64*4490696bSAlexander Motin 	int i, mw, mwu, mwt, spad, spadu, spadt, db, dbu, dbt;
65*4490696bSAlexander Motin 	char cfg[128] = "";
66*4490696bSAlexander Motin 	char buf[32];
67*4490696bSAlexander Motin 	char *n, *np, *c, *p, *name;
68*4490696bSAlexander Motin 
69*4490696bSAlexander Motin 	mwu = 0;
70*4490696bSAlexander Motin 	mwt = NTB_MW_COUNT(dev);
71*4490696bSAlexander Motin 	spadu = 0;
72*4490696bSAlexander Motin 	spadt = NTB_SPAD_COUNT(dev);
73*4490696bSAlexander Motin 	dbu = 0;
74*4490696bSAlexander Motin 	dbt = flsll(NTB_DB_VALID_MASK(dev));
75*4490696bSAlexander Motin 
76*4490696bSAlexander Motin 	device_printf(dev, "%d memory windows, %d scratchpads, "
77*4490696bSAlexander Motin 	    "%d doorbells\n", mwt, spadt, dbt);
78*4490696bSAlexander Motin 
79*4490696bSAlexander Motin 	snprintf(buf, sizeof(buf), "hint.%s.%d.config", device_get_name(dev),
80*4490696bSAlexander Motin 	    device_get_unit(dev));
81*4490696bSAlexander Motin 	TUNABLE_STR_FETCH(buf, cfg, sizeof(cfg));
82*4490696bSAlexander Motin 	n = cfg;
83*4490696bSAlexander Motin 	i = 0;
84*4490696bSAlexander Motin 	while ((c = strsep(&n, ",")) != NULL) {
85*4490696bSAlexander Motin 		np = c;
86*4490696bSAlexander Motin 		name = strsep(&np, ":");
87*4490696bSAlexander Motin 		if (name != NULL && name[0] == 0)
88*4490696bSAlexander Motin 			name = NULL;
89*4490696bSAlexander Motin 		p = strsep(&np, ":");
90*4490696bSAlexander Motin 		mw = (p && p[0] != 0) ? strtol(p, NULL, 10) : mwt - mwu;
91*4490696bSAlexander Motin 		p = strsep(&np, ":");
92*4490696bSAlexander Motin 		spad = (p && p[0] != 0) ? strtol(p, NULL, 10) : spadt - spadu;
93*4490696bSAlexander Motin 		db = (np && np[0] != 0) ? strtol(np, NULL, 10) : dbt - dbu;
94*4490696bSAlexander Motin 
95*4490696bSAlexander Motin 		if (mw > mwt - mwu || spad > spadt - spadu || db > dbt - dbu) {
96*4490696bSAlexander Motin 			device_printf(dev, "Not enough resources for config\n");
97*4490696bSAlexander Motin 			break;
98*4490696bSAlexander Motin 		}
99*4490696bSAlexander Motin 
100*4490696bSAlexander Motin 		nc = malloc(sizeof(*nc), M_DEVBUF, M_WAITOK | M_ZERO);
101*4490696bSAlexander Motin 		nc->mwoff = mwu;
102*4490696bSAlexander Motin 		nc->mwcnt = mw;
103*4490696bSAlexander Motin 		nc->spadoff = spadu;
104*4490696bSAlexander Motin 		nc->spadcnt = spad;
105*4490696bSAlexander Motin 		nc->dboff = dbu;
106*4490696bSAlexander Motin 		nc->dbmask = (db == 0) ? 0 : (0xffffffffffffffff >> (64 - db));
107*4490696bSAlexander Motin 		rm_init(&nc->ctx_lock, "ntb ctx");
108*4490696bSAlexander Motin 		nc->dev = device_add_child(dev, name, -1);
109*4490696bSAlexander Motin 		if (nc->dev == NULL) {
110*4490696bSAlexander Motin 			ntb_unregister_device(dev);
111*4490696bSAlexander Motin 			return (ENOMEM);
112*4490696bSAlexander Motin 		}
113*4490696bSAlexander Motin 		device_set_ivars(nc->dev, nc);
114*4490696bSAlexander Motin 		*cpp = nc;
115*4490696bSAlexander Motin 		cpp = &nc->next;
116*4490696bSAlexander Motin 
117*4490696bSAlexander Motin 		if (bootverbose) {
118*4490696bSAlexander Motin 			device_printf(dev, "%d \"%s\":", i, name);
119*4490696bSAlexander Motin 			if (mw > 0) {
120*4490696bSAlexander Motin 				printf(" memory windows %d", mwu);
121*4490696bSAlexander Motin 				if (mw > 1)
122*4490696bSAlexander Motin 					printf("-%d", mwu + mw - 1);
123*4490696bSAlexander Motin 			}
124*4490696bSAlexander Motin 			if (spad > 0) {
125*4490696bSAlexander Motin 				printf(" scratchpads %d", spadu);
126*4490696bSAlexander Motin 				if (spad > 1)
127*4490696bSAlexander Motin 					printf("-%d", spadu + spad - 1);
128*4490696bSAlexander Motin 			}
129*4490696bSAlexander Motin 			if (db > 0) {
130*4490696bSAlexander Motin 				printf(" doorbells %d", dbu);
131*4490696bSAlexander Motin 				if (db > 1)
132*4490696bSAlexander Motin 					printf("-%d", dbu + db - 1);
133*4490696bSAlexander Motin 			}
134*4490696bSAlexander Motin 			printf("\n");
135*4490696bSAlexander Motin 		}
136*4490696bSAlexander Motin 
137*4490696bSAlexander Motin 		mwu += mw;
138*4490696bSAlexander Motin 		spadu += spad;
139*4490696bSAlexander Motin 		dbu += db;
140*4490696bSAlexander Motin 		i++;
141*4490696bSAlexander Motin 	}
142*4490696bSAlexander Motin 
143*4490696bSAlexander Motin 	bus_generic_attach(dev);
144*4490696bSAlexander Motin 	return (0);
145*4490696bSAlexander Motin }
146*4490696bSAlexander Motin 
147*4490696bSAlexander Motin int
148*4490696bSAlexander Motin ntb_unregister_device(device_t dev)
149*4490696bSAlexander Motin {
150*4490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
151*4490696bSAlexander Motin 	struct ntb_child *nc;
152*4490696bSAlexander Motin 	int error = 0;
153*4490696bSAlexander Motin 
154*4490696bSAlexander Motin 	while ((nc = *cpp) != NULL) {
155*4490696bSAlexander Motin 		*cpp = (*cpp)->next;
156*4490696bSAlexander Motin 		error = device_delete_child(dev, nc->dev);
157*4490696bSAlexander Motin 		if (error)
158*4490696bSAlexander Motin 			break;
159*4490696bSAlexander Motin 		rm_destroy(&nc->ctx_lock);
160*4490696bSAlexander Motin 		free(nc, M_DEVBUF);
161*4490696bSAlexander Motin 	}
162*4490696bSAlexander Motin 	return (error);
163*4490696bSAlexander Motin }
164*4490696bSAlexander Motin 
165*4490696bSAlexander Motin void
166*4490696bSAlexander Motin ntb_link_event(device_t dev)
167*4490696bSAlexander Motin {
168*4490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
169*4490696bSAlexander Motin 	struct ntb_child *nc;
170*4490696bSAlexander Motin 	struct rm_priotracker ctx_tracker;
171*4490696bSAlexander Motin 
172*4490696bSAlexander Motin 	for (nc = *cpp; nc != NULL; nc = nc->next) {
173*4490696bSAlexander Motin 		rm_rlock(&nc->ctx_lock, &ctx_tracker);
174*4490696bSAlexander Motin 		if (nc->ctx_ops != NULL && nc->ctx_ops->link_event != NULL)
175*4490696bSAlexander Motin 			nc->ctx_ops->link_event(nc->ctx);
176*4490696bSAlexander Motin 		rm_runlock(&nc->ctx_lock, &ctx_tracker);
177*4490696bSAlexander Motin 	}
178*4490696bSAlexander Motin }
179*4490696bSAlexander Motin 
180*4490696bSAlexander Motin void
181*4490696bSAlexander Motin ntb_db_event(device_t dev, uint32_t vec)
182*4490696bSAlexander Motin {
183*4490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
184*4490696bSAlexander Motin 	struct ntb_child *nc;
185*4490696bSAlexander Motin 	struct rm_priotracker ctx_tracker;
186*4490696bSAlexander Motin 
187*4490696bSAlexander Motin 	for (nc = *cpp; nc != NULL; nc = nc->next) {
188*4490696bSAlexander Motin 		rm_rlock(&nc->ctx_lock, &ctx_tracker);
189*4490696bSAlexander Motin 		if (nc->ctx_ops != NULL && nc->ctx_ops->db_event != NULL)
190*4490696bSAlexander Motin 			nc->ctx_ops->db_event(nc->ctx, vec);
191*4490696bSAlexander Motin 		rm_runlock(&nc->ctx_lock, &ctx_tracker);
192*4490696bSAlexander Motin 	}
193*4490696bSAlexander Motin }
194*4490696bSAlexander Motin 
195*4490696bSAlexander Motin bool
196*4490696bSAlexander Motin ntb_link_is_up(device_t ntb, enum ntb_speed *speed, enum ntb_width *width)
197*4490696bSAlexander Motin {
198*4490696bSAlexander Motin 
199*4490696bSAlexander Motin 	return (NTB_LINK_IS_UP(device_get_parent(ntb), speed, width));
200*4490696bSAlexander Motin }
201*4490696bSAlexander Motin 
202*4490696bSAlexander Motin int
203*4490696bSAlexander Motin ntb_link_enable(device_t ntb, enum ntb_speed speed, enum ntb_width width)
204*4490696bSAlexander Motin {
205*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
206*4490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(device_get_parent(nc->dev));
207*4490696bSAlexander Motin 	struct ntb_child *nc1;
208*4490696bSAlexander Motin 
209*4490696bSAlexander Motin 	for (nc1 = *cpp; nc1 != NULL; nc1 = nc->next) {
210*4490696bSAlexander Motin 		if (nc1->enabled) {
211*4490696bSAlexander Motin 			nc->enabled = 1;
212*4490696bSAlexander Motin 			return (0);
213*4490696bSAlexander Motin 		}
214*4490696bSAlexander Motin 	}
215*4490696bSAlexander Motin 	nc->enabled = 1;
216*4490696bSAlexander Motin 	return (NTB_LINK_ENABLE(device_get_parent(ntb), speed, width));
217*4490696bSAlexander Motin }
218*4490696bSAlexander Motin 
219*4490696bSAlexander Motin int
220*4490696bSAlexander Motin ntb_link_disable(device_t ntb)
221*4490696bSAlexander Motin {
222*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
223*4490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(device_get_parent(nc->dev));
224*4490696bSAlexander Motin 	struct ntb_child *nc1;
225*4490696bSAlexander Motin 
226*4490696bSAlexander Motin 	if (!nc->enabled)
227*4490696bSAlexander Motin 		return (0);
228*4490696bSAlexander Motin 	nc->enabled = 0;
229*4490696bSAlexander Motin 	for (nc1 = *cpp; nc1 != NULL; nc1 = nc->next) {
230*4490696bSAlexander Motin 		if (nc1->enabled)
231*4490696bSAlexander Motin 			return (0);
232*4490696bSAlexander Motin 	}
233*4490696bSAlexander Motin 	return (NTB_LINK_DISABLE(device_get_parent(ntb)));
234*4490696bSAlexander Motin }
235*4490696bSAlexander Motin 
236*4490696bSAlexander Motin bool
237*4490696bSAlexander Motin ntb_link_enabled(device_t ntb)
238*4490696bSAlexander Motin {
239*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
240*4490696bSAlexander Motin 
241*4490696bSAlexander Motin 	return (nc->enabled && NTB_LINK_ENABLED(device_get_parent(ntb)));
242*4490696bSAlexander Motin }
243*4490696bSAlexander Motin 
244*4490696bSAlexander Motin int
245*4490696bSAlexander Motin ntb_set_ctx(device_t ntb, void *ctx, const struct ntb_ctx_ops *ctx_ops)
246*4490696bSAlexander Motin {
247*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
248*4490696bSAlexander Motin 
249*4490696bSAlexander Motin 	if (ctx == NULL || ctx_ops == NULL)
250*4490696bSAlexander Motin 		return (EINVAL);
251*4490696bSAlexander Motin 
252*4490696bSAlexander Motin 	rm_wlock(&nc->ctx_lock);
253*4490696bSAlexander Motin 	if (nc->ctx_ops != NULL) {
254*4490696bSAlexander Motin 		rm_wunlock(&nc->ctx_lock);
255*4490696bSAlexander Motin 		return (EINVAL);
256*4490696bSAlexander Motin 	}
257*4490696bSAlexander Motin 	nc->ctx = ctx;
258*4490696bSAlexander Motin 	nc->ctx_ops = ctx_ops;
259*4490696bSAlexander Motin 	rm_wunlock(&nc->ctx_lock);
260*4490696bSAlexander Motin 
261*4490696bSAlexander Motin 	return (0);
262*4490696bSAlexander Motin }
263*4490696bSAlexander Motin 
264*4490696bSAlexander Motin void *
265*4490696bSAlexander Motin ntb_get_ctx(device_t ntb, const struct ntb_ctx_ops **ctx_ops)
266*4490696bSAlexander Motin {
267*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
268*4490696bSAlexander Motin 
269*4490696bSAlexander Motin 	KASSERT(nc->ntb_ctx != NULL && nc->ctx_ops != NULL, ("bogus"));
270*4490696bSAlexander Motin 	if (ctx_ops != NULL)
271*4490696bSAlexander Motin 		*ctx_ops = nc->ctx_ops;
272*4490696bSAlexander Motin 	return (nc->ctx);
273*4490696bSAlexander Motin }
274*4490696bSAlexander Motin 
275*4490696bSAlexander Motin void
276*4490696bSAlexander Motin ntb_clear_ctx(device_t ntb)
277*4490696bSAlexander Motin {
278*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
279*4490696bSAlexander Motin 
280*4490696bSAlexander Motin 	rm_wlock(&nc->ctx_lock);
281*4490696bSAlexander Motin 	nc->ctx = NULL;
282*4490696bSAlexander Motin 	nc->ctx_ops = NULL;
283*4490696bSAlexander Motin 	rm_wunlock(&nc->ctx_lock);
284*4490696bSAlexander Motin }
285*4490696bSAlexander Motin 
286*4490696bSAlexander Motin uint8_t
287*4490696bSAlexander Motin ntb_mw_count(device_t ntb)
288*4490696bSAlexander Motin {
289*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
290*4490696bSAlexander Motin 
291*4490696bSAlexander Motin 	return (nc->mwcnt);
292*4490696bSAlexander Motin }
293*4490696bSAlexander Motin 
294*4490696bSAlexander Motin int
295*4490696bSAlexander Motin ntb_mw_get_range(device_t ntb, unsigned mw_idx, vm_paddr_t *base,
296*4490696bSAlexander Motin     caddr_t *vbase, size_t *size, size_t *align, size_t *align_size,
297*4490696bSAlexander Motin     bus_addr_t *plimit)
298*4490696bSAlexander Motin {
299*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
300*4490696bSAlexander Motin 
301*4490696bSAlexander Motin 	return (NTB_MW_GET_RANGE(device_get_parent(ntb), mw_idx + nc->mwoff,
302*4490696bSAlexander Motin 	    base, vbase, size, align, align_size, plimit));
303*4490696bSAlexander Motin }
304*4490696bSAlexander Motin 
305*4490696bSAlexander Motin int
306*4490696bSAlexander Motin ntb_mw_set_trans(device_t ntb, unsigned mw_idx, bus_addr_t addr, size_t size)
307*4490696bSAlexander Motin {
308*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
309*4490696bSAlexander Motin 
310*4490696bSAlexander Motin 	return (NTB_MW_SET_TRANS(device_get_parent(ntb), mw_idx + nc->mwoff,
311*4490696bSAlexander Motin 	    addr, size));
312*4490696bSAlexander Motin }
313*4490696bSAlexander Motin 
314*4490696bSAlexander Motin int
315*4490696bSAlexander Motin ntb_mw_clear_trans(device_t ntb, unsigned mw_idx)
316*4490696bSAlexander Motin {
317*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
318*4490696bSAlexander Motin 
319*4490696bSAlexander Motin 	return (NTB_MW_CLEAR_TRANS(device_get_parent(ntb), mw_idx + nc->mwoff));
320*4490696bSAlexander Motin }
321*4490696bSAlexander Motin 
322*4490696bSAlexander Motin int
323*4490696bSAlexander Motin ntb_mw_get_wc(device_t ntb, unsigned mw_idx, vm_memattr_t *mode)
324*4490696bSAlexander Motin {
325*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
326*4490696bSAlexander Motin 
327*4490696bSAlexander Motin 	return (NTB_MW_GET_WC(device_get_parent(ntb), mw_idx + nc->mwoff, mode));
328*4490696bSAlexander Motin }
329*4490696bSAlexander Motin 
330*4490696bSAlexander Motin int
331*4490696bSAlexander Motin ntb_mw_set_wc(device_t ntb, unsigned mw_idx, vm_memattr_t mode)
332*4490696bSAlexander Motin {
333*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
334*4490696bSAlexander Motin 
335*4490696bSAlexander Motin 	return (NTB_MW_SET_WC(device_get_parent(ntb), mw_idx + nc->mwoff, mode));
336*4490696bSAlexander Motin }
337*4490696bSAlexander Motin 
338*4490696bSAlexander Motin uint8_t
339*4490696bSAlexander Motin ntb_spad_count(device_t ntb)
340*4490696bSAlexander Motin {
341*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
342*4490696bSAlexander Motin 
343*4490696bSAlexander Motin 	return (nc->spadcnt);
344*4490696bSAlexander Motin }
345*4490696bSAlexander Motin 
346*4490696bSAlexander Motin void
347*4490696bSAlexander Motin ntb_spad_clear(device_t ntb)
348*4490696bSAlexander Motin {
349*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
350*4490696bSAlexander Motin 	unsigned i;
351*4490696bSAlexander Motin 
352*4490696bSAlexander Motin 	for (i = 0; i < nc->spadcnt; i++)
353*4490696bSAlexander Motin 		NTB_SPAD_WRITE(device_get_parent(ntb), i + nc->spadoff, 0);
354*4490696bSAlexander Motin }
355*4490696bSAlexander Motin 
356*4490696bSAlexander Motin int
357*4490696bSAlexander Motin ntb_spad_write(device_t ntb, unsigned int idx, uint32_t val)
358*4490696bSAlexander Motin {
359*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
360*4490696bSAlexander Motin 
361*4490696bSAlexander Motin 	return (NTB_SPAD_WRITE(device_get_parent(ntb), idx + nc->spadoff, val));
362*4490696bSAlexander Motin }
363*4490696bSAlexander Motin 
364*4490696bSAlexander Motin int
365*4490696bSAlexander Motin ntb_spad_read(device_t ntb, unsigned int idx, uint32_t *val)
366*4490696bSAlexander Motin {
367*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
368*4490696bSAlexander Motin 
369*4490696bSAlexander Motin 	return (NTB_SPAD_READ(device_get_parent(ntb), idx + nc->spadoff, val));
370*4490696bSAlexander Motin }
371*4490696bSAlexander Motin 
372*4490696bSAlexander Motin int
373*4490696bSAlexander Motin ntb_peer_spad_write(device_t ntb, unsigned int idx, uint32_t val)
374*4490696bSAlexander Motin {
375*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
376*4490696bSAlexander Motin 
377*4490696bSAlexander Motin 	return (NTB_PEER_SPAD_WRITE(device_get_parent(ntb), idx + nc->spadoff,
378*4490696bSAlexander Motin 	    val));
379*4490696bSAlexander Motin }
380*4490696bSAlexander Motin 
381*4490696bSAlexander Motin int
382*4490696bSAlexander Motin ntb_peer_spad_read(device_t ntb, unsigned int idx, uint32_t *val)
383*4490696bSAlexander Motin {
384*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
385*4490696bSAlexander Motin 
386*4490696bSAlexander Motin 	return (NTB_PEER_SPAD_READ(device_get_parent(ntb), idx + nc->spadoff,
387*4490696bSAlexander Motin 	    val));
388*4490696bSAlexander Motin }
389*4490696bSAlexander Motin 
390*4490696bSAlexander Motin uint64_t
391*4490696bSAlexander Motin ntb_db_valid_mask(device_t ntb)
392*4490696bSAlexander Motin {
393*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
394*4490696bSAlexander Motin 
395*4490696bSAlexander Motin 	return (nc->dbmask);
396*4490696bSAlexander Motin }
397*4490696bSAlexander Motin 
398*4490696bSAlexander Motin int
399*4490696bSAlexander Motin ntb_db_vector_count(device_t ntb)
400*4490696bSAlexander Motin {
401*4490696bSAlexander Motin 
402*4490696bSAlexander Motin 	return (NTB_DB_VECTOR_COUNT(device_get_parent(ntb)));
403*4490696bSAlexander Motin }
404*4490696bSAlexander Motin 
405*4490696bSAlexander Motin uint64_t
406*4490696bSAlexander Motin ntb_db_vector_mask(device_t ntb, uint32_t vector)
407*4490696bSAlexander Motin {
408*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
409*4490696bSAlexander Motin 
410*4490696bSAlexander Motin 	return ((NTB_DB_VECTOR_MASK(device_get_parent(ntb), vector)
411*4490696bSAlexander Motin 	    >> nc->dboff) & nc->dbmask);
412*4490696bSAlexander Motin }
413*4490696bSAlexander Motin 
414*4490696bSAlexander Motin int
415*4490696bSAlexander Motin ntb_peer_db_addr(device_t ntb, bus_addr_t *db_addr, vm_size_t *db_size)
416*4490696bSAlexander Motin {
417*4490696bSAlexander Motin 
418*4490696bSAlexander Motin 	return (NTB_PEER_DB_ADDR(device_get_parent(ntb), db_addr, db_size));
419*4490696bSAlexander Motin }
420*4490696bSAlexander Motin 
421*4490696bSAlexander Motin void
422*4490696bSAlexander Motin ntb_db_clear(device_t ntb, uint64_t bits)
423*4490696bSAlexander Motin {
424*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
425*4490696bSAlexander Motin 
426*4490696bSAlexander Motin 	return (NTB_DB_CLEAR(device_get_parent(ntb), bits << nc->dboff));
427*4490696bSAlexander Motin }
428*4490696bSAlexander Motin 
429*4490696bSAlexander Motin void
430*4490696bSAlexander Motin ntb_db_clear_mask(device_t ntb, uint64_t bits)
431*4490696bSAlexander Motin {
432*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
433*4490696bSAlexander Motin 
434*4490696bSAlexander Motin 	return (NTB_DB_CLEAR_MASK(device_get_parent(ntb), bits << nc->dboff));
435*4490696bSAlexander Motin }
436*4490696bSAlexander Motin 
437*4490696bSAlexander Motin uint64_t
438*4490696bSAlexander Motin ntb_db_read(device_t ntb)
439*4490696bSAlexander Motin {
440*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
441*4490696bSAlexander Motin 
442*4490696bSAlexander Motin 	return ((NTB_DB_READ(device_get_parent(ntb)) >> nc->dboff)
443*4490696bSAlexander Motin 	    & nc->dbmask);
444*4490696bSAlexander Motin }
445*4490696bSAlexander Motin 
446*4490696bSAlexander Motin void
447*4490696bSAlexander Motin ntb_db_set_mask(device_t ntb, uint64_t bits)
448*4490696bSAlexander Motin {
449*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
450*4490696bSAlexander Motin 
451*4490696bSAlexander Motin 	return (NTB_DB_SET_MASK(device_get_parent(ntb), bits << nc->dboff));
452*4490696bSAlexander Motin }
453*4490696bSAlexander Motin 
454*4490696bSAlexander Motin void
455*4490696bSAlexander Motin ntb_peer_db_set(device_t ntb, uint64_t bits)
456*4490696bSAlexander Motin {
457*4490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
458*4490696bSAlexander Motin 
459*4490696bSAlexander Motin 	return (NTB_PEER_DB_SET(device_get_parent(ntb), bits << nc->dboff));
460*4490696bSAlexander Motin }
461*4490696bSAlexander Motin 
4629a5325c2SAlexander Motin MODULE_VERSION(ntb, 1);
463