1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-14 10:09:48 +00:00

Fix a bug in the driver -- under load, the receive unit could become

idle and the driver would not detect the event, requiring userland
to cycle the interface to bring it up again.
The fix consists in adding SIS_IMR_RX_IDLE to the interrupt mask and
add a command in sis_intr() to restart the receiver when this happens.

While at it, make the test of status bits more efficient.
This commit is contained in:
Luigi Rizzo 2001-11-27 16:29:11 +00:00
parent ad48dba20f
commit 49a79b6661
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=86984
2 changed files with 13 additions and 14 deletions

View File

@ -1439,14 +1439,13 @@ static void sis_intr(arg)
u_int32_t status;
sc = arg;
SIS_LOCK(sc);
ifp = &sc->arpcom.ac_if;
SIS_LOCK(sc);
/* Supress unwanted interrupts */
if (!(ifp->if_flags & IFF_UP)) {
sis_stop(sc);
SIS_UNLOCK(sc);
return;
goto done;
}
/* Disable interrupts. */
@ -1459,20 +1458,19 @@ static void sis_intr(arg)
if ((status & SIS_INTRS) == 0)
break;
if ((status & SIS_ISR_TX_DESC_OK) ||
(status & SIS_ISR_TX_ERR) ||
(status & SIS_ISR_TX_OK) ||
(status & SIS_ISR_TX_IDLE))
if (status &
(SIS_ISR_TX_DESC_OK | SIS_ISR_TX_ERR |
SIS_ISR_TX_OK | SIS_ISR_TX_IDLE) )
sis_txeof(sc);
if ((status & SIS_ISR_RX_DESC_OK) ||
(status & SIS_ISR_RX_OK))
if (status & (SIS_ISR_RX_DESC_OK|SIS_ISR_RX_OK|SIS_ISR_RX_IDLE))
sis_rxeof(sc);
if ((status & SIS_ISR_RX_ERR) ||
(status & SIS_ISR_RX_OFLOW)) {
if (status & (SIS_ISR_RX_ERR | SIS_ISR_RX_OFLOW))
sis_rxeoc(sc);
}
if (status & (SIS_ISR_RX_IDLE))
SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
if (status & SIS_ISR_SYSERR) {
sis_reset(sc);
@ -1485,7 +1483,7 @@ static void sis_intr(arg)
if (ifp->if_snd.ifq_head != NULL)
sis_start(ifp);
done:
SIS_UNLOCK(sc);
return;

View File

@ -185,6 +185,7 @@
#define SIS_INTRS \
(SIS_IMR_RX_OFLOW|SIS_IMR_TX_UFLOW|SIS_IMR_TX_OK|\
SIS_IMR_TX_IDLE|SIS_IMR_RX_OK|SIS_IMR_RX_ERR|\
SIS_IMR_RX_IDLE|\
SIS_IMR_SYSERR)
#define SIS_IER_INTRENB 0x00000001
@ -306,7 +307,7 @@ struct sis_desc {
#define SIS_LASTDESC(x) (!((x)->sis_ctl & SIS_CMDSTS_MORE)))
#define SIS_OWNDESC(x) ((x)->sis_ctl & SIS_CMDSTS_OWN)
#define SIS_INC(x, y) (x) = (x + 1) % y
#define SIS_INC(x, y) { if (++(x) == y) x=0 ; }
#define SIS_RXBYTES(x) ((x)->sis_ctl & SIS_CMDSTS_BUFLEN)
#define SIS_RXSTAT_COLL 0x00010000