summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_em.c
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2005-10-24 21:42:35 +0000
committerBrad Smith <brad@cvs.openbsd.org>2005-10-24 21:42:35 +0000
commitfaa30474957681cf6d13e6afefc7d87248e7c708 (patch)
tree07fbbb11228e7a172c7daebcec5cf992343aa5bc /sys/dev/pci/if_em.c
parentb24a160b6e91b206b2575311ceac6a59bc9f18bc (diff)
Revamp interrupt handling in em(4) driver:
o Do not mask the RX overrun interrupt. o Rewrite em_intr(): - Axe EM_MAX_INTR. - Cycle acknowledging interrupts and processing packets until zero interrupt cause register is read. - If RX overrun comes in log this fact. From glebius FreeBSD ok krw@ beck@
Diffstat (limited to 'sys/dev/pci/if_em.c')
-rw-r--r--sys/dev/pci/if_em.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c
index 44029fcc1c9..272a6890d47 100644
--- a/sys/dev/pci/if_em.c
+++ b/sys/dev/pci/if_em.c
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
-/* $OpenBSD: if_em.c,v 1.80 2005/10/21 02:10:34 brad Exp $ */
+/* $OpenBSD: if_em.c,v 1.81 2005/10/24 21:42:34 brad Exp $ */
/* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */
#include <dev/pci/if_em.h>
@@ -714,44 +714,52 @@ em_init(void *arg)
int
em_intr(void *arg)
{
- u_int32_t loop_cnt = EM_MAX_INTR;
- u_int32_t reg_icr;
- struct ifnet *ifp;
struct em_softc *sc = arg;
- int s;
+ struct ifnet *ifp;
+ u_int32_t reg_icr;
+ int s, claimed = 0, wantinit = 0;
s = splnet();
ifp = &sc->interface_data.ac_if;
- reg_icr = E1000_READ_REG(&sc->hw, ICR);
- if (!reg_icr) {
- splx(s);
- return (0);
- }
+ for (;;) {
+ reg_icr = E1000_READ_REG(&sc->hw, ICR);
+ if (reg_icr == 0)
+ break;
- /* Link status change */
- if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- timeout_del(&sc->timer_handle);
- sc->hw.get_link_status = 1;
- em_check_for_link(&sc->hw);
- em_update_link_status(sc);
- timeout_add(&sc->timer_handle, hz);
- }
+ claimed = 1;
- while (loop_cnt > 0) {
if (ifp->if_flags & IFF_RUNNING) {
em_process_receive_interrupts(sc, -1);
em_clean_transmit_interrupts(sc);
}
- loop_cnt--;
+
+ /* Link status change */
+ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ timeout_del(&sc->timer_handle);
+ sc->hw.get_link_status = 1;
+ em_check_for_link(&sc->hw);
+ em_update_link_status(sc);
+ timeout_add(&sc->timer_handle, hz);
+ }
+
+ if (reg_icr & E1000_ICR_RXO) {
+ ifp->if_ierrors++;
+ wantinit = 1;
+ }
}
+#if 0
+ if (wantinit)
+ em_init(sc);
+#endif
- if (ifp->if_flags & IFF_RUNNING && IFQ_IS_EMPTY(&ifp->if_snd) == 0)
+ if (ifp->if_flags & IFF_RUNNING &&
+ IFQ_IS_EMPTY(&ifp->if_snd) == 0)
em_start(ifp);
splx(s);
- return (1);
+ return (claimed);
}
/*********************************************************************