summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_vic.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/sys/dev/pci/if_vic.c b/sys/dev/pci/if_vic.c
index b8516b74f35..56734d63358 100644
--- a/sys/dev/pci/if_vic.c
+++ b/sys/dev/pci/if_vic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vic.c,v 1.14 2006/11/01 05:45:15 dlg Exp $ */
+/* $OpenBSD: if_vic.c,v 1.15 2006/11/01 10:21:57 dlg Exp $ */
/*
* Copyright (c) 2006 Reyk Floeter <reyk@openbsd.org>
@@ -456,7 +456,7 @@ vic_init_data(struct vic_softc *sc)
for (i = 0; i < sc->sc_ntxbuf; i++) {
txb = &sc->sc_txbuf[i];
- if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1 /* XXX 6 */,
+ if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, VIC_SG_MAX,
MCLBYTES, 0, BUS_DMA_NOWAIT, &txb->txb_dmamap) != 0) {
printf("%s: unable to create dmamap for tx %d\n",
DEVNAME(sc), i);
@@ -636,7 +636,8 @@ vic_tx_proc(struct vic_softc *sc)
break;
}
- /* XXX bus dma sync */
+ bus_dmamap_sync(sc->sc_dmat, txb->txb_dmamap, 0,
+ txb->txb_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_dmat, txb->txb_dmamap);
m_freem(txb->txb_m);
@@ -749,8 +750,11 @@ vic_encap(struct vic_softc *sc, struct mbuf *m)
struct ifnet *ifp = &sc->sc_ac.ac_if;
struct vic_txbuf *txb;
struct vic_txdesc *txd;
+ struct vic_sg *sge;
struct mbuf *m0 = NULL;
- int idx;
+ bus_dmamap_t dmap;
+ int error;
+ int i, idx;
bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_map, 0, sc->sc_dma_size,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -775,8 +779,12 @@ vic_encap(struct vic_softc *sc, struct mbuf *m)
return (ENOMEM);
}
- if (bus_dmamap_load_mbuf(sc->sc_dmat, txb->txb_dmamap,
- m, BUS_DMA_NOWAIT) != 0) {
+ dmap = txb->txb_dmamap;
+ error = bus_dmamap_load_mbuf(sc->sc_dmat, dmap, m, BUS_DMA_NOWAIT);
+ switch (error) {
+ case 0:
+ break;
+ case EFBIG:
/* XXX this is bollocks */
MGETHDR(m0, M_DONTWAIT, MT_DATA);
if (m0 == NULL)
@@ -790,11 +798,15 @@ vic_encap(struct vic_softc *sc, struct mbuf *m)
}
m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
- if (bus_dmamap_load_mbuf(sc->sc_dmat, txb->txb_dmamap,
- m0, BUS_DMA_NOWAIT) != 0) {
+ if (bus_dmamap_load_mbuf(sc->sc_dmat, dmap, m0,
+ BUS_DMA_NOWAIT) != 0) {
m_freem(m0);
return (ENOBUFS);
}
+ break;
+ default:
+ printf("%s: tx dmamap load error %d\n", DEVNAME(sc), error);
+ return (ENOBUFS);
}
#if NBPFILTER > 0
@@ -802,36 +814,33 @@ vic_encap(struct vic_softc *sc, struct mbuf *m)
bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
#endif
- /* m0 means this has to be done here, more bollocks */
IFQ_DEQUEUE(&ifp->if_snd, m);
if (m0 != NULL) {
m_freem(m);
m = m0;
m0 = NULL;
}
+ txb->txb_m = m;
- /* XXX nsegs are cool */
txd->tx_flags = VIC_TX_FLAGS_KEEP;
- txd->tx_sa.sa_addr_type = VIC_SG_ADDR_PHYS;
- txd->tx_sa.sa_length = 1;
- txd->tx_sa.sa_sg[0].sg_length = m->m_len;
- txd->tx_sa.sa_sg[0].sg_addr_low = 0;
- txd->tx_sa.sa_sg[0].sg_addr_low = txb->txb_dmamap->dm_segs[0].ds_addr;
txd->tx_owner = VIC_OWNER_NIC;
+ txd->tx_sa.sa_addr_type = VIC_SG_ADDR_PHYS;
+ txd->tx_sa.sa_length = dmap->dm_nsegs;
+ for (i = 0; i < dmap->dm_nsegs; i++) {
+ sge = &txd->tx_sa.sa_sg[i];
+ sge->sg_length = dmap->dm_segs[i].ds_len;
+ sge->sg_addr_low = dmap->dm_segs[i].ds_addr;
+ }
- /* XXX bus dma sync */
- txb->txb_m = m;
-
- if (VIC_TXURN_WARN(sc)) {
- if (ifp->if_flags & IFF_DEBUG)
- printf("%s: running out of tx descriptors\n",
- DEVNAME(sc));
+ if (VIC_TXURN_WARN(sc))
txd->tx_flags |= VIC_TX_FLAGS_TXURN;
- }
ifp->if_opackets++;
sc->sc_txpending++;
+ bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
+ BUS_DMASYNC_PREWRITE);
+
sc->sc_data->vd_tx_stopped = 1;
VIC_INC(sc->sc_data->vd_tx_nextidx, sc->sc_data->vd_tx_length);