xref: /onnv-gate/usr/src/uts/common/io/igb/igb_buf.c (revision 8571:60e408ef19cc)
15779Sxy150489 /*
25779Sxy150489  * CDDL HEADER START
35779Sxy150489  *
4*8571SChenlu.Chen@Sun.COM  * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
55779Sxy150489  * The contents of this file are subject to the terms of the
65779Sxy150489  * Common Development and Distribution License (the "License").
75779Sxy150489  * You may not use this file except in compliance with the License.
85779Sxy150489  *
95779Sxy150489  * You can obtain a copy of the license at:
105779Sxy150489  *	http://www.opensolaris.org/os/licensing.
115779Sxy150489  * See the License for the specific language governing permissions
125779Sxy150489  * and limitations under the License.
135779Sxy150489  *
145779Sxy150489  * When using or redistributing this file, you may do so under the
155779Sxy150489  * License only. No other modification of this header is permitted.
165779Sxy150489  *
175779Sxy150489  * If applicable, add the following below this CDDL HEADER, with the
185779Sxy150489  * fields enclosed by brackets "[]" replaced with your own identifying
195779Sxy150489  * information: Portions Copyright [yyyy] [name of copyright owner]
205779Sxy150489  *
215779Sxy150489  * CDDL HEADER END
225779Sxy150489  */
235779Sxy150489 
245779Sxy150489 /*
25*8571SChenlu.Chen@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
265779Sxy150489  * Use is subject to license terms of the CDDL.
275779Sxy150489  */
285779Sxy150489 
295779Sxy150489 #include "igb_sw.h"
305779Sxy150489 
315779Sxy150489 static int igb_alloc_tbd_ring(igb_tx_ring_t *);
325779Sxy150489 static void igb_free_tbd_ring(igb_tx_ring_t *);
335779Sxy150489 static int igb_alloc_rbd_ring(igb_rx_ring_t *);
345779Sxy150489 static void igb_free_rbd_ring(igb_rx_ring_t *);
355779Sxy150489 static int igb_alloc_dma_buffer(igb_t *, dma_buffer_t *, size_t);
365779Sxy150489 static void igb_free_dma_buffer(dma_buffer_t *);
375779Sxy150489 static int igb_alloc_tcb_lists(igb_tx_ring_t *);
385779Sxy150489 static void igb_free_tcb_lists(igb_tx_ring_t *);
395779Sxy150489 static int igb_alloc_rcb_lists(igb_rx_ring_t *);
405779Sxy150489 static void igb_free_rcb_lists(igb_rx_ring_t *);
415779Sxy150489 
425779Sxy150489 #ifdef __sparc
435779Sxy150489 #define	IGB_DMA_ALIGNMENT	0x0000000000002000ull
445779Sxy150489 #else
455779Sxy150489 #define	IGB_DMA_ALIGNMENT	0x0000000000001000ull
465779Sxy150489 #endif
475779Sxy150489 
485779Sxy150489 /*
495779Sxy150489  * DMA attributes for tx/rx descriptors
505779Sxy150489  */
515779Sxy150489 static ddi_dma_attr_t igb_desc_dma_attr = {
525779Sxy150489 	DMA_ATTR_V0,			/* version number */
535779Sxy150489 	0x0000000000000000ull,		/* low address */
545779Sxy150489 	0xFFFFFFFFFFFFFFFFull,		/* high address */
555779Sxy150489 	0x00000000FFFFFFFFull,		/* dma counter max */
565779Sxy150489 	IGB_DMA_ALIGNMENT,		/* alignment */
575779Sxy150489 	0x00000FFF,			/* burst sizes */
585779Sxy150489 	0x00000001,			/* minimum transfer size */
595779Sxy150489 	0x00000000FFFFFFFFull,		/* maximum transfer size */
605779Sxy150489 	0xFFFFFFFFFFFFFFFFull,		/* maximum segment size */
615779Sxy150489 	1,				/* scatter/gather list length */
625779Sxy150489 	0x00000001,			/* granularity */
636624Sgl147354 	DDI_DMA_FLAGERR,		/* DMA flags */
645779Sxy150489 };
655779Sxy150489 
665779Sxy150489 /*
675779Sxy150489  * DMA attributes for tx/rx buffers
685779Sxy150489  */
695779Sxy150489 static ddi_dma_attr_t igb_buf_dma_attr = {
705779Sxy150489 	DMA_ATTR_V0,			/* version number */
715779Sxy150489 	0x0000000000000000ull,		/* low address */
725779Sxy150489 	0xFFFFFFFFFFFFFFFFull,		/* high address */
735779Sxy150489 	0x00000000FFFFFFFFull,		/* dma counter max */
745779Sxy150489 	IGB_DMA_ALIGNMENT,		/* alignment */
755779Sxy150489 	0x00000FFF,			/* burst sizes */
765779Sxy150489 	0x00000001,			/* minimum transfer size */
775779Sxy150489 	0x00000000FFFFFFFFull,		/* maximum transfer size */
785779Sxy150489 	0xFFFFFFFFFFFFFFFFull,		/* maximum segment size	 */
795779Sxy150489 	1,				/* scatter/gather list length */
805779Sxy150489 	0x00000001,			/* granularity */
816624Sgl147354 	DDI_DMA_FLAGERR,		/* DMA flags */
825779Sxy150489 };
835779Sxy150489 
845779Sxy150489 /*
855779Sxy150489  * DMA attributes for transmit
865779Sxy150489  */
875779Sxy150489 static ddi_dma_attr_t igb_tx_dma_attr = {
885779Sxy150489 	DMA_ATTR_V0,			/* version number */
895779Sxy150489 	0x0000000000000000ull,		/* low address */
905779Sxy150489 	0xFFFFFFFFFFFFFFFFull,		/* high address */
915779Sxy150489 	0x00000000FFFFFFFFull,		/* dma counter max */
925779Sxy150489 	1,				/* alignment */
935779Sxy150489 	0x00000FFF,			/* burst sizes */
945779Sxy150489 	0x00000001,			/* minimum transfer size */
955779Sxy150489 	0x00000000FFFFFFFFull,		/* maximum transfer size */
965779Sxy150489 	0xFFFFFFFFFFFFFFFFull,		/* maximum segment size	 */
975779Sxy150489 	MAX_COOKIE,			/* scatter/gather list length */
985779Sxy150489 	0x00000001,			/* granularity */
996624Sgl147354 	DDI_DMA_FLAGERR,		/* DMA flags */
1005779Sxy150489 };
1015779Sxy150489 
1025779Sxy150489 /*
1035779Sxy150489  * DMA access attributes for descriptors.
1045779Sxy150489  */
1055779Sxy150489 static ddi_device_acc_attr_t igb_desc_acc_attr = {
1065779Sxy150489 	DDI_DEVICE_ATTR_V0,
1075779Sxy150489 	DDI_STRUCTURE_LE_ACC,
1086624Sgl147354 	DDI_STRICTORDER_ACC,
1096624Sgl147354 	DDI_FLAGERR_ACC
1105779Sxy150489 };
1115779Sxy150489 
1125779Sxy150489 /*
1135779Sxy150489  * DMA access attributes for buffers.
1145779Sxy150489  */
1155779Sxy150489 static ddi_device_acc_attr_t igb_buf_acc_attr = {
1165779Sxy150489 	DDI_DEVICE_ATTR_V0,
1175779Sxy150489 	DDI_NEVERSWAP_ACC,
1185779Sxy150489 	DDI_STRICTORDER_ACC
1195779Sxy150489 };
1205779Sxy150489 
1215779Sxy150489 
1225779Sxy150489 /*
1235779Sxy150489  * igb_alloc_dma - Allocate DMA resources for all rx/tx rings
1245779Sxy150489  */
1255779Sxy150489 int
1265779Sxy150489 igb_alloc_dma(igb_t *igb)
1275779Sxy150489 {
1285779Sxy150489 	igb_rx_ring_t *rx_ring;
1295779Sxy150489 	igb_tx_ring_t *tx_ring;
1305779Sxy150489 	int i;
1315779Sxy150489 
1325779Sxy150489 	for (i = 0; i < igb->num_rx_rings; i++) {
1335779Sxy150489 		/*
1345779Sxy150489 		 * Allocate receive desciptor ring and control block lists
1355779Sxy150489 		 */
1365779Sxy150489 		rx_ring = &igb->rx_rings[i];
1375779Sxy150489 
1385779Sxy150489 		if (igb_alloc_rbd_ring(rx_ring) != IGB_SUCCESS)
1395779Sxy150489 			goto alloc_dma_failure;
1405779Sxy150489 
1415779Sxy150489 		if (igb_alloc_rcb_lists(rx_ring) != IGB_SUCCESS)
1425779Sxy150489 			goto alloc_dma_failure;
1435779Sxy150489 	}
1445779Sxy150489 
1455779Sxy150489 	for (i = 0; i < igb->num_tx_rings; i++) {
1465779Sxy150489 		/*
1475779Sxy150489 		 * Allocate transmit desciptor ring and control block lists
1485779Sxy150489 		 */
1495779Sxy150489 		tx_ring = &igb->tx_rings[i];
1505779Sxy150489 
1515779Sxy150489 		if (igb_alloc_tbd_ring(tx_ring) != IGB_SUCCESS)
1525779Sxy150489 			goto alloc_dma_failure;
1535779Sxy150489 
1545779Sxy150489 		if (igb_alloc_tcb_lists(tx_ring) != IGB_SUCCESS)
1555779Sxy150489 			goto alloc_dma_failure;
1565779Sxy150489 	}
1575779Sxy150489 
1585779Sxy150489 	return (IGB_SUCCESS);
1595779Sxy150489 
1605779Sxy150489 alloc_dma_failure:
1615779Sxy150489 	igb_free_dma(igb);
1625779Sxy150489 
1635779Sxy150489 	return (IGB_FAILURE);
1645779Sxy150489 }
1655779Sxy150489 
1665779Sxy150489 
1675779Sxy150489 /*
1685779Sxy150489  * igb_free_dma - Free all the DMA resources of all rx/tx rings
1695779Sxy150489  */
1705779Sxy150489 void
1715779Sxy150489 igb_free_dma(igb_t *igb)
1725779Sxy150489 {
1735779Sxy150489 	igb_rx_ring_t *rx_ring;
1745779Sxy150489 	igb_tx_ring_t *tx_ring;
1755779Sxy150489 	int i;
1765779Sxy150489 
1775779Sxy150489 	/*
1785779Sxy150489 	 * Free DMA resources of rx rings
1795779Sxy150489 	 */
1805779Sxy150489 	for (i = 0; i < igb->num_rx_rings; i++) {
1815779Sxy150489 		rx_ring = &igb->rx_rings[i];
1825779Sxy150489 		igb_free_rbd_ring(rx_ring);
1835779Sxy150489 		igb_free_rcb_lists(rx_ring);
1845779Sxy150489 	}
1855779Sxy150489 
1865779Sxy150489 	/*
1875779Sxy150489 	 * Free DMA resources of tx rings
1885779Sxy150489 	 */
1895779Sxy150489 	for (i = 0; i < igb->num_tx_rings; i++) {
1905779Sxy150489 		tx_ring = &igb->tx_rings[i];
1915779Sxy150489 		igb_free_tbd_ring(tx_ring);
1925779Sxy150489 		igb_free_tcb_lists(tx_ring);
1935779Sxy150489 	}
1945779Sxy150489 }
1955779Sxy150489 
1965779Sxy150489 /*
1975779Sxy150489  * igb_alloc_tbd_ring - Memory allocation for the tx descriptors of one ring.
1985779Sxy150489  */
1995779Sxy150489 static int
2005779Sxy150489 igb_alloc_tbd_ring(igb_tx_ring_t *tx_ring)
2015779Sxy150489 {
2025779Sxy150489 	int ret;
2035779Sxy150489 	size_t size;
2045779Sxy150489 	size_t len;
2055779Sxy150489 	uint_t cookie_num;
2065779Sxy150489 	dev_info_t *devinfo;
2075779Sxy150489 	ddi_dma_cookie_t cookie;
2085779Sxy150489 	igb_t *igb = tx_ring->igb;
2095779Sxy150489 
2105779Sxy150489 	devinfo = igb->dip;
2115779Sxy150489 	size = sizeof (union e1000_adv_tx_desc) * tx_ring->ring_size;
2125779Sxy150489 
2135779Sxy150489 	/*
2145779Sxy150489 	 * If tx head write-back is enabled, an extra tbd is allocated
2155779Sxy150489 	 * to save the head write-back value
2165779Sxy150489 	 */
2175779Sxy150489 	if (igb->tx_head_wb_enable) {
2185779Sxy150489 		size += sizeof (union e1000_adv_tx_desc);
2195779Sxy150489 	}
2205779Sxy150489 
2215779Sxy150489 	/*
2225779Sxy150489 	 * Allocate a DMA handle for the transmit descriptor
2235779Sxy150489 	 * memory area.
2245779Sxy150489 	 */
2255779Sxy150489 	ret = ddi_dma_alloc_handle(devinfo, &igb_desc_dma_attr,
2265779Sxy150489 	    DDI_DMA_DONTWAIT, NULL,
2275779Sxy150489 	    &tx_ring->tbd_area.dma_handle);
2285779Sxy150489 
2295779Sxy150489 	if (ret != DDI_SUCCESS) {
2305779Sxy150489 		igb_error(igb,
2315779Sxy150489 		    "Could not allocate tbd dma handle: %x", ret);
2325779Sxy150489 		tx_ring->tbd_area.dma_handle = NULL;
2335779Sxy150489 
2345779Sxy150489 		return (IGB_FAILURE);
2355779Sxy150489 	}
2365779Sxy150489 
2375779Sxy150489 	/*
2385779Sxy150489 	 * Allocate memory to DMA data to and from the transmit
2395779Sxy150489 	 * descriptors.
2405779Sxy150489 	 */
2415779Sxy150489 	ret = ddi_dma_mem_alloc(tx_ring->tbd_area.dma_handle,
2425779Sxy150489 	    size, &igb_desc_acc_attr, DDI_DMA_CONSISTENT,
2435779Sxy150489 	    DDI_DMA_DONTWAIT, NULL,
2445779Sxy150489 	    (caddr_t *)&tx_ring->tbd_area.address,
2455779Sxy150489 	    &len, &tx_ring->tbd_area.acc_handle);
2465779Sxy150489 
2475779Sxy150489 	if (ret != DDI_SUCCESS) {
2485779Sxy150489 		igb_error(igb,
2495779Sxy150489 		    "Could not allocate tbd dma memory: %x", ret);
2505779Sxy150489 		tx_ring->tbd_area.acc_handle = NULL;
2515779Sxy150489 		tx_ring->tbd_area.address = NULL;
2525779Sxy150489 		if (tx_ring->tbd_area.dma_handle != NULL) {
2535779Sxy150489 			ddi_dma_free_handle(&tx_ring->tbd_area.dma_handle);
2545779Sxy150489 			tx_ring->tbd_area.dma_handle = NULL;
2555779Sxy150489 		}
2565779Sxy150489 		return (IGB_FAILURE);
2575779Sxy150489 	}
2585779Sxy150489 
2595779Sxy150489 	/*
2605779Sxy150489 	 * Initialize the entire transmit buffer descriptor area to zero
2615779Sxy150489 	 */
2625779Sxy150489 	bzero(tx_ring->tbd_area.address, len);
2635779Sxy150489 
2645779Sxy150489 	/*
2655779Sxy150489 	 * Allocates DMA resources for the memory that was allocated by
2665779Sxy150489 	 * the ddi_dma_mem_alloc call. The DMA resources then get bound to the
2675779Sxy150489 	 * the memory address
2685779Sxy150489 	 */
2695779Sxy150489 	ret = ddi_dma_addr_bind_handle(tx_ring->tbd_area.dma_handle,
2705779Sxy150489 	    NULL, (caddr_t)tx_ring->tbd_area.address,
2715779Sxy150489 	    len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2725779Sxy150489 	    DDI_DMA_DONTWAIT, NULL, &cookie, &cookie_num);
2735779Sxy150489 
2745779Sxy150489 	if (ret != DDI_DMA_MAPPED) {
2755779Sxy150489 		igb_error(igb,
2765779Sxy150489 		    "Could not bind tbd dma resource: %x", ret);
2775779Sxy150489 		tx_ring->tbd_area.dma_address = NULL;
2785779Sxy150489 		if (tx_ring->tbd_area.acc_handle != NULL) {
2795779Sxy150489 			ddi_dma_mem_free(&tx_ring->tbd_area.acc_handle);
2805779Sxy150489 			tx_ring->tbd_area.acc_handle = NULL;
2815779Sxy150489 			tx_ring->tbd_area.address = NULL;
2825779Sxy150489 		}
2835779Sxy150489 		if (tx_ring->tbd_area.dma_handle != NULL) {
2845779Sxy150489 			ddi_dma_free_handle(&tx_ring->tbd_area.dma_handle);
2855779Sxy150489 			tx_ring->tbd_area.dma_handle = NULL;
2865779Sxy150489 		}
2875779Sxy150489 		return (IGB_FAILURE);
2885779Sxy150489 	}
2895779Sxy150489 
2905779Sxy150489 	ASSERT(cookie_num == 1);
2915779Sxy150489 
2925779Sxy150489 	tx_ring->tbd_area.dma_address = cookie.dmac_laddress;
2935779Sxy150489 	tx_ring->tbd_area.size = len;
2945779Sxy150489 
2955779Sxy150489 	tx_ring->tbd_ring = (union e1000_adv_tx_desc *)(uintptr_t)
2965779Sxy150489 	    tx_ring->tbd_area.address;
2975779Sxy150489 
2985779Sxy150489 	return (IGB_SUCCESS);
2995779Sxy150489 }
3005779Sxy150489 
3015779Sxy150489 /*
3025779Sxy150489  * igb_free_tbd_ring - Free the tx descriptors of one ring.
3035779Sxy150489  */
3045779Sxy150489 static void
3055779Sxy150489 igb_free_tbd_ring(igb_tx_ring_t *tx_ring)
3065779Sxy150489 {
3075779Sxy150489 	if (tx_ring->tbd_area.dma_handle != NULL) {
3085779Sxy150489 		(void) ddi_dma_unbind_handle(tx_ring->tbd_area.dma_handle);
3095779Sxy150489 	}
3105779Sxy150489 	if (tx_ring->tbd_area.acc_handle != NULL) {
3115779Sxy150489 		ddi_dma_mem_free(&tx_ring->tbd_area.acc_handle);
3125779Sxy150489 		tx_ring->tbd_area.acc_handle = NULL;
3135779Sxy150489 	}
3145779Sxy150489 	if (tx_ring->tbd_area.dma_handle != NULL) {
3155779Sxy150489 		ddi_dma_free_handle(&tx_ring->tbd_area.dma_handle);
3165779Sxy150489 		tx_ring->tbd_area.dma_handle = NULL;
3175779Sxy150489 	}
3185779Sxy150489 	tx_ring->tbd_area.address = NULL;
3195779Sxy150489 	tx_ring->tbd_area.dma_address = NULL;
3205779Sxy150489 	tx_ring->tbd_area.size = 0;
3215779Sxy150489 
3225779Sxy150489 	tx_ring->tbd_ring = NULL;
3235779Sxy150489 }
3245779Sxy150489 
3255779Sxy150489 /*
3265779Sxy150489  * igb_alloc_rbd_ring - Memory allocation for the rx descriptors of one ring.
3275779Sxy150489  */
3285779Sxy150489 static int
3295779Sxy150489 igb_alloc_rbd_ring(igb_rx_ring_t *rx_ring)
3305779Sxy150489 {
3315779Sxy150489 	int ret;
3325779Sxy150489 	size_t size;
3335779Sxy150489 	size_t len;
3345779Sxy150489 	uint_t cookie_num;
3355779Sxy150489 	dev_info_t *devinfo;
3365779Sxy150489 	ddi_dma_cookie_t cookie;
3375779Sxy150489 	igb_t *igb = rx_ring->igb;
3385779Sxy150489 
3395779Sxy150489 	devinfo = igb->dip;
3405779Sxy150489 	size = sizeof (union e1000_adv_rx_desc) * rx_ring->ring_size;
3415779Sxy150489 
3425779Sxy150489 	/*
3435779Sxy150489 	 * Allocate a new DMA handle for the receive descriptor
3445779Sxy150489 	 * memory area.
3455779Sxy150489 	 */
3465779Sxy150489 	ret = ddi_dma_alloc_handle(devinfo, &igb_desc_dma_attr,
3475779Sxy150489 	    DDI_DMA_DONTWAIT, NULL,
3485779Sxy150489 	    &rx_ring->rbd_area.dma_handle);
3495779Sxy150489 
3505779Sxy150489 	if (ret != DDI_SUCCESS) {
3515779Sxy150489 		igb_error(igb,
3525779Sxy150489 		    "Could not allocate rbd dma handle: %x", ret);
3535779Sxy150489 		rx_ring->rbd_area.dma_handle = NULL;
3545779Sxy150489 		return (IGB_FAILURE);
3555779Sxy150489 	}
3565779Sxy150489 
3575779Sxy150489 	/*
3585779Sxy150489 	 * Allocate memory to DMA data to and from the receive
3595779Sxy150489 	 * descriptors.
3605779Sxy150489 	 */
3615779Sxy150489 	ret = ddi_dma_mem_alloc(rx_ring->rbd_area.dma_handle,
3625779Sxy150489 	    size, &igb_desc_acc_attr, DDI_DMA_CONSISTENT,
3635779Sxy150489 	    DDI_DMA_DONTWAIT, NULL,
3645779Sxy150489 	    (caddr_t *)&rx_ring->rbd_area.address,
3655779Sxy150489 	    &len, &rx_ring->rbd_area.acc_handle);
3665779Sxy150489 
3675779Sxy150489 	if (ret != DDI_SUCCESS) {
3685779Sxy150489 		igb_error(igb,
3695779Sxy150489 		    "Could not allocate rbd dma memory: %x", ret);
3705779Sxy150489 		rx_ring->rbd_area.acc_handle = NULL;
3715779Sxy150489 		rx_ring->rbd_area.address = NULL;
3725779Sxy150489 		if (rx_ring->rbd_area.dma_handle != NULL) {
3735779Sxy150489 			ddi_dma_free_handle(&rx_ring->rbd_area.dma_handle);
3745779Sxy150489 			rx_ring->rbd_area.dma_handle = NULL;
3755779Sxy150489 		}
3765779Sxy150489 		return (IGB_FAILURE);
3775779Sxy150489 	}
3785779Sxy150489 
3795779Sxy150489 	/*
3805779Sxy150489 	 * Initialize the entire transmit buffer descriptor area to zero
3815779Sxy150489 	 */
3825779Sxy150489 	bzero(rx_ring->rbd_area.address, len);
3835779Sxy150489 
3845779Sxy150489 	/*
3855779Sxy150489 	 * Allocates DMA resources for the memory that was allocated by
3865779Sxy150489 	 * the ddi_dma_mem_alloc call.
3875779Sxy150489 	 */
3885779Sxy150489 	ret = ddi_dma_addr_bind_handle(rx_ring->rbd_area.dma_handle,
3895779Sxy150489 	    NULL, (caddr_t)rx_ring->rbd_area.address,
3905779Sxy150489 	    len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
3915779Sxy150489 	    DDI_DMA_DONTWAIT, NULL, &cookie, &cookie_num);
3925779Sxy150489 
3935779Sxy150489 	if (ret != DDI_DMA_MAPPED) {
3945779Sxy150489 		igb_error(igb,
3955779Sxy150489 		    "Could not bind rbd dma resource: %x", ret);
3965779Sxy150489 		rx_ring->rbd_area.dma_address = NULL;
3975779Sxy150489 		if (rx_ring->rbd_area.acc_handle != NULL) {
3985779Sxy150489 			ddi_dma_mem_free(&rx_ring->rbd_area.acc_handle);
3995779Sxy150489 			rx_ring->rbd_area.acc_handle = NULL;
4005779Sxy150489 			rx_ring->rbd_area.address = NULL;
4015779Sxy150489 		}
4025779Sxy150489 		if (rx_ring->rbd_area.dma_handle != NULL) {
4035779Sxy150489 			ddi_dma_free_handle(&rx_ring->rbd_area.dma_handle);
4045779Sxy150489 			rx_ring->rbd_area.dma_handle = NULL;
4055779Sxy150489 		}
4065779Sxy150489 		return (IGB_FAILURE);
4075779Sxy150489 	}
4085779Sxy150489 
4095779Sxy150489 	ASSERT(cookie_num == 1);
4105779Sxy150489 
4115779Sxy150489 	rx_ring->rbd_area.dma_address = cookie.dmac_laddress;
4125779Sxy150489 	rx_ring->rbd_area.size = len;
4135779Sxy150489 
4145779Sxy150489 	rx_ring->rbd_ring = (union e1000_adv_rx_desc *)(uintptr_t)
4155779Sxy150489 	    rx_ring->rbd_area.address;
4165779Sxy150489 
4175779Sxy150489 	return (IGB_SUCCESS);
4185779Sxy150489 }
4195779Sxy150489 
4205779Sxy150489 /*
4215779Sxy150489  * igb_free_rbd_ring - Free the rx descriptors of one ring.
4225779Sxy150489  */
4235779Sxy150489 static void
4245779Sxy150489 igb_free_rbd_ring(igb_rx_ring_t *rx_ring)
4255779Sxy150489 {
4265779Sxy150489 	if (rx_ring->rbd_area.dma_handle != NULL) {
4275779Sxy150489 		(void) ddi_dma_unbind_handle(rx_ring->rbd_area.dma_handle);
4285779Sxy150489 	}
4295779Sxy150489 	if (rx_ring->rbd_area.acc_handle != NULL) {
4305779Sxy150489 		ddi_dma_mem_free(&rx_ring->rbd_area.acc_handle);
4315779Sxy150489 		rx_ring->rbd_area.acc_handle = NULL;
4325779Sxy150489 	}
4335779Sxy150489 	if (rx_ring->rbd_area.dma_handle != NULL) {
4345779Sxy150489 		ddi_dma_free_handle(&rx_ring->rbd_area.dma_handle);
4355779Sxy150489 		rx_ring->rbd_area.dma_handle = NULL;
4365779Sxy150489 	}
4375779Sxy150489 	rx_ring->rbd_area.address = NULL;
4385779Sxy150489 	rx_ring->rbd_area.dma_address = NULL;
4395779Sxy150489 	rx_ring->rbd_area.size = 0;
4405779Sxy150489 
4415779Sxy150489 	rx_ring->rbd_ring = NULL;
4425779Sxy150489 }
4435779Sxy150489 
4445779Sxy150489 
4455779Sxy150489 /*
4465779Sxy150489  * igb_alloc_dma_buffer - Allocate DMA resources for a DMA buffer
4475779Sxy150489  */
4485779Sxy150489 static int
4495779Sxy150489 igb_alloc_dma_buffer(igb_t *igb,
4505779Sxy150489     dma_buffer_t *buf, size_t size)
4515779Sxy150489 {
4525779Sxy150489 	int ret;
4535779Sxy150489 	dev_info_t *devinfo = igb->dip;
4545779Sxy150489 	ddi_dma_cookie_t cookie;
4555779Sxy150489 	size_t len;
4565779Sxy150489 	uint_t cookie_num;
4575779Sxy150489 
4585779Sxy150489 	ret = ddi_dma_alloc_handle(devinfo,
4595779Sxy150489 	    &igb_buf_dma_attr, DDI_DMA_DONTWAIT,
4605779Sxy150489 	    NULL, &buf->dma_handle);
4615779Sxy150489 
4625779Sxy150489 	if (ret != DDI_SUCCESS) {
4635779Sxy150489 		buf->dma_handle = NULL;
4645779Sxy150489 		igb_error(igb,
4655779Sxy150489 		    "Could not allocate dma buffer handle: %x", ret);
4665779Sxy150489 		return (IGB_FAILURE);
4675779Sxy150489 	}
4685779Sxy150489 
4695779Sxy150489 	ret = ddi_dma_mem_alloc(buf->dma_handle,
4705779Sxy150489 	    size, &igb_buf_acc_attr, DDI_DMA_STREAMING,
4715779Sxy150489 	    DDI_DMA_DONTWAIT, NULL, &buf->address,
4725779Sxy150489 	    &len, &buf->acc_handle);
4735779Sxy150489 
4745779Sxy150489 	if (ret != DDI_SUCCESS) {
4755779Sxy150489 		buf->acc_handle = NULL;
4765779Sxy150489 		buf->address = NULL;
4775779Sxy150489 		if (buf->dma_handle != NULL) {
4785779Sxy150489 			ddi_dma_free_handle(&buf->dma_handle);
4795779Sxy150489 			buf->dma_handle = NULL;
4805779Sxy150489 		}
4815779Sxy150489 		igb_error(igb,
4825779Sxy150489 		    "Could not allocate dma buffer memory: %x", ret);
4835779Sxy150489 		return (IGB_FAILURE);
4845779Sxy150489 	}
4855779Sxy150489 
4865779Sxy150489 	ret = ddi_dma_addr_bind_handle(buf->dma_handle, NULL,
4875779Sxy150489 	    buf->address,
4885779Sxy150489 	    len, DDI_DMA_RDWR | DDI_DMA_STREAMING,
4895779Sxy150489 	    DDI_DMA_DONTWAIT, NULL, &cookie, &cookie_num);
4905779Sxy150489 
4915779Sxy150489 	if (ret != DDI_DMA_MAPPED) {
4925779Sxy150489 		buf->dma_address = NULL;
4935779Sxy150489 		if (buf->acc_handle != NULL) {
4945779Sxy150489 			ddi_dma_mem_free(&buf->acc_handle);
4955779Sxy150489 			buf->acc_handle = NULL;
4965779Sxy150489 			buf->address = NULL;
4975779Sxy150489 		}
4985779Sxy150489 		if (buf->dma_handle != NULL) {
4995779Sxy150489 			ddi_dma_free_handle(&buf->dma_handle);
5005779Sxy150489 			buf->dma_handle = NULL;
5015779Sxy150489 		}
5025779Sxy150489 		igb_error(igb,
5035779Sxy150489 		    "Could not bind dma buffer handle: %x", ret);
5045779Sxy150489 		return (IGB_FAILURE);
5055779Sxy150489 	}
5065779Sxy150489 
5075779Sxy150489 	ASSERT(cookie_num == 1);
5085779Sxy150489 
5095779Sxy150489 	buf->dma_address = cookie.dmac_laddress;
5105779Sxy150489 	buf->size = len;
5115779Sxy150489 	buf->len = 0;
5125779Sxy150489 
5135779Sxy150489 	return (IGB_SUCCESS);
5145779Sxy150489 }
5155779Sxy150489 
5165779Sxy150489 /*
5175779Sxy150489  * igb_free_dma_buffer - Free one allocated area of dma memory and handle
5185779Sxy150489  */
5195779Sxy150489 static void
5205779Sxy150489 igb_free_dma_buffer(dma_buffer_t *buf)
5215779Sxy150489 {
5225779Sxy150489 	if (buf->dma_handle != NULL) {
5235779Sxy150489 		(void) ddi_dma_unbind_handle(buf->dma_handle);
5245779Sxy150489 		buf->dma_address = NULL;
5255779Sxy150489 	} else {
5265779Sxy150489 		return;
5275779Sxy150489 	}
5285779Sxy150489 
5295779Sxy150489 	if (buf->acc_handle != NULL) {
5305779Sxy150489 		ddi_dma_mem_free(&buf->acc_handle);
5315779Sxy150489 		buf->acc_handle = NULL;
5325779Sxy150489 		buf->address = NULL;
5335779Sxy150489 	}
5345779Sxy150489 
5355779Sxy150489 	if (buf->dma_handle != NULL) {
5365779Sxy150489 		ddi_dma_free_handle(&buf->dma_handle);
5375779Sxy150489 		buf->dma_handle = NULL;
5385779Sxy150489 	}
5395779Sxy150489 
5405779Sxy150489 	buf->size = 0;
5415779Sxy150489 	buf->len = 0;
5425779Sxy150489 }
5435779Sxy150489 
5445779Sxy150489 /*
5455779Sxy150489  * igb_alloc_tcb_lists - Memory allocation for the transmit control bolcks
5465779Sxy150489  * of one ring.
5475779Sxy150489  */
5485779Sxy150489 static int
5495779Sxy150489 igb_alloc_tcb_lists(igb_tx_ring_t *tx_ring)
5505779Sxy150489 {
5515779Sxy150489 	int i;
5525779Sxy150489 	int ret;
5535779Sxy150489 	tx_control_block_t *tcb;
5545779Sxy150489 	dma_buffer_t *tx_buf;
5555779Sxy150489 	igb_t *igb = tx_ring->igb;
5565779Sxy150489 	dev_info_t *devinfo = igb->dip;
5575779Sxy150489 
5585779Sxy150489 	/*
5595779Sxy150489 	 * Allocate memory for the work list.
5605779Sxy150489 	 */
5615779Sxy150489 	tx_ring->work_list = kmem_zalloc(sizeof (tx_control_block_t *) *
5625779Sxy150489 	    tx_ring->ring_size, KM_NOSLEEP);
5635779Sxy150489 
5645779Sxy150489 	if (tx_ring->work_list == NULL) {
5655779Sxy150489 		igb_error(igb,
5665779Sxy150489 		    "Cound not allocate memory for tx work list");
5675779Sxy150489 		return (IGB_FAILURE);
5685779Sxy150489 	}
5695779Sxy150489 
5705779Sxy150489 	/*
5715779Sxy150489 	 * Allocate memory for the free list.
5725779Sxy150489 	 */
5735779Sxy150489 	tx_ring->free_list = kmem_zalloc(sizeof (tx_control_block_t *) *
5745779Sxy150489 	    tx_ring->free_list_size, KM_NOSLEEP);
5755779Sxy150489 
5765779Sxy150489 	if (tx_ring->free_list == NULL) {
5775779Sxy150489 		kmem_free(tx_ring->work_list,
5785779Sxy150489 		    sizeof (tx_control_block_t *) * tx_ring->ring_size);
5795779Sxy150489 		tx_ring->work_list = NULL;
5805779Sxy150489 
5815779Sxy150489 		igb_error(igb,
5825779Sxy150489 		    "Cound not allocate memory for tx free list");
5835779Sxy150489 		return (IGB_FAILURE);
5845779Sxy150489 	}
5855779Sxy150489 
5865779Sxy150489 	/*
5875779Sxy150489 	 * Allocate memory for the tx control blocks of free list.
5885779Sxy150489 	 */
5895779Sxy150489 	tx_ring->tcb_area =
5905779Sxy150489 	    kmem_zalloc(sizeof (tx_control_block_t) *
5915779Sxy150489 	    tx_ring->free_list_size, KM_NOSLEEP);
5925779Sxy150489 
5935779Sxy150489 	if (tx_ring->tcb_area == NULL) {
5945779Sxy150489 		kmem_free(tx_ring->work_list,
5955779Sxy150489 		    sizeof (tx_control_block_t *) * tx_ring->ring_size);
5965779Sxy150489 		tx_ring->work_list = NULL;
5975779Sxy150489 
5985779Sxy150489 		kmem_free(tx_ring->free_list,
5995779Sxy150489 		    sizeof (tx_control_block_t *) * tx_ring->free_list_size);
6005779Sxy150489 		tx_ring->free_list = NULL;
6015779Sxy150489 
6025779Sxy150489 		igb_error(igb,
6035779Sxy150489 		    "Cound not allocate memory for tx control blocks");
6045779Sxy150489 		return (IGB_FAILURE);
6055779Sxy150489 	}
6065779Sxy150489 
6075779Sxy150489 	/*
6085779Sxy150489 	 * Allocate dma memory for the tx control block of free list.
6095779Sxy150489 	 */
6105779Sxy150489 	tcb = tx_ring->tcb_area;
6115779Sxy150489 	for (i = 0; i < tx_ring->free_list_size; i++, tcb++) {
6125779Sxy150489 		ASSERT(tcb != NULL);
6135779Sxy150489 
6145779Sxy150489 		tx_ring->free_list[i] = tcb;
6155779Sxy150489 
6165779Sxy150489 		/*
6175779Sxy150489 		 * Pre-allocate dma handles for transmit. These dma handles
6185779Sxy150489 		 * will be dynamically bound to the data buffers passed down
6195779Sxy150489 		 * from the upper layers at the time of transmitting.
6205779Sxy150489 		 */
6215779Sxy150489 		ret = ddi_dma_alloc_handle(devinfo,
6225779Sxy150489 		    &igb_tx_dma_attr,
6235779Sxy150489 		    DDI_DMA_DONTWAIT, NULL,
6245779Sxy150489 		    &tcb->tx_dma_handle);
6255779Sxy150489 		if (ret != DDI_SUCCESS) {
6265779Sxy150489 			tcb->tx_dma_handle = NULL;
6275779Sxy150489 			igb_error(igb,
6285779Sxy150489 			    "Could not allocate tx dma handle: %x", ret);
6295779Sxy150489 			goto alloc_tcb_lists_fail;
6305779Sxy150489 		}
6315779Sxy150489 
6325779Sxy150489 		/*
6335779Sxy150489 		 * Pre-allocate transmit buffers for packets that the
6345779Sxy150489 		 * size is less than bcopy_thresh.
6355779Sxy150489 		 */
6365779Sxy150489 		tx_buf = &tcb->tx_buf;
6375779Sxy150489 
6385779Sxy150489 		ret = igb_alloc_dma_buffer(igb,
6395779Sxy150489 		    tx_buf, igb->tx_buf_size);
6405779Sxy150489 
6415779Sxy150489 		if (ret != IGB_SUCCESS) {
6425779Sxy150489 			ASSERT(tcb->tx_dma_handle != NULL);
6435779Sxy150489 			ddi_dma_free_handle(&tcb->tx_dma_handle);
6445779Sxy150489 			tcb->tx_dma_handle = NULL;
6455779Sxy150489 			igb_error(igb, "Allocate tx dma buffer failed");
6465779Sxy150489 			goto alloc_tcb_lists_fail;
6475779Sxy150489 		}
6485779Sxy150489 	}
6495779Sxy150489 
6505779Sxy150489 	return (IGB_SUCCESS);
6515779Sxy150489 
6525779Sxy150489 alloc_tcb_lists_fail:
6535779Sxy150489 	igb_free_tcb_lists(tx_ring);
6545779Sxy150489 
6555779Sxy150489 	return (IGB_FAILURE);
6565779Sxy150489 }
6575779Sxy150489 
6585779Sxy150489 /*
6595779Sxy150489  * igb_free_tcb_lists - Release the memory allocated for
6605779Sxy150489  * the transmit control bolcks of one ring.
6615779Sxy150489  */
6625779Sxy150489 static void
6635779Sxy150489 igb_free_tcb_lists(igb_tx_ring_t *tx_ring)
6645779Sxy150489 {
6655779Sxy150489 	int i;
6665779Sxy150489 	tx_control_block_t *tcb;
6675779Sxy150489 
6685779Sxy150489 	tcb = tx_ring->tcb_area;
6695779Sxy150489 	if (tcb == NULL)
6705779Sxy150489 		return;
6715779Sxy150489 
6725779Sxy150489 	for (i = 0; i < tx_ring->free_list_size; i++, tcb++) {
6735779Sxy150489 		ASSERT(tcb != NULL);
6745779Sxy150489 
6755779Sxy150489 		/* Free the tx dma handle for dynamical binding */
6765779Sxy150489 		if (tcb->tx_dma_handle != NULL) {
6775779Sxy150489 			ddi_dma_free_handle(&tcb->tx_dma_handle);
6785779Sxy150489 			tcb->tx_dma_handle = NULL;
6795779Sxy150489 		} else {
6805779Sxy150489 			/*
6815779Sxy150489 			 * If the dma handle is NULL, then we don't
6825779Sxy150489 			 * have to check the remaining.
6835779Sxy150489 			 */
6845779Sxy150489 			break;
6855779Sxy150489 		}
6865779Sxy150489 
6875779Sxy150489 		igb_free_dma_buffer(&tcb->tx_buf);
6885779Sxy150489 	}
6895779Sxy150489 
6905779Sxy150489 	if (tx_ring->tcb_area != NULL) {
6915779Sxy150489 		kmem_free(tx_ring->tcb_area,
6925779Sxy150489 		    sizeof (tx_control_block_t) * tx_ring->free_list_size);
6935779Sxy150489 		tx_ring->tcb_area = NULL;
6945779Sxy150489 	}
6955779Sxy150489 
6965779Sxy150489 	if (tx_ring->work_list != NULL) {
6975779Sxy150489 		kmem_free(tx_ring->work_list,
6985779Sxy150489 		    sizeof (tx_control_block_t *) * tx_ring->ring_size);
6995779Sxy150489 		tx_ring->work_list = NULL;
7005779Sxy150489 	}
7015779Sxy150489 
7025779Sxy150489 	if (tx_ring->free_list != NULL) {
7035779Sxy150489 		kmem_free(tx_ring->free_list,
7045779Sxy150489 		    sizeof (tx_control_block_t *) * tx_ring->free_list_size);
7055779Sxy150489 		tx_ring->free_list = NULL;
7065779Sxy150489 	}
7075779Sxy150489 }
7085779Sxy150489 
7095779Sxy150489 /*
7105779Sxy150489  * igb_alloc_rcb_lists - Memory allocation for the receive control blocks
7115779Sxy150489  * of one ring.
7125779Sxy150489  */
7135779Sxy150489 static int
7145779Sxy150489 igb_alloc_rcb_lists(igb_rx_ring_t *rx_ring)
7155779Sxy150489 {
7165779Sxy150489 	int i;
7175779Sxy150489 	int ret;
7185779Sxy150489 	rx_control_block_t *rcb;
7195779Sxy150489 	igb_t *igb = rx_ring->igb;
7205779Sxy150489 	dma_buffer_t *rx_buf;
7215779Sxy150489 	uint32_t rcb_count;
7225779Sxy150489 
7235779Sxy150489 	/*
7245779Sxy150489 	 * Allocate memory for the work list.
7255779Sxy150489 	 */
7265779Sxy150489 	rx_ring->work_list = kmem_zalloc(sizeof (rx_control_block_t *) *
7275779Sxy150489 	    rx_ring->ring_size, KM_NOSLEEP);
7285779Sxy150489 
7295779Sxy150489 	if (rx_ring->work_list == NULL) {
7305779Sxy150489 		igb_error(igb,
7315779Sxy150489 		    "Could not allocate memory for rx work list");
7325779Sxy150489 		return (IGB_FAILURE);
7335779Sxy150489 	}
7345779Sxy150489 
7355779Sxy150489 	/*
7365779Sxy150489 	 * Allocate memory for the free list.
7375779Sxy150489 	 */
7385779Sxy150489 	rx_ring->free_list = kmem_zalloc(sizeof (rx_control_block_t *) *
7395779Sxy150489 	    rx_ring->free_list_size, KM_NOSLEEP);
7405779Sxy150489 
7415779Sxy150489 	if (rx_ring->free_list == NULL) {
7425779Sxy150489 		kmem_free(rx_ring->work_list,
7435779Sxy150489 		    sizeof (rx_control_block_t *) * rx_ring->ring_size);
7445779Sxy150489 		rx_ring->work_list = NULL;
7455779Sxy150489 
7465779Sxy150489 		igb_error(igb,
7475779Sxy150489 		    "Cound not allocate memory for rx free list");
7485779Sxy150489 		return (IGB_FAILURE);
7495779Sxy150489 	}
7505779Sxy150489 
7515779Sxy150489 	/*
7525779Sxy150489 	 * Allocate memory for the rx control blocks for work list and
7535779Sxy150489 	 * free list.
7545779Sxy150489 	 */
7555779Sxy150489 	rcb_count = rx_ring->ring_size + rx_ring->free_list_size;
7565779Sxy150489 	rx_ring->rcb_area =
7575779Sxy150489 	    kmem_zalloc(sizeof (rx_control_block_t) * rcb_count,
7585779Sxy150489 	    KM_NOSLEEP);
7595779Sxy150489 
7605779Sxy150489 	if (rx_ring->rcb_area == NULL) {
7615779Sxy150489 		kmem_free(rx_ring->work_list,
7625779Sxy150489 		    sizeof (rx_control_block_t *) * rx_ring->ring_size);
7635779Sxy150489 		rx_ring->work_list = NULL;
7645779Sxy150489 
7655779Sxy150489 		kmem_free(rx_ring->free_list,
7665779Sxy150489 		    sizeof (rx_control_block_t *) * rx_ring->free_list_size);
7675779Sxy150489 		rx_ring->free_list = NULL;
7685779Sxy150489 
7695779Sxy150489 		igb_error(igb,
7705779Sxy150489 		    "Cound not allocate memory for rx control blocks");
7715779Sxy150489 		return (IGB_FAILURE);
7725779Sxy150489 	}
7735779Sxy150489 
7745779Sxy150489 	/*
7755779Sxy150489 	 * Allocate dma memory for the rx control blocks
7765779Sxy150489 	 */
7775779Sxy150489 	rcb = rx_ring->rcb_area;
7785779Sxy150489 	for (i = 0; i < rcb_count; i++, rcb++) {
7795779Sxy150489 		ASSERT(rcb != NULL);
7805779Sxy150489 
7815779Sxy150489 		if (i < rx_ring->ring_size) {
7825779Sxy150489 			/* Attach the rx control block to the work list */
7835779Sxy150489 			rx_ring->work_list[i] = rcb;
7845779Sxy150489 		} else {
7855779Sxy150489 			/* Attach the rx control block to the free list */
7865779Sxy150489 			rx_ring->free_list[i - rx_ring->ring_size] = rcb;
7875779Sxy150489 		}
7885779Sxy150489 
7895779Sxy150489 		rx_buf = &rcb->rx_buf;
7905779Sxy150489 		ret = igb_alloc_dma_buffer(igb,
7915779Sxy150489 		    rx_buf, igb->rx_buf_size);
7925779Sxy150489 
7935779Sxy150489 		if (ret != IGB_SUCCESS) {
7945779Sxy150489 			igb_error(igb, "Allocate rx dma buffer failed");
7955779Sxy150489 			goto alloc_rcb_lists_fail;
7965779Sxy150489 		}
7975779Sxy150489 
7985779Sxy150489 		rx_buf->size -= IPHDR_ALIGN_ROOM;
7995779Sxy150489 		rx_buf->address += IPHDR_ALIGN_ROOM;
8005779Sxy150489 		rx_buf->dma_address += IPHDR_ALIGN_ROOM;
8015779Sxy150489 
8025779Sxy150489 		rcb->state = RCB_FREE;
8035779Sxy150489 		rcb->rx_ring = (igb_rx_ring_t *)rx_ring;
8045779Sxy150489 		rcb->free_rtn.free_func = igb_rx_recycle;
8055779Sxy150489 		rcb->free_rtn.free_arg = (char *)rcb;
8065779Sxy150489 
8075779Sxy150489 		rcb->mp = desballoc((unsigned char *)
808*8571SChenlu.Chen@Sun.COM 		    rx_buf->address,
809*8571SChenlu.Chen@Sun.COM 		    rx_buf->size,
8105779Sxy150489 		    0, &rcb->free_rtn);
8115779Sxy150489 	}
8125779Sxy150489 
8135779Sxy150489 	return (IGB_SUCCESS);
8145779Sxy150489 
8155779Sxy150489 alloc_rcb_lists_fail:
8165779Sxy150489 	igb_free_rcb_lists(rx_ring);
8175779Sxy150489 
8185779Sxy150489 	return (IGB_FAILURE);
8195779Sxy150489 }
8205779Sxy150489 
8215779Sxy150489 /*
8225779Sxy150489  * igb_free_rcb_lists - Free the receive control blocks of one ring.
8235779Sxy150489  */
8245779Sxy150489 static void
8255779Sxy150489 igb_free_rcb_lists(igb_rx_ring_t *rx_ring)
8265779Sxy150489 {
8275779Sxy150489 	int i;
8285779Sxy150489 	rx_control_block_t *rcb;
8295779Sxy150489 	uint32_t rcb_count;
8305779Sxy150489 
8315779Sxy150489 	rcb = rx_ring->rcb_area;
8325779Sxy150489 	if (rcb == NULL)
8335779Sxy150489 		return;
8345779Sxy150489 
8355779Sxy150489 	rcb_count = rx_ring->ring_size + rx_ring->free_list_size;
8365779Sxy150489 	for (i = 0; i < rcb_count; i++, rcb++) {
8375779Sxy150489 		ASSERT(rcb != NULL);
8385779Sxy150489 		ASSERT(rcb->state == RCB_FREE);
8395779Sxy150489 
8405779Sxy150489 		if (rcb->mp != NULL) {
8415779Sxy150489 			freemsg(rcb->mp);
8425779Sxy150489 			rcb->mp = NULL;
8435779Sxy150489 		}
8445779Sxy150489 
8455779Sxy150489 		igb_free_dma_buffer(&rcb->rx_buf);
8465779Sxy150489 	}
8475779Sxy150489 
8485779Sxy150489 	if (rx_ring->rcb_area != NULL) {
8495779Sxy150489 		kmem_free(rx_ring->rcb_area,
8505779Sxy150489 		    sizeof (rx_control_block_t) * rcb_count);
8515779Sxy150489 		rx_ring->rcb_area = NULL;
8525779Sxy150489 	}
8535779Sxy150489 
8545779Sxy150489 	if (rx_ring->work_list != NULL) {
8555779Sxy150489 		kmem_free(rx_ring->work_list,
8565779Sxy150489 		    sizeof (rx_control_block_t *) * rx_ring->ring_size);
8575779Sxy150489 		rx_ring->work_list = NULL;
8585779Sxy150489 	}
8595779Sxy150489 
8605779Sxy150489 	if (rx_ring->free_list != NULL) {
8615779Sxy150489 		kmem_free(rx_ring->free_list,
8625779Sxy150489 		    sizeof (rx_control_block_t *) * rx_ring->free_list_size);
8635779Sxy150489 		rx_ring->free_list = NULL;
8645779Sxy150489 	}
8655779Sxy150489 }
8666624Sgl147354 
8676624Sgl147354 void
8686624Sgl147354 igb_set_fma_flags(int acc_flag, int dma_flag)
8696624Sgl147354 {
8706624Sgl147354 	if (acc_flag) {
8716624Sgl147354 		igb_desc_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
8726624Sgl147354 	} else {
8736624Sgl147354 		igb_desc_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
8746624Sgl147354 	}
8756624Sgl147354 
8766624Sgl147354 	if (dma_flag) {
8776624Sgl147354 		igb_tx_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
8786624Sgl147354 		igb_buf_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
8796624Sgl147354 		igb_desc_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
8806624Sgl147354 	} else {
8816624Sgl147354 		igb_tx_dma_attr.dma_attr_flags = 0;
8826624Sgl147354 		igb_buf_dma_attr.dma_attr_flags = 0;
8836624Sgl147354 		igb_desc_dma_attr.dma_attr_flags = 0;
8846624Sgl147354 	}
8856624Sgl147354 }
886