/* * igb_free_dma - Free all the DMA resources of all rx/tx rings */ void igb_free_dma(igb_t *igb) { igb_rx_ring_t *rx_ring; igb_rx_data_t *rx_data; igb_tx_ring_t *tx_ring; int i; /* * Free DMA resources of rx rings */ for (i = 0; i < igb->num_rx_rings; i++) { rx_ring = &igb->rx_rings[i]; rx_data = rx_ring->rx_data; igb_free_rbd_ring(rx_data); igb_free_rcb_lists(rx_data); } /* * Free DMA resources of tx rings */ for (i = 0; i < igb->num_tx_rings; i++) { tx_ring = &igb->tx_rings[i]; igb_free_tbd_ring(tx_ring); igb_free_tcb_lists(tx_ring); } }
/* * igb_alloc_rcb_lists - Memory allocation for the receive control blocks * of one ring. */ static int igb_alloc_rcb_lists(igb_rx_data_t *rx_data) { int i; int ret; rx_control_block_t *rcb; igb_t *igb = rx_data->rx_ring->igb; dma_buffer_t *rx_buf; uint32_t rcb_count; /* * Allocate memory for the rx control blocks for work list and * free list. */ rcb_count = rx_data->ring_size + rx_data->free_list_size; rcb = rx_data->rcb_area; for (i = 0; i < rcb_count; i++, rcb++) { ASSERT(rcb != NULL); if (i < rx_data->ring_size) { /* Attach the rx control block to the work list */ rx_data->work_list[i] = rcb; } else { /* Attach the rx control block to the free list */ rx_data->free_list[i - rx_data->ring_size] = rcb; } rx_buf = &rcb->rx_buf; ret = igb_alloc_dma_buffer(igb, rx_buf, igb->rx_buf_size); if (ret != IGB_SUCCESS) { igb_log(igb, IGB_LOG_ERROR, "Allocate rx dma buffer failed"); goto alloc_rcb_lists_fail; } rx_buf->size -= IPHDR_ALIGN_ROOM; rx_buf->address += IPHDR_ALIGN_ROOM; rx_buf->dma_address += IPHDR_ALIGN_ROOM; rcb->ref_cnt = 1; rcb->rx_data = (igb_rx_data_t *)rx_data; rcb->free_rtn.free_func = igb_rx_recycle; rcb->free_rtn.free_arg = (char *)rcb; rcb->mp = desballoc((unsigned char *) rx_buf->address, rx_buf->size, 0, &rcb->free_rtn); } return (IGB_SUCCESS); alloc_rcb_lists_fail: igb_free_rcb_lists(rx_data); return (IGB_FAILURE); }