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
32 * Platform-dependent "glue" code
38 /******************************************
39 * Includes and defines
40 ******************************************/
41 #include <sys/param.h>
42 #include <sys/systm.h>
44 #include <sys/protosw.h>
45 #include <sys/socket.h>
46 #include <sys/malloc.h>
47 #include <sys/kernel.h>
48 #include <sys/module.h>
51 #include <sys/mutex.h>
53 #include <sys/stddef.h>
54 #include <sys/types.h>
55 #include <sys/sockio.h>
57 #include <sys/mutex.h>
58 #include <sys/types.h>
59 #include <sys/endian.h>
60 #include <machine/bus.h>
61 #include <machine/resource.h>
62 #include <machine/clock.h>
65 #include <dev/pci/pcivar.h>
66 #include <dev/pci/pcireg.h>
67 #include <dev/pci/pci_private.h>
69 #include <net/if_arp.h>
70 #include <net/ethernet.h>
71 #include <net/if_dl.h>
72 #include <net/if_media.h>
73 #include <net/if_var.h>
75 #include <net/if_types.h>
78 #define XGE_OS_PLATFORM_64BIT
80 #if BYTE_ORDER == BIG_ENDIAN
81 #define XGE_OS_HOST_BIG_ENDIAN 1
82 #elif BYTE_ORDER == LITTLE_ENDIAN
83 #define XGE_OS_HOST_LITTLE_ENDIAN 1
86 #define XGE_HAL_USE_5B_MODE 1
87 #define XGE_HAL_PROCESS_LINK_INT_IN_ISR 1
88 #define OS_NETSTACK_BUF struct mbuf *
89 #define XGE_LL_IP_FAST_CSUM(hdr, len) 0
91 #define xge_os_ntohs ntohs
92 #define xge_os_ntohl ntohl
93 #define xge_os_htons htons
94 #define xge_os_htonl htonl
97 #define __DECONST(type, var) ((type)(uintrptr_t)(const void *)(var))
100 typedef struct busresources {
101 bus_space_tag_t bus_tag; /* DMA Tag */
102 bus_space_handle_t bus_handle; /* Bus handle */
103 struct resource *bar_start_addr;/* BAR start address */
106 typedef struct xge_dma_alloc {
107 bus_addr_t dma_phyaddr; /* Physical Address */
108 caddr_t dma_viraddr; /* Virtual Address */
109 bus_dma_tag_t dma_tag; /* DMA Tag */
110 bus_dmamap_t dma_map; /* DMA Map */
111 bus_dma_segment_t dma_segment; /* DMA Segment */
112 bus_size_t dma_size; /* Size */
113 int dma_nseg; /* Maximum scatter-gather segs. */
116 struct xge_dma_mbuf {
117 bus_addr_t dma_phyaddr; /* Physical Address */
118 bus_dmamap_t dma_map; /* DMA Map */
121 typedef struct pci_info {
122 device_t device; /* Device */
123 struct resource *regmap0; /* Resource for BAR0 */
124 struct resource *regmap1; /* Resource for BAR1 */
125 void *bar0resource; /* BAR0 tag and handle */
126 void *bar1resource; /* BAR1 tag and handle */
130 /******************************************
131 * Fixed size primitive types
132 ******************************************/
137 #define ulong_t unsigned long
138 #define uint unsigned int
139 #define ptrdiff_t ptrdiff_t
140 typedef bus_addr_t dma_addr_t;
141 typedef struct mtx spinlock_t;
142 typedef pci_info_t *pci_dev_h;
143 typedef busresource_t *pci_reg_h;
144 typedef struct xge_dma_alloc pci_dma_h;
145 typedef struct resource *pci_irq_h;
146 typedef pci_info_t *pci_cfg_h;
147 typedef struct xge_dma_alloc pci_dma_acc_h;
149 /******************************************
150 * "libc" functionality
151 ******************************************/
152 #define xge_os_memzero(addr, size) bzero(addr, size)
153 #define xge_os_memcpy(dst, src, size) bcopy(src, dst, size)
154 #define xge_os_memcmp memcmp
155 #define xge_os_strcpy strcpy
156 #define xge_os_strlen strlen
157 #define xge_os_snprintf snprintf
158 #define xge_os_sprintf sprintf
159 #define xge_os_printf(fmt...) { \
164 #define xge_os_vaprintf(fmt) { \
165 sprintf(fmt, fmt, "\n"); \
172 #define xge_os_vasprintf(buf, fmt) { \
175 (void) vaprintf(buf, fmt, va); \
179 #define xge_os_timestamp(buf) { \
180 struct timeval current_time; \
181 gettimeofday(¤t_time, 0); \
182 sprintf(buf, "%08li.%08li: ", current_time.tv_sec, \
183 current_time.tv_usec); \
186 #define xge_os_println xge_os_printf
188 /******************************************
189 * Synchronization Primitives
190 ******************************************/
191 /* Initialize the spin lock */
192 #define xge_os_spin_lock_init(lockp, ctxh) \
193 if(mtx_initialized(lockp) == 0) { \
194 mtx_init((lockp), "xge", MTX_NETWORK_LOCK, MTX_DEF); \
197 /* Initialize the spin lock (IRQ version) */
198 #define xge_os_spin_lock_init_irq(lockp, ctxh) \
199 if(mtx_initialized(lockp) == 0) { \
200 mtx_init((lockp), "xge", MTX_NETWORK_LOCK, MTX_DEF); \
203 /* Destroy the lock */
204 #define xge_os_spin_lock_destroy(lockp, ctxh) \
205 if(mtx_initialized(lockp) != 0) { \
206 mtx_destroy(lockp); \
209 /* Destroy the lock (IRQ version) */
210 #define xge_os_spin_lock_destroy_irq(lockp, ctxh) \
211 if(mtx_initialized(lockp) != 0) { \
212 mtx_destroy(lockp); \
215 /* Acquire the lock */
216 #define xge_os_spin_lock(lockp) \
217 if(mtx_owned(lockp) == 0) mtx_lock(lockp)
219 /* Release the lock */
220 #define xge_os_spin_unlock(lockp) mtx_unlock(lockp)
222 /* Acquire the lock (IRQ version) */
223 #define xge_os_spin_lock_irq(lockp, flags) { \
225 if(mtx_owned(lockp) == 0) mtx_lock_flags(lockp, flags); \
228 /* Release the lock (IRQ version) */
229 #define xge_os_spin_unlock_irq(lockp, flags) { \
231 mtx_unlock_flags(lockp, flags); \
234 /* Write memory barrier */
237 /* Delay (in micro seconds) */
238 #define xge_os_udelay(us) DELAY(us)
240 /* Delay (in milli seconds) */
241 #define xge_os_mdelay(ms) DELAY(ms * 1000)
243 /* Compare and exchange */
244 //#define xge_os_cmpxchg(targetp, cmd, newval)
246 /******************************************
248 ******************************************/
249 #define xge_os_unlikely(x) (x)
250 #define xge_os_prefetch(x) (x=x)
251 #define xge_os_prefetchw(x) (x=x)
252 #define xge_os_bug(fmt...) printf(fmt...)
253 #define xge_os_htohs ntohs
254 #define xge_os_ntohl ntohl
255 #define xge_os_htons htons
256 #define xge_os_htonl htonl
258 /******************************************
260 ******************************************/
261 #define __xge_os_attr_cacheline_aligned
262 #define __xge_os_cacheline_size 32
264 /******************************************
266 ******************************************/
267 #define XGE_OS_INVALID_DMA_ADDR ((dma_addr_t)0)
269 /******************************************
270 * xge_os_malloc - Allocate non DMA-able memory.
271 * @pdev: Device context.
272 * @size: Size to allocate.
274 * Allocate @size bytes of memory. This allocation can sleep, and
275 * therefore, and therefore it requires process context. In other words,
276 * xge_os_malloc() cannot be called from the interrupt context.
277 * Use xge_os_free() to free the allocated block.
279 * Returns: Pointer to allocated memory, NULL - on failure.
281 * See also: xge_os_free().
282 ******************************************/
284 xge_os_malloc(pci_dev_h pdev, unsigned long size) {
285 void *vaddr = malloc((size), M_DEVBUF, M_NOWAIT);
286 xge_os_memzero(vaddr, size);
287 XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, file, line);
291 /******************************************
292 * xge_os_free - Free non DMA-able memory.
293 * @pdev: Device context.
294 * @vaddr: Address of the allocated memory block.
295 * @size: Some OS's require to provide size on free
297 * Free the memory area obtained via xge_os_malloc().
298 * This call may also sleep, and therefore it cannot be used inside
301 * See also: xge_os_malloc().
302 ******************************************/
304 xge_os_free(pci_dev_h pdev, const void *vaddr, unsigned long size) {
305 XGE_OS_MEMORY_CHECK_FREE(vaddr, size);
306 free(__DECONST(void *, vaddr), M_DEVBUF);
310 xge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) {
312 *(bus_addr_t *) arg = segs->ds_addr;
316 /******************************************
317 * xge_os_dma_malloc - Allocate DMA-able memory.
318 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
319 * @size: Size (in bytes) to allocate.
320 * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED,
321 * XGE_OS_DMA_STREAMING,
322 * XGE_OS_DMA_CONSISTENT
323 * Note that the last two flags are mutually exclusive.
324 * @p_dmah: Handle used to map the memory onto the corresponding device memory
325 * space. See xge_os_dma_map(). The handle is an out-parameter
326 * returned by the function.
327 * @p_dma_acch: One more DMA handle used subsequently to free the
328 * DMA object (via xge_os_dma_free()).
330 * Allocate DMA-able contiguous memory block of the specified @size.
331 * This memory can be subsequently freed using xge_os_dma_free().
332 * Note: can be used inside interrupt context.
334 * Returns: Pointer to allocated memory(DMA-able), NULL on failure.
336 ******************************************/
338 xge_os_dma_malloc(pci_dev_h pdev, unsigned long size, int dma_flags,
339 pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch) {
340 int retValue = bus_dma_tag_create(
341 bus_get_dma_tag(pdev->device), /* Parent */
342 PAGE_SIZE, /* Alignment no specific alignment */
344 BUS_SPACE_MAXADDR, /* Low Address */
345 BUS_SPACE_MAXADDR, /* High Address */
347 NULL, /* Filter arg */
350 size, /* max segment size */
351 BUS_DMA_ALLOCNOW, /* Flags */
352 NULL, /* lockfunction */
354 &p_dmah->dma_tag); /* DMA tag */
356 xge_os_printf("bus_dma_tag_create failed\n");
359 p_dmah->dma_size = size;
360 retValue = bus_dmamem_alloc(p_dmah->dma_tag,
361 (void **)&p_dmah->dma_viraddr, BUS_DMA_NOWAIT, &p_dmah->dma_map);
363 xge_os_printf("bus_dmamem_alloc failed\n");
366 return(p_dmah->dma_viraddr);
368 fail_2: bus_dma_tag_destroy(p_dmah->dma_tag);
369 fail_1: return(NULL);
372 /******************************************
373 * xge_os_dma_free - Free previously allocated DMA-able memory.
374 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
375 * @vaddr: Virtual address of the DMA-able memory.
376 * @p_dma_acch: DMA handle used to free the resource.
377 * @p_dmah: DMA handle used for mapping. See xge_os_dma_malloc().
379 * Free DMA-able memory originally allocated by xge_os_dma_malloc().
380 * Note: can be used inside interrupt.
381 * See also: xge_os_dma_malloc().
382 ******************************************/
384 xge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size,
385 pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah) {
386 XGE_OS_MEMORY_CHECK_FREE(p_dmah->dma_viraddr, size);
387 bus_dmamem_free(p_dmah->dma_tag, p_dmah->dma_viraddr, p_dmah->dma_map);
388 bus_dma_tag_destroy(p_dmah->dma_tag);
389 p_dmah->dma_map = NULL;
390 p_dmah->dma_tag = NULL;
391 p_dmah->dma_viraddr = NULL;
395 /******************************************
396 * IO/PCI/DMA Primitives
397 ******************************************/
398 #define XGE_OS_DMA_DIR_TODEVICE 0
399 #define XGE_OS_DMA_DIR_FROMDEVICE 1
400 #define XGE_OS_DMA_DIR_BIDIRECTIONAL 2
402 /******************************************
403 * xge_os_pci_read8 - Read one byte from device PCI configuration.
404 * @pdev: Device context. Some OSs require device context to perform
405 * PIO and/or config space IO.
406 * @cfgh: PCI configuration space handle.
407 * @where: Offset in the PCI configuration space.
408 * @val: Address of the result.
410 * Read byte value from the specified @regh PCI configuration space at the
411 * specified offset = @where.
412 * Returns: 0 - success, non-zero - failure.
413 ******************************************/
414 #define xge_os_pci_read8(pdev, cfgh, where, val) \
415 (*(val) = pci_read_config(pdev->device, where, 1))
417 /******************************************
418 * xge_os_pci_write8 - Write one byte into device PCI configuration.
419 * @pdev: Device context. Some OSs require device context to perform
420 * PIO and/or config space IO.
421 * @cfgh: PCI configuration space handle.
422 * @where: Offset in the PCI configuration space.
423 * @val: Value to write.
425 * Write byte value into the specified PCI configuration space
426 * Returns: 0 - success, non-zero - failure.
427 ******************************************/
428 #define xge_os_pci_write8(pdev, cfgh, where, val) \
429 pci_write_config(pdev->device, where, val, 1)
431 /******************************************
432 * xge_os_pci_read16 - Read 16bit word from device PCI configuration.
433 * @pdev: Device context.
434 * @cfgh: PCI configuration space handle.
435 * @where: Offset in the PCI configuration space.
436 * @val: Address of the 16bit result.
438 * Read 16bit value from the specified PCI configuration space at the
440 * Returns: 0 - success, non-zero - failure.
441 ******************************************/
442 #define xge_os_pci_read16(pdev, cfgh, where, val) \
443 (*(val) = pci_read_config(pdev->device, where, 2))
445 /******************************************
446 * xge_os_pci_write16 - Write 16bit word into device PCI configuration.
447 * @pdev: Device context.
448 * @cfgh: PCI configuration space handle.
449 * @where: Offset in the PCI configuration space.
450 * @val: Value to write.
452 * Write 16bit value into the specified @offset in PCI
453 * configuration space.
454 * Returns: 0 - success, non-zero - failure.
455 ******************************************/
456 #define xge_os_pci_write16(pdev, cfgh, where, val) \
457 pci_write_config(pdev->device, where, val, 2)
459 /******************************************
460 * xge_os_pci_read32 - Read 32bit word from device PCI configuration.
461 * @pdev: Device context.
462 * @cfgh: PCI configuration space handle.
463 * @where: Offset in the PCI configuration space.
464 * @val: Address of 32bit result.
466 * Read 32bit value from the specified PCI configuration space at the
468 * Returns: 0 - success, non-zero - failure.
469 ******************************************/
470 #define xge_os_pci_read32(pdev, cfgh, where, val) \
471 (*(val) = pci_read_config(pdev->device, where, 4))
473 /******************************************
474 * xge_os_pci_write32 - Write 32bit word into device PCI configuration.
475 * @pdev: Device context.
476 * @cfgh: PCI configuration space handle.
477 * @where: Offset in the PCI configuration space.
478 * @val: Value to write.
480 * Write 32bit value into the specified @offset in PCI
481 * configuration space.
482 * Returns: 0 - success, non-zero - failure.
483 ******************************************/
484 #define xge_os_pci_write32(pdev, cfgh, where, val) \
485 pci_write_config(pdev->device, where, val, 4)
487 /******************************************
488 * xge_os_pio_mem_read8 - Read 1 byte from device memory mapped space.
489 * @pdev: Device context.
490 * @regh: PCI configuration space handle.
491 * @addr: Address in device memory space.
493 * Returns: 1 byte value read from the specified (mapped) memory space address.
494 ******************************************/
496 xge_os_pio_mem_read8(pci_dev_h pdev, pci_reg_h regh, void *addr)
498 bus_space_tag_t tag =
499 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag);
500 bus_space_handle_t handle =
501 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle);
502 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr);
504 return bus_space_read_1(tag, handle, (caddr_t)(addr) - addrss);
507 /******************************************
508 * xge_os_pio_mem_write8 - Write 1 byte into device memory mapped
510 * @pdev: Device context.
511 * @regh: PCI configuration space handle.
512 * @val: Value to write.
513 * @addr: Address in device memory space.
515 * Write byte value into the specified (mapped) device memory space.
516 ******************************************/
518 xge_os_pio_mem_write8(pci_dev_h pdev, pci_reg_h regh, u8 val, void *addr)
520 bus_space_tag_t tag =
521 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag);
522 bus_space_handle_t handle =
523 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle);
524 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr);
526 bus_space_write_1(tag, handle, (caddr_t)(addr) - addrss, val);
529 /******************************************
530 * xge_os_pio_mem_read16 - Read 16bit from device memory mapped space.
531 * @pdev: Device context.
532 * @regh: PCI configuration space handle.
533 * @addr: Address in device memory space.
535 * Returns: 16bit value read from the specified (mapped) memory space address.
536 ******************************************/
538 xge_os_pio_mem_read16(pci_dev_h pdev, pci_reg_h regh, void *addr)
540 bus_space_tag_t tag =
541 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag);
542 bus_space_handle_t handle =
543 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle);
544 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr);
546 return bus_space_read_2(tag, handle, (caddr_t)(addr) - addrss);
549 /******************************************
550 * xge_os_pio_mem_write16 - Write 16bit into device memory mapped space.
551 * @pdev: Device context.
552 * @regh: PCI configuration space handle.
553 * @val: Value to write.
554 * @addr: Address in device memory space.
556 * Write 16bit value into the specified (mapped) device memory space.
557 ******************************************/
559 xge_os_pio_mem_write16(pci_dev_h pdev, pci_reg_h regh, u16 val, void *addr)
561 bus_space_tag_t tag =
562 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag);
563 bus_space_handle_t handle =
564 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle);
565 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr);
567 bus_space_write_2(tag, handle, (caddr_t)(addr) - addrss, val);
570 /******************************************
571 * xge_os_pio_mem_read32 - Read 32bit from device memory mapped space.
572 * @pdev: Device context.
573 * @regh: PCI configuration space handle.
574 * @addr: Address in device memory space.
576 * Returns: 32bit value read from the specified (mapped) memory space address.
577 ******************************************/
579 xge_os_pio_mem_read32(pci_dev_h pdev, pci_reg_h regh, void *addr)
581 bus_space_tag_t tag =
582 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag);
583 bus_space_handle_t handle =
584 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle);
585 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr);
587 return bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss);
590 /******************************************
591 * xge_os_pio_mem_write32 - Write 32bit into device memory space.
592 * @pdev: Device context.
593 * @regh: PCI configuration space handle.
594 * @val: Value to write.
595 * @addr: Address in device memory space.
597 * Write 32bit value into the specified (mapped) device memory space.
598 ******************************************/
600 xge_os_pio_mem_write32(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr)
602 bus_space_tag_t tag =
603 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag);
604 bus_space_handle_t handle =
605 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle);
606 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr);
607 bus_space_write_4(tag, handle, (caddr_t)(addr) - addrss, val);
610 /******************************************
611 * xge_os_pio_mem_read64 - Read 64bit from device memory mapped space.
612 * @pdev: Device context.
613 * @regh: PCI configuration space handle.
614 * @addr: Address in device memory space.
616 * Returns: 64bit value read from the specified (mapped) memory space address.
617 ******************************************/
619 xge_os_pio_mem_read64(pci_dev_h pdev, pci_reg_h regh, void *addr)
623 bus_space_tag_t tag =
624 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag);
625 bus_space_handle_t handle =
626 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle);
627 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr);
629 value1 = bus_space_read_4(tag, handle, (caddr_t)(addr) + 4 - addrss);
631 value2 = bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss);
636 /******************************************
637 * xge_os_pio_mem_write64 - Write 32bit into device memory space.
638 * @pdev: Device context.
639 * @regh: PCI configuration space handle.
640 * @val: Value to write.
641 * @addr: Address in device memory space.
643 * Write 64bit value into the specified (mapped) device memory space.
644 ******************************************/
646 xge_os_pio_mem_write64(pci_dev_h pdev, pci_reg_h regh, u64 val, void *addr)
648 u32 vall = val & 0xffffffff;
649 xge_os_pio_mem_write32(pdev, regh, vall, addr);
650 xge_os_pio_mem_write32(pdev, regh, val >> 32, ((caddr_t)(addr) + 4));
653 /******************************************
655 ******************************************/
656 #define xge_os_flush_bridge xge_os_pio_mem_read64
658 /******************************************
659 * xge_os_dma_map - Map DMA-able memory block to, or from, or
660 * to-and-from device.
661 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
662 * @dmah: DMA handle used to map the memory block. Obtained via
663 * xge_os_dma_malloc().
664 * @vaddr: Virtual address of the DMA-able memory.
665 * @size: Size (in bytes) to be mapped.
666 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
667 * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED,
668 * XGE_OS_DMA_STREAMING,
669 * XGE_OS_DMA_CONSISTENT
670 * Note that the last two flags are mutually exclusive.
672 * Map a single memory block.
674 * Returns: DMA address of the memory block,
675 * XGE_OS_INVALID_DMA_ADDR on failure.
677 * See also: xge_os_dma_malloc(), xge_os_dma_unmap(),
679 ******************************************/
680 static inline dma_addr_t
681 xge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah, void *vaddr, size_t size,
682 int dir, int dma_flags)
685 bus_dmamap_load(dmah.dma_tag, dmah.dma_map, dmah.dma_viraddr,
686 dmah.dma_size, xge_dmamap_cb, &dmah.dma_phyaddr, BUS_DMA_NOWAIT);
688 xge_os_printf("bus_dmamap_load_ failed\n");
689 return XGE_OS_INVALID_DMA_ADDR;
691 dmah.dma_size = size;
692 return dmah.dma_phyaddr;
695 /******************************************
696 * xge_os_dma_unmap - Unmap DMA-able memory.
697 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
698 * @dmah: DMA handle used to map the memory block. Obtained via
699 * xge_os_dma_malloc().
700 * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map().
701 * @size: Size (in bytes) to be unmapped.
702 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
704 * Unmap a single DMA-able memory block that was previously mapped
705 * using xge_os_dma_map().
706 * See also: xge_os_dma_malloc(), xge_os_dma_map().
707 ******************************************/
709 xge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr,
710 size_t size, int dir)
712 bus_dmamap_unload(dmah.dma_tag, dmah.dma_map);
716 /******************************************
717 * xge_os_dma_sync - Synchronize mapped memory.
718 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
719 * @dmah: DMA handle used to map the memory block. Obtained via
720 * xge_os_dma_malloc().
721 * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map().
722 * @dma_offset: Offset from start of the blocke. Used by Solaris only.
723 * @length: Size of the block.
724 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
726 * Make physical and CPU memory consistent for a single
727 * streaming mode DMA translation.
728 * This API compiles to NOP on cache-coherent platforms.
729 * On non cache-coherent platforms, depending on the direction
730 * of the "sync" operation, this API will effectively
731 * either invalidate CPU cache (that might contain old data),
732 * or flush CPU cache to update physical memory.
733 * See also: xge_os_dma_malloc(), xge_os_dma_map(),
734 * xge_os_dma_unmap().
735 ******************************************/
737 xge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr,
738 u64 dma_offset, size_t length, int dir)
740 bus_dmasync_op_t syncop;
742 case XGE_OS_DMA_DIR_TODEVICE:
743 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTWRITE;
746 case XGE_OS_DMA_DIR_FROMDEVICE:
747 syncop = BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD;
750 case XGE_OS_DMA_DIR_BIDIRECTIONAL:
751 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREWRITE;
754 bus_dmamap_sync(dmah.dma_tag, dmah.dma_map, syncop);
758 #endif /* XGE_OSDEP_H */