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
This commit is contained in:
Mike Silbersack 2002-08-15 04:04:53 +00:00
parent 4576293d3e
commit f3b2d59e18
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=101896
4 changed files with 60 additions and 30 deletions

View file

@ -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_TX_UNDERRUN)||(status & VR_ISR_TX_ABRT)){
ifp->if_oerrors++;
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_BUSERR) {
if ((status & VR_ISR_BUSERR) || (status & VR_ISR_TX_UNDERRUN)) {
vr_reset(sc);
vr_init(sc);
break;
}
if ((status & VR_ISR_TX_OK) || (status & VR_ISR_TX_ABRT) ||
(status & VR_ISR_TX_ABRT2) || (status & VR_ISR_UDFI)) {
vr_txeof(sc);
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);
}
}
/* Re-enable interrupts. */

View file

@ -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

View file

@ -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_TX_UNDERRUN)||(status & VR_ISR_TX_ABRT)){
ifp->if_oerrors++;
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_BUSERR) {
if ((status & VR_ISR_BUSERR) || (status & VR_ISR_TX_UNDERRUN)) {
vr_reset(sc);
vr_init(sc);
break;
}
if ((status & VR_ISR_TX_OK) || (status & VR_ISR_TX_ABRT) ||
(status & VR_ISR_TX_ABRT2) || (status & VR_ISR_UDFI)) {
vr_txeof(sc);
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);
}
}
/* Re-enable interrupts. */

View file

@ -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