--- if_em.c.orig Thu Oct 20 18:31:15 2005 +++ if_em.c Thu Oct 20 20:40:29 2005 @@ -34,6 +34,7 @@ /*$FreeBSD: src/sys/dev/em/if_em.c,v 1.44.2.9 2005/05/19 08:23:06 glebius Exp $*/ #include +#include /********************************************************************* * Set this to one to display debug statistics @@ -981,7 +982,6 @@ static void em_intr(void *arg) { - u_int32_t loop_cnt = EM_MAX_INTR; u_int32_t reg_icr; struct ifnet *ifp; struct adapter *adapter = arg; @@ -1005,32 +1005,26 @@ } #endif /* DEVICE_POLLING */ - reg_icr = E1000_READ_REG(&adapter->hw, ICR); - if (!reg_icr) { - EM_UNLOCK(adapter); - return; - } - - /* Link status change */ - if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - callout_stop(&adapter->timer); - adapter->hw.get_link_status = 1; - em_check_for_link(&adapter->hw); - em_print_link_status(adapter); - callout_reset(&adapter->timer, hz, em_local_timer, adapter); - } - - while (loop_cnt > 0) { - if (ifp->if_flags & IFF_RUNNING) { - em_process_receive_interrupts(adapter, -1); - em_clean_transmit_interrupts(adapter); - } - loop_cnt--; - } - - if (ifp->if_flags & IFF_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - em_start_locked(ifp); - + for (;;) { + reg_icr = E1000_READ_REG(&adapter->hw, ICR); + if (reg_icr == 0) + break; + if (ifp->if_flags & IFF_RUNNING) { + em_process_receive_interrupts(adapter, -1); + em_clean_transmit_interrupts(adapter); + } + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + callout_stop(&adapter->timer); + adapter->hw.get_link_status = 1; + em_check_for_link(&adapter->hw); + em_print_link_status(adapter); + callout_reset(&adapter->timer, hz, em_local_timer, adapter); + } + if (reg_icr & E1000_ICR_RXO) + log(LOG_WARNING, "%s: RX overrun\n", ifp->if_xname); + } + if (ifp->if_flags & IFF_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp); EM_UNLOCK(adapter); return; }