summaryrefslogtreecommitdiff
path: root/sys/dev/ic/xl.c
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2004-10-23 05:12:56 +0000
committerBrad Smith <brad@cvs.openbsd.org>2004-10-23 05:12:56 +0000
commitb1c81e36c54c4e852fec39b886d174970a87fffc (patch)
tree12f8f9491fb415c5f1e5eec11bc7494941535dac /sys/dev/ic/xl.c
parentfd88652636c08d2a788e844a893158fa5e01b70e (diff)
re-add old xl_encap_90xB() for 905B/C cards. removed in rev 1.52.
fixes reported mbuf leaks as well as transmit side breakage on macppc, PR 3892. ok mcbride@
Diffstat (limited to 'sys/dev/ic/xl.c')
-rw-r--r--sys/dev/ic/xl.c81
1 files changed, 70 insertions, 11 deletions
diff --git a/sys/dev/ic/xl.c b/sys/dev/ic/xl.c
index 4b1204e218b..62f24c926eb 100644
--- a/sys/dev/ic/xl.c
+++ b/sys/dev/ic/xl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xl.c,v 1.57 2004/10/02 16:44:23 brad Exp $ */
+/* $OpenBSD: xl.c,v 1.58 2004/10/23 05:12:55 brad Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -153,6 +153,8 @@ int xl_newbuf(struct xl_softc *, struct xl_chain_onefrag *);
void xl_stats_update(void *);
int xl_encap(struct xl_softc *, struct xl_chain *,
struct mbuf * );
+int xl_encap_90xB(struct xl_softc *, struct xl_chain *,
+ struct mbuf * );
void xl_rxeof(struct xl_softc *);
int xl_rx_resync(struct xl_softc *);
void xl_txeof(struct xl_softc *);
@@ -1742,15 +1744,6 @@ reload:
c->xl_ptr->xl_status = htole32(total_len);
c->xl_ptr->xl_next = 0;
-#ifndef XL905B_TXCSUM_BROKEN
- if (m_head->m_pkthdr.csum & M_IPV4_CSUM_OUT)
- c->xl_ptr->xl_status |= htole32(XL_TXSTAT_IPCKSUM);
- if (m_head->m_pkthdr.csum & M_TCPV4_CSUM_OUT)
- c->xl_ptr->xl_status |= htole32(XL_TXSTAT_TCPCKSUM);
- if (m_head->m_pkthdr.csum & M_UDPV4_CSUM_OUT)
- c->xl_ptr->xl_status |= htole32(XL_TXSTAT_UDPCKSUM);
-#endif
-
bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
offsetof(struct xl_list_data, xl_tx_list[0]),
sizeof(struct xl_list) * XL_TX_LIST_CNT,
@@ -1899,6 +1892,72 @@ xl_start(ifp)
return;
}
+int
+xl_encap_90xB(sc, c, m_head)
+ struct xl_softc *sc;
+ struct xl_chain *c;
+ struct mbuf *m_head;
+{
+ struct xl_frag *f = NULL;
+ struct xl_list *d;
+ int frag;
+ bus_dmamap_t map;
+
+ /*
+ * Start packing the mbufs in this chain into
+ * the fragment pointers. Stop when we run out
+ * of fragments or hit the end of the mbuf chain.
+ */
+ map = sc->sc_tx_sparemap;
+ d = c->xl_ptr;
+ d->xl_status = htole32(0);
+ d->xl_next = 0;
+
+ if (bus_dmamap_load_mbuf(sc->sc_dmat, map,
+ m_head, BUS_DMA_NOWAIT) != 0)
+ return (ENOBUFS);
+
+ for (frag = 0; frag < map->dm_nsegs; frag++) {
+ if (frag == XL_MAXFRAGS)
+ break;
+ f = &d->xl_frag[frag];
+ f->xl_addr = htole32(map->dm_segs[frag].ds_addr);
+ f->xl_len = htole32(map->dm_segs[frag].ds_len);
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
+ BUS_DMASYNC_PREWRITE);
+
+ /* sync the old map, and unload it (if necessary) */
+ if (c->map->dm_nsegs != 0) {
+ bus_dmamap_sync(sc->sc_dmat, c->map, 0, c->map->dm_mapsize,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->sc_dmat, c->map);
+ }
+
+ c->xl_mbuf = m_head;
+ sc->sc_tx_sparemap = c->map;
+ c->map = map;
+ c->xl_ptr->xl_frag[frag - 1].xl_len |= htole32(XL_LAST_FRAG);
+ c->xl_ptr->xl_status = htole32(XL_TXSTAT_RND_DEFEAT);
+
+#ifndef XL905B_TXCSUM_BROKEN
+ if (m_head->m_pkthdr.csum & M_IPV4_CSUM_OUT)
+ c->xl_ptr->xl_status |= htole32(XL_TXSTAT_IPCKSUM);
+ if (m_head->m_pkthdr.csum & M_TCPV4_CSUM_OUT)
+ c->xl_ptr->xl_status |= htole32(XL_TXSTAT_TCPCKSUM);
+ if (m_head->m_pkthdr.csum & M_UDPV4_CSUM_OUT)
+ c->xl_ptr->xl_status |= htole32(XL_TXSTAT_UDPCKSUM);
+#endif
+
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
+ offsetof(struct xl_list_data, xl_tx_list[0]),
+ sizeof(struct xl_list) * XL_TX_LIST_CNT,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ return(0);
+}
+
void
xl_start_90xB(ifp)
struct ifnet *ifp;
@@ -1932,7 +1991,7 @@ xl_start_90xB(ifp)
cur_tx = &sc->xl_cdata.xl_tx_chain[idx];
/* Pack the data into the descriptor. */
- error = xl_encap(sc, cur_tx, m_head);
+ error = xl_encap_90xB(sc, cur_tx, m_head);
if (error) {
cur_tx = prev_tx;
continue;