summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_em.c25
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;