FreeBSD/sys/dev/cadence/if_cgem.c
/* Find completed transmits and free their mbufs. */
Find completed transmits and free their mbufs.
Find completed transmits and free their mbufs .
static void
cgem_clean_tx(struct cgem_softc *sc)
{
	struct mbuf *m;
	uint32_t ctl;
	CGEM_ASSERT_LOCKED(sc);
	while (sc->txring_queued > 0 &&
	       ((ctl = sc->txring[sc->txring_tl_ptr].ctl) &
		CGEM_TXDESC_USED) != 0) {
		bus_dmamap_sync(sc->mbuf_dma_tag,
				sc->txring_m_dmamap[sc->txring_tl_ptr],
				BUS_DMASYNC_POSTWRITE);
		bus_dmamap_unload(sc->mbuf_dma_tag,
				  sc->txring_m_dmamap[sc->txring_tl_ptr]);
		bus_dmamap_destroy(sc->mbuf_dma_tag,
				   sc->txring_m_dmamap[sc->txring_tl_ptr]);
		sc->txring_m_dmamap[sc->txring_tl_ptr] = NULL;
		m = sc->txring_m[sc->txring_tl_ptr];
		sc->txring_m[sc->txring_tl_ptr] = NULL;
		m_freem(m);
		if ((ctl & CGEM_TXDESC_AHB_ERR) != 0) {
			device_printf(sc->dev, "cgem_clean_tx: Whoa! "
				   "AHB error, addr=0x%x\n",
				   sc->txring[sc->txring_tl_ptr].addr);
		} else if ((ctl & (CGEM_TXDESC_RETRY_ERR |
				   CGEM_TXDESC_LATE_COLL)) != 0) {
			if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
		} else
			if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
		while ((ctl & CGEM_TXDESC_LAST_BUF) == 0) {
			if ((ctl & CGEM_TXDESC_WRAP) != 0)
				sc->txring_tl_ptr = 0;
			else
				sc->txring_tl_ptr++;
			sc->txring_queued--;
			ctl = sc->txring[sc->txring_tl_ptr].ctl;
			sc->txring[sc->txring_tl_ptr].ctl =
				ctl | CGEM_TXDESC_USED;
		}
		if ((ctl & CGEM_TXDESC_WRAP) != 0)
			sc->txring_tl_ptr = 0;
		else
			sc->txring_tl_ptr++;
		sc->txring_queued--;
		if_setdrvflagbits(sc->ifp, 0, IFF_DRV_OACTIVE);
	}
}
static void cgem_clean_tx ( struct cgem_softc * sc ) { struct mbuf * m ; uint32_t ctl ; CGEM_ASSERT_LOCKED ( sc ) ; while ( sc -> txring_queued > 0 && ( ( ctl = sc -> txring [ sc -> txring_tl_ptr ] . ctl ) & CGEM_TXDESC_USED ) != 0 ) { bus_dmamap_sync ( sc -> mbuf_dma_tag , sc -> txring_m_dmamap [ sc -> txring_tl_ptr ] , BUS_DMASYNC_POSTWRITE ) ; bus_dmamap_unload ( sc -> mbuf_dma_tag , sc -> txring_m_dmamap [ sc -> txring_tl_ptr ] ) ; bus_dmamap_destroy ( sc -> mbuf_dma_tag , sc -> txring_m_dmamap [ sc -> txring_tl_ptr ] ) ; sc -> txring_m_dmamap [ sc -> txring_tl_ptr ] = NULL ; m = sc -> txring_m [ sc -> txring_tl_ptr ] ; sc -> txring_m [ sc -> txring_tl_ptr ] = NULL ; m_freem ( m ) ; if ( ( ctl & CGEM_TXDESC_AHB_ERR ) != 0 ) { device_printf ( sc -> dev , " " " \n " , sc -> txring [ sc -> txring_tl_ptr ] . addr ) ; } else if ( ( ctl & ( CGEM_TXDESC_RETRY_ERR | CGEM_TXDESC_LATE_COLL ) ) != 0 ) { if_inc_counter ( sc -> ifp , IFCOUNTER_OERRORS , 1 ) ; } else if_inc_counter ( sc -> ifp , IFCOUNTER_OPACKETS , 1 ) ; while ( ( ctl & CGEM_TXDESC_LAST_BUF ) == 0 ) { if ( ( ctl & CGEM_TXDESC_WRAP ) != 0 ) sc -> txring_tl_ptr = 0 ; else sc -> txring_tl_ptr ++ ; sc -> txring_queued -- ; ctl = sc -> txring [ sc -> txring_tl_ptr ] . ctl ; sc -> txring [ sc -> txring_tl_ptr ] . ctl = ctl | CGEM_TXDESC_USED ; } if ( ( ctl & CGEM_TXDESC_WRAP ) != 0 ) sc -> txring_tl_ptr = 0 ; else sc -> txring_tl_ptr ++ ; sc -> txring_queued -- ; if_setdrvflagbits ( sc -> ifp , 0 , IFF_DRV_OACTIVE ) ; } }
Find completed transmits and free their mbufs.
Find completed transmits and free their mbufs .
/* free up finished transmits. */ /* Sync cache. */ /* Unload and destroy DMA map. */ /* Free up the mbuf. */ /* Check the status. */ /* Serious bus error. log to console. */ /* If the packet spanned more than one tx descriptor,
		 * skip descriptors until we find the end so that only
		 * start-of-frame descriptors are processed.
		 */ /* Next descriptor. */