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