summaryrefslogtreecommitdiffstats
path: root/sys/dev/vr
diff options
context:
space:
mode:
authorsilby <silby@FreeBSD.org>2002-08-15 04:04:53 +0000
committersilby <silby@FreeBSD.org>2002-08-15 04:04:53 +0000
commite4af9029cce2e19945be82d95c075561d2e80ae9 (patch)
treed6f049cd22ccbbf3bfe7dbad3878defeefef92d5 /sys/dev/vr
parent849f861756ce407ff63685e6bee7aa674929e2fb (diff)
downloadFreeBSD-src-e4af9029cce2e19945be82d95c075561d2e80ae9.zip
FreeBSD-src-e4af9029cce2e19945be82d95c075561d2e80ae9.tar.gz
Improve handling of TX errors. Early reports indicate that this
elimiates the driver lockup problem reported by many. Concepts used were taken from Via's if_fet driver. Verification and implementation were done by Thomas Nystrom. Submitted by: Thomas Nystrom <thn@saeab.se> MFC after: 3 days
Diffstat (limited to 'sys/dev/vr')
-rw-r--r--sys/dev/vr/if_vr.c38
-rw-r--r--sys/dev/vr/if_vrreg.h3
2 files changed, 28 insertions, 13 deletions
diff --git a/sys/dev/vr/if_vr.c b/sys/dev/vr/if_vr.c
index 76326b7..18f8fde 100644
--- a/sys/dev/vr/if_vr.c
+++ b/sys/dev/vr/if_vr.c
@@ -1088,6 +1088,15 @@ static void vr_txeof(sc)
cur_tx = sc->vr_cdata.vr_tx_head;
txstat = cur_tx->vr_ptr->vr_status;
+ if ((txstat & VR_TXSTAT_ABRT) ||
+ (txstat & VR_TXSTAT_UDF)) {
+ while (CSR_READ_2(sc, VR_COMMAND) & VR_CMD_TX_ON)
+ ; /* Wait for chip to shutdown */
+ VR_TXOWN(cur_tx) = VR_TXSTAT_OWN;
+ CSR_WRITE_4(sc, VR_TXADDR, vtophys(cur_tx->vr_ptr));
+ break;
+ }
+
if (txstat & VR_TXSTAT_OWN)
break;
@@ -1196,24 +1205,27 @@ static void vr_intr(arg)
vr_rxeoc(sc);
}
- if (status & VR_ISR_TX_OK) {
- vr_txeof(sc);
- vr_txeoc(sc);
+ if ((status & VR_ISR_BUSERR) || (status & VR_ISR_TX_UNDERRUN)) {
+ vr_reset(sc);
+ vr_init(sc);
+ break;
}
- if ((status & VR_ISR_TX_UNDERRUN)||(status & VR_ISR_TX_ABRT)){
- ifp->if_oerrors++;
+ if ((status & VR_ISR_TX_OK) || (status & VR_ISR_TX_ABRT) ||
+ (status & VR_ISR_TX_ABRT2) || (status & VR_ISR_UDFI)) {
vr_txeof(sc);
- if (sc->vr_cdata.vr_tx_head != NULL) {
- VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON);
- VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_GO);
- }
+ if ((status & VR_ISR_UDFI) ||
+ (status & VR_ISR_TX_ABRT2) ||
+ (status & VR_ISR_TX_ABRT)) {
+ ifp->if_oerrors++;
+ if (sc->vr_cdata.vr_tx_head != NULL) {
+ VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON);
+ VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_GO);
+ }
+ } else
+ vr_txeoc(sc);
}
- if (status & VR_ISR_BUSERR) {
- vr_reset(sc);
- vr_init(sc);
- }
}
/* Re-enable interrupts. */
diff --git a/sys/dev/vr/if_vrreg.h b/sys/dev/vr/if_vrreg.h
index 73b074e..47718bb 100644
--- a/sys/dev/vr/if_vrreg.h
+++ b/sys/dev/vr/if_vrreg.h
@@ -149,6 +149,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_ETI 0x0200 /* Tx early (3043/3071) */
+#define VR_ISR_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
@@ -368,6 +370,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
OpenPOWER on IntegriCloud