Be more careful about issuing CU_RESUME in fxp_start()--only doing

it if we think it's probably necessary.  Then do it again in the
tx interrupt handler, if we again think it's necessary.  This
reduces the number of commands we issue the chip.  Prior to this
change, the i82550 (running without extended feature set, so like
a '559) would sometimes fail in fxp_scb_wait() prior to issuing
another CU_RESUME, resulting in
	fxp0: WARNING: SCB timed out!
messages on the console, often followed by device timeouts.
This commit is contained in:
briggs 2004-03-31 14:48:31 +00:00
parent 31d9ef775a
commit 1c0ca89048
1 changed files with 17 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: i82557.c,v 1.81 2004/02/19 14:21:40 yamt Exp $ */
/* $NetBSD: i82557.c,v 1.82 2004/03/31 14:48:31 briggs Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999, 2001, 2002 The NetBSD Foundation, Inc.
@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i82557.c,v 1.81 2004/02/19 14:21:40 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: i82557.c,v 1.82 2004/03/31 14:48:31 briggs Exp $");
#include "bpfilter.h"
#include "rnd.h"
@ -1089,9 +1089,18 @@ fxp_start(struct ifnet *ifp)
/*
* Issue a Resume command in case the chip was suspended.
* We only do this if we know we were idle before. If we
* weren't idle before, we might be now, but we should also
* have a pending interrupt, and we'll kick it again, there.
* This might result in a tiny delay, but it also prevents
* us from slamming the chip with CU_RESUME commands, which
* might sometimes fail, resulting in SCB timeouts in
* fxp_scb_wait().
*/
fxp_scb_wait(sc);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
if (opending == 0) {
fxp_scb_wait(sc);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
}
/* Set a watchdog timer in case the chip flakes out. */
ifp->if_timer = 5;
@ -1224,6 +1233,10 @@ fxp_txintr(struct fxp_softc *sc)
*/
if (sc->sc_txpending == 0)
ifp->if_timer = 0;
else {
fxp_scb_wait(sc);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
}
}
/*