xref: /illumos-gate/usr/src/uts/common/io/xge/drv/xge_osdep.h (revision 4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3)
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 2006 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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
41 
42 #include <sys/ddi.h>
43 #include <sys/sunddi.h>
44 #include <sys/varargs.h>
45 #include <sys/atomic.h>
46 #include <sys/policy.h>
47 #include <sys/int_fmtio.h>
48 #include <sys/thread.h>
49 #include <sys/cpuvar.h>
50 
51 #include <inet/common.h>
52 #include <inet/ip.h>
53 #include <inet/mi.h>
54 #include <inet/nd.h>
55 
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59 
60 #ifdef DEBUG
61 #define	XGE_DEBUG_ASSERT
62 #endif
63 
64 /* ------------------------- includes and defines ------------------------- */
65 
66 #define	XGE_HAL_TX_MULTI_POST_IRQ	1
67 #define	XGE_HAL_TX_MULTI_RESERVE_IRQ	1
68 #define	XGE_HAL_TX_MULTI_FREE_IRQ	1
69 #define	XGE_HAL_DMA_DTR_CONSISTENT	1
70 #define	XGE_HAL_DMA_STATS_STREAMING	1
71 
72 #if defined(__sparc)
73 #define	XGE_OS_DMA_REQUIRES_SYNC	1
74 #endif
75 
76 #define	XGE_HAL_ALIGN_XMIT		1
77 
78 #ifdef _BIG_ENDIAN
79 #define	XGE_OS_HOST_BIG_ENDIAN		1
80 #else
81 #define	XGE_OS_HOST_LITTLE_ENDIAN	1
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_HAL_CONFIG_LRO		0
94 #define	XGE_LL_IP_FAST_CSUM(hdr, len)	0 /* ip_ocsum(hdr, len>>1, 0); */
95 
96 /* ---------------------- fixed size primitive types ----------------------- */
97 
98 #define	u8			uint8_t
99 #define	u16			uint16_t
100 #define	u32			uint32_t
101 #define	u64			uint64_t
102 typedef	u64			dma_addr_t;
103 #define	ulong_t			ulong_t
104 #define	ptrdiff_t		ptrdiff_t
105 typedef	kmutex_t		spinlock_t;
106 typedef dev_info_t		*pci_dev_h;
107 typedef ddi_acc_handle_t	pci_reg_h;
108 typedef ddi_acc_handle_t	pci_cfg_h;
109 typedef ddi_iblock_cookie_t	pci_irq_h;
110 typedef ddi_dma_handle_t	pci_dma_h;
111 typedef ddi_acc_handle_t	pci_dma_acc_h;
112 
113 /* LRO types */
114 #define	OS_NETSTACK_BUF		mblk_t *
115 #define	OS_LL_HEADER		uint8_t *
116 #define	OS_IP_HEADER		uint8_t *
117 #define	OS_TL_HEADER		uint8_t *
118 
119 /* -------------------------- "libc" functionality ------------------------- */
120 
121 #define	xge_os_strcpy			(void) strcpy
122 #define	xge_os_strlen			strlen
123 #define	xge_os_snprintf			snprintf
124 #define	xge_os_memzero(addr, size)	bzero(addr, size)
125 #define	xge_os_memcpy(dst, src, size)	bcopy(src, dst, size)
126 #define	xge_os_memcmp(src1, src2, size)	bcmp(src1, src2, size)
127 #define	xge_os_ntohl			ntohl
128 #define	xge_os_htons			htons
129 #define	xge_os_ntohs			ntohs
130 
131 #ifdef __GNUC__
132 #define	xge_os_printf(fmt...)		cmn_err(CE_CONT, fmt)
133 #define	xge_os_sprintf(buf, fmt...)	strlen(sprintf(buf, fmt))
134 #else
135 #define	xge_os_vaprintf(fmt) { \
136 	va_list va; \
137 	va_start(va, fmt); \
138 	vcmn_err(CE_CONT, fmt, va); \
139 	va_end(va); \
140 }
141 
142 static inline void xge_os_printf(char *fmt, ...) {
143 	xge_os_vaprintf(fmt);
144 }
145 
146 #define	xge_os_vasprintf(buf, fmt) { \
147 	va_list va; \
148 	va_start(va, fmt); \
149 	(void) vsprintf(buf, fmt, va); \
150 	va_end(va); \
151 }
152 
153 static inline int xge_os_sprintf(char *buf, char *fmt, ...) {
154 	xge_os_vasprintf(buf, fmt);
155 	return (strlen(buf));
156 }
157 #endif
158 
159 #define	xge_os_timestamp(buf) { \
160 	todinfo_t todinfo = utc_to_tod(ddi_get_time()); \
161 	(void) xge_os_sprintf(buf, "%2d/%2d/%2d.%2d:%2d:%2d: ", \
162 	    todinfo.tod_day, todinfo.tod_month, \
163 	    (1970 + todinfo.tod_year - 70), \
164 	    todinfo.tod_hour, todinfo.tod_min, todinfo.tod_sec); \
165 }
166 
167 #define	xge_os_println			xge_os_printf
168 
169 /* -------------------- synchronization primitives ------------------------- */
170 
171 #define	xge_os_spin_lock_init(lockp, ctxh) \
172 	mutex_init(lockp, NULL, MUTEX_DRIVER, NULL)
173 #define	xge_os_spin_lock_init_irq(lockp, irqh) \
174 	mutex_init(lockp, NULL, MUTEX_DRIVER, irqh)
175 #define	xge_os_spin_lock_destroy(lockp, cthx) \
176 	(cthx = cthx, mutex_destroy(lockp))
177 #define	xge_os_spin_lock_destroy_irq(lockp, cthx) \
178 	(cthx = cthx, mutex_destroy(lockp))
179 #define	xge_os_spin_lock(lockp)			mutex_enter(lockp)
180 #define	xge_os_spin_unlock(lockp)		mutex_exit(lockp)
181 #define	xge_os_spin_lock_irq(lockp, flags) (flags = flags, mutex_enter(lockp))
182 #define	xge_os_spin_unlock_irq(lockp, flags)	mutex_exit(lockp)
183 
184 /* x86 arch will never re-order writes, Sparc can */
185 #define	xge_os_wmb()				membar_producer()
186 
187 #define	xge_os_udelay(us)			drv_usecwait(us)
188 #define	xge_os_mdelay(ms)			drv_usecwait(ms * 1000)
189 
190 #define	xge_os_cmpxchg(targetp, cmp, newval)		\
191 	sizeof (*(targetp)) == 4 ?			\
192 	cas32((uint32_t *)targetp, cmp, newval) :	\
193 	cas64((uint64_t *)targetp, cmp, newval)
194 
195 /* ------------------------- misc primitives ------------------------------- */
196 
197 #define	xge_os_unlikely(x)		(x)
198 #define	xge_os_prefetch(a)		(a = a)
199 #define	xge_os_prefetchw
200 #ifdef __GNUC__
201 #define	xge_os_bug(fmt...)		cmn_err(CE_PANIC, fmt)
202 #else
203 static inline void xge_os_bug(char *fmt, ...) {
204 	va_list ap;
205 
206 	va_start(ap, fmt);
207 	vcmn_err(CE_PANIC, fmt, ap);
208 	va_end(ap);
209 }
210 #endif
211 
212 /* -------------------------- compiler stuffs ------------------------------ */
213 
214 #if defined(__i386)
215 #define	__xge_os_cacheline_size		64 /* L1-cache line size: x86_64 */
216 #else
217 #define	__xge_os_cacheline_size		64 /* L1-cache line size: sparcv9 */
218 #endif
219 
220 #ifdef __GNUC__
221 #define	__xge_os_attr_cacheline_aligned	\
222 	__attribute__((__aligned__(__xge_os_cacheline_size)))
223 #else
224 #define	__xge_os_attr_cacheline_aligned
225 #endif
226 
227 /* ---------------------- memory primitives -------------------------------- */
228 
229 static inline void *__xge_os_malloc(pci_dev_h pdev, unsigned long size,
230     char *file, int line)
231 {
232 	void *vaddr = kmem_alloc(size, KM_SLEEP);
233 
234 	XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, file, line);
235 	return (vaddr);
236 }
237 
238 static inline void xge_os_free(pci_dev_h pdev, const void *vaddr,
239     unsigned long size)
240 {
241 	XGE_OS_MEMORY_CHECK_FREE(vaddr, size);
242 	kmem_free((void*)vaddr, size);
243 }
244 
245 #define	xge_os_malloc(pdev, size) \
246 	__xge_os_malloc(pdev, size, __FILE__, __LINE__)
247 
248 static inline void *__xge_os_dma_malloc(pci_dev_h pdev, unsigned long size,
249     int dma_flags, pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch, char *file,
250     int line)
251 {
252 	void *vaddr;
253 	int ret;
254 	size_t real_size;
255 	extern ddi_device_acc_attr_t *p_xge_dev_attr;
256 	extern struct ddi_dma_attr *p_hal_dma_attr;
257 	extern struct ddi_dma_attr *p_hal_dma_attr_aligned;
258 
259 	ret = ddi_dma_alloc_handle(pdev,
260 	    (dma_flags & XGE_OS_DMA_CACHELINE_ALIGNED ?
261 		p_hal_dma_attr_aligned : p_hal_dma_attr),
262 	    DDI_DMA_DONTWAIT, 0, p_dmah);
263 	if (ret != DDI_SUCCESS) {
264 		return (NULL);
265 	}
266 
267 	ret = ddi_dma_mem_alloc(*p_dmah, size, p_xge_dev_attr,
268 	    (dma_flags & XGE_OS_DMA_CONSISTENT ?
269 	    DDI_DMA_CONSISTENT : DDI_DMA_STREAMING), DDI_DMA_DONTWAIT, 0,
270 	    (caddr_t *)&vaddr, &real_size, p_dma_acch);
271 	if (ret != DDI_SUCCESS) {
272 		ddi_dma_free_handle(p_dmah);
273 		return (NULL);
274 	}
275 
276 	if (size > real_size) {
277 		ddi_dma_mem_free(p_dma_acch);
278 		ddi_dma_free_handle(p_dmah);
279 		return (NULL);
280 	}
281 
282 	XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, file, line);
283 
284 	return (vaddr);
285 }
286 
287 #define	xge_os_dma_malloc(pdev, size, dma_flags, p_dmah, p_dma_acch) \
288 	__xge_os_dma_malloc(pdev, size, dma_flags, p_dmah, p_dma_acch, \
289 	    __FILE__, __LINE__)
290 
291 static inline void xge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size,
292     pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah)
293 {
294 	XGE_OS_MEMORY_CHECK_FREE(vaddr, 0);
295 	ddi_dma_mem_free(p_dma_acch);
296 	ddi_dma_free_handle(p_dmah);
297 }
298 
299 
300 /* --------------------------- pci primitives ------------------------------ */
301 
302 #define	xge_os_pci_read8(pdev, cfgh, where, val)	\
303 	(*(val) = pci_config_get8(cfgh, where))
304 
305 #define	xge_os_pci_write8(pdev, cfgh, where, val)	\
306 	pci_config_put8(cfgh, where, val)
307 
308 #define	xge_os_pci_read16(pdev, cfgh, where, val)	\
309 	(*(val) = pci_config_get16(cfgh, where))
310 
311 #define	xge_os_pci_write16(pdev, cfgh, where, val)	\
312 	pci_config_put16(cfgh, where, val)
313 
314 #define	xge_os_pci_read32(pdev, cfgh, where, val)	\
315 	(*(val) = pci_config_get32(cfgh, where))
316 
317 #define	xge_os_pci_write32(pdev, cfgh, where, val)	\
318 	pci_config_put32(cfgh, where, val)
319 
320 /* --------------------------- io primitives ------------------------------- */
321 
322 #define	xge_os_pio_mem_read8(pdev, regh, addr)		\
323 	(ddi_get8(regh, (uint8_t *)(addr)))
324 
325 #define	xge_os_pio_mem_write8(pdev, regh, val, addr)	\
326 	(ddi_put8(regh, (uint8_t *)(addr), val))
327 
328 #define	xge_os_pio_mem_read16(pdev, regh, addr)		\
329 	(ddi_get16(regh, (uint16_t *)(addr)))
330 
331 #define	xge_os_pio_mem_write16(pdev, regh, val, addr)	\
332 	(ddi_put16(regh, (uint16_t *)(addr), val))
333 
334 #define	xge_os_pio_mem_read32(pdev, regh, addr)		\
335 	(ddi_get32(regh, (uint32_t *)(addr)))
336 
337 #define	xge_os_pio_mem_write32(pdev, regh, val, addr)	\
338 	(ddi_put32(regh, (uint32_t *)(addr), val))
339 
340 #define	xge_os_pio_mem_read64(pdev, regh, addr)		\
341 	(ddi_get64(regh, (uint64_t *)(addr)))
342 
343 #define	xge_os_pio_mem_write64(pdev, regh, val, addr)	\
344 	(ddi_put64(regh, (uint64_t *)(addr), val))
345 
346 #define	xge_os_flush_bridge xge_os_pio_mem_read64
347 
348 /* --------------------------- dma primitives ----------------------------- */
349 
350 #define	XGE_OS_DMA_DIR_TODEVICE		DDI_DMA_SYNC_FORDEV
351 #define	XGE_OS_DMA_DIR_FROMDEVICE	DDI_DMA_SYNC_FORKERNEL
352 #define	XGE_OS_DMA_DIR_BIDIRECTIONAL	-1
353 #if defined(__x86)
354 #define	XGE_OS_DMA_USES_IOMMU		0
355 #else
356 #define	XGE_OS_DMA_USES_IOMMU		1
357 #endif
358 
359 #define	XGE_OS_INVALID_DMA_ADDR		((dma_addr_t)0)
360 
361 static inline dma_addr_t xge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah,
362     void *vaddr, size_t size, int dir, int dma_flags) {
363 	int ret;
364 	uint_t flags;
365 	uint_t ncookies;
366 	ddi_dma_cookie_t dma_cookie;
367 
368 	switch (dir) {
369 	case XGE_OS_DMA_DIR_TODEVICE:
370 		flags = DDI_DMA_WRITE;
371 		break;
372 	case XGE_OS_DMA_DIR_FROMDEVICE:
373 		flags = DDI_DMA_READ;
374 		break;
375 	case XGE_OS_DMA_DIR_BIDIRECTIONAL:
376 		flags = DDI_DMA_RDWR;
377 		break;
378 	default:
379 		return (0);
380 	}
381 
382 	flags |= (dma_flags & XGE_OS_DMA_CONSISTENT) ?
383 	    DDI_DMA_CONSISTENT : DDI_DMA_STREAMING;
384 
385 	ret = ddi_dma_addr_bind_handle(dmah, NULL, vaddr, size, flags,
386 	    DDI_DMA_SLEEP, 0, &dma_cookie, &ncookies);
387 	if (ret != DDI_SUCCESS) {
388 		return (0);
389 	}
390 
391 	if (ncookies != 1 || dma_cookie.dmac_size < size) {
392 		(void) ddi_dma_unbind_handle(dmah);
393 		return (0);
394 	}
395 
396 	return (dma_cookie.dmac_laddress);
397 }
398 
399 static inline void xge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah,
400     dma_addr_t dma_addr, size_t size, int dir)
401 {
402 	(void) ddi_dma_unbind_handle(dmah);
403 }
404 
405 static inline void xge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah,
406     dma_addr_t dma_addr, u64 dma_offset, size_t length, int dir)
407 {
408 	(void) ddi_dma_sync(dmah, dma_offset, length, dir);
409 }
410 
411 #ifdef __cplusplus
412 }
413 #endif
414 
415 #endif /* _SYS_XGE_OSDEP_H */
416