diff options
| author | Bill Paul <wpaul@FreeBSD.org> | 2001-08-15 17:38:43 +0000 |
|---|---|---|
| committer | Bill Paul <wpaul@FreeBSD.org> | 2001-08-15 17:38:43 +0000 |
| commit | 0219a4215565cddeb1e24915d291bbb42181ed7c (patch) | |
| tree | d02c2e7dcb5460927414e17349bd92e6b0abbd0a /sys | |
| parent | 4559d1c897e097b601a4d39ab339eda3efc2b916 (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/pci/if_rl.c | 107 | ||||
| -rw-r--r-- | sys/pci/if_rlreg.h | 13 | ||||
| -rw-r--r-- | sys/pci/if_sis.c | 283 | ||||
| -rw-r--r-- | sys/pci/if_sisreg.h | 23 |
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 |
