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