Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/qbus Redo previous in a better way:
details: https://anonhg.NetBSD.org/src/rev/4b84c30eacef
branches: trunk
changeset: 541721:4b84c30eacef
user: bouyer <bouyer%NetBSD.org@localhost>
date: Fri Jan 17 15:45:59 2003 +0000
description:
Redo previous in a better way:
allocate a static buffer, which is added at the end of short packets
to pad the buffer to ETHER_MIN_LEN - ETHER_CRC_LEN.
While I'm there fix 2 bugs:
in qeinit(), unload the right dmamap if bus_dmamap_load fails
in qestart, don't dmamap_load the mbuf if its len is 0.
Tested on simh-vax.
diffstat:
sys/dev/qbus/if_qe.c | 78 ++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 57 insertions(+), 21 deletions(-)
diffs (194 lines):
diff -r 78c8f652187b -r 4b84c30eacef sys/dev/qbus/if_qe.c
--- a/sys/dev/qbus/if_qe.c Fri Jan 17 15:41:05 2003 +0000
+++ b/sys/dev/qbus/if_qe.c Fri Jan 17 15:45:59 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_qe.c,v 1.56 2003/01/15 22:10:25 bouyer Exp $ */
+/* $NetBSD: if_qe.c,v 1.57 2003/01/17 15:45:59 bouyer Exp $ */
/*
* Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
*
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_qe.c,v 1.56 2003/01/15 22:10:25 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_qe.c,v 1.57 2003/01/17 15:45:59 bouyer Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@@ -95,6 +95,7 @@
struct mbuf* sc_rxmbuf[RXDESCS];
bus_dmamap_t sc_xmtmap[TXDESCS];
bus_dmamap_t sc_rcvmap[RXDESCS];
+ bus_dmamap_t sc_nulldmamap; /* ethernet padding buffer */
struct ubinfo sc_ui;
int sc_intvec; /* Interrupt vector */
int sc_nexttx;
@@ -125,6 +126,8 @@
#define LOWORD(x) ((int)(x) & 0xffff)
#define HIWORD(x) (((int)(x) >> 16) & 0x3f)
+#define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
+
/*
* Check for present DEQNA. Done by sending a fake setup packet
* and wait for interrupt.
@@ -215,6 +218,7 @@
struct qe_ring *rp;
u_int8_t enaddr[ETHER_ADDR_LEN];
int i, error;
+ char *nullbuf;
sc->sc_iot = ua->ua_iot;
sc->sc_ioh = ua->ua_ioh;
@@ -224,7 +228,7 @@
* Allocate DMA safe memory for descriptors and setup memory.
*/
- sc->sc_ui.ui_size = sizeof(struct qe_cdata);
+ sc->sc_ui.ui_size = sizeof(struct qe_cdata) + ETHER_PAD_LEN;
if ((error = ubmemalloc((struct uba_softc *)parent, &sc->sc_ui, 0))) {
printf(": unable to ubmemalloc(), error = %d\n", error);
return;
@@ -235,7 +239,8 @@
/*
* Zero the newly allocated memory.
*/
- bzero(sc->sc_qedata, sizeof(struct qe_cdata));
+ bzero(sc->sc_qedata, sizeof(struct qe_cdata) + ETHER_PAD_LEN);
+ nullbuf = ((char*)sc->sc_qedata) + sizeof(struct qe_cdata);
/*
* Create the transmit descriptor DMA maps. We take advantage
* of the fact that the Qbus address space is big, and therefore
@@ -275,6 +280,21 @@
}
}
+ if ((error = bus_dmamap_create(sc->sc_dmat, ETHER_PAD_LEN, 1,
+ ETHER_PAD_LEN, 0, BUS_DMA_NOWAIT,&sc->sc_nulldmamap)) != 0) {
+ printf("%s: unable to create pad buffer DMA map, "
+ "error = %d\n", sc->sc_dev.dv_xname, error);
+ goto fail_6;
+ }
+ if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_nulldmamap,
+ nullbuf, ETHER_PAD_LEN, NULL, BUS_DMA_NOWAIT)) != 0) {
+ printf("%s: unable to load pad buffer DMA map, "
+ "error = %d\n", sc->sc_dev.dv_xname, error);
+ goto fail_7;
+ }
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_nulldmamap, 0, ETHER_PAD_LEN,
+ BUS_DMASYNC_PREWRITE);
+
/*
* Create ring loops of the buffer chains.
* This is only done once.
@@ -338,10 +358,12 @@
* Free any resources we've allocated during the failed attach
* attempt. Do this in reverse order and fall through.
*/
+ fail_7:
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_nulldmamap);
fail_6:
for (i = 0; i < RXDESCS; i++) {
if (sc->sc_rxmbuf[i] != NULL) {
- bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[i]);
+ bus_dmamap_unload(sc->sc_dmat, sc->sc_rcvmap[i]);
m_freem(sc->sc_rxmbuf[i]);
}
}
@@ -427,7 +449,7 @@
struct qe_cdata *qc = sc->sc_qedata;
paddr_t buffer;
struct mbuf *m, *m0;
- int idx, len, s, i, totlen, error;
+ int idx, len, s, i, totlen, buflen, error;
short orword, csr;
if ((QE_RCSR(QE_CSR_CSR) & QE_RCV_ENABLE) == 0)
@@ -452,6 +474,11 @@
for (m0 = m, i = 0; m0; m0 = m0->m_next)
if (m0->m_len)
i++;
+ if (m->m_pkthdr.len < ETHER_PAD_LEN) {
+ buflen = ETHER_PAD_LEN;
+ i++;
+ } else
+ buflen = m->m_pkthdr.len;
if (i >= TXDESCS)
panic("qestart");
@@ -471,20 +498,26 @@
* Loop around and set it.
*/
totlen = 0;
- for (m0 = m; m0; m0 = m0->m_next) {
- error = bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[idx],
- mtod(m0, void *), m0->m_len, 0, 0);
- buffer = sc->sc_xmtmap[idx]->dm_segs[0].ds_addr;
- len = m0->m_len;
- if (len == 0)
- continue;
+ for (m0 = m; ; m0 = m0->m_next) {
+ if (m0) {
+ if (m0->m_len == 0)
+ continue;
+ error = bus_dmamap_load(sc->sc_dmat,
+ sc->sc_xmtmap[idx], mtod(m0, void *),
+ m0->m_len, 0, 0);
+ buffer = sc->sc_xmtmap[idx]->dm_segs[0].ds_addr;
+ len = m0->m_len;
+ } else if (totlen < ETHER_PAD_LEN) {
+ buffer = sc->sc_nulldmamap->dm_segs[0].ds_addr;
+ len = ETHER_PAD_LEN - totlen;
+ } else {
+ break;
+ }
totlen += len;
/* Word alignment calc */
orword = 0;
- if (totlen == m->m_pkthdr.len) {
- if (totlen < ETHER_MIN_LEN)
- len += (ETHER_MIN_LEN - totlen);
+ if (totlen == buflen) {
orword |= QE_EOMSG;
sc->sc_txmbuf[idx] = m;
}
@@ -494,8 +527,6 @@
orword |= QE_ODDBEGIN;
if ((buffer + len) & 1)
orword |= QE_ODDEND;
- if (len > m0->m_len) {
- memset(buffer + m0->m_len, 0, len - m0->m_len);
qc->qc_xmit[idx].qe_buf_len = -(len/2);
qc->qc_xmit[idx].qe_addr_lo = LOWORD(buffer);
qc->qc_xmit[idx].qe_addr_hi = HIWORD(buffer);
@@ -505,9 +536,11 @@
if (++idx == TXDESCS)
idx = 0;
sc->sc_inq++;
+ if (m0 == NULL)
+ break;
}
#ifdef DIAGNOSTIC
- if (totlen != m->m_pkthdr.len)
+ if (totlen != buflen)
panic("qestart: len fault");
#endif
@@ -583,10 +616,13 @@
if (qc->qc_xmit[idx].qe_addr_hi & QE_SETUP)
continue;
- bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[idx]);
+ if (sc->sc_txmbuf[idx] == NULL ||
+ sc->sc_txmbuf[idx]->m_pkthdr.len < ETHER_PAD_LEN)
+ bus_dmamap_unload(sc->sc_dmat,
+ sc->sc_xmtmap[idx]);
if (sc->sc_txmbuf[idx]) {
m_freem(sc->sc_txmbuf[idx]);
- sc->sc_txmbuf[idx] = 0;
+ sc->sc_txmbuf[idx] = NULL;
}
}
ifp->if_timer = 0;
Home |
Main Index |
Thread Index |
Old Index