2 * Copyright (C) 2007 VMware, Inc. All rights reserved.
4 * The contents of this file are subject to the terms of the Common
5 * Development and Distribution License (the "License") version 1.0
6 * and no later version. You may not use this file except in
7 * compliance with the License.
9 * You can obtain a copy of the License at
10 * http://www.opensource.org/licenses/cddl1.php
12 * See the License for the specific language governing permissions
13 * and limitations under the License.
16 * Copyright (c) 2016 by Delphix. All rights reserved.
21 /* Used by ddi_regs_map_setup() and ddi_dma_mem_alloc() */
22 ddi_device_acc_attr_t vmxnet3_dev_attr
= {
28 /* Buffers with no alignment constraint DMA description */
29 static ddi_dma_attr_t vmxnet3_dma_attrs_1
= {
30 .dma_attr_version
= DMA_ATTR_V0
,
31 .dma_attr_addr_lo
= 0x0000000000000000ull
,
32 .dma_attr_addr_hi
= 0xFFFFFFFFFFFFFFFFull
,
33 .dma_attr_count_max
= 0xFFFFFFFFFFFFFFFFull
,
34 .dma_attr_align
= 0x0000000000000001ull
,
35 .dma_attr_burstsizes
= 0x0000000000000001ull
,
36 .dma_attr_minxfer
= 0x00000001,
37 .dma_attr_maxxfer
= 0xFFFFFFFFFFFFFFFFull
,
38 .dma_attr_seg
= 0xFFFFFFFFFFFFFFFFull
,
40 .dma_attr_granular
= 0x00000001,
44 /* Buffers with a 128-bytes alignment constraint DMA description */
45 static ddi_dma_attr_t vmxnet3_dma_attrs_128
= {
46 .dma_attr_version
= DMA_ATTR_V0
,
47 .dma_attr_addr_lo
= 0x0000000000000000ull
,
48 .dma_attr_addr_hi
= 0xFFFFFFFFFFFFFFFFull
,
49 .dma_attr_count_max
= 0xFFFFFFFFFFFFFFFFull
,
50 .dma_attr_align
= 0x0000000000000080ull
,
51 .dma_attr_burstsizes
= 0x0000000000000001ull
,
52 .dma_attr_minxfer
= 0x00000001,
53 .dma_attr_maxxfer
= 0xFFFFFFFFFFFFFFFFull
,
54 .dma_attr_seg
= 0xFFFFFFFFFFFFFFFFull
,
56 .dma_attr_granular
= 0x00000001,
60 /* Buffers with a 512-bytes alignment constraint DMA description */
61 static ddi_dma_attr_t vmxnet3_dma_attrs_512
= {
62 .dma_attr_version
= DMA_ATTR_V0
,
63 .dma_attr_addr_lo
= 0x0000000000000000ull
,
64 .dma_attr_addr_hi
= 0xFFFFFFFFFFFFFFFFull
,
65 .dma_attr_count_max
= 0xFFFFFFFFFFFFFFFFull
,
66 .dma_attr_align
= 0x0000000000000200ull
,
67 .dma_attr_burstsizes
= 0x0000000000000001ull
,
68 .dma_attr_minxfer
= 0x00000001,
69 .dma_attr_maxxfer
= 0xFFFFFFFFFFFFFFFFull
,
70 .dma_attr_seg
= 0xFFFFFFFFFFFFFFFFull
,
72 .dma_attr_granular
= 0x00000001,
77 vmxnet3_dmaerr2errno(int dmaerr
)
82 case DDI_DMA_NORESOURCES
:
90 case DDI_DMA_NOMAPPING
:
99 * Allocate /size/ bytes of contiguous DMA-ble memory.
102 * 0 on success, non-zero on failure.
105 vmxnet3_alloc_dma_mem(vmxnet3_softc_t
*dp
, vmxnet3_dmabuf_t
*dma
, size_t size
,
106 boolean_t canSleep
, ddi_dma_attr_t
*dma_attrs
)
108 ddi_dma_cookie_t cookie
;
111 int (*cb
) (caddr_t
) = canSleep
? DDI_DMA_SLEEP
: DDI_DMA_DONTWAIT
;
116 * Allocate a DMA handle
118 if ((dmaerr
= ddi_dma_alloc_handle(dp
->dip
, dma_attrs
, cb
, NULL
,
119 &dma
->dmaHandle
)) != DDI_SUCCESS
) {
120 VMXNET3_WARN(dp
, "ddi_dma_alloc_handle() failed: %d", dmaerr
);
121 err
= vmxnet3_dmaerr2errno(dmaerr
);
128 if (ddi_dma_mem_alloc(dma
->dmaHandle
, size
, &vmxnet3_dev_attr
,
129 DDI_DMA_CONSISTENT
, cb
, NULL
, &dma
->buf
, &dma
->bufLen
,
130 &dma
->dataHandle
) != DDI_SUCCESS
) {
131 VMXNET3_WARN(dp
, "ddi_dma_mem_alloc() failed");
133 goto error_dma_handle
;
139 if ((dmaerr
= ddi_dma_addr_bind_handle(dma
->dmaHandle
, NULL
, dma
->buf
,
140 dma
->bufLen
, DDI_DMA_RDWR
| DDI_DMA_STREAMING
, cb
, NULL
, &cookie
,
141 &cookieCount
)) != DDI_DMA_MAPPED
) {
142 VMXNET3_WARN(dp
, "ddi_dma_addr_bind_handle() failed: %d",
144 err
= vmxnet3_dmaerr2errno(dmaerr
);
148 ASSERT(cookieCount
== 1);
149 dma
->bufPA
= cookie
.dmac_laddress
;
154 ddi_dma_mem_free(&dma
->dataHandle
);
156 ddi_dma_free_handle(&dma
->dmaHandle
);
165 vmxnet3_alloc_dma_mem_1(vmxnet3_softc_t
*dp
, vmxnet3_dmabuf_t
*dma
, size_t size
,
168 return (vmxnet3_alloc_dma_mem(dp
, dma
, size
, canSleep
,
169 &vmxnet3_dma_attrs_1
));
173 vmxnet3_alloc_dma_mem_512(vmxnet3_softc_t
*dp
, vmxnet3_dmabuf_t
*dma
,
174 size_t size
, boolean_t canSleep
)
176 return (vmxnet3_alloc_dma_mem(dp
, dma
, size
, canSleep
,
177 &vmxnet3_dma_attrs_512
));
181 vmxnet3_alloc_dma_mem_128(vmxnet3_softc_t
*dp
, vmxnet3_dmabuf_t
*dma
,
182 size_t size
, boolean_t canSleep
)
184 return (vmxnet3_alloc_dma_mem(dp
, dma
, size
, canSleep
,
185 &vmxnet3_dma_attrs_128
));
189 * Free DMA-ble memory.
192 vmxnet3_free_dma_mem(vmxnet3_dmabuf_t
*dma
)
194 (void) ddi_dma_unbind_handle(dma
->dmaHandle
);
195 ddi_dma_mem_free(&dma
->dataHandle
);
196 ddi_dma_free_handle(&dma
->dmaHandle
);
204 * Get the numeric value of the property "name" in vmxnet3s.conf for
205 * the corresponding device instance.
206 * If the property isn't found or if it doesn't satisfy the conditions,
210 * The value of the property or "def".
213 vmxnet3_getprop(vmxnet3_softc_t
*dp
, char *name
, int min
, int max
, int def
)
219 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY
, dp
->dip
, DDI_PROP_DONTPASS
,
220 name
, &props
, &nprops
) == DDI_PROP_SUCCESS
) {
221 if (dp
->instance
< nprops
) {
222 ret
= props
[dp
->instance
];
224 VMXNET3_WARN(dp
, "property %s not available for this "
227 ddi_prop_free(props
);
230 if (ret
< min
|| ret
> max
) {
231 ASSERT(def
>= min
&& def
<= max
);
232 VMXNET3_WARN(dp
, "property %s invalid (%d <= %d <= %d)\n",
233 name
, min
, ret
, max
);
237 VMXNET3_DEBUG(dp
, 2, "getprop(%s) -> %d\n", name
, ret
);