xge-osdep.h revision 173139
1/*-
2 * Copyright (c) 2002-2007 Neterion, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/dev/nxge/xge-osdep.h 173139 2007-10-29 14:19:32Z rwatson $
27 */
28
29#ifndef XGE_OSDEP_H
30#define XGE_OSDEP_H
31
32/**
33 * Includes and defines
34 */
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/mbuf.h>
38#include <sys/protosw.h>
39#include <sys/socket.h>
40#include <sys/malloc.h>
41#include <sys/kernel.h>
42#include <sys/module.h>
43#include <sys/bus.h>
44#include <sys/lock.h>
45#include <sys/mutex.h>
46#include <sys/rman.h>
47#include <sys/stddef.h>
48#include <sys/types.h>
49#include <sys/sockio.h>
50#include <sys/proc.h>
51#include <sys/mutex.h>
52#include <sys/types.h>
53#include <sys/endian.h>
54#include <sys/sysctl.h>
55#include <sys/endian.h>
56#include <sys/socket.h>
57#include <machine/bus.h>
58#include <machine/resource.h>
59#include <machine/clock.h>
60#include <vm/vm.h>
61#include <vm/pmap.h>
62#include <dev/pci/pcivar.h>
63#include <dev/pci/pcireg.h>
64#include <dev/pci/pci_private.h>
65#include <net/if.h>
66#include <net/if_arp.h>
67#include <net/ethernet.h>
68#include <net/if_dl.h>
69#include <net/if_media.h>
70#include <net/if_var.h>
71#include <net/bpf.h>
72#include <net/if_types.h>
73#include <netinet/in_systm.h>
74#include <netinet/in.h>
75#include <netinet/ip.h>
76#include <netinet/tcp.h>
77
78#define XGE_OS_PLATFORM_64BIT
79
80#if BYTE_ORDER == BIG_ENDIAN
81#define XGE_OS_HOST_BIG_ENDIAN
82#elif BYTE_ORDER == LITTLE_ENDIAN
83#define XGE_OS_HOST_LITTLE_ENDIAN
84#endif
85
86#define XGE_HAL_USE_5B_MODE
87
88#ifdef XGE_TRACE_ASSERT
89#undef XGE_TRACE_ASSERT
90#endif
91
92#define OS_NETSTACK_BUF struct mbuf *
93#define XGE_LL_IP_FAST_CSUM(hdr, len)  0
94
95#ifndef __DECONST
96#define __DECONST(type, var)    ((type)(uintrptr_t)(const void *)(var))
97#endif
98
99#define xge_os_ntohs                    ntohs
100#define xge_os_ntohl                    ntohl
101#define xge_os_htons                    htons
102#define xge_os_htonl                    htonl
103
104typedef struct xge_bus_resource_t {
105	bus_space_tag_t       bus_tag;        /* DMA Tag                      */
106	bus_space_handle_t    bus_handle;     /* Bus handle                   */
107	struct resource       *bar_start_addr;/* BAR start address            */
108} xge_bus_resource_t;
109
110typedef struct xge_dma_alloc_t {
111	bus_addr_t            dma_phyaddr;    /* Physical Address             */
112	caddr_t               dma_viraddr;    /* Virtual Address              */
113	bus_dma_tag_t         dma_tag;        /* DMA Tag                      */
114	bus_dmamap_t          dma_map;        /* DMA Map                      */
115	bus_dma_segment_t     dma_segment;    /* DMA Segment                  */
116	bus_size_t            dma_size;       /* Size                         */
117	int                   dma_nseg;       /* Maximum scatter-gather segs. */
118} xge_dma_alloc_t;
119
120typedef struct xge_dma_mbuf_t {
121	bus_addr_t            dma_phyaddr;    /* Physical Address             */
122	bus_dmamap_t          dma_map;        /* DMA Map                      */
123}xge_dma_mbuf_t;
124
125typedef struct xge_pci_info {
126	device_t              device;         /* Device                       */
127	struct resource       *regmap0;       /* Resource for BAR0            */
128	struct resource       *regmap1;       /* Resource for BAR1            */
129	void                  *bar0resource;  /* BAR0 tag and handle          */
130	void                  *bar1resource;  /* BAR1 tag and handle          */
131} xge_pci_info_t;
132
133
134/**
135 * Fixed size primitive types
136 */
137#define u8                         uint8_t
138#define u16                        uint16_t
139#define u32                        uint32_t
140#define u64                        uint64_t
141#define ulong_t                    unsigned long
142#define uint                       unsigned int
143#define ptrdiff_t                  ptrdiff_t
144typedef bus_addr_t                 dma_addr_t;
145typedef struct mtx                 spinlock_t;
146typedef xge_pci_info_t             *pci_dev_h;
147typedef xge_bus_resource_t         *pci_reg_h;
148typedef xge_dma_alloc_t             pci_dma_h;
149typedef xge_dma_alloc_t             pci_dma_acc_h;
150typedef struct resource            *pci_irq_h;
151typedef xge_pci_info_t             *pci_cfg_h;
152
153/**
154 * "libc" functionality
155 */
156#define xge_os_memzero(addr, size)    bzero(addr, size)
157#define xge_os_memcpy(dst, src, size) bcopy(src, dst, size)
158#define xge_os_memcmp                 memcmp
159#define xge_os_strcpy                 strcpy
160#define xge_os_strlen                 strlen
161#define xge_os_snprintf               snprintf
162#define xge_os_sprintf                sprintf
163#define xge_os_printf(fmt...) {                                                \
164	printf(fmt);                                                           \
165	printf("\n");                                                          \
166}
167
168#define xge_os_vaprintf(fmt) {                                                 \
169	sprintf(fmt, fmt, "\n");                                               \
170	va_list va;                                                            \
171	va_start(va, fmt);                                                     \
172	vprintf(fmt, va);                                                      \
173	va_end(va);                                                            \
174}
175
176#define xge_os_vasprintf(buf, fmt) {                                           \
177	va_list va;                                                            \
178	va_start(va, fmt);                                                     \
179	(void) vaprintf(buf, fmt, va);                                         \
180	va_end(va);                                                            \
181}
182
183#define xge_os_timestamp(buf) {                                                \
184	struct timeval current_time;                                           \
185	gettimeofday(&current_time, 0);                                        \
186	sprintf(buf, "%08li.%08li: ", current_time.tv_sec,                     \
187	    current_time.tv_usec);                                             \
188}
189
190#define xge_os_println            xge_os_printf
191
192/**
193 * Synchronization Primitives
194 */
195/* Initialize the spin lock */
196#define xge_os_spin_lock_init(lockp, ctxh) {                                   \
197	if(mtx_initialized(lockp) == 0) {                                      \
198	    mtx_init((lockp), "xge", NULL, MTX_DEF);                           \
199	}                                                                      \
200}
201
202/* Initialize the spin lock (IRQ version) */
203#define xge_os_spin_lock_init_irq(lockp, ctxh) {                               \
204	if(mtx_initialized(lockp) == 0) {                                      \
205	    mtx_init((lockp), "xge", NULL, MTX_DEF);                           \
206	}                                                                      \
207}
208
209/* Destroy the lock */
210#define xge_os_spin_lock_destroy(lockp, ctxh) {                                \
211	if(mtx_initialized(lockp) != 0) {                                      \
212	    mtx_destroy(lockp);                                                \
213	}                                                                      \
214}
215
216/* Destroy the lock (IRQ version) */
217#define xge_os_spin_lock_destroy_irq(lockp, ctxh) {                            \
218	if(mtx_initialized(lockp) != 0) {                                      \
219	    mtx_destroy(lockp);                                                \
220	}                                                                      \
221}
222
223/* Acquire the lock */
224#define xge_os_spin_lock(lockp) {                                              \
225	if(mtx_owned(lockp) == 0) mtx_lock(lockp);                             \
226}
227
228/* Release the lock */
229#define xge_os_spin_unlock(lockp) {                                            \
230	mtx_unlock(lockp);                                                     \
231}
232
233/* Acquire the lock (IRQ version) */
234#define xge_os_spin_lock_irq(lockp, flags) {                                   \
235	flags = MTX_QUIET;                                                     \
236	if(mtx_owned(lockp) == 0) mtx_lock_flags(lockp, flags);                \
237}
238
239/* Release the lock (IRQ version) */
240#define xge_os_spin_unlock_irq(lockp, flags) {                                 \
241	flags = MTX_QUIET;                                                     \
242	mtx_unlock_flags(lockp, flags);                                        \
243}
244
245/* Write memory barrier */
246#define xge_os_wmb()
247
248/* Delay (in micro seconds) */
249#define xge_os_udelay(us)            DELAY(us)
250
251/* Delay (in milli seconds) */
252#define xge_os_mdelay(ms)            DELAY(ms * 1000)
253
254/* Compare and exchange */
255//#define xge_os_cmpxchg(targetp, cmd, newval)
256
257/**
258 * Misc primitives
259 */
260#define xge_os_unlikely(x)    (x)
261#define xge_os_prefetch(x)    (x=x)
262#define xge_os_prefetchw(x)   (x=x)
263#define xge_os_bug(fmt...)    printf(fmt)
264#define xge_os_htohs          ntohs
265#define xge_os_ntohl          ntohl
266#define xge_os_htons          htons
267#define xge_os_htonl          htonl
268
269/**
270 * Compiler Stuffs
271 */
272#define __xge_os_attr_cacheline_aligned
273#define __xge_os_cacheline_size        32
274
275/**
276 * Memory Primitives
277 */
278#define XGE_OS_INVALID_DMA_ADDR ((dma_addr_t)0)
279
280/**
281 * xge_os_malloc
282 * Allocate non DMA-able memory.
283 * @pdev: Device context.
284 * @size: Size to allocate.
285 *
286 * Allocate @size bytes of memory. This allocation can sleep, and therefore,
287 * and therefore it requires process context. In other words, xge_os_malloc()
288 * cannot be called from the interrupt context. Use xge_os_free() to free the
289 * allocated block.
290 *
291 * Returns: Pointer to allocated memory, NULL - on failure.
292 *
293 * See also: xge_os_free().
294 */
295static inline void *
296xge_os_malloc(pci_dev_h pdev, unsigned long size) {
297	void *vaddr = malloc((size), M_DEVBUF, M_NOWAIT | M_ZERO);
298	if(vaddr != NULL) {
299	    XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, __FILE__, __LINE__);
300	    xge_os_memzero(vaddr, size);
301	}
302	return (vaddr);
303}
304
305/**
306 * xge_os_free
307 * Free non DMA-able memory.
308 * @pdev: Device context.
309 * @vaddr: Address of the allocated memory block.
310 * @size: Some OS's require to provide size on free
311 *
312 * Free the memory area obtained via xge_os_malloc(). This call may also sleep,
313 * and therefore it cannot be used inside interrupt.
314 *
315 * See also: xge_os_malloc().
316 */
317static inline void
318xge_os_free(pci_dev_h pdev, const void *vaddr, unsigned long size) {
319	XGE_OS_MEMORY_CHECK_FREE(vaddr, size);
320	free(__DECONST(void *, vaddr), M_DEVBUF);
321}
322
323static void
324xge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) {
325	if(error) return;
326	*(bus_addr_t *) arg = segs->ds_addr;
327	return;
328}
329
330/**
331 * xge_os_dma_malloc
332 * Allocate DMA-able memory.
333 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
334 * @size: Size (in bytes) to allocate.
335 * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, XGE_OS_DMA_STREAMING,
336 * XGE_OS_DMA_CONSISTENT (Note that the last two flags are mutually exclusive.)
337 * @p_dmah: Handle used to map the memory onto the corresponding device memory
338 * space. See xge_os_dma_map(). The handle is an out-parameter returned by the
339 * function.
340 * @p_dma_acch: One more DMA handle used subsequently to free the DMA object
341 * (via xge_os_dma_free()).
342 *
343 * Allocate DMA-able contiguous memory block of the specified @size. This memory
344 * can be subsequently freed using xge_os_dma_free().
345 * Note: can be used inside interrupt context.
346 *
347 * Returns: Pointer to allocated memory(DMA-able), NULL on failure.
348 */
349static inline void *
350xge_os_dma_malloc(pci_dev_h pdev, unsigned long size, int dma_flags,
351	pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch) {
352	int retValue = bus_dma_tag_create(
353	    bus_get_dma_tag(pdev->device), /* Parent                          */
354	    PAGE_SIZE,                     /* Alignment no specific alignment */
355	    0,                             /* Bounds                          */
356	    BUS_SPACE_MAXADDR,             /* Low Address                     */
357	    BUS_SPACE_MAXADDR,             /* High Address                    */
358	    NULL,                          /* Filter                          */
359	    NULL,                          /* Filter arg                      */
360	    size,                          /* Max Size                        */
361	    1,                             /* n segments                      */
362	    size,                          /* max segment size                */
363	    BUS_DMA_ALLOCNOW,              /* Flags                           */
364	    NULL,                          /* lockfunction                    */
365	    NULL,                          /* lock arg                        */
366	    &p_dmah->dma_tag);             /* DMA tag                         */
367	if(retValue != 0) {
368	    xge_os_printf("bus_dma_tag_create failed\n")
369	    goto fail_1;
370	}
371	p_dmah->dma_size = size;
372	retValue = bus_dmamem_alloc(p_dmah->dma_tag,
373	    (void **)&p_dmah->dma_viraddr, BUS_DMA_NOWAIT, &p_dmah->dma_map);
374	if(retValue != 0) {
375	    xge_os_printf("bus_dmamem_alloc failed\n")
376	    goto fail_2;
377	}
378	XGE_OS_MEMORY_CHECK_MALLOC(p_dmah->dma_viraddr, p_dmah->dma_size,
379	    __FILE__, __LINE__);
380	return(p_dmah->dma_viraddr);
381
382fail_2: bus_dma_tag_destroy(p_dmah->dma_tag);
383fail_1: return(NULL);
384}
385
386/**
387 * xge_os_dma_free
388 * Free previously allocated DMA-able memory.
389 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
390 * @vaddr: Virtual address of the DMA-able memory.
391 * @p_dma_acch: DMA handle used to free the resource.
392 * @p_dmah: DMA handle used for mapping. See xge_os_dma_malloc().
393 *
394 * Free DMA-able memory originally allocated by xge_os_dma_malloc().
395 * Note: can be used inside interrupt.
396 * See also: xge_os_dma_malloc().
397 */
398static inline void
399xge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size,
400	pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah)
401{
402	XGE_OS_MEMORY_CHECK_FREE(p_dmah->dma_viraddr, size);
403	bus_dmamem_free(p_dmah->dma_tag, p_dmah->dma_viraddr, p_dmah->dma_map);
404	bus_dma_tag_destroy(p_dmah->dma_tag);
405	p_dmah->dma_map = NULL;
406	p_dmah->dma_tag = NULL;
407	p_dmah->dma_viraddr = NULL;
408	return;
409}
410
411/**
412 * IO/PCI/DMA Primitives
413 */
414#define XGE_OS_DMA_DIR_TODEVICE        0
415#define XGE_OS_DMA_DIR_FROMDEVICE      1
416#define XGE_OS_DMA_DIR_BIDIRECTIONAL   2
417
418/**
419 * xge_os_pci_read8
420 * Read one byte from device PCI configuration.
421 * @pdev: Device context. Some OSs require device context to perform PIO and/or
422 * config space IO.
423 * @cfgh: PCI configuration space handle.
424 * @where: Offset in the PCI configuration space.
425 * @val: Address of the result.
426 *
427 * Read byte value from the specified @regh PCI configuration space at the
428 * specified offset = @where.
429 * Returns: 0 - success, non-zero - failure.
430 */
431#define xge_os_pci_read8(pdev, cfgh, where, val)                               \
432	(*(val) = pci_read_config(pdev->device, where, 1))
433
434/**
435 * xge_os_pci_write8
436 * Write one byte into device PCI configuration.
437 * @pdev: Device context. Some OSs require device context to perform PIO and/or
438 * config space IO.
439 * @cfgh: PCI configuration space handle.
440 * @where: Offset in the PCI configuration space.
441 * @val: Value to write.
442 *
443 * Write byte value into the specified PCI configuration space
444 * Returns: 0 - success, non-zero - failure.
445 */
446#define xge_os_pci_write8(pdev, cfgh, where, val)                              \
447	pci_write_config(pdev->device, where, val, 1)
448
449/**
450 * xge_os_pci_read16
451 * Read 16bit word from device PCI configuration.
452 * @pdev: Device context.
453 * @cfgh: PCI configuration space handle.
454 * @where: Offset in the PCI configuration space.
455 * @val: Address of the 16bit result.
456 *
457 * Read 16bit value from the specified PCI configuration space at the
458 * specified offset.
459 * Returns: 0 - success, non-zero - failure.
460 */
461#define xge_os_pci_read16(pdev, cfgh, where, val)                              \
462	(*(val) = pci_read_config(pdev->device, where, 2))
463
464/**
465 * xge_os_pci_write16
466 * Write 16bit word into device PCI configuration.
467 * @pdev: Device context.
468 * @cfgh: PCI configuration space handle.
469 * @where: Offset in the PCI configuration space.
470 * @val: Value to write.
471 *
472 * Write 16bit value into the specified @offset in PCI configuration space.
473 * Returns: 0 - success, non-zero - failure.
474 */
475#define xge_os_pci_write16(pdev, cfgh, where, val)                             \
476	pci_write_config(pdev->device, where, val, 2)
477
478/**
479 * xge_os_pci_read32
480 * Read 32bit word from device PCI configuration.
481 * @pdev: Device context.
482 * @cfgh: PCI configuration space handle.
483 * @where: Offset in the PCI configuration space.
484 * @val: Address of 32bit result.
485 *
486 * Read 32bit value from the specified PCI configuration space at the
487 * specified offset.
488 * Returns: 0 - success, non-zero - failure.
489 */
490#define xge_os_pci_read32(pdev, cfgh, where, val)                              \
491	(*(val) = pci_read_config(pdev->device, where, 4))
492
493/**
494 * xge_os_pci_write32
495 * Write 32bit word into device PCI configuration.
496 * @pdev: Device context.
497 * @cfgh: PCI configuration space handle.
498 * @where: Offset in the PCI configuration space.
499 * @val: Value to write.
500 *
501 * Write 32bit value into the specified @offset in PCI configuration space.
502 * Returns: 0 - success, non-zero - failure.
503 */
504#define xge_os_pci_write32(pdev, cfgh, where, val)                             \
505	pci_write_config(pdev->device, where, val, 4)
506
507/**
508 * xge_os_pio_mem_read8
509 * Read 1 byte from device memory mapped space.
510 * @pdev: Device context.
511 * @regh: PCI configuration space handle.
512 * @addr: Address in device memory space.
513 *
514 * Returns: 1 byte value read from the specified (mapped) memory space address.
515 */
516static inline u8
517xge_os_pio_mem_read8(pci_dev_h pdev, pci_reg_h regh, void *addr)
518{
519	bus_space_tag_t tag =
520	    (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
521	bus_space_handle_t handle =
522	    (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
523	caddr_t addrss = (caddr_t)
524	    (((xge_bus_resource_t *)(regh))->bar_start_addr);
525
526	return bus_space_read_1(tag, handle, (caddr_t)(addr) - addrss);
527}
528
529/**
530 * xge_os_pio_mem_write8
531 * Write 1 byte into device memory mapped space.
532 * @pdev: Device context.
533 * @regh: PCI configuration space handle.
534 * @val: Value to write.
535 * @addr: Address in device memory space.
536 *
537 * Write byte value into the specified (mapped) device memory space.
538 */
539static inline void
540xge_os_pio_mem_write8(pci_dev_h pdev, pci_reg_h regh, u8 val, void *addr)
541{
542	bus_space_tag_t tag =
543	    (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
544	bus_space_handle_t handle =
545	    (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
546	caddr_t addrss = (caddr_t)
547	    (((xge_bus_resource_t *)(regh))->bar_start_addr);
548
549	bus_space_write_1(tag, handle, (caddr_t)(addr) - addrss, val);
550}
551
552/**
553 * xge_os_pio_mem_read16
554 * Read 16bit from device memory mapped space.
555 * @pdev: Device context.
556 * @regh: PCI configuration space handle.
557 * @addr: Address in device memory space.
558 *
559 * Returns: 16bit value read from the specified (mapped) memory space address.
560 */
561static inline u16
562xge_os_pio_mem_read16(pci_dev_h pdev, pci_reg_h regh, void *addr)
563{
564	bus_space_tag_t tag =
565	    (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
566	bus_space_handle_t handle =
567	    (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
568	caddr_t addrss = (caddr_t)
569	    (((xge_bus_resource_t *)(regh))->bar_start_addr);
570
571	return bus_space_read_2(tag, handle, (caddr_t)(addr) - addrss);
572}
573
574/**
575 * xge_os_pio_mem_write16
576 * Write 16bit into device memory mapped space.
577 * @pdev: Device context.
578 * @regh: PCI configuration space handle.
579 * @val: Value to write.
580 * @addr: Address in device memory space.
581 *
582 * Write 16bit value into the specified (mapped) device memory space.
583 */
584static inline void
585xge_os_pio_mem_write16(pci_dev_h pdev, pci_reg_h regh, u16 val, void *addr)
586{
587	bus_space_tag_t tag =
588	    (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
589	bus_space_handle_t handle =
590	    (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
591	caddr_t addrss = (caddr_t)(((xge_bus_resource_t *)(regh))->bar_start_addr);
592
593	bus_space_write_2(tag, handle, (caddr_t)(addr) - addrss, val);
594}
595
596/**
597 * xge_os_pio_mem_read32
598 * Read 32bit from device memory mapped space.
599 * @pdev: Device context.
600 * @regh: PCI configuration space handle.
601 * @addr: Address in device memory space.
602 *
603 * Returns: 32bit value read from the specified (mapped) memory space address.
604 */
605static inline u32
606xge_os_pio_mem_read32(pci_dev_h pdev, pci_reg_h regh, void *addr)
607{
608	bus_space_tag_t tag =
609	    (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
610	bus_space_handle_t handle =
611	    (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
612	caddr_t addrss = (caddr_t)
613	    (((xge_bus_resource_t *)(regh))->bar_start_addr);
614
615	return bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss);
616}
617
618/**
619 * xge_os_pio_mem_write32
620 * Write 32bit into device memory space.
621 * @pdev: Device context.
622 * @regh: PCI configuration space handle.
623 * @val: Value to write.
624 * @addr: Address in device memory space.
625 *
626 * Write 32bit value into the specified (mapped) device memory space.
627 */
628static inline void
629xge_os_pio_mem_write32(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr)
630{
631	bus_space_tag_t tag =
632	    (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
633	bus_space_handle_t handle =
634	    (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
635	caddr_t addrss = (caddr_t)(((xge_bus_resource_t *)(regh))->bar_start_addr);
636	bus_space_write_4(tag, handle, (caddr_t)(addr) - addrss, val);
637}
638
639/**
640 * xge_os_pio_mem_read64
641 * Read 64bit from device memory mapped space.
642 * @pdev: Device context.
643 * @regh: PCI configuration space handle.
644 * @addr: Address in device memory space.
645 *
646 * Returns: 64bit value read from the specified (mapped) memory space address.
647 */
648static inline u64
649xge_os_pio_mem_read64(pci_dev_h pdev, pci_reg_h regh, void *addr)
650{
651	u64 value1, value2;
652
653	bus_space_tag_t tag =
654	    (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
655	bus_space_handle_t handle =
656	    (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
657	caddr_t addrss = (caddr_t)
658	    (((xge_bus_resource_t *)(regh))->bar_start_addr);
659
660	value1 = bus_space_read_4(tag, handle, (caddr_t)(addr) + 4 - addrss);
661	value1 <<= 32;
662	value2 = bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss);
663	value1 |= value2;
664	return value1;
665}
666
667/**
668 * xge_os_pio_mem_write64
669 * Write 32bit into device memory space.
670 * @pdev: Device context.
671 * @regh: PCI configuration space handle.
672 * @val: Value to write.
673 * @addr: Address in device memory space.
674 *
675 * Write 64bit value into the specified (mapped) device memory space.
676 */
677static inline void
678xge_os_pio_mem_write64(pci_dev_h pdev, pci_reg_h regh, u64 val, void *addr)
679{
680	u32 vall = val & 0xffffffff;
681	xge_os_pio_mem_write32(pdev, regh, vall, addr);
682	xge_os_pio_mem_write32(pdev, regh, val >> 32, ((caddr_t)(addr) + 4));
683}
684
685/**
686 * FIXME: document
687 */
688#define xge_os_flush_bridge    xge_os_pio_mem_read64
689
690/**
691 * xge_os_dma_map
692 * Map DMA-able memory block to, or from, or to-and-from device.
693 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
694 * @dmah: DMA handle used to map the memory block. Obtained via
695 * xge_os_dma_malloc().
696 * @vaddr: Virtual address of the DMA-able memory.
697 * @size: Size (in bytes) to be mapped.
698 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
699 * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, XGE_OS_DMA_STREAMING,
700 * XGE_OS_DMA_CONSISTENT (Note that the last two flags are mutually exclusive).
701 *
702 * Map a single memory block.
703 *
704 * Returns: DMA address of the memory block, XGE_OS_INVALID_DMA_ADDR on failure.
705 *
706 * See also: xge_os_dma_malloc(), xge_os_dma_unmap(), xge_os_dma_sync().
707 */
708static inline dma_addr_t
709xge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah, void *vaddr, size_t size,
710	int dir, int dma_flags)
711{
712	int retValue =
713	    bus_dmamap_load(dmah.dma_tag, dmah.dma_map, dmah.dma_viraddr,
714	    dmah.dma_size, xge_dmamap_cb, &dmah.dma_phyaddr, BUS_DMA_NOWAIT);
715	if(retValue != 0) {
716	    xge_os_printf("bus_dmamap_load_ failed\n")
717	    return XGE_OS_INVALID_DMA_ADDR;
718	}
719	dmah.dma_size = size;
720	return dmah.dma_phyaddr;
721}
722
723/**
724 * xge_os_dma_unmap - Unmap DMA-able memory.
725 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
726 * @dmah: DMA handle used to map the memory block. Obtained via
727 * xge_os_dma_malloc().
728 * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map().
729 * @size: Size (in bytes) to be unmapped.
730 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
731 *
732 * Unmap a single DMA-able memory block that was previously mapped using
733 * xge_os_dma_map().
734 * See also: xge_os_dma_malloc(), xge_os_dma_map().
735 */
736static inline void
737xge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr,
738	size_t size, int dir)
739{
740	bus_dmamap_unload(dmah.dma_tag, dmah.dma_map);
741	return;
742}
743
744/**
745 * xge_os_dma_sync - Synchronize mapped memory.
746 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
747 * @dmah: DMA handle used to map the memory block. Obtained via
748 * xge_os_dma_malloc().
749 * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map().
750 * @dma_offset: Offset from start of the blocke. Used by Solaris only.
751 * @length: Size of the block.
752 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
753 *
754 * Make physical and CPU memory consistent for a single streaming mode DMA
755 * translation. This API compiles to NOP on cache-coherent platforms. On
756 * non cache-coherent platforms, depending on the direction of the "sync"
757 * operation, this API will effectively either invalidate CPU cache (that might
758 * contain old data), or flush CPU cache to update physical memory.
759 * See also: xge_os_dma_malloc(), xge_os_dma_map(),
760 * xge_os_dma_unmap().
761 */
762static inline void
763xge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr,
764	u64 dma_offset, size_t length, int dir)
765{
766	bus_dmasync_op_t syncop;
767	switch(dir) {
768	    case XGE_OS_DMA_DIR_TODEVICE:
769	        syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTWRITE;
770	        break;
771
772	    case XGE_OS_DMA_DIR_FROMDEVICE:
773	        syncop = BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD;
774	        break;
775
776	    default:
777	        syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREWRITE;
778	        break;
779	}
780	bus_dmamap_sync(dmah.dma_tag, dmah.dma_map, syncop);
781	return;
782}
783
784#endif /* XGE_OSDEP_H */
785
786