FreeBSD/sys/dev/ste/if_ste.c
/*
 * A frame has been uploaded: pass the resulting mbuf chain up to
 * the higher level protocols.
 */
A frame has been uploaded: pass the resulting mbuf chain up to
the higher level protocols.
A frame has been uploaded : pass the resulting mbuf chain up to the higher level protocols .
static int
ste_rxeof(struct ste_softc *sc, int count)
{
        struct mbuf *m;
        struct ifnet *ifp;
	struct ste_chain_onefrag *cur_rx;
	uint32_t rxstat;
	int total_len, rx_npkts;
	ifp = sc->ste_ifp;
	bus_dmamap_sync(sc->ste_cdata.ste_rx_list_tag,
	    sc->ste_cdata.ste_rx_list_map,
	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
	cur_rx = sc->ste_cdata.ste_rx_head;
	for (rx_npkts = 0; rx_npkts < STE_RX_LIST_CNT; rx_npkts++,
	    cur_rx = cur_rx->ste_next) {
		rxstat = le32toh(cur_rx->ste_ptr->ste_status);
		if ((rxstat & STE_RXSTAT_DMADONE) == 0)
			break;
#ifdef DEVICE_POLLING
		if (ifp->if_capenable & IFCAP_POLLING) {
			if (count == 0)
				break;
			count--;
		}
#endif
		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
			break;
		if (rxstat & STE_RXSTAT_FRAME_ERR) {
			if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
			cur_rx->ste_ptr->ste_status = 0;
			continue;
		}
		m = cur_rx->ste_mbuf;
		total_len = STE_RX_BYTES(rxstat);
		if (ste_newbuf(sc, cur_rx) != 0) {
			if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
			cur_rx->ste_ptr->ste_status = 0;
			continue;
		}
		m->m_pkthdr.rcvif = ifp;
		m->m_pkthdr.len = m->m_len = total_len;
		if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
		STE_UNLOCK(sc);
		(*ifp->if_input)(ifp, m);
		STE_LOCK(sc);
	}
	if (rx_npkts > 0) {
		sc->ste_cdata.ste_rx_head = cur_rx;
		bus_dmamap_sync(sc->ste_cdata.ste_rx_list_tag,
		    sc->ste_cdata.ste_rx_list_map,
		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
	}
	return (rx_npkts);
}
static int ste_rxeof ( struct ste_softc * sc , int count ) { struct mbuf * m ; struct ifnet * ifp ; struct ste_chain_onefrag * cur_rx ; uint32_t rxstat ; int total_len , rx_npkts ; ifp = sc -> ste_ifp ; bus_dmamap_sync ( sc -> ste_cdata . ste_rx_list_tag , sc -> ste_cdata . ste_rx_list_map , BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE ) ; cur_rx = sc -> ste_cdata . ste_rx_head ; for ( rx_npkts = 0 ; rx_npkts < STE_RX_LIST_CNT ; rx_npkts ++ , cur_rx = cur_rx -> ste_next ) { rxstat = le32toh ( cur_rx -> ste_ptr -> ste_status ) ; if ( ( rxstat & STE_RXSTAT_DMADONE ) == 0 ) break ; #ifdef DEVICE_POLLING if ( ifp -> if_capenable & IFCAP_POLLING ) { if ( count == 0 ) break ; count -- ; } #endif if ( ( ifp -> if_drv_flags & IFF_DRV_RUNNING ) == 0 ) break ; if ( rxstat & STE_RXSTAT_FRAME_ERR ) { if_inc_counter ( ifp , IFCOUNTER_IERRORS , 1 ) ; cur_rx -> ste_ptr -> ste_status = 0 ; continue ; } m = cur_rx -> ste_mbuf ; total_len = STE_RX_BYTES ( rxstat ) ; if ( ste_newbuf ( sc , cur_rx ) != 0 ) { if_inc_counter ( ifp , IFCOUNTER_IQDROPS , 1 ) ; cur_rx -> ste_ptr -> ste_status = 0 ; continue ; } m -> m_pkthdr . rcvif = ifp ; m -> m_pkthdr . len = m -> m_len = total_len ; if_inc_counter ( ifp , IFCOUNTER_IPACKETS , 1 ) ; STE_UNLOCK ( sc ) ; ( * ifp -> if_input ) ( ifp , m ) ; STE_LOCK ( sc ) ; } if ( rx_npkts > 0 ) { sc -> ste_cdata . ste_rx_head = cur_rx ; bus_dmamap_sync ( sc -> ste_cdata . ste_rx_list_tag , sc -> ste_cdata . ste_rx_list_map , BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE ) ; } return ( rx_npkts ) ; }
A frame has been uploaded: pass the resulting mbuf chain up to
 the higher level protocols.
A frame has been uploaded : pass the resulting mbuf chain up to the higher level protocols .
/*
		 * If an error occurs, update stats, clear the
		 * status word and leave the mbuf cluster in place:
		 * it should simply get re-used next time this descriptor
	 	 * comes up in the ring.
		 */ /* No errors; receive the packet. */ /*
		 * Try to conjure up a new mbuf cluster. If that
		 * fails, it means we have an out of memory condition and
		 * should leave the buffer in place and continue. This will
		 * result in a lost packet, but there's little else we
		 * can do in this situation.
		 */