diff options
Diffstat (limited to 'sys/dev/nxge/xge-osdep.h')
-rw-r--r-- | sys/dev/nxge/xge-osdep.h | 758 |
1 files changed, 758 insertions, 0 deletions
diff --git a/sys/dev/nxge/xge-osdep.h b/sys/dev/nxge/xge-osdep.h new file mode 100644 index 0000000..b2c448d --- /dev/null +++ b/sys/dev/nxge/xge-osdep.h @@ -0,0 +1,758 @@ +/*- + * Copyright (c) 2002-2007 Neterion, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * xge-osdep.h + * + * Platform-dependent "glue" code + */ + +#ifndef XGE_OSDEP_H +#define XGE_OSDEP_H + +/****************************************** + * Includes and defines + ******************************************/ +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/protosw.h> +#include <sys/socket.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/bus.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/rman.h> +#include <sys/stddef.h> +#include <sys/types.h> +#include <sys/sockio.h> +#include <sys/proc.h> +#include <sys/mutex.h> +#include <sys/types.h> +#include <sys/endian.h> +#include <machine/bus.h> +#include <machine/resource.h> +#include <machine/clock.h> +#include <vm/vm.h> +#include <vm/pmap.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pci_private.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <net/ethernet.h> +#include <net/if_dl.h> +#include <net/if_media.h> +#include <net/if_var.h> +#include <net/bpf.h> +#include <net/if_types.h> + + +#define XGE_OS_PLATFORM_64BIT + +#if BYTE_ORDER == BIG_ENDIAN +#define XGE_OS_HOST_BIG_ENDIAN 1 +#elif BYTE_ORDER == LITTLE_ENDIAN +#define XGE_OS_HOST_LITTLE_ENDIAN 1 +#endif + +#define XGE_HAL_USE_5B_MODE 1 +#define XGE_HAL_PROCESS_LINK_INT_IN_ISR 1 +#define OS_NETSTACK_BUF struct mbuf * +#define XGE_LL_IP_FAST_CSUM(hdr, len) 0 + +#define xge_os_ntohs ntohs +#define xge_os_ntohl ntohl +#define xge_os_htons htons +#define xge_os_htonl htonl + +#ifndef __DECONST +#define __DECONST(type, var) ((type)(uintrptr_t)(const void *)(var)) +#endif + +typedef struct busresources { + bus_space_tag_t bus_tag; /* DMA Tag */ + bus_space_handle_t bus_handle; /* Bus handle */ + struct resource *bar_start_addr;/* BAR start address */ +} busresource_t; + +typedef struct xge_dma_alloc { + bus_addr_t dma_phyaddr; /* Physical Address */ + caddr_t dma_viraddr; /* Virtual Address */ + bus_dma_tag_t dma_tag; /* DMA Tag */ + bus_dmamap_t dma_map; /* DMA Map */ + bus_dma_segment_t dma_segment; /* DMA Segment */ + bus_size_t dma_size; /* Size */ + int dma_nseg; /* Maximum scatter-gather segs. */ +} xdma; + +struct xge_dma_mbuf { + bus_addr_t dma_phyaddr; /* Physical Address */ + bus_dmamap_t dma_map; /* DMA Map */ +}; + +typedef struct pci_info { + device_t device; /* Device */ + struct resource *regmap0; /* Resource for BAR0 */ + struct resource *regmap1; /* Resource for BAR1 */ + void *bar0resource; /* BAR0 tag and handle */ + void *bar1resource; /* BAR1 tag and handle */ +} pci_info_t; + + +/****************************************** + * Fixed size primitive types + ******************************************/ +#define u8 uint8_t +#define u16 uint16_t +#define u32 uint32_t +#define u64 uint64_t +#define ulong_t unsigned long +#define uint unsigned int +#define ptrdiff_t ptrdiff_t +typedef bus_addr_t dma_addr_t; +typedef struct mtx spinlock_t; +typedef pci_info_t *pci_dev_h; +typedef busresource_t *pci_reg_h; +typedef struct xge_dma_alloc pci_dma_h; +typedef struct resource *pci_irq_h; +typedef pci_info_t *pci_cfg_h; +typedef struct xge_dma_alloc pci_dma_acc_h; + +/****************************************** + * "libc" functionality + ******************************************/ +#define xge_os_memzero(addr, size) bzero(addr, size) +#define xge_os_memcpy(dst, src, size) bcopy(src, dst, size) +#define xge_os_memcmp memcmp +#define xge_os_strcpy strcpy +#define xge_os_strlen strlen +#define xge_os_snprintf snprintf +#define xge_os_sprintf sprintf +#define xge_os_printf(fmt...) { \ + printf(fmt); \ + printf("\n"); \ +} + +#define xge_os_vaprintf(fmt) { \ + sprintf(fmt, fmt, "\n"); \ + va_list va; \ + va_start(va, fmt); \ + vprintf(fmt, va); \ + va_end(va); \ +} + +#define xge_os_vasprintf(buf, fmt) { \ + va_list va; \ + va_start(va, fmt); \ + (void) vaprintf(buf, fmt, va); \ + va_end(va); \ +} + +#define xge_os_timestamp(buf) { \ + struct timeval current_time; \ + gettimeofday(¤t_time, 0); \ + sprintf(buf, "%08li.%08li: ", current_time.tv_sec, \ + current_time.tv_usec); \ +} + +#define xge_os_println xge_os_printf + +/****************************************** + * Synchronization Primitives + ******************************************/ +/* Initialize the spin lock */ +#define xge_os_spin_lock_init(lockp, ctxh) \ + if(mtx_initialized(lockp) == 0) { \ + mtx_init((lockp), "xge", MTX_NETWORK_LOCK, MTX_DEF); \ + } + +/* Initialize the spin lock (IRQ version) */ +#define xge_os_spin_lock_init_irq(lockp, ctxh) \ + if(mtx_initialized(lockp) == 0) { \ + mtx_init((lockp), "xge", MTX_NETWORK_LOCK, MTX_DEF); \ + } + +/* Destroy the lock */ +#define xge_os_spin_lock_destroy(lockp, ctxh) \ + if(mtx_initialized(lockp) != 0) { \ + mtx_destroy(lockp); \ + } + +/* Destroy the lock (IRQ version) */ +#define xge_os_spin_lock_destroy_irq(lockp, ctxh) \ + if(mtx_initialized(lockp) != 0) { \ + mtx_destroy(lockp); \ + } + +/* Acquire the lock */ +#define xge_os_spin_lock(lockp) \ + if(mtx_owned(lockp) == 0) mtx_lock(lockp) + +/* Release the lock */ +#define xge_os_spin_unlock(lockp) mtx_unlock(lockp) + +/* Acquire the lock (IRQ version) */ +#define xge_os_spin_lock_irq(lockp, flags) { \ + flags = MTX_QUIET; \ + if(mtx_owned(lockp) == 0) mtx_lock_flags(lockp, flags); \ +} + +/* Release the lock (IRQ version) */ +#define xge_os_spin_unlock_irq(lockp, flags) { \ + flags = MTX_QUIET; \ + mtx_unlock_flags(lockp, flags); \ +} + +/* Write memory barrier */ +#define xge_os_wmb() + +/* Delay (in micro seconds) */ +#define xge_os_udelay(us) DELAY(us) + +/* Delay (in milli seconds) */ +#define xge_os_mdelay(ms) DELAY(ms * 1000) + +/* Compare and exchange */ +//#define xge_os_cmpxchg(targetp, cmd, newval) + +/****************************************** + * Misc primitives + ******************************************/ +#define xge_os_unlikely(x) (x) +#define xge_os_prefetch(x) (x=x) +#define xge_os_prefetchw(x) (x=x) +#define xge_os_bug(fmt...) printf(fmt...) +#define xge_os_htohs ntohs +#define xge_os_ntohl ntohl +#define xge_os_htons htons +#define xge_os_htonl htonl + +/****************************************** + * Compiler Stuffs + ******************************************/ +#define __xge_os_attr_cacheline_aligned +#define __xge_os_cacheline_size 32 + +/****************************************** + * Memory Primitives + ******************************************/ +#define XGE_OS_INVALID_DMA_ADDR ((dma_addr_t)0) + +/****************************************** + * xge_os_malloc - Allocate non DMA-able memory. + * @pdev: Device context. + * @size: Size to allocate. + * + * Allocate @size bytes of memory. This allocation can sleep, and + * therefore, and therefore it requires process context. In other words, + * xge_os_malloc() cannot be called from the interrupt context. + * Use xge_os_free() to free the allocated block. + * + * Returns: Pointer to allocated memory, NULL - on failure. + * + * See also: xge_os_free(). + ******************************************/ +static inline void * +xge_os_malloc(pci_dev_h pdev, unsigned long size) { + void *vaddr = malloc((size), M_DEVBUF, M_NOWAIT); + xge_os_memzero(vaddr, size); + XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, file, line); + return (vaddr); +} + +/****************************************** + * xge_os_free - Free non DMA-able memory. + * @pdev: Device context. + * @vaddr: Address of the allocated memory block. + * @size: Some OS's require to provide size on free + * + * Free the memory area obtained via xge_os_malloc(). + * This call may also sleep, and therefore it cannot be used inside + * interrupt. + * + * See also: xge_os_malloc(). + ******************************************/ +static inline void +xge_os_free(pci_dev_h pdev, const void *vaddr, unsigned long size) { + XGE_OS_MEMORY_CHECK_FREE(vaddr, size); + free(__DECONST(void *, vaddr), M_DEVBUF); +} + +static void +xge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) { + if(error) return; + *(bus_addr_t *) arg = segs->ds_addr; + return; +} + +/****************************************** + * xge_os_dma_malloc - Allocate DMA-able memory. + * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. + * @size: Size (in bytes) to allocate. + * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, + * XGE_OS_DMA_STREAMING, + * XGE_OS_DMA_CONSISTENT + * Note that the last two flags are mutually exclusive. + * @p_dmah: Handle used to map the memory onto the corresponding device memory + * space. See xge_os_dma_map(). The handle is an out-parameter + * returned by the function. + * @p_dma_acch: One more DMA handle used subsequently to free the + * DMA object (via xge_os_dma_free()). + * + * Allocate DMA-able contiguous memory block of the specified @size. + * This memory can be subsequently freed using xge_os_dma_free(). + * Note: can be used inside interrupt context. + * + * Returns: Pointer to allocated memory(DMA-able), NULL on failure. + * + ******************************************/ +static inline void * +xge_os_dma_malloc(pci_dev_h pdev, unsigned long size, int dma_flags, + pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch) { + int retValue = bus_dma_tag_create( + bus_get_dma_tag(pdev->device), /* Parent */ + PAGE_SIZE, /* Alignment no specific alignment */ + 0, /* Bounds */ + BUS_SPACE_MAXADDR, /* Low Address */ + BUS_SPACE_MAXADDR, /* High Address */ + NULL, /* Filter */ + NULL, /* Filter arg */ + size, /* Max Size */ + 1, /* n segments */ + size, /* max segment size */ + BUS_DMA_ALLOCNOW, /* Flags */ + NULL, /* lockfunction */ + NULL, /* lock arg */ + &p_dmah->dma_tag); /* DMA tag */ + if(retValue != 0) { + xge_os_printf("bus_dma_tag_create failed\n"); + goto fail_1; + } + p_dmah->dma_size = size; + retValue = bus_dmamem_alloc(p_dmah->dma_tag, + (void **)&p_dmah->dma_viraddr, BUS_DMA_NOWAIT, &p_dmah->dma_map); + if(retValue != 0) { + xge_os_printf("bus_dmamem_alloc failed\n"); + goto fail_2; + } + return(p_dmah->dma_viraddr); + +fail_2: bus_dma_tag_destroy(p_dmah->dma_tag); +fail_1: return(NULL); +} + +/****************************************** + * xge_os_dma_free - Free previously allocated DMA-able memory. + * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. + * @vaddr: Virtual address of the DMA-able memory. + * @p_dma_acch: DMA handle used to free the resource. + * @p_dmah: DMA handle used for mapping. See xge_os_dma_malloc(). + * + * Free DMA-able memory originally allocated by xge_os_dma_malloc(). + * Note: can be used inside interrupt. + * See also: xge_os_dma_malloc(). + ******************************************/ +static inline void +xge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size, + pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah) { + XGE_OS_MEMORY_CHECK_FREE(p_dmah->dma_viraddr, size); + bus_dmamem_free(p_dmah->dma_tag, p_dmah->dma_viraddr, p_dmah->dma_map); + bus_dma_tag_destroy(p_dmah->dma_tag); + p_dmah->dma_map = NULL; + p_dmah->dma_tag = NULL; + p_dmah->dma_viraddr = NULL; + return; +} + +/****************************************** + * IO/PCI/DMA Primitives + ******************************************/ +#define XGE_OS_DMA_DIR_TODEVICE 0 +#define XGE_OS_DMA_DIR_FROMDEVICE 1 +#define XGE_OS_DMA_DIR_BIDIRECTIONAL 2 + +/****************************************** + * xge_os_pci_read8 - Read one byte from device PCI configuration. + * @pdev: Device context. Some OSs require device context to perform + * PIO and/or config space IO. + * @cfgh: PCI configuration space handle. + * @where: Offset in the PCI configuration space. + * @val: Address of the result. + * + * Read byte value from the specified @regh PCI configuration space at the + * specified offset = @where. + * Returns: 0 - success, non-zero - failure. + ******************************************/ +#define xge_os_pci_read8(pdev, cfgh, where, val) \ + (*(val) = pci_read_config(pdev->device, where, 1)) + +/****************************************** + * xge_os_pci_write8 - Write one byte into device PCI configuration. + * @pdev: Device context. Some OSs require device context to perform + * PIO and/or config space IO. + * @cfgh: PCI configuration space handle. + * @where: Offset in the PCI configuration space. + * @val: Value to write. + * + * Write byte value into the specified PCI configuration space + * Returns: 0 - success, non-zero - failure. + ******************************************/ +#define xge_os_pci_write8(pdev, cfgh, where, val) \ + pci_write_config(pdev->device, where, val, 1) + +/****************************************** + * xge_os_pci_read16 - Read 16bit word from device PCI configuration. + * @pdev: Device context. + * @cfgh: PCI configuration space handle. + * @where: Offset in the PCI configuration space. + * @val: Address of the 16bit result. + * + * Read 16bit value from the specified PCI configuration space at the + * specified offset. + * Returns: 0 - success, non-zero - failure. + ******************************************/ +#define xge_os_pci_read16(pdev, cfgh, where, val) \ + (*(val) = pci_read_config(pdev->device, where, 2)) + +/****************************************** + * xge_os_pci_write16 - Write 16bit word into device PCI configuration. + * @pdev: Device context. + * @cfgh: PCI configuration space handle. + * @where: Offset in the PCI configuration space. + * @val: Value to write. + * + * Write 16bit value into the specified @offset in PCI + * configuration space. + * Returns: 0 - success, non-zero - failure. + ******************************************/ +#define xge_os_pci_write16(pdev, cfgh, where, val) \ + pci_write_config(pdev->device, where, val, 2) + +/****************************************** + * xge_os_pci_read32 - Read 32bit word from device PCI configuration. + * @pdev: Device context. + * @cfgh: PCI configuration space handle. + * @where: Offset in the PCI configuration space. + * @val: Address of 32bit result. + * + * Read 32bit value from the specified PCI configuration space at the + * specified offset. + * Returns: 0 - success, non-zero - failure. + ******************************************/ +#define xge_os_pci_read32(pdev, cfgh, where, val) \ + (*(val) = pci_read_config(pdev->device, where, 4)) + +/****************************************** + * xge_os_pci_write32 - Write 32bit word into device PCI configuration. + * @pdev: Device context. + * @cfgh: PCI configuration space handle. + * @where: Offset in the PCI configuration space. + * @val: Value to write. + * + * Write 32bit value into the specified @offset in PCI + * configuration space. + * Returns: 0 - success, non-zero - failure. + ******************************************/ +#define xge_os_pci_write32(pdev, cfgh, where, val) \ + pci_write_config(pdev->device, where, val, 4) + +/****************************************** + * xge_os_pio_mem_read8 - Read 1 byte from device memory mapped space. + * @pdev: Device context. + * @regh: PCI configuration space handle. + * @addr: Address in device memory space. + * + * Returns: 1 byte value read from the specified (mapped) memory space address. + ******************************************/ +static inline u8 +xge_os_pio_mem_read8(pci_dev_h pdev, pci_reg_h regh, void *addr) +{ + bus_space_tag_t tag = + (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); + bus_space_handle_t handle = + (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); + caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); + + return bus_space_read_1(tag, handle, (caddr_t)(addr) - addrss); +} + +/****************************************** + * xge_os_pio_mem_write8 - Write 1 byte into device memory mapped + * space. + * @pdev: Device context. + * @regh: PCI configuration space handle. + * @val: Value to write. + * @addr: Address in device memory space. + * + * Write byte value into the specified (mapped) device memory space. + ******************************************/ +static inline void +xge_os_pio_mem_write8(pci_dev_h pdev, pci_reg_h regh, u8 val, void *addr) +{ + bus_space_tag_t tag = + (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); + bus_space_handle_t handle = + (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); + caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); + + bus_space_write_1(tag, handle, (caddr_t)(addr) - addrss, val); +} + +/****************************************** + * xge_os_pio_mem_read16 - Read 16bit from device memory mapped space. + * @pdev: Device context. + * @regh: PCI configuration space handle. + * @addr: Address in device memory space. + * + * Returns: 16bit value read from the specified (mapped) memory space address. + ******************************************/ +static inline u16 +xge_os_pio_mem_read16(pci_dev_h pdev, pci_reg_h regh, void *addr) +{ + bus_space_tag_t tag = + (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); + bus_space_handle_t handle = + (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); + caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); + + return bus_space_read_2(tag, handle, (caddr_t)(addr) - addrss); +} + +/****************************************** + * xge_os_pio_mem_write16 - Write 16bit into device memory mapped space. + * @pdev: Device context. + * @regh: PCI configuration space handle. + * @val: Value to write. + * @addr: Address in device memory space. + * + * Write 16bit value into the specified (mapped) device memory space. + ******************************************/ +static inline void +xge_os_pio_mem_write16(pci_dev_h pdev, pci_reg_h regh, u16 val, void *addr) +{ + bus_space_tag_t tag = + (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); + bus_space_handle_t handle = + (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); + caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); + + bus_space_write_2(tag, handle, (caddr_t)(addr) - addrss, val); +} + +/****************************************** + * xge_os_pio_mem_read32 - Read 32bit from device memory mapped space. + * @pdev: Device context. + * @regh: PCI configuration space handle. + * @addr: Address in device memory space. + * + * Returns: 32bit value read from the specified (mapped) memory space address. + ******************************************/ +static inline u32 +xge_os_pio_mem_read32(pci_dev_h pdev, pci_reg_h regh, void *addr) +{ + bus_space_tag_t tag = + (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); + bus_space_handle_t handle = + (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); + caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); + + return bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss); +} + +/****************************************** + * xge_os_pio_mem_write32 - Write 32bit into device memory space. + * @pdev: Device context. + * @regh: PCI configuration space handle. + * @val: Value to write. + * @addr: Address in device memory space. + * + * Write 32bit value into the specified (mapped) device memory space. + ******************************************/ +static inline void +xge_os_pio_mem_write32(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr) +{ + bus_space_tag_t tag = + (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); + bus_space_handle_t handle = + (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); + caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); + bus_space_write_4(tag, handle, (caddr_t)(addr) - addrss, val); +} + +/****************************************** + * xge_os_pio_mem_read64 - Read 64bit from device memory mapped space. + * @pdev: Device context. + * @regh: PCI configuration space handle. + * @addr: Address in device memory space. + * + * Returns: 64bit value read from the specified (mapped) memory space address. + ******************************************/ +static inline u64 +xge_os_pio_mem_read64(pci_dev_h pdev, pci_reg_h regh, void *addr) +{ + u64 value1, value2; + + bus_space_tag_t tag = + (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); + bus_space_handle_t handle = + (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); + caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); + + value1 = bus_space_read_4(tag, handle, (caddr_t)(addr) + 4 - addrss); + value1 <<= 32; + value2 = bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss); + value1 |= value2; + return value1; +} + +/****************************************** + * xge_os_pio_mem_write64 - Write 32bit into device memory space. + * @pdev: Device context. + * @regh: PCI configuration space handle. + * @val: Value to write. + * @addr: Address in device memory space. + * + * Write 64bit value into the specified (mapped) device memory space. + ******************************************/ +static inline void +xge_os_pio_mem_write64(pci_dev_h pdev, pci_reg_h regh, u64 val, void *addr) +{ + u32 vall = val & 0xffffffff; + xge_os_pio_mem_write32(pdev, regh, vall, addr); + xge_os_pio_mem_write32(pdev, regh, val >> 32, ((caddr_t)(addr) + 4)); +} + +/****************************************** + * FIXME: document + ******************************************/ +#define xge_os_flush_bridge xge_os_pio_mem_read64 + +/****************************************** + * xge_os_dma_map - Map DMA-able memory block to, or from, or + * to-and-from device. + * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. + * @dmah: DMA handle used to map the memory block. Obtained via + * xge_os_dma_malloc(). + * @vaddr: Virtual address of the DMA-able memory. + * @size: Size (in bytes) to be mapped. + * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.) + * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, + * XGE_OS_DMA_STREAMING, + * XGE_OS_DMA_CONSISTENT + * Note that the last two flags are mutually exclusive. + * + * Map a single memory block. + * + * Returns: DMA address of the memory block, + * XGE_OS_INVALID_DMA_ADDR on failure. + * + * See also: xge_os_dma_malloc(), xge_os_dma_unmap(), + * xge_os_dma_sync(). + ******************************************/ +static inline dma_addr_t +xge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah, void *vaddr, size_t size, + int dir, int dma_flags) +{ + int retValue = + bus_dmamap_load(dmah.dma_tag, dmah.dma_map, dmah.dma_viraddr, + dmah.dma_size, xge_dmamap_cb, &dmah.dma_phyaddr, BUS_DMA_NOWAIT); + if(retValue != 0) { + xge_os_printf("bus_dmamap_load_ failed\n"); + return XGE_OS_INVALID_DMA_ADDR; + } + dmah.dma_size = size; + return dmah.dma_phyaddr; +} + +/****************************************** + * xge_os_dma_unmap - Unmap DMA-able memory. + * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. + * @dmah: DMA handle used to map the memory block. Obtained via + * xge_os_dma_malloc(). + * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map(). + * @size: Size (in bytes) to be unmapped. + * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.) + * + * Unmap a single DMA-able memory block that was previously mapped + * using xge_os_dma_map(). + * See also: xge_os_dma_malloc(), xge_os_dma_map(). + ******************************************/ +static inline void +xge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr, + size_t size, int dir) +{ + bus_dmamap_unload(dmah.dma_tag, dmah.dma_map); + return; +} + +/****************************************** + * xge_os_dma_sync - Synchronize mapped memory. + * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. + * @dmah: DMA handle used to map the memory block. Obtained via + * xge_os_dma_malloc(). + * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map(). + * @dma_offset: Offset from start of the blocke. Used by Solaris only. + * @length: Size of the block. + * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.) + * + * Make physical and CPU memory consistent for a single + * streaming mode DMA translation. + * This API compiles to NOP on cache-coherent platforms. + * On non cache-coherent platforms, depending on the direction + * of the "sync" operation, this API will effectively + * either invalidate CPU cache (that might contain old data), + * or flush CPU cache to update physical memory. + * See also: xge_os_dma_malloc(), xge_os_dma_map(), + * xge_os_dma_unmap(). + ******************************************/ +static inline void +xge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr, + u64 dma_offset, size_t length, int dir) +{ + bus_dmasync_op_t syncop; + switch(dir) { + case XGE_OS_DMA_DIR_TODEVICE: + syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTWRITE; + break; + + case XGE_OS_DMA_DIR_FROMDEVICE: + syncop = BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD; + break; + + case XGE_OS_DMA_DIR_BIDIRECTIONAL: + syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREWRITE; + break; + } + bus_dmamap_sync(dmah.dma_tag, dmah.dma_map, syncop); + return; +} + +#endif /* XGE_OSDEP_H */ |