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