xge-osdep.h revision 173139
1171095Ssam/*- 2171095Ssam * Copyright (c) 2002-2007 Neterion, Inc. 3171095Ssam * All rights reserved. 4171095Ssam * 5171095Ssam * Redistribution and use in source and binary forms, with or without 6171095Ssam * modification, are permitted provided that the following conditions 7171095Ssam * are met: 8171095Ssam * 1. Redistributions of source code must retain the above copyright 9171095Ssam * notice, this list of conditions and the following disclaimer. 10171095Ssam * 2. Redistributions in binary form must reproduce the above copyright 11171095Ssam * notice, this list of conditions and the following disclaimer in the 12171095Ssam * documentation and/or other materials provided with the distribution. 13171095Ssam * 14171095Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15171095Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16171095Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17171095Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18171095Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19171095Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20171095Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21171095Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22171095Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23171095Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24171095Ssam * SUCH DAMAGE. 25171095Ssam * 26171095Ssam * $FreeBSD: head/sys/dev/nxge/xge-osdep.h 173139 2007-10-29 14:19:32Z rwatson $ 27171095Ssam */ 28171095Ssam 29171095Ssam#ifndef XGE_OSDEP_H 30171095Ssam#define XGE_OSDEP_H 31171095Ssam 32173139Srwatson/** 33171095Ssam * Includes and defines 34173139Srwatson */ 35171095Ssam#include <sys/param.h> 36171095Ssam#include <sys/systm.h> 37171095Ssam#include <sys/mbuf.h> 38171095Ssam#include <sys/protosw.h> 39171095Ssam#include <sys/socket.h> 40171095Ssam#include <sys/malloc.h> 41171095Ssam#include <sys/kernel.h> 42171095Ssam#include <sys/module.h> 43171095Ssam#include <sys/bus.h> 44171095Ssam#include <sys/lock.h> 45171095Ssam#include <sys/mutex.h> 46171095Ssam#include <sys/rman.h> 47171095Ssam#include <sys/stddef.h> 48171095Ssam#include <sys/types.h> 49171095Ssam#include <sys/sockio.h> 50171095Ssam#include <sys/proc.h> 51171095Ssam#include <sys/mutex.h> 52171095Ssam#include <sys/types.h> 53171095Ssam#include <sys/endian.h> 54173139Srwatson#include <sys/sysctl.h> 55173139Srwatson#include <sys/endian.h> 56173139Srwatson#include <sys/socket.h> 57171095Ssam#include <machine/bus.h> 58171095Ssam#include <machine/resource.h> 59171095Ssam#include <machine/clock.h> 60171095Ssam#include <vm/vm.h> 61171095Ssam#include <vm/pmap.h> 62171095Ssam#include <dev/pci/pcivar.h> 63171095Ssam#include <dev/pci/pcireg.h> 64171095Ssam#include <dev/pci/pci_private.h> 65171095Ssam#include <net/if.h> 66171095Ssam#include <net/if_arp.h> 67171095Ssam#include <net/ethernet.h> 68171095Ssam#include <net/if_dl.h> 69171095Ssam#include <net/if_media.h> 70171095Ssam#include <net/if_var.h> 71171095Ssam#include <net/bpf.h> 72171095Ssam#include <net/if_types.h> 73173139Srwatson#include <netinet/in_systm.h> 74173139Srwatson#include <netinet/in.h> 75173139Srwatson#include <netinet/ip.h> 76173139Srwatson#include <netinet/tcp.h> 77171095Ssam 78171095Ssam#define XGE_OS_PLATFORM_64BIT 79171095Ssam 80171095Ssam#if BYTE_ORDER == BIG_ENDIAN 81173139Srwatson#define XGE_OS_HOST_BIG_ENDIAN 82171095Ssam#elif BYTE_ORDER == LITTLE_ENDIAN 83173139Srwatson#define XGE_OS_HOST_LITTLE_ENDIAN 84171095Ssam#endif 85171095Ssam 86173139Srwatson#define XGE_HAL_USE_5B_MODE 87173139Srwatson 88173139Srwatson#ifdef XGE_TRACE_ASSERT 89173139Srwatson#undef XGE_TRACE_ASSERT 90173139Srwatson#endif 91173139Srwatson 92171095Ssam#define OS_NETSTACK_BUF struct mbuf * 93171095Ssam#define XGE_LL_IP_FAST_CSUM(hdr, len) 0 94171095Ssam 95173139Srwatson#ifndef __DECONST 96173139Srwatson#define __DECONST(type, var) ((type)(uintrptr_t)(const void *)(var)) 97173139Srwatson#endif 98173139Srwatson 99171095Ssam#define xge_os_ntohs ntohs 100171095Ssam#define xge_os_ntohl ntohl 101171095Ssam#define xge_os_htons htons 102171095Ssam#define xge_os_htonl htonl 103171095Ssam 104173139Srwatsontypedef struct xge_bus_resource_t { 105173139Srwatson bus_space_tag_t bus_tag; /* DMA Tag */ 106173139Srwatson bus_space_handle_t bus_handle; /* Bus handle */ 107173139Srwatson struct resource *bar_start_addr;/* BAR start address */ 108173139Srwatson} xge_bus_resource_t; 109171095Ssam 110173139Srwatsontypedef struct xge_dma_alloc_t { 111173139Srwatson bus_addr_t dma_phyaddr; /* Physical Address */ 112173139Srwatson caddr_t dma_viraddr; /* Virtual Address */ 113173139Srwatson bus_dma_tag_t dma_tag; /* DMA Tag */ 114173139Srwatson bus_dmamap_t dma_map; /* DMA Map */ 115173139Srwatson bus_dma_segment_t dma_segment; /* DMA Segment */ 116173139Srwatson bus_size_t dma_size; /* Size */ 117173139Srwatson int dma_nseg; /* Maximum scatter-gather segs. */ 118173139Srwatson} xge_dma_alloc_t; 119171095Ssam 120173139Srwatsontypedef struct xge_dma_mbuf_t { 121173139Srwatson bus_addr_t dma_phyaddr; /* Physical Address */ 122173139Srwatson bus_dmamap_t dma_map; /* DMA Map */ 123173139Srwatson}xge_dma_mbuf_t; 124171095Ssam 125173139Srwatsontypedef struct xge_pci_info { 126173139Srwatson device_t device; /* Device */ 127173139Srwatson struct resource *regmap0; /* Resource for BAR0 */ 128173139Srwatson struct resource *regmap1; /* Resource for BAR1 */ 129173139Srwatson void *bar0resource; /* BAR0 tag and handle */ 130173139Srwatson void *bar1resource; /* BAR1 tag and handle */ 131173139Srwatson} xge_pci_info_t; 132171095Ssam 133171095Ssam 134173139Srwatson/** 135171095Ssam * Fixed size primitive types 136173139Srwatson */ 137171095Ssam#define u8 uint8_t 138171095Ssam#define u16 uint16_t 139171095Ssam#define u32 uint32_t 140171095Ssam#define u64 uint64_t 141171095Ssam#define ulong_t unsigned long 142171095Ssam#define uint unsigned int 143171095Ssam#define ptrdiff_t ptrdiff_t 144171095Ssamtypedef bus_addr_t dma_addr_t; 145171095Ssamtypedef struct mtx spinlock_t; 146173139Srwatsontypedef xge_pci_info_t *pci_dev_h; 147173139Srwatsontypedef xge_bus_resource_t *pci_reg_h; 148173139Srwatsontypedef xge_dma_alloc_t pci_dma_h; 149173139Srwatsontypedef xge_dma_alloc_t pci_dma_acc_h; 150171095Ssamtypedef struct resource *pci_irq_h; 151173139Srwatsontypedef xge_pci_info_t *pci_cfg_h; 152171095Ssam 153173139Srwatson/** 154171095Ssam * "libc" functionality 155173139Srwatson */ 156171095Ssam#define xge_os_memzero(addr, size) bzero(addr, size) 157171095Ssam#define xge_os_memcpy(dst, src, size) bcopy(src, dst, size) 158171095Ssam#define xge_os_memcmp memcmp 159171095Ssam#define xge_os_strcpy strcpy 160171095Ssam#define xge_os_strlen strlen 161171095Ssam#define xge_os_snprintf snprintf 162171095Ssam#define xge_os_sprintf sprintf 163173139Srwatson#define xge_os_printf(fmt...) { \ 164173139Srwatson printf(fmt); \ 165173139Srwatson printf("\n"); \ 166171095Ssam} 167171095Ssam 168173139Srwatson#define xge_os_vaprintf(fmt) { \ 169173139Srwatson sprintf(fmt, fmt, "\n"); \ 170173139Srwatson va_list va; \ 171173139Srwatson va_start(va, fmt); \ 172173139Srwatson vprintf(fmt, va); \ 173173139Srwatson va_end(va); \ 174171095Ssam} 175171095Ssam 176173139Srwatson#define xge_os_vasprintf(buf, fmt) { \ 177173139Srwatson va_list va; \ 178173139Srwatson va_start(va, fmt); \ 179173139Srwatson (void) vaprintf(buf, fmt, va); \ 180173139Srwatson va_end(va); \ 181171095Ssam} 182171095Ssam 183173139Srwatson#define xge_os_timestamp(buf) { \ 184173139Srwatson struct timeval current_time; \ 185173139Srwatson gettimeofday(¤t_time, 0); \ 186173139Srwatson sprintf(buf, "%08li.%08li: ", current_time.tv_sec, \ 187173139Srwatson current_time.tv_usec); \ 188171095Ssam} 189171095Ssam 190171095Ssam#define xge_os_println xge_os_printf 191171095Ssam 192173139Srwatson/** 193171095Ssam * Synchronization Primitives 194173139Srwatson */ 195171095Ssam/* Initialize the spin lock */ 196173139Srwatson#define xge_os_spin_lock_init(lockp, ctxh) { \ 197173139Srwatson if(mtx_initialized(lockp) == 0) { \ 198173139Srwatson mtx_init((lockp), "xge", NULL, MTX_DEF); \ 199173139Srwatson } \ 200173139Srwatson} 201171095Ssam 202171095Ssam/* Initialize the spin lock (IRQ version) */ 203173139Srwatson#define xge_os_spin_lock_init_irq(lockp, ctxh) { \ 204173139Srwatson if(mtx_initialized(lockp) == 0) { \ 205173139Srwatson mtx_init((lockp), "xge", NULL, MTX_DEF); \ 206173139Srwatson } \ 207173139Srwatson} 208171095Ssam 209171095Ssam/* Destroy the lock */ 210173139Srwatson#define xge_os_spin_lock_destroy(lockp, ctxh) { \ 211173139Srwatson if(mtx_initialized(lockp) != 0) { \ 212173139Srwatson mtx_destroy(lockp); \ 213173139Srwatson } \ 214173139Srwatson} 215171095Ssam 216171095Ssam/* Destroy the lock (IRQ version) */ 217173139Srwatson#define xge_os_spin_lock_destroy_irq(lockp, ctxh) { \ 218173139Srwatson if(mtx_initialized(lockp) != 0) { \ 219173139Srwatson mtx_destroy(lockp); \ 220173139Srwatson } \ 221173139Srwatson} 222171095Ssam 223171095Ssam/* Acquire the lock */ 224173139Srwatson#define xge_os_spin_lock(lockp) { \ 225173139Srwatson if(mtx_owned(lockp) == 0) mtx_lock(lockp); \ 226173139Srwatson} 227171095Ssam 228171095Ssam/* Release the lock */ 229173139Srwatson#define xge_os_spin_unlock(lockp) { \ 230173139Srwatson mtx_unlock(lockp); \ 231173139Srwatson} 232171095Ssam 233171095Ssam/* Acquire the lock (IRQ version) */ 234173139Srwatson#define xge_os_spin_lock_irq(lockp, flags) { \ 235173139Srwatson flags = MTX_QUIET; \ 236173139Srwatson if(mtx_owned(lockp) == 0) mtx_lock_flags(lockp, flags); \ 237171095Ssam} 238171095Ssam 239171095Ssam/* Release the lock (IRQ version) */ 240173139Srwatson#define xge_os_spin_unlock_irq(lockp, flags) { \ 241173139Srwatson flags = MTX_QUIET; \ 242173139Srwatson mtx_unlock_flags(lockp, flags); \ 243171095Ssam} 244171095Ssam 245171095Ssam/* Write memory barrier */ 246171095Ssam#define xge_os_wmb() 247171095Ssam 248171095Ssam/* Delay (in micro seconds) */ 249171095Ssam#define xge_os_udelay(us) DELAY(us) 250171095Ssam 251171095Ssam/* Delay (in milli seconds) */ 252171095Ssam#define xge_os_mdelay(ms) DELAY(ms * 1000) 253171095Ssam 254171095Ssam/* Compare and exchange */ 255173139Srwatson//#define xge_os_cmpxchg(targetp, cmd, newval) 256171095Ssam 257173139Srwatson/** 258171095Ssam * Misc primitives 259173139Srwatson */ 260171095Ssam#define xge_os_unlikely(x) (x) 261173139Srwatson#define xge_os_prefetch(x) (x=x) 262173139Srwatson#define xge_os_prefetchw(x) (x=x) 263173139Srwatson#define xge_os_bug(fmt...) printf(fmt) 264171095Ssam#define xge_os_htohs ntohs 265171095Ssam#define xge_os_ntohl ntohl 266171095Ssam#define xge_os_htons htons 267171095Ssam#define xge_os_htonl htonl 268171095Ssam 269173139Srwatson/** 270171095Ssam * Compiler Stuffs 271173139Srwatson */ 272173139Srwatson#define __xge_os_attr_cacheline_aligned 273171095Ssam#define __xge_os_cacheline_size 32 274171095Ssam 275173139Srwatson/** 276171095Ssam * Memory Primitives 277173139Srwatson */ 278171095Ssam#define XGE_OS_INVALID_DMA_ADDR ((dma_addr_t)0) 279171095Ssam 280173139Srwatson/** 281173139Srwatson * xge_os_malloc 282173139Srwatson * Allocate non DMA-able memory. 283171095Ssam * @pdev: Device context. 284171095Ssam * @size: Size to allocate. 285171095Ssam * 286173139Srwatson * Allocate @size bytes of memory. This allocation can sleep, and therefore, 287173139Srwatson * and therefore it requires process context. In other words, xge_os_malloc() 288173139Srwatson * cannot be called from the interrupt context. Use xge_os_free() to free the 289173139Srwatson * allocated block. 290171095Ssam * 291171095Ssam * Returns: Pointer to allocated memory, NULL - on failure. 292171095Ssam * 293171095Ssam * See also: xge_os_free(). 294173139Srwatson */ 295171095Ssamstatic inline void * 296171095Ssamxge_os_malloc(pci_dev_h pdev, unsigned long size) { 297173139Srwatson void *vaddr = malloc((size), M_DEVBUF, M_NOWAIT | M_ZERO); 298173139Srwatson if(vaddr != NULL) { 299173139Srwatson XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, __FILE__, __LINE__); 300173139Srwatson xge_os_memzero(vaddr, size); 301173139Srwatson } 302173139Srwatson return (vaddr); 303171095Ssam} 304171095Ssam 305173139Srwatson/** 306173139Srwatson * xge_os_free 307173139Srwatson * Free non DMA-able memory. 308171095Ssam * @pdev: Device context. 309171095Ssam * @vaddr: Address of the allocated memory block. 310171095Ssam * @size: Some OS's require to provide size on free 311171095Ssam * 312173139Srwatson * Free the memory area obtained via xge_os_malloc(). This call may also sleep, 313173139Srwatson * and therefore it cannot be used inside interrupt. 314171095Ssam * 315171095Ssam * See also: xge_os_malloc(). 316173139Srwatson */ 317171095Ssamstatic inline void 318171095Ssamxge_os_free(pci_dev_h pdev, const void *vaddr, unsigned long size) { 319171095Ssam XGE_OS_MEMORY_CHECK_FREE(vaddr, size); 320171095Ssam free(__DECONST(void *, vaddr), M_DEVBUF); 321171095Ssam} 322171095Ssam 323171095Ssamstatic void 324171095Ssamxge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) { 325171095Ssam if(error) return; 326171095Ssam *(bus_addr_t *) arg = segs->ds_addr; 327171095Ssam return; 328171095Ssam} 329171095Ssam 330173139Srwatson/** 331173139Srwatson * xge_os_dma_malloc 332173139Srwatson * Allocate DMA-able memory. 333171095Ssam * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 334171095Ssam * @size: Size (in bytes) to allocate. 335173139Srwatson * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, XGE_OS_DMA_STREAMING, 336173139Srwatson * XGE_OS_DMA_CONSISTENT (Note that the last two flags are mutually exclusive.) 337171095Ssam * @p_dmah: Handle used to map the memory onto the corresponding device memory 338173139Srwatson * space. See xge_os_dma_map(). The handle is an out-parameter returned by the 339173139Srwatson * function. 340173139Srwatson * @p_dma_acch: One more DMA handle used subsequently to free the DMA object 341173139Srwatson * (via xge_os_dma_free()). 342171095Ssam * 343173139Srwatson * Allocate DMA-able contiguous memory block of the specified @size. This memory 344173139Srwatson * can be subsequently freed using xge_os_dma_free(). 345171095Ssam * Note: can be used inside interrupt context. 346171095Ssam * 347171095Ssam * Returns: Pointer to allocated memory(DMA-able), NULL on failure. 348173139Srwatson */ 349171095Ssamstatic inline void * 350171095Ssamxge_os_dma_malloc(pci_dev_h pdev, unsigned long size, int dma_flags, 351171095Ssam pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch) { 352171095Ssam int retValue = bus_dma_tag_create( 353173139Srwatson bus_get_dma_tag(pdev->device), /* Parent */ 354171095Ssam PAGE_SIZE, /* Alignment no specific alignment */ 355173139Srwatson 0, /* Bounds */ 356173139Srwatson BUS_SPACE_MAXADDR, /* Low Address */ 357173139Srwatson BUS_SPACE_MAXADDR, /* High Address */ 358173139Srwatson NULL, /* Filter */ 359173139Srwatson NULL, /* Filter arg */ 360173139Srwatson size, /* Max Size */ 361173139Srwatson 1, /* n segments */ 362173139Srwatson size, /* max segment size */ 363173139Srwatson BUS_DMA_ALLOCNOW, /* Flags */ 364173139Srwatson NULL, /* lockfunction */ 365173139Srwatson NULL, /* lock arg */ 366173139Srwatson &p_dmah->dma_tag); /* DMA tag */ 367171095Ssam if(retValue != 0) { 368173139Srwatson xge_os_printf("bus_dma_tag_create failed\n") 369171095Ssam goto fail_1; 370171095Ssam } 371171095Ssam p_dmah->dma_size = size; 372171095Ssam retValue = bus_dmamem_alloc(p_dmah->dma_tag, 373171095Ssam (void **)&p_dmah->dma_viraddr, BUS_DMA_NOWAIT, &p_dmah->dma_map); 374171095Ssam if(retValue != 0) { 375173139Srwatson xge_os_printf("bus_dmamem_alloc failed\n") 376171095Ssam goto fail_2; 377171095Ssam } 378173139Srwatson XGE_OS_MEMORY_CHECK_MALLOC(p_dmah->dma_viraddr, p_dmah->dma_size, 379173139Srwatson __FILE__, __LINE__); 380171095Ssam return(p_dmah->dma_viraddr); 381171095Ssam 382171095Ssamfail_2: bus_dma_tag_destroy(p_dmah->dma_tag); 383171095Ssamfail_1: return(NULL); 384171095Ssam} 385171095Ssam 386173139Srwatson/** 387173139Srwatson * xge_os_dma_free 388173139Srwatson * Free previously allocated DMA-able memory. 389171095Ssam * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 390171095Ssam * @vaddr: Virtual address of the DMA-able memory. 391171095Ssam * @p_dma_acch: DMA handle used to free the resource. 392171095Ssam * @p_dmah: DMA handle used for mapping. See xge_os_dma_malloc(). 393171095Ssam * 394171095Ssam * Free DMA-able memory originally allocated by xge_os_dma_malloc(). 395171095Ssam * Note: can be used inside interrupt. 396171095Ssam * See also: xge_os_dma_malloc(). 397173139Srwatson */ 398171095Ssamstatic inline void 399171095Ssamxge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size, 400173139Srwatson pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah) 401173139Srwatson{ 402171095Ssam XGE_OS_MEMORY_CHECK_FREE(p_dmah->dma_viraddr, size); 403171095Ssam bus_dmamem_free(p_dmah->dma_tag, p_dmah->dma_viraddr, p_dmah->dma_map); 404171095Ssam bus_dma_tag_destroy(p_dmah->dma_tag); 405171095Ssam p_dmah->dma_map = NULL; 406171095Ssam p_dmah->dma_tag = NULL; 407171095Ssam p_dmah->dma_viraddr = NULL; 408171095Ssam return; 409171095Ssam} 410171095Ssam 411173139Srwatson/** 412171095Ssam * IO/PCI/DMA Primitives 413173139Srwatson */ 414171095Ssam#define XGE_OS_DMA_DIR_TODEVICE 0 415171095Ssam#define XGE_OS_DMA_DIR_FROMDEVICE 1 416171095Ssam#define XGE_OS_DMA_DIR_BIDIRECTIONAL 2 417171095Ssam 418173139Srwatson/** 419173139Srwatson * xge_os_pci_read8 420173139Srwatson * Read one byte from device PCI configuration. 421173139Srwatson * @pdev: Device context. Some OSs require device context to perform PIO and/or 422173139Srwatson * config space IO. 423171095Ssam * @cfgh: PCI configuration space handle. 424171095Ssam * @where: Offset in the PCI configuration space. 425171095Ssam * @val: Address of the result. 426171095Ssam * 427171095Ssam * Read byte value from the specified @regh PCI configuration space at the 428171095Ssam * specified offset = @where. 429171095Ssam * Returns: 0 - success, non-zero - failure. 430173139Srwatson */ 431173139Srwatson#define xge_os_pci_read8(pdev, cfgh, where, val) \ 432171095Ssam (*(val) = pci_read_config(pdev->device, where, 1)) 433171095Ssam 434173139Srwatson/** 435173139Srwatson * xge_os_pci_write8 436173139Srwatson * Write one byte into device PCI configuration. 437173139Srwatson * @pdev: Device context. Some OSs require device context to perform PIO and/or 438173139Srwatson * config space IO. 439171095Ssam * @cfgh: PCI configuration space handle. 440171095Ssam * @where: Offset in the PCI configuration space. 441171095Ssam * @val: Value to write. 442171095Ssam * 443171095Ssam * Write byte value into the specified PCI configuration space 444171095Ssam * Returns: 0 - success, non-zero - failure. 445173139Srwatson */ 446173139Srwatson#define xge_os_pci_write8(pdev, cfgh, where, val) \ 447171095Ssam pci_write_config(pdev->device, where, val, 1) 448171095Ssam 449173139Srwatson/** 450173139Srwatson * xge_os_pci_read16 451173139Srwatson * Read 16bit word from device PCI configuration. 452171095Ssam * @pdev: Device context. 453171095Ssam * @cfgh: PCI configuration space handle. 454171095Ssam * @where: Offset in the PCI configuration space. 455171095Ssam * @val: Address of the 16bit result. 456171095Ssam * 457171095Ssam * Read 16bit value from the specified PCI configuration space at the 458171095Ssam * specified offset. 459171095Ssam * Returns: 0 - success, non-zero - failure. 460173139Srwatson */ 461173139Srwatson#define xge_os_pci_read16(pdev, cfgh, where, val) \ 462171095Ssam (*(val) = pci_read_config(pdev->device, where, 2)) 463171095Ssam 464173139Srwatson/** 465173139Srwatson * xge_os_pci_write16 466173139Srwatson * Write 16bit word into device PCI configuration. 467171095Ssam * @pdev: Device context. 468171095Ssam * @cfgh: PCI configuration space handle. 469171095Ssam * @where: Offset in the PCI configuration space. 470171095Ssam * @val: Value to write. 471171095Ssam * 472173139Srwatson * Write 16bit value into the specified @offset in PCI configuration space. 473171095Ssam * Returns: 0 - success, non-zero - failure. 474173139Srwatson */ 475173139Srwatson#define xge_os_pci_write16(pdev, cfgh, where, val) \ 476171095Ssam pci_write_config(pdev->device, where, val, 2) 477171095Ssam 478173139Srwatson/** 479173139Srwatson * xge_os_pci_read32 480173139Srwatson * Read 32bit word from device PCI configuration. 481171095Ssam * @pdev: Device context. 482171095Ssam * @cfgh: PCI configuration space handle. 483171095Ssam * @where: Offset in the PCI configuration space. 484171095Ssam * @val: Address of 32bit result. 485171095Ssam * 486171095Ssam * Read 32bit value from the specified PCI configuration space at the 487171095Ssam * specified offset. 488171095Ssam * Returns: 0 - success, non-zero - failure. 489173139Srwatson */ 490173139Srwatson#define xge_os_pci_read32(pdev, cfgh, where, val) \ 491171095Ssam (*(val) = pci_read_config(pdev->device, where, 4)) 492171095Ssam 493173139Srwatson/** 494173139Srwatson * xge_os_pci_write32 495173139Srwatson * Write 32bit word into device PCI configuration. 496171095Ssam * @pdev: Device context. 497171095Ssam * @cfgh: PCI configuration space handle. 498171095Ssam * @where: Offset in the PCI configuration space. 499171095Ssam * @val: Value to write. 500171095Ssam * 501173139Srwatson * Write 32bit value into the specified @offset in PCI configuration space. 502171095Ssam * Returns: 0 - success, non-zero - failure. 503173139Srwatson */ 504173139Srwatson#define xge_os_pci_write32(pdev, cfgh, where, val) \ 505171095Ssam pci_write_config(pdev->device, where, val, 4) 506171095Ssam 507173139Srwatson/** 508173139Srwatson * xge_os_pio_mem_read8 509173139Srwatson * Read 1 byte from device memory mapped space. 510171095Ssam * @pdev: Device context. 511171095Ssam * @regh: PCI configuration space handle. 512171095Ssam * @addr: Address in device memory space. 513171095Ssam * 514171095Ssam * Returns: 1 byte value read from the specified (mapped) memory space address. 515173139Srwatson */ 516171095Ssamstatic inline u8 517171095Ssamxge_os_pio_mem_read8(pci_dev_h pdev, pci_reg_h regh, void *addr) 518171095Ssam{ 519171095Ssam bus_space_tag_t tag = 520173139Srwatson (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag); 521171095Ssam bus_space_handle_t handle = 522173139Srwatson (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle); 523173139Srwatson caddr_t addrss = (caddr_t) 524173139Srwatson (((xge_bus_resource_t *)(regh))->bar_start_addr); 525171095Ssam 526171095Ssam return bus_space_read_1(tag, handle, (caddr_t)(addr) - addrss); 527171095Ssam} 528171095Ssam 529173139Srwatson/** 530173139Srwatson * xge_os_pio_mem_write8 531173139Srwatson * Write 1 byte into device memory mapped space. 532171095Ssam * @pdev: Device context. 533171095Ssam * @regh: PCI configuration space handle. 534171095Ssam * @val: Value to write. 535171095Ssam * @addr: Address in device memory space. 536171095Ssam * 537171095Ssam * Write byte value into the specified (mapped) device memory space. 538173139Srwatson */ 539171095Ssamstatic inline void 540171095Ssamxge_os_pio_mem_write8(pci_dev_h pdev, pci_reg_h regh, u8 val, void *addr) 541171095Ssam{ 542171095Ssam bus_space_tag_t tag = 543173139Srwatson (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag); 544171095Ssam bus_space_handle_t handle = 545173139Srwatson (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle); 546173139Srwatson caddr_t addrss = (caddr_t) 547173139Srwatson (((xge_bus_resource_t *)(regh))->bar_start_addr); 548171095Ssam 549171095Ssam bus_space_write_1(tag, handle, (caddr_t)(addr) - addrss, val); 550171095Ssam} 551171095Ssam 552173139Srwatson/** 553173139Srwatson * xge_os_pio_mem_read16 554173139Srwatson * Read 16bit from device memory mapped space. 555171095Ssam * @pdev: Device context. 556171095Ssam * @regh: PCI configuration space handle. 557171095Ssam * @addr: Address in device memory space. 558171095Ssam * 559171095Ssam * Returns: 16bit value read from the specified (mapped) memory space address. 560173139Srwatson */ 561171095Ssamstatic inline u16 562171095Ssamxge_os_pio_mem_read16(pci_dev_h pdev, pci_reg_h regh, void *addr) 563171095Ssam{ 564171095Ssam bus_space_tag_t tag = 565173139Srwatson (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag); 566171095Ssam bus_space_handle_t handle = 567173139Srwatson (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle); 568173139Srwatson caddr_t addrss = (caddr_t) 569173139Srwatson (((xge_bus_resource_t *)(regh))->bar_start_addr); 570171095Ssam 571171095Ssam return bus_space_read_2(tag, handle, (caddr_t)(addr) - addrss); 572171095Ssam} 573171095Ssam 574173139Srwatson/** 575173139Srwatson * xge_os_pio_mem_write16 576173139Srwatson * Write 16bit into device memory mapped space. 577171095Ssam * @pdev: Device context. 578171095Ssam * @regh: PCI configuration space handle. 579171095Ssam * @val: Value to write. 580171095Ssam * @addr: Address in device memory space. 581171095Ssam * 582171095Ssam * Write 16bit value into the specified (mapped) device memory space. 583173139Srwatson */ 584171095Ssamstatic inline void 585171095Ssamxge_os_pio_mem_write16(pci_dev_h pdev, pci_reg_h regh, u16 val, void *addr) 586171095Ssam{ 587171095Ssam bus_space_tag_t tag = 588173139Srwatson (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag); 589171095Ssam bus_space_handle_t handle = 590173139Srwatson (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle); 591173139Srwatson caddr_t addrss = (caddr_t)(((xge_bus_resource_t *)(regh))->bar_start_addr); 592171095Ssam 593171095Ssam bus_space_write_2(tag, handle, (caddr_t)(addr) - addrss, val); 594171095Ssam} 595171095Ssam 596173139Srwatson/** 597173139Srwatson * xge_os_pio_mem_read32 598173139Srwatson * Read 32bit from device memory mapped space. 599171095Ssam * @pdev: Device context. 600171095Ssam * @regh: PCI configuration space handle. 601171095Ssam * @addr: Address in device memory space. 602171095Ssam * 603171095Ssam * Returns: 32bit value read from the specified (mapped) memory space address. 604173139Srwatson */ 605171095Ssamstatic inline u32 606171095Ssamxge_os_pio_mem_read32(pci_dev_h pdev, pci_reg_h regh, void *addr) 607171095Ssam{ 608171095Ssam bus_space_tag_t tag = 609173139Srwatson (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag); 610171095Ssam bus_space_handle_t handle = 611173139Srwatson (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle); 612173139Srwatson caddr_t addrss = (caddr_t) 613173139Srwatson (((xge_bus_resource_t *)(regh))->bar_start_addr); 614171095Ssam 615171095Ssam return bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss); 616171095Ssam} 617171095Ssam 618173139Srwatson/** 619173139Srwatson * xge_os_pio_mem_write32 620173139Srwatson * Write 32bit into device memory space. 621171095Ssam * @pdev: Device context. 622171095Ssam * @regh: PCI configuration space handle. 623171095Ssam * @val: Value to write. 624171095Ssam * @addr: Address in device memory space. 625171095Ssam * 626171095Ssam * Write 32bit value into the specified (mapped) device memory space. 627173139Srwatson */ 628171095Ssamstatic inline void 629171095Ssamxge_os_pio_mem_write32(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr) 630171095Ssam{ 631171095Ssam bus_space_tag_t tag = 632173139Srwatson (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag); 633171095Ssam bus_space_handle_t handle = 634173139Srwatson (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle); 635173139Srwatson caddr_t addrss = (caddr_t)(((xge_bus_resource_t *)(regh))->bar_start_addr); 636171095Ssam bus_space_write_4(tag, handle, (caddr_t)(addr) - addrss, val); 637171095Ssam} 638171095Ssam 639173139Srwatson/** 640173139Srwatson * xge_os_pio_mem_read64 641173139Srwatson * Read 64bit from device memory mapped space. 642171095Ssam * @pdev: Device context. 643171095Ssam * @regh: PCI configuration space handle. 644171095Ssam * @addr: Address in device memory space. 645171095Ssam * 646171095Ssam * Returns: 64bit value read from the specified (mapped) memory space address. 647173139Srwatson */ 648171095Ssamstatic inline u64 649171095Ssamxge_os_pio_mem_read64(pci_dev_h pdev, pci_reg_h regh, void *addr) 650171095Ssam{ 651171095Ssam u64 value1, value2; 652171095Ssam 653171095Ssam bus_space_tag_t tag = 654173139Srwatson (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag); 655171095Ssam bus_space_handle_t handle = 656173139Srwatson (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle); 657173139Srwatson caddr_t addrss = (caddr_t) 658173139Srwatson (((xge_bus_resource_t *)(regh))->bar_start_addr); 659171095Ssam 660171095Ssam value1 = bus_space_read_4(tag, handle, (caddr_t)(addr) + 4 - addrss); 661171095Ssam value1 <<= 32; 662171095Ssam value2 = bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss); 663171095Ssam value1 |= value2; 664171095Ssam return value1; 665171095Ssam} 666171095Ssam 667173139Srwatson/** 668173139Srwatson * xge_os_pio_mem_write64 669173139Srwatson * Write 32bit into device memory space. 670171095Ssam * @pdev: Device context. 671171095Ssam * @regh: PCI configuration space handle. 672171095Ssam * @val: Value to write. 673171095Ssam * @addr: Address in device memory space. 674171095Ssam * 675171095Ssam * Write 64bit value into the specified (mapped) device memory space. 676173139Srwatson */ 677171095Ssamstatic inline void 678171095Ssamxge_os_pio_mem_write64(pci_dev_h pdev, pci_reg_h regh, u64 val, void *addr) 679171095Ssam{ 680171095Ssam u32 vall = val & 0xffffffff; 681171095Ssam xge_os_pio_mem_write32(pdev, regh, vall, addr); 682171095Ssam xge_os_pio_mem_write32(pdev, regh, val >> 32, ((caddr_t)(addr) + 4)); 683171095Ssam} 684171095Ssam 685173139Srwatson/** 686171095Ssam * FIXME: document 687173139Srwatson */ 688171095Ssam#define xge_os_flush_bridge xge_os_pio_mem_read64 689171095Ssam 690173139Srwatson/** 691173139Srwatson * xge_os_dma_map 692173139Srwatson * Map DMA-able memory block to, or from, or to-and-from device. 693171095Ssam * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 694171095Ssam * @dmah: DMA handle used to map the memory block. Obtained via 695171095Ssam * xge_os_dma_malloc(). 696171095Ssam * @vaddr: Virtual address of the DMA-able memory. 697171095Ssam * @size: Size (in bytes) to be mapped. 698171095Ssam * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.) 699173139Srwatson * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, XGE_OS_DMA_STREAMING, 700173139Srwatson * XGE_OS_DMA_CONSISTENT (Note that the last two flags are mutually exclusive). 701171095Ssam * 702171095Ssam * Map a single memory block. 703171095Ssam * 704173139Srwatson * Returns: DMA address of the memory block, XGE_OS_INVALID_DMA_ADDR on failure. 705171095Ssam * 706173139Srwatson * See also: xge_os_dma_malloc(), xge_os_dma_unmap(), xge_os_dma_sync(). 707173139Srwatson */ 708171095Ssamstatic inline dma_addr_t 709171095Ssamxge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah, void *vaddr, size_t size, 710171095Ssam int dir, int dma_flags) 711171095Ssam{ 712171095Ssam int retValue = 713171095Ssam bus_dmamap_load(dmah.dma_tag, dmah.dma_map, dmah.dma_viraddr, 714171095Ssam dmah.dma_size, xge_dmamap_cb, &dmah.dma_phyaddr, BUS_DMA_NOWAIT); 715171095Ssam if(retValue != 0) { 716173139Srwatson xge_os_printf("bus_dmamap_load_ failed\n") 717171095Ssam return XGE_OS_INVALID_DMA_ADDR; 718171095Ssam } 719171095Ssam dmah.dma_size = size; 720171095Ssam return dmah.dma_phyaddr; 721171095Ssam} 722171095Ssam 723173139Srwatson/** 724171095Ssam * xge_os_dma_unmap - Unmap DMA-able memory. 725171095Ssam * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 726171095Ssam * @dmah: DMA handle used to map the memory block. Obtained via 727171095Ssam * xge_os_dma_malloc(). 728171095Ssam * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map(). 729171095Ssam * @size: Size (in bytes) to be unmapped. 730171095Ssam * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.) 731171095Ssam * 732173139Srwatson * Unmap a single DMA-able memory block that was previously mapped using 733173139Srwatson * xge_os_dma_map(). 734171095Ssam * See also: xge_os_dma_malloc(), xge_os_dma_map(). 735173139Srwatson */ 736171095Ssamstatic inline void 737171095Ssamxge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr, 738171095Ssam size_t size, int dir) 739171095Ssam{ 740171095Ssam bus_dmamap_unload(dmah.dma_tag, dmah.dma_map); 741171095Ssam return; 742171095Ssam} 743171095Ssam 744173139Srwatson/** 745171095Ssam * xge_os_dma_sync - Synchronize mapped memory. 746171095Ssam * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 747171095Ssam * @dmah: DMA handle used to map the memory block. Obtained via 748171095Ssam * xge_os_dma_malloc(). 749171095Ssam * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map(). 750171095Ssam * @dma_offset: Offset from start of the blocke. Used by Solaris only. 751171095Ssam * @length: Size of the block. 752171095Ssam * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.) 753171095Ssam * 754173139Srwatson * Make physical and CPU memory consistent for a single streaming mode DMA 755173139Srwatson * translation. This API compiles to NOP on cache-coherent platforms. On 756173139Srwatson * non cache-coherent platforms, depending on the direction of the "sync" 757173139Srwatson * operation, this API will effectively either invalidate CPU cache (that might 758173139Srwatson * contain old data), or flush CPU cache to update physical memory. 759171095Ssam * See also: xge_os_dma_malloc(), xge_os_dma_map(), 760171095Ssam * xge_os_dma_unmap(). 761173139Srwatson */ 762171095Ssamstatic inline void 763171095Ssamxge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr, 764171095Ssam u64 dma_offset, size_t length, int dir) 765171095Ssam{ 766171095Ssam bus_dmasync_op_t syncop; 767171095Ssam switch(dir) { 768171095Ssam case XGE_OS_DMA_DIR_TODEVICE: 769171095Ssam syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTWRITE; 770171095Ssam break; 771171095Ssam 772171095Ssam case XGE_OS_DMA_DIR_FROMDEVICE: 773171095Ssam syncop = BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD; 774171095Ssam break; 775171095Ssam 776173139Srwatson default: 777171095Ssam syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREWRITE; 778171095Ssam break; 779171095Ssam } 780171095Ssam bus_dmamap_sync(dmah.dma_tag, dmah.dma_map, syncop); 781171095Ssam return; 782171095Ssam} 783171095Ssam 784171095Ssam#endif /* XGE_OSDEP_H */ 785173139Srwatson 786