xref: /freebsd/sys/dev/ntb/ntb.c (revision fdafd315)
19a5325c2SAlexander Motin /*-
2b7dd3fbeSAlexander Motin  * Copyright (c) 2016-2017 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/param.h>
289a5325c2SAlexander Motin #include <sys/kernel.h>
299a5325c2SAlexander Motin #include <sys/systm.h>
309a5325c2SAlexander Motin #include <sys/bus.h>
314490696bSAlexander Motin #include <sys/rmlock.h>
324490696bSAlexander Motin #include <sys/malloc.h>
339a5325c2SAlexander Motin #include <sys/module.h>
34ddfc9c4cSWarner Losh #include <sys/sbuf.h>
359a5325c2SAlexander Motin #include <sys/sysctl.h>
369a5325c2SAlexander Motin 
379a5325c2SAlexander Motin #include "ntb.h"
389a5325c2SAlexander Motin 
397029da5cSPawel Biernacki SYSCTL_NODE(_hw, OID_AUTO, ntb, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
407029da5cSPawel Biernacki     "NTB sysctls");
419a5325c2SAlexander Motin 
424490696bSAlexander Motin struct ntb_child {
434490696bSAlexander Motin 	device_t	dev;
44b7dd3fbeSAlexander Motin 	int		function;
454490696bSAlexander Motin 	int		enabled;
464490696bSAlexander Motin 	int		mwoff;
474490696bSAlexander Motin 	int		mwcnt;
484490696bSAlexander Motin 	int		spadoff;
494490696bSAlexander Motin 	int		spadcnt;
504490696bSAlexander Motin 	int		dboff;
51b7dd3fbeSAlexander Motin 	int		dbcnt;
52b7dd3fbeSAlexander Motin 	uint64_t	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
ntb_register_device(device_t dev)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);
101b7dd3fbeSAlexander Motin 		nc->function = i;
1024490696bSAlexander Motin 		nc->mwoff = mwu;
1034490696bSAlexander Motin 		nc->mwcnt = mw;
1044490696bSAlexander Motin 		nc->spadoff = spadu;
1054490696bSAlexander Motin 		nc->spadcnt = spad;
1064490696bSAlexander Motin 		nc->dboff = dbu;
107b7dd3fbeSAlexander Motin 		nc->dbcnt = db;
1084490696bSAlexander Motin 		nc->dbmask = (db == 0) ? 0 : (0xffffffffffffffff >> (64 - db));
1094490696bSAlexander Motin 		rm_init(&nc->ctx_lock, "ntb ctx");
1104490696bSAlexander Motin 		nc->dev = device_add_child(dev, name, -1);
1114490696bSAlexander Motin 		if (nc->dev == NULL) {
1124490696bSAlexander Motin 			ntb_unregister_device(dev);
1134490696bSAlexander Motin 			return (ENOMEM);
1144490696bSAlexander Motin 		}
1154490696bSAlexander Motin 		device_set_ivars(nc->dev, nc);
1164490696bSAlexander Motin 		*cpp = nc;
1174490696bSAlexander Motin 		cpp = &nc->next;
1184490696bSAlexander Motin 
1194490696bSAlexander Motin 		if (bootverbose) {
1204490696bSAlexander Motin 			device_printf(dev, "%d \"%s\":", i, name);
1214490696bSAlexander Motin 			if (mw > 0) {
1224490696bSAlexander Motin 				printf(" memory windows %d", mwu);
1234490696bSAlexander Motin 				if (mw > 1)
1244490696bSAlexander Motin 					printf("-%d", mwu + mw - 1);
1254490696bSAlexander Motin 			}
1264490696bSAlexander Motin 			if (spad > 0) {
1274490696bSAlexander Motin 				printf(" scratchpads %d", spadu);
1284490696bSAlexander Motin 				if (spad > 1)
1294490696bSAlexander Motin 					printf("-%d", spadu + spad - 1);
1304490696bSAlexander Motin 			}
1314490696bSAlexander Motin 			if (db > 0) {
1324490696bSAlexander Motin 				printf(" doorbells %d", dbu);
1334490696bSAlexander Motin 				if (db > 1)
1344490696bSAlexander Motin 					printf("-%d", dbu + db - 1);
1354490696bSAlexander Motin 			}
1364490696bSAlexander Motin 			printf("\n");
1374490696bSAlexander Motin 		}
1384490696bSAlexander Motin 
1394490696bSAlexander Motin 		mwu += mw;
1404490696bSAlexander Motin 		spadu += spad;
1414490696bSAlexander Motin 		dbu += db;
1424490696bSAlexander Motin 		i++;
1434490696bSAlexander Motin 	}
1444490696bSAlexander Motin 
1454490696bSAlexander Motin 	bus_generic_attach(dev);
1464490696bSAlexander Motin 	return (0);
1474490696bSAlexander Motin }
1484490696bSAlexander Motin 
1494490696bSAlexander Motin int
ntb_unregister_device(device_t dev)1504490696bSAlexander Motin ntb_unregister_device(device_t dev)
1514490696bSAlexander Motin {
1524490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
1534490696bSAlexander Motin 	struct ntb_child *nc;
1544490696bSAlexander Motin 	int error = 0;
1554490696bSAlexander Motin 
1564490696bSAlexander Motin 	while ((nc = *cpp) != NULL) {
1574490696bSAlexander Motin 		*cpp = (*cpp)->next;
1584490696bSAlexander Motin 		error = device_delete_child(dev, nc->dev);
1594490696bSAlexander Motin 		if (error)
1604490696bSAlexander Motin 			break;
1614490696bSAlexander Motin 		rm_destroy(&nc->ctx_lock);
1624490696bSAlexander Motin 		free(nc, M_DEVBUF);
1634490696bSAlexander Motin 	}
1644490696bSAlexander Motin 	return (error);
1654490696bSAlexander Motin }
1664490696bSAlexander Motin 
167b7dd3fbeSAlexander Motin int
ntb_child_location(device_t dev,device_t child,struct sbuf * sb)168ddfc9c4cSWarner Losh ntb_child_location(device_t dev, device_t child, struct sbuf *sb)
169b7dd3fbeSAlexander Motin {
170b7dd3fbeSAlexander Motin 	struct ntb_child *nc = device_get_ivars(child);
171b7dd3fbeSAlexander Motin 
172ddfc9c4cSWarner Losh 	sbuf_printf(sb, "function=%d", nc->function);
173b7dd3fbeSAlexander Motin 	return (0);
174b7dd3fbeSAlexander Motin }
175b7dd3fbeSAlexander Motin 
176b7dd3fbeSAlexander Motin int
ntb_print_child(device_t dev,device_t child)177b7dd3fbeSAlexander Motin ntb_print_child(device_t dev, device_t child)
178b7dd3fbeSAlexander Motin {
179b7dd3fbeSAlexander Motin 	struct ntb_child *nc = device_get_ivars(child);
180b7dd3fbeSAlexander Motin 	int retval;
181b7dd3fbeSAlexander Motin 
182b7dd3fbeSAlexander Motin 	retval = bus_print_child_header(dev, child);
183b7dd3fbeSAlexander Motin 	if (nc->mwcnt > 0) {
184b7dd3fbeSAlexander Motin 		printf(" mw %d", nc->mwoff);
185b7dd3fbeSAlexander Motin 		if (nc->mwcnt > 1)
186b7dd3fbeSAlexander Motin 			printf("-%d", nc->mwoff + nc->mwcnt - 1);
187b7dd3fbeSAlexander Motin 	}
188b7dd3fbeSAlexander Motin 	if (nc->spadcnt > 0) {
189b7dd3fbeSAlexander Motin 		printf(" spad %d", nc->spadoff);
190b7dd3fbeSAlexander Motin 		if (nc->spadcnt > 1)
191b7dd3fbeSAlexander Motin 			printf("-%d", nc->spadoff + nc->spadcnt - 1);
192b7dd3fbeSAlexander Motin 	}
193b7dd3fbeSAlexander Motin 	if (nc->dbcnt > 0) {
194b7dd3fbeSAlexander Motin 		printf(" db %d", nc->dboff);
195b7dd3fbeSAlexander Motin 		if (nc->dbcnt > 1)
196b7dd3fbeSAlexander Motin 			printf("-%d", nc->dboff + nc->dbcnt - 1);
197b7dd3fbeSAlexander Motin 	}
198b7dd3fbeSAlexander Motin 	retval += printf(" at function %d", nc->function);
199b7dd3fbeSAlexander Motin 	retval += bus_print_child_domain(dev, child);
200b7dd3fbeSAlexander Motin 	retval += bus_print_child_footer(dev, child);
201b7dd3fbeSAlexander Motin 
202b7dd3fbeSAlexander Motin 	return (retval);
203b7dd3fbeSAlexander Motin }
204b7dd3fbeSAlexander Motin 
2057f215e07SAlexander Motin bus_dma_tag_t
ntb_get_dma_tag(device_t bus,device_t child)2067f215e07SAlexander Motin ntb_get_dma_tag(device_t bus, device_t child)
2077f215e07SAlexander Motin {
2087f215e07SAlexander Motin 
2097f215e07SAlexander Motin 	return (bus_get_dma_tag(bus));
2107f215e07SAlexander Motin }
2117f215e07SAlexander Motin 
2124490696bSAlexander Motin void
ntb_link_event(device_t dev)2134490696bSAlexander Motin ntb_link_event(device_t dev)
2144490696bSAlexander Motin {
2154490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
2164490696bSAlexander Motin 	struct ntb_child *nc;
2174490696bSAlexander Motin 	struct rm_priotracker ctx_tracker;
21848c47677SAlexander Motin 	enum ntb_speed speed;
21948c47677SAlexander Motin 	enum ntb_width width;
2204490696bSAlexander Motin 
22148c47677SAlexander Motin 	if (NTB_LINK_IS_UP(dev, &speed, &width)) {
22248c47677SAlexander Motin 		device_printf(dev, "Link is up (PCIe %d.x / x%d)\n",
22348c47677SAlexander Motin 		    (int)speed, (int)width);
22448c47677SAlexander Motin 	} else {
22548c47677SAlexander Motin 		device_printf(dev, "Link is down\n");
22648c47677SAlexander Motin 	}
2274490696bSAlexander Motin 	for (nc = *cpp; nc != NULL; nc = nc->next) {
2284490696bSAlexander Motin 		rm_rlock(&nc->ctx_lock, &ctx_tracker);
2294490696bSAlexander Motin 		if (nc->ctx_ops != NULL && nc->ctx_ops->link_event != NULL)
2304490696bSAlexander Motin 			nc->ctx_ops->link_event(nc->ctx);
2314490696bSAlexander Motin 		rm_runlock(&nc->ctx_lock, &ctx_tracker);
2324490696bSAlexander Motin 	}
2334490696bSAlexander Motin }
2344490696bSAlexander Motin 
2354490696bSAlexander Motin void
ntb_db_event(device_t dev,uint32_t vec)2364490696bSAlexander Motin ntb_db_event(device_t dev, uint32_t vec)
2374490696bSAlexander Motin {
2384490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(dev);
2394490696bSAlexander Motin 	struct ntb_child *nc;
2404490696bSAlexander Motin 	struct rm_priotracker ctx_tracker;
2414490696bSAlexander Motin 
2424490696bSAlexander Motin 	for (nc = *cpp; nc != NULL; nc = nc->next) {
2434490696bSAlexander Motin 		rm_rlock(&nc->ctx_lock, &ctx_tracker);
2444490696bSAlexander Motin 		if (nc->ctx_ops != NULL && nc->ctx_ops->db_event != NULL)
2454490696bSAlexander Motin 			nc->ctx_ops->db_event(nc->ctx, vec);
2464490696bSAlexander Motin 		rm_runlock(&nc->ctx_lock, &ctx_tracker);
2474490696bSAlexander Motin 	}
2484490696bSAlexander Motin }
2494490696bSAlexander Motin 
2506683132dSAlexander Motin int
ntb_port_number(device_t ntb)2516683132dSAlexander Motin ntb_port_number(device_t ntb)
2526683132dSAlexander Motin {
2536683132dSAlexander Motin 	return (NTB_PORT_NUMBER(device_get_parent(ntb)));
2546683132dSAlexander Motin }
2556683132dSAlexander Motin 
2566683132dSAlexander Motin int
ntb_peer_port_count(device_t ntb)2576683132dSAlexander Motin ntb_peer_port_count(device_t ntb)
2586683132dSAlexander Motin {
2596683132dSAlexander Motin 	return (NTB_PEER_PORT_COUNT(device_get_parent(ntb)));
2606683132dSAlexander Motin }
2616683132dSAlexander Motin 
2626683132dSAlexander Motin int
ntb_peer_port_number(device_t ntb,int pidx)2636683132dSAlexander Motin ntb_peer_port_number(device_t ntb, int pidx)
2646683132dSAlexander Motin {
2656683132dSAlexander Motin 	return (NTB_PEER_PORT_NUMBER(device_get_parent(ntb), pidx));
2666683132dSAlexander Motin }
2676683132dSAlexander Motin 
2686683132dSAlexander Motin int
ntb_peer_port_idx(device_t ntb,int port)2696683132dSAlexander Motin ntb_peer_port_idx(device_t ntb, int port)
2706683132dSAlexander Motin {
2716683132dSAlexander Motin 	return (NTB_PEER_PORT_IDX(device_get_parent(ntb), port));
2726683132dSAlexander Motin }
2736683132dSAlexander Motin 
2744490696bSAlexander Motin bool
ntb_link_is_up(device_t ntb,enum ntb_speed * speed,enum ntb_width * width)2754490696bSAlexander Motin ntb_link_is_up(device_t ntb, enum ntb_speed *speed, enum ntb_width *width)
2764490696bSAlexander Motin {
2774490696bSAlexander Motin 
2784490696bSAlexander Motin 	return (NTB_LINK_IS_UP(device_get_parent(ntb), speed, width));
2794490696bSAlexander Motin }
2804490696bSAlexander Motin 
2814490696bSAlexander Motin int
ntb_link_enable(device_t ntb,enum ntb_speed speed,enum ntb_width width)2824490696bSAlexander Motin ntb_link_enable(device_t ntb, enum ntb_speed speed, enum ntb_width width)
2834490696bSAlexander Motin {
2844490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
2854490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(device_get_parent(nc->dev));
2864490696bSAlexander Motin 	struct ntb_child *nc1;
2874490696bSAlexander Motin 
288cf2e151fSAlexander Motin 	for (nc1 = *cpp; nc1 != NULL; nc1 = nc1->next) {
2894490696bSAlexander Motin 		if (nc1->enabled) {
2904490696bSAlexander Motin 			nc->enabled = 1;
2914490696bSAlexander Motin 			return (0);
2924490696bSAlexander Motin 		}
2934490696bSAlexander Motin 	}
2944490696bSAlexander Motin 	nc->enabled = 1;
2954490696bSAlexander Motin 	return (NTB_LINK_ENABLE(device_get_parent(ntb), speed, width));
2964490696bSAlexander Motin }
2974490696bSAlexander Motin 
2984490696bSAlexander Motin int
ntb_link_disable(device_t ntb)2994490696bSAlexander Motin ntb_link_disable(device_t ntb)
3004490696bSAlexander Motin {
3014490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3024490696bSAlexander Motin 	struct ntb_child **cpp = device_get_softc(device_get_parent(nc->dev));
3034490696bSAlexander Motin 	struct ntb_child *nc1;
3044490696bSAlexander Motin 
3054490696bSAlexander Motin 	if (!nc->enabled)
3064490696bSAlexander Motin 		return (0);
3074490696bSAlexander Motin 	nc->enabled = 0;
308cf2e151fSAlexander Motin 	for (nc1 = *cpp; nc1 != NULL; nc1 = nc1->next) {
3094490696bSAlexander Motin 		if (nc1->enabled)
3104490696bSAlexander Motin 			return (0);
3114490696bSAlexander Motin 	}
3124490696bSAlexander Motin 	return (NTB_LINK_DISABLE(device_get_parent(ntb)));
3134490696bSAlexander Motin }
3144490696bSAlexander Motin 
3154490696bSAlexander Motin bool
ntb_link_enabled(device_t ntb)3164490696bSAlexander Motin ntb_link_enabled(device_t ntb)
3174490696bSAlexander Motin {
3184490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3194490696bSAlexander Motin 
3204490696bSAlexander Motin 	return (nc->enabled && NTB_LINK_ENABLED(device_get_parent(ntb)));
3214490696bSAlexander Motin }
3224490696bSAlexander Motin 
3234490696bSAlexander Motin int
ntb_set_ctx(device_t ntb,void * ctx,const struct ntb_ctx_ops * ctx_ops)3244490696bSAlexander Motin ntb_set_ctx(device_t ntb, void *ctx, const struct ntb_ctx_ops *ctx_ops)
3254490696bSAlexander Motin {
3264490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3274490696bSAlexander Motin 
3284490696bSAlexander Motin 	if (ctx == NULL || ctx_ops == NULL)
3294490696bSAlexander Motin 		return (EINVAL);
3304490696bSAlexander Motin 
3314490696bSAlexander Motin 	rm_wlock(&nc->ctx_lock);
3324490696bSAlexander Motin 	if (nc->ctx_ops != NULL) {
3334490696bSAlexander Motin 		rm_wunlock(&nc->ctx_lock);
3344490696bSAlexander Motin 		return (EINVAL);
3354490696bSAlexander Motin 	}
3364490696bSAlexander Motin 	nc->ctx = ctx;
3374490696bSAlexander Motin 	nc->ctx_ops = ctx_ops;
338c7dabb65SAlexander Motin 
339c7dabb65SAlexander Motin 	/*
340c7dabb65SAlexander Motin 	 * If applicaiton driver asks for link events, generate fake one now
341c7dabb65SAlexander Motin 	 * to let it update link state without races while we hold the lock.
342c7dabb65SAlexander Motin 	 */
343c7dabb65SAlexander Motin 	if (ctx_ops->link_event != NULL)
344c7dabb65SAlexander Motin 		ctx_ops->link_event(ctx);
3454490696bSAlexander Motin 	rm_wunlock(&nc->ctx_lock);
3464490696bSAlexander Motin 
3474490696bSAlexander Motin 	return (0);
3484490696bSAlexander Motin }
3494490696bSAlexander Motin 
3504490696bSAlexander Motin void *
ntb_get_ctx(device_t ntb,const struct ntb_ctx_ops ** ctx_ops)3514490696bSAlexander Motin ntb_get_ctx(device_t ntb, const struct ntb_ctx_ops **ctx_ops)
3524490696bSAlexander Motin {
3534490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3544490696bSAlexander Motin 
3558709930cSAlexander Motin 	KASSERT(nc->ctx != NULL && nc->ctx_ops != NULL, ("bogus"));
3564490696bSAlexander Motin 	if (ctx_ops != NULL)
3574490696bSAlexander Motin 		*ctx_ops = nc->ctx_ops;
3584490696bSAlexander Motin 	return (nc->ctx);
3594490696bSAlexander Motin }
3604490696bSAlexander Motin 
3614490696bSAlexander Motin void
ntb_clear_ctx(device_t ntb)3624490696bSAlexander Motin ntb_clear_ctx(device_t ntb)
3634490696bSAlexander Motin {
3644490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3654490696bSAlexander Motin 
3664490696bSAlexander Motin 	rm_wlock(&nc->ctx_lock);
3674490696bSAlexander Motin 	nc->ctx = NULL;
3684490696bSAlexander Motin 	nc->ctx_ops = NULL;
3694490696bSAlexander Motin 	rm_wunlock(&nc->ctx_lock);
3704490696bSAlexander Motin }
3714490696bSAlexander Motin 
3724490696bSAlexander Motin uint8_t
ntb_mw_count(device_t ntb)3734490696bSAlexander Motin ntb_mw_count(device_t ntb)
3744490696bSAlexander Motin {
3754490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3764490696bSAlexander Motin 
3774490696bSAlexander Motin 	return (nc->mwcnt);
3784490696bSAlexander Motin }
3794490696bSAlexander Motin 
3804490696bSAlexander Motin int
ntb_mw_get_range(device_t ntb,unsigned mw_idx,vm_paddr_t * base,caddr_t * vbase,size_t * size,size_t * align,size_t * align_size,bus_addr_t * plimit)3814490696bSAlexander Motin ntb_mw_get_range(device_t ntb, unsigned mw_idx, vm_paddr_t *base,
3824490696bSAlexander Motin     caddr_t *vbase, size_t *size, size_t *align, size_t *align_size,
3834490696bSAlexander Motin     bus_addr_t *plimit)
3844490696bSAlexander Motin {
3854490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3864490696bSAlexander Motin 
3874490696bSAlexander Motin 	return (NTB_MW_GET_RANGE(device_get_parent(ntb), mw_idx + nc->mwoff,
3884490696bSAlexander Motin 	    base, vbase, size, align, align_size, plimit));
3894490696bSAlexander Motin }
3904490696bSAlexander Motin 
3914490696bSAlexander Motin int
ntb_mw_set_trans(device_t ntb,unsigned mw_idx,bus_addr_t addr,size_t size)3924490696bSAlexander Motin ntb_mw_set_trans(device_t ntb, unsigned mw_idx, bus_addr_t addr, size_t size)
3934490696bSAlexander Motin {
3944490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
3954490696bSAlexander Motin 
3964490696bSAlexander Motin 	return (NTB_MW_SET_TRANS(device_get_parent(ntb), mw_idx + nc->mwoff,
3974490696bSAlexander Motin 	    addr, size));
3984490696bSAlexander Motin }
3994490696bSAlexander Motin 
4004490696bSAlexander Motin int
ntb_mw_clear_trans(device_t ntb,unsigned mw_idx)4014490696bSAlexander Motin ntb_mw_clear_trans(device_t ntb, unsigned mw_idx)
4024490696bSAlexander Motin {
4034490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4044490696bSAlexander Motin 
4054490696bSAlexander Motin 	return (NTB_MW_CLEAR_TRANS(device_get_parent(ntb), mw_idx + nc->mwoff));
4064490696bSAlexander Motin }
4074490696bSAlexander Motin 
4084490696bSAlexander Motin int
ntb_mw_get_wc(device_t ntb,unsigned mw_idx,vm_memattr_t * mode)4094490696bSAlexander Motin ntb_mw_get_wc(device_t ntb, unsigned mw_idx, vm_memattr_t *mode)
4104490696bSAlexander Motin {
4114490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4124490696bSAlexander Motin 
4134490696bSAlexander Motin 	return (NTB_MW_GET_WC(device_get_parent(ntb), mw_idx + nc->mwoff, mode));
4144490696bSAlexander Motin }
4154490696bSAlexander Motin 
4164490696bSAlexander Motin int
ntb_mw_set_wc(device_t ntb,unsigned mw_idx,vm_memattr_t mode)4174490696bSAlexander Motin ntb_mw_set_wc(device_t ntb, unsigned mw_idx, vm_memattr_t mode)
4184490696bSAlexander Motin {
4194490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4204490696bSAlexander Motin 
4214490696bSAlexander Motin 	return (NTB_MW_SET_WC(device_get_parent(ntb), mw_idx + nc->mwoff, mode));
4224490696bSAlexander Motin }
4234490696bSAlexander Motin 
4244490696bSAlexander Motin uint8_t
ntb_spad_count(device_t ntb)4254490696bSAlexander Motin ntb_spad_count(device_t ntb)
4264490696bSAlexander Motin {
4274490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4284490696bSAlexander Motin 
4294490696bSAlexander Motin 	return (nc->spadcnt);
4304490696bSAlexander Motin }
4314490696bSAlexander Motin 
4324490696bSAlexander Motin void
ntb_spad_clear(device_t ntb)4334490696bSAlexander Motin ntb_spad_clear(device_t ntb)
4344490696bSAlexander Motin {
4354490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4364490696bSAlexander Motin 	unsigned i;
4374490696bSAlexander Motin 
4384490696bSAlexander Motin 	for (i = 0; i < nc->spadcnt; i++)
4394490696bSAlexander Motin 		NTB_SPAD_WRITE(device_get_parent(ntb), i + nc->spadoff, 0);
4404490696bSAlexander Motin }
4414490696bSAlexander Motin 
4424490696bSAlexander Motin int
ntb_spad_write(device_t ntb,unsigned int idx,uint32_t val)4434490696bSAlexander Motin ntb_spad_write(device_t ntb, unsigned int idx, uint32_t val)
4444490696bSAlexander Motin {
4454490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4464490696bSAlexander Motin 
4474490696bSAlexander Motin 	return (NTB_SPAD_WRITE(device_get_parent(ntb), idx + nc->spadoff, val));
4484490696bSAlexander Motin }
4494490696bSAlexander Motin 
4504490696bSAlexander Motin int
ntb_spad_read(device_t ntb,unsigned int idx,uint32_t * val)4514490696bSAlexander Motin ntb_spad_read(device_t ntb, unsigned int idx, uint32_t *val)
4524490696bSAlexander Motin {
4534490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4544490696bSAlexander Motin 
4554490696bSAlexander Motin 	return (NTB_SPAD_READ(device_get_parent(ntb), idx + nc->spadoff, val));
4564490696bSAlexander Motin }
4574490696bSAlexander Motin 
4584490696bSAlexander Motin int
ntb_peer_spad_write(device_t ntb,unsigned int idx,uint32_t val)4594490696bSAlexander Motin ntb_peer_spad_write(device_t ntb, unsigned int idx, uint32_t val)
4604490696bSAlexander Motin {
4614490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4624490696bSAlexander Motin 
4634490696bSAlexander Motin 	return (NTB_PEER_SPAD_WRITE(device_get_parent(ntb), idx + nc->spadoff,
4644490696bSAlexander Motin 	    val));
4654490696bSAlexander Motin }
4664490696bSAlexander Motin 
4674490696bSAlexander Motin int
ntb_peer_spad_read(device_t ntb,unsigned int idx,uint32_t * val)4684490696bSAlexander Motin ntb_peer_spad_read(device_t ntb, unsigned int idx, uint32_t *val)
4694490696bSAlexander Motin {
4704490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4714490696bSAlexander Motin 
4724490696bSAlexander Motin 	return (NTB_PEER_SPAD_READ(device_get_parent(ntb), idx + nc->spadoff,
4734490696bSAlexander Motin 	    val));
4744490696bSAlexander Motin }
4754490696bSAlexander Motin 
4764490696bSAlexander Motin uint64_t
ntb_db_valid_mask(device_t ntb)4774490696bSAlexander Motin ntb_db_valid_mask(device_t ntb)
4784490696bSAlexander Motin {
4794490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4804490696bSAlexander Motin 
4814490696bSAlexander Motin 	return (nc->dbmask);
4824490696bSAlexander Motin }
4834490696bSAlexander Motin 
4844490696bSAlexander Motin int
ntb_db_vector_count(device_t ntb)4854490696bSAlexander Motin ntb_db_vector_count(device_t ntb)
4864490696bSAlexander Motin {
4874490696bSAlexander Motin 
4884490696bSAlexander Motin 	return (NTB_DB_VECTOR_COUNT(device_get_parent(ntb)));
4894490696bSAlexander Motin }
4904490696bSAlexander Motin 
4914490696bSAlexander Motin uint64_t
ntb_db_vector_mask(device_t ntb,uint32_t vector)4924490696bSAlexander Motin ntb_db_vector_mask(device_t ntb, uint32_t vector)
4934490696bSAlexander Motin {
4944490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
4954490696bSAlexander Motin 
4964490696bSAlexander Motin 	return ((NTB_DB_VECTOR_MASK(device_get_parent(ntb), vector)
4974490696bSAlexander Motin 	    >> nc->dboff) & nc->dbmask);
4984490696bSAlexander Motin }
4994490696bSAlexander Motin 
5004490696bSAlexander Motin int
ntb_peer_db_addr(device_t ntb,bus_addr_t * db_addr,vm_size_t * db_size)5014490696bSAlexander Motin ntb_peer_db_addr(device_t ntb, bus_addr_t *db_addr, vm_size_t *db_size)
5024490696bSAlexander Motin {
5034490696bSAlexander Motin 
5044490696bSAlexander Motin 	return (NTB_PEER_DB_ADDR(device_get_parent(ntb), db_addr, db_size));
5054490696bSAlexander Motin }
5064490696bSAlexander Motin 
5074490696bSAlexander Motin void
ntb_db_clear(device_t ntb,uint64_t bits)5084490696bSAlexander Motin ntb_db_clear(device_t ntb, uint64_t bits)
5094490696bSAlexander Motin {
5104490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
5114490696bSAlexander Motin 
5124490696bSAlexander Motin 	return (NTB_DB_CLEAR(device_get_parent(ntb), bits << nc->dboff));
5134490696bSAlexander Motin }
5144490696bSAlexander Motin 
5154490696bSAlexander Motin void
ntb_db_clear_mask(device_t ntb,uint64_t bits)5164490696bSAlexander Motin ntb_db_clear_mask(device_t ntb, uint64_t bits)
5174490696bSAlexander Motin {
5184490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
5194490696bSAlexander Motin 
5204490696bSAlexander Motin 	return (NTB_DB_CLEAR_MASK(device_get_parent(ntb), bits << nc->dboff));
5214490696bSAlexander Motin }
5224490696bSAlexander Motin 
5234490696bSAlexander Motin uint64_t
ntb_db_read(device_t ntb)5244490696bSAlexander Motin ntb_db_read(device_t ntb)
5254490696bSAlexander Motin {
5264490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
5274490696bSAlexander Motin 
5284490696bSAlexander Motin 	return ((NTB_DB_READ(device_get_parent(ntb)) >> nc->dboff)
5294490696bSAlexander Motin 	    & nc->dbmask);
5304490696bSAlexander Motin }
5314490696bSAlexander Motin 
5324490696bSAlexander Motin void
ntb_db_set_mask(device_t ntb,uint64_t bits)5334490696bSAlexander Motin ntb_db_set_mask(device_t ntb, uint64_t bits)
5344490696bSAlexander Motin {
5354490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
5364490696bSAlexander Motin 
5374490696bSAlexander Motin 	return (NTB_DB_SET_MASK(device_get_parent(ntb), bits << nc->dboff));
5384490696bSAlexander Motin }
5394490696bSAlexander Motin 
5404490696bSAlexander Motin void
ntb_peer_db_set(device_t ntb,uint64_t bits)5414490696bSAlexander Motin ntb_peer_db_set(device_t ntb, uint64_t bits)
5424490696bSAlexander Motin {
5434490696bSAlexander Motin 	struct ntb_child *nc = device_get_ivars(ntb);
5444490696bSAlexander Motin 
5454490696bSAlexander Motin 	return (NTB_PEER_DB_SET(device_get_parent(ntb), bits << nc->dboff));
5464490696bSAlexander Motin }
5474490696bSAlexander Motin 
5489a5325c2SAlexander Motin MODULE_VERSION(ntb, 1);
549