Fix the OACTIVE handling on if_dwc.

Previously the OACTIVE flag was being set when the tx descriptors are fully
allocated but it wasn't unset anywhere.

As soon as a packet is transmitted, unset the OACTIVE flag and call start
routine to push any pending packets from the tx queue.

This closes another race where a full tx queue would jam the tx path (tx
queue is full, new packets cannot be added to queue and dwc_txstart never
gets called).
This commit is contained in:
Luiz Otavio O Souza 2015-06-03 14:48:03 +00:00
parent 8826d90475
commit 9500101c2f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=283948

View File

@ -741,9 +741,11 @@ dwc_txfinish_locked(struct dwc_softc *sc)
{
struct dwc_bufmap *bmap;
struct dwc_hwdesc *desc;
struct ifnet *ifp;
DWC_ASSERT_LOCKED(sc);
fp = sc->ifp;
while (sc->tx_idx_tail != sc->tx_idx_head) {
desc = &sc->txdesc_ring[sc->tx_idx_tail];
if ((desc->tdes0 & DDESC_TDES0_OWN) != 0)
@ -756,6 +758,7 @@ dwc_txfinish_locked(struct dwc_softc *sc)
bmap->mbuf = NULL;
dwc_setup_txdesc(sc, sc->tx_idx_tail, 0, 0);
sc->tx_idx_tail = next_txidx(sc, sc->tx_idx_tail);
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
/* If there are no buffers outstanding, muzzle the watchdog. */
@ -838,8 +841,10 @@ dwc_intr(void *arg)
if (reg & DMA_STATUS_RI)
dwc_rxfinish_locked(sc);
if (reg & DMA_STATUS_TI)
if (reg & DMA_STATUS_TI) {
dwc_txfinish_locked(sc);
dwc_txstart_locked(sc);
}
}
if (reg & DMA_STATUS_AIS) {