2 * Copyright (c) 2002-2007 Neterion, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * Includes and defines
35 #include <sys/param.h>
36 #include <sys/systm.h>
38 #include <sys/protosw.h>
39 #include <sys/socket.h>
40 #include <sys/malloc.h>
41 #include <sys/kernel.h>
42 #include <sys/module.h>
45 #include <sys/mutex.h>
47 #include <sys/stddef.h>
48 #include <sys/types.h>
49 #include <sys/sockio.h>
51 #include <sys/mutex.h>
52 #include <sys/types.h>
53 #include <sys/endian.h>
54 #include <sys/sysctl.h>
55 #include <sys/endian.h>
56 #include <sys/socket.h>
57 #include <machine/bus.h>
58 #include <machine/resource.h>
59 #include <machine/clock.h>
62 #include <dev/pci/pcivar.h>
63 #include <dev/pci/pcireg.h>
64 #include <dev/pci/pci_private.h>
66 #include <net/if_arp.h>
67 #include <net/ethernet.h>
68 #include <net/if_dl.h>
69 #include <net/if_media.h>
70 #include <net/if_var.h>
72 #include <net/if_types.h>
73 #include <netinet/in_systm.h>
74 #include <netinet/in.h>
75 #include <netinet/ip.h>
76 #include <netinet/tcp.h>
78 #define XGE_OS_PLATFORM_64BIT
80 #if BYTE_ORDER == BIG_ENDIAN
81 #define XGE_OS_HOST_BIG_ENDIAN
82 #elif BYTE_ORDER == LITTLE_ENDIAN
83 #define XGE_OS_HOST_LITTLE_ENDIAN
86 #define XGE_HAL_USE_5B_MODE
88 #ifdef XGE_TRACE_ASSERT
89 #undef XGE_TRACE_ASSERT
92 #define OS_NETSTACK_BUF struct mbuf *
93 #define XGE_LL_IP_FAST_CSUM(hdr, len) 0
96 #define __DECONST(type, var) ((type)(uintrptr_t)(const void *)(var))
99 #define xge_os_ntohs ntohs
100 #define xge_os_ntohl ntohl
101 #define xge_os_htons htons
102 #define xge_os_htonl htonl
104 typedef struct xge_bus_resource_t {
105 bus_space_tag_t bus_tag; /* DMA Tag */
106 bus_space_handle_t bus_handle; /* Bus handle */
107 struct resource *bar_start_addr;/* BAR start address */
108 } xge_bus_resource_t;
110 typedef struct xge_dma_alloc_t {
111 bus_addr_t dma_phyaddr; /* Physical Address */
112 caddr_t dma_viraddr; /* Virtual Address */
113 bus_dma_tag_t dma_tag; /* DMA Tag */
114 bus_dmamap_t dma_map; /* DMA Map */
115 bus_dma_segment_t dma_segment; /* DMA Segment */
116 bus_size_t dma_size; /* Size */
117 int dma_nseg; /* Maximum scatter-gather segs. */
120 typedef struct xge_dma_mbuf_t {
121 bus_addr_t dma_phyaddr; /* Physical Address */
122 bus_dmamap_t dma_map; /* DMA Map */
125 typedef struct xge_pci_info {
126 device_t device; /* Device */
127 struct resource *regmap0; /* Resource for BAR0 */
128 struct resource *regmap1; /* Resource for BAR1 */
129 void *bar0resource; /* BAR0 tag and handle */
130 void *bar1resource; /* BAR1 tag and handle */
135 * Fixed size primitive types
141 #define ulong_t unsigned long
142 #define uint unsigned int
143 #define ptrdiff_t ptrdiff_t
144 typedef bus_addr_t dma_addr_t;
145 typedef struct mtx spinlock_t;
146 typedef xge_pci_info_t *pci_dev_h;
147 typedef xge_bus_resource_t *pci_reg_h;
148 typedef xge_dma_alloc_t pci_dma_h;
149 typedef xge_dma_alloc_t pci_dma_acc_h;
150 typedef struct resource *pci_irq_h;
151 typedef xge_pci_info_t *pci_cfg_h;
154 * "libc" functionality
156 #define xge_os_memzero(addr, size) bzero(addr, size)
157 #define xge_os_memcpy(dst, src, size) bcopy(src, dst, size)
158 #define xge_os_memcmp memcmp
159 #define xge_os_strcpy strcpy
160 #define xge_os_strlen strlen
161 #define xge_os_snprintf snprintf
162 #define xge_os_sprintf sprintf
163 #define xge_os_printf(fmt...) { \
168 #define xge_os_vaprintf(fmt) { \
169 sprintf(fmt, fmt, "\n"); \
176 #define xge_os_vasprintf(buf, fmt) { \
179 (void) vaprintf(buf, fmt, va); \
183 #define xge_os_timestamp(buf) { \
184 struct timeval current_time; \
185 gettimeofday(¤t_time, 0); \
186 sprintf(buf, "%08li.%08li: ", current_time.tv_sec, \
187 current_time.tv_usec); \
190 #define xge_os_println xge_os_printf
193 * Synchronization Primitives
195 /* Initialize the spin lock */
196 #define xge_os_spin_lock_init(lockp, ctxh) { \
197 if(mtx_initialized(lockp) == 0) { \
198 mtx_init((lockp), "xge", NULL, MTX_DEF); \
202 /* Initialize the spin lock (IRQ version) */
203 #define xge_os_spin_lock_init_irq(lockp, ctxh) { \
204 if(mtx_initialized(lockp) == 0) { \
205 mtx_init((lockp), "xge", NULL, MTX_DEF); \
209 /* Destroy the lock */
210 #define xge_os_spin_lock_destroy(lockp, ctxh) { \
211 if(mtx_initialized(lockp) != 0) { \
212 mtx_destroy(lockp); \
216 /* Destroy the lock (IRQ version) */
217 #define xge_os_spin_lock_destroy_irq(lockp, ctxh) { \
218 if(mtx_initialized(lockp) != 0) { \
219 mtx_destroy(lockp); \
223 /* Acquire the lock */
224 #define xge_os_spin_lock(lockp) { \
225 if(mtx_owned(lockp) == 0) mtx_lock(lockp); \
228 /* Release the lock */
229 #define xge_os_spin_unlock(lockp) { \
233 /* Acquire the lock (IRQ version) */
234 #define xge_os_spin_lock_irq(lockp, flags) { \
236 if(mtx_owned(lockp) == 0) mtx_lock_flags(lockp, flags); \
239 /* Release the lock (IRQ version) */
240 #define xge_os_spin_unlock_irq(lockp, flags) { \
242 mtx_unlock_flags(lockp, flags); \
245 #if __FreeBSD_version > 800053
246 /* Write memory barrier */
247 #define xge_os_wmb() wmb()
252 /* Delay (in micro seconds) */
253 #define xge_os_udelay(us) DELAY(us)
255 /* Delay (in milli seconds) */
256 #define xge_os_mdelay(ms) DELAY(ms * 1000)
258 /* Compare and exchange */
259 //#define xge_os_cmpxchg(targetp, cmd, newval)
264 #define xge_os_unlikely(x) (x)
265 #define xge_os_prefetch(x) (x=x)
266 #define xge_os_prefetchw(x) (x=x)
267 #define xge_os_bug(fmt...) printf(fmt)
268 #define xge_os_htohs ntohs
269 #define xge_os_ntohl ntohl
270 #define xge_os_htons htons
271 #define xge_os_htonl htonl
276 #define __xge_os_attr_cacheline_aligned
277 #define __xge_os_cacheline_size 32
282 #define XGE_OS_INVALID_DMA_ADDR ((dma_addr_t)0)
286 * Allocate non DMA-able memory.
287 * @pdev: Device context.
288 * @size: Size to allocate.
290 * Allocate @size bytes of memory. This allocation can sleep, and therefore,
291 * and therefore it requires process context. In other words, xge_os_malloc()
292 * cannot be called from the interrupt context. Use xge_os_free() to free the
295 * Returns: Pointer to allocated memory, NULL - on failure.
297 * See also: xge_os_free().
300 xge_os_malloc(pci_dev_h pdev, unsigned long size) {
301 void *vaddr = malloc((size), M_DEVBUF, M_NOWAIT | M_ZERO);
303 XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, __FILE__, __LINE__);
304 xge_os_memzero(vaddr, size);
311 * Free non DMA-able memory.
312 * @pdev: Device context.
313 * @vaddr: Address of the allocated memory block.
314 * @size: Some OS's require to provide size on free
316 * Free the memory area obtained via xge_os_malloc(). This call may also sleep,
317 * and therefore it cannot be used inside interrupt.
319 * See also: xge_os_malloc().
322 xge_os_free(pci_dev_h pdev, const void *vaddr, unsigned long size) {
323 XGE_OS_MEMORY_CHECK_FREE(vaddr, size);
324 free(__DECONST(void *, vaddr), M_DEVBUF);
328 xge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) {
330 *(bus_addr_t *) arg = segs->ds_addr;
336 * Allocate DMA-able memory.
337 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
338 * @size: Size (in bytes) to allocate.
339 * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, XGE_OS_DMA_STREAMING,
340 * XGE_OS_DMA_CONSISTENT (Note that the last two flags are mutually exclusive.)
341 * @p_dmah: Handle used to map the memory onto the corresponding device memory
342 * space. See xge_os_dma_map(). The handle is an out-parameter returned by the
344 * @p_dma_acch: One more DMA handle used subsequently to free the DMA object
345 * (via xge_os_dma_free()).
347 * Allocate DMA-able contiguous memory block of the specified @size. This memory
348 * can be subsequently freed using xge_os_dma_free().
349 * Note: can be used inside interrupt context.
351 * Returns: Pointer to allocated memory(DMA-able), NULL on failure.
354 xge_os_dma_malloc(pci_dev_h pdev, unsigned long size, int dma_flags,
355 pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch) {
356 int retValue = bus_dma_tag_create(
357 bus_get_dma_tag(pdev->device), /* Parent */
358 PAGE_SIZE, /* Alignment no specific alignment */
360 BUS_SPACE_MAXADDR, /* Low Address */
361 BUS_SPACE_MAXADDR, /* High Address */
363 NULL, /* Filter arg */
366 size, /* max segment size */
367 BUS_DMA_ALLOCNOW, /* Flags */
368 NULL, /* lockfunction */
370 &p_dmah->dma_tag); /* DMA tag */
372 xge_os_printf("bus_dma_tag_create failed\n")
375 p_dmah->dma_size = size;
376 retValue = bus_dmamem_alloc(p_dmah->dma_tag,
377 (void **)&p_dmah->dma_viraddr, BUS_DMA_NOWAIT, &p_dmah->dma_map);
379 xge_os_printf("bus_dmamem_alloc failed\n")
382 XGE_OS_MEMORY_CHECK_MALLOC(p_dmah->dma_viraddr, p_dmah->dma_size,
384 return(p_dmah->dma_viraddr);
386 fail_2: bus_dma_tag_destroy(p_dmah->dma_tag);
387 fail_1: return(NULL);
392 * Free previously allocated DMA-able memory.
393 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
394 * @vaddr: Virtual address of the DMA-able memory.
395 * @p_dma_acch: DMA handle used to free the resource.
396 * @p_dmah: DMA handle used for mapping. See xge_os_dma_malloc().
398 * Free DMA-able memory originally allocated by xge_os_dma_malloc().
399 * Note: can be used inside interrupt.
400 * See also: xge_os_dma_malloc().
403 xge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size,
404 pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah)
406 XGE_OS_MEMORY_CHECK_FREE(p_dmah->dma_viraddr, size);
407 bus_dmamem_free(p_dmah->dma_tag, p_dmah->dma_viraddr, p_dmah->dma_map);
408 bus_dma_tag_destroy(p_dmah->dma_tag);
409 p_dmah->dma_tag = NULL;
410 p_dmah->dma_viraddr = NULL;
415 * IO/PCI/DMA Primitives
417 #define XGE_OS_DMA_DIR_TODEVICE 0
418 #define XGE_OS_DMA_DIR_FROMDEVICE 1
419 #define XGE_OS_DMA_DIR_BIDIRECTIONAL 2
423 * Read one byte from device PCI configuration.
424 * @pdev: Device context. Some OSs require device context to perform PIO and/or
426 * @cfgh: PCI configuration space handle.
427 * @where: Offset in the PCI configuration space.
428 * @val: Address of the result.
430 * Read byte value from the specified @regh PCI configuration space at the
431 * specified offset = @where.
432 * Returns: 0 - success, non-zero - failure.
434 #define xge_os_pci_read8(pdev, cfgh, where, val) \
435 (*(val) = pci_read_config(pdev->device, where, 1))
439 * Write one byte into device PCI configuration.
440 * @pdev: Device context. Some OSs require device context to perform PIO and/or
442 * @cfgh: PCI configuration space handle.
443 * @where: Offset in the PCI configuration space.
444 * @val: Value to write.
446 * Write byte value into the specified PCI configuration space
447 * Returns: 0 - success, non-zero - failure.
449 #define xge_os_pci_write8(pdev, cfgh, where, val) \
450 pci_write_config(pdev->device, where, val, 1)
454 * Read 16bit word from device PCI configuration.
455 * @pdev: Device context.
456 * @cfgh: PCI configuration space handle.
457 * @where: Offset in the PCI configuration space.
458 * @val: Address of the 16bit result.
460 * Read 16bit value from the specified PCI configuration space at the
462 * Returns: 0 - success, non-zero - failure.
464 #define xge_os_pci_read16(pdev, cfgh, where, val) \
465 (*(val) = pci_read_config(pdev->device, where, 2))
469 * Write 16bit word into device PCI configuration.
470 * @pdev: Device context.
471 * @cfgh: PCI configuration space handle.
472 * @where: Offset in the PCI configuration space.
473 * @val: Value to write.
475 * Write 16bit value into the specified @offset in PCI configuration space.
476 * Returns: 0 - success, non-zero - failure.
478 #define xge_os_pci_write16(pdev, cfgh, where, val) \
479 pci_write_config(pdev->device, where, val, 2)
483 * Read 32bit word from device PCI configuration.
484 * @pdev: Device context.
485 * @cfgh: PCI configuration space handle.
486 * @where: Offset in the PCI configuration space.
487 * @val: Address of 32bit result.
489 * Read 32bit value from the specified PCI configuration space at the
491 * Returns: 0 - success, non-zero - failure.
493 #define xge_os_pci_read32(pdev, cfgh, where, val) \
494 (*(val) = pci_read_config(pdev->device, where, 4))
498 * Write 32bit word into device PCI configuration.
499 * @pdev: Device context.
500 * @cfgh: PCI configuration space handle.
501 * @where: Offset in the PCI configuration space.
502 * @val: Value to write.
504 * Write 32bit value into the specified @offset in PCI configuration space.
505 * Returns: 0 - success, non-zero - failure.
507 #define xge_os_pci_write32(pdev, cfgh, where, val) \
508 pci_write_config(pdev->device, where, val, 4)
511 * xge_os_pio_mem_read8
512 * Read 1 byte from device memory mapped space.
513 * @pdev: Device context.
514 * @regh: PCI configuration space handle.
515 * @addr: Address in device memory space.
517 * Returns: 1 byte value read from the specified (mapped) memory space address.
520 xge_os_pio_mem_read8(pci_dev_h pdev, pci_reg_h regh, void *addr)
522 bus_space_tag_t tag =
523 (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
524 bus_space_handle_t handle =
525 (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
526 caddr_t addrss = (caddr_t)
527 (((xge_bus_resource_t *)(regh))->bar_start_addr);
529 return bus_space_read_1(tag, handle, (caddr_t)(addr) - addrss);
533 * xge_os_pio_mem_write8
534 * Write 1 byte into device memory mapped space.
535 * @pdev: Device context.
536 * @regh: PCI configuration space handle.
537 * @val: Value to write.
538 * @addr: Address in device memory space.
540 * Write byte value into the specified (mapped) device memory space.
543 xge_os_pio_mem_write8(pci_dev_h pdev, pci_reg_h regh, u8 val, void *addr)
545 bus_space_tag_t tag =
546 (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
547 bus_space_handle_t handle =
548 (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
549 caddr_t addrss = (caddr_t)
550 (((xge_bus_resource_t *)(regh))->bar_start_addr);
552 bus_space_write_1(tag, handle, (caddr_t)(addr) - addrss, val);
556 * xge_os_pio_mem_read16
557 * Read 16bit from device memory mapped space.
558 * @pdev: Device context.
559 * @regh: PCI configuration space handle.
560 * @addr: Address in device memory space.
562 * Returns: 16bit value read from the specified (mapped) memory space address.
565 xge_os_pio_mem_read16(pci_dev_h pdev, pci_reg_h regh, void *addr)
567 bus_space_tag_t tag =
568 (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
569 bus_space_handle_t handle =
570 (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
571 caddr_t addrss = (caddr_t)
572 (((xge_bus_resource_t *)(regh))->bar_start_addr);
574 return bus_space_read_2(tag, handle, (caddr_t)(addr) - addrss);
578 * xge_os_pio_mem_write16
579 * Write 16bit into device memory mapped space.
580 * @pdev: Device context.
581 * @regh: PCI configuration space handle.
582 * @val: Value to write.
583 * @addr: Address in device memory space.
585 * Write 16bit value into the specified (mapped) device memory space.
588 xge_os_pio_mem_write16(pci_dev_h pdev, pci_reg_h regh, u16 val, void *addr)
590 bus_space_tag_t tag =
591 (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
592 bus_space_handle_t handle =
593 (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
594 caddr_t addrss = (caddr_t)(((xge_bus_resource_t *)(regh))->bar_start_addr);
596 bus_space_write_2(tag, handle, (caddr_t)(addr) - addrss, val);
600 * xge_os_pio_mem_read32
601 * Read 32bit from device memory mapped space.
602 * @pdev: Device context.
603 * @regh: PCI configuration space handle.
604 * @addr: Address in device memory space.
606 * Returns: 32bit value read from the specified (mapped) memory space address.
609 xge_os_pio_mem_read32(pci_dev_h pdev, pci_reg_h regh, void *addr)
611 bus_space_tag_t tag =
612 (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
613 bus_space_handle_t handle =
614 (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
615 caddr_t addrss = (caddr_t)
616 (((xge_bus_resource_t *)(regh))->bar_start_addr);
618 return bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss);
622 * xge_os_pio_mem_write32
623 * Write 32bit into device memory space.
624 * @pdev: Device context.
625 * @regh: PCI configuration space handle.
626 * @val: Value to write.
627 * @addr: Address in device memory space.
629 * Write 32bit value into the specified (mapped) device memory space.
632 xge_os_pio_mem_write32(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr)
634 bus_space_tag_t tag =
635 (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
636 bus_space_handle_t handle =
637 (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
638 caddr_t addrss = (caddr_t)(((xge_bus_resource_t *)(regh))->bar_start_addr);
639 bus_space_write_4(tag, handle, (caddr_t)(addr) - addrss, val);
643 * xge_os_pio_mem_read64
644 * Read 64bit from device memory mapped space.
645 * @pdev: Device context.
646 * @regh: PCI configuration space handle.
647 * @addr: Address in device memory space.
649 * Returns: 64bit value read from the specified (mapped) memory space address.
652 xge_os_pio_mem_read64(pci_dev_h pdev, pci_reg_h regh, void *addr)
656 bus_space_tag_t tag =
657 (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
658 bus_space_handle_t handle =
659 (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
660 caddr_t addrss = (caddr_t)
661 (((xge_bus_resource_t *)(regh))->bar_start_addr);
663 value1 = bus_space_read_4(tag, handle, (caddr_t)(addr) + 4 - addrss);
665 value2 = bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss);
671 * xge_os_pio_mem_write64
672 * Write 32bit into device memory space.
673 * @pdev: Device context.
674 * @regh: PCI configuration space handle.
675 * @val: Value to write.
676 * @addr: Address in device memory space.
678 * Write 64bit value into the specified (mapped) device memory space.
681 xge_os_pio_mem_write64(pci_dev_h pdev, pci_reg_h regh, u64 val, void *addr)
683 u32 vall = val & 0xffffffff;
684 xge_os_pio_mem_write32(pdev, regh, vall, addr);
685 xge_os_pio_mem_write32(pdev, regh, val >> 32, ((caddr_t)(addr) + 4));
691 #define xge_os_flush_bridge xge_os_pio_mem_read64
695 * Map DMA-able memory block to, or from, or to-and-from device.
696 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
697 * @dmah: DMA handle used to map the memory block. Obtained via
698 * xge_os_dma_malloc().
699 * @vaddr: Virtual address of the DMA-able memory.
700 * @size: Size (in bytes) to be mapped.
701 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
702 * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, XGE_OS_DMA_STREAMING,
703 * XGE_OS_DMA_CONSISTENT (Note that the last two flags are mutually exclusive).
705 * Map a single memory block.
707 * Returns: DMA address of the memory block, XGE_OS_INVALID_DMA_ADDR on failure.
709 * See also: xge_os_dma_malloc(), xge_os_dma_unmap(), xge_os_dma_sync().
711 static inline dma_addr_t
712 xge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah, void *vaddr, size_t size,
713 int dir, int dma_flags)
716 bus_dmamap_load(dmah.dma_tag, dmah.dma_map, dmah.dma_viraddr,
717 dmah.dma_size, xge_dmamap_cb, &dmah.dma_phyaddr, BUS_DMA_NOWAIT);
719 xge_os_printf("bus_dmamap_load_ failed\n")
720 return XGE_OS_INVALID_DMA_ADDR;
722 dmah.dma_size = size;
723 return dmah.dma_phyaddr;
727 * xge_os_dma_unmap - Unmap DMA-able memory.
728 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
729 * @dmah: DMA handle used to map the memory block. Obtained via
730 * xge_os_dma_malloc().
731 * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map().
732 * @size: Size (in bytes) to be unmapped.
733 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
735 * Unmap a single DMA-able memory block that was previously mapped using
737 * See also: xge_os_dma_malloc(), xge_os_dma_map().
740 xge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr,
741 size_t size, int dir)
743 bus_dmamap_unload(dmah.dma_tag, dmah.dma_map);
748 * xge_os_dma_sync - Synchronize mapped memory.
749 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
750 * @dmah: DMA handle used to map the memory block. Obtained via
751 * xge_os_dma_malloc().
752 * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map().
753 * @dma_offset: Offset from start of the blocke. Used by Solaris only.
754 * @length: Size of the block.
755 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
757 * Make physical and CPU memory consistent for a single streaming mode DMA
758 * translation. This API compiles to NOP on cache-coherent platforms. On
759 * non cache-coherent platforms, depending on the direction of the "sync"
760 * operation, this API will effectively either invalidate CPU cache (that might
761 * contain old data), or flush CPU cache to update physical memory.
762 * See also: xge_os_dma_malloc(), xge_os_dma_map(),
763 * xge_os_dma_unmap().
766 xge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr,
767 u64 dma_offset, size_t length, int dir)
769 bus_dmasync_op_t syncop;
771 case XGE_OS_DMA_DIR_TODEVICE:
772 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTWRITE;
775 case XGE_OS_DMA_DIR_FROMDEVICE:
776 syncop = BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD;
780 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREWRITE;
783 bus_dmamap_sync(dmah.dma_tag, dmah.dma_map, syncop);
787 #endif /* XGE_OSDEP_H */