FreeBSD/sys/dev/ixl/ixl_txrx.c
/*********************************************************************
 *
 *  (Re)Initialize the queue receive ring and its buffers.
 *
 **********************************************************************/
(Re)Initialize the queue receive ring and its buffers.
( Re ) Initialize the queue receive ring and its buffers .
int
ixl_init_rx_ring(struct ixl_queue *que)
{
	struct	rx_ring 	*rxr = &que->rxr;
	struct ixl_vsi		*vsi = que->vsi;
#if defined(INET6) || defined(INET)
	struct ifnet		*ifp = vsi->ifp;
	struct lro_ctrl		*lro = &rxr->lro;
#endif
	struct ixl_rx_buf	*buf;
	bus_dma_segment_t	pseg[1], hseg[1];
	int			rsize, nsegs, error = 0;
#ifdef DEV_NETMAP
	struct netmap_adapter *na = NA(que->vsi->ifp);
	struct netmap_slot *slot;
#endif 
	IXL_RX_LOCK(rxr);
#ifdef DEV_NETMAP
	slot = netmap_reset(na, NR_RX, que->me, 0);
#endif 
	rsize = roundup2(que->num_desc *
	    sizeof(union i40e_rx_desc), DBA_ALIGN);
	bzero((void *)rxr->base, rsize);
	for (int i = 0; i < que->num_desc; i++) {
		buf = &rxr->buffers[i];
		if (buf->m_head != NULL) {
			bus_dmamap_sync(rxr->htag, buf->hmap,
			    BUS_DMASYNC_POSTREAD);
			bus_dmamap_unload(rxr->htag, buf->hmap);
			buf->m_head->m_flags |= M_PKTHDR;
			m_freem(buf->m_head);
		}
		if (buf->m_pack != NULL) {
			bus_dmamap_sync(rxr->ptag, buf->pmap,
			    BUS_DMASYNC_POSTREAD);
			bus_dmamap_unload(rxr->ptag, buf->pmap);
			buf->m_pack->m_flags |= M_PKTHDR;
			m_freem(buf->m_pack);
		}
		buf->m_head = NULL;
		buf->m_pack = NULL;
	}
	rxr->hdr_split = FALSE;
	for (int j = 0; j != que->num_desc; ++j) {
		struct mbuf	*mh, *mp;
		buf = &rxr->buffers[j];
#ifdef DEV_NETMAP
		if (slot) {
			int sj = netmap_idx_n2k(&na->rx_rings[que->me], j);
			uint64_t paddr;
			void *addr;
			addr = PNMB(na, slot + sj, &paddr);
			netmap_load_map(na, rxr->dma.tag, buf->pmap, addr);
			rxr->base[j].read.pkt_addr = htole64(paddr);
			rxr->base[j].read.hdr_addr = 0;
			continue;
		}
#endif 
		if (rxr->hdr_split == FALSE)
			goto skip_head;
		buf->m_head = m_gethdr(M_NOWAIT, MT_DATA);
		if (buf->m_head == NULL) {
			error = ENOBUFS;
			goto fail;
		}
		m_adj(buf->m_head, ETHER_ALIGN);
		mh = buf->m_head;
		mh->m_len = mh->m_pkthdr.len = MHLEN;
		mh->m_flags |= M_PKTHDR;
		error = bus_dmamap_load_mbuf_sg(rxr->htag,
		    buf->hmap, buf->m_head, hseg,
		    &nsegs, BUS_DMA_NOWAIT);
		if (error != 0) 
			goto fail;
		bus_dmamap_sync(rxr->htag,
		    buf->hmap, BUS_DMASYNC_PREREAD);
		rxr->base[j].read.hdr_addr = htole64(hseg[0].ds_addr);
skip_head:
		buf->m_pack = m_getjcl(M_NOWAIT, MT_DATA,
		    M_PKTHDR, rxr->mbuf_sz);
		if (buf->m_pack == NULL) {
			error = ENOBUFS;
                        goto fail;
		}
		mp = buf->m_pack;
		mp->m_pkthdr.len = mp->m_len = rxr->mbuf_sz;
		error = bus_dmamap_load_mbuf_sg(rxr->ptag,
		    buf->pmap, mp, pseg,
		    &nsegs, BUS_DMA_NOWAIT);
		if (error != 0)
                        goto fail;
		bus_dmamap_sync(rxr->ptag,
		    buf->pmap, BUS_DMASYNC_PREREAD);
		rxr->base[j].read.pkt_addr = htole64(pseg[0].ds_addr);
		rxr->base[j].read.hdr_addr = 0;
	}
	rxr->next_check = 0;
	rxr->next_refresh = 0;
	rxr->lro_enabled = FALSE;
	rxr->split = 0;
	rxr->bytes = 0;
	rxr->discard = FALSE;
	wr32(vsi->hw, rxr->tail, que->num_desc - 1);
	ixl_flush(vsi->hw);
#if defined(INET6) || defined(INET)
	if (ifp->if_capenable & IFCAP_LRO) {
		int err = tcp_lro_init(lro);
		if (err) {
			if_printf(ifp, "queue %d: LRO Initialization failed!\n", que->me);
			goto fail;
		}
		INIT_DBG_IF(ifp, "queue %d: RX Soft LRO Initialized", que->me);
		rxr->lro_enabled = TRUE;
		lro->ifp = vsi->ifp;
	}
#endif
	bus_dmamap_sync(rxr->dma.tag, rxr->dma.map,
	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
fail:
	IXL_RX_UNLOCK(rxr);
	return (error);
}
int ixl_init_rx_ring ( struct ixl_queue * que ) { struct rx_ring * rxr = & que -> rxr ; struct ixl_vsi * vsi = que -> vsi ; #if defined ( INET6 ) || defined ( INET ) struct ifnet * ifp = vsi -> ifp ; struct lro_ctrl * lro = & rxr -> lro ; #endif struct ixl_rx_buf * buf ; bus_dma_segment_t pseg [ 1 ] , hseg [ 1 ] ; int rsize , nsegs , error = 0 ; #ifdef DEV_NETMAP struct netmap_adapter * na = NA ( que -> vsi -> ifp ) ; struct netmap_slot * slot ; #endif IXL_RX_LOCK ( rxr ) ; #ifdef DEV_NETMAP slot = netmap_reset ( na , NR_RX , que -> me , 0 ) ; #endif rsize = roundup2 ( que -> num_desc * sizeof ( union i40e_rx_desc ) , DBA_ALIGN ) ; bzero ( ( void * ) rxr -> base , rsize ) ; for ( int i = 0 ; i < que -> num_desc ; i ++ ) { buf = & rxr -> buffers [ i ] ; if ( buf -> m_head != NULL ) { bus_dmamap_sync ( rxr -> htag , buf -> hmap , BUS_DMASYNC_POSTREAD ) ; bus_dmamap_unload ( rxr -> htag , buf -> hmap ) ; buf -> m_head -> m_flags |= M_PKTHDR ; m_freem ( buf -> m_head ) ; } if ( buf -> m_pack != NULL ) { bus_dmamap_sync ( rxr -> ptag , buf -> pmap , BUS_DMASYNC_POSTREAD ) ; bus_dmamap_unload ( rxr -> ptag , buf -> pmap ) ; buf -> m_pack -> m_flags |= M_PKTHDR ; m_freem ( buf -> m_pack ) ; } buf -> m_head = NULL ; buf -> m_pack = NULL ; } rxr -> hdr_split = FALSE ; for ( int j = 0 ; j != que -> num_desc ; ++ j ) { struct mbuf * mh , * mp ; buf = & rxr -> buffers [ j ] ; #ifdef DEV_NETMAP if ( slot ) { int sj = netmap_idx_n2k ( & na -> rx_rings [ que -> me ] , j ) ; uint64_t paddr ; void * addr ; addr = PNMB ( na , slot + sj , & paddr ) ; netmap_load_map ( na , rxr -> dma . tag , buf -> pmap , addr ) ; rxr -> base [ j ] . read . pkt_addr = htole64 ( paddr ) ; rxr -> base [ j ] . read . hdr_addr = 0 ; continue ; } #endif if ( rxr -> hdr_split == FALSE ) goto skip_head ; buf -> m_head = m_gethdr ( M_NOWAIT , MT_DATA ) ; if ( buf -> m_head == NULL ) { error = ENOBUFS ; goto fail ; } m_adj ( buf -> m_head , ETHER_ALIGN ) ; mh = buf -> m_head ; mh -> m_len = mh -> m_pkthdr . len = MHLEN ; mh -> m_flags |= M_PKTHDR ; error = bus_dmamap_load_mbuf_sg ( rxr -> htag , buf -> hmap , buf -> m_head , hseg , & nsegs , BUS_DMA_NOWAIT ) ; if ( error != 0 ) goto fail ; bus_dmamap_sync ( rxr -> htag , buf -> hmap , BUS_DMASYNC_PREREAD ) ; rxr -> base [ j ] . read . hdr_addr = htole64 ( hseg [ 0 ] . ds_addr ) ; skip_head : buf -> m_pack = m_getjcl ( M_NOWAIT , MT_DATA , M_PKTHDR , rxr -> mbuf_sz ) ; if ( buf -> m_pack == NULL ) { error = ENOBUFS ; goto fail ; } mp = buf -> m_pack ; mp -> m_pkthdr . len = mp -> m_len = rxr -> mbuf_sz ; error = bus_dmamap_load_mbuf_sg ( rxr -> ptag , buf -> pmap , mp , pseg , & nsegs , BUS_DMA_NOWAIT ) ; if ( error != 0 ) goto fail ; bus_dmamap_sync ( rxr -> ptag , buf -> pmap , BUS_DMASYNC_PREREAD ) ; rxr -> base [ j ] . read . pkt_addr = htole64 ( pseg [ 0 ] . ds_addr ) ; rxr -> base [ j ] . read . hdr_addr = 0 ; } rxr -> next_check = 0 ; rxr -> next_refresh = 0 ; rxr -> lro_enabled = FALSE ; rxr -> split = 0 ; rxr -> bytes = 0 ; rxr -> discard = FALSE ; wr32 ( vsi -> hw , rxr -> tail , que -> num_desc - 1 ) ; ixl_flush ( vsi -> hw ) ; #if defined ( INET6 ) || defined ( INET ) if ( ifp -> if_capenable & IFCAP_LRO ) { int err = tcp_lro_init ( lro ) ; if ( err ) { if_printf ( ifp , " \n " , que -> me ) ; goto fail ; } INIT_DBG_IF ( ifp , " " , que -> me ) ; rxr -> lro_enabled = TRUE ; lro -> ifp = vsi -> ifp ; } #endif bus_dmamap_sync ( rxr -> dma . tag , rxr -> dma . map , BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE ) ; fail : IXL_RX_UNLOCK ( rxr ) ; return ( error ) ; }
(Re)Initialize the queue receive ring and its buffers.
( Re ) Initialize the queue receive ring and its buffers .
/* DEV_NETMAP */ /* same as in ixl_init_tx_ring() */ /* DEV_NETMAP */ /* Clear the ring contents */ /* Cleanup any existing buffers */ /* header split is off */ /* Now replenish the mbufs */ /*
		 * In netmap mode, fill the map and set the buffer
		 * address in the NIC ring, considering the offset
		 * between the netmap and NIC rings (see comment in
		 * ixgbe_setup_transmit_ring() ). No need to allocate
		 * an mbuf, so end the block with a continue;
		 */ /* Update descriptor and the cached value */ /* DEV_NETMAP */ /*
		** Don't allocate mbufs if not
		** doing header split, its wasteful
		*/ /* First the header */ /* Get the memory mapping */ /* Nothing elegant to do here */ /* Update descriptor */ /* Now the payload cluster */ /* Get the memory mapping */ /* Update descriptor */ /* Setup our descriptor indices */ /*
	** Now set up the LRO interface:
	*/