2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * This file is part of the Chelsio T4 support code.
15 * Copyright (C) 2011-2013 Chelsio Communications. All rights reserved.
17 * This program is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this
20 * release for licensing terms and conditions.
24 #include <sys/sunddi.h>
25 #include <sys/atomic.h>
26 #include <sys/types.h>
32 static int rxbuf_ctor(void *, void *, int);
33 static void rxbuf_dtor(void *, void *);
36 cxgb_printf(dev_info_t
*dip
, int level
, char *f
, ...)
41 (void) snprintf(fmt
, sizeof (fmt
), "%s%d: %s", ddi_driver_name(dip
),
42 ddi_get_instance(dip
), f
);
44 vcmn_err(level
, fmt
, list
);
49 rxbuf_cache_create(struct rxbuf_cache_params
*p
)
53 (void) snprintf(name
, sizeof (name
), "%s%d_rxbuf_cache",
54 ddi_driver_name(p
->dip
), ddi_get_instance(p
->dip
));
56 return kmem_cache_create(name
, sizeof (struct rxbuf
), CACHE_LINE
,
57 rxbuf_ctor
, rxbuf_dtor
, NULL
, p
, NULL
, 0);
61 rxbuf_cache_destroy(kmem_cache_t
*cache
)
63 kmem_cache_destroy(cache
);
67 * If ref_cnt is more than 1 then those many calls to rxbuf_free will
68 * have to be made before the rxb is released back to the kmem_cache.
71 rxbuf_alloc(kmem_cache_t
*cache
, int kmflags
, uint_t ref_cnt
)
77 rxb
= kmem_cache_alloc(cache
, kmflags
);
79 rxb
->ref_cnt
= ref_cnt
;
87 * This is normally called via the rxb's freefunc, when an mblk referencing the
91 rxbuf_free(struct rxbuf
*rxb
)
93 if (atomic_dec_uint_nv(&rxb
->ref_cnt
) == 0)
94 kmem_cache_free(rxb
->cache
, rxb
);
98 rxbuf_ctor(void *arg1
, void *arg2
, int kmflag
)
100 struct rxbuf
*rxb
= arg1
;
101 struct rxbuf_cache_params
*p
= arg2
;
103 ddi_dma_cookie_t cookie
;
105 int (*callback
)(caddr_t
);
108 if (kmflag
& KM_SLEEP
)
109 callback
= DDI_DMA_SLEEP
;
111 callback
= DDI_DMA_DONTWAIT
;
113 rc
= ddi_dma_alloc_handle(p
->dip
, &p
->dma_attr_rx
, callback
, 0,
115 if (rc
!= DDI_SUCCESS
)
116 return (rc
== DDI_DMA_BADATTR
? EINVAL
: ENOMEM
);
118 rc
= ddi_dma_mem_alloc(rxb
->dhdl
, p
->buf_size
, &p
->acc_attr_rx
,
119 DDI_DMA_STREAMING
, callback
, 0, &rxb
->va
, &real_len
, &rxb
->ahdl
);
120 if (rc
!= DDI_SUCCESS
) {
125 rc
= ddi_dma_addr_bind_handle(rxb
->dhdl
, NULL
, rxb
->va
, p
->buf_size
,
126 DDI_DMA_READ
| DDI_DMA_STREAMING
, NULL
, NULL
, &cookie
, &ccount
);
127 if (rc
!= DDI_DMA_MAPPED
) {
128 if (rc
== DDI_DMA_INUSE
)
130 else if (rc
== DDI_DMA_TOOBIG
)
143 rxb
->buf_size
= p
->buf_size
;
144 rxb
->freefunc
.free_arg
= (caddr_t
)rxb
;
145 rxb
->freefunc
.free_func
= rxbuf_free
;
146 rxb
->ba
= cookie
.dmac_laddress
;
150 fail3
: (void) ddi_dma_unbind_handle(rxb
->dhdl
);
151 fail2
: ddi_dma_mem_free(&rxb
->ahdl
);
152 fail1
: ddi_dma_free_handle(&rxb
->dhdl
);
158 rxbuf_dtor(void *arg1
, void *arg2
)
160 struct rxbuf
*rxb
= arg1
;
162 (void) ddi_dma_unbind_handle(rxb
->dhdl
);
163 ddi_dma_mem_free(&rxb
->ahdl
);
164 ddi_dma_free_handle(&rxb
->dhdl
);