Pull several fixes which improve TX error handling
from FreeBSD's if_vr.c rev 1.52: - check more error status in TX descriptor and restart TX module appropriately in vr_txeof() - check more error interrupt status in vr_intr() I can't confirm whether these changes actually fix TX stalls because I can't reproduce the problem I had about seven years ago (I guess it might be caused by excessive collisions on a dumb hub), but at least they don't seem to have bad side effects on normal operations on my macppc.
This commit is contained in:
parent
57a0051fe5
commit
690e60f366
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_vr.c,v 1.81 2006/11/02 17:32:11 tsutsui Exp $ */
|
||||
/* $NetBSD: if_vr.c,v 1.82 2006/11/03 08:41:05 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
@ -104,7 +104,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.81 2006/11/02 17:32:11 tsutsui Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.82 2006/11/03 08:41:05 tsutsui Exp $");
|
||||
|
||||
#include "rnd.h"
|
||||
|
||||
@ -832,7 +832,7 @@ vr_txeof(struct vr_softc *sc)
|
||||
struct vr_desc *d;
|
||||
struct vr_descsoft *ds;
|
||||
u_int32_t txstat;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
ifp->if_flags &= ~IFF_OACTIVE;
|
||||
|
||||
@ -848,6 +848,25 @@ vr_txeof(struct vr_softc *sc)
|
||||
VR_CDTXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
txstat = le32toh(d->vr_status);
|
||||
|
||||
if (txstat & (VR_TXSTAT_ABRT | VR_TXSTAT_UDF)) {
|
||||
VR_CLRBIT16(sc, VR_COMMAND, VR_CMD_TX_ON);
|
||||
for (j = 0; j < VR_TIMEOUT; j++) {
|
||||
DELAY(10);
|
||||
if ((CSR_READ_2(sc, VR_COMMAND) &
|
||||
VR_CMD_TX_ON) == 0)
|
||||
break;
|
||||
}
|
||||
if (j == VR_TIMEOUT) {
|
||||
/* XXX need reset? */
|
||||
printf("%s: TX shutdown never complete\n",
|
||||
sc->vr_dev.dv_xname);
|
||||
}
|
||||
d->vr_status = htole32(VR_TXSTAT_OWN);
|
||||
CSR_WRITE_4(sc, VR_TXADDR, VR_CDTXADDR(sc, i));
|
||||
break;
|
||||
}
|
||||
|
||||
if (txstat & VR_TXSTAT_OWN)
|
||||
break;
|
||||
|
||||
@ -927,18 +946,33 @@ vr_intr(void *arg)
|
||||
(VR_ISR_RX_ERR | VR_ISR_RX_NOBUF | VR_ISR_RX_OFLOW))
|
||||
vr_rxeoc(sc);
|
||||
|
||||
|
||||
if (status & (VR_ISR_BUSERR | VR_ISR_TX_UNDERRUN)) {
|
||||
if (status & VR_ISR_BUSERR)
|
||||
printf("%s: PCI bus error\n",
|
||||
sc->vr_dev.dv_xname);
|
||||
if (status & VR_ISR_TX_UNDERRUN)
|
||||
printf("%s: transmit underrun\n",
|
||||
sc->vr_dev.dv_xname);
|
||||
/* vr_init() calls vr_start() */
|
||||
dotx = 0;
|
||||
(void)vr_init(ifp);
|
||||
|
||||
}
|
||||
|
||||
if (status & VR_ISR_TX_OK) {
|
||||
dotx = 1;
|
||||
vr_txeof(sc);
|
||||
}
|
||||
|
||||
if (status & (VR_ISR_TX_UNDERRUN | VR_ISR_TX_ABRT)) {
|
||||
if (status & VR_ISR_TX_UNDERRUN)
|
||||
printf("%s: transmit underrun\n",
|
||||
sc->vr_dev.dv_xname);
|
||||
if (status & VR_ISR_TX_ABRT)
|
||||
if (status &
|
||||
(VR_ISR_TX_ABRT | VR_ISR_TX_ABRT2 | VR_ISR_TX_UDFI)) {
|
||||
if (status & (VR_ISR_TX_ABRT | VR_ISR_TX_ABRT2))
|
||||
printf("%s: transmit aborted\n",
|
||||
sc->vr_dev.dv_xname);
|
||||
if (status & VR_ISR_TX_UDFI)
|
||||
printf("%s: transmit underflow\n",
|
||||
sc->vr_dev.dv_xname);
|
||||
ifp->if_oerrors++;
|
||||
dotx = 1;
|
||||
vr_txeof(sc);
|
||||
@ -946,22 +980,6 @@ vr_intr(void *arg)
|
||||
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON);
|
||||
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_GO);
|
||||
}
|
||||
/*
|
||||
* Unfortunately many cards get stuck after
|
||||
* aborted transmits, so we reset them.
|
||||
*/
|
||||
if (status & VR_ISR_TX_ABRT) {
|
||||
printf("%s: restarting\n", sc->vr_dev.dv_xname);
|
||||
dotx = 0;
|
||||
(void) vr_init(ifp);
|
||||
}
|
||||
}
|
||||
|
||||
if (status & VR_ISR_BUSERR) {
|
||||
printf("%s: PCI bus error\n", sc->vr_dev.dv_xname);
|
||||
/* vr_init() calls vr_start() */
|
||||
dotx = 0;
|
||||
(void) vr_init(ifp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_vrreg.h,v 1.14 2006/11/02 10:44:30 tsutsui Exp $ */
|
||||
/* $NetBSD: if_vrreg.h,v 1.15 2006/11/03 08:41:05 tsutsui Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998
|
||||
@ -155,6 +155,8 @@
|
||||
#define VR_ISR_STATSOFLOW 0x0080 /* stats counter oflow */
|
||||
#define VR_ISR_RX_EARLY 0x0100 /* rx early */
|
||||
#define VR_ISR_LINKSTAT 0x0200 /* MII status change */
|
||||
#define VR_ISR_TX_ETI 0x0200 /* TX early (3043/3071) */
|
||||
#define VR_ISR_TX_UDFI 0x0200 /* TX FIFO underflow (3065) */
|
||||
#define VR_ISR_RX_OFLOW 0x0400 /* rx FIFO overflow */
|
||||
#define VR_ISR_RX_DROPPED 0x0800
|
||||
#define VR_ISR_RX_NOBUF2 0x1000
|
||||
@ -371,6 +373,7 @@ struct vr_desc {
|
||||
#define VR_TXSTAT_ABRT 0x00000100
|
||||
#define VR_TXSTAT_LATECOLL 0x00000200
|
||||
#define VR_TXSTAT_CARRLOST 0x00000400
|
||||
#define VR_TXSTAT_UDF 0x00000800
|
||||
#define VR_TXSTAT_BUSERR 0x00002000
|
||||
#define VR_TXSTAT_JABTIMEO 0x00004000
|
||||
#define VR_TXSTAT_ERRSUM 0x00008000
|
||||
|
Loading…
Reference in New Issue
Block a user