summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_nxe.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2007-08-15 06:45:16 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2007-08-15 06:45:16 +0000
commitd517d1ae6bcca202f23b9404413225fa7ae433c6 (patch)
tree2e9c07f7a5c4c84abe9193eb596536e1c89a0fdc /sys/dev/pci/if_nxe.c
parentc07eae7e3b9bbb2a7fa4cf632fff162bbc264c0a (diff)
when the interface is brought up allocate all the things that are needed
for the chip to work with, eg, the context region, the cmd consumer, the cmd/tx ring, the status ring, and the 3 rx rings. free it all when we bring the chip down.
Diffstat (limited to 'sys/dev/pci/if_nxe.c')
-rw-r--r--sys/dev/pci/if_nxe.c88
1 files changed, 87 insertions, 1 deletions
diff --git a/sys/dev/pci/if_nxe.c b/sys/dev/pci/if_nxe.c
index adb761a498a..5d1ebe54879 100644
--- a/sys/dev/pci/if_nxe.c
+++ b/sys/dev/pci/if_nxe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nxe.c,v 1.33 2007/08/15 06:14:00 dlg Exp $ */
+/* $OpenBSD: if_nxe.c,v 1.34 2007/08/15 06:45:15 dlg Exp $ */
/*
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
@@ -689,6 +689,13 @@ struct nxe_softc {
/* allocations for the hw */
struct nxe_dmamem *sc_dummy_dma;
+ struct nxe_dmamem *sc_ctx;
+ u_int32_t *sc_cmd_consumer;
+
+ struct nxe_ring *sc_cmd_ring;
+ struct nxe_ring *sc_rx_rings[NXE_NRING];
+ struct nxe_ring *sc_status_ring;
+
/* monitoring */
struct timeout sc_tick;
struct ksensor sc_sensor;
@@ -1010,9 +1017,22 @@ err:
void
nxe_up(struct nxe_softc *sc)
{
+ struct ifnet *ifp = &sc->sc_ac.ac_if;
+ static const u_int rx_ring_sizes[] = { 16384, 1024, 128 };
+ struct {
+ struct nxe_ctx ctx;
+ u_int32_t cmd_consumer;
+ } __packed *dmamem;
+ struct nxe_ctx *ctx;
+ struct nxe_ctx_ring *ring;
+ struct nxe_ring *nr;
+ u_int64_t dva;
+ int i;
+
if (nxe_up_fw(sc) != 0)
return;
+ /* allocate pkt lists */
sc->sc_tx_pkts = nxe_pkt_alloc(sc, 128, NXE_TXD_MAX_SEGS);
if (sc->sc_tx_pkts == NULL)
return;
@@ -1020,9 +1040,69 @@ nxe_up(struct nxe_softc *sc)
if (sc->sc_rx_pkts == NULL)
goto free_tx_pkts;
+ /* allocate the context memory and the consumer field */
+ sc->sc_ctx = nxe_dmamem_alloc(sc, sizeof(*dmamem), PAGE_SIZE);
+ if (sc->sc_ctx == NULL)
+ goto free_rx_pkts;
+
+ dmamem = NXE_DMA_KVA(sc->sc_ctx);
+ dva = NXE_DMA_DVA(sc->sc_ctx);
+
+ ctx = &dmamem->ctx;
+ ctx->ctx_cmd_consumer_addr = htole64(dva + sizeof(dmamem->ctx));
+ ctx->ctx_id = htole32(sc->sc_function);
+
+ sc->sc_cmd_consumer = &dmamem->cmd_consumer;
+
+ /* allocate the cmd/tx ring */
+ sc->sc_cmd_ring = nxe_ring_alloc(sc,
+ sizeof(struct nxe_tx_desc), 1024 /* XXX */);
+ if (sc->sc_cmd_ring == NULL)
+ goto free_ctx;
+
+ ctx->ctx_cmd_ring.r_addr =
+ htole64(NXE_DMA_DVA(sc->sc_cmd_ring->nr_dmamem));
+ ctx->ctx_cmd_ring.r_size = htole64(sc->sc_cmd_ring->nr_nentries);
+
+ /* allocate the status ring */
+ sc->sc_status_ring = nxe_ring_alloc(sc,
+ sizeof(struct nxe_status_desc), 16384 /* XXX */);
+ if (sc->sc_status_ring == NULL)
+ goto free_cmd_ring;
+
+ ctx->ctx_status_ring_addr =
+ htole64(NXE_DMA_DVA(sc->sc_status_ring->nr_dmamem));
+ ctx->ctx_status_ring_size = htole64(sc->sc_status_ring->nr_nentries);
+
+ /* allocate the rx rings */
+ for (i = 0; i < NXE_NRING; i++) {
+ ring = &ctx->ctx_rx_rings[i];
+ nr = nxe_ring_alloc(sc, sizeof(struct nxe_rx_desc),
+ rx_ring_sizes[i]);
+ if (nr == NULL)
+ goto free_rx_rings;
+
+ ring->r_addr = htole64(NXE_DMA_DVA(nr->nr_dmamem));
+ ring->r_size = htole32(nr->nr_nentries);
+
+ sc->sc_rx_rings[i] = nr;
+ }
+
+ SET(ifp->if_flags, IFF_RUNNING);
return;
+free_rx_rings:
+ while (i > 0)
+ nxe_ring_free(sc, sc->sc_rx_rings[--i]);
+
+ nxe_ring_free(sc, sc->sc_status_ring);
+free_cmd_ring:
+ nxe_ring_free(sc, sc->sc_cmd_ring);
+free_ctx:
+ nxe_dmamem_free(sc, sc->sc_ctx);
+free_rx_pkts:
+ nxe_pkt_free(sc, sc->sc_rx_pkts);
free_tx_pkts:
nxe_pkt_free(sc, sc->sc_tx_pkts);
}
@@ -1061,9 +1141,15 @@ void
nxe_down(struct nxe_softc *sc)
{
struct ifnet *ifp = &sc->sc_ac.ac_if;
+ int i;
CLR(ifp->if_flags, IFF_RUNNING | IFF_OACTIVE | IFF_ALLMULTI);
+ for (i = 0; i < NXE_NRING; i++)
+ nxe_ring_free(sc, sc->sc_rx_rings[i]);
+ nxe_ring_free(sc, sc->sc_status_ring);
+ nxe_ring_free(sc, sc->sc_cmd_ring);
+ nxe_dmamem_free(sc, sc->sc_ctx);
nxe_pkt_free(sc, sc->sc_rx_pkts);
nxe_pkt_free(sc, sc->sc_tx_pkts);
}