FreeBSD/sys/dev/cadence/if_cgem.c
/* Pull received packets off of receive descriptor ring. */
Pull received packets off of receive descriptor ring.
Pull received packets off of receive descriptor ring .
static void
cgem_recv(struct cgem_softc *sc)
{
	if_t ifp = sc->ifp;
	struct mbuf *m, *m_hd, **m_tl;
	uint32_t ctl;
	CGEM_ASSERT_LOCKED(sc);
	m_hd = NULL;
	m_tl = &m_hd;
	while (sc->rxring_queued > 0 &&
	       (sc->rxring[sc->rxring_tl_ptr].addr & CGEM_RXDESC_OWN) != 0) {
		ctl = sc->rxring[sc->rxring_tl_ptr].ctl;
		m = sc->rxring_m[sc->rxring_tl_ptr];
		sc->rxring_m[sc->rxring_tl_ptr] = NULL;
		bus_dmamap_sync(sc->mbuf_dma_tag,
				sc->rxring_m_dmamap[sc->rxring_tl_ptr],
				BUS_DMASYNC_POSTREAD);
		bus_dmamap_unload(sc->mbuf_dma_tag,
		  	sc->rxring_m_dmamap[sc->rxring_tl_ptr]);
		bus_dmamap_destroy(sc->mbuf_dma_tag,
				   sc->rxring_m_dmamap[sc->rxring_tl_ptr]);
		sc->rxring_m_dmamap[sc->rxring_tl_ptr] = NULL;
		if (++sc->rxring_tl_ptr == CGEM_NUM_RX_DESCS)
			sc->rxring_tl_ptr = 0;
		sc->rxring_queued--;
		if ((ctl & CGEM_RXDESC_BAD_FCS) != 0 ||
		    (ctl & (CGEM_RXDESC_SOF | CGEM_RXDESC_EOF)) !=
		           (CGEM_RXDESC_SOF | CGEM_RXDESC_EOF)) {
			m_free(m);
			if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
			continue;
		}
		m->m_data += ETHER_ALIGN;
		m->m_len = (ctl & CGEM_RXDESC_LENGTH_MASK);
		m->m_pkthdr.rcvif = ifp;
		m->m_pkthdr.len = m->m_len;
		if ((if_getcapenable(ifp) & IFCAP_RXCSUM) != 0) {
			if ((ctl & CGEM_RXDESC_CKSUM_STAT_MASK) ==
			    CGEM_RXDESC_CKSUM_STAT_TCP_GOOD ||
			    (ctl & CGEM_RXDESC_CKSUM_STAT_MASK) ==
			    CGEM_RXDESC_CKSUM_STAT_UDP_GOOD) {
				m->m_pkthdr.csum_flags |=
					CSUM_IP_CHECKED | CSUM_IP_VALID |
					CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
				m->m_pkthdr.csum_data = 0xffff;
			} else if ((ctl & CGEM_RXDESC_CKSUM_STAT_MASK) ==
				   CGEM_RXDESC_CKSUM_STAT_IP_GOOD) {
				m->m_pkthdr.csum_flags |=
					CSUM_IP_CHECKED | CSUM_IP_VALID;
				m->m_pkthdr.csum_data = 0xffff;
			}
		}
		*m_tl = m;
		m_tl = &m->m_next;
	}
	cgem_fill_rqueue(sc);
	CGEM_UNLOCK(sc);
	while (m_hd != NULL) {
		m = m_hd;
		m_hd = m_hd->m_next;
		m->m_next = NULL;
		if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
		if_input(ifp, m);
	}
	CGEM_LOCK(sc);
}
static void cgem_recv ( struct cgem_softc * sc ) { if_t ifp = sc -> ifp ; struct mbuf * m , * m_hd , * * m_tl ; uint32_t ctl ; CGEM_ASSERT_LOCKED ( sc ) ; m_hd = NULL ; m_tl = & m_hd ; while ( sc -> rxring_queued > 0 && ( sc -> rxring [ sc -> rxring_tl_ptr ] . addr & CGEM_RXDESC_OWN ) != 0 ) { ctl = sc -> rxring [ sc -> rxring_tl_ptr ] . ctl ; m = sc -> rxring_m [ sc -> rxring_tl_ptr ] ; sc -> rxring_m [ sc -> rxring_tl_ptr ] = NULL ; bus_dmamap_sync ( sc -> mbuf_dma_tag , sc -> rxring_m_dmamap [ sc -> rxring_tl_ptr ] , BUS_DMASYNC_POSTREAD ) ; bus_dmamap_unload ( sc -> mbuf_dma_tag , sc -> rxring_m_dmamap [ sc -> rxring_tl_ptr ] ) ; bus_dmamap_destroy ( sc -> mbuf_dma_tag , sc -> rxring_m_dmamap [ sc -> rxring_tl_ptr ] ) ; sc -> rxring_m_dmamap [ sc -> rxring_tl_ptr ] = NULL ; if ( ++ sc -> rxring_tl_ptr == CGEM_NUM_RX_DESCS ) sc -> rxring_tl_ptr = 0 ; sc -> rxring_queued -- ; if ( ( ctl & CGEM_RXDESC_BAD_FCS ) != 0 || ( ctl & ( CGEM_RXDESC_SOF | CGEM_RXDESC_EOF ) ) != ( CGEM_RXDESC_SOF | CGEM_RXDESC_EOF ) ) { m_free ( m ) ; if_inc_counter ( ifp , IFCOUNTER_IERRORS , 1 ) ; continue ; } m -> m_data += ETHER_ALIGN ; m -> m_len = ( ctl & CGEM_RXDESC_LENGTH_MASK ) ; m -> m_pkthdr . rcvif = ifp ; m -> m_pkthdr . len = m -> m_len ; if ( ( if_getcapenable ( ifp ) & IFCAP_RXCSUM ) != 0 ) { if ( ( ctl & CGEM_RXDESC_CKSUM_STAT_MASK ) == CGEM_RXDESC_CKSUM_STAT_TCP_GOOD || ( ctl & CGEM_RXDESC_CKSUM_STAT_MASK ) == CGEM_RXDESC_CKSUM_STAT_UDP_GOOD ) { m -> m_pkthdr . csum_flags |= CSUM_IP_CHECKED | CSUM_IP_VALID | CSUM_DATA_VALID | CSUM_PSEUDO_HDR ; m -> m_pkthdr . csum_data = 0xffff ; } else if ( ( ctl & CGEM_RXDESC_CKSUM_STAT_MASK ) == CGEM_RXDESC_CKSUM_STAT_IP_GOOD ) { m -> m_pkthdr . csum_flags |= CSUM_IP_CHECKED | CSUM_IP_VALID ; m -> m_pkthdr . csum_data = 0xffff ; } } * m_tl = m ; m_tl = & m -> m_next ; } cgem_fill_rqueue ( sc ) ; CGEM_UNLOCK ( sc ) ; while ( m_hd != NULL ) { m = m_hd ; m_hd = m_hd -> m_next ; m -> m_next = NULL ; if_inc_counter ( ifp , IFCOUNTER_IPACKETS , 1 ) ; if_input ( ifp , m ) ; } CGEM_LOCK ( sc ) ; }
Pull received packets off of receive descriptor ring.
Pull received packets off of receive descriptor ring .
/* Pick up all packets in which the OWN bit is set. */ /* Grab filled mbuf. */ /* Sync cache with receive buffer. */ /* Unload and destroy dmamap. */ /* Increment tail pointer. */ /* Check FCS and make sure entire packet landed in one mbuf
		 * cluster (which is much bigger than the largest ethernet
		 * packet).
		 */ /* discard. */ /* Ready it to hand off to upper layers. */ /* Are we using hardware checksumming?  Check the
		 * status in the receive descriptor.
		 */ /* TCP or UDP checks out, IP checks out too. */ /* Only IP checks out. */ /* Queue it up for delivery below. */ /* Replenish receive buffers. */ /* Unlock and send up packets. */