From 49a79b66615ba806c5f6efd5fff555069d6eba1f Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Tue, 27 Nov 2001 16:29:11 +0000 Subject: [PATCH] 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. --- sys/pci/if_sis.c | 24 +++++++++++------------- sys/pci/if_sisreg.h | 3 ++- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c index 19f6d3253e8c..a924e99e48ec 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; diff --git a/sys/pci/if_sisreg.h b/sys/pci/if_sisreg.h index 21cb22af8608..7ac424f0d970 100644 --- a/sys/pci/if_sisreg.h +++ b/sys/pci/if_sisreg.h @@ -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