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