summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2005-11-05 11:49:02 +0000
committerBrad Smith <brad@cvs.openbsd.org>2005-11-05 11:49:02 +0000
commitf43d63d8ec76b40ecd312f784f636a0fd96a7308 (patch)
treea685542b46db89eb11396916d5b41b9730ab25ae /sys/dev
parenta83a75f3cdc91a1e05b70efee323ff59f74fdce3 (diff)
add bus_dma and big endian support.
From NetBSD Thanks to Jason Ackley for testing on i386/amd64/sparc64 with both T1 and T3 cards. "looks ok" dlg@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_lmc.c357
-rw-r--r--sys/dev/pci/if_lmc_common.c39
-rw-r--r--sys/dev/pci/if_lmc_media.c6
-rw-r--r--sys/dev/pci/if_lmc_obsd.c116
-rw-r--r--sys/dev/pci/if_lmc_types.h18
-rw-r--r--sys/dev/pci/if_lmcioctl.h6
-rw-r--r--sys/dev/pci/if_lmcvar.h138
7 files changed, 505 insertions, 175 deletions
diff --git a/sys/dev/pci/if_lmc.c b/sys/dev/pci/if_lmc.c
index 6399154f598..1105c903fe7 100644
--- a/sys/dev/pci/if_lmc.c
+++ b/sys/dev/pci/if_lmc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_lmc.c,v 1.18 2004/11/28 23:39:45 canacar Exp $ */
+/* $OpenBSD: if_lmc.c,v 1.19 2005/11/05 11:49:01 brad Exp $ */
/* $NetBSD: if_lmc.c,v 1.1 1999/03/25 03:32:43 explorer Exp $ */
/*-
@@ -116,8 +116,6 @@
#include <net/bpf.h>
#endif
-#include <uvm/uvm_extern.h>
-
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <net/if_sppp.h>
#endif
@@ -169,12 +167,6 @@
#define INCLUDE_PATH_PREFIX "dev/pci/"
#endif /* __NetBSD__ */
-#if defined(__OpenBSD__)
-#define d_length1 u.bd_length1
-#define d_length2 u.bd_length2
-#define d_flag u.bd_flag
-#endif
-
/*
* Sigh. Every OS puts these in different places. NetBSD and FreeBSD use
* a C preprocessor that allows this hack, but BSDI does not. Grr.
@@ -441,7 +433,6 @@ lmc_watchdog(int unit)
/* Is the transmit clock still available? */
ticks = LMC_CSR_READ (sc, csr_gp_timer);
ticks = 0x0000ffff - (ticks & 0x0000ffff);
-
if (ticks == 0)
{
/* no clock found ? */
@@ -555,6 +546,7 @@ lmc_ifup(lmc_softc_t * const sc)
*/
sc->lmc_intrmask |= (TULIP_STS_NORMALINTR
| TULIP_STS_RXINTR
+ | TULIP_STS_RXNOBUF
| TULIP_STS_TXINTR
| TULIP_STS_ABNRMLINTR
| TULIP_STS_SYSERROR
@@ -594,15 +586,18 @@ lmc_rx_intr(lmc_softc_t * const sc)
{
lmc_ringinfo_t * const ri = &sc->lmc_rxinfo;
struct ifnet * const ifp = &sc->lmc_if;
+ u_int32_t status;
int fillok = 1;
sc->lmc_rxtick++;
for (;;) {
- tulip_desc_t *eop = ri->ri_nextin;
+ lmc_desc_t *eop = ri->ri_nextin;
int total_len = 0, last_offset = 0;
struct mbuf *ms = NULL, *me = NULL;
int accept = 0;
+ bus_dmamap_t map;
+ int error;
if (fillok && sc->lmc_rxq.ifq_len < LMC_RXQ_TARGET)
goto queue_mbuf;
@@ -618,14 +613,18 @@ lmc_rx_intr(lmc_softc_t * const sc)
* 90% of the packets will fit in one descriptor. So we
* optimize for that case.
*/
- if ((((volatile tulip_desc_t *) eop)->d_status & (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) {
+ LMC_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
+ status = letoh32(((volatile lmc_desc_t *) eop)->d_status);
+ if ((status &
+ (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) ==
+ (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) {
IF_DEQUEUE(&sc->lmc_rxq, ms);
me = ms;
} else {
/*
* If still owned by the TULIP, don't touch it.
*/
- if (((volatile tulip_desc_t *)eop)->d_status & TULIP_DSTS_OWNER)
+ if (status & TULIP_DSTS_OWNER)
break;
/*
@@ -634,10 +633,14 @@ lmc_rx_intr(lmc_softc_t * const sc)
* for a received packet to cross more than one
* receive descriptor.
*/
- while ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_RxLASTDESC) == 0) {
+ while ((status & TULIP_DSTS_RxLASTDESC) == 0) {
if (++eop == ri->ri_last)
eop = ri->ri_first;
- if (eop == ri->ri_nextout || ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER))) {
+ LMC_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
+ status = letoh32(((volatile lmc_desc_t *)
+ eop)->d_status);
+ if (eop == ri->ri_nextout ||
+ (status & TULIP_DSTS_OWNER)) {
return;
}
total_len++;
@@ -658,6 +661,13 @@ lmc_rx_intr(lmc_softc_t * const sc)
*/
IF_DEQUEUE(&sc->lmc_rxq, ms);
for (me = ms; total_len > 0; total_len--) {
+ map = LMC_GETCTX(me, bus_dmamap_t);
+ LMC_RXMAP_POSTSYNC(sc, map);
+ bus_dmamap_unload(sc->lmc_dmatag, map);
+ sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
+#if defined(DIAGNOSTIC)
+ LMC_SETCTX(me, NULL);
+#endif
me->m_len = LMC_RX_BUFLEN;
last_offset += LMC_RX_BUFLEN;
IF_DEQUEUE(&sc->lmc_rxq, me->m_next);
@@ -668,19 +678,29 @@ lmc_rx_intr(lmc_softc_t * const sc)
/*
* Now get the size of received packet (minus the CRC).
*/
- total_len = ((eop->d_status >> 16) & 0x7FFF);
+ total_len = ((status >> 16) & 0x7FFF);
if (sc->ictl.crc_length == 16)
total_len -= 2;
else
total_len -= 4;
if ((sc->lmc_flags & LMC_RXIGNORE) == 0
- && ((eop->d_status & LMC_DSTS_ERRSUM) == 0
+ && ((status & LMC_DSTS_ERRSUM) == 0
#ifdef BIG_PACKET
|| (total_len <= sc->lmc_if.if_mtu + PPP_HEADER_LEN
- && (eop->d_status & TULIP_DSTS_RxOVERFLOW) == 0)
+ && (status & TULIP_DSTS_RxOVERFLOW) == 0)
#endif
)) {
+
+ map = LMC_GETCTX(me, bus_dmamap_t);
+ bus_dmamap_sync(sc->lmc_dmatag, map, 0, me->m_len,
+ BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->lmc_dmatag, map);
+ sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
+#if defined(DIAGNOSTIC)
+ LMC_SETCTX(me, NULL);
+#endif
+
me->m_len = total_len - last_offset;
#if NBPFILTER > 0
if (sc->lmc_bpf != NULL) {
@@ -694,9 +714,15 @@ lmc_rx_intr(lmc_softc_t * const sc)
accept = 1;
} else {
ifp->if_ierrors++;
- if (eop->d_status & TULIP_DSTS_RxOVERFLOW) {
+ if (status & TULIP_DSTS_RxOVERFLOW) {
sc->lmc_dot3stats.dot3StatsInternalMacReceiveErrors++;
}
+ map = LMC_GETCTX(me, bus_dmamap_t);
+ bus_dmamap_unload(sc->lmc_dmatag, map);
+ sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
+#if defined(DIAGNOSTIC)
+ LMC_SETCTX(me, NULL);
+#endif
}
ifp->if_ipackets++;
@@ -754,9 +780,52 @@ lmc_rx_intr(lmc_softc_t * const sc)
* receive queue.
*/
do {
- ri->ri_nextout->d_length1 = LMC_RX_BUFLEN;
- ri->ri_nextout->d_addr1 = LMC_KVATOPHYS(sc, mtod(ms, caddr_t));
- ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
+ u_int32_t ctl;
+ lmc_desc_t * const nextout = ri->ri_nextout;
+
+ if (sc->lmc_rxmaps_free > 0) {
+ map = sc->lmc_rxmaps[--sc->lmc_rxmaps_free];
+ } else {
+ m_freem(ms);
+ sc->lmc_flags |= LMC_RXBUFSLOW;
+#if defined(LMC_DEBUG)
+ sc->lmc_dbg.dbg_rxlowbufs++;
+#endif
+ break;
+ }
+ LMC_SETCTX(ms, map);
+ error = bus_dmamap_load(sc->lmc_dmatag, map,
+ mtod(ms, void *), LMC_RX_BUFLEN,
+ NULL, BUS_DMA_NOWAIT);
+ if (error) {
+ printf(LMC_PRINTF_FMT
+ ": unable to load rx map, "
+ "error = %d\n",
+ LMC_PRINTF_ARGS, error);
+ panic("lmc_rx_intr"); /* XXX */
+ }
+
+ ctl = letoh32(nextout->d_ctl);
+ /* For some weird reason we lose TULIP_DFLAG_ENDRING */
+ if ((nextout+1) == ri->ri_last)
+ ctl = LMC_CTL(LMC_CTL_FLGS(ctl)|
+ TULIP_DFLAG_ENDRING, 0, 0);
+ nextout->d_addr1 = htole32(map->dm_segs[0].ds_addr);
+ if (map->dm_nsegs == 2) {
+ nextout->d_addr2 = htole32(map->dm_segs[1].ds_addr);
+ nextout->d_ctl =
+ htole32(LMC_CTL(LMC_CTL_FLGS(ctl),
+ map->dm_segs[0].ds_len,
+ map->dm_segs[1].ds_len));
+ } else {
+ nextout->d_addr2 = 0;
+ nextout->d_ctl =
+ htole32(LMC_CTL(LMC_CTL_FLGS(ctl),
+ map->dm_segs[0].ds_len, 0));
+ }
+ LMC_RXDESC_POSTSYNC(sc, nextout, sizeof(*nextout));
+ ri->ri_nextout->d_status = htole32(TULIP_DSTS_OWNER);
+ LMC_RXDESC_POSTSYNC(sc, nextout, sizeof(u_int32_t));
if (++ri->ri_nextout == ri->ri_last)
ri->ri_nextout = ri->ri_first;
me = ms->m_next;
@@ -776,29 +845,25 @@ lmc_tx_intr(lmc_softc_t * const sc)
struct mbuf *m;
int xmits = 0;
int descs = 0;
+ u_int32_t d_status;
sc->lmc_txtick++;
while (ri->ri_free < ri->ri_max) {
-#ifdef __OpenBSD__
- u_int32_t duh_flag;
-#else
- u_int32_t d_flag;
-#endif
+ u_int32_t flag;
- if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER)
+ LMC_TXDESC_POSTSYNC(sc, ri->ri_nextin, sizeof(*ri->ri_nextin));
+ d_status = letoh32(((volatile lmc_desc_t *) ri->ri_nextin)->d_status);
+ if (d_status & TULIP_DSTS_OWNER)
break;
-#ifdef __OpenBSD__
- duh_flag = ri->ri_nextin->d_flag;
- if (duh_flag & TULIP_DFLAG_TxLASTSEG) {
-#else
- d_flag = ri->ri_nextin->d_flag;
- if (d_flag & TULIP_DFLAG_TxLASTSEG) {
-#endif
- const u_int32_t d_status = ri->ri_nextin->d_status;
+ flag = LMC_CTL_FLGS(letoh32(ri->ri_nextin->d_ctl));
+ if (flag & TULIP_DFLAG_TxLASTSEG) {
IF_DEQUEUE(&sc->lmc_txq, m);
if (m != NULL) {
+ bus_dmamap_t map = LMC_GETCTX(m, bus_dmamap_t);
+ LMC_TXMAP_POSTSYNC(sc, map);
+ sc->lmc_txmaps[sc->lmc_txmaps_free++] = map;
#if NBPFILTER > 0
if (sc->lmc_bpf != NULL)
LMC_BPF_MTAP(sc, m);
@@ -812,11 +877,13 @@ lmc_tx_intr(lmc_softc_t * const sc)
xmits++;
if (d_status & LMC_DSTS_ERRSUM) {
sc->lmc_if.if_oerrors++;
- if (d_status & TULIP_DSTS_TxUNDERFLOW)
+ if (d_status & TULIP_DSTS_TxUNDERFLOW) {
sc->lmc_dot3stats.dot3StatsInternalTransmitUnderflows++;
+ }
} else {
- if (d_status & TULIP_DSTS_TxDEFERRED)
+ if (d_status & TULIP_DSTS_TxDEFERRED) {
sc->lmc_dot3stats.dot3StatsDeferredTransmissions++;
+ }
}
}
@@ -1006,10 +1073,11 @@ static struct mbuf *
lmc_txput(lmc_softc_t * const sc, struct mbuf *m)
{
lmc_ringinfo_t * const ri = &sc->lmc_txinfo;
- tulip_desc_t *eop, *nextout;
+ lmc_desc_t *eop, *nextout;
int segcnt, free;
- u_int32_t d_status;
- struct mbuf *m0;
+ u_int32_t d_status, ctl;
+ bus_dmamap_t map;
+ int error;
#if defined(LMC_DEBUG)
if ((sc->lmc_cmdmode & TULIP_CMD_TXRUN) == 0) {
@@ -1037,84 +1105,113 @@ lmc_txput(lmc_softc_t * const sc, struct mbuf *m)
* case we will just wait for the ring to empty. In the
* latter case we have to recopy.
*/
- again:
d_status = 0;
eop = nextout = ri->ri_nextout;
- m0 = m;
segcnt = 0;
free = ri->ri_free;
- do {
- int len = m0->m_len;
- caddr_t addr = mtod(m0, caddr_t);
- unsigned clsize = PAGE_SIZE - (((u_long) addr) & PAGE_MASK);
-
- while (len > 0) {
- unsigned slen = min(len, clsize);
-#ifdef BIG_PACKET
- int partial = 0;
- if (slen >= 2048)
- slen = 2040, partial = 1;
+ /*
+ * Reclaim some DMA maps from if we are out.
+ */
+ if (sc->lmc_txmaps_free == 0) {
+#if defined(LMC_DEBUG)
+ sc->lmc_dbg.dbg_no_txmaps++;
#endif
- segcnt++;
- if (segcnt > LMC_MAX_TXSEG) {
- /*
- * The packet exceeds the number of transmit
- * buffer entries that we can use for one
- * packet, so we have recopy it into one mbuf
- * and then try again.
- */
- m = lmc_mbuf_compress(m);
- if (m == NULL)
- goto finish;
- goto again;
- }
- if (segcnt & 1) {
- if (--free == 0) {
- /*
- * See if there's any unclaimed space
- * in the transmit ring.
- */
- if ((free += lmc_tx_intr(sc)) == 0) {
- /*
- * There's no more room but
- * since nothing has been
- * committed at this point,
- * just show output is active,
- * put back the mbuf and
- * return.
- */
- sc->lmc_flags |= LMC_WANTTXSTART;
- goto finish;
- }
- }
- eop = nextout;
- if (++nextout == ri->ri_last)
- nextout = ri->ri_first;
- eop->d_flag &= TULIP_DFLAG_ENDRING;
- eop->d_flag |= TULIP_DFLAG_TxNOPADDING;
- if (sc->ictl.crc_length == 16)
- eop->d_flag |= TULIP_DFLAG_TxHASCRC;
- eop->d_status = d_status;
- eop->d_addr1 = LMC_KVATOPHYS(sc, addr);
- eop->d_length1 = slen;
- } else {
- /*
- * Fill in second half of descriptor
- */
- eop->d_addr2 = LMC_KVATOPHYS(sc, addr);
- eop->d_length2 = slen;
+ free += lmc_tx_intr(sc);
+ }
+ if (sc->lmc_txmaps_free > 0) {
+ map = sc->lmc_txmaps[sc->lmc_txmaps_free-1];
+ } else {
+ sc->lmc_flags |= LMC_WANTTXSTART;
+#if defined(LMC_DEBUG)
+ sc->lmc_dbg.dbg_txput_finishes[1]++;
+#endif
+ goto finish;
+ }
+ error = bus_dmamap_load_mbuf(sc->lmc_dmatag, map, m, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ if (error == EFBIG) {
+ /*
+ * The packet exceeds the number of transmit buffer
+ * entries that we can use for one packet, so we have
+ * to recopy it into one mbuf and then try again.
+ */
+ m = lmc_mbuf_compress(m);
+ if (m == NULL) {
+#if defined(LMC_DEBUG)
+ sc->lmc_dbg.dbg_txput_finishes[2]++;
+#endif
+ goto finish;
}
- d_status = TULIP_DSTS_OWNER;
- len -= slen;
- addr += slen;
-#ifdef BIG_PACKET
- if (partial)
- continue;
+ error = bus_dmamap_load_mbuf(sc->lmc_dmatag, map, m,
+ BUS_DMA_NOWAIT);
+ }
+ if (error != 0) {
+ printf(LMC_PRINTF_FMT ": unable to load tx map, "
+ "error = %d\n", LMC_PRINTF_ARGS, error);
+#if defined(LMC_DEBUG)
+ sc->lmc_dbg.dbg_txput_finishes[3]++;
#endif
- clsize = PAGE_SIZE;
+ goto finish;
}
- } while ((m0 = m0->m_next) != NULL);
+ }
+ if ((free -= (map->dm_nsegs + 1) / 2) <= 0
+ /*
+ * See if there's any unclaimed space in the transmit ring.
+ */
+ && (free += lmc_tx_intr(sc)) <= 0) {
+ /*
+ * There's no more room but since nothing
+ * has been committed at this point, just
+ * show output is active, put back the
+ * mbuf and return.
+ */
+ sc->lmc_flags |= LMC_WANTTXSTART;
+#if defined(LMC_DEBUG)
+ sc->lmc_dbg.dbg_txput_finishes[4]++;
+#endif
+ bus_dmamap_unload(sc->lmc_dmatag, map);
+ goto finish;
+ }
+ for (; map->dm_nsegs - segcnt > 1; segcnt += 2) {
+ int flg;
+ eop = nextout;
+ flg = LMC_CTL_FLGS(letoh32(eop->d_ctl));
+ flg &= TULIP_DFLAG_ENDRING;
+ flg |= TULIP_DFLAG_TxNOPADDING;
+ if (sc->ictl.crc_length == 16)
+ flg |= TULIP_DFLAG_TxHASCRC;
+ eop->d_status = htole32(d_status);
+ eop->d_addr1 = htole32(map->dm_segs[segcnt].ds_addr);
+ eop->d_addr2 = htole32(map->dm_segs[segcnt+1].ds_addr);
+ eop->d_ctl = htole32(LMC_CTL(flg,
+ map->dm_segs[segcnt].ds_len,
+ map->dm_segs[segcnt+1].ds_len));
+ d_status = TULIP_DSTS_OWNER;
+ if (++nextout == ri->ri_last)
+ nextout = ri->ri_first;
+ }
+ if (segcnt < map->dm_nsegs) {
+ int flg;
+
+ eop = nextout;
+ flg = LMC_CTL_FLGS(letoh32(eop->d_ctl));
+ flg &= TULIP_DFLAG_ENDRING;
+ flg |= TULIP_DFLAG_TxNOPADDING;
+ if (sc->ictl.crc_length == 16)
+ flg |= TULIP_DFLAG_TxHASCRC;
+ eop->d_status = htole32(d_status);
+ eop->d_addr1 = htole32(map->dm_segs[segcnt].ds_addr);
+ eop->d_addr2 = 0;
+ eop->d_ctl = htole32(LMC_CTL(flg,
+ map->dm_segs[segcnt].ds_len, 0));
+ if (++nextout == ri->ri_last)
+ nextout = ri->ri_first;
+ }
+ LMC_TXMAP_PRESYNC(sc, map);
+ LMC_SETCTX(m, map);
+ map = NULL;
+ --sc->lmc_txmaps_free; /* commit to using the dmamap */
/*
* The descriptors have been filled in. Now get ready
@@ -1129,29 +1226,39 @@ lmc_txput(lmc_softc_t * const sc, struct mbuf *m)
* of room in the ring.
*/
nextout->d_status = 0;
-
- /*
- * If we only used the first segment of the last descriptor,
- * make sure the second segment will not be used.
- */
- if (segcnt & 1) {
- eop->d_addr2 = 0;
- eop->d_length2 = 0;
- }
+ LMC_TXDESC_PRESYNC(sc, nextout, sizeof(u_int32_t));
/*
* Mark the last and first segments, indicate we want a transmit
* complete interrupt, and tell it to transmit!
*/
- eop->d_flag |= TULIP_DFLAG_TxLASTSEG | TULIP_DFLAG_TxWANTINTR;
+ ctl = letoh32(eop->d_ctl);
+ eop->d_ctl = htole32(LMC_CTL(
+ LMC_CTL_FLGS(ctl)|TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR,
+ LMC_CTL_LEN1(ctl),
+ LMC_CTL_LEN2(ctl)));
/*
* Note that ri->ri_nextout is still the start of the packet
* and until we set the OWNER bit, we can still back out of
* everything we have done.
*/
- ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG;
- ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
+ ctl = letoh32(ri->ri_nextout->d_ctl);
+ ri->ri_nextout->d_ctl = htole32(LMC_CTL(
+ LMC_CTL_FLGS(ctl)|TULIP_DFLAG_TxFIRSTSEG,
+ LMC_CTL_LEN1(ctl),
+ LMC_CTL_LEN2(ctl)));
+ if (eop < ri->ri_nextout) {
+ LMC_TXDESC_PRESYNC(sc, ri->ri_nextout,
+ (caddr_t) ri->ri_last - (caddr_t) ri->ri_nextout);
+ LMC_TXDESC_PRESYNC(sc, ri->ri_first,
+ (caddr_t) (eop + 1) - (caddr_t) ri->ri_first);
+ } else {
+ LMC_TXDESC_PRESYNC(sc, ri->ri_nextout,
+ (caddr_t) (eop + 1) - (caddr_t) ri->ri_nextout);
+ }
+ ri->ri_nextout->d_status = htole32(TULIP_DSTS_OWNER);
+ LMC_TXDESC_PRESYNC(sc, ri->ri_nextout, sizeof(u_int32_t));
LMC_CSR_WRITE(sc, csr_txpoll, 1);
@@ -1481,14 +1588,14 @@ lmc_attach(lmc_softc_t * const sc)
else
lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED2);
}
-
+
void
lmc_initring(lmc_softc_t * const sc, lmc_ringinfo_t * const ri,
- tulip_desc_t *descs, int ndescs)
+ lmc_desc_t *descs, int ndescs)
{
ri->ri_max = ndescs;
ri->ri_first = descs;
ri->ri_last = ri->ri_first + ri->ri_max;
bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
- ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING;
+ ri->ri_last[-1].d_ctl = htole32(LMC_CTL(TULIP_DFLAG_ENDRING, 0, 0));
}
diff --git a/sys/dev/pci/if_lmc_common.c b/sys/dev/pci/if_lmc_common.c
index d422d626a9f..3f2ecc72e38 100644
--- a/sys/dev/pci/if_lmc_common.c
+++ b/sys/dev/pci/if_lmc_common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_lmc_common.c,v 1.9 2004/05/12 06:35:11 tedu Exp $ */
+/* $OpenBSD: if_lmc_common.c,v 1.10 2005/11/05 11:49:01 brad Exp $ */
/* $NetBSD: if_lmc_common.c,v 1.1 1999/03/25 03:32:43 explorer Exp $ */
/*-
@@ -100,8 +100,6 @@
#include <net/bpf.h>
#endif
-#include <uvm/uvm_extern.h>
-
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <net/if_sppp.h>
#endif
@@ -253,7 +251,7 @@ lmc_dec_reset(lmc_softc_t * const sc)
{
#ifndef __linux__
lmc_ringinfo_t *ri;
- tulip_desc_t *di;
+ lmc_desc_t *di;
#endif
u_int32_t val;
@@ -329,15 +327,12 @@ lmc_dec_reset(lmc_softc_t * const sc)
/*
* reprogram the tx desc, rx desc, and PCI bus options
*/
- LMC_CSR_WRITE(sc, csr_txlist,
- LMC_KVATOPHYS(sc, &sc->lmc_txinfo.ri_first[0]));
- LMC_CSR_WRITE(sc, csr_rxlist,
- LMC_KVATOPHYS(sc, &sc->lmc_rxinfo.ri_first[0]));
+ LMC_CSR_WRITE(sc, csr_txlist, sc->lmc_txdescmap->dm_segs[0].ds_addr);
+ LMC_CSR_WRITE(sc, csr_rxlist, sc->lmc_rxdescmap->dm_segs[0].ds_addr);
LMC_CSR_WRITE(sc, csr_busmode,
- (1 << (LMC_BURSTSIZE(sc->lmc_unit) + 8))
- |TULIP_BUSMODE_CACHE_ALIGN8
- |TULIP_BUSMODE_READMULTIPLE
- |(BYTE_ORDER != LITTLE_ENDIAN ? TULIP_BUSMODE_BIGENDIAN : 0));
+ (1 << (LMC_BURSTSIZE(sc->lmc_unit) + 8))
+ |TULIP_BUSMODE_CACHE_ALIGN8
+ |TULIP_BUSMODE_READMULTIPLE);
sc->lmc_txq.ifq_maxlen = LMC_TXDESCS;
@@ -345,11 +340,15 @@ lmc_dec_reset(lmc_softc_t * const sc)
* Free all the mbufs that were on the transmit ring.
*/
for (;;) {
+ bus_dmamap_t map;
struct mbuf *m;
IF_DEQUEUE(&sc->lmc_txq, m);
if (m == NULL)
break;
+ map = LMC_GETCTX(m, bus_dmamap_t);
+ bus_dmamap_unload(sc->lmc_dmatag, map);
+ sc->lmc_txmaps[sc->lmc_txmaps_free++] = map;
m_freem(m);
}
@@ -361,6 +360,9 @@ lmc_dec_reset(lmc_softc_t * const sc)
ri->ri_free = ri->ri_max;
for (di = ri->ri_first; di < ri->ri_last; di++)
di->d_status = 0;
+ bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_txdescmap,
+ 0, sc->lmc_txdescmap->dm_mapsize,
+ BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
/*
* We need to collect all the mbufs were on the
@@ -372,15 +374,24 @@ lmc_dec_reset(lmc_softc_t * const sc)
ri->ri_nextin = ri->ri_nextout = ri->ri_first;
ri->ri_free = ri->ri_max;
for (di = ri->ri_first; di < ri->ri_last; di++) {
+ u_int32_t ctl = di->d_ctl;
di->d_status = 0;
- di->d_length1 = 0; di->d_addr1 = 0;
- di->d_length2 = 0; di->d_addr2 = 0;
+ di->d_ctl = LMC_CTL(LMC_CTL_FLGS(ctl),0,0);
+ di->d_addr1 = 0;
+ di->d_addr2 = 0;
}
+ bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_rxdescmap,
+ 0, sc->lmc_rxdescmap->dm_mapsize,
+ BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
for (;;) {
+ bus_dmamap_t map;
struct mbuf *m;
IF_DEQUEUE(&sc->lmc_rxq, m);
if (m == NULL)
break;
+ map = LMC_GETCTX(m, bus_dmamap_t);
+ bus_dmamap_unload(sc->lmc_dmatag, map);
+ sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
m_freem(m);
}
#endif
diff --git a/sys/dev/pci/if_lmc_media.c b/sys/dev/pci/if_lmc_media.c
index c03f514554a..548a2fc344b 100644
--- a/sys/dev/pci/if_lmc_media.c
+++ b/sys/dev/pci/if_lmc_media.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_lmc_media.c,v 1.14 2004/05/12 06:35:11 tedu Exp $ */
-/* $Id: if_lmc_media.c,v 1.14 2004/05/12 06:35:11 tedu Exp $ */
+/* $OpenBSD: if_lmc_media.c,v 1.15 2005/11/05 11:49:01 brad Exp $ */
+/* $Id: if_lmc_media.c,v 1.15 2005/11/05 11:49:01 brad Exp $ */
/*-
* Copyright (c) 1997-1999 LAN Media Corporation (LMC)
@@ -76,8 +76,6 @@
#include <net/bpf.h>
#endif
-#include <uvm/uvm_extern.h>
-
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <net/if_sppp.h>
#endif
diff --git a/sys/dev/pci/if_lmc_obsd.c b/sys/dev/pci/if_lmc_obsd.c
index b08b5c8dda1..70c5fc97761 100644
--- a/sys/dev/pci/if_lmc_obsd.c
+++ b/sys/dev/pci/if_lmc_obsd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_lmc_obsd.c,v 1.16 2005/08/09 04:10:12 mickey Exp $ */
+/* $OpenBSD: if_lmc_obsd.c,v 1.17 2005/11/05 11:49:01 brad Exp $ */
/* $NetBSD: if_lmc_nbsd.c,v 1.1 1999/03/25 03:32:43 explorer Exp $ */
/*-
@@ -100,8 +100,6 @@
#include <net/bpf.h>
#endif
-#include <uvm/uvm_extern.h>
-
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <net/if_sppp.h>
#endif
@@ -176,6 +174,9 @@
*/
static void lmc_shutdown(void *arg);
+static int lmc_busdma_init(lmc_softc_t * const sc);
+static int lmc_busdma_allocmem(lmc_softc_t * const sc, size_t size,
+ bus_dmamap_t *map_p, lmc_desc_t **desc_p);
static int
lmc_pci_probe(struct device *parent,
@@ -210,7 +211,7 @@ lmc_pci_probe(struct device *parent,
&& (PCI_CHIPID(id) != PCI_PRODUCT_LMC_DS1))
return 0;
- return 10; /* must be > than any other tulip driver */
+ return 20; /* must be > than any other tulip driver */
}
static void lmc_pci_attach(struct device * const parent,
@@ -231,9 +232,6 @@ lmc_pci_attach(struct device * const parent,
u_int32_t revinfo, cfdainfo, id, ssid;
pci_intr_handle_t intrhandle;
const char *intrstr;
-#if 0
- vm_offset_t pa_csrs;
-#endif
unsigned csroffset = LMC_PCI_CSROFFSET;
unsigned csrsize = LMC_PCI_CSRSIZE;
lmc_csrptr_t csr_base;
@@ -320,6 +318,12 @@ lmc_pci_attach(struct device * const parent,
}
}
+ sc->lmc_dmatag = pa->pa_dmat;
+ if ((lmc_busdma_init(sc)) != 0) {
+ printf("error initing bus_dma\n");
+ return;
+ }
+
lmc_initcsrs(sc, csr_base + csroffset, csrsize);
lmc_initring(sc, &sc->lmc_rxinfo, sc->lmc_rxdescs,
LMC_RXDESCS);
@@ -398,3 +402,101 @@ lmc_shutdown(void *arg)
sc->lmc_miireg16 = 0; /* deassert ready, and all others too */
lmc_led_on(sc, LMC_MII16_LED_ALL);
}
+
+static int
+lmc_busdma_allocmem(
+ lmc_softc_t * const sc,
+ size_t size,
+ bus_dmamap_t *map_p,
+ lmc_desc_t **desc_p)
+{
+ bus_dma_segment_t segs[1];
+ int nsegs, error;
+ error = bus_dmamem_alloc(sc->lmc_dmatag, size, 1, NBPG,
+ segs, sizeof(segs)/sizeof(segs[0]),
+ &nsegs, BUS_DMA_NOWAIT);
+ if (error == 0) {
+ void *desc;
+ error = bus_dmamem_map(sc->lmc_dmatag, segs, nsegs, size,
+ (void *) &desc, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
+ if (error == 0) {
+ bus_dmamap_t map;
+ error = bus_dmamap_create(sc->lmc_dmatag, size, 1, size, 0,
+ BUS_DMA_NOWAIT, &map);
+ if (error == 0) {
+ error = bus_dmamap_load(sc->lmc_dmatag, map, desc,
+ size, NULL, BUS_DMA_NOWAIT);
+ if (error)
+ bus_dmamap_destroy(sc->lmc_dmatag, map);
+ else
+ *map_p = map;
+ }
+ if (error)
+ bus_dmamem_unmap(sc->lmc_dmatag, desc, size);
+ }
+ if (error)
+ bus_dmamem_free(sc->lmc_dmatag, segs, nsegs);
+ else
+ *desc_p = desc;
+ }
+ return error;
+}
+
+static int
+lmc_busdma_init(
+ lmc_softc_t * const sc)
+{
+ int error = 0;
+
+ /*
+ * Allocate space and dmamap for transmit ring
+ */
+ if (error == 0) {
+ error = lmc_busdma_allocmem(sc, sizeof(lmc_desc_t) * LMC_TXDESCS,
+ &sc->lmc_txdescmap,
+ &sc->lmc_txdescs);
+ }
+
+ /*
+ * Allocate dmamaps for each transmit descriptors
+ */
+ if (error == 0) {
+ while (error == 0 && sc->lmc_txmaps_free < LMC_TXDESCS) {
+ bus_dmamap_t map;
+ if ((error = LMC_TXMAP_CREATE(sc, &map)) == 0)
+ sc->lmc_txmaps[sc->lmc_txmaps_free++] = map;
+ }
+ if (error) {
+ while (sc->lmc_txmaps_free > 0)
+ bus_dmamap_destroy(sc->lmc_dmatag,
+ sc->lmc_txmaps[--sc->lmc_txmaps_free]);
+ }
+ }
+
+ /*
+ * Allocate space and dmamap for receive ring
+ */
+ if (error == 0) {
+ error = lmc_busdma_allocmem(sc, sizeof(lmc_desc_t) * LMC_RXDESCS,
+ &sc->lmc_rxdescmap,
+ &sc->lmc_rxdescs);
+ }
+
+ /*
+ * Allocate dmamaps for each receive descriptors
+ */
+ if (error == 0) {
+ while (error == 0 && sc->lmc_rxmaps_free < LMC_RXDESCS) {
+ bus_dmamap_t map;
+ if ((error = LMC_RXMAP_CREATE(sc, &map)) == 0)
+ sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
+ }
+ if (error) {
+ while (sc->lmc_rxmaps_free > 0)
+ bus_dmamap_destroy(sc->lmc_dmatag,
+ sc->lmc_rxmaps[--sc->lmc_rxmaps_free]);
+ }
+ }
+
+ return error;
+}
diff --git a/sys/dev/pci/if_lmc_types.h b/sys/dev/pci/if_lmc_types.h
index db468cfaee5..674a5690e9b 100644
--- a/sys/dev/pci/if_lmc_types.h
+++ b/sys/dev/pci/if_lmc_types.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_lmc_types.h,v 1.2 2000/02/01 18:01:42 chris Exp $ */
+/* $OpenBSD: if_lmc_types.h,v 1.3 2005/11/05 11:49:01 brad Exp $ */
/* $NetBSD: if_lmc_types.h,v 1.2 1999/03/25 04:09:33 explorer Exp $ */
/*-
@@ -56,6 +56,22 @@
#endif
#if defined(LMC_IS_KERNEL)
+
+/*
+ * LMC has weird endianness issues, so we can't use the tulip_desc_t.
+ */
+typedef struct {
+ u_int32_t d_status;
+ u_int32_t d_ctl;
+ u_int32_t d_addr1;
+ u_int32_t d_addr2;
+} lmc_desc_t;
+
+#define LMC_CTL_FLGS(x) (((x)>>22)&0x3ff)
+#define LMC_CTL_LEN2(x) (((x)>>11)&0x7ff)
+#define LMC_CTL_LEN1(x) ((x)&0x7ff)
+#define LMC_CTL(f,l1,l2) ((((f)&0x3ff)<<22)|(((l2)&0x7ff)<<11)|((l1)&0x7ff))
+
#if defined(__NetBSD__) || defined(__OpenBSD__)
typedef bus_addr_t lmc_csrptr_t;
#else
diff --git a/sys/dev/pci/if_lmcioctl.h b/sys/dev/pci/if_lmcioctl.h
index 7c3c2bbd14a..679d5e95d72 100644
--- a/sys/dev/pci/if_lmcioctl.h
+++ b/sys/dev/pci/if_lmcioctl.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_lmcioctl.h,v 1.4 2000/11/10 15:33:09 provos Exp $ */
-/* $Id: if_lmcioctl.h,v 1.4 2000/11/10 15:33:09 provos Exp $ */
+/* $OpenBSD: if_lmcioctl.h,v 1.5 2005/11/05 11:49:01 brad Exp $ */
+/* $Id: if_lmcioctl.h,v 1.5 2005/11/05 11:49:01 brad Exp $ */
/*
* Copyright (c) 1997-1999 LAN Media Corporation (LMC)
@@ -328,5 +328,5 @@ lmc_intrfunc_t lmc_intr_normal(void *);
int lmc_read_macaddr(lmc_softc_t * const sc);
void lmc_attach(lmc_softc_t * const sc);
void lmc_initring(lmc_softc_t * const sc, lmc_ringinfo_t * const ri,
- tulip_desc_t *descs, int ndescs);
+ lmc_desc_t *descs, int ndescs);
#endif /* LMC_IS_KERNEL */
diff --git a/sys/dev/pci/if_lmcvar.h b/sys/dev/pci/if_lmcvar.h
index de226048d2b..2b4d064b4f7 100644
--- a/sys/dev/pci/if_lmcvar.h
+++ b/sys/dev/pci/if_lmcvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_lmcvar.h,v 1.6 2002/06/02 22:50:00 deraadt Exp $ */
+/* $OpenBSD: if_lmcvar.h,v 1.7 2005/11/05 11:49:01 brad Exp $ */
/* $NetBSD: if_lmcvar.h,v 1.1 1999/03/25 03:32:43 explorer Exp $ */
/*-
@@ -66,6 +66,7 @@
#define LMC_MTU 1500
#define PPP_HEADER_LEN 4
#define BIG_PACKET
+#define LMC_DATA_PER_DESC 2032
/*
* This turns on all sort of debugging stuff and make the
@@ -73,6 +74,32 @@
*/
#if 0
#define LMC_DEBUG
+typedef enum {
+ LMC_21040_GENERIC, /* Generic 21040 (works with most any board) */
+ LMC_21140_ISV, /* Digital Semicondutor 21140 ISV SROM Format */
+ LMC_21142_ISV, /* Digital Semicondutor 21142 ISV SROM Format */
+ LMC_21143_ISV, /* Digital Semicondutor 21143 ISV SROM Format */
+ LMC_21140_DEC_EB, /* Digital Semicondutor 21140 Evaluation Board */
+ LMC_21140_MII, /* 21140[A] with MII */
+ LMC_21140_DEC_DE500, /* Digital DE500-?? 10/100 */
+ LMC_21140_SMC_9332, /* SMC 9332 */
+ LMC_21140_COGENT_EM100, /* Cogent EM100 100 only */
+ LMC_21140_ZNYX_ZX34X, /* ZNYX ZX342 10/100 */
+ LMC_21140_ASANTE, /* AsanteFast 10/100 */
+ LMC_21140_EN1207, /* Accton EN2107 10/100 BNC */
+ LMC_21041_GENERIC /* Generic 21041 card */
+} lmc_board_t;
+
+typedef enum {
+ LMC_MEDIAPOLL_TIMER, /* 100ms timer fired */
+ LMC_MEDIAPOLL_FASTTIMER, /* <100ms timer fired */
+ LMC_MEDIAPOLL_LINKFAIL, /* called from interrupt routine */
+ LMC_MEDIAPOLL_LINKPASS, /* called from interrupt routine */
+ LMC_MEDIAPOLL_START, /* start a media probe (called from reset) */
+ LMC_MEDIAPOLL_TXPROBE_OK, /* txprobe succeeded */
+ LMC_MEDIAPOLL_TXPROBE_FAILED, /* txprobe failed */
+ LMC_MEDIAPOLL_MAX
+} lmc_mediapoll_event_t;
#define DP(x) printf x
#else
#define DP(x)
@@ -194,10 +221,10 @@ typedef struct {
* traditional FIFO ring.
*/
struct lmc_ringinfo {
- tulip_desc_t *ri_first; /* first entry in ring */
- tulip_desc_t *ri_last; /* one after last entry */
- tulip_desc_t *ri_nextin; /* next to processed by host */
- tulip_desc_t *ri_nextout; /* next to processed by adapter */
+ lmc_desc_t *ri_first; /* first entry in ring */
+ lmc_desc_t *ri_last; /* one after last entry */
+ lmc_desc_t *ri_nextin; /* next to processed by host */
+ lmc_desc_t *ri_nextout; /* next to processed by adapter */
int ri_max;
int ri_free;
};
@@ -331,19 +358,23 @@ struct lmc___softc {
lmc_media_t *lmc_media;
lmc_ctl_t ictl;
+ bus_dma_tag_t lmc_dmatag; /* bus DMA tag */
+ bus_dmamap_t lmc_setupmap;
+ bus_dmamap_t lmc_txdescmap;
+ bus_dmamap_t lmc_txmaps[LMC_TXDESCS];
+ unsigned lmc_txmaps_free;
+ bus_dmamap_t lmc_rxdescmap;
+ bus_dmamap_t lmc_rxmaps[LMC_RXDESCS];
+ unsigned lmc_rxmaps_free;
+
#if defined(__NetBSD__) || defined(__OpenBSD__)
struct device *lmc_pci_busno; /* needed for multiport boards */
#else
u_int8_t lmc_pci_busno; /* needed for multiport boards */
#endif
u_int8_t lmc_pci_devno; /* needed for multiport boards */
-#if defined(__FreeBSD__)
- tulip_desc_t *lmc_rxdescs;
- tulip_desc_t *lmc_txdescs;
-#else
- tulip_desc_t lmc_rxdescs[LMC_RXDESCS];
- tulip_desc_t lmc_txdescs[LMC_TXDESCS];
-#endif
+ lmc_desc_t *lmc_rxdescs;
+ lmc_desc_t *lmc_txdescs;
#if defined(__NetBSD__) && NRND > 0
rndsource_element_t lmc_rndsource;
#endif
@@ -354,6 +385,36 @@ struct lmc___softc {
char lmc_timing; /* for HSSI and SSI */
u_int16_t t1_alarm1_status;
u_int16_t t1_alarm2_status;
+#if defined(LMC_DEBUG)
+ /*
+ * Debugging/Statistical information
+ */
+ struct {
+ lmc_media_t dbg_last_media;
+ u_int32_t dbg_intrs;
+ u_int32_t dbg_media_probes;
+ u_int32_t dbg_txprobe_nocarr;
+ u_int32_t dbg_txprobe_exccoll;
+ u_int32_t dbg_link_downed;
+ u_int32_t dbg_link_suspected;
+ u_int32_t dbg_link_intrs;
+ u_int32_t dbg_link_pollintrs;
+ u_int32_t dbg_link_failures;
+ u_int32_t dbg_nway_starts;
+ u_int32_t dbg_nway_failures;
+ u_int16_t dbg_phyregs[32][4];
+ u_int32_t dbg_rxlowbufs;
+ u_int32_t dbg_rxintrs;
+ u_int32_t dbg_last_rxintrs;
+ u_int32_t dbg_high_rxintrs_hz;
+ u_int32_t dbg_no_txmaps;
+ u_int32_t dbg_txput_finishes[8];
+ u_int32_t dbg_txprobes_ok;
+ u_int32_t dbg_txprobes_failed;
+ u_int32_t dbg_events[LMC_MEDIAPOLL_MAX];
+ u_int32_t dbg_rxpktsperintr[LMC_RXDESCS];
+ } lmc_dbg;
+#endif
};
/*
@@ -424,6 +485,7 @@ static const char * const lmc_system_errors[] = {
"reserved #7",
};
+#if 0
static const char * const lmc_status_bits[] = {
NULL,
"transmit process stopped",
@@ -444,12 +506,51 @@ static const char * const lmc_status_bits[] = {
NULL,
NULL,
};
+#endif
/*
* This driver supports a maximum of 32 devices.
*/
#define LMC_MAX_DEVICES 32
+#define LMC_RXDESC_PRESYNC(sc, di, s) \
+ bus_dmamap_sync((sc)->lmc_dmatag, (sc)->lmc_rxdescmap, \
+ (caddr_t) di - (caddr_t) (sc)->lmc_rxdescs, \
+ (s), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
+#define LMC_RXDESC_POSTSYNC(sc, di, s) \
+ bus_dmamap_sync((sc)->lmc_dmatag, (sc)->lmc_rxdescmap, \
+ (caddr_t) di - (caddr_t) (sc)->lmc_rxdescs, \
+ (s), BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
+#define LMC_RXMAP_PRESYNC(sc, map) \
+ bus_dmamap_sync((sc)->lmc_dmatag, (map), 0, (map)->dm_mapsize, \
+ BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
+#define LMC_RXMAP_POSTSYNC(sc, map) \
+ bus_dmamap_sync((sc)->lmc_dmatag, (map), 0, (map)->dm_mapsize, \
+ BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
+#define LMC_RXMAP_CREATE(sc, mapp) \
+ bus_dmamap_create((sc)->lmc_dmatag, LMC_RX_BUFLEN, 2, \
+ LMC_DATA_PER_DESC, 0, \
+ BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, (mapp))
+
+#define LMC_TXDESC_PRESYNC(sc, di, s) \
+ bus_dmamap_sync((sc)->lmc_dmatag, (sc)->lmc_txdescmap, \
+ (caddr_t) di - (caddr_t) (sc)->lmc_txdescs, \
+ (s), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
+#define LMC_TXDESC_POSTSYNC(sc, di, s) \
+ bus_dmamap_sync((sc)->lmc_dmatag, (sc)->lmc_txdescmap, \
+ (caddr_t) di - (caddr_t) (sc)->lmc_txdescs, \
+ (s), BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
+#define LMC_TXMAP_PRESYNC(sc, map) \
+ bus_dmamap_sync((sc)->lmc_dmatag, (map), 0, (map)->dm_mapsize, \
+ BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
+#define LMC_TXMAP_POSTSYNC(sc, map) \
+ bus_dmamap_sync((sc)->lmc_dmatag, (map), 0, (map)->dm_mapsize, \
+ BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
+#define LMC_TXMAP_CREATE(sc, mapp) \
+ bus_dmamap_create((sc)->lmc_dmatag, LMC_DATA_PER_DESC, \
+ LMC_MAX_TXSEG, LMC_DATA_PER_DESC, \
+ 0, BUS_DMA_NOWAIT, (mapp))
+
#if defined(__FreeBSD__)
typedef void ifnet_ret_t;
typedef int ioctl_cmd_t;
@@ -507,10 +608,6 @@ extern struct cfdriver lmc_cd;
#define loudprintf printf
#define LMC_PRINTF_FMT "%s"
#define LMC_PRINTF_ARGS sc->lmc_xname
-#if defined(__alpha__)
-/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
-#define LMC_KVATOPHYS(sc, va) alpha_XXX_dmamap((vm_offset_t)(va))
-#endif
#endif /* __NetBSD__ */
#ifndef LMC_PRINTF_FMT
@@ -541,12 +638,8 @@ extern struct cfdriver lmc_cd;
#endif
#endif
-#if !defined(LMC_KVATOPHYS)
-#define LMC_KVATOPHYS(sc, va) vtophys(va)
-#endif
-
#ifndef LMC_RAISESPL
-#define LMC_RAISESPL() splimp()
+#define LMC_RAISESPL() splnet()
#endif
#ifndef LMC_RAISESOFTSPL
#define LMC_RAISESOFTSPL() splnet()
@@ -586,3 +679,6 @@ extern struct cfdriver lmc_cd;
&& ((u_int16_t *)a1)[2] == 0xFFFFU)
typedef int lmc_spl_t;
+
+#define LMC_GETCTX(m, t) ((t) (m)->m_pkthdr.rcvif + 0)
+#define LMC_SETCTX(m, c) ((void) ((m)->m_pkthdr.rcvif = (void *) (c)))