summaryrefslogtreecommitdiffstats
path: root/sys/dev/bce
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2006-10-21 07:54:39 +0000
committerscottl <scottl@FreeBSD.org>2006-10-21 07:54:39 +0000
commit077b3a2427d98693ce9a6f507645597093ce1753 (patch)
treed6bb97928310902437eb05c607c0c9a3af06dfa6 /sys/dev/bce
parent8659159398bccc8797b336e55c8b24e136f510bd (diff)
downloadFreeBSD-src-077b3a2427d98693ce9a6f507645597093ce1753.zip
FreeBSD-src-077b3a2427d98693ce9a6f507645597093ce1753.tar.gz
Be more like the BGE driver. Ensure that at least 16 TX descriptors are
kept unused in the ring. This check should probably be moved up to bce_start_locked at some point, as it'll make the loop up there slightly more efficient, and will eliminate a costly set of busdma operations when the ring is full. But this works for now. This makes all of my UDP torture tests work. I'll cautiously say that it might even work for other users now. Feedback is appreciated.
Diffstat (limited to 'sys/dev/bce')
-rw-r--r--sys/dev/bce/if_bce.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 0eacbe2..cefd7f8 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -4549,13 +4549,6 @@ bce_tx_encap(struct bce_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 - BCE_TX_SLACK_SPACE) <= 0) {
- return (ENOBUFS);
- }
-
/* Map the mbuf into our DMA address space. */
error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
segs, &nsegs, BUS_DMA_NOWAIT);
@@ -4596,6 +4589,16 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
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 nsegs
+ * and do this calculation higher up?
+ */
+ if (nsegs > (USABLE_TX_BD - sc->used_tx_bd - BCE_TX_SLACK_SPACE)) {
+ bus_dmamap_unload(sc->tx_mbuf_tag, map);
+ return (ENOBUFS);
+ }
/* prod points to an empty tx_bd at this point. */
prod_bseq = sc->tx_prod_bseq;
@@ -4701,7 +4704,7 @@ bce_start_locked(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_DRV_IS_EMPTY(&ifp->if_snd)) {
+ while (sc->tx_mbuf_ptr[tx_chain_prod] == NULL) {
/* Check for any frames to send. */
IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
OpenPOWER on IntegriCloud