Home | History | Annotate | Download | only in drv
      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
     55 extern "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
    101 typedef	u64			dma_addr_t;
    102 #define	ulong_t			ulong_t
    103 #define	ptrdiff_t		ptrdiff_t
    104 typedef	kmutex_t		spinlock_t;
    105 typedef dev_info_t		*pci_dev_h;
    106 typedef ddi_acc_handle_t	pci_reg_h;
    107 typedef ddi_acc_handle_t	pci_cfg_h;
    108 typedef uint_t			pci_irq_h;
    109 typedef ddi_dma_handle_t	pci_dma_h;
    110 typedef 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 
    141 static 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 
    152 static 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 	cas32((uint32_t *)targetp, cmp, newval) :	\
    192 	cas64((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
    202 static 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 
    228 static 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 
    237 static 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 
    247 static 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 
    287 static 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 
    357 static 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 
    395 static 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 
    401 static 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