Make Tulip-style filter setup interrupt-driven.

This commit is contained in:
thorpej 1999-09-01 20:56:15 +00:00
parent a6aa19699f
commit cfbc8a82fb
2 changed files with 40 additions and 22 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: tulip.c,v 1.3 1999/09/01 20:11:19 thorpej Exp $ */
/* $NetBSD: tulip.c,v 1.4 1999/09/01 20:56:15 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -631,9 +631,23 @@ tlp_watchdog(ifp)
struct ifnet *ifp;
{
struct tulip_softc *sc = ifp->if_softc;
int doing_setup, doing_transmit;
doing_setup = (sc->sc_flags & TULIPF_DOING_SETUP);
doing_transmit = (SIMPLEQ_FIRST(&sc->sc_txdirtyq) != NULL);
if (doing_setup && doing_transmit) {
printf("%s: filter setup and transmit timeout\n",
sc->sc_dev.dv_xname);
ifp->if_oerrors++;
} else if (doing_transmit) {
printf("%s: transmit timeout\n", sc->sc_dev.dv_xname);
ifp->if_oerrors++;
} else if (doing_setup)
printf("%s: filter setup timeout\n", sc->sc_dev.dv_xname);
else
printf("%s: spurious watchdog timeout\n", sc->sc_dev.dv_xname);
printf("%s: device timeout\n", sc->sc_dev.dv_xname);
ifp->if_oerrors++;
(void) tlp_init(sc);
/* Try to get more packets going. */
@ -1090,6 +1104,15 @@ tlp_txintr(sc)
ifp->if_flags &= ~IFF_OACTIVE;
/*
* If we were doing a filter setup, check to see if it completed.
*/
if (sc->sc_flags & TULIPF_DOING_SETUP) {
TULIP_CDSDSYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
if ((sc->sc_setup_desc.td_status & TDSTAT_OWN) == 0)
sc->sc_flags &= ~TULIPF_DOING_SETUP;
}
/*
* Go through our Tx list and free mbufs for those
* frames that have been transmitted.
@ -1154,7 +1177,7 @@ tlp_txintr(sc)
* If there are no more pending transmissions, cancel the watchdog
* timer.
*/
if (txs == NULL)
if (txs == NULL && (sc->sc_flags & TULIPF_DOING_SETUP) == 0)
ifp->if_timer = 0;
/*
@ -1497,7 +1520,7 @@ tlp_stop(sc, drain)
tlp_rxdrain(sc);
}
sc->sc_flags &= ~TULIPF_WANT_SETUP;
sc->sc_flags &= ~(TULIPF_WANT_SETUP|TULIPF_DOING_SETUP);
/*
* Mark the interface down and cancel the watchdog timer.
@ -1740,7 +1763,8 @@ tlp_filter_setup(sc)
* If there are transmissions pending, wait until they have
* completed.
*/
if (SIMPLEQ_FIRST(&sc->sc_txdirtyq) != NULL) {
if (SIMPLEQ_FIRST(&sc->sc_txdirtyq) != NULL ||
(sc->sc_flags & TULIPF_DOING_SETUP) != 0) {
sc->sc_flags |= TULIPF_WANT_SETUP;
DPRINTF(("%s: tlp_filter_setup: deferring\n",
sc->sc_dev.dv_xname));
@ -1910,7 +1934,7 @@ tlp_filter_setup(sc)
sc->sc_setup_desc.td_ctl =
(TULIP_SETUP_PACKET_LEN << TDCTL_SIZE1_SHIFT) |
sc->sc_filtmode | TDCTL_Tx_SET | TDCTL_Tx_FS | TDCTL_Tx_LS |
TDCTL_CH;
TDCTL_Tx_IC | TDCTL_CH;
sc->sc_setup_desc.td_status = TDSTAT_OWN;
TULIP_CDSDSYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
@ -1928,6 +1952,8 @@ tlp_filter_setup(sc)
*/
TULIP_WRITE(sc, CSR_OPMODE, sc->sc_opmode);
sc->sc_flags |= TULIPF_DOING_SETUP;
/*
* Kick the transmitter; this will cause the Tulip to
* read the setup descriptor.
@ -1935,18 +1961,9 @@ tlp_filter_setup(sc)
/* XXX USE AUTOPOLLING? */
TULIP_WRITE(sc, CSR_TXPOLL, TXPOLL_TPD);
/*
* Now wait for the OWN bit to clear.
*/
for (cnt = 0; cnt < 1000; cnt++) {
TULIP_CDSDSYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
if ((sc->sc_setup_desc.td_status & TDSTAT_OWN) == 0)
break;
delay(10);
}
if (sc->sc_setup_desc.td_status & TDSTAT_OWN)
printf("%s: filter setup failed to complete\n",
sc->sc_dev.dv_xname);
/* Set up a watchdog timer in case the chip flakes out. */
ifp->if_timer = 5;
DPRINTF(("%s: tlp_filter_setup: returning\n", sc->sc_dev.dv_xname));
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: tulipvar.h,v 1.2 1999/09/01 05:07:04 thorpej Exp $ */
/* $NetBSD: tulipvar.h,v 1.3 1999/09/01 20:56:15 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -250,8 +250,9 @@ struct tulip_softc {
/* sc_flags */
#define TULIPF_WANT_SETUP 0x00000001 /* want filter setup */
#define TULIPF_HAS_MII 0x00000002 /* has media on MII */
#define TULIPF_IC_FS 0x00000004 /* IC bit on first tx seg */
#define TULIPF_DOING_SETUP 0x00000002 /* doing multicast setup */
#define TULIPF_HAS_MII 0x00000004 /* has media on MII */
#define TULIPF_IC_FS 0x00000008 /* IC bit on first tx seg */
#define TULIP_CDTXADDR(sc, x) ((sc)->sc_cddma + TULIP_CDTXOFF((x)))
#define TULIP_CDRXADDR(sc, x) ((sc)->sc_cddma + TULIP_CDRXOFF((x)))