xge-osdep.h revision 267589
11558Srgrimes/*- 21558Srgrimes * Copyright (c) 2002-2007 Neterion, Inc. 31558Srgrimes * All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 141558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 151558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 181558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241558Srgrimes * SUCH DAMAGE. 251558Srgrimes * 261558Srgrimes * $FreeBSD: head/sys/dev/nxge/xge-osdep.h 267589 2014-06-17 18:10:06Z jhb $ 271558Srgrimes */ 281558Srgrimes 291558Srgrimes#ifndef XGE_OSDEP_H 301558Srgrimes#define XGE_OSDEP_H 311558Srgrimes 321558Srgrimes/** 331558Srgrimes * Includes and defines 34114589Sobrien */ 351558Srgrimes#include <sys/param.h> 367585Sbde#include <sys/systm.h> 371558Srgrimes#include <sys/mbuf.h> 381558Srgrimes#include <sys/protosw.h> 391558Srgrimes#include <sys/socket.h> 401558Srgrimes#include <sys/malloc.h> 411558Srgrimes#include <sys/kernel.h> 4241477Sjulian#include <sys/module.h> 43114589Sobrien#include <sys/bus.h> 4441477Sjulian#include <sys/lock.h> 4593103Smarkm#include <sys/mutex.h> 4693103Smarkm#include <sys/rman.h> 4793103Smarkm#include <sys/stddef.h> 481558Srgrimes#include <sys/types.h> 4955275Speter#include <sys/sockio.h> 5075557Smckusick#include <sys/proc.h> 511558Srgrimes#include <sys/mutex.h> 521558Srgrimes#include <sys/types.h> 5340918Smjacob#include <sys/endian.h> 5486514Siedowse#include <sys/sysctl.h> 5598542Smckusick#include <sys/endian.h> 5623675Speter#include <sys/socket.h> 571558Srgrimes#include <machine/bus.h> 5823675Speter#include <machine/resource.h> 591558Srgrimes#include <machine/clock.h> 6023675Speter#include <vm/vm.h> 6123675Speter#include <vm/pmap.h> 6255725Speter#include <dev/pci/pcivar.h> 631558Srgrimes#include <dev/pci/pcireg.h> 6455725Speter#include <dev/pci/pci_private.h> 65101037Smux#include <net/if.h> 6686514Siedowse#include <net/if_arp.h> 6723675Speter#include <net/ethernet.h> 681558Srgrimes#include <net/if_dl.h> 691558Srgrimes#include <net/if_media.h> 7092839Simp#include <net/if_var.h> 71100935Sphk#include <net/bpf.h> 7292839Simp#include <net/if_types.h> 7392839Simp#include <netinet/in_systm.h> 7423675Speter#include <netinet/in.h> 757585Sbde#include <netinet/ip.h> 7692839Simp#include <netinet/tcp.h> 771558Srgrimes 781558Srgrimes#define XGE_OS_PLATFORM_64BIT 7941474Sjulian 8066861Sadrian#if BYTE_ORDER == BIG_ENDIAN 811558Srgrimes#define XGE_OS_HOST_BIG_ENDIAN 821558Srgrimes#elif BYTE_ORDER == LITTLE_ENDIAN 8366861Sadrian#define XGE_OS_HOST_LITTLE_ENDIAN 8475927Smckusick#endif 851558Srgrimes 861558Srgrimes#define XGE_HAL_USE_5B_MODE 8766861Sadrian 881558Srgrimes#ifdef XGE_TRACE_ASSERT 891558Srgrimes#undef XGE_TRACE_ASSERT 901558Srgrimes#endif 911558Srgrimes 9274556Smckusick#define OS_NETSTACK_BUF struct mbuf * 9374556Smckusick#define XGE_LL_IP_FAST_CSUM(hdr, len) 0 9474556Smckusick 9574556Smckusick#ifndef __DECONST 961558Srgrimes#define __DECONST(type, var) ((type)(uintrptr_t)(const void *)(var)) 9766861Sadrian#endif 981558Srgrimes 9998542Smckusick#define xge_os_ntohs ntohs 10098542Smckusick#define xge_os_ntohl ntohl 10198542Smckusick#define xge_os_htons htons 1021558Srgrimes#define xge_os_htonl htonl 1038871Srgrimes 1041558Srgrimestypedef struct xge_bus_resource_t { 1051558Srgrimes bus_space_tag_t bus_tag; /* DMA Tag */ 1061558Srgrimes bus_space_handle_t bus_handle; /* Bus handle */ 1071558Srgrimes struct resource *bar_start_addr;/* BAR start address */ 1082153Sdg} xge_bus_resource_t; 10966861Sadrian 1102153Sdgtypedef struct xge_dma_alloc_t { 1112153Sdg bus_addr_t dma_phyaddr; /* Physical Address */ 11275927Smckusick caddr_t dma_viraddr; /* Virtual Address */ 11375927Smckusick bus_dma_tag_t dma_tag; /* DMA Tag */ 11475927Smckusick bus_dmamap_t dma_map; /* DMA Map */ 11575927Smckusick bus_dma_segment_t dma_segment; /* DMA Segment */ 1161558Srgrimes bus_size_t dma_size; /* Size */ 1171558Srgrimes int dma_nseg; /* Maximum scatter-gather segs. */ 1181558Srgrimes} xge_dma_alloc_t; 11923675Speter 1201558Srgrimestypedef struct xge_dma_mbuf_t { 1211558Srgrimes bus_addr_t dma_phyaddr; /* Physical Address */ 1221558Srgrimes bus_dmamap_t dma_map; /* DMA Map */ 1231558Srgrimes}xge_dma_mbuf_t; 1241558Srgrimes 1251558Srgrimestypedef struct xge_pci_info { 1261558Srgrimes device_t device; /* Device */ 1271558Srgrimes struct resource *regmap0; /* Resource for BAR0 */ 12866861Sadrian struct resource *regmap1; /* Resource for BAR1 */ 12966861Sadrian void *bar0resource; /* BAR0 tag and handle */ 13066861Sadrian void *bar1resource; /* BAR1 tag and handle */ 13166861Sadrian} xge_pci_info_t; 1321558Srgrimes 1331558Srgrimes 1341558Srgrimes/** 1351558Srgrimes * Fixed size primitive types 1361558Srgrimes */ 1371558Srgrimes#define u8 uint8_t 13866861Sadrian#define u16 uint16_t 1391558Srgrimes#define u32 uint32_t 1401558Srgrimes#define u64 uint64_t 1411558Srgrimes#define ulong_t unsigned long 1421558Srgrimes#define uint unsigned int 14366861Sadrian#define ptrdiff_t ptrdiff_t 14466861Sadriantypedef bus_addr_t dma_addr_t; 14566861Sadriantypedef struct mtx spinlock_t; 14666861Sadriantypedef xge_pci_info_t *pci_dev_h; 1471558Srgrimestypedef xge_bus_resource_t *pci_reg_h; 1481558Srgrimestypedef xge_dma_alloc_t pci_dma_h; 1491558Srgrimestypedef xge_dma_alloc_t pci_dma_acc_h; 1501558Srgrimestypedef struct resource *pci_irq_h; 15170050Siedowsetypedef xge_pci_info_t *pci_cfg_h; 15241474Sjulian 15341474Sjulian/** 154102231Strhodes * "libc" functionality 15541474Sjulian */ 15641474Sjulian#define xge_os_memzero(addr, size) bzero(addr, size) 15741474Sjulian#define xge_os_memcpy(dst, src, size) bcopy(src, dst, size) 15841474Sjulian#define xge_os_memcmp memcmp 15941474Sjulian#define xge_os_strcpy strcpy 16066861Sadrian#define xge_os_strlen strlen 16186514Siedowse#define xge_os_snprintf snprintf 16241474Sjulian#define xge_os_sprintf sprintf 1631558Srgrimes#define xge_os_printf(fmt...) { \ 16466861Sadrian printf(fmt); \ 1651558Srgrimes printf("\n"); \ 1661558Srgrimes} 1671558Srgrimes 16823675Speter#define xge_os_vaprintf(fmt) { \ 169100935Sphk sprintf(fmt, fmt, "\n"); \ 1701558Srgrimes va_list va; \ 1711558Srgrimes va_start(va, fmt); \ 1721558Srgrimes vprintf(fmt, va); \ 1731558Srgrimes va_end(va); \ 1741558Srgrimes} 1751558Srgrimes 17623675Speter#define xge_os_vasprintf(buf, fmt) { \ 1771558Srgrimes va_list va; \ 1781558Srgrimes va_start(va, fmt); \ 1791558Srgrimes (void) vaprintf(buf, fmt, va); \ 1801558Srgrimes va_end(va); \ 181102231Strhodes} 1821558Srgrimes 1831558Srgrimes#define xge_os_timestamp(buf) { \ 18423675Speter struct timeval current_time; \ 18592839Simp gettimeofday(¤t_time, 0); \ 1861558Srgrimes sprintf(buf, "%08li.%08li: ", current_time.tv_sec, \ 18798542Smckusick current_time.tv_usec); \ 18874556Smckusick} 1891558Srgrimes 19074556Smckusick#define xge_os_println xge_os_printf 1911558Srgrimes 19298542Smckusick/** 193101037Smux * Synchronization Primitives 19498542Smckusick */ 195101037Smux/* Initialize the spin lock */ 1961558Srgrimes#define xge_os_spin_lock_init(lockp, ctxh) { \ 1971558Srgrimes if(mtx_initialized(lockp) == 0) { \ 1981558Srgrimes mtx_init((lockp), "xge", NULL, MTX_DEF); \ 1991558Srgrimes } \ 20075927Smckusick} 20175927Smckusick 202102231Strhodes/* Initialize the spin lock (IRQ version) */ 20375927Smckusick#define xge_os_spin_lock_init_irq(lockp, ctxh) { \ 20475927Smckusick if(mtx_initialized(lockp) == 0) { \ 20575927Smckusick mtx_init((lockp), "xge", NULL, MTX_DEF); \ 20675927Smckusick } \ 20775927Smckusick} 20875927Smckusick 20975927Smckusick/* Destroy the lock */ 21075927Smckusick#define xge_os_spin_lock_destroy(lockp, ctxh) { \ 21175927Smckusick if(mtx_initialized(lockp) != 0) { \ 21275927Smckusick mtx_destroy(lockp); \ 21375927Smckusick } \ 21475927Smckusick} 21575927Smckusick 21675557Smckusick/* Destroy the lock (IRQ version) */ 21775927Smckusick#define xge_os_spin_lock_destroy_irq(lockp, ctxh) { \ 21875927Smckusick if(mtx_initialized(lockp) != 0) { \ 21975927Smckusick mtx_destroy(lockp); \ 22075927Smckusick } \ 22175927Smckusick} 22275927Smckusick 22375927Smckusick/* Acquire the lock */ 22475927Smckusick#define xge_os_spin_lock(lockp) { \ 22575927Smckusick if(mtx_owned(lockp) == 0) mtx_lock(lockp); \ 22675927Smckusick} 22775927Smckusick 22875927Smckusick/* Release the lock */ 22975927Smckusick#define xge_os_spin_unlock(lockp) { \ 23075927Smckusick mtx_unlock(lockp); \ 23175927Smckusick} 23275927Smckusick 23374556Smckusick/* Acquire the lock (IRQ version) */ 23474556Smckusick#define xge_os_spin_lock_irq(lockp, flags) { \ 235102231Strhodes flags = MTX_QUIET; \ 23674556Smckusick if(mtx_owned(lockp) == 0) mtx_lock_flags(lockp, flags); \ 23774556Smckusick} 23874556Smckusick 23974556Smckusick/* Release the lock (IRQ version) */ 24074556Smckusick#define xge_os_spin_unlock_irq(lockp, flags) { \ 24174556Smckusick flags = MTX_QUIET; \ 24274556Smckusick mtx_unlock_flags(lockp, flags); \ 24375557Smckusick} 24474556Smckusick 24574556Smckusick#if __FreeBSD_version > 800053 24675557Smckusick/* Write memory barrier */ 24775557Smckusick#define xge_os_wmb() wmb() 24874556Smckusick#else 24974556Smckusick#define xge_os_wmb() 25075557Smckusick#endif 25175557Smckusick 25275557Smckusick/* Delay (in micro seconds) */ 25375557Smckusick#define xge_os_udelay(us) DELAY(us) 25475557Smckusick 25575557Smckusick/* Delay (in milli seconds) */ 25675557Smckusick#define xge_os_mdelay(ms) DELAY(ms * 1000) 25775557Smckusick 25875557Smckusick/* Compare and exchange */ 25975557Smckusick//#define xge_os_cmpxchg(targetp, cmd, newval) 26075557Smckusick 261102231Strhodes/** 26275557Smckusick * Misc primitives 26375557Smckusick */ 26475557Smckusick#define xge_os_unlikely(x) (x) 26575557Smckusick#define xge_os_prefetch(x) (x=x) 26675557Smckusick#define xge_os_prefetchw(x) (x=x) 26775557Smckusick#define xge_os_bug(fmt...) printf(fmt) 26875557Smckusick#define xge_os_htohs ntohs 26975557Smckusick#define xge_os_ntohl ntohl 27075557Smckusick#define xge_os_htons htons 27175557Smckusick#define xge_os_htonl htonl 27274556Smckusick 27374556Smckusick/** 27474556Smckusick * Compiler Stuffs 27574556Smckusick */ 27674556Smckusick#define __xge_os_attr_cacheline_aligned 27774556Smckusick#define __xge_os_cacheline_size 32 27874556Smckusick 27974556Smckusick/** 28074556Smckusick * Memory Primitives 28175557Smckusick */ 28274556Smckusick#define XGE_OS_INVALID_DMA_ADDR ((dma_addr_t)0) 28374556Smckusick 28474556Smckusick/** 28574556Smckusick * xge_os_malloc 28674556Smckusick * Allocate non DMA-able memory. 28774556Smckusick * @pdev: Device context. 28874556Smckusick * @size: Size to allocate. 28974556Smckusick * 29023675Speter * Allocate @size bytes of memory. This allocation can sleep, and therefore, 29123675Speter * and therefore it requires process context. In other words, xge_os_malloc() 2921558Srgrimes * cannot be called from the interrupt context. Use xge_os_free() to free the 2931558Srgrimes * allocated block. 29441477Sjulian * 29523675Speter * Returns: Pointer to allocated memory, NULL - on failure. 29675557Smckusick * 29786514Siedowse * See also: xge_os_free(). 29886514Siedowse */ 299100935Sphkstatic inline void * 300100935Sphkxge_os_malloc(pci_dev_h pdev, unsigned long size) { 301100935Sphk void *vaddr = malloc((size), M_DEVBUF, M_NOWAIT | M_ZERO); 30241477Sjulian if(vaddr != NULL) { 30331904Sbde XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, __FILE__, __LINE__); 3042153Sdg xge_os_memzero(vaddr, size); 30555275Speter } 30655275Speter return (vaddr); 30734266Sjulian} 30834266Sjulian 30934266Sjulian/** 31034266Sjulian * xge_os_free 31134266Sjulian * Free non DMA-able memory. 3121558Srgrimes * @pdev: Device context. 3131558Srgrimes * @vaddr: Address of the allocated memory block. 3141558Srgrimes * @size: Some OS's require to provide size on free 3151558Srgrimes * 31674556Smckusick * Free the memory area obtained via xge_os_malloc(). This call may also sleep, 317102231Strhodes * and therefore it cannot be used inside interrupt. 3181558Srgrimes * 3191558Srgrimes * See also: xge_os_malloc(). 3201558Srgrimes */ 3211558Srgrimesstatic inline void 3221558Srgrimesxge_os_free(pci_dev_h pdev, const void *vaddr, unsigned long size) { 3231558Srgrimes XGE_OS_MEMORY_CHECK_FREE(vaddr, size); 3241558Srgrimes free(__DECONST(void *, vaddr), M_DEVBUF); 3251558Srgrimes} 32634266Sjulian 3271558Srgrimesstatic void 3281558Srgrimesxge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) { 3291558Srgrimes if(error) return; 3301558Srgrimes *(bus_addr_t *) arg = segs->ds_addr; 3311558Srgrimes return; 3321558Srgrimes} 3331558Srgrimes 3341558Srgrimes/** 3351558Srgrimes * xge_os_dma_malloc 3361558Srgrimes * Allocate DMA-able memory. 3371558Srgrimes * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 3381558Srgrimes * @size: Size (in bytes) to allocate. 3391558Srgrimes * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, XGE_OS_DMA_STREAMING, 3401558Srgrimes * XGE_OS_DMA_CONSISTENT (Note that the last two flags are mutually exclusive.) 3411558Srgrimes * @p_dmah: Handle used to map the memory onto the corresponding device memory 3421558Srgrimes * space. See xge_os_dma_map(). The handle is an out-parameter returned by the 3431558Srgrimes * function. 3441558Srgrimes * @p_dma_acch: One more DMA handle used subsequently to free the DMA object 3451558Srgrimes * (via xge_os_dma_free()). 3461558Srgrimes * 3471558Srgrimes * Allocate DMA-able contiguous memory block of the specified @size. This memory 3481558Srgrimes * can be subsequently freed using xge_os_dma_free(). 3491558Srgrimes * Note: can be used inside interrupt context. 3501558Srgrimes * 3511558Srgrimes * Returns: Pointer to allocated memory(DMA-able), NULL on failure. 3521558Srgrimes */ 3531558Srgrimesstatic inline void * 3541558Srgrimesxge_os_dma_malloc(pci_dev_h pdev, unsigned long size, int dma_flags, 3551558Srgrimes pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch) { 3561558Srgrimes int retValue = bus_dma_tag_create( 3571558Srgrimes bus_get_dma_tag(pdev->device), /* Parent */ 3581558Srgrimes PAGE_SIZE, /* Alignment no specific alignment */ 3591558Srgrimes 0, /* Bounds */ 3601558Srgrimes BUS_SPACE_MAXADDR, /* Low Address */ 3611558Srgrimes BUS_SPACE_MAXADDR, /* High Address */ 3621558Srgrimes NULL, /* Filter */ 3631558Srgrimes NULL, /* Filter arg */ 3641558Srgrimes size, /* Max Size */ 36574556Smckusick 1, /* n segments */ 36674556Smckusick size, /* max segment size */ 36774556Smckusick BUS_DMA_ALLOCNOW, /* Flags */ 36874556Smckusick NULL, /* lockfunction */ 36974556Smckusick NULL, /* lock arg */ 37074556Smckusick &p_dmah->dma_tag); /* DMA tag */ 37174556Smckusick if(retValue != 0) { 37274556Smckusick xge_os_printf("bus_dma_tag_create failed\n") 373100935Sphk goto fail_1; 374100935Sphk } 37574556Smckusick p_dmah->dma_size = size; 376101037Smux retValue = bus_dmamem_alloc(p_dmah->dma_tag, 377101037Smux (void **)&p_dmah->dma_viraddr, BUS_DMA_NOWAIT, &p_dmah->dma_map); 378101037Smux if(retValue != 0) { 379101037Smux xge_os_printf("bus_dmamem_alloc failed\n") 380101037Smux goto fail_2; 381101037Smux } 3821558Srgrimes XGE_OS_MEMORY_CHECK_MALLOC(p_dmah->dma_viraddr, p_dmah->dma_size, 38374556Smckusick __FILE__, __LINE__); 38474556Smckusick return(p_dmah->dma_viraddr); 38574556Smckusick 386100935Sphkfail_2: bus_dma_tag_destroy(p_dmah->dma_tag); 3871558Srgrimesfail_1: return(NULL); 3881558Srgrimes} 3891558Srgrimes 390100935Sphk/** 3911558Srgrimes * xge_os_dma_free 3921558Srgrimes * Free previously allocated DMA-able memory. 3931558Srgrimes * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 3941558Srgrimes * @vaddr: Virtual address of the DMA-able memory. 3951558Srgrimes * @p_dma_acch: DMA handle used to free the resource. 39631904Sbde * @p_dmah: DMA handle used for mapping. See xge_os_dma_malloc(). 3971558Srgrimes * 3981558Srgrimes * Free DMA-able memory originally allocated by xge_os_dma_malloc(). 3991558Srgrimes * Note: can be used inside interrupt. 4001558Srgrimes * See also: xge_os_dma_malloc(). 4011558Srgrimes */ 4021558Srgrimesstatic inline void 4031558Srgrimesxge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size, 4042179Sdg pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah) 40541474Sjulian{ 4061558Srgrimes XGE_OS_MEMORY_CHECK_FREE(p_dmah->dma_viraddr, size); 4071558Srgrimes bus_dmamem_free(p_dmah->dma_tag, p_dmah->dma_viraddr, p_dmah->dma_map); 4081558Srgrimes bus_dma_tag_destroy(p_dmah->dma_tag); 4098871Srgrimes p_dmah->dma_tag = NULL; 4101558Srgrimes p_dmah->dma_viraddr = NULL; 4111558Srgrimes return; 4121558Srgrimes} 4131558Srgrimes 41498542Smckusick/** 41598542Smckusick * IO/PCI/DMA Primitives 4161558Srgrimes */ 41734266Sjulian#define XGE_OS_DMA_DIR_TODEVICE 0 41834266Sjulian#define XGE_OS_DMA_DIR_FROMDEVICE 1 41955275Speter#define XGE_OS_DMA_DIR_BIDIRECTIONAL 2 42055725Speter 421102231Strhodes/** 42255725Speter * xge_os_pci_read8 42374556Smckusick * Read one byte from device PCI configuration. 42455275Speter * @pdev: Device context. Some OSs require device context to perform PIO and/or 42534266Sjulian * config space IO. 42641474Sjulian * @cfgh: PCI configuration space handle. 42741474Sjulian * @where: Offset in the PCI configuration space. 42841474Sjulian * @val: Address of the result. 42941474Sjulian * 43041474Sjulian * Read byte value from the specified @regh PCI configuration space at the 43141474Sjulian * specified offset = @where. 43241474Sjulian * Returns: 0 - success, non-zero - failure. 4331558Srgrimes */ 43418808Sguido#define xge_os_pci_read8(pdev, cfgh, where, val) \ 43518808Sguido (*(val) = pci_read_config(pdev->device, where, 1)) 43674556Smckusick 43755725Speter/** 438102231Strhodes * xge_os_pci_write8 43955725Speter * Write one byte into device PCI configuration. 44055725Speter * @pdev: Device context. Some OSs require device context to perform PIO and/or 44155725Speter * config space IO. 44274556Smckusick * @cfgh: PCI configuration space handle. 44355725Speter * @where: Offset in the PCI configuration space. 44455725Speter * @val: Value to write. 44555725Speter * 44674556Smckusick * Write byte value into the specified PCI configuration space 44774556Smckusick * Returns: 0 - success, non-zero - failure. 44855725Speter */ 44955725Speter#define xge_os_pci_write8(pdev, cfgh, where, val) \ 45055725Speter pci_write_config(pdev->device, where, val, 1) 45174556Smckusick 45255725Speter/** 45341474Sjulian * xge_os_pci_read16 45441474Sjulian * Read 16bit word from device PCI configuration. 4551558Srgrimes * @pdev: Device context. 4561558Srgrimes * @cfgh: PCI configuration space handle. 4571558Srgrimes * @where: Offset in the PCI configuration space. 4581558Srgrimes * @val: Address of the 16bit result. 4591558Srgrimes * 4601558Srgrimes * Read 16bit value from the specified PCI configuration space at the 4611558Srgrimes * specified offset. 46255275Speter * Returns: 0 - success, non-zero - failure. 46355275Speter */ 46475927Smckusick#define xge_os_pci_read16(pdev, cfgh, where, val) \ 46555275Speter (*(val) = pci_read_config(pdev->device, where, 2)) 46655275Speter 46792839Simp/** 46855275Speter * xge_os_pci_write16 46955725Speter * Write 16bit word into device PCI configuration. 47055725Speter * @pdev: Device context. 471100935Sphk * @cfgh: PCI configuration space handle. 47275927Smckusick * @where: Offset in the PCI configuration space. 47375927Smckusick * @val: Value to write. 47455275Speter * 47575927Smckusick * Write 16bit value into the specified @offset in PCI configuration space. 47655275Speter * Returns: 0 - success, non-zero - failure. 47775927Smckusick */ 47875927Smckusick#define xge_os_pci_write16(pdev, cfgh, where, val) \ 47975927Smckusick pci_write_config(pdev->device, where, val, 2) 48075927Smckusick 48155275Speter/** 48255275Speter * xge_os_pci_read32 48375927Smckusick * Read 32bit word from device PCI configuration. 484100935Sphk * @pdev: Device context. 485100935Sphk * @cfgh: PCI configuration space handle. 48655725Speter * @where: Offset in the PCI configuration space. 487100935Sphk * @val: Address of 32bit result. 48875927Smckusick * 48955725Speter * Read 32bit value from the specified PCI configuration space at the 49075927Smckusick * specified offset. 49175927Smckusick * Returns: 0 - success, non-zero - failure. 49275927Smckusick */ 49375927Smckusick#define xge_os_pci_read32(pdev, cfgh, where, val) \ 49475927Smckusick (*(val) = pci_read_config(pdev->device, where, 4)) 495100935Sphk 49655725Speter/** 49775927Smckusick * xge_os_pci_write32 49855275Speter * Write 32bit word into device PCI configuration. 49975927Smckusick * @pdev: Device context. 50075927Smckusick * @cfgh: PCI configuration space handle. 50155275Speter * @where: Offset in the PCI configuration space. 50266861Sadrian * @val: Value to write. 50366861Sadrian * 50492839Simp * Write 32bit value into the specified @offset in PCI configuration space. 50566861Sadrian * Returns: 0 - success, non-zero - failure. 50666861Sadrian */ 50795258Sdes#define xge_os_pci_write32(pdev, cfgh, where, val) \ 508102231Strhodes pci_write_config(pdev->device, where, val, 4) 50993103Smarkm 51066861Sadrian/** 51166861Sadrian * 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. 516 * 517 * Returns: 1 byte value read from the specified (mapped) memory space address. 518 */ 519static inline u8 520xge_os_pio_mem_read8(pci_dev_h pdev, pci_reg_h regh, void *addr) 521{ 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); 528 529 return bus_space_read_1(tag, handle, (caddr_t)(addr) - addrss); 530} 531 532/** 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. 539 * 540 * Write byte value into the specified (mapped) device memory space. 541 */ 542static inline void 543xge_os_pio_mem_write8(pci_dev_h pdev, pci_reg_h regh, u8 val, void *addr) 544{ 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); 551 552 bus_space_write_1(tag, handle, (caddr_t)(addr) - addrss, val); 553} 554 555/** 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. 561 * 562 * Returns: 16bit value read from the specified (mapped) memory space address. 563 */ 564static inline u16 565xge_os_pio_mem_read16(pci_dev_h pdev, pci_reg_h regh, void *addr) 566{ 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); 573 574 return bus_space_read_2(tag, handle, (caddr_t)(addr) - addrss); 575} 576 577/** 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. 584 * 585 * Write 16bit value into the specified (mapped) device memory space. 586 */ 587static inline void 588xge_os_pio_mem_write16(pci_dev_h pdev, pci_reg_h regh, u16 val, void *addr) 589{ 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); 595 596 bus_space_write_2(tag, handle, (caddr_t)(addr) - addrss, val); 597} 598 599/** 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. 605 * 606 * Returns: 32bit value read from the specified (mapped) memory space address. 607 */ 608static inline u32 609xge_os_pio_mem_read32(pci_dev_h pdev, pci_reg_h regh, void *addr) 610{ 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); 617 618 return bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss); 619} 620 621/** 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. 628 * 629 * Write 32bit value into the specified (mapped) device memory space. 630 */ 631static inline void 632xge_os_pio_mem_write32(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr) 633{ 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); 640} 641 642/** 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. 648 * 649 * Returns: 64bit value read from the specified (mapped) memory space address. 650 */ 651static inline u64 652xge_os_pio_mem_read64(pci_dev_h pdev, pci_reg_h regh, void *addr) 653{ 654 u64 value1, value2; 655 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); 662 663 value1 = bus_space_read_4(tag, handle, (caddr_t)(addr) + 4 - addrss); 664 value1 <<= 32; 665 value2 = bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss); 666 value1 |= value2; 667 return value1; 668} 669 670/** 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. 677 * 678 * Write 64bit value into the specified (mapped) device memory space. 679 */ 680static inline void 681xge_os_pio_mem_write64(pci_dev_h pdev, pci_reg_h regh, u64 val, void *addr) 682{ 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)); 686} 687 688/** 689 * FIXME: document 690 */ 691#define xge_os_flush_bridge xge_os_pio_mem_read64 692 693/** 694 * xge_os_dma_map 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). 704 * 705 * Map a single memory block. 706 * 707 * Returns: DMA address of the memory block, XGE_OS_INVALID_DMA_ADDR on failure. 708 * 709 * See also: xge_os_dma_malloc(), xge_os_dma_unmap(), xge_os_dma_sync(). 710 */ 711static inline dma_addr_t 712xge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah, void *vaddr, size_t size, 713 int dir, int dma_flags) 714{ 715 int retValue = 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); 718 if(retValue != 0) { 719 xge_os_printf("bus_dmamap_load_ failed\n") 720 return XGE_OS_INVALID_DMA_ADDR; 721 } 722 dmah.dma_size = size; 723 return dmah.dma_phyaddr; 724} 725 726/** 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.) 734 * 735 * Unmap a single DMA-able memory block that was previously mapped using 736 * xge_os_dma_map(). 737 * See also: xge_os_dma_malloc(), xge_os_dma_map(). 738 */ 739static inline void 740xge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr, 741 size_t size, int dir) 742{ 743 bus_dmamap_unload(dmah.dma_tag, dmah.dma_map); 744 return; 745} 746 747/** 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.) 756 * 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(). 764 */ 765static inline void 766xge_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) 768{ 769 bus_dmasync_op_t syncop; 770 switch(dir) { 771 case XGE_OS_DMA_DIR_TODEVICE: 772 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTWRITE; 773 break; 774 775 case XGE_OS_DMA_DIR_FROMDEVICE: 776 syncop = BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD; 777 break; 778 779 default: 780 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREWRITE; 781 break; 782 } 783 bus_dmamap_sync(dmah.dma_tag, dmah.dma_map, syncop); 784 return; 785} 786 787#endif /* XGE_OSDEP_H */ 788 789