FreeBSD/sys/dev/e1000/if_em.c
/*********************************************************************
 *
 *  Initialize a receive ring and its buffers.
 *
 **********************************************************************/
Initialize a receive ring and its buffers.
Initialize a receive ring and its buffers .
static int
em_setup_receive_ring(struct rx_ring *rxr)
{
	struct	adapter 	*adapter = rxr->adapter;
	struct em_rxbuffer	*rxbuf;
	bus_dma_segment_t	seg[1];
	int			rsize, nsegs, error = 0;
#ifdef DEV_NETMAP
	struct netmap_slot *slot;
	struct netmap_adapter *na = netmap_getna(adapter->ifp);
#endif
	EM_RX_LOCK(rxr);
	rsize = roundup2(adapter->num_rx_desc *
	    sizeof(union e1000_rx_desc_extended), EM_DBA_ALIGN);
	bzero((void *)rxr->rx_base, rsize);
#ifdef DEV_NETMAP
	slot = netmap_reset(na, NR_RX, rxr->me, 0);
#endif
	for (int i = 0; i < adapter->num_rx_desc; i++) {
		rxbuf = &rxr->rx_buffers[i];
		if (rxbuf->m_head != NULL) {
			bus_dmamap_sync(rxr->rxtag, rxbuf->map,
			    BUS_DMASYNC_POSTREAD);
			bus_dmamap_unload(rxr->rxtag, rxbuf->map);
			m_freem(rxbuf->m_head);
			rxbuf->m_head = NULL; 
		}
	}
        for (int j = 0; j != adapter->num_rx_desc; ++j) {
		rxbuf = &rxr->rx_buffers[j];
#ifdef DEV_NETMAP
		if (slot) {
			int si = netmap_idx_n2k(&na->rx_rings[rxr->me], j);
			uint64_t paddr;
			void *addr;
			addr = PNMB(na, slot + si, &paddr);
			netmap_load_map(na, rxr->rxtag, rxbuf->map, addr);
			rxbuf->paddr = paddr;
			em_setup_rxdesc(&rxr->rx_base[j], rxbuf);
			continue;
		}
#endif 
		rxbuf->m_head = m_getjcl(M_NOWAIT, MT_DATA,
		    M_PKTHDR, adapter->rx_mbuf_sz);
		if (rxbuf->m_head == NULL) {
			error = ENOBUFS;
			goto fail;
		}
		rxbuf->m_head->m_len = adapter->rx_mbuf_sz;
		rxbuf->m_head->m_flags &= ~M_HASFCS; 
		rxbuf->m_head->m_pkthdr.len = adapter->rx_mbuf_sz;
		error = bus_dmamap_load_mbuf_sg(rxr->rxtag,
		    rxbuf->map, rxbuf->m_head, seg,
		    &nsegs, BUS_DMA_NOWAIT);
		if (error != 0) {
			m_freem(rxbuf->m_head);
			rxbuf->m_head = NULL;
			goto fail;
		}
		bus_dmamap_sync(rxr->rxtag,
		    rxbuf->map, BUS_DMASYNC_PREREAD);
		rxbuf->paddr = seg[0].ds_addr;
		em_setup_rxdesc(&rxr->rx_base[j], rxbuf);
	}
	rxr->next_to_check = 0;
	rxr->next_to_refresh = 0;
	bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
fail:
	EM_RX_UNLOCK(rxr);
	return (error);
}
static int em_setup_receive_ring ( struct rx_ring * rxr ) { struct adapter * adapter = rxr -> adapter ; struct em_rxbuffer * rxbuf ; bus_dma_segment_t seg [ 1 ] ; int rsize , nsegs , error = 0 ; #ifdef DEV_NETMAP struct netmap_slot * slot ; struct netmap_adapter * na = netmap_getna ( adapter -> ifp ) ; #endif EM_RX_LOCK ( rxr ) ; rsize = roundup2 ( adapter -> num_rx_desc * sizeof ( union e1000_rx_desc_extended ) , EM_DBA_ALIGN ) ; bzero ( ( void * ) rxr -> rx_base , rsize ) ; #ifdef DEV_NETMAP slot = netmap_reset ( na , NR_RX , rxr -> me , 0 ) ; #endif for ( int i = 0 ; i < adapter -> num_rx_desc ; i ++ ) { rxbuf = & rxr -> rx_buffers [ i ] ; if ( rxbuf -> m_head != NULL ) { bus_dmamap_sync ( rxr -> rxtag , rxbuf -> map , BUS_DMASYNC_POSTREAD ) ; bus_dmamap_unload ( rxr -> rxtag , rxbuf -> map ) ; m_freem ( rxbuf -> m_head ) ; rxbuf -> m_head = NULL ; } } for ( int j = 0 ; j != adapter -> num_rx_desc ; ++ j ) { rxbuf = & rxr -> rx_buffers [ j ] ; #ifdef DEV_NETMAP if ( slot ) { int si = netmap_idx_n2k ( & na -> rx_rings [ rxr -> me ] , j ) ; uint64_t paddr ; void * addr ; addr = PNMB ( na , slot + si , & paddr ) ; netmap_load_map ( na , rxr -> rxtag , rxbuf -> map , addr ) ; rxbuf -> paddr = paddr ; em_setup_rxdesc ( & rxr -> rx_base [ j ] , rxbuf ) ; continue ; } #endif rxbuf -> m_head = m_getjcl ( M_NOWAIT , MT_DATA , M_PKTHDR , adapter -> rx_mbuf_sz ) ; if ( rxbuf -> m_head == NULL ) { error = ENOBUFS ; goto fail ; } rxbuf -> m_head -> m_len = adapter -> rx_mbuf_sz ; rxbuf -> m_head -> m_flags &= ~ M_HASFCS ; rxbuf -> m_head -> m_pkthdr . len = adapter -> rx_mbuf_sz ; error = bus_dmamap_load_mbuf_sg ( rxr -> rxtag , rxbuf -> map , rxbuf -> m_head , seg , & nsegs , BUS_DMA_NOWAIT ) ; if ( error != 0 ) { m_freem ( rxbuf -> m_head ) ; rxbuf -> m_head = NULL ; goto fail ; } bus_dmamap_sync ( rxr -> rxtag , rxbuf -> map , BUS_DMASYNC_PREREAD ) ; rxbuf -> paddr = seg [ 0 ] . ds_addr ; em_setup_rxdesc ( & rxr -> rx_base [ j ] , rxbuf ) ; } rxr -> next_to_check = 0 ; rxr -> next_to_refresh = 0 ; bus_dmamap_sync ( rxr -> rxdma . dma_tag , rxr -> rxdma . dma_map , BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE ) ; fail : EM_RX_UNLOCK ( rxr ) ; return ( error ) ; }
Initialize a receive ring and its buffers.
Initialize a receive ring and its buffers .
/* Clear the ring contents */ /*
	** Free current RX buffer structs and their mbufs
	*/ /* mark as freed */ /* Now replenish the mbufs */ /* DEV_NETMAP */ /* we strip it */ /* Get the memory mapping */