/* * Allocate and initialize the shared data structures * of a vmxnet3s device. */ static int vmxnet3s_prepare_drivershared(vmxnet3s_softc_t *dp) { vmxnet3s_drvshared_t *ds; size_t allocsz = sizeof (vmxnet3s_drvshared_t); if (vmxnet3s_alloc1(dp, &dp->shareddata, allocsz, B_TRUE) != DDI_SUCCESS) return (DDI_FAILURE); ds = VMXNET3_DS(dp); (void) memset(ds, 0, allocsz); allocsz = sizeof (vmxnet3s_txqdesc_t) + sizeof (vmxnet3s_rxqdesc_t); if (vmxnet3s_alloc128(dp, &dp->qdescs, allocsz, B_TRUE) != DDI_SUCCESS) { vmxnet3s_free(&dp->shareddata); return (DDI_FAILURE); } (void) memset(dp->qdescs.buf, 0, allocsz); ds->magic = VMXNET3_REV1_MAGIC; /* Take care of most of devread */ ds->devread.misc.drvinfo.version = BUILD_NUMBER_NUMERIC; if (sizeof (void *) == 4) ds->devread.misc.drvinfo.gos.gosbits = VMXNET3_GOS_BITS_32; else if (sizeof (void *) == 8) ds->devread.misc.drvinfo.gos.gosbits = VMXNET3_GOS_BITS_64; else ASSERT(B_FALSE); ds->devread.misc.drvinfo.gos.gostype = VMXNET3_GOS_TYPE_SOLARIS; ds->devread.misc.drvinfo.gos.gosver = 10; ds->devread.misc.drvinfo.vmxnet3srevspt = 1; ds->devread.misc.drvinfo.uptverspt = 1; ds->devread.misc.uptfeatures = UPT1_F_RXCSUM; ds->devread.misc.mtu = dp->cur_mtu; /* XXX ds->devread.misc.maxnumrxsg */ ds->devread.misc.numtxq = 1; ds->devread.misc.numrxq = 1; ds->devread.misc.queuedescpa = dp->qdescs.bufpa; ds->devread.misc.queuedesclen = allocsz; /* txq and rxq information is filled in other functions */ ds->devread.intrconf.automask = (dp->intrmaskmode == VMXNET3_IMM_AUTO); ds->devread.intrconf.numintrs = 1; /* XXX ds->intr.modlevels */ ds->devread.intrconf.eventintridx = 0; VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_DSAL, VMXNET3_ADDR_LO(dp->shareddata.bufpa)); VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_DSAH, VMXNET3_ADDR_HI(dp->shareddata.bufpa)); return (DDI_SUCCESS); }
/* * Allocate new rxbuf from memory. All its fields are set except * for its associated mblk which has to be allocated later. */ static vmxnet3s_rxbuf_t * vmxnet3s_alloc_rxbuf(vmxnet3s_softc_t *dp, boolean_t cansleep) { vmxnet3s_rxbuf_t *rxbuf; int flag = cansleep ? KM_SLEEP : KM_NOSLEEP; if ((rxbuf = kmem_zalloc(sizeof (vmxnet3s_rxbuf_t), flag)) == NULL) return (NULL); if (vmxnet3s_alloc1(dp, &rxbuf->dma, (dp->cur_mtu + 18), cansleep) != DDI_SUCCESS) { kmem_free(rxbuf, sizeof (vmxnet3s_rxbuf_t)); return (NULL); } rxbuf->freecb.free_func = vmxnet3s_put_rxbuf; rxbuf->freecb.free_arg = (caddr_t)rxbuf; rxbuf->dp = dp; atomic_inc_32(&dp->rxnumbufs); return (rxbuf); }