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