xge-osdep.h revision 171095
1/*- 2 * Copyright (c) 2002-2007 Neterion, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/dev/nxge/xge-osdep.h 171095 2007-06-29 22:47:18Z sam $ 27 */ 28 29/* 30 * xge-osdep.h 31 * 32 * Platform-dependent "glue" code 33 */ 34 35#ifndef XGE_OSDEP_H 36#define XGE_OSDEP_H 37 38/****************************************** 39 * Includes and defines 40 ******************************************/ 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/mbuf.h> 44#include <sys/protosw.h> 45#include <sys/socket.h> 46#include <sys/malloc.h> 47#include <sys/kernel.h> 48#include <sys/module.h> 49#include <sys/bus.h> 50#include <sys/lock.h> 51#include <sys/mutex.h> 52#include <sys/rman.h> 53#include <sys/stddef.h> 54#include <sys/types.h> 55#include <sys/sockio.h> 56#include <sys/proc.h> 57#include <sys/mutex.h> 58#include <sys/types.h> 59#include <sys/endian.h> 60#include <machine/bus.h> 61#include <machine/resource.h> 62#include <machine/clock.h> 63#include <vm/vm.h> 64#include <vm/pmap.h> 65#include <dev/pci/pcivar.h> 66#include <dev/pci/pcireg.h> 67#include <dev/pci/pci_private.h> 68#include <net/if.h> 69#include <net/if_arp.h> 70#include <net/ethernet.h> 71#include <net/if_dl.h> 72#include <net/if_media.h> 73#include <net/if_var.h> 74#include <net/bpf.h> 75#include <net/if_types.h> 76 77 78#define XGE_OS_PLATFORM_64BIT 79 80#if BYTE_ORDER == BIG_ENDIAN 81#define XGE_OS_HOST_BIG_ENDIAN 1 82#elif BYTE_ORDER == LITTLE_ENDIAN 83#define XGE_OS_HOST_LITTLE_ENDIAN 1 84#endif 85 86#define XGE_HAL_USE_5B_MODE 1 87#define XGE_HAL_PROCESS_LINK_INT_IN_ISR 1 88#define OS_NETSTACK_BUF struct mbuf * 89#define XGE_LL_IP_FAST_CSUM(hdr, len) 0 90 91#define xge_os_ntohs ntohs 92#define xge_os_ntohl ntohl 93#define xge_os_htons htons 94#define xge_os_htonl htonl 95 96#ifndef __DECONST 97#define __DECONST(type, var) ((type)(uintrptr_t)(const void *)(var)) 98#endif 99 100typedef struct busresources { 101 bus_space_tag_t bus_tag; /* DMA Tag */ 102 bus_space_handle_t bus_handle; /* Bus handle */ 103 struct resource *bar_start_addr;/* BAR start address */ 104} busresource_t; 105 106typedef struct xge_dma_alloc { 107 bus_addr_t dma_phyaddr; /* Physical Address */ 108 caddr_t dma_viraddr; /* Virtual Address */ 109 bus_dma_tag_t dma_tag; /* DMA Tag */ 110 bus_dmamap_t dma_map; /* DMA Map */ 111 bus_dma_segment_t dma_segment; /* DMA Segment */ 112 bus_size_t dma_size; /* Size */ 113 int dma_nseg; /* Maximum scatter-gather segs. */ 114} xdma; 115 116struct xge_dma_mbuf { 117 bus_addr_t dma_phyaddr; /* Physical Address */ 118 bus_dmamap_t dma_map; /* DMA Map */ 119}; 120 121typedef struct pci_info { 122 device_t device; /* Device */ 123 struct resource *regmap0; /* Resource for BAR0 */ 124 struct resource *regmap1; /* Resource for BAR1 */ 125 void *bar0resource; /* BAR0 tag and handle */ 126 void *bar1resource; /* BAR1 tag and handle */ 127} pci_info_t; 128 129 130/****************************************** 131 * Fixed size primitive types 132 ******************************************/ 133#define u8 uint8_t 134#define u16 uint16_t 135#define u32 uint32_t 136#define u64 uint64_t 137#define ulong_t unsigned long 138#define uint unsigned int 139#define ptrdiff_t ptrdiff_t 140typedef bus_addr_t dma_addr_t; 141typedef struct mtx spinlock_t; 142typedef pci_info_t *pci_dev_h; 143typedef busresource_t *pci_reg_h; 144typedef struct xge_dma_alloc pci_dma_h; 145typedef struct resource *pci_irq_h; 146typedef pci_info_t *pci_cfg_h; 147typedef struct xge_dma_alloc pci_dma_acc_h; 148 149/****************************************** 150 * "libc" functionality 151 ******************************************/ 152#define xge_os_memzero(addr, size) bzero(addr, size) 153#define xge_os_memcpy(dst, src, size) bcopy(src, dst, size) 154#define xge_os_memcmp memcmp 155#define xge_os_strcpy strcpy 156#define xge_os_strlen strlen 157#define xge_os_snprintf snprintf 158#define xge_os_sprintf sprintf 159#define xge_os_printf(fmt...) { \ 160 printf(fmt); \ 161 printf("\n"); \ 162} 163 164#define xge_os_vaprintf(fmt) { \ 165 sprintf(fmt, fmt, "\n"); \ 166 va_list va; \ 167 va_start(va, fmt); \ 168 vprintf(fmt, va); \ 169 va_end(va); \ 170} 171 172#define xge_os_vasprintf(buf, fmt) { \ 173 va_list va; \ 174 va_start(va, fmt); \ 175 (void) vaprintf(buf, fmt, va); \ 176 va_end(va); \ 177} 178 179#define xge_os_timestamp(buf) { \ 180 struct timeval current_time; \ 181 gettimeofday(¤t_time, 0); \ 182 sprintf(buf, "%08li.%08li: ", current_time.tv_sec, \ 183 current_time.tv_usec); \ 184} 185 186#define xge_os_println xge_os_printf 187 188/****************************************** 189 * Synchronization Primitives 190 ******************************************/ 191/* Initialize the spin lock */ 192#define xge_os_spin_lock_init(lockp, ctxh) \ 193 if(mtx_initialized(lockp) == 0) { \ 194 mtx_init((lockp), "xge", MTX_NETWORK_LOCK, MTX_DEF); \ 195 } 196 197/* Initialize the spin lock (IRQ version) */ 198#define xge_os_spin_lock_init_irq(lockp, ctxh) \ 199 if(mtx_initialized(lockp) == 0) { \ 200 mtx_init((lockp), "xge", MTX_NETWORK_LOCK, MTX_DEF); \ 201 } 202 203/* Destroy the lock */ 204#define xge_os_spin_lock_destroy(lockp, ctxh) \ 205 if(mtx_initialized(lockp) != 0) { \ 206 mtx_destroy(lockp); \ 207 } 208 209/* Destroy the lock (IRQ version) */ 210#define xge_os_spin_lock_destroy_irq(lockp, ctxh) \ 211 if(mtx_initialized(lockp) != 0) { \ 212 mtx_destroy(lockp); \ 213 } 214 215/* Acquire the lock */ 216#define xge_os_spin_lock(lockp) \ 217 if(mtx_owned(lockp) == 0) mtx_lock(lockp) 218 219/* Release the lock */ 220#define xge_os_spin_unlock(lockp) mtx_unlock(lockp) 221 222/* Acquire the lock (IRQ version) */ 223#define xge_os_spin_lock_irq(lockp, flags) { \ 224 flags = MTX_QUIET; \ 225 if(mtx_owned(lockp) == 0) mtx_lock_flags(lockp, flags); \ 226} 227 228/* Release the lock (IRQ version) */ 229#define xge_os_spin_unlock_irq(lockp, flags) { \ 230 flags = MTX_QUIET; \ 231 mtx_unlock_flags(lockp, flags); \ 232} 233 234/* Write memory barrier */ 235#define xge_os_wmb() 236 237/* Delay (in micro seconds) */ 238#define xge_os_udelay(us) DELAY(us) 239 240/* Delay (in milli seconds) */ 241#define xge_os_mdelay(ms) DELAY(ms * 1000) 242 243/* Compare and exchange */ 244//#define xge_os_cmpxchg(targetp, cmd, newval) 245 246/****************************************** 247 * Misc primitives 248 ******************************************/ 249#define xge_os_unlikely(x) (x) 250#define xge_os_prefetch(x) (x=x) 251#define xge_os_prefetchw(x) (x=x) 252#define xge_os_bug(fmt...) printf(fmt...) 253#define xge_os_htohs ntohs 254#define xge_os_ntohl ntohl 255#define xge_os_htons htons 256#define xge_os_htonl htonl 257 258/****************************************** 259 * Compiler Stuffs 260 ******************************************/ 261#define __xge_os_attr_cacheline_aligned 262#define __xge_os_cacheline_size 32 263 264/****************************************** 265 * Memory Primitives 266 ******************************************/ 267#define XGE_OS_INVALID_DMA_ADDR ((dma_addr_t)0) 268 269/****************************************** 270 * xge_os_malloc - Allocate non DMA-able memory. 271 * @pdev: Device context. 272 * @size: Size to allocate. 273 * 274 * Allocate @size bytes of memory. This allocation can sleep, and 275 * therefore, and therefore it requires process context. In other words, 276 * xge_os_malloc() cannot be called from the interrupt context. 277 * Use xge_os_free() to free the allocated block. 278 * 279 * Returns: Pointer to allocated memory, NULL - on failure. 280 * 281 * See also: xge_os_free(). 282 ******************************************/ 283static inline void * 284xge_os_malloc(pci_dev_h pdev, unsigned long size) { 285 void *vaddr = malloc((size), M_DEVBUF, M_NOWAIT); 286 xge_os_memzero(vaddr, size); 287 XGE_OS_MEMORY_CHECK_MALLOC(vaddr, size, file, line); 288 return (vaddr); 289} 290 291/****************************************** 292 * xge_os_free - Free non DMA-able memory. 293 * @pdev: Device context. 294 * @vaddr: Address of the allocated memory block. 295 * @size: Some OS's require to provide size on free 296 * 297 * Free the memory area obtained via xge_os_malloc(). 298 * This call may also sleep, and therefore it cannot be used inside 299 * interrupt. 300 * 301 * See also: xge_os_malloc(). 302 ******************************************/ 303static inline void 304xge_os_free(pci_dev_h pdev, const void *vaddr, unsigned long size) { 305 XGE_OS_MEMORY_CHECK_FREE(vaddr, size); 306 free(__DECONST(void *, vaddr), M_DEVBUF); 307} 308 309static void 310xge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) { 311 if(error) return; 312 *(bus_addr_t *) arg = segs->ds_addr; 313 return; 314} 315 316/****************************************** 317 * xge_os_dma_malloc - Allocate DMA-able memory. 318 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 319 * @size: Size (in bytes) to allocate. 320 * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, 321 * XGE_OS_DMA_STREAMING, 322 * XGE_OS_DMA_CONSISTENT 323 * Note that the last two flags are mutually exclusive. 324 * @p_dmah: Handle used to map the memory onto the corresponding device memory 325 * space. See xge_os_dma_map(). The handle is an out-parameter 326 * returned by the function. 327 * @p_dma_acch: One more DMA handle used subsequently to free the 328 * DMA object (via xge_os_dma_free()). 329 * 330 * Allocate DMA-able contiguous memory block of the specified @size. 331 * This memory can be subsequently freed using xge_os_dma_free(). 332 * Note: can be used inside interrupt context. 333 * 334 * Returns: Pointer to allocated memory(DMA-able), NULL on failure. 335 * 336 ******************************************/ 337static inline void * 338xge_os_dma_malloc(pci_dev_h pdev, unsigned long size, int dma_flags, 339 pci_dma_h *p_dmah, pci_dma_acc_h *p_dma_acch) { 340 int retValue = bus_dma_tag_create( 341 bus_get_dma_tag(pdev->device), /* Parent */ 342 PAGE_SIZE, /* Alignment no specific alignment */ 343 0, /* Bounds */ 344 BUS_SPACE_MAXADDR, /* Low Address */ 345 BUS_SPACE_MAXADDR, /* High Address */ 346 NULL, /* Filter */ 347 NULL, /* Filter arg */ 348 size, /* Max Size */ 349 1, /* n segments */ 350 size, /* max segment size */ 351 BUS_DMA_ALLOCNOW, /* Flags */ 352 NULL, /* lockfunction */ 353 NULL, /* lock arg */ 354 &p_dmah->dma_tag); /* DMA tag */ 355 if(retValue != 0) { 356 xge_os_printf("bus_dma_tag_create failed\n"); 357 goto fail_1; 358 } 359 p_dmah->dma_size = size; 360 retValue = bus_dmamem_alloc(p_dmah->dma_tag, 361 (void **)&p_dmah->dma_viraddr, BUS_DMA_NOWAIT, &p_dmah->dma_map); 362 if(retValue != 0) { 363 xge_os_printf("bus_dmamem_alloc failed\n"); 364 goto fail_2; 365 } 366 return(p_dmah->dma_viraddr); 367 368fail_2: bus_dma_tag_destroy(p_dmah->dma_tag); 369fail_1: return(NULL); 370} 371 372/****************************************** 373 * xge_os_dma_free - Free previously allocated DMA-able memory. 374 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 375 * @vaddr: Virtual address of the DMA-able memory. 376 * @p_dma_acch: DMA handle used to free the resource. 377 * @p_dmah: DMA handle used for mapping. See xge_os_dma_malloc(). 378 * 379 * Free DMA-able memory originally allocated by xge_os_dma_malloc(). 380 * Note: can be used inside interrupt. 381 * See also: xge_os_dma_malloc(). 382 ******************************************/ 383static inline void 384xge_os_dma_free(pci_dev_h pdev, const void *vaddr, int size, 385 pci_dma_acc_h *p_dma_acch, pci_dma_h *p_dmah) { 386 XGE_OS_MEMORY_CHECK_FREE(p_dmah->dma_viraddr, size); 387 bus_dmamem_free(p_dmah->dma_tag, p_dmah->dma_viraddr, p_dmah->dma_map); 388 bus_dma_tag_destroy(p_dmah->dma_tag); 389 p_dmah->dma_map = NULL; 390 p_dmah->dma_tag = NULL; 391 p_dmah->dma_viraddr = NULL; 392 return; 393} 394 395/****************************************** 396 * IO/PCI/DMA Primitives 397 ******************************************/ 398#define XGE_OS_DMA_DIR_TODEVICE 0 399#define XGE_OS_DMA_DIR_FROMDEVICE 1 400#define XGE_OS_DMA_DIR_BIDIRECTIONAL 2 401 402/****************************************** 403 * xge_os_pci_read8 - Read one byte from device PCI configuration. 404 * @pdev: Device context. Some OSs require device context to perform 405 * PIO and/or config space IO. 406 * @cfgh: PCI configuration space handle. 407 * @where: Offset in the PCI configuration space. 408 * @val: Address of the result. 409 * 410 * Read byte value from the specified @regh PCI configuration space at the 411 * specified offset = @where. 412 * Returns: 0 - success, non-zero - failure. 413 ******************************************/ 414#define xge_os_pci_read8(pdev, cfgh, where, val) \ 415 (*(val) = pci_read_config(pdev->device, where, 1)) 416 417/****************************************** 418 * xge_os_pci_write8 - Write one byte into device PCI configuration. 419 * @pdev: Device context. Some OSs require device context to perform 420 * PIO and/or config space IO. 421 * @cfgh: PCI configuration space handle. 422 * @where: Offset in the PCI configuration space. 423 * @val: Value to write. 424 * 425 * Write byte value into the specified PCI configuration space 426 * Returns: 0 - success, non-zero - failure. 427 ******************************************/ 428#define xge_os_pci_write8(pdev, cfgh, where, val) \ 429 pci_write_config(pdev->device, where, val, 1) 430 431/****************************************** 432 * xge_os_pci_read16 - Read 16bit word from device PCI configuration. 433 * @pdev: Device context. 434 * @cfgh: PCI configuration space handle. 435 * @where: Offset in the PCI configuration space. 436 * @val: Address of the 16bit result. 437 * 438 * Read 16bit value from the specified PCI configuration space at the 439 * specified offset. 440 * Returns: 0 - success, non-zero - failure. 441 ******************************************/ 442#define xge_os_pci_read16(pdev, cfgh, where, val) \ 443 (*(val) = pci_read_config(pdev->device, where, 2)) 444 445/****************************************** 446 * xge_os_pci_write16 - Write 16bit word into device PCI configuration. 447 * @pdev: Device context. 448 * @cfgh: PCI configuration space handle. 449 * @where: Offset in the PCI configuration space. 450 * @val: Value to write. 451 * 452 * Write 16bit value into the specified @offset in PCI 453 * configuration space. 454 * Returns: 0 - success, non-zero - failure. 455 ******************************************/ 456#define xge_os_pci_write16(pdev, cfgh, where, val) \ 457 pci_write_config(pdev->device, where, val, 2) 458 459/****************************************** 460 * xge_os_pci_read32 - Read 32bit word from device PCI configuration. 461 * @pdev: Device context. 462 * @cfgh: PCI configuration space handle. 463 * @where: Offset in the PCI configuration space. 464 * @val: Address of 32bit result. 465 * 466 * Read 32bit value from the specified PCI configuration space at the 467 * specified offset. 468 * Returns: 0 - success, non-zero - failure. 469 ******************************************/ 470#define xge_os_pci_read32(pdev, cfgh, where, val) \ 471 (*(val) = pci_read_config(pdev->device, where, 4)) 472 473/****************************************** 474 * xge_os_pci_write32 - Write 32bit word into device PCI configuration. 475 * @pdev: Device context. 476 * @cfgh: PCI configuration space handle. 477 * @where: Offset in the PCI configuration space. 478 * @val: Value to write. 479 * 480 * Write 32bit value into the specified @offset in PCI 481 * configuration space. 482 * Returns: 0 - success, non-zero - failure. 483 ******************************************/ 484#define xge_os_pci_write32(pdev, cfgh, where, val) \ 485 pci_write_config(pdev->device, where, val, 4) 486 487/****************************************** 488 * xge_os_pio_mem_read8 - Read 1 byte from device memory mapped space. 489 * @pdev: Device context. 490 * @regh: PCI configuration space handle. 491 * @addr: Address in device memory space. 492 * 493 * Returns: 1 byte value read from the specified (mapped) memory space address. 494 ******************************************/ 495static inline u8 496xge_os_pio_mem_read8(pci_dev_h pdev, pci_reg_h regh, void *addr) 497{ 498 bus_space_tag_t tag = 499 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); 500 bus_space_handle_t handle = 501 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); 502 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); 503 504 return bus_space_read_1(tag, handle, (caddr_t)(addr) - addrss); 505} 506 507/****************************************** 508 * xge_os_pio_mem_write8 - Write 1 byte into device memory mapped 509 * space. 510 * @pdev: Device context. 511 * @regh: PCI configuration space handle. 512 * @val: Value to write. 513 * @addr: Address in device memory space. 514 * 515 * Write byte value into the specified (mapped) device memory space. 516 ******************************************/ 517static inline void 518xge_os_pio_mem_write8(pci_dev_h pdev, pci_reg_h regh, u8 val, void *addr) 519{ 520 bus_space_tag_t tag = 521 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); 522 bus_space_handle_t handle = 523 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); 524 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); 525 526 bus_space_write_1(tag, handle, (caddr_t)(addr) - addrss, val); 527} 528 529/****************************************** 530 * xge_os_pio_mem_read16 - Read 16bit from device memory mapped space. 531 * @pdev: Device context. 532 * @regh: PCI configuration space handle. 533 * @addr: Address in device memory space. 534 * 535 * Returns: 16bit value read from the specified (mapped) memory space address. 536 ******************************************/ 537static inline u16 538xge_os_pio_mem_read16(pci_dev_h pdev, pci_reg_h regh, void *addr) 539{ 540 bus_space_tag_t tag = 541 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); 542 bus_space_handle_t handle = 543 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); 544 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); 545 546 return bus_space_read_2(tag, handle, (caddr_t)(addr) - addrss); 547} 548 549/****************************************** 550 * xge_os_pio_mem_write16 - Write 16bit into device memory mapped space. 551 * @pdev: Device context. 552 * @regh: PCI configuration space handle. 553 * @val: Value to write. 554 * @addr: Address in device memory space. 555 * 556 * Write 16bit value into the specified (mapped) device memory space. 557 ******************************************/ 558static inline void 559xge_os_pio_mem_write16(pci_dev_h pdev, pci_reg_h regh, u16 val, void *addr) 560{ 561 bus_space_tag_t tag = 562 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); 563 bus_space_handle_t handle = 564 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); 565 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); 566 567 bus_space_write_2(tag, handle, (caddr_t)(addr) - addrss, val); 568} 569 570/****************************************** 571 * xge_os_pio_mem_read32 - Read 32bit from device memory mapped space. 572 * @pdev: Device context. 573 * @regh: PCI configuration space handle. 574 * @addr: Address in device memory space. 575 * 576 * Returns: 32bit value read from the specified (mapped) memory space address. 577 ******************************************/ 578static inline u32 579xge_os_pio_mem_read32(pci_dev_h pdev, pci_reg_h regh, void *addr) 580{ 581 bus_space_tag_t tag = 582 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); 583 bus_space_handle_t handle = 584 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); 585 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); 586 587 return bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss); 588} 589 590/****************************************** 591 * xge_os_pio_mem_write32 - Write 32bit into device memory space. 592 * @pdev: Device context. 593 * @regh: PCI configuration space handle. 594 * @val: Value to write. 595 * @addr: Address in device memory space. 596 * 597 * Write 32bit value into the specified (mapped) device memory space. 598 ******************************************/ 599static inline void 600xge_os_pio_mem_write32(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr) 601{ 602 bus_space_tag_t tag = 603 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); 604 bus_space_handle_t handle = 605 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); 606 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); 607 bus_space_write_4(tag, handle, (caddr_t)(addr) - addrss, val); 608} 609 610/****************************************** 611 * xge_os_pio_mem_read64 - Read 64bit from device memory mapped space. 612 * @pdev: Device context. 613 * @regh: PCI configuration space handle. 614 * @addr: Address in device memory space. 615 * 616 * Returns: 64bit value read from the specified (mapped) memory space address. 617 ******************************************/ 618static inline u64 619xge_os_pio_mem_read64(pci_dev_h pdev, pci_reg_h regh, void *addr) 620{ 621 u64 value1, value2; 622 623 bus_space_tag_t tag = 624 (bus_space_tag_t)(((busresource_t *)regh)->bus_tag); 625 bus_space_handle_t handle = 626 (bus_space_handle_t)(((busresource_t *)regh)->bus_handle); 627 caddr_t addrss = (caddr_t)(((busresource_t *)(regh))->bar_start_addr); 628 629 value1 = bus_space_read_4(tag, handle, (caddr_t)(addr) + 4 - addrss); 630 value1 <<= 32; 631 value2 = bus_space_read_4(tag, handle, (caddr_t)(addr) - addrss); 632 value1 |= value2; 633 return value1; 634} 635 636/****************************************** 637 * xge_os_pio_mem_write64 - Write 32bit into device memory space. 638 * @pdev: Device context. 639 * @regh: PCI configuration space handle. 640 * @val: Value to write. 641 * @addr: Address in device memory space. 642 * 643 * Write 64bit value into the specified (mapped) device memory space. 644 ******************************************/ 645static inline void 646xge_os_pio_mem_write64(pci_dev_h pdev, pci_reg_h regh, u64 val, void *addr) 647{ 648 u32 vall = val & 0xffffffff; 649 xge_os_pio_mem_write32(pdev, regh, vall, addr); 650 xge_os_pio_mem_write32(pdev, regh, val >> 32, ((caddr_t)(addr) + 4)); 651} 652 653/****************************************** 654 * FIXME: document 655 ******************************************/ 656#define xge_os_flush_bridge xge_os_pio_mem_read64 657 658/****************************************** 659 * xge_os_dma_map - Map DMA-able memory block to, or from, or 660 * to-and-from device. 661 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 662 * @dmah: DMA handle used to map the memory block. Obtained via 663 * xge_os_dma_malloc(). 664 * @vaddr: Virtual address of the DMA-able memory. 665 * @size: Size (in bytes) to be mapped. 666 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.) 667 * @dma_flags: XGE_OS_DMA_CACHELINE_ALIGNED, 668 * XGE_OS_DMA_STREAMING, 669 * XGE_OS_DMA_CONSISTENT 670 * Note that the last two flags are mutually exclusive. 671 * 672 * Map a single memory block. 673 * 674 * Returns: DMA address of the memory block, 675 * XGE_OS_INVALID_DMA_ADDR on failure. 676 * 677 * See also: xge_os_dma_malloc(), xge_os_dma_unmap(), 678 * xge_os_dma_sync(). 679 ******************************************/ 680static inline dma_addr_t 681xge_os_dma_map(pci_dev_h pdev, pci_dma_h dmah, void *vaddr, size_t size, 682 int dir, int dma_flags) 683{ 684 int retValue = 685 bus_dmamap_load(dmah.dma_tag, dmah.dma_map, dmah.dma_viraddr, 686 dmah.dma_size, xge_dmamap_cb, &dmah.dma_phyaddr, BUS_DMA_NOWAIT); 687 if(retValue != 0) { 688 xge_os_printf("bus_dmamap_load_ failed\n"); 689 return XGE_OS_INVALID_DMA_ADDR; 690 } 691 dmah.dma_size = size; 692 return dmah.dma_phyaddr; 693} 694 695/****************************************** 696 * xge_os_dma_unmap - Unmap DMA-able memory. 697 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 698 * @dmah: DMA handle used to map the memory block. Obtained via 699 * xge_os_dma_malloc(). 700 * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map(). 701 * @size: Size (in bytes) to be unmapped. 702 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.) 703 * 704 * Unmap a single DMA-able memory block that was previously mapped 705 * using xge_os_dma_map(). 706 * See also: xge_os_dma_malloc(), xge_os_dma_map(). 707 ******************************************/ 708static inline void 709xge_os_dma_unmap(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr, 710 size_t size, int dir) 711{ 712 bus_dmamap_unload(dmah.dma_tag, dmah.dma_map); 713 return; 714} 715 716/****************************************** 717 * xge_os_dma_sync - Synchronize mapped memory. 718 * @pdev: Device context. Used to allocate/pin/map/unmap DMA-able memory. 719 * @dmah: DMA handle used to map the memory block. Obtained via 720 * xge_os_dma_malloc(). 721 * @dma_addr: DMA address of the block. Obtained via xge_os_dma_map(). 722 * @dma_offset: Offset from start of the blocke. Used by Solaris only. 723 * @length: Size of the block. 724 * @dir: Direction of this operation (XGE_OS_DMA_DIR_TODEVICE, etc.) 725 * 726 * Make physical and CPU memory consistent for a single 727 * streaming mode DMA translation. 728 * This API compiles to NOP on cache-coherent platforms. 729 * On non cache-coherent platforms, depending on the direction 730 * of the "sync" operation, this API will effectively 731 * either invalidate CPU cache (that might contain old data), 732 * or flush CPU cache to update physical memory. 733 * See also: xge_os_dma_malloc(), xge_os_dma_map(), 734 * xge_os_dma_unmap(). 735 ******************************************/ 736static inline void 737xge_os_dma_sync(pci_dev_h pdev, pci_dma_h dmah, dma_addr_t dma_addr, 738 u64 dma_offset, size_t length, int dir) 739{ 740 bus_dmasync_op_t syncop; 741 switch(dir) { 742 case XGE_OS_DMA_DIR_TODEVICE: 743 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTWRITE; 744 break; 745 746 case XGE_OS_DMA_DIR_FROMDEVICE: 747 syncop = BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD; 748 break; 749 750 case XGE_OS_DMA_DIR_BIDIRECTIONAL: 751 syncop = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREWRITE; 752 break; 753 } 754 bus_dmamap_sync(dmah.dma_tag, dmah.dma_map, syncop); 755 return; 756} 757 758#endif /* XGE_OSDEP_H */ 759