iflib: introduce isc_dma_width
Some DMA controllers are unable to address the full host memory space and are instead limited to a subset of address range (e.g. 48-bit). Allow the driver to specify the maximum allowed DMA addressing width (in bits) for the NIC hardware, by introducing a new field in if_softc_ctx. If said field is omitted (set to 0), the lowaddr of DMA window bounds defaults to BUS_SPACE_MAXADDR. Submitted by: Artur Rojek <ar@semihalf.com> Obtained from: Semihalf Sponsored by: Amazon, Inc. Differential Revision: https://reviews.freebsd.org/D28706
This commit is contained in:
parent
cc3fa1e29f
commit
6dd69f0064
@ -1389,15 +1389,22 @@ _iflib_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
|
||||
*(bus_addr_t *) arg = segs[0].ds_addr;
|
||||
}
|
||||
|
||||
#define DMA_WIDTH_TO_BUS_LOWADDR(width) \
|
||||
(((width) == 0) || (width) == flsl(BUS_SPACE_MAXADDR) ? \
|
||||
BUS_SPACE_MAXADDR : (1ULL << (width)) - 1ULL)
|
||||
|
||||
int
|
||||
iflib_dma_alloc_align(if_ctx_t ctx, int size, int align, iflib_dma_info_t dma, int mapflags)
|
||||
{
|
||||
int err;
|
||||
device_t dev = ctx->ifc_dev;
|
||||
bus_addr_t lowaddr;
|
||||
|
||||
lowaddr = DMA_WIDTH_TO_BUS_LOWADDR(ctx->ifc_softc_ctx.isc_dma_width);
|
||||
|
||||
err = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
|
||||
align, 0, /* alignment, bounds */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
lowaddr, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
size, /* maxsize */
|
||||
@ -1648,6 +1655,7 @@ iflib_txsd_alloc(iflib_txq_t txq)
|
||||
if_softc_ctx_t scctx = &ctx->ifc_softc_ctx;
|
||||
device_t dev = ctx->ifc_dev;
|
||||
bus_size_t tsomaxsize;
|
||||
bus_addr_t lowaddr;
|
||||
int err, nsegments, ntsosegments;
|
||||
bool tso;
|
||||
|
||||
@ -1664,12 +1672,14 @@ iflib_txsd_alloc(iflib_txq_t txq)
|
||||
MPASS(sctx->isc_tso_maxsize >= tsomaxsize);
|
||||
}
|
||||
|
||||
lowaddr = DMA_WIDTH_TO_BUS_LOWADDR(scctx->isc_dma_width);
|
||||
|
||||
/*
|
||||
* Set up DMA tags for TX buffers.
|
||||
*/
|
||||
if ((err = bus_dma_tag_create(bus_get_dma_tag(dev),
|
||||
1, 0, /* alignment, bounds */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
lowaddr, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
sctx->isc_tx_maxsize, /* maxsize */
|
||||
@ -1687,7 +1697,7 @@ iflib_txsd_alloc(iflib_txq_t txq)
|
||||
tso = (if_getcapabilities(ctx->ifc_ifp) & IFCAP_TSO) != 0;
|
||||
if (tso && (err = bus_dma_tag_create(bus_get_dma_tag(dev),
|
||||
1, 0, /* alignment, bounds */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
lowaddr, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
tsomaxsize, /* maxsize */
|
||||
@ -1889,18 +1899,21 @@ iflib_rxsd_alloc(iflib_rxq_t rxq)
|
||||
if_softc_ctx_t scctx = &ctx->ifc_softc_ctx;
|
||||
device_t dev = ctx->ifc_dev;
|
||||
iflib_fl_t fl;
|
||||
bus_addr_t lowaddr;
|
||||
int err;
|
||||
|
||||
MPASS(scctx->isc_nrxd[0] > 0);
|
||||
MPASS(scctx->isc_nrxd[rxq->ifr_fl_offset] > 0);
|
||||
|
||||
lowaddr = DMA_WIDTH_TO_BUS_LOWADDR(scctx->isc_dma_width);
|
||||
|
||||
fl = rxq->ifr_fl;
|
||||
for (int i = 0; i < rxq->ifr_nfl; i++, fl++) {
|
||||
fl->ifl_size = scctx->isc_nrxd[rxq->ifr_fl_offset]; /* this isn't necessarily the same */
|
||||
/* Set up DMA tag for RX buffers. */
|
||||
err = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
|
||||
1, 0, /* alignment, bounds */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
lowaddr, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
sctx->isc_rx_maxsize, /* maxsize */
|
||||
@ -4748,6 +4761,8 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
_iflib_pre_assert(scctx);
|
||||
ctx->ifc_txrx = *scctx->isc_txrx;
|
||||
|
||||
MPASS(scctx->isc_dma_width <= flsl(BUS_SPACE_MAXADDR));
|
||||
|
||||
if (sctx->isc_flags & IFLIB_DRIVER_MEDIA)
|
||||
ctx->ifc_mediap = scctx->isc_media;
|
||||
|
||||
|
@ -236,6 +236,8 @@ typedef struct if_softc_ctx {
|
||||
int isc_disable_msix;
|
||||
if_txrx_t isc_txrx;
|
||||
struct ifmedia *isc_media;
|
||||
bus_size_t isc_dma_width; /* device dma width in bits, 0 means
|
||||
use BUS_SPACE_MAXADDR instead */
|
||||
} *if_softc_ctx_t;
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user