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