summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2006-08-05 21:03:23 +0000
committerBrad Smith <brad@cvs.openbsd.org>2006-08-05 21:03:23 +0000
commitc1e52cec9c4ff6e5effd5ec092f354a270ec24e0 (patch)
treed384ba19396ffeb4c9430a70dcff5e83bc01ce93
parent15518a6f4c640a3ef231c948f0d3e77bb3eecee8 (diff)
- restructure the TX descriptor handling code to decouple the
number of TX descriptors, the number of RX descriptors, and the number of mbufs. - bump the number of TX descriptors for the rtl8169 chipset. From yamt@NetBSD
-rw-r--r--sys/dev/ic/re.c236
-rw-r--r--sys/dev/ic/rtl81x9reg.h47
2 files changed, 157 insertions, 126 deletions
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c
index feabebe7f15..8845422cdd6 100644
--- a/sys/dev/ic/re.c
+++ b/sys/dev/ic/re.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: re.c,v 1.37 2006/08/05 16:53:16 brad Exp $ */
+/* $OpenBSD: re.c,v 1.38 2006/08/05 21:03:22 brad Exp $ */
/* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -660,10 +660,12 @@ re_diag(struct rl_softc *sc)
dmamap = sc->rl_ldata.rl_rx_list_map;
bus_dmamap_sync(sc->sc_dmat,
- dmamap, 0, dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ dmamap, 0, dmamap->dm_mapsize,
+ BUS_DMASYNC_POSTREAD);
dmamap = sc->rl_ldata.rl_rx_dmamap[0];
- bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
- BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_sync(sc->sc_dmat,
+ dmamap, 0, dmamap->dm_mapsize,
+ BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->sc_dmat,
sc->rl_ldata.rl_rx_dmamap[0]);
@@ -753,13 +755,18 @@ re_attach(struct rl_softc *sc)
eaddr[(i * 2) + 1] = as[i] >> 8;
}
- /* Set RX length mask */
+ /*
+ * Set RX length mask, TX poll request register
+ * and TX descriptor count.
+ */
if (sc->rl_type == RL_8169) {
sc->rl_rxlenmask = RL_RDESC_STAT_GFRAGLEN;
sc->rl_txstart = RL_GTXSTART;
+ sc->rl_ldata.rl_tx_desc_cnt = RL_TX_DESC_CNT_8169;
} else {
sc->rl_rxlenmask = RL_RDESC_STAT_FRAGLEN;
sc->rl_txstart = RL_TXSTART;
+ sc->rl_ldata.rl_tx_desc_cnt = RL_TX_DESC_CNT_8139;
}
bcopy(eaddr, (char *)&sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
@@ -767,8 +774,14 @@ re_attach(struct rl_softc *sc)
printf(", address %s\n",
ether_sprintf(sc->sc_arpcom.ac_enaddr));
+ if (sc->rl_ldata.rl_tx_desc_cnt >
+ PAGE_SIZE / sizeof(struct rl_desc)) {
+ sc->rl_ldata.rl_tx_desc_cnt =
+ PAGE_SIZE / sizeof(struct rl_desc);
+ }
+
/* Allocate DMA'able memory for the TX ring */
- if ((error = bus_dmamem_alloc(sc->sc_dmat, RL_TX_LIST_SZ,
+ if ((error = bus_dmamem_alloc(sc->sc_dmat, RL_TX_LIST_SZ(sc),
RE_ETHER_ALIGN, 0, &sc->rl_ldata.rl_tx_listseg, 1,
&sc->rl_ldata.rl_tx_listnseg, BUS_DMA_NOWAIT)) != 0) {
printf("%s: can't allocate tx listseg, error = %d\n",
@@ -778,17 +791,17 @@ re_attach(struct rl_softc *sc)
/* Load the map for the TX ring. */
if ((error = bus_dmamem_map(sc->sc_dmat, &sc->rl_ldata.rl_tx_listseg,
- sc->rl_ldata.rl_tx_listnseg, RL_TX_LIST_SZ,
+ sc->rl_ldata.rl_tx_listnseg, RL_TX_LIST_SZ(sc),
(caddr_t *)&sc->rl_ldata.rl_tx_list,
BUS_DMA_NOWAIT)) != 0) {
printf("%s: can't map tx list, error = %d\n",
sc->sc_dev.dv_xname, error);
goto fail_1;
}
- memset(sc->rl_ldata.rl_tx_list, 0, RL_TX_LIST_SZ);
+ memset(sc->rl_ldata.rl_tx_list, 0, RL_TX_LIST_SZ(sc));
- if ((error = bus_dmamap_create(sc->sc_dmat, RL_TX_LIST_SZ, 1,
- RL_TX_LIST_SZ, 0, BUS_DMA_ALLOCNOW,
+ if ((error = bus_dmamap_create(sc->sc_dmat, RL_TX_LIST_SZ(sc), 1,
+ RL_TX_LIST_SZ(sc), 0, BUS_DMA_ALLOCNOW,
&sc->rl_ldata.rl_tx_list_map)) != 0) {
printf("%s: can't create tx list map, error = %d\n",
sc->sc_dev.dv_xname, error);
@@ -797,17 +810,19 @@ re_attach(struct rl_softc *sc)
if ((error = bus_dmamap_load(sc->sc_dmat,
sc->rl_ldata.rl_tx_list_map, sc->rl_ldata.rl_tx_list,
- RL_TX_LIST_SZ, NULL, BUS_DMA_NOWAIT)) != 0) {
+ RL_TX_LIST_SZ(sc), NULL, BUS_DMA_NOWAIT)) != 0) {
printf("%s: can't load tx list, error = %d\n",
sc->sc_dev.dv_xname, error);
goto fail_3;
}
/* Create DMA maps for TX buffers */
- for (i = 0; i < RL_TX_DESC_CNT; i++) {
- error = bus_dmamap_create(sc->sc_dmat, MCLBYTES * RL_NTXSEGS,
- RL_NTXSEGS, MCLBYTES, 0, BUS_DMA_ALLOCNOW,
- &sc->rl_ldata.rl_tx_dmamap[i]);
+ for (i = 0; i < RL_TX_QLEN; i++) {
+ error = bus_dmamap_create(sc->sc_dmat,
+ RL_JUMBO_FRAMELEN,
+ RL_TX_DESC_CNT(sc) - 4, RL_TDESC_CMD_FRAGLEN,
+ 0, BUS_DMA_ALLOCNOW,
+ &sc->rl_ldata.rl_txq[i].txq_dmamap);
if (error) {
printf("%s: can't create DMA map for TX\n",
sc->sc_dev.dv_xname);
@@ -876,7 +891,7 @@ re_attach(struct rl_softc *sc)
ifp->if_hardmtu = RL_JUMBO_MTU;
} else
ifp->if_baudrate = 100000000;
- IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN);
+ IFQ_SET_MAXLEN(&ifp->if_snd, RL_TX_QLEN);
IFQ_SET_READY(&ifp->if_snd);
ifp->if_capabilities = IFCAP_VLAN_MTU;
@@ -899,7 +914,6 @@ re_attach(struct rl_softc *sc)
sc->sc_mii.mii_statchg = re_miibus_statchg;
ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, re_ifmedia_upd,
re_ifmedia_sts);
- DPRINTF(("calling mii_attach\n"));
mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
MII_OFFSET_ANY, 0);
if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
@@ -933,8 +947,7 @@ re_attach(struct rl_softc *sc)
}
#endif
- DPRINTF(("leaving re_attach\n"));
- return (1);
+ return (0);
fail_8:
/* Destroy DMA maps for RX buffers. */
@@ -957,10 +970,10 @@ fail_5:
fail_4:
/* Destroy DMA maps for TX buffers. */
- for (i = 0; i < RL_TX_DESC_CNT; i++) {
- if (sc->rl_ldata.rl_tx_dmamap[i] != NULL)
+ for (i = 0; i < RL_TX_QLEN; i++) {
+ if (sc->rl_ldata.rl_txq[i].txq_dmamap != NULL)
bus_dmamap_destroy(sc->sc_dmat,
- sc->rl_ldata.rl_tx_dmamap[i]);
+ sc->rl_ldata.rl_txq[i].txq_dmamap);
}
/* Free DMA'able memory for the TX ring. */
@@ -969,7 +982,7 @@ fail_3:
bus_dmamap_destroy(sc->sc_dmat, sc->rl_ldata.rl_tx_list_map);
fail_2:
bus_dmamem_unmap(sc->sc_dmat,
- (caddr_t)sc->rl_ldata.rl_tx_list, RL_TX_LIST_SZ);
+ (caddr_t)sc->rl_ldata.rl_tx_list, RL_TX_LIST_SZ(sc));
fail_1:
bus_dmamem_free(sc->sc_dmat,
&sc->rl_ldata.rl_tx_listseg, sc->rl_ldata.rl_tx_listnseg);
@@ -1019,7 +1032,8 @@ re_newbuf(struct rl_softc *sc, int idx, struct mbuf *m)
map = sc->rl_ldata.rl_rx_dmamap[idx];
- error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT);
+ error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m,
+ BUS_DMA_READ|BUS_DMA_NOWAIT);
if (error)
goto out;
@@ -1030,13 +1044,10 @@ re_newbuf(struct rl_softc *sc, int idx, struct mbuf *m)
cmdstat = map->dm_segs[0].ds_len;
d->rl_bufaddr_lo = htole32(RL_ADDR_LO(map->dm_segs[0].ds_addr));
d->rl_bufaddr_hi = htole32(RL_ADDR_HI(map->dm_segs[0].ds_addr));
- cmdstat |= RL_TDESC_CMD_SOF;
if (idx == (RL_RX_DESC_CNT - 1))
- cmdstat |= RL_TDESC_CMD_EOR;
+ cmdstat |= RL_RDESC_CMD_EOR;
d->rl_cmdstat = htole32(cmdstat);
- d->rl_cmdstat |= htole32(RL_TDESC_CMD_EOF);
-
sc->rl_ldata.rl_rx_list[idx].rl_cmdstat |= htole32(RL_RDESC_CMD_OWN);
sc->rl_ldata.rl_rx_mbuf[idx] = m;
@@ -1071,16 +1082,20 @@ re_fixup_rx(struct mbuf *m)
int
re_tx_list_init(struct rl_softc *sc)
{
- memset((char *)sc->rl_ldata.rl_tx_list, 0, RL_TX_LIST_SZ);
- memset((char *)&sc->rl_ldata.rl_tx_mbuf, 0,
- (RL_TX_DESC_CNT * sizeof(struct mbuf *)));
+ int i;
+
+ memset(sc->rl_ldata.rl_tx_list, 0, RL_TX_LIST_SZ(sc));
+ for (i = 0; i < RL_TX_QLEN; i++) {
+ sc->rl_ldata.rl_txq[i].txq_mbuf = NULL;
+ }
bus_dmamap_sync(sc->sc_dmat,
sc->rl_ldata.rl_tx_list_map, 0,
sc->rl_ldata.rl_tx_list_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
- sc->rl_ldata.rl_tx_prodidx = 0;
- sc->rl_ldata.rl_tx_considx = 0;
- sc->rl_ldata.rl_tx_free = RL_TX_DESC_CNT;
+ sc->rl_ldata.rl_txq_prodidx = 0;
+ sc->rl_ldata.rl_txq_considx = 0;
+ sc->rl_ldata.rl_tx_free = RL_TX_DESC_CNT(sc);
+ sc->rl_ldata.rl_tx_nextfree = 0;
return (0);
}
@@ -1147,7 +1162,7 @@ re_rxeof(struct rl_softc *sc)
bus_dmamap_sync(sc->sc_dmat,
sc->rl_ldata.rl_rx_dmamap[i],
0, sc->rl_ldata.rl_rx_dmamap[i]->dm_mapsize,
- BUS_DMASYNC_POSTWRITE);
+ BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->sc_dmat,
sc->rl_ldata.rl_rx_dmamap[i]);
@@ -1161,7 +1176,7 @@ re_rxeof(struct rl_softc *sc)
sc->rl_tail = m;
}
re_newbuf(sc, i, NULL);
- RL_DESC_INC(i);
+ RL_RX_DESC_INC(sc, i);
continue;
}
@@ -1200,7 +1215,7 @@ re_rxeof(struct rl_softc *sc)
sc->rl_head = sc->rl_tail = NULL;
}
re_newbuf(sc, i, m);
- RL_DESC_INC(i);
+ RL_RX_DESC_INC(sc, i);
continue;
}
@@ -1216,11 +1231,11 @@ re_rxeof(struct rl_softc *sc)
sc->rl_head = sc->rl_tail = NULL;
}
re_newbuf(sc, i, m);
- RL_DESC_INC(i);
+ RL_RX_DESC_INC(sc, i);
continue;
}
- RL_DESC_INC(i);
+ RL_RX_DESC_INC(sc, i);
if (sc->rl_head != NULL) {
m->m_len = total_len % RE_RX_DESC_BUFLEN;
@@ -1289,11 +1304,10 @@ void
re_txeof(struct rl_softc *sc)
{
struct ifnet *ifp;
- u_int32_t txstat;
int idx;
ifp = &sc->sc_arpcom.ac_if;
- idx = sc->rl_ldata.rl_tx_considx;
+ idx = sc->rl_ldata.rl_txq_considx;
/* Invalidate the TX descriptor list */
@@ -1302,39 +1316,43 @@ re_txeof(struct rl_softc *sc)
0, sc->rl_ldata.rl_tx_list_map->dm_mapsize,
BUS_DMASYNC_POSTREAD);
- while (idx != sc->rl_ldata.rl_tx_prodidx) {
- txstat = letoh32(sc->rl_ldata.rl_tx_list[idx].rl_cmdstat);
+ while (/* CONSTCOND */ 1) {
+ struct rl_txq *txq = &sc->rl_ldata.rl_txq[idx];
+ int descidx;
+ u_int32_t txstat;
+
+ if (txq->txq_mbuf == NULL) {
+ KASSERT(idx == sc->rl_ldata.rl_txq_prodidx);
+ break;
+ }
+
+ descidx = txq->txq_descidx;
+ txstat =
+ letoh32(sc->rl_ldata.rl_tx_list[descidx].rl_cmdstat);
+ KASSERT((txstat & RL_TDESC_CMD_EOF) != 0);
if (txstat & RL_TDESC_CMD_OWN)
break;
- /*
- * We only stash mbufs in the last descriptor
- * in a fragment chain, which also happens to
- * be the only place where the TX status bits
- * are valid.
- */
+ sc->rl_ldata.rl_tx_free += txq->txq_dmamap->dm_nsegs;
+ KASSERT(sc->rl_ldata.rl_tx_free <= RL_TX_DESC_CNT(sc));
+ bus_dmamap_unload(sc->sc_dmat, txq->txq_dmamap);
+ m_freem(txq->txq_mbuf);
+ txq->txq_mbuf = NULL;
- if (txstat & RL_TDESC_CMD_EOF) {
- m_freem(sc->rl_ldata.rl_tx_mbuf[idx]);
- sc->rl_ldata.rl_tx_mbuf[idx] = NULL;
- bus_dmamap_unload(sc->sc_dmat,
- sc->rl_ldata.rl_tx_dmamap[idx]);
- if (txstat & (RL_TDESC_STAT_EXCESSCOL|
- RL_TDESC_STAT_COLCNT))
- ifp->if_collisions++;
- if (txstat & RL_TDESC_STAT_TXERRSUM)
- ifp->if_oerrors++;
- else
- ifp->if_opackets++;
- }
- sc->rl_ldata.rl_tx_free++;
- RL_DESC_INC(idx);
+ if (txstat & (RL_TDESC_STAT_EXCESSCOL | RL_TDESC_STAT_COLCNT))
+ ifp->if_collisions++;
+ if (txstat & RL_TDESC_STAT_TXERRSUM)
+ ifp->if_oerrors++;
+ else
+ ifp->if_opackets++;
+
+ idx = (idx + 1) % RL_TX_QLEN;
}
/* No changes made to the TX ring, so no flush needed */
- if (idx != sc->rl_ldata.rl_tx_considx) {
- sc->rl_ldata.rl_tx_considx = idx;
+ if (idx != sc->rl_ldata.rl_txq_considx) {
+ sc->rl_ldata.rl_txq_considx = idx;
ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_timer = 0;
}
@@ -1345,7 +1363,7 @@ re_txeof(struct rl_softc *sc)
* interrupt that will cause us to re-enter this routine.
* This is done in case the transmitter has gone idle.
*/
- if (sc->rl_ldata.rl_tx_free != RL_TX_DESC_CNT)
+ if (sc->rl_ldata.rl_tx_free != RL_TX_DESC_CNT(sc))
CSR_WRITE_4(sc, RL_TIMERCNT, 1);
}
@@ -1440,12 +1458,13 @@ int
re_encap(struct rl_softc *sc, struct mbuf *m, int *idx)
{
bus_dmamap_t map;
- int error, i, curidx;
+ int error, i, startidx, curidx;
#ifdef RE_VLAN
struct m_tag *mtag;
#endif
struct rl_desc *d;
u_int32_t cmdstat, rl_flags = 0;
+ struct rl_txq *txq;
if (sc->rl_ldata.rl_tx_free <= 4)
return (EFBIG);
@@ -1474,9 +1493,10 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx)
}
#endif
- map = sc->rl_ldata.rl_tx_dmamap[*idx];
-
- error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT);
+ txq = &sc->rl_ldata.rl_txq[*idx];
+ map = txq->txq_dmamap;
+ error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m,
+ BUS_DMA_WRITE|BUS_DMA_NOWAIT);
if (error) {
/* XXX try to defrag if EFBIG? */
printf("%s: can't map mbuf (error %d)\n",
@@ -1490,6 +1510,13 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx)
}
/*
+ * Make sure that the caches are synchronized before we
+ * ask the chip to start DMA for the packet data.
+ */
+ bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
+ BUS_DMASYNC_PREWRITE);
+
+ /*
* Map the segment array into descriptors. Note that we set the
* start-of-frame and end-of-frame markers for either TX or RX, but
* they really only have meaning in the TX case. (In the RX case,
@@ -1501,14 +1528,14 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx)
* reception.)
*/
i = 0;
- curidx = *idx;
+ curidx = startidx = sc->rl_ldata.rl_tx_nextfree;
while (1) {
d = &sc->rl_ldata.rl_tx_list[curidx];
- if (letoh32(d->rl_cmdstat) & RL_RDESC_STAT_OWN) {
+ if (letoh32(d->rl_cmdstat) & RL_TDESC_STAT_OWN) {
while (i > 0) {
sc->rl_ldata.rl_tx_list[
- (curidx + RL_TX_DESC_CNT - i) %
- RL_TX_DESC_CNT].rl_cmdstat = 0;
+ (curidx + RL_TX_DESC_CNT(sc) - i) %
+ RL_TX_DESC_CNT(sc)].rl_cmdstat = 0;
i--;
}
error = ENOBUFS;
@@ -1524,26 +1551,18 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx)
cmdstat |= RL_TDESC_CMD_SOF;
else
cmdstat |= RL_TDESC_CMD_OWN;
- if (curidx == (RL_RX_DESC_CNT - 1))
+ if (curidx == (RL_TX_DESC_CNT(sc) - 1))
cmdstat |= RL_TDESC_CMD_EOR;
d->rl_cmdstat = htole32(cmdstat | rl_flags);
i++;
if (i == map->dm_nsegs)
break;
- RL_DESC_INC(curidx);
+ RL_TX_DESC_INC(sc, curidx);
}
d->rl_cmdstat |= htole32(RL_TDESC_CMD_EOF);
- /*
- * Ensure that the map for this transmission
- * is placed at the array index of the last descriptor
- * in this chain. (Swap last and first dmamaps.)
- */
- sc->rl_ldata.rl_tx_dmamap[*idx] =
- sc->rl_ldata.rl_tx_dmamap[curidx];
- sc->rl_ldata.rl_tx_dmamap[curidx] = map;
- sc->rl_ldata.rl_tx_mbuf[curidx] = m;
+ txq->txq_mbuf = m;
sc->rl_ldata.rl_tx_free -= map->dm_nsegs;
/*
@@ -1562,19 +1581,16 @@ re_encap(struct rl_softc *sc, struct mbuf *m, int *idx)
/* Transfer ownership of packet to the chip. */
- bus_dmamap_sync(sc->sc_dmat,
- sc->rl_ldata.rl_tx_dmamap[curidx],
- 0, sc->rl_ldata.rl_tx_dmamap[curidx]->dm_mapsize,
- BUS_DMASYNC_PREWRITE);
-
sc->rl_ldata.rl_tx_list[curidx].rl_cmdstat |=
htole32(RL_TDESC_CMD_OWN);
- if (*idx != curidx)
- sc->rl_ldata.rl_tx_list[*idx].rl_cmdstat |=
+ if (startidx != curidx)
+ sc->rl_ldata.rl_tx_list[startidx].rl_cmdstat |=
htole32(RL_TDESC_CMD_OWN);
- RL_DESC_INC(curidx);
- *idx = curidx;
+ txq->txq_descidx = curidx;
+ RL_TX_DESC_INC(sc, curidx);
+ sc->rl_ldata.rl_tx_nextfree = curidx;
+ *idx = (*idx + 1) % RL_TX_QLEN;
return (0);
@@ -1599,8 +1615,8 @@ re_start(struct ifnet *ifp)
if (!sc->rl_link || ifp->if_flags & IFF_OACTIVE)
return;
- idx = sc->rl_ldata.rl_tx_prodidx;
- while (sc->rl_ldata.rl_tx_mbuf[idx] == NULL) {
+ idx = sc->rl_ldata.rl_txq_prodidx;
+ while (/* CONSTCOND */ 1) {
struct mbuf *m;
int error;
@@ -1608,9 +1624,15 @@ re_start(struct ifnet *ifp)
if (m == NULL)
break;
+ if (sc->rl_ldata.rl_txq[idx].txq_mbuf != NULL) {
+ KASSERT(idx == sc->rl_ldata.rl_txq_considx);
+ ifp->if_flags |= IFF_OACTIVE;
+ break;
+ }
+
error = re_encap(sc, m, &idx);
if (error == EFBIG &&
- sc->rl_ldata.rl_tx_free == RL_TX_DESC_CNT) {
+ sc->rl_ldata.rl_tx_free == RL_TX_DESC_CNT(sc)) {
IFQ_DEQUEUE(&ifp->if_snd, m);
m_freem(m);
ifp->if_oerrors++;
@@ -1637,6 +1659,8 @@ re_start(struct ifnet *ifp)
if (queued == 0)
return;
+ sc->rl_ldata.rl_txq_prodidx = idx;
+
/* Flush the TX descriptors */
bus_dmamap_sync(sc->sc_dmat,
@@ -1644,12 +1668,6 @@ re_start(struct ifnet *ifp)
0, sc->rl_ldata.rl_tx_list_map->dm_mapsize,
BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
- sc->rl_ldata.rl_tx_prodidx = idx;
-
- /*
- * RealTek put the TX poll request register in a different
- * location on the 8169 gigE chip. I don't know why.
- */
CSR_WRITE_2(sc, sc->rl_txstart, RL_TXSTART_START);
/*
@@ -1979,12 +1997,12 @@ re_stop(struct ifnet *ifp, int disable)
}
/* Free the TX list buffers. */
- for (i = 0; i < RL_TX_DESC_CNT; i++) {
- if (sc->rl_ldata.rl_tx_mbuf[i] != NULL) {
+ for (i = 0; i < RL_TX_QLEN; i++) {
+ if (sc->rl_ldata.rl_txq[i].txq_mbuf != NULL) {
bus_dmamap_unload(sc->sc_dmat,
- sc->rl_ldata.rl_tx_dmamap[i]);
- m_freem(sc->rl_ldata.rl_tx_mbuf[i]);
- sc->rl_ldata.rl_tx_mbuf[i] = NULL;
+ sc->rl_ldata.rl_txq[i].txq_dmamap);
+ m_freem(sc->rl_ldata.rl_txq[i].txq_mbuf);
+ sc->rl_ldata.rl_txq[i].txq_mbuf = NULL;
}
}
diff --git a/sys/dev/ic/rtl81x9reg.h b/sys/dev/ic/rtl81x9reg.h
index d072443d22b..019a29ba450 100644
--- a/sys/dev/ic/rtl81x9reg.h
+++ b/sys/dev/ic/rtl81x9reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtl81x9reg.h,v 1.25 2006/07/03 02:28:39 brad Exp $ */
+/* $OpenBSD: rtl81x9reg.h,v 1.26 2006/08/05 21:03:22 brad Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -582,13 +582,13 @@ struct rl_stats {
};
#define RL_RX_DESC_CNT 64
-#define RL_TX_DESC_CNT 64
+#define RL_TX_DESC_CNT_8139 64
+#define RL_TX_DESC_CNT_8169 1024
+
+#define RL_TX_QLEN 64
#define RL_RX_LIST_SZ (RL_RX_DESC_CNT * sizeof(struct rl_desc))
-#define RL_TX_LIST_SZ (RL_TX_DESC_CNT * sizeof(struct rl_desc))
#define RL_RING_ALIGN 256
-#define RL_IFQ_MAXLEN 512
-#define RL_DESC_INC(x) (x = (x + 1) % RL_TX_DESC_CNT)
#define RL_OWN(x) (letoh32((x)->rl_cmdstat) & RL_RDESC_STAT_OWN)
#define RL_RXBYTES(x) (letoh32((x)->rl_cmdstat) & sc->rl_rxlenmask)
#define RL_PKTSZ(x) ((x)/* >> 3*/)
@@ -600,6 +600,15 @@ struct rl_stats {
#define RE_RX_DESC_BUFLEN MCLBYTES
#endif
+#define RL_TX_DESC_CNT(sc) \
+ ((sc)->rl_ldata.rl_tx_desc_cnt)
+#define RL_TX_LIST_SZ(sc) \
+ (RL_TX_DESC_CNT(sc) * sizeof(struct rl_desc))
+#define RL_TX_DESC_INC(sc, x) \
+ ((x) = ((x) + 1) % RL_TX_DESC_CNT(sc))
+#define RL_RX_DESC_INC(sc, x) \
+ ((x) = ((x) + 1) % RL_RX_DESC_CNT)
+
#define RL_ADDR_LO(y) ((u_int64_t) (y) & 0xFFFFFFFF)
#define RL_ADDR_HI(y) ((u_int64_t) (y) >> 32)
@@ -607,8 +616,6 @@ struct rl_stats {
#define RL_JUMBO_FRAMELEN 7440
#define RL_JUMBO_MTU (RL_JUMBO_FRAMELEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
-#define RL_NTXSEGS 32
-
#define MAX_NUM_MULTICAST_ADDRESSES 128
#define RL_INC(x) (x = (x + 1) % RL_TX_LIST_CNT)
@@ -653,22 +660,28 @@ struct rl_mii_frame {
(x)->rl_type == RL_8169)
struct rl_list_data {
- struct mbuf *rl_tx_mbuf[RL_TX_DESC_CNT];
+ struct rl_txq {
+ struct mbuf *txq_mbuf;
+ bus_dmamap_t txq_dmamap;
+ int txq_descidx;
+ } rl_txq[RL_TX_QLEN];
+ int rl_txq_considx;
+ int rl_txq_prodidx;
+ bus_dmamap_t rl_tx_list_map;
+ struct rl_desc *rl_tx_list;
+ bus_dma_segment_t rl_tx_listseg;
+ int rl_tx_free; /* # of free descriptors */
+ int rl_tx_nextfree; /* next descriptor to use */
+ int rl_tx_desc_cnt; /* # of descriptors */
+ int rl_tx_listnseg;
+
struct mbuf *rl_rx_mbuf[RL_RX_DESC_CNT];
- int rl_tx_prodidx;
- int rl_rx_prodidx;
- int rl_tx_considx;
- int rl_tx_free;
- bus_dmamap_t rl_tx_dmamap[RL_TX_DESC_CNT];
bus_dmamap_t rl_rx_dmamap[RL_RX_DESC_CNT];
bus_dmamap_t rl_rx_list_map;
struct rl_desc *rl_rx_list;
bus_dma_segment_t rl_rx_listseg;
+ int rl_rx_prodidx;
int rl_rx_listnseg;
- bus_dmamap_t rl_tx_list_map;
- struct rl_desc *rl_tx_list;
- bus_dma_segment_t rl_tx_listseg;
- int rl_tx_listnseg;
};
struct rl_softc {