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