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