summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_myx.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-10-31 01:23:47 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-10-31 01:23:47 +0000
commit344d5abd886a25f7f20839734f9813a67d673550 (patch)
treeebce12a70b78f8d9284aab55310cce1ac097cf3d /sys/dev/pci/if_myx.c
parentdd5499ac9a8b37c020c8f4552a1cd891f0f6fcd0 (diff)
revert 1.97 where i moved myx to using the system pools
my early revision board doesnt like it at all
Diffstat (limited to 'sys/dev/pci/if_myx.c')
-rw-r--r--sys/dev/pci/if_myx.c79
1 files changed, 67 insertions, 12 deletions
diff --git a/sys/dev/pci/if_myx.c b/sys/dev/pci/if_myx.c
index df01711c7fa..ea797fcd720 100644
--- a/sys/dev/pci/if_myx.c
+++ b/sys/dev/pci/if_myx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_myx.c,v 1.97 2016/10/28 10:14:16 dlg Exp $ */
+/* $OpenBSD: if_myx.c,v 1.98 2016/10/31 01:23:46 dlg Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org>
@@ -29,6 +29,7 @@
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/malloc.h>
+#include <sys/pool.h>
#include <sys/timeout.h>
#include <sys/device.h>
#include <sys/proc.h>
@@ -78,6 +79,8 @@ struct myx_dmamem {
caddr_t mxm_kva;
};
+struct pool *myx_mcl_pool;
+
struct myx_slot {
bus_dmamap_t ms_map;
struct mbuf *ms_m;
@@ -92,7 +95,7 @@ struct myx_rx_ring {
u_int mrr_running;
u_int mrr_prod;
u_int mrr_cons;
- u_int mrr_size;
+ struct mbuf *(*mrr_mclget)(void);
};
enum myx_state {
@@ -207,7 +210,9 @@ void myx_rxeof(struct myx_softc *);
void myx_txeof(struct myx_softc *, u_int32_t);
int myx_buf_fill(struct myx_softc *, struct myx_slot *,
- u_int);
+ struct mbuf *(*)(void));
+struct mbuf * myx_mcl_small(void);
+struct mbuf * myx_mcl_big(void);
int myx_rx_init(struct myx_softc *, int, bus_size_t);
int myx_rx_fill(struct myx_softc *, struct myx_rx_ring *);
@@ -251,11 +256,11 @@ myx_attach(struct device *parent, struct device *self, void *aux)
sc->sc_dmat = pa->pa_dmat;
sc->sc_rx_ring[MYX_RXSMALL].mrr_softc = sc;
- sc->sc_rx_ring[MYX_RXSMALL].mrr_size = MYX_RXSMALL_SIZE;
+ sc->sc_rx_ring[MYX_RXSMALL].mrr_mclget = myx_mcl_small;
timeout_set(&sc->sc_rx_ring[MYX_RXSMALL].mrr_refill, myx_refill,
&sc->sc_rx_ring[MYX_RXSMALL]);
sc->sc_rx_ring[MYX_RXBIG].mrr_softc = sc;
- sc->sc_rx_ring[MYX_RXBIG].mrr_size = MYX_RXBIG_SIZE;
+ sc->sc_rx_ring[MYX_RXBIG].mrr_mclget = myx_mcl_big;
timeout_set(&sc->sc_rx_ring[MYX_RXBIG].mrr_refill, myx_refill,
&sc->sc_rx_ring[MYX_RXBIG]);
@@ -286,6 +291,22 @@ myx_attach(struct device *parent, struct device *self, void *aux)
part[0] == '\0' ? "(unknown)" : part,
ether_sprintf(sc->sc_ac.ac_enaddr));
+ /* this is sort of racy */
+ if (myx_mcl_pool == NULL) {
+ extern struct kmem_pa_mode kp_dma_contig;
+
+ myx_mcl_pool = malloc(sizeof(*myx_mcl_pool), M_DEVBUF,
+ M_WAITOK);
+ if (myx_mcl_pool == NULL) {
+ printf("%s: unable to allocate mcl pool\n",
+ DEVNAME(sc));
+ goto unmap;
+ }
+ pool_init(myx_mcl_pool, MYX_RXBIG_SIZE, MYX_BOUNDARY, IPL_NET,
+ 0, "myxmcl", NULL);
+ pool_set_constraints(myx_mcl_pool, &kp_dma_contig);
+ }
+
if (myx_pcie_dc(sc, pa) != 0)
printf("%s: unable to configure PCI Express\n", DEVNAME(sc));
@@ -1751,7 +1772,7 @@ myx_rx_fill_slots(struct myx_softc *sc, struct myx_rx_ring *mrr, u_int slots)
u_int p, first, fills;
first = p = mrr->mrr_prod;
- if (myx_buf_fill(sc, &mrr->mrr_slots[first], mrr->mrr_size) != 0)
+ if (myx_buf_fill(sc, &mrr->mrr_slots[first], mrr->mrr_mclget) != 0)
return (slots);
if (++p >= sc->sc_rx_ring_count)
@@ -1760,7 +1781,7 @@ myx_rx_fill_slots(struct myx_softc *sc, struct myx_rx_ring *mrr, u_int slots)
for (fills = 1; fills < slots; fills++) {
ms = &mrr->mrr_slots[p];
- if (myx_buf_fill(sc, ms, mrr->mrr_size) != 0)
+ if (myx_buf_fill(sc, ms, mrr->mrr_mclget) != 0)
break;
rxd.rx_addr = htobe64(ms->ms_map->dm_segs[0].ds_addr);
@@ -1879,19 +1900,53 @@ myx_rx_free(struct myx_softc *sc, struct myx_rx_ring *mrr)
free(mrr->mrr_slots, M_DEVBUF, sizeof(*ms) * sc->sc_rx_ring_count);
}
+struct mbuf *
+myx_mcl_small(void)
+{
+ struct mbuf *m;
+
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MYX_RXSMALL_SIZE);
+ if (m == NULL)
+ return (NULL);
+
+ m->m_len = m->m_pkthdr.len = MYX_RXSMALL_SIZE;
+
+ return (m);
+}
+
+struct mbuf *
+myx_mcl_big(void)
+{
+ struct mbuf *m;
+ void *mcl;
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL)
+ return (NULL);
+
+ mcl = pool_get(myx_mcl_pool, PR_NOWAIT);
+ if (mcl == NULL) {
+ m_free(m);
+ return (NULL);
+ }
+
+ MEXTADD(m, mcl, MYX_RXBIG_SIZE, M_EXTWR, MEXTFREE_POOL, myx_mcl_pool);
+ m->m_len = m->m_pkthdr.len = MYX_RXBIG_SIZE;
+
+ return (m);
+}
+
int
-myx_buf_fill(struct myx_softc *sc, struct myx_slot *ms, u_int size)
+myx_buf_fill(struct myx_softc *sc, struct myx_slot *ms,
+ struct mbuf *(*mclget)(void))
{
struct mbuf *m;
int rv;
-
- m = MCLGETI(NULL, M_DONTWAIT, NULL, size);
+ m = (*mclget)();
if (m == NULL)
return (ENOMEM);
- m->m_pkthdr.len = m->m_len = size;
-
rv = bus_dmamap_load_mbuf(sc->sc_dmat, ms->ms_map, m, BUS_DMA_NOWAIT);
if (rv != 0) {
m_freem(m);