FreeBSD/sys/dev/e1000/if_igb.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
igb_allocate_queues(struct adapter *adapter)
{
	device_t dev = adapter->dev;
	struct igb_queue	*que = NULL;
	struct tx_ring		*txr = NULL;
	struct rx_ring		*rxr = NULL;
	int rsize, tsize, error = E1000_SUCCESS;
	int txconf = 0, rxconf = 0;
	if (!(adapter->queues =
	    (struct igb_queue *) malloc(sizeof(struct igb_queue) *
	    adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) {
		device_printf(dev, "Unable to allocate queue memory\n");
		error = ENOMEM;
		goto fail;
	}
	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 tx_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(union e1000_adv_tx_desc), IGB_DBA_ALIGN);
	for (int i = 0; i < adapter->num_queues; i++, txconf++) {
		txr = &adapter->tx_rings[i];
		txr->adapter = adapter;
		txr->me = i;
		txr->num_desc = adapter->num_tx_desc;
		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 (igb_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 = (union e1000_adv_tx_desc *)txr->txdma.dma_vaddr;
		bzero((void *)txr->tx_base, tsize);
        	if (igb_allocate_transmit_buffers(txr)) {
			device_printf(dev,
			    "Critical Failure setting up transmit buffers\n");
			error = ENOMEM;
			goto err_tx_desc;
        	}
#ifndef IGB_LEGACY_TX
		txr->br = buf_ring_alloc(igb_buf_ring_size, M_DEVBUF,
		    M_WAITOK, &txr->tx_mtx);
#endif
	}
	rsize = roundup2(adapter->num_rx_desc *
	    sizeof(union e1000_adv_rx_desc), IGB_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 (igb_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_adv_rx_desc *)rxr->rxdma.dma_vaddr;
		bzero((void *)rxr->rx_base, rsize);
		if (igb_allocate_receive_buffers(rxr)) {
			device_printf(dev,
			    "Critical Failure setting up receive buffers\n");
			error = ENOMEM;
			goto err_rx_desc;
		}
	}
	for (int i = 0; i < adapter->num_queues; i++) {
		que = &adapter->queues[i];
		que->adapter = adapter;
		que->txr = &adapter->tx_rings[i];
		que->rxr = &adapter->rx_rings[i];
	}
	return (0);
err_rx_desc:
	for (rxr = adapter->rx_rings; rxconf > 0; rxr++, rxconf--)
		igb_dma_free(adapter, &rxr->rxdma);
err_tx_desc:
	for (txr = adapter->tx_rings; txconf > 0; txr++, txconf--)
		igb_dma_free(adapter, &txr->txdma);
	free(adapter->rx_rings, M_DEVBUF);
rx_fail:
#ifndef IGB_LEGACY_TX
	buf_ring_free(txr->br, M_DEVBUF);
#endif
	free(adapter->tx_rings, M_DEVBUF);
tx_fail:
	free(adapter->queues, M_DEVBUF);
fail:
	return (error);
}
static int igb_allocate_queues ( struct adapter * adapter ) { device_t dev = adapter -> dev ; struct igb_queue * que = NULL ; struct tx_ring * txr = NULL ; struct rx_ring * rxr = NULL ; int rsize , tsize , error = E1000_SUCCESS ; int txconf = 0 , rxconf = 0 ; if ( ! ( adapter -> queues = ( struct igb_queue * ) malloc ( sizeof ( struct igb_queue ) * adapter -> num_queues , M_DEVBUF , M_NOWAIT | M_ZERO ) ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto fail ; } 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 tx_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 ( union e1000_adv_tx_desc ) , IGB_DBA_ALIGN ) ; for ( int i = 0 ; i < adapter -> num_queues ; i ++ , txconf ++ ) { txr = & adapter -> tx_rings [ i ] ; txr -> adapter = adapter ; txr -> me = i ; txr -> num_desc = adapter -> num_tx_desc ; 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 ( igb_dma_malloc ( adapter , tsize , & txr -> txdma , BUS_DMA_NOWAIT ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto err_tx_desc ; } txr -> tx_base = ( union e1000_adv_tx_desc * ) txr -> txdma . dma_vaddr ; bzero ( ( void * ) txr -> tx_base , tsize ) ; if ( igb_allocate_transmit_buffers ( txr ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto err_tx_desc ; } #ifndef IGB_LEGACY_TX txr -> br = buf_ring_alloc ( igb_buf_ring_size , M_DEVBUF , M_WAITOK , & txr -> tx_mtx ) ; #endif } rsize = roundup2 ( adapter -> num_rx_desc * sizeof ( union e1000_adv_rx_desc ) , IGB_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 ( igb_dma_malloc ( adapter , rsize , & rxr -> rxdma , BUS_DMA_NOWAIT ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto err_rx_desc ; } rxr -> rx_base = ( union e1000_adv_rx_desc * ) rxr -> rxdma . dma_vaddr ; bzero ( ( void * ) rxr -> rx_base , rsize ) ; if ( igb_allocate_receive_buffers ( rxr ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto err_rx_desc ; } } for ( int i = 0 ; i < adapter -> num_queues ; i ++ ) { que = & adapter -> queues [ i ] ; que -> adapter = adapter ; que -> txr = & adapter -> tx_rings [ i ] ; que -> rxr = & adapter -> rx_rings [ i ] ; } return ( 0 ) ; err_rx_desc : for ( rxr = adapter -> rx_rings ; rxconf > 0 ; rxr ++ , rxconf -- ) igb_dma_free ( adapter , & rxr -> rxdma ) ; err_tx_desc : for ( txr = adapter -> tx_rings ; txconf > 0 ; txr ++ , txconf -- ) igb_dma_free ( adapter , & txr -> txdma ) ; free ( adapter -> rx_rings , M_DEVBUF ) ; rx_fail : #ifndef IGB_LEGACY_TX buf_ring_free ( txr -> br , M_DEVBUF ) ; #endif free ( adapter -> tx_rings , M_DEVBUF ) ; tx_fail : free ( adapter -> queues , 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 .
/* First allocate the top level queue structs */ /* Next 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 */ /* Now allocate transmit buffers for the ring */ /* Allocate a buf ring */ /*
	 * Next the RX queues...
	 */ /* Initialize the RX lock */ /* Allocate receive buffers for the ring*/ /*
	** Finally set up the queue holding structs
	*/