From 4ddeda6c041ac9f8d0e5b422c600fb0591ccfb5d Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Thu, 1 Apr 2004 16:24:57 +0000 Subject: [PATCH] Convert sis(4) from vtophys to busdma. Obtained-from: FreeBSD 5 --- sys/dev/netif/sis/if_sis.c | 367 +++++++++++++++++++++++++--------- sys/dev/netif/sis/if_sisreg.h | 27 ++- 2 files changed, 289 insertions(+), 105 deletions(-) diff --git a/sys/dev/netif/sis/if_sis.c b/sys/dev/netif/sis/if_sis.c index 192112fc6d..d2cac49030 100644 --- a/sys/dev/netif/sis/if_sis.c +++ b/sys/dev/netif/sis/if_sis.c @@ -30,7 +30,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/pci/if_sis.c,v 1.13.4.24 2003/03/05 18:42:33 njl Exp $ - * $DragonFly: src/sys/dev/netif/sis/if_sis.c,v 1.10 2004/03/23 22:19:03 hsu Exp $ + * $DragonFly: src/sys/dev/netif/sis/if_sis.c,v 1.11 2004/04/01 16:24:57 joerg Exp $ * * $FreeBSD: src/sys/pci/if_sis.c,v 1.13.4.24 2003/03/05 18:42:33 njl Exp $ */ @@ -79,9 +79,6 @@ #include -#include /* for vtophys */ -#include /* for vtophys */ -#include /* for DELAY */ #include #include #include @@ -159,6 +156,10 @@ static uint32_t sis_mchash(struct sis_softc *, const uint8_t *); static void sis_reset(struct sis_softc *); static int sis_list_rx_init(struct sis_softc *); static int sis_list_tx_init(struct sis_softc *); + +static void sis_dma_map_desc_ptr(void *, bus_dma_segment_t *, int, int); +static void sis_dma_map_desc_next(void *, bus_dma_segment_t *, int, int); +static void sis_dma_map_ring(void *, bus_dma_segment_t *, int, int); #ifdef SIS_USEIOSPACE #define SIS_RES SYS_RES_IOPORT #define SIS_RID SIS_PCI_LOIO @@ -210,6 +211,33 @@ 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(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + struct sis_desc *r; + + r = arg; + r->sis_next = segs->ds_addr; +} + +static void +sis_dma_map_desc_ptr(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + struct sis_desc *r; + + r = arg; + r->sis_ptr = segs->ds_addr; +} + +static void +sis_dma_map_ring(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + uint32_t *p; + + p = arg; + *p = segs->ds_addr; +} + /* * Routine to reverse the bits in a word. Stolen almost * verbatim from /usr/games/fortune. @@ -926,15 +954,12 @@ sis_probe(device_t dev) static int sis_attach(device_t dev) { - int s; uint8_t eaddr[ETHER_ADDR_LEN]; uint32_t command; struct sis_softc *sc; struct ifnet *ifp; int unit, error, rid, waittime; - s = splimp(); - error = waittime = 0; sc = device_get_softc(dev); unit = device_get_unit(dev); @@ -1020,21 +1045,10 @@ sis_attach(device_t dev) if (sc->sis_irq == NULL) { printf("sis%d: couldn't map interrupt\n", unit); - bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res); error = ENXIO; goto fail; } - error = bus_setup_intr(dev, sc->sis_irq, INTR_TYPE_NET, - sis_intr, sc, &sc->sis_intrhand); - - if (error) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq); - bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res); - printf("sis%d: couldn't set up irq\n", unit); - goto fail; - } - /* Reset the adapter. */ sis_reset(sc); @@ -1150,18 +1164,119 @@ sis_attach(device_t dev) sc->sis_unit = unit; callout_handle_init(&sc->sis_stat_ch); - 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); + if (error) + goto fail; - if (sc->sis_ldata == NULL) { - 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); - error = ENXIO; + /* + * Now allocate a tag for the DMA descriptor lists and a chunk + * of DMA-able memory based on the tag. Also obtain the physical + * addresses of the RX and TX ring, which we'll need later. + * 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); + if (error) + goto fail; + + error = bus_dmamem_alloc(sc->sis_ldata.sis_rx_tag, + (void **)&sc->sis_ldata.sis_rx_list, + BUS_DMA_WAITOK | BUS_DMA_ZERO, + &sc->sis_ldata.sis_rx_dmamap); + + if (error) { + device_printf(dev, "no memory for rx list buffers!\n"); + bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag); + sc->sis_ldata.sis_rx_tag = NULL; + goto fail; + } + + error = bus_dmamap_load(sc->sis_ldata.sis_rx_tag, + sc->sis_ldata.sis_rx_dmamap, + sc->sis_ldata.sis_rx_list, + sizeof(struct sis_desc), sis_dma_map_ring, + &sc->sis_cdata.sis_rx_paddr, 0); + + if (error) { + device_printf(dev, "cannot get address of the rx ring!\n"); + bus_dmamem_free(sc->sis_ldata.sis_rx_tag, + sc->sis_ldata.sis_rx_list, + sc->sis_ldata.sis_rx_dmamap); + bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag); + sc->sis_ldata.sis_rx_tag = NULL; + goto fail; + } + + 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); + if (error) + goto fail; + + error = bus_dmamem_alloc(sc->sis_ldata.sis_tx_tag, + (void **)&sc->sis_ldata.sis_tx_list, + BUS_DMA_WAITOK | BUS_DMA_ZERO, + &sc->sis_ldata.sis_tx_dmamap); + + if (error) { + device_printf(dev, "no memory for tx list buffers!\n"); + bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag); + sc->sis_ldata.sis_tx_tag = NULL; + goto fail; + } + + error = bus_dmamap_load(sc->sis_ldata.sis_tx_tag, + sc->sis_ldata.sis_tx_dmamap, + sc->sis_ldata.sis_tx_list, + sizeof(struct sis_desc), sis_dma_map_ring, + &sc->sis_cdata.sis_tx_paddr, 0); + + if (error) { + device_printf(dev, "cannot get address of the tx ring!\n"); + bus_dmamem_free(sc->sis_ldata.sis_tx_tag, + sc->sis_ldata.sis_tx_list, + sc->sis_ldata.sis_tx_dmamap); + bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag); + sc->sis_ldata.sis_tx_tag = NULL; goto fail; } - bzero(sc->sis_ldata, sizeof(struct sis_list_data)); + + 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 */ + MCLBYTES, 1, /* maxsize, nsegments */ + BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ + 0, /* flags */ + &sc->sis_tag); + if (error) + goto fail; ifp = &sc->arpcom.ac_if; ifp->if_softc = sc; @@ -1181,12 +1296,7 @@ sis_attach(device_t dev) */ if (mii_phy_probe(dev, &sc->sis_miibus, sis_ifmedia_upd, sis_ifmedia_sts)) { - printf("sis%d: MII without any PHY!\n", sc->sis_unit); - contigfree(sc->sis_ldata, sizeof(struct sis_list_data), - M_DEVBUF); - 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); + device_printf(dev, "MII without any PHY!\n"); error = ENXIO; goto fail; } @@ -1203,11 +1313,27 @@ sis_attach(device_t dev) callout_handle_init(&sc->sis_stat_ch); + error = bus_setup_intr(dev, sc->sis_irq, INTR_TYPE_NET, + sis_intr, sc, &sc->sis_intrhand); + + if (error) { + device_printf(dev, "couldn't set up irq\n"); + ether_ifdetach(ifp); + goto fail; + } + fail: - splx(s); + if (error) + sis_detach(dev); + return(error); } +/* + * Shutdown hardware and free up resources. It is called in both the error case + * and the normal detach case so it needs to be careful about only freeing + * resources that have actually been allocated. + */ static int sis_detach(device_t dev) { @@ -1220,18 +1346,43 @@ sis_detach(device_t dev) sc = device_get_softc(dev); ifp = &sc->arpcom.ac_if; - sis_reset(sc); - sis_stop(sc); - ether_ifdetach(ifp); - + if (device_is_attached(dev)) { + sis_reset(sc); + sis_stop(sc); + ether_ifdetach(ifp); + } + if (sc->sis_miibus) + device_delete_child(dev, sc->sis_miibus); bus_generic_detach(dev); - device_delete_child(dev, sc->sis_miibus); - 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); + if (sc->sis_intrhand) + bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand); + if (sc->sis_irq) + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq); + if (sc->sis_res) + bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res); - contigfree(sc->sis_ldata, sizeof(struct sis_list_data), M_DEVBUF); + if (sc->sis_ldata.sis_rx_tag) { + bus_dmamap_unload(sc->sis_ldata.sis_rx_tag, + sc->sis_ldata.sis_rx_dmamap); + bus_dmamem_free(sc->sis_ldata.sis_rx_tag, + sc->sis_ldata.sis_rx_list, + sc->sis_ldata.sis_rx_dmamap); + bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag); + } + + if (sc->sis_ldata.sis_tx_tag) { + bus_dmamap_unload(sc->sis_ldata.sis_tx_tag, + sc->sis_ldata.sis_tx_dmamap); + bus_dmamem_free(sc->sis_ldata.sis_tx_tag, + sc->sis_ldata.sis_tx_list, + sc->sis_ldata.sis_tx_dmamap); + bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag); + } + if (sc->sis_tag) + bus_dma_tag_destroy(sc->sis_tag); + if (sc->sis_parent_tag) + bus_dma_tag_destroy(sc->sis_parent_tag); splx(s); @@ -1249,14 +1400,17 @@ sis_list_tx_init(struct sis_softc *sc) int i, nexti; cd = &sc->sis_cdata; - ld = sc->sis_ldata; + ld = &sc->sis_ldata; for (i = 0; i < SIS_TX_LIST_CNT; i++) { nexti = (i == (SIS_TX_LIST_CNT - 1)) ? 0 : i+1; ld->sis_tx_list[i].sis_nextdesc = &ld->sis_tx_list[nexti]; - ld->sis_tx_list[i].sis_next = - vtophys(&ld->sis_tx_list[nexti]); + bus_dmamap_load(sc->sis_ldata.sis_tx_tag, + sc->sis_ldata.sis_tx_dmamap, + &ld->sis_tx_list[nexti], + 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; ld->sis_tx_list[i].sis_ctl = 0; @@ -1264,6 +1418,9 @@ sis_list_tx_init(struct sis_softc *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_tx_dmamap, + BUS_DMASYNC_PREWRITE); + return(0); } @@ -1279,7 +1436,7 @@ sis_list_rx_init(struct sis_softc *sc) struct sis_ring_data *cd; int i, nexti; - ld = sc->sis_ldata; + ld = &sc->sis_ldata; cd = &sc->sis_cdata; for (i = 0; i < SIS_RX_LIST_CNT; i++) { @@ -1288,10 +1445,16 @@ sis_list_rx_init(struct sis_softc *sc) nexti = (i == (SIS_RX_LIST_CNT - 1)) ? 0 : i+1; ld->sis_rx_list[i].sis_nextdesc = &ld->sis_rx_list[nexti]; - ld->sis_rx_list[i].sis_next = - vtophys(&ld->sis_rx_list[nexti]); + bus_dmamap_load(sc->sis_ldata.sis_rx_tag, + sc->sis_ldata.sis_rx_dmamap, + &ld->sis_rx_list[nexti], + 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); @@ -1312,9 +1475,13 @@ sis_newbuf(struct sis_softc *sc, struct sis_desc *c, struct mbuf *m) } c->sis_mbuf = m; - c->sis_ptr = vtophys(mtod(m, 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, void *), MCLBYTES, + sis_dma_map_desc_ptr, c, 0); + bus_dmamap_sync(sc->sis_tag, c->sis_map, BUS_DMASYNC_PREWRITE); + return(0); } @@ -1334,7 +1501,7 @@ sis_rxeof(struct sis_softc *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])) { #ifdef DEVICE_POLLING if (ifp->if_ipending & IFF_POLLING) { @@ -1343,8 +1510,12 @@ sis_rxeof(struct sis_softc *sc) sc->rxcycles--; } #endif /* DEVICE_POLLING */ - 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); @@ -1403,7 +1574,7 @@ static void sis_rxeoc(struct sis_softc *sc) { sis_rxeof(sc); - /* sis_init(sc); */ + sis_init(sc); } /* @@ -1414,7 +1585,7 @@ sis_rxeoc(struct sis_softc *sc) static void sis_txeof(struct sis_softc *sc) { - struct sis_desc *cur_tx = NULL; + struct sis_desc *cur_tx; struct ifnet *ifp; uint32_t idx; @@ -1424,18 +1595,15 @@ sis_txeof(struct sis_softc *sc) * Go through our tx list and free mbufs for those * frames that have been transmitted. */ - idx = sc->sis_cdata.sis_tx_cons; - while (idx != sc->sis_cdata.sis_tx_prod) { - cur_tx = &sc->sis_ldata->sis_tx_list[idx]; + for (idx = sc->sis_cdata.sis_tx_cons; sc->sis_cdata.sis_tx_cnt > 0; + sc->sis_cdata.sis_tx_cnt--, SIS_INC(idx, SIS_TX_LIST_CNT) ) { + cur_tx = &sc->sis_ldata.sis_tx_list[idx]; if (SIS_OWNDESC(cur_tx)) break; - if (cur_tx->sis_ctl & SIS_CMDSTS_MORE) { - sc->sis_cdata.sis_tx_cnt--; - SIS_INC(idx, SIS_TX_LIST_CNT); + if (cur_tx->sis_ctl & SIS_CMDSTS_MORE) continue; - } if (!(cur_tx->sis_ctl & SIS_CMDSTS_PKT_OK)) { ifp->if_oerrors++; @@ -1452,14 +1620,13 @@ sis_txeof(struct sis_softc *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--; - SIS_INC(idx, SIS_TX_LIST_CNT); - ifp->if_timer = 0; } if (idx != sc->sis_cdata.sis_tx_cons) { + /* we freed up some buffers */ sc->sis_cdata.sis_tx_cons = idx; ifp->if_flags &= ~IFF_OACTIVE; } @@ -1618,6 +1785,12 @@ sis_encap(struct sis_softc *sc, struct mbuf *m_head, uint32_t *txidx) struct mbuf *m; int frag, cur, cnt = 0; + /* + * If there's no way we can send any packets, return now. + */ + if (SIS_TX_LIST_CNT - sc->sis_cdata.sis_tx_cnt < 2) + return (ENOBUFS); + /* * Start packing the mbufs in this chain into * the fragment pointers. Stop when we run out @@ -1631,9 +1804,14 @@ sis_encap(struct sis_softc *sc, struct mbuf *m_head, uint32_t *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; @@ -1645,9 +1823,9 @@ sis_encap(struct sis_softc *sc, struct mbuf *m_head, uint32_t *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; @@ -1678,7 +1856,7 @@ sis_start(struct ifnet *ifp) if (ifp->if_flags & IFF_OACTIVE) 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; @@ -1799,10 +1977,8 @@ sis_init(void *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); /* SIS_CFG_EDB_MASTER_EN indicates the EDB bus is used instead of * the PCI bus. When this bit is set, the Max DMA Burst Size @@ -1927,14 +2103,7 @@ sis_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr) struct mii_data *mii; int s, error = 0; - s = splimp(); - switch(command) { - case SIOCSIFADDR: - case SIOCGIFADDR: - case SIOCSIFMTU: - error = ether_ioctl(ifp, command, data); - break; case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { sis_init(sc); @@ -1946,24 +2115,26 @@ sis_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr) break; case SIOCADDMULTI: case SIOCDELMULTI: + s = splimp(); if (sc->sis_type == SIS_TYPE_83815) sis_setmulti_ns(sc); else sis_setmulti_sis(sc); + splx(s); error = 0; break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: mii = device_get_softc(sc->sis_miibus); + s = splimp(); error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); + splx(s); break; default: - error = EINVAL; + error = ether_ioctl(ifp, command, data); break; } - splx(s); - return(error); } @@ -2017,26 +2188,32 @@ sis_stop(struct sis_softc *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)); } /* diff --git a/sys/dev/netif/sis/if_sisreg.h b/sys/dev/netif/sis/if_sisreg.h index 448f166228..69a6a848d4 100644 --- a/sys/dev/netif/sis/if_sisreg.h +++ b/sys/dev/netif/sis/if_sisreg.h @@ -30,7 +30,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/pci/if_sisreg.h,v 1.1.4.11 2003/02/05 21:49:01 mbr Exp $ - * $DragonFly: src/sys/dev/netif/sis/if_sisreg.h,v 1.3 2004/03/16 22:48:00 joerg Exp $ + * $DragonFly: src/sys/dev/netif/sis/if_sisreg.h,v 1.4 2004/04/01 16:24:57 joerg Exp $ */ /* @@ -315,6 +315,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 @@ -326,7 +327,7 @@ struct sis_desc { #define SIS_LASTDESC(x) (!((x)->sis_ctl & SIS_CMDSTS_MORE))) #define SIS_OWNDESC(x) ((x)->sis_ctl & SIS_CMDSTS_OWN) -#define SIS_INC(x, y) { if (++(x) == y) x=0 ; } +#define SIS_INC(x, y) (x) = ((x) == ((y)-1)) ? 0 : (x)+1 #define SIS_RXBYTES(x) (((x)->sis_ctl & SIS_CMDSTS_BUFLEN) - ETHER_CRC_LEN) #define SIS_RXSTAT_COLL 0x00010000 @@ -357,9 +358,16 @@ 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 { - struct sis_desc sis_rx_list[SIS_RX_LIST_CNT]; - struct sis_desc sis_tx_list[SIS_TX_LIST_CNT]; + 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 { @@ -367,6 +375,8 @@ struct sis_ring_data { int sis_tx_prod; int sis_tx_cons; int sis_tx_cnt; + uint32_t sis_rx_paddr; + uint32_t sis_tx_paddr; }; @@ -442,7 +452,9 @@ struct sis_softc { uint8_t sis_type; uint8_t sis_rev; uint8_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; #ifdef DEVICE_POLLING @@ -504,8 +516,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 -- 2.41.0