Date: Mon, 8 Jul 2002 15:21:14 -0700 From: Luigi Rizzo <luigi@FreeBSD.ORG> To: Peter Wemm <peter@wemm.org> Cc: Don Lewis <dl-freebsd@catspoiler.org>, cvs-committers@FreeBSD.ORG, cvs-all@FreeBSD.ORG Subject: Re: cvs commit: src/sys/dev/fxp if_fxp.c Message-ID: <20020708152114.K77043@iguana.icir.org> In-Reply-To: <20020708215808.B34E53808@overcee.wemm.org>; from peter@wemm.org on Mon, Jul 08, 2002 at 02:58:08PM -0700 References: <20020708145235.I77043@iguana.icir.org> <20020708215808.B34E53808@overcee.wemm.org>
next in thread | previous in thread | raw e-mail | index | archive | help
The intended behaviour of the timeout was to fire if you queue a packet for transmission and do not get any success report (typically an interrupt) within some time (typically 5 seconds). Then a bunch of drivers came out which incorrectly reset the timeout after the first successful transmission, irrespective of the presence of other queued packets. If the card for some reason stalls on one of these packets, there is no other way (at least as implemented) to wake it up. I have been hit myself by this problem with the "dc" and "sis" drivers -- the problem is sporadical but when it happened it prevented further transmission on the interface unless some other process did a *_init() e.g. by bringing the interface down/up or doing some reconfiguration on it. I have received reports of the same problem on the "fxp" as well, though I have not experienced one myself. Now, one thing that is peculiar about the fxp driver is that it does not interrupt on every transmission, but only every now and then. So the timeout might fire when the queue has been drained but no signal has been posted. So in this specific driver, it would be more correct to invoke fxp_intr_body() from the watchdog handler, and check if there are pending tx packets after that before declaring a real timeout. In case you want to try it, the following should do: static void fxp_watchdog(struct ifnet *ifp) { struct fxp_softc *sc = ifp->if_softc; + int s = splimp(); + fxp_intr_body(sc, FXP_SCB_STATACK_CNA, 0); + splx(s); + if (sc->tx_queued == 0) + return; + device_printf(sc->dev, "device timeout\n"); ifp->if_oerrors++; fxp_init(sc); } I'd be grateful if you could try it. cheers luigi To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe cvs-all" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020708152114.K77043>