vxge-osdep.h revision 221167
1221167Sgnn/*-
2221167Sgnn * Copyright(c) 2002-2011 Exar Corp.
3221167Sgnn * All rights reserved.
4221167Sgnn *
5221167Sgnn * Redistribution and use in source and binary forms, with or without
6221167Sgnn * modification are permitted provided the following conditions are met:
7221167Sgnn *
8221167Sgnn *    1. Redistributions of source code must retain the above copyright notice,
9221167Sgnn *       this list of conditions and the following disclaimer.
10221167Sgnn *
11221167Sgnn *    2. Redistributions in binary form must reproduce the above copyright
12221167Sgnn *       notice, this list of conditions and the following disclaimer in the
13221167Sgnn *       documentation and/or other materials provided with the distribution.
14221167Sgnn *
15221167Sgnn *    3. Neither the name of the Exar Corporation nor the names of its
16221167Sgnn *       contributors may be used to endorse or promote products derived from
17221167Sgnn *       this software without specific prior written permission.
18221167Sgnn *
19221167Sgnn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20221167Sgnn * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21221167Sgnn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22221167Sgnn * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23221167Sgnn * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24221167Sgnn * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25221167Sgnn * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26221167Sgnn * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27221167Sgnn * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28221167Sgnn * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29221167Sgnn * POSSIBILITY OF SUCH DAMAGE.
30221167Sgnn */
31221167Sgnn/*$FreeBSD: head/sys/dev/vxge/vxge-osdep.h 221167 2011-04-28 14:33:15Z gnn $*/
32221167Sgnn
33221167Sgnn/* LINTLIBRARY */
34221167Sgnn
35221167Sgnn#ifndef	_VXGE_OSDEP_H_
36221167Sgnn#define	_VXGE_OSDEP_H_
37221167Sgnn
38221167Sgnn#include <sys/param.h>
39221167Sgnn#include <sys/systm.h>
40221167Sgnn
41221167Sgnn#if __FreeBSD_version >= 800000
42221167Sgnn#include <sys/buf_ring.h>
43221167Sgnn#endif
44221167Sgnn
45221167Sgnn#include <sys/mbuf.h>
46221167Sgnn#include <sys/protosw.h>
47221167Sgnn#include <sys/socket.h>
48221167Sgnn#include <sys/malloc.h>
49221167Sgnn#include <sys/kernel.h>
50221167Sgnn#include <sys/module.h>
51221167Sgnn#include <sys/bus.h>
52221167Sgnn#include <sys/sockio.h>
53221167Sgnn#include <sys/lock.h>
54221167Sgnn#include <sys/mutex.h>
55221167Sgnn#include <sys/rman.h>
56221167Sgnn#include <sys/stddef.h>
57221167Sgnn#include <sys/proc.h>
58221167Sgnn#include <sys/endian.h>
59221167Sgnn#include <sys/sysctl.h>
60221167Sgnn#include <sys/pcpu.h>
61221167Sgnn#include <sys/smp.h>
62221167Sgnn
63221167Sgnn#include <net/if.h>
64221167Sgnn#include <net/if_arp.h>
65221167Sgnn#include <net/bpf.h>
66221167Sgnn#include <net/ethernet.h>
67221167Sgnn#include <net/if_dl.h>
68221167Sgnn#include <net/if_media.h>
69221167Sgnn#include <net/if_types.h>
70221167Sgnn#include <net/if_var.h>
71221167Sgnn#include <net/if_vlan_var.h>
72221167Sgnn
73221167Sgnn#include <netinet/in_systm.h>
74221167Sgnn#include <netinet/in.h>
75221167Sgnn#include <netinet/if_ether.h>
76221167Sgnn#include <netinet/ip.h>
77221167Sgnn#include <netinet/ip6.h>
78221167Sgnn#include <netinet/tcp.h>
79221167Sgnn#include <netinet/tcp_lro.h>
80221167Sgnn#include <netinet/udp.h>
81221167Sgnn
82221167Sgnn#include <machine/bus.h>
83221167Sgnn#include <machine/resource.h>
84221167Sgnn#include <machine/clock.h>
85221167Sgnn#include <machine/stdarg.h>
86221167Sgnn#include <machine/in_cksum.h>
87221167Sgnn
88221167Sgnn#include <vm/vm.h>
89221167Sgnn#include <vm/pmap.h>
90221167Sgnn
91221167Sgnn#include <dev/pci/pcivar.h>
92221167Sgnn#include <dev/pci/pcireg.h>
93221167Sgnn#include <dev/pci/pci_private.h>
94221167Sgnn
95221167Sgnn#include <dev/vxge/include/vxge-defs.h>
96221167Sgnn
97221167Sgnn/*
98221167Sgnn * ------------------------- includes and defines -------------------------
99221167Sgnn */
100221167Sgnn
101221167Sgnn#if BYTE_ORDER == BIG_ENDIAN
102221167Sgnn#define	VXGE_OS_HOST_BIG_ENDIAN
103221167Sgnn#else
104221167Sgnn#define	VXGE_OS_HOST_LITTLE_ENDIAN
105221167Sgnn#endif
106221167Sgnn
107221167Sgnn#if __LONG_BIT == 64
108221167Sgnn#define	VXGE_OS_PLATFORM_64BIT
109221167Sgnn#else
110221167Sgnn#define	VXGE_OS_PLATFORM_32BIT
111221167Sgnn#endif
112221167Sgnn
113221167Sgnn#define	VXGE_OS_PCI_CONFIG_SIZE		256
114221167Sgnn#define	VXGE_OS_HOST_PAGE_SIZE		4096
115221167Sgnn#define	VXGE_LL_IP_FAST_CSUM(hdr, len)	0
116221167Sgnn
117221167Sgnn#ifndef	__DECONST
118221167Sgnn#define	__DECONST(type, var)	((type)(uintrptr_t)(const void *)(var))
119221167Sgnn#endif
120221167Sgnn
121221167Sgnntypedef struct ifnet *ifnet_t;
122221167Sgnntypedef struct mbuf *mbuf_t;
123221167Sgnntypedef struct mbuf *OS_NETSTACK_BUF;
124221167Sgnn
125221167Sgnntypedef struct _vxge_bus_res_t {
126221167Sgnn
127221167Sgnn	u_long			bus_res_len;
128221167Sgnn	bus_space_tag_t		bus_space_tag;		/* DMA Tag */
129221167Sgnn	bus_space_handle_t	bus_space_handle;	/* Bus handle */
130221167Sgnn	struct resource		*bar_start_addr;	/* BAR address */
131221167Sgnn
132221167Sgnn} vxge_bus_res_t;
133221167Sgnn
134221167Sgnntypedef struct _vxge_dma_alloc_t {
135221167Sgnn
136221167Sgnn	bus_addr_t		dma_paddr;		/* Physical Address */
137221167Sgnn	caddr_t			dma_vaddr;		/* Virtual Address */
138221167Sgnn	bus_dma_tag_t		dma_tag;		/* DMA Tag */
139221167Sgnn	bus_dmamap_t		dma_map;		/* DMA Map */
140221167Sgnn	bus_dma_segment_t	dma_segment;		/* DMA Segment */
141221167Sgnn	bus_size_t		dma_size;		/* Size */
142221167Sgnn	int			dma_nseg;		/* scatter-gather */
143221167Sgnn
144221167Sgnn} vxge_dma_alloc_t;
145221167Sgnn
146221167Sgnntypedef struct _vxge_pci_info {
147221167Sgnn
148221167Sgnn	device_t	ndev;		/* Device */
149221167Sgnn	void		*reg_map[3];	/* BAR Resource */
150221167Sgnn	struct resource	*bar_info[3];	/* BAR tag and handle */
151221167Sgnn
152221167Sgnn} vxge_pci_info_t;
153221167Sgnn
154221167Sgnn/*
155221167Sgnn * ---------------------- fixed size primitive types -----------------------
156221167Sgnn */
157221167Sgnntypedef size_t			ptr_t;
158221167Sgnntypedef int8_t			s8;
159221167Sgnntypedef uint8_t			u8;
160221167Sgnntypedef uint16_t		u16;
161221167Sgnntypedef int32_t			s32;
162221167Sgnntypedef uint32_t		u32;
163221167Sgnntypedef unsigned long long int	u64;
164221167Sgnntypedef boolean_t		bool;
165221167Sgnntypedef bus_addr_t		dma_addr_t;
166221167Sgnntypedef struct mtx		spinlock_t;
167221167Sgnntypedef struct resource		*pci_irq_h;
168221167Sgnntypedef vxge_pci_info_t		*pci_dev_h;
169221167Sgnntypedef vxge_pci_info_t		*pci_cfg_h;
170221167Sgnntypedef vxge_bus_res_t		*pci_reg_h;
171221167Sgnntypedef vxge_dma_alloc_t	pci_dma_h;
172221167Sgnntypedef vxge_dma_alloc_t	pci_dma_acc_h;
173221167Sgnn
174221167Sgnn/*
175221167Sgnn * -------------------------- "libc" functionality -------------------------
176221167Sgnn */
177221167Sgnn#define	vxge_os_curr_time		systime
178221167Sgnn#define	vxge_os_strcpy			strcpy
179221167Sgnn#define	vxge_os_strlcpy			strlcpy
180221167Sgnn#define	vxge_os_strlen			strlen
181221167Sgnn#define	vxge_os_sprintf			sprintf
182221167Sgnn#define	vxge_os_snprintf		snprintf
183221167Sgnn#define	vxge_os_println(buf)		printf("%s\n", buf)
184221167Sgnn#define	vxge_os_memzero			bzero
185221167Sgnn#define	vxge_os_memcmp			memcmp
186221167Sgnn#define	vxge_os_memcpy(dst, src, size)	bcopy(src, dst, size)
187221167Sgnn
188221167Sgnn#define	vxge_os_timestamp(buff) {			\
189221167Sgnn	struct timeval cur_time;			\
190221167Sgnn	gettimeofday(&cur_time, 0);			\
191221167Sgnn	snprintf(buff, sizeof(buff), "%08li.%08li: ",	\
192221167Sgnn		cur_time.tv_sec, cur_time.tv_usec);	\
193221167Sgnn}
194221167Sgnn
195221167Sgnn#define	vxge_os_printf(fmt...) {			\
196221167Sgnn	printf(fmt);					\
197221167Sgnn	printf("\n");					\
198221167Sgnn}
199221167Sgnn
200221167Sgnn#define	vxge_os_vaprintf(fmt...)			\
201221167Sgnn	vxge_os_printf(fmt);
202221167Sgnn
203221167Sgnn#define	vxge_os_vasprintf(fmt...) {			\
204221167Sgnn	vxge_os_printf(fmt);				\
205221167Sgnn}
206221167Sgnn
207221167Sgnn#define	vxge_trace(trace, fmt, args...)			\
208221167Sgnn	vxge_debug_uld(VXGE_COMPONENT_ULD,		\
209221167Sgnn		trace, hldev, vpid, fmt, ## args)
210221167Sgnn
211221167Sgnn/*
212221167Sgnn * -------------------- synchronization primitives -------------------------
213221167Sgnn */
214221167Sgnn/* Initialize the spin lock */
215221167Sgnn#define	vxge_os_spin_lock_init(lockp, ctxh) {			\
216221167Sgnn	if (mtx_initialized(lockp) == 0)			\
217221167Sgnn		mtx_init((lockp), "vxge", NULL, MTX_DEF);	\
218221167Sgnn}
219221167Sgnn
220221167Sgnn/* Initialize the spin lock (IRQ version) */
221221167Sgnn#define	vxge_os_spin_lock_init_irq(lockp, ctxh) {		\
222221167Sgnn	if (mtx_initialized(lockp) == 0)			\
223221167Sgnn		mtx_init((lockp), "vxge", NULL, MTX_DEF);	\
224221167Sgnn}
225221167Sgnn
226221167Sgnn/* Destroy the lock */
227221167Sgnn#define	vxge_os_spin_lock_destroy(lockp, ctxh) {		\
228221167Sgnn	if (mtx_initialized(lockp) != 0)			\
229221167Sgnn		mtx_destroy(lockp);				\
230221167Sgnn}
231221167Sgnn
232221167Sgnn/* Destroy the lock (IRQ version) */
233221167Sgnn#define	vxge_os_spin_lock_destroy_irq(lockp, ctxh) {		\
234221167Sgnn	if (mtx_initialized(lockp) != 0)			\
235221167Sgnn		mtx_destroy(lockp);				\
236221167Sgnn}
237221167Sgnn
238221167Sgnn/* Acquire the lock */
239221167Sgnn#define	vxge_os_spin_lock(lockp) {				\
240221167Sgnn	if (mtx_owned(lockp) == 0)				\
241221167Sgnn		mtx_lock(lockp);				\
242221167Sgnn}
243221167Sgnn
244221167Sgnn/* Release the lock */
245221167Sgnn#define	vxge_os_spin_unlock(lockp)	mtx_unlock(lockp)
246221167Sgnn
247221167Sgnn/* Acquire the lock (IRQ version) */
248221167Sgnn#define	vxge_os_spin_lock_irq(lockp, flags) {			\
249221167Sgnn	flags = MTX_QUIET;					\
250221167Sgnn	if (mtx_owned(lockp) == 0)				\
251221167Sgnn		mtx_lock_flags(lockp, flags);			\
252221167Sgnn}
253221167Sgnn
254221167Sgnn/* Release the lock (IRQ version) */
255221167Sgnn#define	vxge_os_spin_unlock_irq(lockp, flags) {			\
256221167Sgnn	flags = MTX_QUIET;					\
257221167Sgnn	mtx_unlock_flags(lockp, flags);				\
258221167Sgnn}
259221167Sgnn
260221167Sgnn/* Write memory	barrier	*/
261221167Sgnn#if __FreeBSD_version <	800000
262221167Sgnn#if defined(__i386__) || defined(__amd64__)
263221167Sgnn#define	mb()  __asm volatile("mfence" ::: "memory")
264221167Sgnn#define	wmb() __asm volatile("sfence" ::: "memory")
265221167Sgnn#define	rmb() __asm volatile("lfence" ::: "memory")
266221167Sgnn#else
267221167Sgnn#define	mb()
268221167Sgnn#define	rmb()
269221167Sgnn#define	wmb()
270221167Sgnn#endif
271221167Sgnn#endif
272221167Sgnn
273221167Sgnn#define	vxge_os_wmb()		wmb()
274221167Sgnn#define	vxge_os_udelay(x)	DELAY(x)
275221167Sgnn#define	vxge_os_stall(x)	DELAY(x)
276221167Sgnn#define	vxge_os_mdelay(x)	DELAY(x * 1000)
277221167Sgnn#define	vxge_os_xchg		(targetp, newval)
278221167Sgnn
279221167Sgnn/*
280221167Sgnn * ------------------------- misc primitives -------------------------------
281221167Sgnn */
282221167Sgnn#define	vxge_os_be32		u32
283221167Sgnn#define	vxge_os_unlikely(x)	(x)
284221167Sgnn#define	vxge_os_prefetch(x)	(x = x)
285221167Sgnn#define	vxge_os_prefetchw(x)	(x = x)
286221167Sgnn#define	vxge_os_bug		vxge_os_printf
287221167Sgnn
288221167Sgnn#define	vxge_os_ntohs		ntohs
289221167Sgnn#define	vxge_os_ntohl		ntohl
290221167Sgnn#define	vxge_os_ntohll		be64toh
291221167Sgnn
292221167Sgnn#define	vxge_os_htons		htons
293221167Sgnn#define	vxge_os_htonl		htonl
294221167Sgnn#define	vxge_os_htonll		htobe64
295221167Sgnn
296221167Sgnn#define	vxge_os_in_multicast		IN_MULTICAST
297221167Sgnn#define	VXGE_OS_INADDR_BROADCAST	INADDR_BROADCAST
298221167Sgnn/*
299221167Sgnn * -------------------------- compiler stuff ------------------------------
300221167Sgnn */
301221167Sgnn#define	__vxge_os_cacheline_size	CACHE_LINE_SIZE
302221167Sgnn#define	__vxge_os_attr_cacheline_aligned __aligned(__vxge_os_cacheline_size)
303221167Sgnn
304221167Sgnn/*
305221167Sgnn * ---------------------- memory primitives --------------------------------
306221167Sgnn */
307221167Sgnn#if defined(VXGE_OS_MEMORY_CHECK)
308221167Sgnn
309221167Sgnntypedef struct _vxge_os_malloc_t {
310221167Sgnn
311221167Sgnn	u_long		line;
312221167Sgnn	u_long		size;
313221167Sgnn	void		*ptr;
314221167Sgnn	const char	*file;
315221167Sgnn
316221167Sgnn} vxge_os_malloc_t;
317221167Sgnn
318221167Sgnn#define	VXGE_OS_MALLOC_CNT_MAX	64*1024
319221167Sgnn
320221167Sgnnextern u32 g_malloc_cnt;
321221167Sgnnextern vxge_os_malloc_t g_malloc_arr[VXGE_OS_MALLOC_CNT_MAX];
322221167Sgnn
323221167Sgnn#define	VXGE_OS_MEMORY_CHECK_MALLOC(_vaddr, _size, _file, _line) {	\
324221167Sgnn	if (_vaddr) {							\
325221167Sgnn		u32 i;							\
326221167Sgnn		for (i = 0; i < g_malloc_cnt; i++) {			\
327221167Sgnn			if (g_malloc_arr[i].ptr == NULL)		\
328221167Sgnn				break;					\
329221167Sgnn		}							\
330221167Sgnn		if (i == g_malloc_cnt) {				\
331221167Sgnn			g_malloc_cnt++;					\
332221167Sgnn			if (g_malloc_cnt >= VXGE_OS_MALLOC_CNT_MAX) {	\
333221167Sgnn				vxge_os_bug("g_malloc_cnt exceed %d\n",	\
334221167Sgnn				    VXGE_OS_MALLOC_CNT_MAX);		\
335221167Sgnn			} else {					\
336221167Sgnn				g_malloc_arr[i].ptr = _vaddr;		\
337221167Sgnn				g_malloc_arr[i].size = _size;		\
338221167Sgnn				g_malloc_arr[i].file = _file;		\
339221167Sgnn				g_malloc_arr[i].line = _line;		\
340221167Sgnn			}						\
341221167Sgnn		}							\
342221167Sgnn	}								\
343221167Sgnn}
344221167Sgnn
345221167Sgnn#define	VXGE_OS_MEMORY_CHECK_FREE(_vaddr, _size, _file, _line) {	\
346221167Sgnn	u32 i;								\
347221167Sgnn	for (i = 0; i < VXGE_OS_MALLOC_CNT_MAX; i++) {			\
348221167Sgnn		if (g_malloc_arr[i].ptr == _vaddr) {			\
349221167Sgnn			g_malloc_arr[i].ptr = NULL;			\
350221167Sgnn			if (_size && g_malloc_arr[i].size !=  _size) {	\
351221167Sgnn				vxge_os_printf("freeing wrong size "	\
352221167Sgnn				    "%lu allocated %s:%lu:"		\
353221167Sgnn				    VXGE_OS_LLXFMT":%lu\n",		\
354221167Sgnn				    _size,				\
355221167Sgnn				    g_malloc_arr[i].file,		\
356221167Sgnn				    g_malloc_arr[i].line,		\
357221167Sgnn				    (u64)(u_long) g_malloc_arr[i].ptr,	\
358221167Sgnn				    g_malloc_arr[i].size);		\
359221167Sgnn			}						\
360221167Sgnn			break;						\
361221167Sgnn		}							\
362221167Sgnn	}								\
363221167Sgnn}
364221167Sgnn
365221167Sgnn#else
366221167Sgnn#define	VXGE_OS_MEMORY_CHECK_MALLOC(prt, size, file, line)
367221167Sgnn#define	VXGE_OS_MEMORY_CHECK_FREE(vaddr, size, file, line)
368221167Sgnn#endif
369221167Sgnn
370221167Sgnnstatic inline void *
371221167Sgnnvxge_mem_alloc_ex(u_long size, const char *file, int line)
372221167Sgnn{
373221167Sgnn	void *vaddr = NULL;
374221167Sgnn	vaddr = malloc(size, M_DEVBUF, M_ZERO | M_NOWAIT);
375221167Sgnn	if (NULL != vaddr) {
376221167Sgnn		VXGE_OS_MEMORY_CHECK_MALLOC((void *)vaddr, size, file, line)
377221167Sgnn		vxge_os_memzero(vaddr, size);
378221167Sgnn	}
379221167Sgnn
380221167Sgnn	return (vaddr);
381221167Sgnn}
382221167Sgnn
383221167Sgnnstatic inline void
384221167Sgnnvxge_mem_free_ex(const void *vaddr, u_long size, const char *file, int line)
385221167Sgnn{
386221167Sgnn	if (NULL != vaddr) {
387221167Sgnn		VXGE_OS_MEMORY_CHECK_FREE(vaddr, size, file, line)
388221167Sgnn		free(__DECONST(void *, vaddr), M_DEVBUF);
389221167Sgnn	}
390221167Sgnn}
391221167Sgnn
392221167Sgnn#define	vxge_os_malloc(pdev, size)			\
393221167Sgnn	vxge_mem_alloc_ex(size, __FILE__, __LINE__)
394221167Sgnn
395221167Sgnn#define	vxge_os_free(pdev, vaddr, size)			\
396221167Sgnn	vxge_mem_free_ex(vaddr, size, __FILE__, __LINE__)
397221167Sgnn
398221167Sgnn#define	vxge_mem_alloc(size)				\
399221167Sgnn	vxge_mem_alloc_ex(size, __FILE__, __LINE__)
400221167Sgnn
401221167Sgnn#define	vxge_mem_free(vaddr, size)			\
402221167Sgnn	vxge_mem_free_ex(vaddr, size, __FILE__, __LINE__)
403221167Sgnn
404221167Sgnn#define	vxge_free_packet(x)				\
405221167Sgnn	if (NULL != x) { m_freem(x); x = NULL; }
406221167Sgnn
407221167Sgnn/*
408221167Sgnn * --------------------------- pci primitives ------------------------------
409221167Sgnn */
410221167Sgnn#define	vxge_os_pci_read8(pdev, cfgh, where, val)	\
411221167Sgnn	(*(val) = pci_read_config(pdev->ndev, where, 1))
412221167Sgnn
413221167Sgnn#define	vxge_os_pci_write8(pdev, cfgh, where, val)	\
414221167Sgnn	pci_write_config(pdev->ndev, where, val, 1)
415221167Sgnn
416221167Sgnn#define	vxge_os_pci_read16(pdev, cfgh, where, val)	\
417221167Sgnn	(*(val) = pci_read_config(pdev->ndev, where, 2))
418221167Sgnn
419221167Sgnn#define	vxge_os_pci_write16(pdev, cfgh, where, val)	\
420221167Sgnn	pci_write_config(pdev->ndev, where, val, 2)
421221167Sgnn
422221167Sgnn#define	vxge_os_pci_read32(pdev, cfgh, where, val)	\
423221167Sgnn	(*(val) = pci_read_config(pdev->ndev, where, 4))
424221167Sgnn
425221167Sgnn#define	vxge_os_pci_write32(pdev, cfgh, where, val)	\
426221167Sgnn	pci_write_config(pdev->ndev, where, val, 4)
427221167Sgnn
428221167Sgnnstatic inline u32
429221167Sgnnvxge_os_pci_res_len(pci_dev_h pdev, pci_reg_h regh)
430221167Sgnn{
431221167Sgnn	return (((vxge_bus_res_t *) regh)->bus_res_len);
432221167Sgnn}
433221167Sgnn
434221167Sgnnstatic inline u8
435221167Sgnnvxge_os_pio_mem_read8(pci_dev_h pdev, pci_reg_h regh, void *addr)
436221167Sgnn{
437221167Sgnn	caddr_t vaddr =
438221167Sgnn	    (caddr_t) (((vxge_bus_res_t *) (regh))->bar_start_addr);
439221167Sgnn
440221167Sgnn	return bus_space_read_1(((vxge_bus_res_t *) regh)->bus_space_tag,
441221167Sgnn				((vxge_bus_res_t *) regh)->bus_space_handle,
442221167Sgnn				(bus_size_t) ((caddr_t) (addr) - vaddr));
443221167Sgnn}
444221167Sgnn
445221167Sgnnstatic inline u16
446221167Sgnnvxge_os_pio_mem_read16(pci_dev_h pdev, pci_reg_h regh, void *addr)
447221167Sgnn{
448221167Sgnn	caddr_t vaddr =
449221167Sgnn	    (caddr_t) (((vxge_bus_res_t *) (regh))->bar_start_addr);
450221167Sgnn
451221167Sgnn	return bus_space_read_2(((vxge_bus_res_t *) regh)->bus_space_tag,
452221167Sgnn				((vxge_bus_res_t *) regh)->bus_space_handle,
453221167Sgnn				(bus_size_t) ((caddr_t) (addr) - vaddr));
454221167Sgnn}
455221167Sgnn
456221167Sgnnstatic inline u32
457221167Sgnnvxge_os_pio_mem_read32(pci_dev_h pdev, pci_reg_h regh, void *addr)
458221167Sgnn{
459221167Sgnn	caddr_t vaddr =
460221167Sgnn	    (caddr_t) (((vxge_bus_res_t *) (regh))->bar_start_addr);
461221167Sgnn
462221167Sgnn	return bus_space_read_4(((vxge_bus_res_t *) regh)->bus_space_tag,
463221167Sgnn				((vxge_bus_res_t *) regh)->bus_space_handle,
464221167Sgnn				(bus_size_t) ((caddr_t) (addr) - vaddr));
465221167Sgnn}
466221167Sgnn
467221167Sgnnstatic inline u64
468221167Sgnnvxge_os_pio_mem_read64(pci_dev_h pdev, pci_reg_h regh, void *addr)
469221167Sgnn{
470221167Sgnn	u64 val, val_l, val_u;
471221167Sgnn
472221167Sgnn	caddr_t vaddr =
473221167Sgnn	    (caddr_t) (((vxge_bus_res_t *) (regh))->bar_start_addr);
474221167Sgnn
475221167Sgnn	val_l = bus_space_read_4(((vxge_bus_res_t *) regh)->bus_space_tag,
476221167Sgnn				((vxge_bus_res_t *) regh)->bus_space_handle,
477221167Sgnn				(bus_size_t) (((caddr_t) addr) + 4 - vaddr));
478221167Sgnn
479221167Sgnn	val_u = bus_space_read_4(((vxge_bus_res_t *) regh)->bus_space_tag,
480221167Sgnn				((vxge_bus_res_t *) regh)->bus_space_handle,
481221167Sgnn				(bus_size_t) ((caddr_t) (addr) - vaddr));
482221167Sgnn
483221167Sgnn	val = ((val_l << 32) | val_u);
484221167Sgnn	return (val);
485221167Sgnn}
486221167Sgnn
487221167Sgnnstatic inline void
488221167Sgnnvxge_os_pio_mem_write8(pci_dev_h pdev, pci_reg_h regh, u8 val, void *addr)
489221167Sgnn{
490221167Sgnn	caddr_t vaddr =
491221167Sgnn	    (caddr_t) (((vxge_bus_res_t *) regh)->bar_start_addr);
492221167Sgnn
493221167Sgnn	bus_space_write_1(((vxge_bus_res_t *) regh)->bus_space_tag,
494221167Sgnn			((vxge_bus_res_t *) regh)->bus_space_handle,
495221167Sgnn			(bus_size_t) ((caddr_t) (addr) - vaddr), val);
496221167Sgnn}
497221167Sgnn
498221167Sgnnstatic inline void
499221167Sgnnvxge_os_pio_mem_write16(pci_dev_h pdev, pci_reg_h regh, u16 val, void *addr)
500221167Sgnn{
501221167Sgnn	caddr_t vaddr =
502221167Sgnn	    (caddr_t) (((vxge_bus_res_t *) (regh))->bar_start_addr);
503221167Sgnn
504221167Sgnn	bus_space_write_2(((vxge_bus_res_t *) regh)->bus_space_tag,
505221167Sgnn			((vxge_bus_res_t *) regh)->bus_space_handle,
506221167Sgnn			(bus_size_t) ((caddr_t) (addr) - vaddr), val);
507221167Sgnn}
508221167Sgnn
509221167Sgnnstatic inline void
510221167Sgnnvxge_os_pio_mem_write32(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr)
511221167Sgnn{
512221167Sgnn	caddr_t vaddr =
513221167Sgnn	    (caddr_t) (((vxge_bus_res_t *) (regh))->bar_start_addr);
514221167Sgnn
515221167Sgnn	bus_space_write_4(((vxge_bus_res_t *) regh)->bus_space_tag,
516221167Sgnn			((vxge_bus_res_t *) regh)->bus_space_handle,
517221167Sgnn			(bus_size_t) ((caddr_t) (addr) - vaddr), val);
518221167Sgnn}
519221167Sgnn
520221167Sgnnstatic inline void
521221167Sgnnvxge_os_pio_mem_write64(pci_dev_h pdev, pci_reg_h regh, u64 val, void *addr)
522221167Sgnn{
523221167Sgnn	u32 val_l = (u32) (val & 0xffffffff);
524221167Sgnn	u32 val_u = (u32) (val >> 32);
525221167Sgnn
526221167Sgnn	vxge_os_pio_mem_write32(pdev, regh, val_l, addr);
527221167Sgnn	vxge_os_pio_mem_write32(pdev, regh, val_u, (caddr_t) addr + 4);
528221167Sgnn}
529221167Sgnn
530221167Sgnn#define	vxge_os_flush_bridge	vxge_os_pio_mem_read64
531221167Sgnn
532221167Sgnn/*
533221167Sgnn * --------------------------- dma primitives -----------------------------
534221167Sgnn */
535221167Sgnn#define	VXGE_OS_DMA_DIR_TODEVICE	0
536221167Sgnn#define	VXGE_OS_DMA_DIR_FROMDEVICE	1
537221167Sgnn#define	VXGE_OS_DMA_DIR_BIDIRECTIONAL	2
538221167Sgnn#define	VXGE_OS_INVALID_DMA_ADDR	((bus_addr_t)0)
539221167Sgnn
540221167Sgnnstatic void
541221167Sgnnvxge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
542221167Sgnn{
543221167Sgnn	if (error)
544221167Sgnn		return;
545221167Sgnn
546221167Sgnn	*(bus_addr_t *) arg = segs->ds_addr;
547221167Sgnn}
548221167Sgnn
549221167Sgnnstatic inline void *
550221167Sgnnvxge_os_dma_malloc(pci_dev_h pdev, u_long bytes, int dma_flags,
551221167Sgnn    pci_dma_h * p_dmah, pci_dma_acc_h * p_dma_acch)
552221167Sgnn{
553221167Sgnn	int error = 0;
554221167Sgnn	bus_addr_t bus_addr = BUS_SPACE_MAXADDR;
555221167Sgnn	bus_size_t boundary, max_size, alignment = PAGE_SIZE;
556221167Sgnn
557221167Sgnn	if (bytes > PAGE_SIZE) {
558221167Sgnn		boundary = 0;
559221167Sgnn		max_size = bytes;
560221167Sgnn	} else {
561221167Sgnn		boundary = PAGE_SIZE;
562221167Sgnn		max_size = PAGE_SIZE;
563221167Sgnn	}
564221167Sgnn
565221167Sgnn	error = bus_dma_tag_create(
566221167Sgnn	    bus_get_dma_tag(pdev->ndev),	/* Parent */
567221167Sgnn	    alignment,				/* Alignment */
568221167Sgnn	    boundary,				/* Bounds */
569221167Sgnn	    bus_addr,				/* Low Address */
570221167Sgnn	    bus_addr,				/* High Address */
571221167Sgnn	    NULL,				/* Filter Func */
572221167Sgnn	    NULL,				/* Filter Func Argument */
573221167Sgnn	    bytes,				/* Maximum Size */
574221167Sgnn	    1,					/* Number of Segments */
575221167Sgnn	    max_size,				/* Maximum Segment Size */
576221167Sgnn	    BUS_DMA_ALLOCNOW,			/* Flags */
577221167Sgnn	    NULL,				/* Lock Func */
578221167Sgnn	    NULL,				/* Lock Func Arguments */
579221167Sgnn	    &(p_dmah->dma_tag));		/* DMA Tag */
580221167Sgnn
581221167Sgnn	if (error != 0) {
582221167Sgnn		device_printf(pdev->ndev, "bus_dma_tag_create failed\n");
583221167Sgnn		goto _exit0;
584221167Sgnn	}
585221167Sgnn
586221167Sgnn	p_dmah->dma_size = bytes;
587221167Sgnn	error = bus_dmamem_alloc(p_dmah->dma_tag, (void **)&p_dmah->dma_vaddr,
588221167Sgnn	    (BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT),
589221167Sgnn	    &p_dmah->dma_map);
590221167Sgnn	if (error != 0) {
591221167Sgnn		device_printf(pdev->ndev, "bus_dmamem_alloc failed\n");
592221167Sgnn		goto _exit1;
593221167Sgnn	}
594221167Sgnn
595221167Sgnn	VXGE_OS_MEMORY_CHECK_MALLOC(p_dmah->dma_vaddr, p_dmah->dma_size,
596221167Sgnn	    __FILE__, __LINE__);
597221167Sgnn
598221167Sgnn	return (p_dmah->dma_vaddr);
599221167Sgnn
600221167Sgnn_exit1:
601221167Sgnn	bus_dma_tag_destroy(p_dmah->dma_tag);
602221167Sgnn_exit0:
603221167Sgnn	return (NULL);
604221167Sgnn}
605221167Sgnn
606221167Sgnnstatic inline void
607221167Sgnnvxge_dma_free(pci_dev_h pdev, const void *vaddr, u_long size,
608221167Sgnn    pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch,
609221167Sgnn    const char *file, int line)
610221167Sgnn{
611221167Sgnn	VXGE_OS_MEMORY_CHECK_FREE(p_dmah->dma_vaddr, size, file, line)
612221167Sgnn
613221167Sgnn	bus_dmamem_free(p_dmah->dma_tag, p_dmah->dma_vaddr, p_dmah->dma_map);
614221167Sgnn	bus_dma_tag_destroy(p_dmah->dma_tag);
615221167Sgnn
616221167Sgnn	p_dmah->dma_map = NULL;
617221167Sgnn	p_dmah->dma_tag = NULL;
618221167Sgnn	p_dmah->dma_vaddr = NULL;
619221167Sgnn}
620221167Sgnn
621221167Sgnnextern void
622221167Sgnnvxge_hal_blockpool_block_add(void *, void *, u32, pci_dma_h *, pci_dma_acc_h *);
623221167Sgnn
624221167Sgnnstatic inline void
625221167Sgnnvxge_os_dma_malloc_async(pci_dev_h pdev, void *devh,
626221167Sgnn    u_long size, int dma_flags)
627221167Sgnn{
628221167Sgnn	pci_dma_h dma_h;
629221167Sgnn	pci_dma_acc_h acc_handle;
630221167Sgnn
631221167Sgnn	void *block_addr = NULL;
632221167Sgnn
633221167Sgnn	block_addr = vxge_os_dma_malloc(pdev, size, dma_flags,
634221167Sgnn	    &dma_h, &acc_handle);
635221167Sgnn
636221167Sgnn	vxge_hal_blockpool_block_add(devh, block_addr, size,
637221167Sgnn	    &dma_h, &acc_handle);
638221167Sgnn}
639221167Sgnn
640221167Sgnnstatic inline void
641221167Sgnnvxge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_paddr,
642221167Sgnn    u64 dma_offset, size_t length, int dir)
643221167Sgnn{
644221167Sgnn	bus_dmasync_op_t dmasync_op;
645221167Sgnn
646221167Sgnn	switch (dir) {
647221167Sgnn	case VXGE_OS_DMA_DIR_TODEVICE:
648221167Sgnn		dmasync_op = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTWRITE;
649221167Sgnn		break;
650221167Sgnn
651221167Sgnn	case VXGE_OS_DMA_DIR_FROMDEVICE:
652221167Sgnn		dmasync_op = BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD;
653221167Sgnn		break;
654221167Sgnn
655221167Sgnn	default:
656221167Sgnn	case VXGE_OS_DMA_DIR_BIDIRECTIONAL:
657221167Sgnn		dmasync_op = BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE;
658221167Sgnn		break;
659221167Sgnn	}
660221167Sgnn
661221167Sgnn	bus_dmamap_sync(dmah.dma_tag, dmah.dma_map, dmasync_op);
662221167Sgnn}
663221167Sgnn
664221167Sgnnstatic inline dma_addr_t
665221167Sgnnvxge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah, void *vaddr, u_long size,
666221167Sgnn		int dir, int dma_flags)
667221167Sgnn{
668221167Sgnn	int error;
669221167Sgnn
670221167Sgnn	error = bus_dmamap_load(dmah.dma_tag, dmah.dma_map, dmah.dma_vaddr,
671221167Sgnn	    dmah.dma_size, vxge_dmamap_cb, &(dmah.dma_paddr), BUS_DMA_NOWAIT);
672221167Sgnn
673221167Sgnn	if (error != 0)
674221167Sgnn		return (VXGE_OS_INVALID_DMA_ADDR);
675221167Sgnn
676221167Sgnn	dmah.dma_size = size;
677221167Sgnn	return (dmah.dma_paddr);
678221167Sgnn}
679221167Sgnn
680221167Sgnnstatic inline void
681221167Sgnnvxge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_paddr,
682221167Sgnn    u32 size, int dir)
683221167Sgnn{
684221167Sgnn	bus_dmamap_unload(dmah.dma_tag, dmah.dma_map);
685221167Sgnn}
686221167Sgnn
687221167Sgnn#define	vxge_os_dma_free(pdev, vaddr, size, dma_flags, p_dma_acch, p_dmah)  \
688221167Sgnn	vxge_dma_free(pdev, vaddr, size, p_dma_acch, p_dmah,		    \
689221167Sgnn		__FILE__, __LINE__)
690221167Sgnn
691221167Sgnnstatic inline int
692221167Sgnnvxge_os_is_my_packet(void *pdev, unsigned long addr)
693221167Sgnn{
694221167Sgnn	return (0);
695221167Sgnn}
696221167Sgnn
697221167Sgnn#endif /* _VXGE_OSDEP_H_ */
698