diff options
author | luigi <luigi@FreeBSD.org> | 2001-11-27 16:29:11 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2001-11-27 16:29:11 +0000 |
commit | d6ea22c61785f66fda317a412e9febf626847326 (patch) | |
tree | a80590a6c440662787b8d2bbe7f8fef3f0069094 /sys/pci/if_sis.c | |
parent | a2f0a76ebcd5b63f172b9f17a662de0c4d59ff22 (diff) | |
download | FreeBSD-src-d6ea22c61785f66fda317a412e9febf626847326.zip FreeBSD-src-d6ea22c61785f66fda317a412e9febf626847326.tar.gz |
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.
Diffstat (limited to 'sys/pci/if_sis.c')
-rw-r--r-- | sys/pci/if_sis.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c index 19f6d32..a924e99 100644 --- a/sys/pci/if_sis.c +++ b/sys/pci/if_sis.c @@ -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; |