Implement a sliding interrupt delay window for Tx interrupts.
This commit is contained in:
parent
0f2cbd0361
commit
6caa2f6db1
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_sip.c,v 1.55 2002/06/30 18:04:12 thorpej Exp $ */
|
||||
/* $NetBSD: if_sip.c,v 1.56 2002/06/30 18:52:21 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
|
||||
@ -82,7 +82,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.55 2002/06/30 18:04:12 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.56 2002/06/30 18:52:21 thorpej Exp $");
|
||||
|
||||
#include "bpfilter.h"
|
||||
|
||||
@ -254,7 +254,9 @@ struct sip_softc {
|
||||
*/
|
||||
struct evcnt sc_ev_txsstall; /* Tx stalled due to no txs */
|
||||
struct evcnt sc_ev_txdstall; /* Tx stalled due to no txd */
|
||||
struct evcnt sc_ev_txintr; /* Tx interrupts */
|
||||
struct evcnt sc_ev_txforceintr; /* Tx interrupts forced */
|
||||
struct evcnt sc_ev_txdintr; /* Tx descriptor interrupts */
|
||||
struct evcnt sc_ev_txiintr; /* Tx idle interrupts */
|
||||
struct evcnt sc_ev_rxintr; /* Rx interrupts */
|
||||
#ifdef DP83820
|
||||
struct evcnt sc_ev_rxipsum; /* IP checksums checked in-bound */
|
||||
@ -286,6 +288,7 @@ struct sip_softc {
|
||||
|
||||
int sc_txfree; /* number of free Tx descriptors */
|
||||
int sc_txnext; /* next ready Tx descriptor */
|
||||
int sc_txwin; /* Tx descriptors since last intr */
|
||||
|
||||
struct sip_txsq sc_txfreeq; /* free Tx descsofts */
|
||||
struct sip_txsq sc_txdirtyq; /* dirty Tx descsofts */
|
||||
@ -936,8 +939,12 @@ SIP_DECL(attach)(struct device *parent, struct device *self, void *aux)
|
||||
NULL, sc->sc_dev.dv_xname, "txsstall");
|
||||
evcnt_attach_dynamic(&sc->sc_ev_txdstall, EVCNT_TYPE_MISC,
|
||||
NULL, sc->sc_dev.dv_xname, "txdstall");
|
||||
evcnt_attach_dynamic(&sc->sc_ev_txintr, EVCNT_TYPE_INTR,
|
||||
NULL, sc->sc_dev.dv_xname, "txintr");
|
||||
evcnt_attach_dynamic(&sc->sc_ev_txforceintr, EVCNT_TYPE_INTR,
|
||||
NULL, sc->sc_dev.dv_xname, "txforceintr");
|
||||
evcnt_attach_dynamic(&sc->sc_ev_txdintr, EVCNT_TYPE_INTR,
|
||||
NULL, sc->sc_dev.dv_xname, "txdintr");
|
||||
evcnt_attach_dynamic(&sc->sc_ev_txiintr, EVCNT_TYPE_INTR,
|
||||
NULL, sc->sc_dev.dv_xname, "txiintr");
|
||||
evcnt_attach_dynamic(&sc->sc_ev_rxintr, EVCNT_TYPE_INTR,
|
||||
NULL, sc->sc_dev.dv_xname, "rxintr");
|
||||
#ifdef DP83820
|
||||
@ -1193,6 +1200,17 @@ SIP_DECL(start)(struct ifnet *ifp)
|
||||
/* Clear the MORE bit on the last segment. */
|
||||
sc->sc_txdescs[lasttx].sipd_cmdsts &= htole32(~CMDSTS_MORE);
|
||||
|
||||
/*
|
||||
* If we're in the interrupt delay window, delay the
|
||||
* interrupt.
|
||||
*/
|
||||
if (++sc->sc_txwin >= (SIP_TXQUEUELEN * 2 / 3)) {
|
||||
SIP_EVCNT_INCR(&sc->sc_ev_txforceintr);
|
||||
sc->sc_txdescs[lasttx].sipd_cmdsts |=
|
||||
htole32(CMDSTS_INTR);
|
||||
sc->sc_txwin = 0;
|
||||
}
|
||||
|
||||
#ifdef DP83820
|
||||
/*
|
||||
* If VLANs are enabled and the packet has a VLAN tag, set
|
||||
@ -1271,14 +1289,6 @@ SIP_DECL(start)(struct ifnet *ifp)
|
||||
}
|
||||
|
||||
if (sc->sc_txfree != ofree) {
|
||||
/*
|
||||
* Cause a descriptor interrupt to happen on the
|
||||
* last packet we enqueued.
|
||||
*/
|
||||
sc->sc_txdescs[lasttx].sipd_cmdsts |= htole32(CMDSTS_INTR);
|
||||
SIP_CDTXSYNC(sc, lasttx, 1,
|
||||
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
||||
|
||||
/*
|
||||
* The entire packet chain is set up. Give the
|
||||
* first descrptor to the chip now.
|
||||
@ -1436,8 +1446,13 @@ SIP_DECL(intr)(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
if (isr & (ISR_TXURN|ISR_TXDESC)) {
|
||||
SIP_EVCNT_INCR(&sc->sc_ev_txintr);
|
||||
if (isr & (ISR_TXURN|ISR_TXDESC|ISR_TXIDLE)) {
|
||||
#ifdef SIP_EVENT_COUNTERS
|
||||
if (isr & ISR_TXDESC)
|
||||
SIP_EVCNT_INCR(&sc->sc_ev_txdintr);
|
||||
else if (isr & ISR_TXIDLE)
|
||||
SIP_EVCNT_INCR(&sc->sc_ev_txiintr);
|
||||
#endif
|
||||
|
||||
/* Sweep up transmit descriptors. */
|
||||
SIP_DECL(txintr)(sc);
|
||||
@ -1563,8 +1578,10 @@ SIP_DECL(txintr)(struct sip_softc *sc)
|
||||
* If there are no more pending transmissions, cancel the watchdog
|
||||
* timer.
|
||||
*/
|
||||
if (txs == NULL)
|
||||
if (txs == NULL) {
|
||||
ifp->if_timer = 0;
|
||||
sc->sc_txwin = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DP83820)
|
||||
@ -2089,6 +2106,7 @@ SIP_DECL(init)(struct ifnet *ifp)
|
||||
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
||||
sc->sc_txfree = SIP_NTXDESC;
|
||||
sc->sc_txnext = 0;
|
||||
sc->sc_txwin = 0;
|
||||
|
||||
/*
|
||||
* Initialize the transmit job descriptors.
|
||||
@ -2224,7 +2242,7 @@ SIP_DECL(init)(struct ifnet *ifp)
|
||||
* Initialize the interrupt mask.
|
||||
*/
|
||||
sc->sc_imr = ISR_DPERR|ISR_SSERR|ISR_RMABT|ISR_RTABT|ISR_RXSOVR|
|
||||
ISR_TXURN|ISR_TXDESC|ISR_RXORN|ISR_RXIDLE|ISR_RXDESC;
|
||||
ISR_TXURN|ISR_TXDESC|ISR_TXIDLE|ISR_RXORN|ISR_RXIDLE|ISR_RXDESC;
|
||||
bus_space_write_4(st, sh, SIP_IMR, sc->sc_imr);
|
||||
|
||||
/* Set up the receive filter. */
|
||||
|
Loading…
Reference in New Issue
Block a user