]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/nxge/xge-osdep.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / dev / nxge / xge-osdep.h
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$
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
104 typedef 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
110 typedef 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
120 typedef 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
125 typedef 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
144 typedef bus_addr_t                 dma_addr_t;
145 typedef struct mtx                 spinlock_t;
146 typedef xge_pci_info_t             *pci_dev_h;
147 typedef xge_bus_resource_t         *pci_reg_h;
148 typedef xge_dma_alloc_t             pci_dma_h;
149 typedef xge_dma_alloc_t             pci_dma_acc_h;
150 typedef struct resource            *pci_irq_h;
151 typedef 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 #if __FreeBSD_version > 800053
246 /* Write memory barrier */
247 #define xge_os_wmb()            wmb()   
248 #else
249 #define xge_os_wmb()
250 #endif
251
252 /* Delay (in micro seconds) */
253 #define xge_os_udelay(us)            DELAY(us)
254
255 /* Delay (in milli seconds) */
256 #define xge_os_mdelay(ms)            DELAY(ms * 1000)
257
258 /* Compare and exchange */
259 //#define xge_os_cmpxchg(targetp, cmd, newval)
260
261 /**
262  * Misc primitives
263  */
264 #define xge_os_unlikely(x)    (x)
265 #define xge_os_prefetch(x)    (x=x)
266 #define xge_os_prefetchw(x)   (x=x)
267 #define xge_os_bug(fmt...)    printf(fmt)
268 #define xge_os_htohs          ntohs
269 #define xge_os_ntohl          ntohl
270 #define xge_os_htons          htons
271 #define xge_os_htonl          htonl
272
273 /**
274  * Compiler Stuffs
275  */
276 #define __xge_os_attr_cacheline_aligned
277 #define __xge_os_cacheline_size        32
278
279 /**
280  * Memory Primitives
281  */
282 #define XGE_OS_INVALID_DMA_ADDR ((dma_addr_t)0)
283
284 /**
285  * xge_os_malloc
286  * Allocate non DMA-able memory.
287  * @pdev: Device context.
288  * @size: Size to allocate.
289  *
290  * Allocate @size bytes of memory. This allocation can sleep, and therefore,
291  * and therefore it requires process context. In other words, xge_os_malloc()
292  * cannot be called from the interrupt context. Use xge_os_free() to free the
293  * allocated block.
294  *
295  * Returns: Pointer to allocated memory, NULL - on failure.
296  *
297  * See also: xge_os_free().
298  */
299 static inline void *
300 xge_os_malloc(pci_dev_h pdev, unsigned long size) {
301         void *vaddr = malloc((size), M_DEVBUF, M_NOWAIT | M_ZERO);
302         if(vaddr != NULL) {
303             XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, __FILE__, __LINE__);
304             xge_os_memzero(vaddr, size);
305         }
306         return (vaddr);
307 }
308
309 /**
310  * xge_os_free
311  * Free non DMA-able memory.
312  * @pdev: Device context.
313  * @vaddr: Address of the allocated memory block.
314  * @size: Some OS's require to provide size on free
315  *
316  * Free the memory area obtained via xge_os_malloc(). This call may also sleep,
317  * and therefore it cannot be used inside interrupt.
318  *
319  * See also: xge_os_malloc().
320  */
321 static inline void
322 xge_os_free(pci_dev_h pdev, const void *vaddr, unsigned long size) {
323         XGE_OS_MEMORY_CHECK_FREE(vaddr, size);
324         free(__DECONST(void *, vaddr), M_DEVBUF);
325 }
326
327 static void
328 xge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) {
329         if(error) return;
330         *(bus_addr_t *) arg = segs->ds_addr;
331         return;
332 }
333
334 /**
335  * xge_os_dma_malloc
336  * Allocate DMA-able memory.
337  * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
338  * @size: Size (in bytes) to allocate.
339  * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, XGE_OS_DMA_STREAMING,
340  * XGE_OS_DMA_CONSISTENT (Note that the last two flags are mutually exclusive.)
341  * @p_dmah: Handle used to map the memory onto the corresponding device memory
342  * space. See xge_os_dma_map(). The handle is an out-parameter returned by the
343  * function.
344  * @p_dma_acch: One more DMA handle used subsequently to free the DMA object
345  * (via xge_os_dma_free()).
346  *
347  * Allocate DMA-able contiguous memory block of the specified @size. This memory
348  * can be subsequently freed using xge_os_dma_free().
349  * Note: can be used inside interrupt context.
350  *
351  * Returns: Pointer to allocated memory(DMA-able), NULL on failure.
352  */
353 static inline void *
354 xge_os_dma_malloc(pci_dev_h pdev, unsigned long size, int dma_flags,
355         pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch) {
356         int retValue = bus_dma_tag_create(
357             bus_get_dma_tag(pdev->device), /* Parent                          */
358             PAGE_SIZE,                     /* Alignment no specific alignment */
359             0,                             /* Bounds                          */
360             BUS_SPACE_MAXADDR,             /* Low Address                     */
361             BUS_SPACE_MAXADDR,             /* High Address                    */
362             NULL,                          /* Filter                          */
363             NULL,                          /* Filter arg                      */
364             size,                          /* Max Size                        */
365             1,                             /* n segments                      */
366             size,                          /* max segment size                */
367             BUS_DMA_ALLOCNOW,              /* Flags                           */
368             NULL,                          /* lockfunction                    */
369             NULL,                          /* lock arg                        */
370             &p_dmah->dma_tag);             /* DMA tag                         */
371         if(retValue != 0) {
372             xge_os_printf("bus_dma_tag_create failed\n")
373             goto fail_1;
374         }
375         p_dmah->dma_size = size;
376         retValue = bus_dmamem_alloc(p_dmah->dma_tag,
377             (void **)&p_dmah->dma_viraddr, BUS_DMA_NOWAIT, &p_dmah->dma_map);
378         if(retValue != 0) {
379             xge_os_printf("bus_dmamem_alloc failed\n")
380             goto fail_2;
381         }
382         XGE_OS_MEMORY_CHECK_MALLOC(p_dmah->dma_viraddr, p_dmah->dma_size,
383             __FILE__, __LINE__);
384         return(p_dmah->dma_viraddr);
385
386 fail_2: bus_dma_tag_destroy(p_dmah->dma_tag);
387 fail_1: return(NULL);
388 }
389
390 /**
391  * xge_os_dma_free
392  * Free previously allocated DMA-able memory.
393  * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
394  * @vaddr: Virtual address of the DMA-able memory.
395  * @p_dma_acch: DMA handle used to free the resource.
396  * @p_dmah: DMA handle used for mapping. See xge_os_dma_malloc().
397  *
398  * Free DMA-able memory originally allocated by xge_os_dma_malloc().
399  * Note: can be used inside interrupt.
400  * See also: xge_os_dma_malloc().
401  */
402 static inline void
403 xge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size,
404         pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah)
405 {
406         XGE_OS_MEMORY_CHECK_FREE(p_dmah->dma_viraddr, size);
407         bus_dmamem_free(p_dmah->dma_tag, p_dmah->dma_viraddr, p_dmah->dma_map);
408         bus_dma_tag_destroy(p_dmah->dma_tag);
409         p_dmah->dma_map = NULL;
410         p_dmah->dma_tag = NULL;
411         p_dmah->dma_viraddr = NULL;
412         return;
413 }
414
415 /**
416  * IO/PCI/DMA Primitives
417  */
418 #define XGE_OS_DMA_DIR_TODEVICE        0
419 #define XGE_OS_DMA_DIR_FROMDEVICE      1
420 #define XGE_OS_DMA_DIR_BIDIRECTIONAL   2
421
422 /**
423  * xge_os_pci_read8
424  * Read one byte from device PCI configuration.
425  * @pdev: Device context. Some OSs require device context to perform PIO and/or
426  * config space IO.
427  * @cfgh: PCI configuration space handle.
428  * @where: Offset in the PCI configuration space.
429  * @val: Address of the result.
430  *
431  * Read byte value from the specified @regh PCI configuration space at the
432  * specified offset = @where.
433  * Returns: 0 - success, non-zero - failure.
434  */
435 #define xge_os_pci_read8(pdev, cfgh, where, val)                               \
436         (*(val) = pci_read_config(pdev->device, where, 1))
437
438 /**
439  * xge_os_pci_write8
440  * Write one byte into device PCI configuration.
441  * @pdev: Device context. Some OSs require device context to perform PIO and/or
442  * config space IO.
443  * @cfgh: PCI configuration space handle.
444  * @where: Offset in the PCI configuration space.
445  * @val: Value to write.
446  *
447  * Write byte value into the specified PCI configuration space
448  * Returns: 0 - success, non-zero - failure.
449  */
450 #define xge_os_pci_write8(pdev, cfgh, where, val)                              \
451         pci_write_config(pdev->device, where, val, 1)
452
453 /**
454  * xge_os_pci_read16
455  * Read 16bit word from device PCI configuration.
456  * @pdev: Device context.
457  * @cfgh: PCI configuration space handle.
458  * @where: Offset in the PCI configuration space.
459  * @val: Address of the 16bit result.
460  *
461  * Read 16bit value from the specified PCI configuration space at the
462  * specified offset.
463  * Returns: 0 - success, non-zero - failure.
464  */
465 #define xge_os_pci_read16(pdev, cfgh, where, val)                              \
466         (*(val) = pci_read_config(pdev->device, where, 2))
467
468 /**
469  * xge_os_pci_write16
470  * Write 16bit word into device PCI configuration.
471  * @pdev: Device context.
472  * @cfgh: PCI configuration space handle.
473  * @where: Offset in the PCI configuration space.
474  * @val: Value to write.
475  *
476  * Write 16bit value into the specified @offset in PCI configuration space.
477  * Returns: 0 - success, non-zero - failure.
478  */
479 #define xge_os_pci_write16(pdev, cfgh, where, val)                             \
480         pci_write_config(pdev->device, where, val, 2)
481
482 /**
483  * xge_os_pci_read32
484  * Read 32bit word from device PCI configuration.
485  * @pdev: Device context.
486  * @cfgh: PCI configuration space handle.
487  * @where: Offset in the PCI configuration space.
488  * @val: Address of 32bit result.
489  *
490  * Read 32bit value from the specified PCI configuration space at the
491  * specified offset.
492  * Returns: 0 - success, non-zero - failure.
493  */
494 #define xge_os_pci_read32(pdev, cfgh, where, val)                              \
495         (*(val) = pci_read_config(pdev->device, where, 4))
496
497 /**
498  * xge_os_pci_write32
499  * Write 32bit word into device PCI configuration.
500  * @pdev: Device context.
501  * @cfgh: PCI configuration space handle.
502  * @where: Offset in the PCI configuration space.
503  * @val: Value to write.
504  *
505  * Write 32bit value into the specified @offset in PCI configuration space.
506  * Returns: 0 - success, non-zero - failure.
507  */
508 #define xge_os_pci_write32(pdev, cfgh, where, val)                             \
509         pci_write_config(pdev->device, where, val, 4)
510
511 /**
512  * xge_os_pio_mem_read8
513  * Read 1 byte from device memory mapped space.
514  * @pdev: Device context.
515  * @regh: PCI configuration space handle.
516  * @addr: Address in device memory space.
517  *
518  * Returns: 1 byte value read from the specified (mapped) memory space address.
519  */
520 static inline u8
521 xge_os_pio_mem_read8(pci_dev_h pdev, pci_reg_h regh, void *addr)
522 {
523         bus_space_tag_t tag =
524             (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
525         bus_space_handle_t handle =
526             (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
527         caddr_t addrss = (caddr_t)
528             (((xge_bus_resource_t *)(regh))->bar_start_addr);
529
530         return bus_space_read_1(tag, handle, (caddr_t)(addr) - addrss);
531 }
532
533 /**
534  * xge_os_pio_mem_write8
535  * Write 1 byte into device memory mapped space.
536  * @pdev: Device context.
537  * @regh: PCI configuration space handle.
538  * @val: Value to write.
539  * @addr: Address in device memory space.
540  *
541  * Write byte value into the specified (mapped) device memory space.
542  */
543 static inline void
544 xge_os_pio_mem_write8(pci_dev_h pdev, pci_reg_h regh, u8 val, void *addr)
545 {
546         bus_space_tag_t tag =
547             (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
548         bus_space_handle_t handle =
549             (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
550         caddr_t addrss = (caddr_t)
551             (((xge_bus_resource_t *)(regh))->bar_start_addr);
552
553         bus_space_write_1(tag, handle, (caddr_t)(addr) - addrss, val);
554 }
555
556 /**
557  * xge_os_pio_mem_read16
558  * Read 16bit from device memory mapped space.
559  * @pdev: Device context.
560  * @regh: PCI configuration space handle.
561  * @addr: Address in device memory space.
562  *
563  * Returns: 16bit value read from the specified (mapped) memory space address.
564  */
565 static inline u16
566 xge_os_pio_mem_read16(pci_dev_h pdev, pci_reg_h regh, void *addr)
567 {
568         bus_space_tag_t tag =
569             (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
570         bus_space_handle_t handle =
571             (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
572         caddr_t addrss = (caddr_t)
573             (((xge_bus_resource_t *)(regh))->bar_start_addr);
574
575         return bus_space_read_2(tag, handle, (caddr_t)(addr) - addrss);
576 }
577
578 /**
579  * xge_os_pio_mem_write16
580  * Write 16bit into device memory mapped space.
581  * @pdev: Device context.
582  * @regh: PCI configuration space handle.
583  * @val: Value to write.
584  * @addr: Address in device memory space.
585  *
586  * Write 16bit value into the specified (mapped) device memory space.
587  */
588 static inline void
589 xge_os_pio_mem_write16(pci_dev_h pdev, pci_reg_h regh, u16 val, void *addr)
590 {
591         bus_space_tag_t tag =
592             (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
593         bus_space_handle_t handle =
594             (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
595         caddr_t addrss = (caddr_t)(((xge_bus_resource_t *)(regh))->bar_start_addr);
596
597         bus_space_write_2(tag, handle, (caddr_t)(addr) - addrss, val);
598 }
599
600 /**
601  * xge_os_pio_mem_read32
602  * Read 32bit from device memory mapped space.
603  * @pdev: Device context.
604  * @regh: PCI configuration space handle.
605  * @addr: Address in device memory space.
606  *
607  * Returns: 32bit value read from the specified (mapped) memory space address.
608  */
609 static inline u32
610 xge_os_pio_mem_read32(pci_dev_h pdev, pci_reg_h regh, void *addr)
611 {
612         bus_space_tag_t tag =
613             (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
614         bus_space_handle_t handle =
615             (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
616         caddr_t addrss = (caddr_t)
617             (((xge_bus_resource_t *)(regh))->bar_start_addr);
618
619         return bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss);
620 }
621
622 /**
623  * xge_os_pio_mem_write32
624  * Write 32bit into device memory space.
625  * @pdev: Device context.
626  * @regh: PCI configuration space handle.
627  * @val: Value to write.
628  * @addr: Address in device memory space.
629  *
630  * Write 32bit value into the specified (mapped) device memory space.
631  */
632 static inline void
633 xge_os_pio_mem_write32(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr)
634 {
635         bus_space_tag_t tag =
636             (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
637         bus_space_handle_t handle =
638             (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
639         caddr_t addrss = (caddr_t)(((xge_bus_resource_t *)(regh))->bar_start_addr);
640         bus_space_write_4(tag, handle, (caddr_t)(addr) - addrss, val);
641 }
642
643 /**
644  * xge_os_pio_mem_read64
645  * Read 64bit from device memory mapped space.
646  * @pdev: Device context.
647  * @regh: PCI configuration space handle.
648  * @addr: Address in device memory space.
649  *
650  * Returns: 64bit value read from the specified (mapped) memory space address.
651  */
652 static inline u64
653 xge_os_pio_mem_read64(pci_dev_h pdev, pci_reg_h regh, void *addr)
654 {
655         u64 value1, value2;
656
657         bus_space_tag_t tag =
658             (bus_space_tag_t)(((xge_bus_resource_t *)regh)->bus_tag);
659         bus_space_handle_t handle =
660             (bus_space_handle_t)(((xge_bus_resource_t *)regh)->bus_handle);
661         caddr_t addrss = (caddr_t)
662             (((xge_bus_resource_t *)(regh))->bar_start_addr);
663
664         value1 = bus_space_read_4(tag, handle, (caddr_t)(addr) + 4 - addrss);
665         value1 <<= 32;
666         value2 = bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss);
667         value1 |= value2;
668         return value1;
669 }
670
671 /**
672  * xge_os_pio_mem_write64
673  * Write 32bit into device memory space.
674  * @pdev: Device context.
675  * @regh: PCI configuration space handle.
676  * @val: Value to write.
677  * @addr: Address in device memory space.
678  *
679  * Write 64bit value into the specified (mapped) device memory space.
680  */
681 static inline void
682 xge_os_pio_mem_write64(pci_dev_h pdev, pci_reg_h regh, u64 val, void *addr)
683 {
684         u32 vall = val & 0xffffffff;
685         xge_os_pio_mem_write32(pdev, regh, vall, addr);
686         xge_os_pio_mem_write32(pdev, regh, val >> 32, ((caddr_t)(addr) + 4));
687 }
688
689 /**
690  * FIXME: document
691  */
692 #define xge_os_flush_bridge    xge_os_pio_mem_read64
693
694 /**
695  * xge_os_dma_map
696  * Map DMA-able memory block to, or from, or to-and-from device.
697  * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
698  * @dmah: DMA handle used to map the memory block. Obtained via
699  * xge_os_dma_malloc().
700  * @vaddr: Virtual address of the DMA-able memory.
701  * @size: Size (in bytes) to be mapped.
702  * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
703  * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, XGE_OS_DMA_STREAMING,
704  * XGE_OS_DMA_CONSISTENT (Note that the last two flags are mutually exclusive).
705  *
706  * Map a single memory block.
707  *
708  * Returns: DMA address of the memory block, XGE_OS_INVALID_DMA_ADDR on failure.
709  *
710  * See also: xge_os_dma_malloc(), xge_os_dma_unmap(), xge_os_dma_sync().
711  */
712 static inline dma_addr_t
713 xge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah, void *vaddr, size_t size,
714         int dir, int dma_flags)
715 {
716         int retValue =
717             bus_dmamap_load(dmah.dma_tag, dmah.dma_map, dmah.dma_viraddr,
718             dmah.dma_size, xge_dmamap_cb, &dmah.dma_phyaddr, BUS_DMA_NOWAIT);
719         if(retValue != 0) {
720             xge_os_printf("bus_dmamap_load_ failed\n")
721             return XGE_OS_INVALID_DMA_ADDR;
722         }
723         dmah.dma_size = size;
724         return dmah.dma_phyaddr;
725 }
726
727 /**
728  * xge_os_dma_unmap - Unmap DMA-able memory.
729  * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
730  * @dmah: DMA handle used to map the memory block. Obtained via
731  * xge_os_dma_malloc().
732  * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map().
733  * @size: Size (in bytes) to be unmapped.
734  * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
735  *
736  * Unmap a single DMA-able memory block that was previously mapped using
737  * xge_os_dma_map().
738  * See also: xge_os_dma_malloc(), xge_os_dma_map().
739  */
740 static inline void
741 xge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr,
742         size_t size, int dir)
743 {
744         bus_dmamap_unload(dmah.dma_tag, dmah.dma_map);
745         return;
746 }
747
748 /**
749  * xge_os_dma_sync - Synchronize mapped memory.
750  * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory.
751  * @dmah: DMA handle used to map the memory block. Obtained via
752  * xge_os_dma_malloc().
753  * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map().
754  * @dma_offset: Offset from start of the blocke. Used by Solaris only.
755  * @length: Size of the block.
756  * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.)
757  *
758  * Make physical and CPU memory consistent for a single streaming mode DMA
759  * translation. This API compiles to NOP on cache-coherent platforms. On
760  * non cache-coherent platforms, depending on the direction of the "sync"
761  * operation, this API will effectively either invalidate CPU cache (that might
762  * contain old data), or flush CPU cache to update physical memory.
763  * See also: xge_os_dma_malloc(), xge_os_dma_map(),
764  * xge_os_dma_unmap().
765  */
766 static inline void
767 xge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr,
768         u64 dma_offset, size_t length, int dir)
769 {
770         bus_dmasync_op_t syncop;
771         switch(dir) {
772             case XGE_OS_DMA_DIR_TODEVICE:
773                 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTWRITE;
774                 break;
775
776             case XGE_OS_DMA_DIR_FROMDEVICE:
777                 syncop = BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD;
778                 break;
779
780             default:
781                 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREWRITE;
782                 break;
783         }
784         bus_dmamap_sync(dmah.dma_tag, dmah.dma_map, syncop);
785         return;
786 }
787
788 #endif /* XGE_OSDEP_H */
789