Home | History | Annotate | Download | only in ixgbe
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
      5  * The contents of this file are subject to the terms of the
      6  * Common Development and Distribution License (the "License").
      7  * You may not use this file except in compliance with the License.
      8  *
      9  * You can obtain a copy of the license at:
     10  *      http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When using or redistributing this file, you may do so under the
     15  * License only. No other modification of this header is permitted.
     16  *
     17  * If applicable, add the following below this CDDL HEADER, with the
     18  * fields enclosed by brackets "[]" replaced with your own identifying
     19  * information: Portions Copyright [yyyy] [name of copyright owner]
     20  *
     21  * CDDL HEADER END
     22  */
     23 
     24 /*
     25  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     26  * Use is subject to license terms.
     27  */
     28 
     29 #include "ixgbe_sw.h"
     30 
     31 static int ixgbe_alloc_tbd_ring(ixgbe_tx_ring_t *);
     32 static void ixgbe_free_tbd_ring(ixgbe_tx_ring_t *);
     33 static int ixgbe_alloc_rbd_ring(ixgbe_rx_data_t *);
     34 static void ixgbe_free_rbd_ring(ixgbe_rx_data_t *);
     35 static int ixgbe_alloc_dma_buffer(ixgbe_t *, dma_buffer_t *, size_t);
     36 static int ixgbe_alloc_tcb_lists(ixgbe_tx_ring_t *);
     37 static void ixgbe_free_tcb_lists(ixgbe_tx_ring_t *);
     38 static int ixgbe_alloc_rcb_lists(ixgbe_rx_data_t *);
     39 static void ixgbe_free_rcb_lists(ixgbe_rx_data_t *);
     40 
     41 #ifdef __sparc
     42 #define	IXGBE_DMA_ALIGNMENT	0x0000000000002000ull
     43 #else
     44 #define	IXGBE_DMA_ALIGNMENT	0x0000000000001000ull
     45 #endif
     46 
     47 /*
     48  * DMA attributes for tx/rx descriptors.
     49  */
     50 static ddi_dma_attr_t ixgbe_desc_dma_attr = {
     51 	DMA_ATTR_V0,			/* version number */
     52 	0x0000000000000000ull,		/* low address */
     53 	0xFFFFFFFFFFFFFFFFull,		/* high address */
     54 	0x00000000FFFFFFFFull,		/* dma counter max */
     55 	IXGBE_DMA_ALIGNMENT,		/* alignment */
     56 	0x00000FFF,			/* burst sizes */
     57 	0x00000001,			/* minimum transfer size */
     58 	0x00000000FFFFFFFFull,		/* maximum transfer size */
     59 	0xFFFFFFFFFFFFFFFFull,		/* maximum segment size */
     60 	1,				/* scatter/gather list length */
     61 	0x00000001,			/* granularity */
     62 	DDI_DMA_FLAGERR			/* DMA flags */
     63 };
     64 
     65 /*
     66  * DMA attributes for tx/rx buffers.
     67  */
     68 static ddi_dma_attr_t ixgbe_buf_dma_attr = {
     69 	DMA_ATTR_V0,			/* version number */
     70 	0x0000000000000000ull,		/* low address */
     71 	0xFFFFFFFFFFFFFFFFull,		/* high address */
     72 	0x00000000FFFFFFFFull,		/* dma counter max */
     73 	IXGBE_DMA_ALIGNMENT,		/* alignment */
     74 	0x00000FFF,			/* burst sizes */
     75 	0x00000001,			/* minimum transfer size */
     76 	0x00000000FFFFFFFFull,		/* maximum transfer size */
     77 	0xFFFFFFFFFFFFFFFFull,		/* maximum segment size	 */
     78 	1,				/* scatter/gather list length */
     79 	0x00000001,			/* granularity */
     80 	DDI_DMA_FLAGERR			/* DMA flags */
     81 };
     82 
     83 /*
     84  * DMA attributes for transmit.
     85  */
     86 static ddi_dma_attr_t ixgbe_tx_dma_attr = {
     87 	DMA_ATTR_V0,			/* version number */
     88 	0x0000000000000000ull,		/* low address */
     89 	0xFFFFFFFFFFFFFFFFull,		/* high address */
     90 	0x00000000FFFFFFFFull,		/* dma counter max */
     91 	1,				/* alignment */
     92 	0x00000FFF,			/* burst sizes */
     93 	0x00000001,			/* minimum transfer size */
     94 	0x00000000FFFFFFFFull,		/* maximum transfer size */
     95 	0xFFFFFFFFFFFFFFFFull,		/* maximum segment size	 */
     96 	MAX_COOKIE,			/* scatter/gather list length */
     97 	0x00000001,			/* granularity */
     98 	DDI_DMA_FLAGERR			/* DMA flags */
     99 };
    100 
    101 /*
    102  * DMA access attributes for descriptors.
    103  */
    104 static ddi_device_acc_attr_t ixgbe_desc_acc_attr = {
    105 	DDI_DEVICE_ATTR_V0,
    106 	DDI_STRUCTURE_LE_ACC,
    107 	DDI_STRICTORDER_ACC,
    108 	DDI_FLAGERR_ACC
    109 };
    110 
    111 /*
    112  * DMA access attributes for buffers.
    113  */
    114 static ddi_device_acc_attr_t ixgbe_buf_acc_attr = {
    115 	DDI_DEVICE_ATTR_V0,
    116 	DDI_NEVERSWAP_ACC,
    117 	DDI_STRICTORDER_ACC
    118 };
    119 
    120 /*
    121  * ixgbe_alloc_dma - Allocate DMA resources for all rx/tx rings.
    122  */
    123 int
    124 ixgbe_alloc_dma(ixgbe_t *ixgbe)
    125 {
    126 	ixgbe_rx_ring_t	*rx_ring;
    127 	ixgbe_rx_data_t *rx_data;
    128 	ixgbe_tx_ring_t *tx_ring;
    129 	int i;
    130 
    131 	for (i = 0; i < ixgbe->num_rx_rings; i++) {
    132 		/*
    133 		 * Allocate receive desciptor ring and control block lists
    134 		 */
    135 		rx_ring = &ixgbe->rx_rings[i];
    136 		rx_data = rx_ring->rx_data;
    137 
    138 		if (ixgbe_alloc_rbd_ring(rx_data) != IXGBE_SUCCESS)
    139 			goto alloc_dma_failure;
    140 
    141 		if (ixgbe_alloc_rcb_lists(rx_data) != IXGBE_SUCCESS)
    142 			goto alloc_dma_failure;
    143 	}
    144 
    145 	for (i = 0; i < ixgbe->num_tx_rings; i++) {
    146 		/*
    147 		 * Allocate transmit desciptor ring and control block lists
    148 		 */
    149 		tx_ring = &ixgbe->tx_rings[i];
    150 
    151 		if (ixgbe_alloc_tbd_ring(tx_ring) != IXGBE_SUCCESS)
    152 			goto alloc_dma_failure;
    153 
    154 		if (ixgbe_alloc_tcb_lists(tx_ring) != IXGBE_SUCCESS)
    155 			goto alloc_dma_failure;
    156 	}
    157 
    158 	return (IXGBE_SUCCESS);
    159 
    160 alloc_dma_failure:
    161 	ixgbe_free_dma(ixgbe);
    162 
    163 	return (IXGBE_FAILURE);
    164 }
    165 
    166 /*
    167  * ixgbe_free_dma - Free all the DMA resources of all rx/tx rings.
    168  */
    169 void
    170 ixgbe_free_dma(ixgbe_t *ixgbe)
    171 {
    172 	ixgbe_rx_ring_t *rx_ring;
    173 	ixgbe_rx_data_t *rx_data;
    174 	ixgbe_tx_ring_t *tx_ring;
    175 	int i;
    176 
    177 	/*
    178 	 * Free DMA resources of rx rings
    179 	 */
    180 	for (i = 0; i < ixgbe->num_rx_rings; i++) {
    181 		rx_ring = &ixgbe->rx_rings[i];
    182 		rx_data = rx_ring->rx_data;
    183 
    184 		ixgbe_free_rbd_ring(rx_data);
    185 		ixgbe_free_rcb_lists(rx_data);
    186 	}
    187 
    188 	/*
    189 	 * Free DMA resources of tx rings
    190 	 */
    191 	for (i = 0; i < ixgbe->num_tx_rings; i++) {
    192 		tx_ring = &ixgbe->tx_rings[i];
    193 		ixgbe_free_tbd_ring(tx_ring);
    194 		ixgbe_free_tcb_lists(tx_ring);
    195 	}
    196 }
    197 
    198 int
    199 ixgbe_alloc_rx_ring_data(ixgbe_rx_ring_t *rx_ring)
    200 {
    201 	ixgbe_rx_data_t	*rx_data;
    202 	ixgbe_t *ixgbe = rx_ring->ixgbe;
    203 	uint32_t rcb_count;
    204 
    205 	/*
    206 	 * Allocate memory for software receive rings
    207 	 */
    208 	rx_data = kmem_zalloc(sizeof (ixgbe_rx_data_t), KM_NOSLEEP);
    209 
    210 	if (rx_data == NULL) {
    211 		ixgbe_error(ixgbe, "Allocate software receive rings failed");
    212 		return (IXGBE_FAILURE);
    213 	}
    214 
    215 	rx_data->rx_ring = rx_ring;
    216 	mutex_init(&rx_data->recycle_lock, NULL,
    217 	    MUTEX_DRIVER, DDI_INTR_PRI(ixgbe->intr_pri));
    218 
    219 	rx_data->ring_size = ixgbe->rx_ring_size;
    220 	rx_data->free_list_size = ixgbe->rx_ring_size;
    221 
    222 	rx_data->rcb_head = 0;
    223 	rx_data->rcb_tail = 0;
    224 	rx_data->rcb_free = rx_data->free_list_size;
    225 
    226 	/*
    227 	 * Allocate memory for the work list.
    228 	 */
    229 	rx_data->work_list = kmem_zalloc(sizeof (rx_control_block_t *) *
    230 	    rx_data->ring_size, KM_NOSLEEP);
    231 
    232 	if (rx_data->work_list == NULL) {
    233 		ixgbe_error(ixgbe,
    234 		    "Could not allocate memory for rx work list");
    235 		goto alloc_rx_data_failure;
    236 	}
    237 
    238 	/*
    239 	 * Allocate memory for the free list.
    240 	 */
    241 	rx_data->free_list = kmem_zalloc(sizeof (rx_control_block_t *) *
    242 	    rx_data->free_list_size, KM_NOSLEEP);
    243 
    244 	if (rx_data->free_list == NULL) {
    245 		ixgbe_error(ixgbe,
    246 		    "Cound not allocate memory for rx free list");
    247 		goto alloc_rx_data_failure;
    248 	}
    249 
    250 	/*
    251 	 * Allocate memory for the rx control blocks for work list and
    252 	 * free list.
    253 	 */
    254 	rcb_count = rx_data->ring_size + rx_data->free_list_size;
    255 	rx_data->rcb_area =
    256 	    kmem_zalloc(sizeof (rx_control_block_t) * rcb_count,
    257 	    KM_NOSLEEP);
    258 
    259 	if (rx_data->rcb_area == NULL) {
    260 		ixgbe_error(ixgbe,
    261 		    "Cound not allocate memory for rx control blocks");
    262 		goto alloc_rx_data_failure;
    263 	}
    264 
    265 	rx_ring->rx_data = rx_data;
    266 	return (IXGBE_SUCCESS);
    267 
    268 alloc_rx_data_failure:
    269 	ixgbe_free_rx_ring_data(rx_data);
    270 	return (IXGBE_FAILURE);
    271 }
    272 
    273 void
    274 ixgbe_free_rx_ring_data(ixgbe_rx_data_t *rx_data)
    275 {
    276 	uint32_t rcb_count;
    277 
    278 	if (rx_data == NULL)
    279 		return;
    280 
    281 	ASSERT(rx_data->rcb_pending == 0);
    282 
    283 	rcb_count = rx_data->ring_size + rx_data->free_list_size;
    284 	if (rx_data->rcb_area != NULL) {
    285 		kmem_free(rx_data->rcb_area,
    286 		    sizeof (rx_control_block_t) * rcb_count);
    287 		rx_data->rcb_area = NULL;
    288 	}
    289 
    290 	if (rx_data->work_list != NULL) {
    291 		kmem_free(rx_data->work_list,
    292 		    sizeof (rx_control_block_t *) * rx_data->ring_size);
    293 		rx_data->work_list = NULL;
    294 	}
    295 
    296 	if (rx_data->free_list != NULL) {
    297 		kmem_free(rx_data->free_list,
    298 		    sizeof (rx_control_block_t *) * rx_data->free_list_size);
    299 		rx_data->free_list = NULL;
    300 	}
    301 
    302 	mutex_destroy(&rx_data->recycle_lock);
    303 	kmem_free(rx_data, sizeof (ixgbe_rx_data_t));
    304 }
    305 
    306 /*
    307  * ixgbe_alloc_tbd_ring - Memory allocation for the tx descriptors of one ring.
    308  */
    309 static int
    310 ixgbe_alloc_tbd_ring(ixgbe_tx_ring_t *tx_ring)
    311 {
    312 	int ret;
    313 	size_t size;
    314 	size_t len;
    315 	uint_t cookie_num;
    316 	dev_info_t *devinfo;
    317 	ddi_dma_cookie_t cookie;
    318 	ixgbe_t *ixgbe = tx_ring->ixgbe;
    319 
    320 	devinfo = ixgbe->dip;
    321 	size = sizeof (union ixgbe_adv_tx_desc) * tx_ring->ring_size;
    322 
    323 	/*
    324 	 * If tx head write-back is enabled, an extra tbd is allocated
    325 	 * to save the head write-back value
    326 	 */
    327 	if (ixgbe->tx_head_wb_enable) {
    328 		size += sizeof (union ixgbe_adv_tx_desc);
    329 	}
    330 
    331 	/*
    332 	 * Allocate a DMA handle for the transmit descriptor
    333 	 * memory area.
    334 	 */
    335 	ret = ddi_dma_alloc_handle(devinfo, &ixgbe_desc_dma_attr,
    336 	    DDI_DMA_DONTWAIT, NULL,
    337 	    &tx_ring->tbd_area.dma_handle);
    338 
    339 	if (ret != DDI_SUCCESS) {
    340 		ixgbe_error(ixgbe,
    341 		    "Could not allocate tbd dma handle: %x", ret);
    342 		tx_ring->tbd_area.dma_handle = NULL;
    343 
    344 		return (IXGBE_FAILURE);
    345 	}
    346 
    347 	/*
    348 	 * Allocate memory to DMA data to and from the transmit
    349 	 * descriptors.
    350 	 */
    351 	ret = ddi_dma_mem_alloc(tx_ring->tbd_area.dma_handle,
    352 	    size, &ixgbe_desc_acc_attr, DDI_DMA_CONSISTENT,
    353 	    DDI_DMA_DONTWAIT, NULL,
    354 	    (caddr_t *)&tx_ring->tbd_area.address,
    355 	    &len, &tx_ring->tbd_area.acc_handle);
    356 
    357 	if (ret != DDI_SUCCESS) {
    358 		ixgbe_error(ixgbe,
    359 		    "Could not allocate tbd dma memory: %x", ret);
    360 		tx_ring->tbd_area.acc_handle = NULL;
    361 		tx_ring->tbd_area.address = NULL;
    362 		if (tx_ring->tbd_area.dma_handle != NULL) {
    363 			ddi_dma_free_handle(&tx_ring->tbd_area.dma_handle);
    364 			tx_ring->tbd_area.dma_handle = NULL;
    365 		}
    366 		return (IXGBE_FAILURE);
    367 	}
    368 
    369 	/*
    370 	 * Initialize the entire transmit buffer descriptor area to zero
    371 	 */
    372 	bzero(tx_ring->tbd_area.address, len);
    373 
    374 	/*
    375 	 * Allocates DMA resources for the memory that was allocated by
    376 	 * the ddi_dma_mem_alloc call. The DMA resources then get bound to the
    377 	 * the memory address
    378 	 */
    379 	ret = ddi_dma_addr_bind_handle(tx_ring->tbd_area.dma_handle,
    380 	    NULL, (caddr_t)tx_ring->tbd_area.address,
    381 	    len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
    382 	    DDI_DMA_DONTWAIT, NULL, &cookie, &cookie_num);
    383 
    384 	if (ret != DDI_DMA_MAPPED) {
    385 		ixgbe_error(ixgbe,
    386 		    "Could not bind tbd dma resource: %x", ret);
    387 		tx_ring->tbd_area.dma_address = NULL;
    388 		if (tx_ring->tbd_area.acc_handle != NULL) {
    389 			ddi_dma_mem_free(&tx_ring->tbd_area.acc_handle);
    390 			tx_ring->tbd_area.acc_handle = NULL;
    391 			tx_ring->tbd_area.address = NULL;
    392 		}
    393 		if (tx_ring->tbd_area.dma_handle != NULL) {
    394 			ddi_dma_free_handle(&tx_ring->tbd_area.dma_handle);
    395 			tx_ring->tbd_area.dma_handle = NULL;
    396 		}
    397 		return (IXGBE_FAILURE);
    398 	}
    399 
    400 	ASSERT(cookie_num == 1);
    401 
    402 	tx_ring->tbd_area.dma_address = cookie.dmac_laddress;
    403 	tx_ring->tbd_area.size = len;
    404 
    405 	tx_ring->tbd_ring = (union ixgbe_adv_tx_desc *)(uintptr_t)
    406 	    tx_ring->tbd_area.address;
    407 
    408 	return (IXGBE_SUCCESS);
    409 }
    410 
    411 /*
    412  * ixgbe_free_tbd_ring - Free the tx descriptors of one ring.
    413  */
    414 static void
    415 ixgbe_free_tbd_ring(ixgbe_tx_ring_t *tx_ring)
    416 {
    417 	if (tx_ring->tbd_area.dma_handle != NULL) {
    418 		(void) ddi_dma_unbind_handle(tx_ring->tbd_area.dma_handle);
    419 	}
    420 	if (tx_ring->tbd_area.acc_handle != NULL) {
    421 		ddi_dma_mem_free(&tx_ring->tbd_area.acc_handle);
    422 		tx_ring->tbd_area.acc_handle = NULL;
    423 	}
    424 	if (tx_ring->tbd_area.dma_handle != NULL) {
    425 		ddi_dma_free_handle(&tx_ring->tbd_area.dma_handle);
    426 		tx_ring->tbd_area.dma_handle = NULL;
    427 	}
    428 	tx_ring->tbd_area.address = NULL;
    429 	tx_ring->tbd_area.dma_address = NULL;
    430 	tx_ring->tbd_area.size = 0;
    431 
    432 	tx_ring->tbd_ring = NULL;
    433 }
    434 
    435 /*
    436  * ixgbe_alloc_rbd_ring - Memory allocation for the rx descriptors of one ring.
    437  */
    438 static int
    439 ixgbe_alloc_rbd_ring(ixgbe_rx_data_t *rx_data)
    440 {
    441 	int ret;
    442 	size_t size;
    443 	size_t len;
    444 	uint_t cookie_num;
    445 	dev_info_t *devinfo;
    446 	ddi_dma_cookie_t cookie;
    447 	ixgbe_t *ixgbe = rx_data->rx_ring->ixgbe;
    448 
    449 	devinfo = ixgbe->dip;
    450 	size = sizeof (union ixgbe_adv_rx_desc) * rx_data->ring_size;
    451 
    452 	/*
    453 	 * Allocate a new DMA handle for the receive descriptor
    454 	 * memory area.
    455 	 */
    456 	ret = ddi_dma_alloc_handle(devinfo, &ixgbe_desc_dma_attr,
    457 	    DDI_DMA_DONTWAIT, NULL,
    458 	    &rx_data->rbd_area.dma_handle);
    459 
    460 	if (ret != DDI_SUCCESS) {
    461 		ixgbe_error(ixgbe,
    462 		    "Could not allocate rbd dma handle: %x", ret);
    463 		rx_data->rbd_area.dma_handle = NULL;
    464 		return (IXGBE_FAILURE);
    465 	}
    466 
    467 	/*
    468 	 * Allocate memory to DMA data to and from the receive
    469 	 * descriptors.
    470 	 */
    471 	ret = ddi_dma_mem_alloc(rx_data->rbd_area.dma_handle,
    472 	    size, &ixgbe_desc_acc_attr, DDI_DMA_CONSISTENT,
    473 	    DDI_DMA_DONTWAIT, NULL,
    474 	    (caddr_t *)&rx_data->rbd_area.address,
    475 	    &len, &rx_data->rbd_area.acc_handle);
    476 
    477 	if (ret != DDI_SUCCESS) {
    478 		ixgbe_error(ixgbe,
    479 		    "Could not allocate rbd dma memory: %x", ret);
    480 		rx_data->rbd_area.acc_handle = NULL;
    481 		rx_data->rbd_area.address = NULL;
    482 		if (rx_data->rbd_area.dma_handle != NULL) {
    483 			ddi_dma_free_handle(&rx_data->rbd_area.dma_handle);
    484 			rx_data->rbd_area.dma_handle = NULL;
    485 		}
    486 		return (IXGBE_FAILURE);
    487 	}
    488 
    489 	/*
    490 	 * Initialize the entire transmit buffer descriptor area to zero
    491 	 */
    492 	bzero(rx_data->rbd_area.address, len);
    493 
    494 	/*
    495 	 * Allocates DMA resources for the memory that was allocated by
    496 	 * the ddi_dma_mem_alloc call.
    497 	 */
    498 	ret = ddi_dma_addr_bind_handle(rx_data->rbd_area.dma_handle,
    499 	    NULL, (caddr_t)rx_data->rbd_area.address,
    500 	    len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
    501 	    DDI_DMA_DONTWAIT, NULL, &cookie, &cookie_num);
    502 
    503 	if (ret != DDI_DMA_MAPPED) {
    504 		ixgbe_error(ixgbe,
    505 		    "Could not bind rbd dma resource: %x", ret);
    506 		rx_data->rbd_area.dma_address = NULL;
    507 		if (rx_data->rbd_area.acc_handle != NULL) {
    508 			ddi_dma_mem_free(&rx_data->rbd_area.acc_handle);
    509 			rx_data->rbd_area.acc_handle = NULL;
    510 			rx_data->rbd_area.address = NULL;
    511 		}
    512 		if (rx_data->rbd_area.dma_handle != NULL) {
    513 			ddi_dma_free_handle(&rx_data->rbd_area.dma_handle);
    514 			rx_data->rbd_area.dma_handle = NULL;
    515 		}
    516 		return (IXGBE_FAILURE);
    517 	}
    518 
    519 	ASSERT(cookie_num == 1);
    520 
    521 	rx_data->rbd_area.dma_address = cookie.dmac_laddress;
    522 	rx_data->rbd_area.size = len;
    523 
    524 	rx_data->rbd_ring = (union ixgbe_adv_rx_desc *)(uintptr_t)
    525 	    rx_data->rbd_area.address;
    526 
    527 	return (IXGBE_SUCCESS);
    528 }
    529 
    530 /*
    531  * ixgbe_free_rbd_ring - Free the rx descriptors of one ring.
    532  */
    533 static void
    534 ixgbe_free_rbd_ring(ixgbe_rx_data_t *rx_data)
    535 {
    536 	if (rx_data->rbd_area.dma_handle != NULL) {
    537 		(void) ddi_dma_unbind_handle(rx_data->rbd_area.dma_handle);
    538 	}
    539 	if (rx_data->rbd_area.acc_handle != NULL) {
    540 		ddi_dma_mem_free(&rx_data->rbd_area.acc_handle);
    541 		rx_data->rbd_area.acc_handle = NULL;
    542 	}
    543 	if (rx_data->rbd_area.dma_handle != NULL) {
    544 		ddi_dma_free_handle(&rx_data->rbd_area.dma_handle);
    545 		rx_data->rbd_area.dma_handle = NULL;
    546 	}
    547 	rx_data->rbd_area.address = NULL;
    548 	rx_data->rbd_area.dma_address = NULL;
    549 	rx_data->rbd_area.size = 0;
    550 
    551 	rx_data->rbd_ring = NULL;
    552 }
    553 
    554 /*
    555  * ixgbe_alloc_dma_buffer - Allocate DMA resources for a DMA buffer.
    556  */
    557 static int
    558 ixgbe_alloc_dma_buffer(ixgbe_t *ixgbe, dma_buffer_t *buf, size_t size)
    559 {
    560 	int ret;
    561 	dev_info_t *devinfo = ixgbe->dip;
    562 	ddi_dma_cookie_t cookie;
    563 	size_t len;
    564 	uint_t cookie_num;
    565 
    566 	ret = ddi_dma_alloc_handle(devinfo,
    567 	    &ixgbe_buf_dma_attr, DDI_DMA_DONTWAIT,
    568 	    NULL, &buf->dma_handle);
    569 
    570 	if (ret != DDI_SUCCESS) {
    571 		buf->dma_handle = NULL;
    572 		ixgbe_error(ixgbe,
    573 		    "Could not allocate dma buffer handle: %x", ret);
    574 		return (IXGBE_FAILURE);
    575 	}
    576 
    577 	ret = ddi_dma_mem_alloc(buf->dma_handle,
    578 	    size, &ixgbe_buf_acc_attr, DDI_DMA_STREAMING,
    579 	    DDI_DMA_DONTWAIT, NULL, &buf->address,
    580 	    &len, &buf->acc_handle);
    581 
    582 	if (ret != DDI_SUCCESS) {
    583 		buf->acc_handle = NULL;
    584 		buf->address = NULL;
    585 		if (buf->dma_handle != NULL) {
    586 			ddi_dma_free_handle(&buf->dma_handle);
    587 			buf->dma_handle = NULL;
    588 		}
    589 		ixgbe_error(ixgbe,
    590 		    "Could not allocate dma buffer memory: %x", ret);
    591 		return (IXGBE_FAILURE);
    592 	}
    593 
    594 	ret = ddi_dma_addr_bind_handle(buf->dma_handle, NULL,
    595 	    buf->address,
    596 	    len, DDI_DMA_RDWR | DDI_DMA_STREAMING,
    597 	    DDI_DMA_DONTWAIT, NULL, &cookie, &cookie_num);
    598 
    599 	if (ret != DDI_DMA_MAPPED) {
    600 		buf->dma_address = NULL;
    601 		if (buf->acc_handle != NULL) {
    602 			ddi_dma_mem_free(&buf->acc_handle);
    603 			buf->acc_handle = NULL;
    604 			buf->address = NULL;
    605 		}
    606 		if (buf->dma_handle != NULL) {
    607 			ddi_dma_free_handle(&buf->dma_handle);
    608 			buf->dma_handle = NULL;
    609 		}
    610 		ixgbe_error(ixgbe,
    611 		    "Could not bind dma buffer handle: %x", ret);
    612 		return (IXGBE_FAILURE);
    613 	}
    614 
    615 	ASSERT(cookie_num == 1);
    616 
    617 	buf->dma_address = cookie.dmac_laddress;
    618 	buf->size = len;
    619 	buf->len = 0;
    620 
    621 	return (IXGBE_SUCCESS);
    622 }
    623 
    624 /*
    625  * ixgbe_free_dma_buffer - Free one allocated area of dma memory and handle.
    626  */
    627 void
    628 ixgbe_free_dma_buffer(dma_buffer_t *buf)
    629 {
    630 	if (buf->dma_handle != NULL) {
    631 		(void) ddi_dma_unbind_handle(buf->dma_handle);
    632 		buf->dma_address = NULL;
    633 	} else {
    634 		return;
    635 	}
    636 
    637 	if (buf->acc_handle != NULL) {
    638 		ddi_dma_mem_free(&buf->acc_handle);
    639 		buf->acc_handle = NULL;
    640 		buf->address = NULL;
    641 	}
    642 
    643 	if (buf->dma_handle != NULL) {
    644 		ddi_dma_free_handle(&buf->dma_handle);
    645 		buf->dma_handle = NULL;
    646 	}
    647 
    648 	buf->size = 0;
    649 	buf->len = 0;
    650 }
    651 
    652 /*
    653  * ixgbe_alloc_tcb_lists - Memory allocation for the transmit control bolcks
    654  * of one ring.
    655  */
    656 static int
    657 ixgbe_alloc_tcb_lists(ixgbe_tx_ring_t *tx_ring)
    658 {
    659 	int i;
    660 	int ret;
    661 	tx_control_block_t *tcb;
    662 	dma_buffer_t *tx_buf;
    663 	ixgbe_t *ixgbe = tx_ring->ixgbe;
    664 	dev_info_t *devinfo = ixgbe->dip;
    665 
    666 	/*
    667 	 * Allocate memory for the work list.
    668 	 */
    669 	tx_ring->work_list = kmem_zalloc(sizeof (tx_control_block_t *) *
    670 	    tx_ring->ring_size, KM_NOSLEEP);
    671 
    672 	if (tx_ring->work_list == NULL) {
    673 		ixgbe_error(ixgbe,
    674 		    "Cound not allocate memory for tx work list");
    675 		return (IXGBE_FAILURE);
    676 	}
    677 
    678 	/*
    679 	 * Allocate memory for the free list.
    680 	 */
    681 	tx_ring->free_list = kmem_zalloc(sizeof (tx_control_block_t *) *
    682 	    tx_ring->free_list_size, KM_NOSLEEP);
    683 
    684 	if (tx_ring->free_list == NULL) {
    685 		kmem_free(tx_ring->work_list,
    686 		    sizeof (tx_control_block_t *) * tx_ring->ring_size);
    687 		tx_ring->work_list = NULL;
    688 
    689 		ixgbe_error(ixgbe,
    690 		    "Cound not allocate memory for tx free list");
    691 		return (IXGBE_FAILURE);
    692 	}
    693 
    694 	/*
    695 	 * Allocate memory for the tx control blocks of free list.
    696 	 */
    697 	tx_ring->tcb_area =
    698 	    kmem_zalloc(sizeof (tx_control_block_t) *
    699 	    tx_ring->free_list_size, KM_NOSLEEP);
    700 
    701 	if (tx_ring->tcb_area == NULL) {
    702 		kmem_free(tx_ring->work_list,
    703 		    sizeof (tx_control_block_t *) * tx_ring->ring_size);
    704 		tx_ring->work_list = NULL;
    705 
    706 		kmem_free(tx_ring->free_list,
    707 		    sizeof (tx_control_block_t *) * tx_ring->free_list_size);
    708 		tx_ring->free_list = NULL;
    709 
    710 		ixgbe_error(ixgbe,
    711 		    "Cound not allocate memory for tx control blocks");
    712 		return (IXGBE_FAILURE);
    713 	}
    714 
    715 	/*
    716 	 * Allocate dma memory for the tx control block of free list.
    717 	 */
    718 	tcb = tx_ring->tcb_area;
    719 	for (i = 0; i < tx_ring->free_list_size; i++, tcb++) {
    720 		ASSERT(tcb != NULL);
    721 
    722 		tx_ring->free_list[i] = tcb;
    723 
    724 		/*
    725 		 * Pre-allocate dma handles for transmit. These dma handles
    726 		 * will be dynamically bound to the data buffers passed down
    727 		 * from the upper layers at the time of transmitting.
    728 		 */
    729 		ret = ddi_dma_alloc_handle(devinfo,
    730 		    &ixgbe_tx_dma_attr,
    731 		    DDI_DMA_DONTWAIT, NULL,
    732 		    &tcb->tx_dma_handle);
    733 		if (ret != DDI_SUCCESS) {
    734 			tcb->tx_dma_handle = NULL;
    735 			ixgbe_error(ixgbe,
    736 			    "Could not allocate tx dma handle: %x", ret);
    737 			goto alloc_tcb_lists_fail;
    738 		}
    739 
    740 		/*
    741 		 * Pre-allocate transmit buffers for packets that the
    742 		 * size is less than bcopy_thresh.
    743 		 */
    744 		tx_buf = &tcb->tx_buf;
    745 
    746 		ret = ixgbe_alloc_dma_buffer(ixgbe,
    747 		    tx_buf, ixgbe->tx_buf_size);
    748 
    749 		if (ret != IXGBE_SUCCESS) {
    750 			ASSERT(tcb->tx_dma_handle != NULL);
    751 			ddi_dma_free_handle(&tcb->tx_dma_handle);
    752 			tcb->tx_dma_handle = NULL;
    753 			ixgbe_error(ixgbe, "Allocate tx dma buffer failed");
    754 			goto alloc_tcb_lists_fail;
    755 		}
    756 
    757 		tcb->last_index = MAX_TX_RING_SIZE;
    758 	}
    759 
    760 	return (IXGBE_SUCCESS);
    761 
    762 alloc_tcb_lists_fail:
    763 	ixgbe_free_tcb_lists(tx_ring);
    764 
    765 	return (IXGBE_FAILURE);
    766 }
    767 
    768 /*
    769  * ixgbe_free_tcb_lists - Release the memory allocated for
    770  * the transmit control bolcks of one ring.
    771  */
    772 static void
    773 ixgbe_free_tcb_lists(ixgbe_tx_ring_t *tx_ring)
    774 {
    775 	int i;
    776 	tx_control_block_t *tcb;
    777 
    778 	tcb = tx_ring->tcb_area;
    779 	if (tcb == NULL)
    780 		return;
    781 
    782 	for (i = 0; i < tx_ring->free_list_size; i++, tcb++) {
    783 		ASSERT(tcb != NULL);
    784 
    785 		/* Free the tx dma handle for dynamical binding */
    786 		if (tcb->tx_dma_handle != NULL) {
    787 			ddi_dma_free_handle(&tcb->tx_dma_handle);
    788 			tcb->tx_dma_handle = NULL;
    789 		} else {
    790 			/*
    791 			 * If the dma handle is NULL, then we don't
    792 			 * have to check the remaining.
    793 			 */
    794 			break;
    795 		}
    796 
    797 		ixgbe_free_dma_buffer(&tcb->tx_buf);
    798 	}
    799 
    800 	if (tx_ring->tcb_area != NULL) {
    801 		kmem_free(tx_ring->tcb_area,
    802 		    sizeof (tx_control_block_t) * tx_ring->free_list_size);
    803 		tx_ring->tcb_area = NULL;
    804 	}
    805 
    806 	if (tx_ring->work_list != NULL) {
    807 		kmem_free(tx_ring->work_list,
    808 		    sizeof (tx_control_block_t *) * tx_ring->ring_size);
    809 		tx_ring->work_list = NULL;
    810 	}
    811 
    812 	if (tx_ring->free_list != NULL) {
    813 		kmem_free(tx_ring->free_list,
    814 		    sizeof (tx_control_block_t *) * tx_ring->free_list_size);
    815 		tx_ring->free_list = NULL;
    816 	}
    817 }
    818 
    819 /*
    820  * ixgbe_alloc_rcb_lists - Memory allocation for the receive control blocks
    821  * of one ring.
    822  */
    823 static int
    824 ixgbe_alloc_rcb_lists(ixgbe_rx_data_t *rx_data)
    825 {
    826 	int i;
    827 	int ret;
    828 	rx_control_block_t *rcb;
    829 	ixgbe_t *ixgbe = rx_data->rx_ring->ixgbe;
    830 	dma_buffer_t *rx_buf;
    831 	uint32_t rcb_count;
    832 
    833 	/*
    834 	 * Allocate memory for the rx control blocks for work list and
    835 	 * free list.
    836 	 */
    837 	rcb_count = rx_data->ring_size + rx_data->free_list_size;
    838 	rcb = rx_data->rcb_area;
    839 
    840 	for (i = 0; i < rcb_count; i++, rcb++) {
    841 		ASSERT(rcb != NULL);
    842 
    843 		if (i < rx_data->ring_size) {
    844 			/* Attach the rx control block to the work list */
    845 			rx_data->work_list[i] = rcb;
    846 		} else {
    847 			/* Attach the rx control block to the free list */
    848 			rx_data->free_list[i - rx_data->ring_size] = rcb;
    849 		}
    850 
    851 		rx_buf = &rcb->rx_buf;
    852 		ret = ixgbe_alloc_dma_buffer(ixgbe,
    853 		    rx_buf, ixgbe->rx_buf_size);
    854 
    855 		if (ret != IXGBE_SUCCESS) {
    856 			ixgbe_error(ixgbe, "Allocate rx dma buffer failed");
    857 			goto alloc_rcb_lists_fail;
    858 		}
    859 
    860 		rx_buf->size -= IPHDR_ALIGN_ROOM;
    861 		rx_buf->address += IPHDR_ALIGN_ROOM;
    862 		rx_buf->dma_address += IPHDR_ALIGN_ROOM;
    863 
    864 		rcb->ref_cnt = 1;
    865 		rcb->rx_data = (ixgbe_rx_data_t *)rx_data;
    866 		rcb->free_rtn.free_func = ixgbe_rx_recycle;
    867 		rcb->free_rtn.free_arg = (char *)rcb;
    868 
    869 		rcb->mp = desballoc((unsigned char *)
    870 		    rx_buf->address,
    871 		    rx_buf->size,
    872 		    0, &rcb->free_rtn);
    873 	}
    874 
    875 	return (IXGBE_SUCCESS);
    876 
    877 alloc_rcb_lists_fail:
    878 	ixgbe_free_rcb_lists(rx_data);
    879 
    880 	return (IXGBE_FAILURE);
    881 }
    882 
    883 /*
    884  * ixgbe_free_rcb_lists - Free the receive control blocks of one ring.
    885  */
    886 static void
    887 ixgbe_free_rcb_lists(ixgbe_rx_data_t *rx_data)
    888 {
    889 	ixgbe_t *ixgbe;
    890 	rx_control_block_t *rcb;
    891 	uint32_t rcb_count;
    892 	uint32_t ref_cnt;
    893 	int i;
    894 
    895 	ixgbe = rx_data->rx_ring->ixgbe;
    896 
    897 	mutex_enter(&ixgbe->rx_pending_lock);
    898 
    899 	rcb = rx_data->rcb_area;
    900 	rcb_count = rx_data->ring_size + rx_data->free_list_size;
    901 
    902 	for (i = 0; i < rcb_count; i++, rcb++) {
    903 		ASSERT(rcb != NULL);
    904 
    905 		ref_cnt = atomic_dec_32_nv(&rcb->ref_cnt);
    906 		if (ref_cnt == 0) {
    907 			if (rcb->mp != NULL) {
    908 				freemsg(rcb->mp);
    909 				rcb->mp = NULL;
    910 			}
    911 			ixgbe_free_dma_buffer(&rcb->rx_buf);
    912 		} else {
    913 			atomic_inc_32(&rx_data->rcb_pending);
    914 			atomic_inc_32(&ixgbe->rcb_pending);
    915 		}
    916 	}
    917 
    918 	mutex_exit(&ixgbe->rx_pending_lock);
    919 }
    920 
    921 /*
    922  * ixgbe_set_fma_flags - Set the attribute for fma support.
    923  */
    924 void
    925 ixgbe_set_fma_flags(int acc_flag, int dma_flag)
    926 {
    927 	if (acc_flag) {
    928 		ixgbe_desc_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
    929 	} else {
    930 		ixgbe_desc_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
    931 	}
    932 
    933 	if (dma_flag) {
    934 		ixgbe_tx_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
    935 		ixgbe_buf_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
    936 		ixgbe_desc_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
    937 	} else {
    938 		ixgbe_tx_dma_attr.dma_attr_flags = 0;
    939 		ixgbe_buf_dma_attr.dma_attr_flags = 0;
    940 		ixgbe_desc_dma_attr.dma_attr_flags = 0;
    941 	}
    942 }
    943