svn commit: r199666 - head/sys/dev/bge
Pyun YongHyeon
yongari at FreeBSD.org
Sun Nov 22 19:44:11 UTC 2009
Author: yongari
Date: Sun Nov 22 19:44:11 2009
New Revision: 199666
URL: http://svn.freebsd.org/changeset/base/199666
Log:
Rearrange bge_start_locked to see we can send more frames by
checking IFF_DRV_RUNNING and IFF_DRV_OACTIVE flags. Also if we
have less than 16 free send BDs set IFF_DRV_OACTIVE and try it
later. Previously bge(4) used to reserve 16 free send BDs after
loading dma maps but hardware just need one reserved send BD. If
prouder index has the same value of consumer index it means the Tx
queue is empty.
While I'm here check IFQ_DRV_IS_EMPTY first to save one lock
operation.
Modified:
head/sys/dev/bge/if_bge.c
Modified: head/sys/dev/bge/if_bge.c
==============================================================================
--- head/sys/dev/bge/if_bge.c Sun Nov 22 19:17:32 2009 (r199665)
+++ head/sys/dev/bge/if_bge.c Sun Nov 22 19:44:11 2009 (r199666)
@@ -3683,11 +3683,8 @@ bge_encap(struct bge_softc *sc, struct m
} else if (error != 0)
return (error);
- /*
- * Sanity check: avoid coming within 16 descriptors
- * of the end of the ring.
- */
- if (nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16)) {
+ /* Check if we have enough free send BDs. */
+ if (sc->bge_txcnt + nsegs >= BGE_TX_RING_CNT) {
bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, map);
return (ENOBUFS);
}
@@ -3752,18 +3749,25 @@ static void
bge_start_locked(struct ifnet *ifp)
{
struct bge_softc *sc;
- struct mbuf *m_head = NULL;
+ struct mbuf *m_head;
uint32_t prodidx;
- int count = 0;
+ int count;
sc = ifp->if_softc;
+ BGE_LOCK_ASSERT(sc);
- if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ if (!sc->bge_link ||
+ (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
return;
prodidx = sc->bge_tx_prodidx;
- while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
+ for (count = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd);) {
+ if (sc->bge_txcnt > BGE_TX_RING_CNT - 16) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
if (m_head == NULL)
break;
@@ -3816,24 +3820,22 @@ bge_start_locked(struct ifnet *ifp)
#endif
}
- if (count == 0)
- /* No packets were dequeued. */
- return;
-
- bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
- sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
- /* Transmit. */
- bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
- /* 5700 b2 errata */
- if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
+ if (count > 0) {
+ bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
+ sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
+ /* Transmit. */
bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
+ /* 5700 b2 errata */
+ if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
+ bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
- sc->bge_tx_prodidx = prodidx;
+ sc->bge_tx_prodidx = prodidx;
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- sc->bge_timer = 5;
+ /*
+ * Set a timeout in case the chip goes out to lunch.
+ */
+ sc->bge_timer = 5;
+ }
}
/*
More information about the svn-src-all
mailing list