summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2006-10-22 20:27:42 +0000
committerBrad Smith <brad@cvs.openbsd.org>2006-10-22 20:27:42 +0000
commitb0bf4f3a32c2b92649e4b9acb88add5c3354ebcc (patch)
tree7612ebd5331a4f883a8e9cf4fc8fe163d709f102 /sys/dev/pci
parent6dc242864643e9b3c397e98709552c44f78e9517 (diff)
now with the right revision of this diff which compiles. ok pedro, mglocker.
- Ensure that at least 16 TX descriptors are kept unused in the ring. - Use more complete error handling for TX load problems. From scottl@FreeBSD
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_bnx.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/sys/dev/pci/if_bnx.c b/sys/dev/pci/if_bnx.c
index 04bd99fcd9c..2b52cb5147c 100644
--- a/sys/dev/pci/if_bnx.c
+++ b/sys/dev/pci/if_bnx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bnx.c,v 1.29 2006/10/21 23:45:51 deraadt Exp $ */
+/* $OpenBSD: if_bnx.c,v 1.30 2006/10/22 20:27:41 brad Exp $ */
/*-
* Copyright (c) 2006 Broadcom Corporation
@@ -4296,20 +4296,27 @@ bnx_tx_encap(struct bnx_softc *sc, struct mbuf **m_head)
chain_prod = TX_CHAIN_IDX(prod);
map = sc->tx_mbuf_map[chain_prod];
- /*
- * XXX This should be handled higher up.
- */
- if ((USABLE_TX_BD - sc->used_tx_bd - BNX_TX_SLACK_SPACE) <= 0)
- return (ENOBUFS);
-
/* Map the mbuf into our DMA address space. */
error = bus_dmamap_load_mbuf(sc->bnx_dmatag, map, m0, BUS_DMA_NOWAIT);
if (error != 0) {
printf("%s: Error mapping mbuf into TX chain!\n",
sc->bnx_dev.dv_xname);
+ m_freem(m0);
+ *m_head = NULL;
return (error);
}
+ /*
+ * The chip seems to require that at least 16 descriptors be kept
+ * empty at all times. Make sure we honor that.
+ * XXX Would it be faster to assume worst case scenario for
+ * map->dm_nsegs and do this calculation higher up?
+ */
+ if (map->dm_nsegs > (USABLE_TX_BD - sc->used_tx_bd - BNX_TX_SLACK_SPACE)) {
+ bus_dmamap_unload(sc->bnx_dmatag, map);
+ return (ENOBUFS);
+ }
+
/* prod points to an empty tx_bd at this point. */
prod_bseq = sc->tx_prod_bseq;
#ifdef BNX_DEBUG
@@ -4413,7 +4420,7 @@ bnx_start(struct ifnet *ifp)
__FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
/* Keep adding entries while there is space in the ring. */
- while (!IFQ_IS_EMPTY(&ifp->if_snd)) {
+ while (sc->tx_mbuf_ptr[tx_chain_prod] == NULL) {
/* Check for any frames to send. */
IFQ_POLL(&ifp->if_snd, m_head);
if (m_head == NULL)
@@ -4421,9 +4428,8 @@ bnx_start(struct ifnet *ifp)
/*
* Pack the data into the transmit ring. If we
- * don't have room, place the mbuf back at the
- * head of the queue and set the OACTIVE flag
- * to wait for the NIC to drain the chain.
+ * don't have room, set the OACTIVE flag to wait
+ * for the NIC to drain the chain.
*/
if (bnx_tx_encap(sc, &m_head)) {
ifp->if_flags |= IFF_OACTIVE;