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");
1105b56413dSWarner Losh nc->dev = device_add_child(dev, name, DEVICE_UNIT_ANY);
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
145*18250ec6SJohn Baldwin bus_attach_children(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