summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2000-01-16 16:17:57 +0000
committerJason Wright <jason@cvs.openbsd.org>2000-01-16 16:17:57 +0000
commit0edd59fa80959f48bc18b1a9e7d41f36722c0152 (patch)
tree49a5446db5c150f8bdd22985924726465b0babbc /sys/dev/pci
parent2587d38cdc9088f53720da616d105fa1fe1278d1 (diff)
Merge with FreeBSD:
o add a new routine, dc_coal(), that copies tx data into a single mbuf o use it on the dm910x chips Tested by jsthyer@uncg.edu
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_dc.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/sys/dev/pci/if_dc.c b/sys/dev/pci/if_dc.c
index 3b19de7d7e4..08aba98d684 100644
--- a/sys/dev/pci/if_dc.c
+++ b/sys/dev/pci/if_dc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_dc.c,v 1.8 2000/01/10 04:18:30 jason Exp $ */
+/* $OpenBSD: if_dc.c,v 1.9 2000/01/16 16:17:56 jason Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -31,7 +31,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/sys/pci/if_dc.c,v 1.4 2000/01/03 15:28:46 wpaul Exp $
+ * $FreeBSD: src/sys/pci/if_dc.c,v 1.5 2000/01/12 22:24:05 wpaul Exp $
*/
/*
@@ -181,6 +181,8 @@ void dc_acpi __P((struct device *, void *));
struct dc_type *dc_devtype __P((void *));
int dc_newbuf __P((struct dc_softc *, int, struct mbuf *));
int dc_encap __P((struct dc_softc *, struct mbuf *, u_int32_t *));
+int dc_coal __P((struct dc_softc *, struct mbuf **));
+
void dc_pnic_rx_bug_war __P((struct dc_softc *, int));
int dc_rx_resync __P((struct dc_softc *));
void dc_rxeof __P((struct dc_softc *));
@@ -1368,7 +1370,7 @@ void dc_attach(parent, self, aux)
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9102) {
found = 1;
sc->dc_type = DC_TYPE_DM9102;
- sc->dc_flags |= DC_TX_USE_TX_INTR;
+ sc->dc_flags |= DC_TX_COALESCE|DC_TX_USE_TX_INTR;
sc->dc_flags |= DC_REDUCED_MII_POLL;
sc->dc_pmode = DC_PMODE_MII;
}
@@ -2285,6 +2287,39 @@ int dc_encap(sc, m_head, txidx)
}
/*
+ * Coalesce an mbuf chain into a single mbuf cluster buffer.
+ * Needed for some really badly behaved chips that just can't
+ * do scatter/gather correctly.
+ */
+int dc_coal(sc, m_head)
+ struct dc_softc *sc;
+ struct mbuf **m_head;
+{
+ struct mbuf *m_new, *m;
+
+ m = *m_head;
+ MGETHDR(m_new, M_DONTWAIT, MT_DATA);
+ if (m_new == NULL) {
+ printf("dc%d: no memory for tx list", sc->dc_unit);
+ return(ENOBUFS);
+ }
+ if (m->m_pkthdr.len > MHLEN) {
+ MCLGET(m_new, M_DONTWAIT);
+ if (!(m_new->m_flags & M_EXT)) {
+ m_freem(m_new);
+ printf("dc%d: no memory for tx list", sc->dc_unit);
+ return(ENOBUFS);
+ }
+ }
+ m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t));
+ m_new->m_pkthdr.len = m_new->m_len = m->m_pkthdr.len;
+ m_freem(m);
+ *m_head = m_new;
+
+ return(0);
+}
+
+/*
* Main transmit routine. To avoid having to do mbuf copies, we put pointers
* to the mbuf data regions directly in the transmit lists. We also save a
* copy of the pointers since the transmit list fragment pointers are
@@ -2313,6 +2348,14 @@ void dc_start(ifp)
if (m_head == NULL)
break;
+ if (sc->dc_flags & DC_TX_COALESCE) {
+ if (dc_coal(sc, &m_head)) {
+ IF_PREPEND(&ifp->if_snd, m_head);
+ ifp->if_flags |= IFF_OACTIVE;
+ break;
+ }
+ }
+
if (dc_encap(sc, m_head, &idx)) {
IF_PREPEND(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;