diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2001-09-05 16:54:02 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2001-09-05 16:54:02 +0000 |
commit | abba7bb1fc5c366e50cbba7c822bd2fa9ff9b008 (patch) | |
tree | ff1679a61b82715061c4f63d0a16e9b9a0322b80 /sys/arch/macppc/dev/if_gm.c | |
parent | 48db4f1abe606dcd0c3ead5c901b7b83289169a4 (diff) |
use dmamem/dmamap for allocating dmaable memory, since malloc
can produce physically non-contiguous memory space, and thus
trash the innocent pages. also make use of pci_mapreg_map
and other `usefull' stuff (;
import a reliability kludge from netbsd, the one to
mark all buffers GMAC_OWN after rint is done.
drahn@ ok
Diffstat (limited to 'sys/arch/macppc/dev/if_gm.c')
-rw-r--r-- | sys/arch/macppc/dev/if_gm.c | 146 |
1 files changed, 90 insertions, 56 deletions
diff --git a/sys/arch/macppc/dev/if_gm.c b/sys/arch/macppc/dev/if_gm.c index 04d546bc9f3..95336155633 100644 --- a/sys/arch/macppc/dev/if_gm.c +++ b/sys/arch/macppc/dev/if_gm.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_gm.c,v 1.2 2001/09/01 17:43:09 drahn Exp $ */ -/* $NetBSD: if_gm.c,v 1.2 2000/03/04 11:17:00 tsubai Exp $ */ +/* $OpenBSD: if_gm.c,v 1.3 2001/09/05 16:54:01 mickey Exp $ */ +/* $NetBSD: if_gm.c,v 1.14 2001/07/22 11:29:46 wiz Exp $ */ /*- * Copyright (c) 2000 Tsubai Masanari. All rights reserved. @@ -72,6 +72,7 @@ #define NTXBUF 4 #define NRXBUF 32 +#define GM_BUFSZ ((NRXBUF + NTXBUF + 2) * 2048) struct gmac_softc { struct device sc_dev; @@ -87,8 +88,13 @@ struct gmac_softc { vaddr_t sc_reg; bus_space_handle_t gm_bush; bus_space_tag_t gm_bust; + bus_dma_tag_t gm_dmat; + bus_dmamap_t sc_bufmap; + bus_dma_segment_t sc_bufseg[1]; struct gmac_dma *sc_txlist; + paddr_t sc_txlist_pa; struct gmac_dma *sc_rxlist; + paddr_t sc_rxlist_pa; int sc_txnext; int sc_rxlast; caddr_t sc_txbuf[NTXBUF]; @@ -135,6 +141,11 @@ void gmac_mii_tick __P((void *)); u_int32_t ether_crc32_le(const u_int8_t *buf, size_t len); +#ifdef __NetBSD__ +#define letoh32 le32toh +#endif + + struct cfattach gm_ca = { sizeof(struct gmac_softc), gmac_match, gmac_attach }; @@ -177,8 +188,7 @@ gmac_attach(parent, self, aux) #ifdef __NetBSD__ int node; #endif - int i; - char *p; + int i, nseg, error; struct gmac_dma *dp; u_char laddr[6]; @@ -206,30 +216,17 @@ gmac_attach(parent, self, aux) pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command); #ifdef USE_IO - if (pci_io_find(pc, pa->pa_tag, 0x10, &iobase, &iosize, NULL)) { - printf(": can't find I/O space\n"); + if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, + &sc->gm_bust, &sc->gm_bush, &iobase, &iosize, 0)) { + printf(": can't map controller i/o space\n"); return; } - if (bus_space_map(pa->pa_iot, iobase, iosize, 0, &sc->gm_bush)) - { - printf(": can't map I/O space\n"); - return; - } - sc->gm_bust = pa->pa_iot; #else /* !USE_IO */ - if (pci_mem_find(pc, pa->pa_tag, 0x10, &membase, &memsize, - NULL)) - { - printf(": can't find MEM space\n"); - return; - } - if (bus_space_map(pa->pa_memt, membase, memsize, 0, - &sc->gm_bush)) - { - printf(": can't map MEM space\n"); + if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM, 0, + &sc->gm_bust, &sc->gm_bush, &membase, &memsize, 0)) { + printf(": can't map controller mem space\n"); return; } - sc->gm_bust = pa->pa_memt; #endif /* !USE_IO */ } @@ -270,35 +267,73 @@ gmac_attach(parent, self, aux) } #endif - /* Setup packet buffers and dma descriptors. */ - p = malloc((NRXBUF + NTXBUF) * 2048 + 3 * 0x800, M_DEVBUF, M_NOWAIT); - if (p == NULL) { - printf(": cannot malloc buffers\n"); + sc->gm_dmat = pa->pa_dmat; + { + vaddr_t va; + paddr_t pa; + error = bus_dmamem_alloc(sc->gm_dmat, GM_BUFSZ, + PAGE_SIZE, 0, sc->sc_bufseg, 1, &nseg, BUS_DMA_NOWAIT); + if (error) { + printf(": cannot allocate buffers (%d)\n", error); + return; + } + + error = bus_dmamem_map(sc->gm_dmat, sc->sc_bufseg, nseg, + GM_BUFSZ, (caddr_t *)&va, BUS_DMA_NOWAIT); + if (error) { + printf(": cannot map buffers (%d)\n", error); + bus_dmamem_free(sc->gm_dmat, sc->sc_bufseg, 1); + return; + } + + error = bus_dmamap_create(sc->gm_dmat, GM_BUFSZ, 1, GM_BUFSZ, 0, + BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_bufmap); + if (error) { + printf(": cannot create buffer dmamap (%d)\n", error); + bus_dmamem_unmap(sc->gm_dmat, (void *)va, GM_BUFSZ); + bus_dmamem_free(sc->gm_dmat, sc->sc_bufseg, 1); + return; + } + error = bus_dmamap_load(sc->gm_dmat, sc->sc_bufmap, (void *)va, + GM_BUFSZ, NULL, BUS_DMA_NOWAIT); + if (error) { + printf(": cannot load buffers dmamap (%d)\n", error); + bus_dmamap_destroy(sc->gm_dmat, sc->sc_bufmap); + bus_dmamem_unmap(sc->gm_dmat, (void *)va, GM_BUFSZ); + bus_dmamem_free(sc->gm_dmat, sc->sc_bufseg, nseg); return; } - p = (void *)roundup((vaddr_t)p, 0x800); - bzero(p, 2048 * (NRXBUF + NTXBUF) + 2 * 0x800); - sc->sc_rxlist = (void *)p; - p += 0x800; - sc->sc_txlist = (void *)p; - p += 0x800; + bzero((void *)va, GM_BUFSZ); + pa = sc->sc_bufseg[0].ds_addr; + + sc->sc_rxlist = (void *)va; + sc->sc_rxlist_pa = pa; + va += 0x800; + pa += 0x800; + sc->sc_txlist = (void *)va; + sc->sc_txlist_pa = pa;; + va += 0x800; + pa += 0x800; dp = sc->sc_rxlist; for (i = 0; i < NRXBUF; i++) { - sc->sc_rxbuf[i] = p; - dp->address = htole32(vtophys((vaddr_t)p)); + sc->sc_rxbuf[i] = (void *)va; + dp->address = htole32(pa); dp->cmd = htole32(GMAC_OWN); dp++; - p += 2048; + va += 2048; + pa += 2048; } dp = sc->sc_txlist; for (i = 0; i < NTXBUF; i++) { - sc->sc_txbuf[i] = p; - dp->address = htole32(vtophys((vaddr_t)p)); + sc->sc_txbuf[i] = (void *)va; + dp->address = htole32(pa); dp++; - p += 2048; + va += 2048; + pa += 2048; + } } #ifdef __OpenBSD__ @@ -460,7 +495,7 @@ gmac_rint(sc) struct ifnet *ifp = &sc->sc_if; volatile struct gmac_dma *dp; struct mbuf *m; - int i, len; + int i, j, len; u_int cmd; for (i = sc->sc_rxlast;; i++) { @@ -468,21 +503,13 @@ gmac_rint(sc) i = 0; dp = &sc->sc_rxlist[i]; -#ifdef __OpenBSD__ cmd = letoh32(dp->cmd); -#else /* !__OpenBSD__ */ - cmd = le32toh(dp->cmd); -#endif /* !__OpenBSD__ */ if (cmd & GMAC_OWN) break; len = (cmd >> 16) & GMAC_LEN_MASK; len -= 4; /* CRC */ -#ifdef __OpenBSD__ - if (letoh32(dp->cmd_hi) & 0x40000000) { -#else /* !__OpenBSD__ */ - if (le32toh(dp->cmd_hi) & 0x40000000) { -#endif /* !__OpenBSD__ */ + if (dp->cmd_hi & htole32(0x40000000)) { ifp->if_ierrors++; goto next; } @@ -514,6 +541,15 @@ next: dp->cmd = htole32(GMAC_OWN); } sc->sc_rxlast = i; + + /* XXX Make sure free buffers have GMAC_OWN. */ + i++; + for (j = 1; j < NRXBUF; j++) { + if (i == NRXBUF) + i = 0; + dp = &sc->sc_rxlist[i++]; + dp->cmd = htole32(GMAC_OWN); + } } struct mbuf * @@ -615,9 +651,8 @@ gmac_start(ifp) bpf_tap(ifp->if_bpf, buff, tlen); #endif i++; - if (i == NTXBUF) { + if (i == NTXBUF) i = 0; - } if (i == gmac_read_reg(sc, GMAC_TXDMACOMPLETE)) { ifp->if_flags |= IFF_OACTIVE; break; @@ -678,9 +713,9 @@ gmac_reset(sc) __asm __volatile ("sync"); gmac_write_reg(sc, GMAC_TXDMADESCBASEHI, 0); - gmac_write_reg(sc, GMAC_TXDMADESCBASELO, vtophys((vaddr_t)sc->sc_txlist)); + gmac_write_reg(sc, GMAC_TXDMADESCBASELO, sc->sc_txlist_pa); gmac_write_reg(sc, GMAC_RXDMADESCBASEHI, 0); - gmac_write_reg(sc, GMAC_RXDMADESCBASELO, vtophys((vaddr_t)sc->sc_rxlist)); + gmac_write_reg(sc, GMAC_RXDMADESCBASELO, sc->sc_rxlist_pa); gmac_write_reg(sc, GMAC_RXDMAKICK, NRXBUF); splx(s); @@ -773,11 +808,10 @@ gmac_init_mac(sc) gmac_write_reg(sc, GMAC_TXMACCONFIG, 0); gmac_write_reg(sc, GMAC_XIFCONFIG, 5); } - if (0) { /* g-bit? */ + if (0) /* g-bit? */ gmac_write_reg(sc, GMAC_MACCTRLCONFIG, 3); - } else { + else gmac_write_reg(sc, GMAC_MACCTRLCONFIG, 0); - } } void |