xref: /freebsd/sys/dev/ntb/ntb.c (revision c7dabb6563630d729b55bca02fa6fd56f1081b6d)
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>
344490696bSAlexander Motin #include <sys/rmlock.h>
354490696bSAlexander 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 
444490696bSAlexander Motin struct ntb_child {
454490696bSAlexander Motin 	device_t	dev;
464490696bSAlexander Motin 	int		enabled;
474490696bSAlexander Motin 	int		mwoff;
484490696bSAlexander Motin 	int		mwcnt;
494490696bSAlexander Motin 	int		spadoff;
504490696bSAlexander Motin 	int		spadcnt;
514490696bSAlexander Motin 	int		dboff;
524490696bSAlexander Motin 	int		dbmask;
534490696bSAlexander Motin 	void		*ctx;
544490696bSAlexander Motin 	const struct ntb_ctx_ops *ctx_ops;
554490696bSAlexander Motin 	struct rmlock	ctx_lock;
564490696bSAlexander Motin 	struct ntb_child *next;
574490696bSAlexander Motin };
584490696bSAlexander Motin 
594490696bSAlexander Motin int
604490696bSAlexander Motin ntb_register_device(device_t dev)
614490696bSAlexander Motin {
624490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
634490696bSAlexander Motin 	struct ntb_child *nc;
644490696bSAlexander Motin 	int i, mw, mwu, mwt, spad, spadu, spadt, db, dbu, dbt;
654490696bSAlexander Motin 	char cfg[128] = "";
664490696bSAlexander Motin 	char buf[32];
674490696bSAlexander Motin 	char *n, *np, *c, *p, *name;
684490696bSAlexander Motin 
694490696bSAlexander Motin 	mwu = 0;
704490696bSAlexander Motin 	mwt = NTB_MW_COUNT(dev);
714490696bSAlexander Motin 	spadu = 0;
724490696bSAlexander Motin 	spadt = NTB_SPAD_COUNT(dev);
734490696bSAlexander Motin 	dbu = 0;
744490696bSAlexander Motin 	dbt = flsll(NTB_DB_VALID_MASK(dev));
754490696bSAlexander Motin 
764490696bSAlexander Motin 	device_printf(dev, "%d memory windows, %d scratchpads, "
774490696bSAlexander Motin 	    "%d doorbells\n", mwt, spadt, dbt);
784490696bSAlexander Motin 
794490696bSAlexander Motin 	snprintf(buf, sizeof(buf), "hint.%s.%d.config", device_get_name(dev),
804490696bSAlexander Motin 	    device_get_unit(dev));
814490696bSAlexander Motin 	TUNABLE_STR_FETCH(buf, cfg, sizeof(cfg));
824490696bSAlexander Motin 	n = cfg;
834490696bSAlexander Motin 	i = 0;
844490696bSAlexander Motin 	while ((c = strsep(&n, ",")) != NULL) {
854490696bSAlexander Motin 		np = c;
864490696bSAlexander Motin 		name = strsep(&np, ":");
874490696bSAlexander Motin 		if (name != NULL && name[0] == 0)
884490696bSAlexander Motin 			name = NULL;
894490696bSAlexander Motin 		p = strsep(&np, ":");
904490696bSAlexander Motin 		mw = (p && p[0] != 0) ? strtol(p, NULL, 10) : mwt - mwu;
914490696bSAlexander Motin 		p = strsep(&np, ":");
924490696bSAlexander Motin 		spad = (p && p[0] != 0) ? strtol(p, NULL, 10) : spadt - spadu;
934490696bSAlexander Motin 		db = (np && np[0] != 0) ? strtol(np, NULL, 10) : dbt - dbu;
944490696bSAlexander Motin 
954490696bSAlexander Motin 		if (mw > mwt - mwu || spad > spadt - spadu || db > dbt - dbu) {
964490696bSAlexander Motin 			device_printf(dev, "Not enough resources for config\n");
974490696bSAlexander Motin 			break;
984490696bSAlexander Motin 		}
994490696bSAlexander Motin 
1004490696bSAlexander Motin 		nc = malloc(sizeof(*nc), M_DEVBUF, M_WAITOK | M_ZERO);
1014490696bSAlexander Motin 		nc->mwoff = mwu;
1024490696bSAlexander Motin 		nc->mwcnt = mw;
1034490696bSAlexander Motin 		nc->spadoff = spadu;
1044490696bSAlexander Motin 		nc->spadcnt = spad;
1054490696bSAlexander Motin 		nc->dboff = dbu;
1064490696bSAlexander Motin 		nc->dbmask = (db == 0) ? 0 : (0xffffffffffffffff >> (64 - db));
1074490696bSAlexander Motin 		rm_init(&nc->ctx_lock, "ntb ctx");
1084490696bSAlexander Motin 		nc->dev = device_add_child(dev, name, -1);
1094490696bSAlexander Motin 		if (nc->dev == NULL) {
1104490696bSAlexander Motin 			ntb_unregister_device(dev);
1114490696bSAlexander Motin 			return (ENOMEM);
1124490696bSAlexander Motin 		}
1134490696bSAlexander Motin 		device_set_ivars(nc->dev, nc);
1144490696bSAlexander Motin 		*cpp = nc;
1154490696bSAlexander Motin 		cpp = &nc->next;
1164490696bSAlexander Motin 
1174490696bSAlexander Motin 		if (bootverbose) {
1184490696bSAlexander Motin 			device_printf(dev, "%d \"%s\":", i, name);
1194490696bSAlexander Motin 			if (mw > 0) {
1204490696bSAlexander Motin 				printf(" memory windows %d", mwu);
1214490696bSAlexander Motin 				if (mw > 1)
1224490696bSAlexander Motin 					printf("-%d", mwu + mw - 1);
1234490696bSAlexander Motin 			}
1244490696bSAlexander Motin 			if (spad > 0) {
1254490696bSAlexander Motin 				printf(" scratchpads %d", spadu);
1264490696bSAlexander Motin 				if (spad > 1)
1274490696bSAlexander Motin 					printf("-%d", spadu + spad - 1);
1284490696bSAlexander Motin 			}
1294490696bSAlexander Motin 			if (db > 0) {
1304490696bSAlexander Motin 				printf(" doorbells %d", dbu);
1314490696bSAlexander Motin 				if (db > 1)
1324490696bSAlexander Motin 					printf("-%d", dbu + db - 1);
1334490696bSAlexander Motin 			}
1344490696bSAlexander Motin 			printf("\n");
1354490696bSAlexander Motin 		}
1364490696bSAlexander Motin 
1374490696bSAlexander Motin 		mwu += mw;
1384490696bSAlexander Motin 		spadu += spad;
1394490696bSAlexander Motin 		dbu += db;
1404490696bSAlexander Motin 		i++;
1414490696bSAlexander Motin 	}
1424490696bSAlexander Motin 
1434490696bSAlexander Motin 	bus_generic_attach(dev);
1444490696bSAlexander Motin 	return (0);
1454490696bSAlexander Motin }
1464490696bSAlexander Motin 
1474490696bSAlexander Motin int
1484490696bSAlexander Motin ntb_unregister_device(device_t dev)
1494490696bSAlexander Motin {
1504490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
1514490696bSAlexander Motin 	struct ntb_child *nc;
1524490696bSAlexander Motin 	int error = 0;
1534490696bSAlexander Motin 
1544490696bSAlexander Motin 	while ((nc = *cpp) != NULL) {
1554490696bSAlexander Motin 		*cpp = (*cpp)->next;
1564490696bSAlexander Motin 		error = device_delete_child(dev, nc->dev);
1574490696bSAlexander Motin 		if (error)
1584490696bSAlexander Motin 			break;
1594490696bSAlexander Motin 		rm_destroy(&nc->ctx_lock);
1604490696bSAlexander Motin 		free(nc, M_DEVBUF);
1614490696bSAlexander Motin 	}
1624490696bSAlexander Motin 	return (error);
1634490696bSAlexander Motin }
1644490696bSAlexander Motin 
1654490696bSAlexander Motin void
1664490696bSAlexander Motin ntb_link_event(device_t dev)
1674490696bSAlexander Motin {
1684490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
1694490696bSAlexander Motin 	struct ntb_child *nc;
1704490696bSAlexander Motin 	struct rm_priotracker ctx_tracker;
17148c47677SAlexander Motin 	enum ntb_speed speed;
17248c47677SAlexander Motin 	enum ntb_width width;
1734490696bSAlexander Motin 
17448c47677SAlexander Motin 	if (NTB_LINK_IS_UP(dev, &speed, &width)) {
17548c47677SAlexander Motin 		device_printf(dev, "Link is up (PCIe %d.x / x%d)\n",
17648c47677SAlexander Motin 		    (int)speed, (int)width);
17748c47677SAlexander Motin 	} else {
17848c47677SAlexander Motin 		device_printf(dev, "Link is down\n");
17948c47677SAlexander Motin 	}
1804490696bSAlexander Motin 	for (nc = *cpp; nc != NULL; nc = nc->next) {
1814490696bSAlexander Motin 		rm_rlock(&nc->ctx_lock, &ctx_tracker);
1824490696bSAlexander Motin 		if (nc->ctx_ops != NULL && nc->ctx_ops->link_event != NULL)
1834490696bSAlexander Motin 			nc->ctx_ops->link_event(nc->ctx);
1844490696bSAlexander Motin 		rm_runlock(&nc->ctx_lock, &ctx_tracker);
1854490696bSAlexander Motin 	}
1864490696bSAlexander Motin }
1874490696bSAlexander Motin 
1884490696bSAlexander Motin void
1894490696bSAlexander Motin ntb_db_event(device_t dev, uint32_t vec)
1904490696bSAlexander Motin {
1914490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
1924490696bSAlexander Motin 	struct ntb_child *nc;
1934490696bSAlexander Motin 	struct rm_priotracker ctx_tracker;
1944490696bSAlexander Motin 
1954490696bSAlexander Motin 	for (nc = *cpp; nc != NULL; nc = nc->next) {
1964490696bSAlexander Motin 		rm_rlock(&nc->ctx_lock, &ctx_tracker);
1974490696bSAlexander Motin 		if (nc->ctx_ops != NULL && nc->ctx_ops->db_event != NULL)
1984490696bSAlexander Motin 			nc->ctx_ops->db_event(nc->ctx, vec);
1994490696bSAlexander Motin 		rm_runlock(&nc->ctx_lock, &ctx_tracker);
2004490696bSAlexander Motin 	}
2014490696bSAlexander Motin }
2024490696bSAlexander Motin 
2034490696bSAlexander Motin bool
2044490696bSAlexander Motin ntb_link_is_up(device_t ntb, enum ntb_speed *speed, enum ntb_width *width)
2054490696bSAlexander Motin {
2064490696bSAlexander Motin 
2074490696bSAlexander Motin 	return (NTB_LINK_IS_UP(device_get_parent(ntb), speed, width));
2084490696bSAlexander Motin }
2094490696bSAlexander Motin 
2104490696bSAlexander Motin int
2114490696bSAlexander Motin ntb_link_enable(device_t ntb, enum ntb_speed speed, enum ntb_width width)
2124490696bSAlexander Motin {
2134490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
2144490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(device_get_parent(nc->dev));
2154490696bSAlexander Motin 	struct ntb_child *nc1;
2164490696bSAlexander Motin 
217cf2e151fSAlexander Motin 	for (nc1 = *cpp; nc1 != NULL; nc1 = nc1->next) {
2184490696bSAlexander Motin 		if (nc1->enabled) {
2194490696bSAlexander Motin 			nc->enabled = 1;
2204490696bSAlexander Motin 			return (0);
2214490696bSAlexander Motin 		}
2224490696bSAlexander Motin 	}
2234490696bSAlexander Motin 	nc->enabled = 1;
2244490696bSAlexander Motin 	return (NTB_LINK_ENABLE(device_get_parent(ntb), speed, width));
2254490696bSAlexander Motin }
2264490696bSAlexander Motin 
2274490696bSAlexander Motin int
2284490696bSAlexander Motin ntb_link_disable(device_t ntb)
2294490696bSAlexander Motin {
2304490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
2314490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(device_get_parent(nc->dev));
2324490696bSAlexander Motin 	struct ntb_child *nc1;
2334490696bSAlexander Motin 
2344490696bSAlexander Motin 	if (!nc->enabled)
2354490696bSAlexander Motin 		return (0);
2364490696bSAlexander Motin 	nc->enabled = 0;
237cf2e151fSAlexander Motin 	for (nc1 = *cpp; nc1 != NULL; nc1 = nc1->next) {
2384490696bSAlexander Motin 		if (nc1->enabled)
2394490696bSAlexander Motin 			return (0);
2404490696bSAlexander Motin 	}
2414490696bSAlexander Motin 	return (NTB_LINK_DISABLE(device_get_parent(ntb)));
2424490696bSAlexander Motin }
2434490696bSAlexander Motin 
2444490696bSAlexander Motin bool
2454490696bSAlexander Motin ntb_link_enabled(device_t ntb)
2464490696bSAlexander Motin {
2474490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
2484490696bSAlexander Motin 
2494490696bSAlexander Motin 	return (nc->enabled && NTB_LINK_ENABLED(device_get_parent(ntb)));
2504490696bSAlexander Motin }
2514490696bSAlexander Motin 
2524490696bSAlexander Motin int
2534490696bSAlexander Motin ntb_set_ctx(device_t ntb, void *ctx, const struct ntb_ctx_ops *ctx_ops)
2544490696bSAlexander Motin {
2554490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
2564490696bSAlexander Motin 
2574490696bSAlexander Motin 	if (ctx == NULL || ctx_ops == NULL)
2584490696bSAlexander Motin 		return (EINVAL);
2594490696bSAlexander Motin 
2604490696bSAlexander Motin 	rm_wlock(&nc->ctx_lock);
2614490696bSAlexander Motin 	if (nc->ctx_ops != NULL) {
2624490696bSAlexander Motin 		rm_wunlock(&nc->ctx_lock);
2634490696bSAlexander Motin 		return (EINVAL);
2644490696bSAlexander Motin 	}
2654490696bSAlexander Motin 	nc->ctx = ctx;
2664490696bSAlexander Motin 	nc->ctx_ops = ctx_ops;
267*c7dabb65SAlexander Motin 
268*c7dabb65SAlexander Motin 	/*
269*c7dabb65SAlexander Motin 	 * If applicaiton driver asks for link events, generate fake one now
270*c7dabb65SAlexander Motin 	 * to let it update link state without races while we hold the lock.
271*c7dabb65SAlexander Motin 	 */
272*c7dabb65SAlexander Motin 	if (ctx_ops->link_event != NULL)
273*c7dabb65SAlexander Motin 		ctx_ops->link_event(ctx);
2744490696bSAlexander Motin 	rm_wunlock(&nc->ctx_lock);
2754490696bSAlexander Motin 
2764490696bSAlexander Motin 	return (0);
2774490696bSAlexander Motin }
2784490696bSAlexander Motin 
2794490696bSAlexander Motin void *
2804490696bSAlexander Motin ntb_get_ctx(device_t ntb, const struct ntb_ctx_ops **ctx_ops)
2814490696bSAlexander Motin {
2824490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
2834490696bSAlexander Motin 
2848709930cSAlexander Motin 	KASSERT(nc->ctx != NULL && nc->ctx_ops != NULL, ("bogus"));
2854490696bSAlexander Motin 	if (ctx_ops != NULL)
2864490696bSAlexander Motin 		*ctx_ops = nc->ctx_ops;
2874490696bSAlexander Motin 	return (nc->ctx);
2884490696bSAlexander Motin }
2894490696bSAlexander Motin 
2904490696bSAlexander Motin void
2914490696bSAlexander Motin ntb_clear_ctx(device_t ntb)
2924490696bSAlexander Motin {
2934490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
2944490696bSAlexander Motin 
2954490696bSAlexander Motin 	rm_wlock(&nc->ctx_lock);
2964490696bSAlexander Motin 	nc->ctx = NULL;
2974490696bSAlexander Motin 	nc->ctx_ops = NULL;
2984490696bSAlexander Motin 	rm_wunlock(&nc->ctx_lock);
2994490696bSAlexander Motin }
3004490696bSAlexander Motin 
3014490696bSAlexander Motin uint8_t
3024490696bSAlexander Motin ntb_mw_count(device_t ntb)
3034490696bSAlexander Motin {
3044490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3054490696bSAlexander Motin 
3064490696bSAlexander Motin 	return (nc->mwcnt);
3074490696bSAlexander Motin }
3084490696bSAlexander Motin 
3094490696bSAlexander Motin int
3104490696bSAlexander Motin ntb_mw_get_range(device_t ntb, unsigned mw_idx, vm_paddr_t *base,
3114490696bSAlexander Motin     caddr_t *vbase, size_t *size, size_t *align, size_t *align_size,
3124490696bSAlexander Motin     bus_addr_t *plimit)
3134490696bSAlexander Motin {
3144490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3154490696bSAlexander Motin 
3164490696bSAlexander Motin 	return (NTB_MW_GET_RANGE(device_get_parent(ntb), mw_idx + nc->mwoff,
3174490696bSAlexander Motin 	    base, vbase, size, align, align_size, plimit));
3184490696bSAlexander Motin }
3194490696bSAlexander Motin 
3204490696bSAlexander Motin int
3214490696bSAlexander Motin ntb_mw_set_trans(device_t ntb, unsigned mw_idx, bus_addr_t addr, size_t size)
3224490696bSAlexander Motin {
3234490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3244490696bSAlexander Motin 
3254490696bSAlexander Motin 	return (NTB_MW_SET_TRANS(device_get_parent(ntb), mw_idx + nc->mwoff,
3264490696bSAlexander Motin 	    addr, size));
3274490696bSAlexander Motin }
3284490696bSAlexander Motin 
3294490696bSAlexander Motin int
3304490696bSAlexander Motin ntb_mw_clear_trans(device_t ntb, unsigned mw_idx)
3314490696bSAlexander Motin {
3324490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3334490696bSAlexander Motin 
3344490696bSAlexander Motin 	return (NTB_MW_CLEAR_TRANS(device_get_parent(ntb), mw_idx + nc->mwoff));
3354490696bSAlexander Motin }
3364490696bSAlexander Motin 
3374490696bSAlexander Motin int
3384490696bSAlexander Motin ntb_mw_get_wc(device_t ntb, unsigned mw_idx, vm_memattr_t *mode)
3394490696bSAlexander Motin {
3404490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3414490696bSAlexander Motin 
3424490696bSAlexander Motin 	return (NTB_MW_GET_WC(device_get_parent(ntb), mw_idx + nc->mwoff, mode));
3434490696bSAlexander Motin }
3444490696bSAlexander Motin 
3454490696bSAlexander Motin int
3464490696bSAlexander Motin ntb_mw_set_wc(device_t ntb, unsigned mw_idx, vm_memattr_t mode)
3474490696bSAlexander Motin {
3484490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3494490696bSAlexander Motin 
3504490696bSAlexander Motin 	return (NTB_MW_SET_WC(device_get_parent(ntb), mw_idx + nc->mwoff, mode));
3514490696bSAlexander Motin }
3524490696bSAlexander Motin 
3534490696bSAlexander Motin uint8_t
3544490696bSAlexander Motin ntb_spad_count(device_t ntb)
3554490696bSAlexander Motin {
3564490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3574490696bSAlexander Motin 
3584490696bSAlexander Motin 	return (nc->spadcnt);
3594490696bSAlexander Motin }
3604490696bSAlexander Motin 
3614490696bSAlexander Motin void
3624490696bSAlexander Motin ntb_spad_clear(device_t ntb)
3634490696bSAlexander Motin {
3644490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3654490696bSAlexander Motin 	unsigned i;
3664490696bSAlexander Motin 
3674490696bSAlexander Motin 	for (i = 0; i < nc->spadcnt; i++)
3684490696bSAlexander Motin 		NTB_SPAD_WRITE(device_get_parent(ntb), i + nc->spadoff, 0);
3694490696bSAlexander Motin }
3704490696bSAlexander Motin 
3714490696bSAlexander Motin int
3724490696bSAlexander Motin ntb_spad_write(device_t ntb, unsigned int idx, uint32_t val)
3734490696bSAlexander Motin {
3744490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3754490696bSAlexander Motin 
3764490696bSAlexander Motin 	return (NTB_SPAD_WRITE(device_get_parent(ntb), idx + nc->spadoff, val));
3774490696bSAlexander Motin }
3784490696bSAlexander Motin 
3794490696bSAlexander Motin int
3804490696bSAlexander Motin ntb_spad_read(device_t ntb, unsigned int idx, uint32_t *val)
3814490696bSAlexander Motin {
3824490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3834490696bSAlexander Motin 
3844490696bSAlexander Motin 	return (NTB_SPAD_READ(device_get_parent(ntb), idx + nc->spadoff, val));
3854490696bSAlexander Motin }
3864490696bSAlexander Motin 
3874490696bSAlexander Motin int
3884490696bSAlexander Motin ntb_peer_spad_write(device_t ntb, unsigned int idx, uint32_t val)
3894490696bSAlexander Motin {
3904490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3914490696bSAlexander Motin 
3924490696bSAlexander Motin 	return (NTB_PEER_SPAD_WRITE(device_get_parent(ntb), idx + nc->spadoff,
3934490696bSAlexander Motin 	    val));
3944490696bSAlexander Motin }
3954490696bSAlexander Motin 
3964490696bSAlexander Motin int
3974490696bSAlexander Motin ntb_peer_spad_read(device_t ntb, unsigned int idx, uint32_t *val)
3984490696bSAlexander Motin {
3994490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4004490696bSAlexander Motin 
4014490696bSAlexander Motin 	return (NTB_PEER_SPAD_READ(device_get_parent(ntb), idx + nc->spadoff,
4024490696bSAlexander Motin 	    val));
4034490696bSAlexander Motin }
4044490696bSAlexander Motin 
4054490696bSAlexander Motin uint64_t
4064490696bSAlexander Motin ntb_db_valid_mask(device_t ntb)
4074490696bSAlexander Motin {
4084490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4094490696bSAlexander Motin 
4104490696bSAlexander Motin 	return (nc->dbmask);
4114490696bSAlexander Motin }
4124490696bSAlexander Motin 
4134490696bSAlexander Motin int
4144490696bSAlexander Motin ntb_db_vector_count(device_t ntb)
4154490696bSAlexander Motin {
4164490696bSAlexander Motin 
4174490696bSAlexander Motin 	return (NTB_DB_VECTOR_COUNT(device_get_parent(ntb)));
4184490696bSAlexander Motin }
4194490696bSAlexander Motin 
4204490696bSAlexander Motin uint64_t
4214490696bSAlexander Motin ntb_db_vector_mask(device_t ntb, uint32_t vector)
4224490696bSAlexander Motin {
4234490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4244490696bSAlexander Motin 
4254490696bSAlexander Motin 	return ((NTB_DB_VECTOR_MASK(device_get_parent(ntb), vector)
4264490696bSAlexander Motin 	    >> nc->dboff) & nc->dbmask);
4274490696bSAlexander Motin }
4284490696bSAlexander Motin 
4294490696bSAlexander Motin int
4304490696bSAlexander Motin ntb_peer_db_addr(device_t ntb, bus_addr_t *db_addr, vm_size_t *db_size)
4314490696bSAlexander Motin {
4324490696bSAlexander Motin 
4334490696bSAlexander Motin 	return (NTB_PEER_DB_ADDR(device_get_parent(ntb), db_addr, db_size));
4344490696bSAlexander Motin }
4354490696bSAlexander Motin 
4364490696bSAlexander Motin void
4374490696bSAlexander Motin ntb_db_clear(device_t ntb, uint64_t bits)
4384490696bSAlexander Motin {
4394490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4404490696bSAlexander Motin 
4414490696bSAlexander Motin 	return (NTB_DB_CLEAR(device_get_parent(ntb), bits << nc->dboff));
4424490696bSAlexander Motin }
4434490696bSAlexander Motin 
4444490696bSAlexander Motin void
4454490696bSAlexander Motin ntb_db_clear_mask(device_t ntb, uint64_t bits)
4464490696bSAlexander Motin {
4474490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4484490696bSAlexander Motin 
4494490696bSAlexander Motin 	return (NTB_DB_CLEAR_MASK(device_get_parent(ntb), bits << nc->dboff));
4504490696bSAlexander Motin }
4514490696bSAlexander Motin 
4524490696bSAlexander Motin uint64_t
4534490696bSAlexander Motin ntb_db_read(device_t ntb)
4544490696bSAlexander Motin {
4554490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4564490696bSAlexander Motin 
4574490696bSAlexander Motin 	return ((NTB_DB_READ(device_get_parent(ntb)) >> nc->dboff)
4584490696bSAlexander Motin 	    & nc->dbmask);
4594490696bSAlexander Motin }
4604490696bSAlexander Motin 
4614490696bSAlexander Motin void
4624490696bSAlexander Motin ntb_db_set_mask(device_t ntb, uint64_t bits)
4634490696bSAlexander Motin {
4644490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4654490696bSAlexander Motin 
4664490696bSAlexander Motin 	return (NTB_DB_SET_MASK(device_get_parent(ntb), bits << nc->dboff));
4674490696bSAlexander Motin }
4684490696bSAlexander Motin 
4694490696bSAlexander Motin void
4704490696bSAlexander Motin ntb_peer_db_set(device_t ntb, uint64_t bits)
4714490696bSAlexander Motin {
4724490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4734490696bSAlexander Motin 
4744490696bSAlexander Motin 	return (NTB_PEER_DB_SET(device_get_parent(ntb), bits << nc->dboff));
4754490696bSAlexander Motin }
4764490696bSAlexander Motin 
4779a5325c2SAlexander Motin MODULE_VERSION(ntb, 1);
478