From 9500101c2f7dab4553943ba8d74fbe41fb5c8322 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Wed, 3 Jun 2015 14:48:03 +0000 Subject: [PATCH] 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). --- sys/dev/dwc/if_dwc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c index 57e6b44eee9..f2603833fc1 100644 --- a/sys/dev/dwc/if_dwc.c +++ b/sys/dev/dwc/if_dwc.c @@ -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) {