diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_em.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c index 0726535ffba..3c1a62eabfe 100644 --- a/sys/dev/pci/if_em.c +++ b/sys/dev/pci/if_em.c @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ /* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */ -/* $OpenBSD: if_em.c,v 1.44 2005/04/01 06:44:14 brad Exp $ */ +/* $OpenBSD: if_em.c,v 1.45 2005/04/10 04:08:40 brad Exp $ */ #include "bpfilter.h" #include "vlan.h" @@ -184,7 +184,7 @@ int em_get_buf(int i, struct em_softc *, struct mbuf *); void em_enable_vlans(struct em_softc *); void em_disable_vlans(struct em_softc *); -int em_encap(struct em_softc *, struct mbuf *); +int em_encap(struct em_softc *, struct mbuf **); void em_smartspeed(struct em_softc *); int em_82547_fifo_workaround(struct em_softc *, int); void em_82547_update_fifo_head(struct em_softc *, int); @@ -460,7 +460,13 @@ em_start_locked(struct ifnet *ifp) if (m_head == NULL) break; - if (em_encap(sc, m_head)) { + /* + * em_encap() can modify our pointer, and or make it NULL on + * failure. In that event, we can't requeue. + */ + if (em_encap(sc, &m_head)) { + if (m_head == NULL) + break; ifp->if_flags |= IFF_OACTIVE; break; } @@ -733,7 +739,7 @@ em_init_locked(struct em_softc *sc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - timeout_add(&sc->timer_handle, 2*hz); + timeout_add(&sc->timer_handle, hz); em_clear_hw_cntrs(&sc->hw); em_enable_intr(sc); @@ -785,7 +791,7 @@ em_intr(void *arg) sc->hw.get_link_status = 1; em_check_for_link(&sc->hw); em_update_link_status(sc); - timeout_add(&sc->timer_handle, 2*hz); + timeout_add(&sc->timer_handle, hz); } while (loop_cnt > 0) { @@ -930,13 +936,15 @@ em_media_change(struct ifnet *ifp) * return 0 on success, positive on failure **********************************************************************/ int -em_encap(struct em_softc *sc, struct mbuf *m_head) +em_encap(struct em_softc *sc, struct mbuf **m_headp) { u_int32_t txd_upper; u_int32_t txd_lower, txd_used = 0, txd_saved = 0; int i, j, error; u_int64_t address; + struct mbuf *m_head; + /* For 82544 Workaround */ DESC_ARRAY desc_array; u_int32_t array_elements; @@ -948,7 +956,8 @@ em_encap(struct em_softc *sc, struct mbuf *m_head) struct em_buffer *tx_buffer = NULL; struct em_tx_desc *current_tx_desc = NULL; - /*struct ifnet *ifp = &sc->interface_data.ac_if;*/ + + m_head = *m_headp; /* * Force a cleanup if number of TX descriptors @@ -1364,7 +1373,7 @@ em_local_timer(void *arg) } em_smartspeed(sc); - timeout_add(&sc->timer_handle, 2*hz); + timeout_add(&sc->timer_handle, hz); EM_UNLOCK(sc); return; |