summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBill Paul <wpaul@FreeBSD.org>2001-08-15 17:38:43 +0000
committerBill Paul <wpaul@FreeBSD.org>2001-08-15 17:38:43 +0000
commit0219a4215565cddeb1e24915d291bbb42181ed7c (patch)
treed02c2e7dcb5460927414e17349bd92e6b0abbd0a /sys
parent4559d1c897e097b601a4d39ab339eda3efc2b916 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/pci/if_rl.c107
-rw-r--r--sys/pci/if_rlreg.h13
-rw-r--r--sys/pci/if_sis.c283
-rw-r--r--sys/pci/if_sisreg.h23
4 files changed, 359 insertions, 67 deletions
diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c
index 5b70c0817672..3502f20f0da6 100644
--- a/sys/pci/if_rl.c
+++ b/sys/pci/if_rl.c
@@ -99,8 +99,6 @@
#include <net/bpf.h>
-#include <vm/vm.h> /* for vtophys */
-#include <vm/pmap.h> /* for vtophys */
#include <machine/bus_pio.h>
#include <machine/bus_memio.h>
#include <machine/bus.h>
@@ -194,6 +192,11 @@ static void rl_setmulti __P((struct rl_softc *));
static void rl_reset __P((struct rl_softc *));
static int rl_list_tx_init __P((struct rl_softc *));
+static void rl_dma_map_rxbuf __P((void *, bus_dma_segment_t *,
+ int, int));
+static void rl_dma_map_txbuf __P((void *, bus_dma_segment_t *,
+ int, int));
+
#ifdef RL_USEIOSPACE
#define RL_RES SYS_RES_IOPORT
#define RL_RID RL_PCI_LOIO
@@ -241,6 +244,34 @@ DRIVER_MODULE(miibus, rl, miibus_driver, miibus_devclass, 0, 0);
CSR_WRITE_1(sc, RL_EECMD, \
CSR_READ_1(sc, RL_EECMD) & ~x)
+static void
+rl_dma_map_rxbuf(arg, segs, nseg, error)
+ void *arg;
+ bus_dma_segment_t *segs;
+ int nseg, error;
+{
+ struct rl_softc *sc;
+
+ sc = arg;
+ CSR_WRITE_4(sc, RL_RXADDR, segs->ds_addr & 0xFFFFFFFF);
+
+ return;
+}
+
+static void
+rl_dma_map_txbuf(arg, segs, nseg, error)
+ void *arg;
+ bus_dma_segment_t *segs;
+ int nseg, error;
+{
+ struct rl_softc *sc;
+
+ sc = arg;
+ CSR_WRITE_4(sc, RL_CUR_TXADDR(sc), segs->ds_addr & 0xFFFFFFFF);
+
+ return;
+}
+
/*
* Send a read command and address to the EEPROM, check for ACK.
*/
@@ -940,14 +971,49 @@ static int rl_attach(dev)
goto fail;
}
- sc->rl_cdata.rl_rx_buf = contigmalloc(RL_RXBUFLEN + 1518, M_DEVBUF,
- M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
+ /*
+ * Allocate the parent bus DMA tag appropriate for PCI.
+ */
+#define RL_NSEG_NEW 32
+ error = bus_dma_tag_create(NULL, /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MAXBSIZE, RL_NSEG_NEW, /* maxsize, nsegments */
+ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
+ BUS_DMA_ALLOCNOW, /* flags */
+ &sc->rl_parent_tag);
+
+ /*
+ * Now allocate a tag for the DMA descriptor lists.
+ * All of our lists are allocated as a contiguous block
+ * of memory.
+ */
+ error = bus_dma_tag_create(sc->rl_parent_tag, /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ RL_RXBUFLEN + 1518, 1, /* maxsize,nsegments */
+ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
+ 0, /* flags */
+ &sc->rl_tag);
+
+ /*
+ * Now allocate a chunk of DMA-able memory based on the
+ * tag we just created.
+ */
+ error = bus_dmamem_alloc(sc->rl_tag,
+ (void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_NOWAIT,
+ &sc->rl_cdata.rl_rx_dmamap);
if (sc->rl_cdata.rl_rx_buf == NULL) {
printf("rl%d: no memory for list buffers!\n", unit);
bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
+ bus_dma_tag_destroy(sc->rl_tag);
error = ENXIO;
goto fail;
}
@@ -963,7 +1029,9 @@ static int rl_attach(dev)
bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
- free(sc->rl_cdata.rl_rx_buf, M_DEVBUF);
+ bus_dmamem_free(sc->rl_tag,
+ sc->rl_cdata.rl_rx_buf, sc->rl_cdata.rl_rx_dmamap);
+ bus_dma_tag_destroy(sc->rl_tag);
error = ENXIO;
goto fail;
}
@@ -1015,7 +1083,11 @@ static int rl_detach(dev)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
- contigfree(sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN + 32, M_DEVBUF);
+ bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap);
+ bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf,
+ sc->rl_cdata.rl_rx_dmamap);
+ bus_dma_tag_destroy(sc->rl_tag);
+ bus_dma_tag_destroy(sc->rl_parent_tag);
RL_UNLOCK(sc);
mtx_destroy(&sc->rl_mtx);
@@ -1082,6 +1154,9 @@ static void rl_rxeof(sc)
ifp = &sc->arpcom.ac_if;
+ bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap,
+ BUS_DMASYNC_POSTWRITE);
+
cur_rx = (CSR_READ_2(sc, RL_CURRXADDR) + 16) % RL_RXBUFLEN;
/* Do not try to read past this point. */
@@ -1212,6 +1287,8 @@ static void rl_txeof(sc)
ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24;
if (RL_LAST_TXMBUF(sc) != NULL) {
+ bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc));
+ bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc));
m_freem(RL_LAST_TXMBUF(sc));
RL_LAST_TXMBUF(sc) = NULL;
}
@@ -1399,8 +1476,12 @@ static void rl_start(ifp)
/*
* Transmit the frame.
*/
- CSR_WRITE_4(sc, RL_CUR_TXADDR(sc),
- vtophys(mtod(RL_CUR_TXMBUF(sc), caddr_t)));
+ bus_dmamap_create(sc->rl_tag, 0, &RL_CUR_DMAMAP(sc));
+ bus_dmamap_load(sc->rl_tag, RL_CUR_DMAMAP(sc),
+ mtod(RL_CUR_TXMBUF(sc), void *),
+ RL_CUR_TXMBUF(sc)->m_pkthdr.len, rl_dma_map_txbuf, sc, 0);
+ bus_dmamap_sync(sc->rl_tag, RL_CUR_DMAMAP(sc),
+ BUS_DMASYNC_PREREAD);
CSR_WRITE_4(sc, RL_CUR_TXSTAT(sc),
RL_TXTHRESH(sc->rl_txthresh) |
RL_CUR_TXMBUF(sc)->m_pkthdr.len);
@@ -1448,7 +1529,10 @@ static void rl_init(xsc)
}
/* Init the RX buffer pointer register. */
- CSR_WRITE_4(sc, RL_RXADDR, vtophys(sc->rl_cdata.rl_rx_buf));
+ bus_dmamap_load(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap,
+ sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN, rl_dma_map_rxbuf, sc, 0);
+ bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap,
+ BUS_DMASYNC_PREWRITE);
/* Init TX descriptors. */
rl_list_tx_init(sc);
@@ -1639,12 +1723,17 @@ static void rl_stop(sc)
CSR_WRITE_1(sc, RL_COMMAND, 0x00);
CSR_WRITE_2(sc, RL_IMR, 0x0000);
+ bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap);
/*
* Free the TX list buffers.
*/
for (i = 0; i < RL_TX_LIST_CNT; i++) {
if (sc->rl_cdata.rl_tx_chain[i] != NULL) {
+ bus_dmamap_unload(sc->rl_tag,
+ sc->rl_cdata.rl_tx_dmamap[i]);
+ bus_dmamap_destroy(sc->rl_tag,
+ sc->rl_cdata.rl_tx_dmamap[i]);
m_freem(sc->rl_cdata.rl_tx_chain[i]);
sc->rl_cdata.rl_tx_chain[i] = NULL;
CSR_WRITE_4(sc, RL_TXADDR0 + i, 0x0000000);
diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h
index 4e08e164752d..aecc83d7e47f 100644
--- a/sys/pci/if_rlreg.h
+++ b/sys/pci/if_rlreg.h
@@ -303,7 +303,7 @@
#define RL_TXTHRESH(x) ((x) << 11)
#define RL_TX_THRESH_INIT 96
#define RL_RX_FIFOTHRESH RL_RXFIFO_256BYTES
-#define RL_RX_MAXDMA RL_RXDMA_UNLIMITED
+#define RL_RX_MAXDMA RL_RXDMA_1024BYTES /*RL_RXDMA_UNLIMITED*/
#define RL_TX_MAXDMA RL_TXDMA_2048BYTES
#define RL_RXCFG_CONFIG (RL_RX_FIFOTHRESH|RL_RX_MAXDMA|RL_RX_BUF_SZ)
@@ -315,8 +315,10 @@ struct rl_chain_data {
u_int16_t cur_rx;
caddr_t rl_rx_buf;
caddr_t rl_rx_buf_ptr;
+ bus_dmamap_t rl_rx_dmamap;
struct mbuf *rl_tx_chain[RL_TX_LIST_CNT];
+ bus_dmamap_t rl_tx_dmamap[RL_TX_LIST_CNT];
u_int8_t last_tx;
u_int8_t cur_tx;
};
@@ -325,9 +327,11 @@ struct rl_chain_data {
#define RL_CUR_TXADDR(x) ((x->rl_cdata.cur_tx * 4) + RL_TXADDR0)
#define RL_CUR_TXSTAT(x) ((x->rl_cdata.cur_tx * 4) + RL_TXSTAT0)
#define RL_CUR_TXMBUF(x) (x->rl_cdata.rl_tx_chain[x->rl_cdata.cur_tx])
+#define RL_CUR_DMAMAP(x) (x->rl_cdata.rl_tx_dmamap[x->rl_cdata.cur_tx])
#define RL_LAST_TXADDR(x) ((x->rl_cdata.last_tx * 4) + RL_TXADDR0)
#define RL_LAST_TXSTAT(x) ((x->rl_cdata.last_tx * 4) + RL_TXSTAT0)
#define RL_LAST_TXMBUF(x) (x->rl_cdata.rl_tx_chain[x->rl_cdata.last_tx])
+#define RL_LAST_DMAMAP(x) (x->rl_cdata.rl_tx_dmamap[x->rl_cdata.last_tx])
struct rl_type {
u_int16_t rl_vid;
@@ -363,6 +367,8 @@ struct rl_softc {
struct resource *rl_irq;
void *rl_intrhand;
device_t rl_miibus;
+ bus_dma_tag_t rl_parent_tag;
+ bus_dma_tag_t rl_tag;
u_int8_t rl_unit; /* interface number */
u_int8_t rl_type;
int rl_eecmd_read;
@@ -483,8 +489,3 @@ struct rl_softc {
#define RL_PSTATE_D3 0x0003
#define RL_PME_EN 0x0010
#define RL_PME_STATUS 0x8000
-
-#ifdef __alpha__
-#undef vtophys
-#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va)
-#endif
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c
index f4d4ea8ebcd4..0e4f0fe70a8a 100644
--- a/sys/pci/if_sis.c
+++ b/sys/pci/if_sis.c
@@ -73,8 +73,6 @@
#include <net/bpf.h>
-#include <vm/vm.h> /* for vtophys */
-#include <vm/pmap.h> /* for vtophys */
#include <machine/bus_pio.h>
#include <machine/bus_memio.h>
#include <machine/bus.h>
@@ -159,6 +157,12 @@ static void sis_reset __P((struct sis_softc *));
static int sis_list_rx_init __P((struct sis_softc *));
static int sis_list_tx_init __P((struct sis_softc *));
+static void sis_dma_map_desc_ptr __P((void *, bus_dma_segment_t *,
+ int, int));
+static void sis_dma_map_desc_next __P((void *, bus_dma_segment_t *,
+ int, int));
+static void sis_dma_map_ring __P((void *, bus_dma_segment_t *,
+ int, int));
#ifdef SIS_USEIOSPACE
#define SIS_RES SYS_RES_IOPORT
#define SIS_RID SIS_PCI_LOIO
@@ -211,6 +215,48 @@ DRIVER_MODULE(miibus, sis, miibus_driver, miibus_devclass, 0, 0);
#define SIO_CLR(x) \
CSR_WRITE_4(sc, SIS_EECTL, CSR_READ_4(sc, SIS_EECTL) & ~x)
+static void
+sis_dma_map_desc_next(arg, segs, nseg, error)
+ void *arg;
+ bus_dma_segment_t *segs;
+ int nseg, error;
+{
+ struct sis_desc *r;
+
+ r = arg;
+ r->sis_next = segs->ds_addr;
+
+ return;
+}
+
+static void
+sis_dma_map_desc_ptr(arg, segs, nseg, error)
+ void *arg;
+ bus_dma_segment_t *segs;
+ int nseg, error;
+{
+ struct sis_desc *r;
+
+ r = arg;
+ r->sis_ptr = segs->ds_addr;
+
+ return;
+}
+
+static void
+sis_dma_map_ring(arg, segs, nseg, error)
+ void *arg;
+ bus_dma_segment_t *segs;
+ int nseg, error;
+{
+ u_int32_t *p;
+
+ p = arg;
+ *p = segs->ds_addr;
+
+ return;
+}
+
/*
* Routine to reverse the bits in a word. Stolen almost
* verbatim from /usr/games/fortune.
@@ -890,18 +936,107 @@ static int sis_attach(dev)
callout_handle_init(&sc->sis_stat_ch);
bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
- sc->sis_ldata = contigmalloc(sizeof(struct sis_list_data), M_DEVBUF,
- M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
+ /*
+ * Allocate the parent bus DMA tag appropriate for PCI.
+ */
+#define SIS_NSEG_NEW 32
+ error = bus_dma_tag_create(NULL, /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MAXBSIZE, SIS_NSEG_NEW, /* maxsize, nsegments */
+ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
+ BUS_DMA_ALLOCNOW, /* flags */
+ &sc->sis_parent_tag);
+
+ /*
+ * Now allocate a tag for the DMA descriptor lists.
+ * All of our lists are allocated as a contiguous block
+ * of memory.
+ */
+ error = bus_dma_tag_create(sc->sis_parent_tag, /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ SIS_RX_LIST_SZ, 1, /* maxsize,nsegments */
+ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
+ 0, /* flags */
+ &sc->sis_ldata.sis_rx_tag);
+
+ error = bus_dma_tag_create(sc->sis_parent_tag, /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ SIS_TX_LIST_SZ, 1, /* maxsize,nsegments */
+ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
+ 0, /* flags */
+ &sc->sis_ldata.sis_tx_tag);
+
+ error = bus_dma_tag_create(sc->sis_parent_tag, /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ SIS_TX_LIST_SZ, 1, /* maxsize,nsegments */
+ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
+ 0, /* flags */
+ &sc->sis_tag);
+
+ /*
+ * Now allocate a chunk of DMA-able memory based on the
+ * tag we just created.
+ */
+ error = bus_dmamem_alloc(sc->sis_ldata.sis_tx_tag,
+ (void **)&sc->sis_ldata.sis_tx_list, BUS_DMA_NOWAIT,
+ &sc->sis_ldata.sis_tx_dmamap);
+
+ if (error) {
+ printf("sis%d: no memory for list buffers!\n", unit);
+ bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
+ bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
+ error = ENXIO;
+ goto fail;
+ }
+
+ error = bus_dmamem_alloc(sc->sis_ldata.sis_rx_tag,
+ (void **)&sc->sis_ldata.sis_rx_list, BUS_DMA_NOWAIT,
+ &sc->sis_ldata.sis_rx_dmamap);
- if (sc->sis_ldata == NULL) {
+ if (error) {
printf("sis%d: no memory for list buffers!\n", unit);
bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
+ bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
error = ENXIO;
goto fail;
}
- bzero(sc->sis_ldata, sizeof(struct sis_list_data));
+
+
+ bzero(sc->sis_ldata.sis_tx_list, SIS_TX_LIST_SZ);
+ bzero(sc->sis_ldata.sis_rx_list, SIS_RX_LIST_SZ);
+
+ /*
+ * Obtain the physical addresses of the RX and TX
+ * rings which we'll need later in the init routine.
+ */
+ bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
+ sc->sis_ldata.sis_tx_dmamap, &(sc->sis_ldata.sis_tx_list[0]),
+ sizeof(struct sis_desc), sis_dma_map_ring,
+ &sc->sis_cdata.sis_tx_paddr, 0);
+ bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_dmamap, &(sc->sis_ldata.sis_rx_list[0]),
+ sizeof(struct sis_desc), sis_dma_map_ring,
+ &sc->sis_cdata.sis_rx_paddr, 0);
ifp = &sc->arpcom.ac_if;
ifp->if_softc = sc;
@@ -926,6 +1061,12 @@ static int sis_attach(dev)
bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
+ bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
+ bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
error = ENXIO;
goto fail;
}
@@ -966,7 +1107,17 @@ static int sis_detach(dev)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
- contigfree(sc->sis_ldata, sizeof(struct sis_list_data), M_DEVBUF);
+ bus_dmamap_unload(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_dmamap);
+ bus_dmamap_unload(sc->sis_ldata.sis_tx_tag,
+ sc->sis_ldata.sis_tx_dmamap);
+ bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
+ bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
+ bus_dma_tag_destroy(sc->sis_parent_tag);
SIS_UNLOCK(sc);
mtx_destroy(&sc->sis_mtx);
@@ -985,19 +1136,23 @@ static int sis_list_tx_init(sc)
int i;
cd = &sc->sis_cdata;
- ld = sc->sis_ldata;
+ ld = &sc->sis_ldata;
for (i = 0; i < SIS_TX_LIST_CNT; i++) {
if (i == (SIS_TX_LIST_CNT - 1)) {
ld->sis_tx_list[i].sis_nextdesc =
&ld->sis_tx_list[0];
- ld->sis_tx_list[i].sis_next =
- vtophys(&ld->sis_tx_list[0]);
+ bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
+ sc->sis_ldata.sis_tx_dmamap, &ld->sis_tx_list[0],
+ sizeof(struct sis_desc), sis_dma_map_desc_next,
+ &ld->sis_tx_list[i], 0);
} else {
ld->sis_tx_list[i].sis_nextdesc =
&ld->sis_tx_list[i + 1];
- ld->sis_tx_list[i].sis_next =
- vtophys(&ld->sis_tx_list[i + 1]);
+ bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
+ sc->sis_ldata.sis_tx_dmamap,
+ &ld->sis_tx_list[i + 1], sizeof(struct sis_desc),
+ sis_dma_map_desc_next, &ld->sis_tx_list[i], 0);
}
ld->sis_tx_list[i].sis_mbuf = NULL;
ld->sis_tx_list[i].sis_ptr = 0;
@@ -1006,10 +1161,12 @@ static int sis_list_tx_init(sc)
cd->sis_tx_prod = cd->sis_tx_cons = cd->sis_tx_cnt = 0;
+ bus_dmamap_sync(sc->sis_ldata.sis_tx_tag,
+ sc->sis_ldata.sis_rx_dmamap, BUS_DMASYNC_PREWRITE);
+
return(0);
}
-
/*
* Initialize the RX descriptors and allocate mbufs for them. Note that
* we arrange the descriptors in a closed ring, so that the last descriptor
@@ -1022,7 +1179,7 @@ static int sis_list_rx_init(sc)
struct sis_ring_data *cd;
int i;
- ld = sc->sis_ldata;
+ ld = &sc->sis_ldata;
cd = &sc->sis_cdata;
for (i = 0; i < SIS_RX_LIST_CNT; i++) {
@@ -1031,16 +1188,25 @@ static int sis_list_rx_init(sc)
if (i == (SIS_RX_LIST_CNT - 1)) {
ld->sis_rx_list[i].sis_nextdesc =
&ld->sis_rx_list[0];
- ld->sis_rx_list[i].sis_next =
- vtophys(&ld->sis_rx_list[0]);
+ bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_dmamap, &ld->sis_rx_list[0],
+ sizeof(struct sis_desc), sis_dma_map_desc_next,
+ &ld->sis_rx_list[i], 0);
+
} else {
ld->sis_rx_list[i].sis_nextdesc =
&ld->sis_rx_list[i + 1];
- ld->sis_rx_list[i].sis_next =
- vtophys(&ld->sis_rx_list[i + 1]);
+ bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_dmamap,
+ &ld->sis_rx_list[i + 1],
+ sizeof(struct sis_desc), sis_dma_map_desc_next,
+ &ld->sis_rx_list[i], 0);
}
}
+ bus_dmamap_sync(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_dmamap, BUS_DMASYNC_PREWRITE);
+
cd->sis_rx_prod = 0;
return(0);
@@ -1056,6 +1222,9 @@ static int sis_newbuf(sc, c, m)
{
struct mbuf *m_new = NULL;
+ if (c == NULL)
+ return(EINVAL);
+
if (m == NULL) {
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
if (m_new == NULL) {
@@ -1081,9 +1250,14 @@ static int sis_newbuf(sc, c, m)
m_adj(m_new, sizeof(u_int64_t));
c->sis_mbuf = m_new;
- c->sis_ptr = vtophys(mtod(m_new, caddr_t));
c->sis_ctl = SIS_RXLEN;
+ bus_dmamap_create(sc->sis_tag, 0, &c->sis_map);
+ bus_dmamap_load(sc->sis_tag, c->sis_map,
+ mtod(m_new, void *), m_new->m_len,
+ sis_dma_map_desc_ptr, c, 0);
+ bus_dmamap_sync(sc->sis_tag, c->sis_map, BUS_DMASYNC_PREWRITE);
+
return(0);
}
@@ -1104,11 +1278,15 @@ static void sis_rxeof(sc)
ifp = &sc->arpcom.ac_if;
i = sc->sis_cdata.sis_rx_prod;
- while(SIS_OWNDESC(&sc->sis_ldata->sis_rx_list[i])) {
+ while(SIS_OWNDESC(&sc->sis_ldata.sis_rx_list[i])) {
struct mbuf *m0 = NULL;
- cur_rx = &sc->sis_ldata->sis_rx_list[i];
+ cur_rx = &sc->sis_ldata.sis_rx_list[i];
rxstat = cur_rx->sis_rxstat;
+ bus_dmamap_sync(sc->sis_tag,
+ cur_rx->sis_map, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->sis_tag, cur_rx->sis_map);
+ bus_dmamap_destroy(sc->sis_tag, cur_rx->sis_map);
m = cur_rx->sis_mbuf;
cur_rx->sis_mbuf = NULL;
total_len = SIS_RXBYTES(cur_rx);
@@ -1182,7 +1360,7 @@ static void sis_txeof(sc)
*/
idx = sc->sis_cdata.sis_tx_cons;
while (idx != sc->sis_cdata.sis_tx_prod) {
- cur_tx = &sc->sis_ldata->sis_tx_list[idx];
+ cur_tx = &sc->sis_ldata.sis_tx_list[idx];
if (SIS_OWNDESC(cur_tx))
break;
@@ -1208,6 +1386,8 @@ static void sis_txeof(sc)
if (cur_tx->sis_mbuf != NULL) {
m_freem(cur_tx->sis_mbuf);
cur_tx->sis_mbuf = NULL;
+ bus_dmamap_unload(sc->sis_tag, cur_tx->sis_map);
+ bus_dmamap_destroy(sc->sis_tag, cur_tx->sis_map);
}
sc->sis_cdata.sis_tx_cnt--;
@@ -1339,9 +1519,14 @@ static int sis_encap(sc, m_head, txidx)
if ((SIS_TX_LIST_CNT -
(sc->sis_cdata.sis_tx_cnt + cnt)) < 2)
return(ENOBUFS);
- f = &sc->sis_ldata->sis_tx_list[frag];
+ f = &sc->sis_ldata.sis_tx_list[frag];
f->sis_ctl = SIS_CMDSTS_MORE | m->m_len;
- f->sis_ptr = vtophys(mtod(m, vm_offset_t));
+ bus_dmamap_create(sc->sis_tag, 0, &f->sis_map);
+ bus_dmamap_load(sc->sis_tag, f->sis_map,
+ mtod(m, void *), m->m_len,
+ sis_dma_map_desc_ptr, f, 0);
+ bus_dmamap_sync(sc->sis_tag,
+ f->sis_map, BUS_DMASYNC_PREREAD);
if (cnt != 0)
f->sis_ctl |= SIS_CMDSTS_OWN;
cur = frag;
@@ -1353,9 +1538,9 @@ static int sis_encap(sc, m_head, txidx)
if (m != NULL)
return(ENOBUFS);
- sc->sis_ldata->sis_tx_list[cur].sis_mbuf = m_head;
- sc->sis_ldata->sis_tx_list[cur].sis_ctl &= ~SIS_CMDSTS_MORE;
- sc->sis_ldata->sis_tx_list[*txidx].sis_ctl |= SIS_CMDSTS_OWN;
+ sc->sis_ldata.sis_tx_list[cur].sis_mbuf = m_head;
+ sc->sis_ldata.sis_tx_list[cur].sis_ctl &= ~SIS_CMDSTS_MORE;
+ sc->sis_ldata.sis_tx_list[*txidx].sis_ctl |= SIS_CMDSTS_OWN;
sc->sis_cdata.sis_tx_cnt += cnt;
*txidx = frag;
@@ -1391,7 +1576,7 @@ static void sis_start(ifp)
return;
}
- while(sc->sis_ldata->sis_tx_list[idx].sis_mbuf == NULL) {
+ while(sc->sis_ldata.sis_tx_list[idx].sis_mbuf == NULL) {
IF_DEQUEUE(&ifp->if_snd, m_head);
if (m_head == NULL)
break;
@@ -1519,10 +1704,8 @@ static void sis_init(xsc)
/*
* Load the address of the RX and TX lists.
*/
- CSR_WRITE_4(sc, SIS_RX_LISTPTR,
- vtophys(&sc->sis_ldata->sis_rx_list[0]));
- CSR_WRITE_4(sc, SIS_TX_LISTPTR,
- vtophys(&sc->sis_ldata->sis_tx_list[0]));
+ CSR_WRITE_4(sc, SIS_RX_LISTPTR, sc->sis_cdata.sis_rx_paddr);
+ CSR_WRITE_4(sc, SIS_TX_LISTPTR, sc->sis_cdata.sis_tx_paddr);
/* Set RX configuration */
CSR_WRITE_4(sc, SIS_RX_CFG, SIS_RXCFG);
@@ -1637,8 +1820,6 @@ static int sis_ioctl(ifp, command, data)
struct mii_data *mii;
int error = 0;
- SIS_LOCK(sc);
-
switch(command) {
case SIOCSIFADDR:
case SIOCGIFADDR:
@@ -1656,24 +1837,26 @@ static int sis_ioctl(ifp, command, data)
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
+ SIS_LOCK(sc);
if (sc->sis_type == SIS_TYPE_83815)
sis_setmulti_ns(sc);
else
sis_setmulti_sis(sc);
+ SIS_UNLOCK(sc);
error = 0;
break;
case SIOCGIFMEDIA:
case SIOCSIFMEDIA:
mii = device_get_softc(sc->sis_miibus);
+ SIS_LOCK(sc);
error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
+ SIS_UNLOCK(sc);
break;
default:
error = EINVAL;
break;
}
- SIS_UNLOCK(sc);
-
return(error);
}
@@ -1729,26 +1912,34 @@ static void sis_stop(sc)
* Free data in the RX lists.
*/
for (i = 0; i < SIS_RX_LIST_CNT; i++) {
- if (sc->sis_ldata->sis_rx_list[i].sis_mbuf != NULL) {
- m_freem(sc->sis_ldata->sis_rx_list[i].sis_mbuf);
- sc->sis_ldata->sis_rx_list[i].sis_mbuf = NULL;
+ if (sc->sis_ldata.sis_rx_list[i].sis_mbuf != NULL) {
+ bus_dmamap_unload(sc->sis_tag,
+ sc->sis_ldata.sis_rx_list[i].sis_map);
+ bus_dmamap_destroy(sc->sis_tag,
+ sc->sis_ldata.sis_rx_list[i].sis_map);
+ m_freem(sc->sis_ldata.sis_rx_list[i].sis_mbuf);
+ sc->sis_ldata.sis_rx_list[i].sis_mbuf = NULL;
}
}
- bzero((char *)&sc->sis_ldata->sis_rx_list,
- sizeof(sc->sis_ldata->sis_rx_list));
+ bzero(sc->sis_ldata.sis_rx_list,
+ sizeof(sc->sis_ldata.sis_rx_list));
/*
* Free the TX list buffers.
*/
for (i = 0; i < SIS_TX_LIST_CNT; i++) {
- if (sc->sis_ldata->sis_tx_list[i].sis_mbuf != NULL) {
- m_freem(sc->sis_ldata->sis_tx_list[i].sis_mbuf);
- sc->sis_ldata->sis_tx_list[i].sis_mbuf = NULL;
+ if (sc->sis_ldata.sis_tx_list[i].sis_mbuf != NULL) {
+ bus_dmamap_unload(sc->sis_tag,
+ sc->sis_ldata.sis_tx_list[i].sis_map);
+ bus_dmamap_destroy(sc->sis_tag,
+ sc->sis_ldata.sis_tx_list[i].sis_map);
+ m_freem(sc->sis_ldata.sis_tx_list[i].sis_mbuf);
+ sc->sis_ldata.sis_tx_list[i].sis_mbuf = NULL;
}
}
- bzero((char *)&sc->sis_ldata->sis_tx_list,
- sizeof(sc->sis_ldata->sis_tx_list));
+ bzero(sc->sis_ldata.sis_tx_list,
+ sizeof(sc->sis_ldata.sis_tx_list));
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
diff --git a/sys/pci/if_sisreg.h b/sys/pci/if_sisreg.h
index 10cc02fab706..21cb22af8608 100644
--- a/sys/pci/if_sisreg.h
+++ b/sys/pci/if_sisreg.h
@@ -294,6 +294,7 @@ struct sis_desc {
/* Driver software section */
struct mbuf *sis_mbuf;
struct sis_desc *sis_nextdesc;
+ bus_dmamap_t sis_map;
};
#define SIS_CMDSTS_BUFLEN 0x00000FFF
@@ -336,9 +337,20 @@ struct sis_desc {
#define SIS_RX_LIST_CNT 64
#define SIS_TX_LIST_CNT 128
+#define SIS_RX_LIST_SZ SIS_RX_LIST_CNT * sizeof(struct sis_desc)
+#define SIS_TX_LIST_SZ SIS_TX_LIST_CNT * sizeof(struct sis_desc)
+
struct sis_list_data {
+#ifdef foo
struct sis_desc sis_rx_list[SIS_RX_LIST_CNT];
struct sis_desc sis_tx_list[SIS_TX_LIST_CNT];
+#endif
+ struct sis_desc *sis_rx_list;
+ struct sis_desc *sis_tx_list;
+ bus_dma_tag_t sis_rx_tag;
+ bus_dmamap_t sis_rx_dmamap;
+ bus_dma_tag_t sis_tx_tag;
+ bus_dmamap_t sis_tx_dmamap;
};
struct sis_ring_data {
@@ -346,6 +358,8 @@ struct sis_ring_data {
int sis_tx_prod;
int sis_tx_cons;
int sis_tx_cnt;
+ u_int32_t sis_rx_paddr;
+ u_int32_t sis_tx_paddr;
};
@@ -398,7 +412,9 @@ struct sis_softc {
u_int8_t sis_unit;
u_int8_t sis_type;
u_int8_t sis_link;
- struct sis_list_data *sis_ldata;
+ struct sis_list_data sis_ldata;
+ bus_dma_tag_t sis_parent_tag;
+ bus_dma_tag_t sis_tag;
struct sis_ring_data sis_cdata;
struct callout_handle sis_stat_ch;
struct mtx sis_mtx;
@@ -458,8 +474,3 @@ struct sis_softc {
#define SIS_PSTATE_D3 0x0003
#define SIS_PME_EN 0x0010
#define SIS_PME_STATUS 0x8000
-
-#ifdef __alpha__
-#undef vtophys
-#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va)
-#endif