FreeBSD/sys/dev/e1000/if_em.c
/*********************************************************************
 *
 *  Allocate memory for the transmit and receive rings, and then
 *  the descriptors associated with each, called only once at attach.
 *
 **********************************************************************/
Allocate memory for the transmit and receive rings, and then
the descriptors associated with each, called only once at attach.
Allocate memory for the transmit and receive rings and then the descriptors associated with each called only once at attach .
static int
em_allocate_queues(struct adapter *adapter)
{
	device_t		dev = adapter->dev;
	struct tx_ring		*txr = NULL;
	struct rx_ring		*rxr = NULL;
	int rsize, tsize, error = E1000_SUCCESS;
	int txconf = 0, rxconf = 0;
	if (!(adapter->tx_rings =
	    (struct tx_ring *) malloc(sizeof(struct tx_ring) *
	    adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) {
		device_printf(dev, "Unable to allocate TX ring memory\n");
		error = ENOMEM;
		goto fail;
	}
	if (!(adapter->rx_rings =
	    (struct rx_ring *) malloc(sizeof(struct rx_ring) *
	    adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) {
		device_printf(dev, "Unable to allocate RX ring memory\n");
		error = ENOMEM;
		goto rx_fail;
	}
	tsize = roundup2(adapter->num_tx_desc *
	    sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
	for (int i = 0; i < adapter->num_queues; i++, txconf++) {
		txr = &adapter->tx_rings[i];
		txr->adapter = adapter;
		txr->me = i;
		snprintf(txr->mtx_name, sizeof(txr->mtx_name), "%s:tx(%d)",
		    device_get_nameunit(dev), txr->me);
		mtx_init(&txr->tx_mtx, txr->mtx_name, NULL, MTX_DEF);
		if (em_dma_malloc(adapter, tsize,
			&txr->txdma, BUS_DMA_NOWAIT)) {
			device_printf(dev,
			    "Unable to allocate TX Descriptor memory\n");
			error = ENOMEM;
			goto err_tx_desc;
		}
		txr->tx_base = (struct e1000_tx_desc *)txr->txdma.dma_vaddr;
		bzero((void *)txr->tx_base, tsize);
        	if (em_allocate_transmit_buffers(txr)) {
			device_printf(dev,
			    "Critical Failure setting up transmit buffers\n");
			error = ENOMEM;
			goto err_tx_desc;
        	}
#if __FreeBSD_version >= 800000
		txr->br = buf_ring_alloc(4096, M_DEVBUF,
		    M_WAITOK, &txr->tx_mtx);
#endif
	}
	rsize = roundup2(adapter->num_rx_desc *
	    sizeof(union e1000_rx_desc_extended), EM_DBA_ALIGN);
	for (int i = 0; i < adapter->num_queues; i++, rxconf++) {
		rxr = &adapter->rx_rings[i];
		rxr->adapter = adapter;
		rxr->me = i;
		snprintf(rxr->mtx_name, sizeof(rxr->mtx_name), "%s:rx(%d)",
		    device_get_nameunit(dev), txr->me);
		mtx_init(&rxr->rx_mtx, rxr->mtx_name, NULL, MTX_DEF);
		if (em_dma_malloc(adapter, rsize,
			&rxr->rxdma, BUS_DMA_NOWAIT)) {
			device_printf(dev,
			    "Unable to allocate RxDescriptor memory\n");
			error = ENOMEM;
			goto err_rx_desc;
		}
		rxr->rx_base = (union e1000_rx_desc_extended *)rxr->rxdma.dma_vaddr;
		bzero((void *)rxr->rx_base, rsize);
		if (em_allocate_receive_buffers(rxr)) {
			device_printf(dev,
			    "Critical Failure setting up receive buffers\n");
			error = ENOMEM;
			goto err_rx_desc;
		}
	}
	return (0);
err_rx_desc:
	for (rxr = adapter->rx_rings; rxconf > 0; rxr++, rxconf--)
		em_dma_free(adapter, &rxr->rxdma);
err_tx_desc:
	for (txr = adapter->tx_rings; txconf > 0; txr++, txconf--)
		em_dma_free(adapter, &txr->txdma);
	free(adapter->rx_rings, M_DEVBUF);
rx_fail:
#if __FreeBSD_version >= 800000
	buf_ring_free(txr->br, M_DEVBUF);
#endif
	free(adapter->tx_rings, M_DEVBUF);
fail:
	return (error);
}
static int em_allocate_queues ( struct adapter * adapter ) { device_t dev = adapter -> dev ; struct tx_ring * txr = NULL ; struct rx_ring * rxr = NULL ; int rsize , tsize , error = E1000_SUCCESS ; int txconf = 0 , rxconf = 0 ; if ( ! ( adapter -> tx_rings = ( struct tx_ring * ) malloc ( sizeof ( struct tx_ring ) * adapter -> num_queues , M_DEVBUF , M_NOWAIT | M_ZERO ) ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto fail ; } if ( ! ( adapter -> rx_rings = ( struct rx_ring * ) malloc ( sizeof ( struct rx_ring ) * adapter -> num_queues , M_DEVBUF , M_NOWAIT | M_ZERO ) ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto rx_fail ; } tsize = roundup2 ( adapter -> num_tx_desc * sizeof ( struct e1000_tx_desc ) , EM_DBA_ALIGN ) ; for ( int i = 0 ; i < adapter -> num_queues ; i ++ , txconf ++ ) { txr = & adapter -> tx_rings [ i ] ; txr -> adapter = adapter ; txr -> me = i ; snprintf ( txr -> mtx_name , sizeof ( txr -> mtx_name ) , " " , device_get_nameunit ( dev ) , txr -> me ) ; mtx_init ( & txr -> tx_mtx , txr -> mtx_name , NULL , MTX_DEF ) ; if ( em_dma_malloc ( adapter , tsize , & txr -> txdma , BUS_DMA_NOWAIT ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto err_tx_desc ; } txr -> tx_base = ( struct e1000_tx_desc * ) txr -> txdma . dma_vaddr ; bzero ( ( void * ) txr -> tx_base , tsize ) ; if ( em_allocate_transmit_buffers ( txr ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto err_tx_desc ; } #if __FreeBSD_version >= 800000 txr -> br = buf_ring_alloc ( 4096 , M_DEVBUF , M_WAITOK , & txr -> tx_mtx ) ; #endif } rsize = roundup2 ( adapter -> num_rx_desc * sizeof ( union e1000_rx_desc_extended ) , EM_DBA_ALIGN ) ; for ( int i = 0 ; i < adapter -> num_queues ; i ++ , rxconf ++ ) { rxr = & adapter -> rx_rings [ i ] ; rxr -> adapter = adapter ; rxr -> me = i ; snprintf ( rxr -> mtx_name , sizeof ( rxr -> mtx_name ) , " " , device_get_nameunit ( dev ) , txr -> me ) ; mtx_init ( & rxr -> rx_mtx , rxr -> mtx_name , NULL , MTX_DEF ) ; if ( em_dma_malloc ( adapter , rsize , & rxr -> rxdma , BUS_DMA_NOWAIT ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto err_rx_desc ; } rxr -> rx_base = ( union e1000_rx_desc_extended * ) rxr -> rxdma . dma_vaddr ; bzero ( ( void * ) rxr -> rx_base , rsize ) ; if ( em_allocate_receive_buffers ( rxr ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto err_rx_desc ; } } return ( 0 ) ; err_rx_desc : for ( rxr = adapter -> rx_rings ; rxconf > 0 ; rxr ++ , rxconf -- ) em_dma_free ( adapter , & rxr -> rxdma ) ; err_tx_desc : for ( txr = adapter -> tx_rings ; txconf > 0 ; txr ++ , txconf -- ) em_dma_free ( adapter , & txr -> txdma ) ; free ( adapter -> rx_rings , M_DEVBUF ) ; rx_fail : #if __FreeBSD_version >= 800000 buf_ring_free ( txr -> br , M_DEVBUF ) ; #endif free ( adapter -> tx_rings , M_DEVBUF ) ; fail : return ( error ) ; }
Allocate memory for the transmit and receive rings, and then
  the descriptors associated with each, called only once at attach.
Allocate memory for the transmit and receive rings and then the descriptors associated with each called only once at attach .
/* Allocate the TX ring struct memory */ /* Now allocate the RX */ /*
	 * Now set up the TX queues, txconf is needed to handle the
	 * possibility that things fail midcourse and we need to
	 * undo memory gracefully
	 */ /* Set up some basics */ /* Initialize the TX lock */ /* Allocate a buf ring */ /*
	 * Next the RX queues...
	 */ /* Initialize the RX lock */ /* Allocate receive buffers for the ring*/