1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*
28 *  Copyright (c) 2002-2005 Neterion, Inc.
29 *  All right Reserved.
30 *
31 *  FileName :    xge_osdep.h
32 *
33 *  Description:  OSPAL - Solaris
34 *
35 */
36
37#ifndef _SYS_XGE_OSDEP_H
38#define	_SYS_XGE_OSDEP_H
39
40#include <sys/ddi.h>
41#include <sys/sunddi.h>
42#include <sys/varargs.h>
43#include <sys/atomic.h>
44#include <sys/policy.h>
45#include <sys/int_fmtio.h>
46#include <sys/thread.h>
47#include <sys/cpuvar.h>
48
49#include <inet/common.h>
50#include <inet/ip.h>
51#include <inet/mi.h>
52#include <inet/nd.h>
53
54#ifdef __cplusplus
55extern "C" {
56#endif
57
58/* ------------------------- includes and defines ------------------------- */
59
60#define	XGE_HAL_TX_MULTI_POST_IRQ	1
61#define	XGE_HAL_TX_MULTI_RESERVE_IRQ	1
62#define	XGE_HAL_TX_MULTI_FREE_IRQ	1
63#define	XGE_HAL_DMA_DTR_CONSISTENT	1
64#define	XGE_HAL_DMA_STATS_STREAMING	1
65
66#if defined(__sparc)
67#define	XGE_OS_DMA_REQUIRES_SYNC	1
68#endif
69
70#define	XGE_HAL_ALIGN_XMIT		1
71
72#ifdef _BIG_ENDIAN
73#define	XGE_OS_HOST_BIG_ENDIAN		1
74#else
75#define	XGE_OS_HOST_LITTLE_ENDIAN	1
76#endif
77
78#if defined(__sparc)
79#define	XGE_OS_HOST_PAGE_SIZE		8192
80#else
81#define	XGE_OS_HOST_PAGE_SIZE		4096
82#endif
83
84#if defined(_LP64)
85#define	XGE_OS_PLATFORM_64BIT		1
86#else
87#define	XGE_OS_PLATFORM_32BIT		1
88#endif
89
90#define	XGE_OS_HAS_SNPRINTF		1
91
92/* LRO defines */
93#define	XGE_LL_IP_FAST_CSUM(hdr, len)	0 /* ip_ocsum(hdr, len>>1, 0); */
94
95/* ---------------------- fixed size primitive types ----------------------- */
96
97#define	u8			uint8_t
98#define	u16			uint16_t
99#define	u32			uint32_t
100#define	u64			uint64_t
101typedef	u64			dma_addr_t;
102#define	ulong_t			ulong_t
103#define	ptrdiff_t		ptrdiff_t
104typedef	kmutex_t		spinlock_t;
105typedef dev_info_t		*pci_dev_h;
106typedef ddi_acc_handle_t	pci_reg_h;
107typedef ddi_acc_handle_t	pci_cfg_h;
108typedef uint_t			pci_irq_h;
109typedef ddi_dma_handle_t	pci_dma_h;
110typedef ddi_acc_handle_t	pci_dma_acc_h;
111
112/* LRO types */
113#define	OS_NETSTACK_BUF		mblk_t *
114#define	OS_LL_HEADER		uint8_t *
115#define	OS_IP_HEADER		uint8_t *
116#define	OS_TL_HEADER		uint8_t *
117
118/* -------------------------- "libc" functionality ------------------------- */
119
120#define	xge_os_strlcpy			(void) strlcpy
121#define	xge_os_strlen			strlen
122#define	xge_os_snprintf			snprintf
123#define	xge_os_memzero(addr, size)	bzero(addr, size)
124#define	xge_os_memcpy(dst, src, size)	bcopy(src, dst, size)
125#define	xge_os_memcmp(src1, src2, size)	bcmp(src1, src2, size)
126#define	xge_os_ntohl			ntohl
127#define	xge_os_htons			htons
128#define	xge_os_ntohs			ntohs
129
130#ifdef __GNUC__
131#define	xge_os_printf(fmt...)		cmn_err(CE_CONT, fmt)
132#define	xge_os_sprintf(buf, fmt...)	strlen(sprintf(buf, fmt))
133#else
134#define	xge_os_vaprintf(fmt) { \
135	va_list va; \
136	va_start(va, fmt); \
137	vcmn_err(CE_CONT, fmt, va); \
138	va_end(va); \
139}
140
141static inline void xge_os_printf(char *fmt, ...) {
142	xge_os_vaprintf(fmt);
143}
144
145#define	xge_os_vasprintf(buf, fmt) { \
146	va_list va; \
147	va_start(va, fmt); \
148	(void) vsprintf(buf, fmt, va); \
149	va_end(va); \
150}
151
152static inline int xge_os_sprintf(char *buf, char *fmt, ...) {
153	xge_os_vasprintf(buf, fmt);
154	return (strlen(buf));
155}
156#endif
157
158#define	xge_os_timestamp(buf) { \
159	todinfo_t todinfo = utc_to_tod(ddi_get_time()); \
160	(void) xge_os_sprintf(buf, "%02d/%02d/%02d.%02d:%02d:%02d: ", \
161	    todinfo.tod_day, todinfo.tod_month, \
162	    (1970 + todinfo.tod_year - 70), \
163	    todinfo.tod_hour, todinfo.tod_min, todinfo.tod_sec); \
164}
165
166#define	xge_os_println			xge_os_printf
167
168/* -------------------- synchronization primitives ------------------------- */
169
170#define	xge_os_spin_lock_init(lockp, ctxh) \
171	mutex_init(lockp, NULL, MUTEX_DRIVER, NULL)
172#define	xge_os_spin_lock_init_irq(lockp, irqh) \
173	mutex_init(lockp, NULL, MUTEX_DRIVER, DDI_INTR_PRI(irqh))
174#define	xge_os_spin_lock_destroy(lockp, cthx) \
175	(cthx = cthx, mutex_destroy(lockp))
176#define	xge_os_spin_lock_destroy_irq(lockp, cthx) \
177	(cthx = cthx, mutex_destroy(lockp))
178#define	xge_os_spin_lock(lockp)			mutex_enter(lockp)
179#define	xge_os_spin_unlock(lockp)		mutex_exit(lockp)
180#define	xge_os_spin_lock_irq(lockp, flags) (flags = flags, mutex_enter(lockp))
181#define	xge_os_spin_unlock_irq(lockp, flags)	mutex_exit(lockp)
182
183/* x86 arch will never re-order writes, Sparc can */
184#define	xge_os_wmb()				membar_producer()
185
186#define	xge_os_udelay(us)			drv_usecwait(us)
187#define	xge_os_mdelay(ms)			drv_usecwait(ms * 1000)
188
189#define	xge_os_cmpxchg(targetp, cmp, newval)		\
190	sizeof (*(targetp)) == 4 ?			\
191	atomic_cas_32((uint32_t *)targetp, cmp, newval) :	\
192	atomic_cas_64((uint64_t *)targetp, cmp, newval)
193
194/* ------------------------- misc primitives ------------------------------- */
195
196#define	xge_os_unlikely(x)		(x)
197#define	xge_os_prefetch(a)		(a = a)
198#define	xge_os_prefetchw
199#ifdef __GNUC__
200#define	xge_os_bug(fmt...)		cmn_err(CE_PANIC, fmt)
201#else
202static inline void xge_os_bug(char *fmt, ...) {
203	va_list ap;
204
205	va_start(ap, fmt);
206	vcmn_err(CE_PANIC, fmt, ap);
207	va_end(ap);
208}
209#endif
210
211/* -------------------------- compiler stuffs ------------------------------ */
212
213#if defined(__i386)
214#define	__xge_os_cacheline_size		64 /* L1-cache line size: x86_64 */
215#else
216#define	__xge_os_cacheline_size		64 /* L1-cache line size: sparcv9 */
217#endif
218
219#ifdef __GNUC__
220#define	__xge_os_attr_cacheline_aligned	\
221	__attribute__((__aligned__(__xge_os_cacheline_size)))
222#else
223#define	__xge_os_attr_cacheline_aligned
224#endif
225
226/* ---------------------- memory primitives -------------------------------- */
227
228static inline void *__xge_os_malloc(pci_dev_h pdev, unsigned long size,
229    char *file, int line)
230{
231	void *vaddr = kmem_alloc(size, KM_SLEEP);
232
233	XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, file, line);
234	return (vaddr);
235}
236
237static inline void xge_os_free(pci_dev_h pdev, const void *vaddr,
238    unsigned long size)
239{
240	XGE_OS_MEMORY_CHECK_FREE(vaddr, size);
241	kmem_free((void*)vaddr, size);
242}
243
244#define	xge_os_malloc(pdev, size) \
245	__xge_os_malloc(pdev, size, __FILE__, __LINE__)
246
247static inline void *__xge_os_dma_malloc(pci_dev_h pdev, unsigned long size,
248    int dma_flags, pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch, char *file,
249    int line)
250{
251	void *vaddr;
252	int ret;
253	size_t real_size;
254	extern ddi_device_acc_attr_t *p_xge_dev_attr;
255	extern struct ddi_dma_attr *p_hal_dma_attr;
256
257	ret = ddi_dma_alloc_handle(pdev, p_hal_dma_attr,
258	    DDI_DMA_DONTWAIT, 0, p_dmah);
259	if (ret != DDI_SUCCESS) {
260		return (NULL);
261	}
262
263	ret = ddi_dma_mem_alloc(*p_dmah, size, p_xge_dev_attr,
264	    (dma_flags & XGE_OS_DMA_CONSISTENT ?
265	    DDI_DMA_CONSISTENT : DDI_DMA_STREAMING), DDI_DMA_DONTWAIT, 0,
266	    (caddr_t *)&vaddr, &real_size, p_dma_acch);
267	if (ret != DDI_SUCCESS) {
268		ddi_dma_free_handle(p_dmah);
269		return (NULL);
270	}
271
272	if (size > real_size) {
273		ddi_dma_mem_free(p_dma_acch);
274		ddi_dma_free_handle(p_dmah);
275		return (NULL);
276	}
277
278	XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, file, line);
279
280	return (vaddr);
281}
282
283#define	xge_os_dma_malloc(pdev, size, dma_flags, p_dmah, p_dma_acch) \
284	__xge_os_dma_malloc(pdev, size, dma_flags, p_dmah, p_dma_acch, \
285	    __FILE__, __LINE__)
286
287static inline void xge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size,
288    pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah)
289{
290	XGE_OS_MEMORY_CHECK_FREE(vaddr, 0);
291	ddi_dma_mem_free(p_dma_acch);
292	ddi_dma_free_handle(p_dmah);
293}
294
295
296/* --------------------------- pci primitives ------------------------------ */
297
298#define	xge_os_pci_read8(pdev, cfgh, where, val)	\
299	(*(val) = pci_config_get8(cfgh, where))
300
301#define	xge_os_pci_write8(pdev, cfgh, where, val)	\
302	pci_config_put8(cfgh, where, val)
303
304#define	xge_os_pci_read16(pdev, cfgh, where, val)	\
305	(*(val) = pci_config_get16(cfgh, where))
306
307#define	xge_os_pci_write16(pdev, cfgh, where, val)	\
308	pci_config_put16(cfgh, where, val)
309
310#define	xge_os_pci_read32(pdev, cfgh, where, val)	\
311	(*(val) = pci_config_get32(cfgh, where))
312
313#define	xge_os_pci_write32(pdev, cfgh, where, val)	\
314	pci_config_put32(cfgh, where, val)
315
316/* --------------------------- io primitives ------------------------------- */
317
318#define	xge_os_pio_mem_read8(pdev, regh, addr)		\
319	(ddi_get8(regh, (uint8_t *)(addr)))
320
321#define	xge_os_pio_mem_write8(pdev, regh, val, addr)	\
322	(ddi_put8(regh, (uint8_t *)(addr), val))
323
324#define	xge_os_pio_mem_read16(pdev, regh, addr)		\
325	(ddi_get16(regh, (uint16_t *)(addr)))
326
327#define	xge_os_pio_mem_write16(pdev, regh, val, addr)	\
328	(ddi_put16(regh, (uint16_t *)(addr), val))
329
330#define	xge_os_pio_mem_read32(pdev, regh, addr)		\
331	(ddi_get32(regh, (uint32_t *)(addr)))
332
333#define	xge_os_pio_mem_write32(pdev, regh, val, addr)	\
334	(ddi_put32(regh, (uint32_t *)(addr), val))
335
336#define	xge_os_pio_mem_read64(pdev, regh, addr)		\
337	(ddi_get64(regh, (uint64_t *)(addr)))
338
339#define	xge_os_pio_mem_write64(pdev, regh, val, addr)	\
340	(ddi_put64(regh, (uint64_t *)(addr), val))
341
342#define	xge_os_flush_bridge xge_os_pio_mem_read64
343
344/* --------------------------- dma primitives ----------------------------- */
345
346#define	XGE_OS_DMA_DIR_TODEVICE		DDI_DMA_SYNC_FORDEV
347#define	XGE_OS_DMA_DIR_FROMDEVICE	DDI_DMA_SYNC_FORKERNEL
348#define	XGE_OS_DMA_DIR_BIDIRECTIONAL	-1
349#if defined(__x86)
350#define	XGE_OS_DMA_USES_IOMMU		0
351#else
352#define	XGE_OS_DMA_USES_IOMMU		1
353#endif
354
355#define	XGE_OS_INVALID_DMA_ADDR		((dma_addr_t)0)
356
357static inline dma_addr_t xge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah,
358    void *vaddr, size_t size, int dir, int dma_flags) {
359	int ret;
360	uint_t flags;
361	uint_t ncookies;
362	ddi_dma_cookie_t dma_cookie;
363
364	switch (dir) {
365	case XGE_OS_DMA_DIR_TODEVICE:
366		flags = DDI_DMA_WRITE;
367		break;
368	case XGE_OS_DMA_DIR_FROMDEVICE:
369		flags = DDI_DMA_READ;
370		break;
371	case XGE_OS_DMA_DIR_BIDIRECTIONAL:
372		flags = DDI_DMA_RDWR;
373		break;
374	default:
375		return (0);
376	}
377
378	flags |= (dma_flags & XGE_OS_DMA_CONSISTENT) ?
379	    DDI_DMA_CONSISTENT : DDI_DMA_STREAMING;
380
381	ret = ddi_dma_addr_bind_handle(dmah, NULL, vaddr, size, flags,
382	    DDI_DMA_SLEEP, 0, &dma_cookie, &ncookies);
383	if (ret != DDI_SUCCESS) {
384		return (0);
385	}
386
387	if (ncookies != 1 || dma_cookie.dmac_size < size) {
388		(void) ddi_dma_unbind_handle(dmah);
389		return (0);
390	}
391
392	return (dma_cookie.dmac_laddress);
393}
394
395static inline void xge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah,
396    dma_addr_t dma_addr, size_t size, int dir)
397{
398	(void) ddi_dma_unbind_handle(dmah);
399}
400
401static inline void xge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah,
402    dma_addr_t dma_addr, u64 dma_offset, size_t length, int dir)
403{
404	(void) ddi_dma_sync(dmah, dma_offset, length, dir);
405}
406
407#ifdef __cplusplus
408}
409#endif
410
411#endif /* _SYS_XGE_OSDEP_H */
412