mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-17 13:53:39 +00:00
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:
parent
4576293d3e
commit
f3b2d59e18
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=101896
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue