Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/ep93xx dont use TX intrs and various other perf...
details: https://anonhg.NetBSD.org/src/rev/38f9fab53d92
branches: trunk
changeset: 573002:38f9fab53d92
user: joff <joff%NetBSD.org@localhost>
date: Mon Jan 17 02:32:29 2005 +0000
description:
dont use TX intrs and various other performance improvements
diffstat:
sys/arch/arm/ep93xx/epe.c | 200 +++++++++++++++++++++++++-----------------
sys/arch/arm/ep93xx/epereg.h | 4 +-
sys/arch/arm/ep93xx/epevar.h | 3 +-
3 files changed, 122 insertions(+), 85 deletions(-)
diffs (truncated from 420 to 300 lines):
diff -r 5ac36d5a376f -r 38f9fab53d92 sys/arch/arm/ep93xx/epe.c
--- a/sys/arch/arm/ep93xx/epe.c Mon Jan 17 01:48:56 2005 +0000
+++ b/sys/arch/arm/ep93xx/epe.c Mon Jan 17 02:32:29 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: epe.c,v 1.1 2004/12/22 19:11:10 joff Exp $ */
+/* $NetBSD: epe.c,v 1.2 2005/01/17 02:32:29 joff Exp $ */
/*
* Copyright (c) 2004 Jesse Off
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: epe.c,v 1.1 2004/12/22 19:11:10 joff Exp $");
+__KERNEL_RCSID(0, "$NetBSD: epe.c,v 1.2 2005/01/17 02:32:29 joff Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -89,19 +89,34 @@
#include <ipkdb/ipkdb.h>
#endif
+#include <arm/ep93xx/ep93xxreg.h>
#include <arm/ep93xx/epereg.h>
#include <arm/ep93xx/epevar.h>
+#ifndef EPE_FAST
+#define EPE_FAST
+#endif
+#ifndef EPE_FAST
#define EPE_READ(x) \
bus_space_read_4(sc->sc_iot, sc->sc_ioh, (EPE_ ## x))
#define EPE_WRITE(x, y) \
bus_space_write_4(sc->sc_iot, sc->sc_ioh, (EPE_ ## x), (y))
+#define CTRLPAGE_DMASYNC(x, y, z) \
+ bus_dmamap_sync(sc->sc_dmat, sc->ctrlpage_dmamap, (x), (y), (z))
+#else
+#define EPE_READ(x) *(__volatile u_int32_t *) \
+ (EP93XX_AHB_VBASE + EP93XX_AHB_EPE + (EPE_ ## x))
+#define EPE_WRITE(x, y) *(__volatile u_int32_t *) \
+ (EP93XX_AHB_VBASE + EP93XX_AHB_EPE + (EPE_ ## x)) = y
+#define CTRLPAGE_DMASYNC(x, y, z)
+#endif /* ! EPE_FAST */
static int epe_match(struct device *, struct cfdata *, void *);
static void epe_attach(struct device *, struct device *, void *);
static void epe_init(struct epe_softc *);
static int epe_intr(void* arg);
+static int epe_gctx(struct epe_softc *);
static int epe_mediachange(struct ifnet *);
static void epe_mediastatus(struct ifnet *, struct ifmediareq *);
int epe_mii_readreg (struct device *, int, int);
@@ -146,6 +161,54 @@
}
static int
+epe_gctx(struct epe_softc *sc)
+{
+ struct ifnet * ifp = &sc->sc_ec.ec_if;
+ u_int32_t *cur, ndq = 0;
+
+ /* Handle transmit completions */
+ cur = (u_int32_t *)(EPE_READ(TXStsQCurAdd) -
+ sc->ctrlpage_dsaddr + sc->ctrlpage);
+
+ if (sc->TXStsQ_cur != cur) {
+ CTRLPAGE_DMASYNC(TX_QLEN * 2 * sizeof(u_int32_t),
+ TX_QLEN * sizeof(u_int32_t), BUS_DMASYNC_PREREAD);
+ } else {
+ return 0;
+ }
+
+ do {
+ u_int32_t tbi = *sc->TXStsQ_cur & 0x7fff;
+ struct mbuf *m = sc->txq[tbi].m;
+
+ if ((*sc->TXStsQ_cur & TXStsQ_TxWE) == 0) {
+ ifp->if_oerrors++;
+ }
+ bus_dmamap_unload(sc->sc_dmat, sc->txq[tbi].m_dmamap);
+ m_freem(m);
+ do {
+ sc->txq[tbi].m = NULL;
+ ndq++;
+ tbi = (tbi + 1) % TX_QLEN;
+ } while (sc->txq[tbi].m == m);
+
+ ifp->if_opackets++;
+ sc->TXStsQ_cur++;
+ if (sc->TXStsQ_cur >= sc->TXStsQ + TX_QLEN) {
+ sc->TXStsQ_cur = sc->TXStsQ;
+ }
+ } while (sc->TXStsQ_cur != cur);
+
+ sc->TXDQ_avail += ndq;
+ if (ifp->if_flags & IFF_OACTIVE) {
+ ifp->if_flags &= ~IFF_OACTIVE;
+ /* Disable end-of-tx-chain interrupt */
+ EPE_WRITE(IntEn, IntEn_REOFIE);
+ }
+ return ndq;
+}
+
+static int
epe_intr(void *arg)
{
struct epe_softc *sc = (struct epe_softc *)arg;
@@ -154,12 +217,9 @@
irq = EPE_READ(IntStsC);
begin:
- if ((irq & IntSts_RxSQ) == 0) goto txq;
cur = (u_int32_t *)(EPE_READ(RXStsQCurAdd) -
- sc->ctrlpage_dmamap->dm_segs[0].ds_addr +
- sc->ctrlpage);
- bus_dmamap_sync(sc->sc_dmat, sc->ctrlpage_dmamap,
- TX_QLEN * 3 * sizeof(u_int32_t),
+ sc->ctrlpage_dsaddr + sc->ctrlpage);
+ CTRLPAGE_DMASYNC(TX_QLEN * 3 * sizeof(u_int32_t),
RX_QLEN * 4 * sizeof(u_int32_t),
BUS_DMASYNC_PREREAD);
while (sc->RXStsQ_cur != cur) {
@@ -169,8 +229,6 @@
u_int32_t fl = sc->RXStsQ_cur[1] & 0xffff;
struct mbuf *m;
- bus_dmamap_sync(sc->sc_dmat, sc->rxq[bi].m_dmamap,
- 0, fl, BUS_DMASYNC_PREREAD);
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m != NULL) MCLGET(m, M_DONTWAIT);
if (m != NULL && (m->m_flags & M_EXT)) {
@@ -191,9 +249,6 @@
NULL, BUS_DMA_NOWAIT);
sc->RXDQ[bi * 2] =
sc->rxq[bi].m_dmamap->dm_segs[0].ds_addr;
- bus_dmamap_sync(sc->sc_dmat,
- sc->rxq[bi].m_dmamap, 0, MCLBYTES,
- BUS_DMASYNC_PREREAD);
} else {
/* Drop packets until we can get replacement
* empty mbufs for the RXDQ.
@@ -217,8 +272,7 @@
if (ndq > 0) {
ifp->if_ipackets += ndq;
- bus_dmamap_sync(sc->sc_dmat, sc->ctrlpage_dmamap,
- TX_QLEN * 3 * sizeof(u_int32_t),
+ CTRLPAGE_DMASYNC(TX_QLEN * 3 * sizeof(u_int32_t),
RX_QLEN * 4 * sizeof(u_int32_t),
BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
EPE_WRITE(RXStsEnq, ndq);
@@ -226,56 +280,14 @@
ndq = 0;
}
-txq:
- if ((irq & IntSts_TxSQ) == 0)
- goto end;
-
- /* Handle transmit completions */
- cur = (u_int32_t *)(EPE_READ(TXStsQCurAdd) -
- sc->ctrlpage_dmamap->dm_segs[0].ds_addr +
- sc->ctrlpage);
- bus_dmamap_sync(sc->sc_dmat, sc->ctrlpage_dmamap,
- TX_QLEN * 2 * sizeof(u_int32_t),
- TX_QLEN * sizeof(u_int32_t), BUS_DMASYNC_PREREAD);
- while (sc->TXStsQ_cur != cur) {
- u_int32_t tbi = *sc->TXStsQ_cur & 0x7fff;
- struct mbuf *m = sc->txq[tbi].m;
+ if (epe_gctx(sc) > 0 && IFQ_IS_EMPTY(&ifp->if_snd) == 0) {
+ epe_ifstart(ifp);
+ }
- if ((*sc->TXStsQ_cur & TXStsQ_TxWE) == 0) {
- ifp->if_oerrors++;
- }
- bus_dmamap_unload(sc->sc_dmat, sc->txq[tbi].m_dmamap);
- m_freem(m);
- do {
- sc->txq[tbi].m = NULL;
- ndq++;
- tbi = (tbi + 1) % TX_QLEN;
- } while (sc->txq[tbi].m == m);
-
- ifp->if_opackets++;
- sc->TXStsQ_cur++;
- if (sc->TXStsQ_cur >= sc->TXStsQ + TX_QLEN) {
- sc->TXStsQ_cur = sc->TXStsQ;
- }
- }
+ irq = EPE_READ(IntStsC);
+ if ((irq & (IntSts_RxSQ|IntSts_ECI)) != 0)
+ goto begin;
- if (ndq > 0) {
- sc->TXDQ_avail += ndq;
- if (sc->TXDQ_avail == TX_QLEN - 1) {
- ifp->if_flags &= ~IFF_OACTIVE;
- ifp->if_timer = 0;
- } else {
- ifp->if_timer = 10;
- }
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0 &&
- sc->TXDQ_avail > TX_QLEN / 2) epe_ifstart(ifp);
- ndq = 0;
- }
-
-end:
- irq = EPE_READ(IntStsC);
- if ((irq & (IntSts_TxSQ|IntSts_RxSQ)) != 0)
- goto begin;
return (1);
}
@@ -315,7 +327,7 @@
&segs, 1, &rsegs, BUS_DMA_WAITOK);
if (err == 0) {
err = bus_dmamem_map(sc->sc_dmat, &segs, 1, PAGE_SIZE,
- &sc->ctrlpage, (BUS_DMA_WAITOK));
+ &sc->ctrlpage, (BUS_DMA_WAITOK|BUS_DMA_COHERENT));
}
if (err == 0) {
err = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE,
@@ -328,6 +340,7 @@
if (err != 0) {
panic("%s: Cannot get DMA memory", sc->sc_dev.dv_xname);
}
+ sc->ctrlpage_dsaddr = sc->ctrlpage_dmamap->dm_segs[0].ds_addr;
bzero(sc->ctrlpage, PAGE_SIZE);
/* Set up pointers to start of each queue in kernel addr space.
@@ -406,14 +419,13 @@
ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
EPE_WRITE(BMCtl, BMCtl_RxEn|BMCtl_TxEn);
- EPE_WRITE(IntEn, IntEn_TSQIE|IntEn_REOFIE);
+ EPE_WRITE(IntEn, IntEn_REOFIE);
/* maximum valid max frame length */
EPE_WRITE(MaxFrmLen, (0x7ff << 16)|MHLEN);
/* wait for receiver ready */
while((EPE_READ(BMSts) & BMSts_RxAct) == 0);
/* enqueue the entries in RXStsQ and RXDQ */
- bus_dmamap_sync(sc->sc_dmat, sc->ctrlpage_dmamap, 0,
- sc->ctrlpage_dmamap->dm_mapsize,
+ CTRLPAGE_DMASYNC(0, sc->ctrlpage_dmamap->dm_mapsize,
BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
EPE_WRITE(RXDEnq, RX_QLEN - 1);
EPE_WRITE(RXStsEnq, RX_QLEN - 1);
@@ -464,9 +476,10 @@
struct device *self;
int phy, reg;
{
- struct epe_softc *sc = (struct epe_softc *)self;
u_int32_t d, v;
+ struct epe_softc *sc;
+ sc = (struct epe_softc *)self;
d = EPE_READ(SelfCtl);
EPE_WRITE(SelfCtl, d & ~SelfCtl_PSPRS); /* no preamble suppress */
EPE_WRITE(MIICmd, (MIICmd_READ | (phy << 5) | reg));
@@ -481,9 +494,10 @@
struct device *self;
int phy, reg, val;
{
- struct epe_softc *sc = (struct epe_softc *)self;
+ struct epe_softc *sc;
u_int32_t d;
+ sc = (struct epe_softc *)self;
d = EPE_READ(SelfCtl);
EPE_WRITE(SelfCtl, d & ~SelfCtl_PSPRS); /* no preamble suppress */
EPE_WRITE(MIICmd, (MIICmd_WRITE | (phy << 5) | reg));
@@ -518,6 +532,7 @@
{
struct epe_softc* sc = (struct epe_softc *)arg;
struct ifnet * ifp = &sc->sc_ec.ec_if;
+ int s;
u_int32_t misses;
ifp->if_collisions += EPE_READ(TXCollCnt);
@@ -526,6 +541,12 @@
if (misses > 0)
printf("%s: %d rx misses\n", sc->sc_dev.dv_xname, misses);
+ s = splnet();
+ if (epe_gctx(sc) > 0 && IFQ_IS_EMPTY(&ifp->if_snd) == 0) {
+ epe_ifstart(ifp);
+ }
+ splx(s);
+
mii_tick(&sc->sc_mii);
callout_reset(&sc->epe_tick_ch, hz, epe_tick, sc);
}
@@ -566,13 +587,22 @@
struct epe_softc *sc = (struct epe_softc *)ifp->if_softc;
struct mbuf *m;
bus_dma_segment_t *segs;
- int s, bi, err, nsegs, ndq = 0;
-
Home |
Main Index |
Thread Index |
Old Index