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(&current_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