1/************************************************************************** 2 3Copyright (c) 2001-2003, Intel Corporation 4All rights reserved. 5 6Redistribution and use in source and binary forms, with or without 7modification, are permitted provided that the following conditions are met: 8 9 1. Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 12 2. Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in the 14 documentation and/or other materials provided with the distribution. 15 16 3. Neither the name of the Intel Corporation nor the names of its 17 contributors may be used to endorse or promote products derived from 18 this software without specific prior written permission. 19 20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30POSSIBILITY OF SUCH DAMAGE. 31 32***************************************************************************/ 33 34#ifndef _IF_EM_OSDEP_H_ 35#define _IF_EM_OSDEP_H_ 36 37#include "driver.h" 38#include "device.h" 39#include "timer.h" 40#include "debug.h" 41 42#include <OS.h> 43#include <KernelExport.h> 44#include <ByteOrder.h> 45 46#include <stdlib.h> 47#include <string.h> 48#include <stdint.h> 49#include <sys/types.h> 50 51#define usec_delay(x) snooze(x) 52#define msec_delay(x) snooze(1000*(x)) 53 54// no longer used in FreeBSD 55#define splx(s) 56#define splimp() 0 57 58#ifndef bzero 59 #define bzero(d,c) memset((d), (0), (c)) 60#endif 61#ifndef bcopy 62 #define bcopy(s,d,c) memmove((d), (s), (c)) 63#endif 64#ifndef bcmp 65 #define bcmp(p1, p2, s) memcmp((p1), (p2), (s)) // XXX correct order? 66#endif 67 68#define TUNABLE_INT(a, b) /* ignored */ 69 70#define FALSE 0 71#define TRUE 1 72 73#define hz 1000000LL 74 75typedef bool boolean_t; 76typedef unsigned long vm_offset_t; 77 78 79struct em_osdep 80{ 81 ipro1000_device *dev; 82}; 83 84typedef ipro1000_device * device_t; 85 86#define PCIR_COMMAND PCI_command 87#define PCIR_REVID PCI_revision 88#define PCIR_SUBVEND_0 PCI_subsystem_vendor_id 89#define PCIR_SUBDEV_0 PCI_subsystem_id 90#define PCIM_CMD_IOEN 0x0001 91#define PCIM_CMD_MEMEN 0x0002 92#define PCIM_CMD_BUSMASTEREN 0x0004 93#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */ 94 95#define pci_read_config(dev, offset, size) \ 96 gPci->read_pci_config(dev->pciBus, dev->pciDev, dev->pciFunc, offset, size) 97 98#define pci_write_config(dev, offset, value, size) \ 99 gPci->write_pci_config(dev->pciBus, dev->pciDev, dev->pciFunc, offset, size, value) 100 101#define pci_get_vendor(dev) \ 102 gPci->read_pci_config(dev->pciBus, dev->pciDev, dev->pciFunc, PCI_vendor_id, 2) 103 104#define pci_get_device(dev) \ 105 gPci->read_pci_config(dev->pciBus, dev->pciDev, dev->pciFunc, PCI_device_id, 2) 106 107#define inl(port) \ 108 gPci->read_io_32(port) 109 110#define outl(port, value) \ 111 gPci->write_io_32(port, value) 112 113 114void *contigmalloc(int size, int p1, int p2, int p3, int p4, int p5, int p6); 115void contigfree(void *p, int p1, int p2); 116 117static inline u_int64_t vtophys(unsigned long virtual_addr) 118{ 119 physical_entry pe; 120 status_t err; 121 // vtophys is called for the start of any page aligned contiguous large buffer, 122 // and also with offset 2 into 2048 byte aligned (non-contiguous) rx/tx buffer. 123 // Thus we only ask for 2046 bytes to get exactly one physical_entry. If the 124 // next physical page is non-contiguous, using 2048 may return B_BUFFER_OVERFLOW. 125 err = get_memory_map((void *)virtual_addr, 2046, &pe, 1); 126 if (err < 0) 127 panic("ipro1000: get_memory_map failed for %p, error %08lx\n", (void *)virtual_addr, err); 128 return pe.address; 129} 130 131#define M_DEVBUF 1 132#define M_NOWAIT 2 133#define PAGE_SIZE 4096 134 135 136struct callout_handle 137{ 138 timer_id timer; 139}; 140 141void callout_handle_init(struct callout_handle *handle); 142struct callout_handle timeout(timer_function func, void *cookie, bigtime_t timeout); 143void untimeout(timer_function func, void *cookie, struct callout_handle handle); 144 145 146// resource management 147struct resource * bus_alloc_resource(device_t dev, int type, int *rid, int d, int e, int f, int g); 148void bus_release_resource(device_t dev, int type, int reg, struct resource *res); 149uint32 rman_get_start(struct resource *res); 150 151#define bus_generic_detach(dev) 152 153#define SYS_RES_IOPORT 0x01 154#define SYS_RES_MEMORY 0x02 155#define SYS_RES_IRQ 0x04 156#define RF_SHAREABLE 0 157#define RF_ACTIVE 0 158 159 160#define INTR_TYPE_NET 0 161int bus_setup_intr(device_t dev, struct resource *res, int p3, interrupt_handler int_func, void *cookie, void **tag); 162void bus_teardown_intr(device_t dev, struct resource *res, void *tag); 163 164 165#undef malloc 166#define malloc driver_malloc 167#undef free 168#define free driver_free 169 170void *driver_malloc(int size, int p2, int p3); 171void driver_free(void *p, int p2); 172 173/* GCC will always emit a read opcode when reading from */ 174/* a volatile pointer, even if the result is unused */ 175#define E1000_WRITE_FLUSH(a) \ 176 E1000_READ_REG(a, STATUS) 177 178/* Read from an absolute offset in the adapter's memory space */ 179#define E1000_READ_OFFSET(hw, offset) \ 180 (*(volatile uint32 *)((char *)(((struct em_osdep *)(hw)->back)->dev->regAddr) + offset)) 181 182/* Write to an absolute offset in the adapter's memory space */ 183#define E1000_WRITE_OFFSET(hw, offset, value) \ 184 (*(volatile uint32 *)((char *)(((struct em_osdep *)(hw)->back)->dev->regAddr) + offset) = value) 185 186/* Convert a register name to its offset in the adapter's memory space */ 187#define E1000_REG_OFFSET(hw, reg) \ 188 ((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg) 189 190#define E1000_READ_REG(hw, reg) \ 191 E1000_READ_OFFSET(hw, E1000_REG_OFFSET(hw, reg)) 192 193#define E1000_WRITE_REG(hw, reg, value) \ 194 E1000_WRITE_OFFSET(hw, E1000_REG_OFFSET(hw, reg), value) 195 196#define E1000_READ_REG_ARRAY(hw, reg, index) \ 197 E1000_READ_OFFSET(hw, E1000_REG_OFFSET(hw, reg) + ((index) << 2)) 198 199#define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \ 200 E1000_WRITE_OFFSET(hw, E1000_REG_OFFSET(hw, reg) + ((index) << 2), value) 201 202#define TAILQ_HEAD(name, type) \ 203 struct name { struct type *tqh_first, **tqh_last; } 204 205#define TAILQ_ENTRY(type) \ 206 struct { struct type *tqe_next, **tqe_prev; } 207 208#define TAILQ_FIRST(head) \ 209 ((head)->tqh_first) 210 211#define TAILQ_NEXT(elm, field) \ 212 ((elm)->field.tqe_next) 213 214#define TAILQ_FOREACH(var, head, field) \ 215 for ((var) = TAILQ_FIRST((head)); (var); (var) = TAILQ_NEXT((var), field)) 216 217#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ 218 for ((var) = TAILQ_FIRST((head)); \ 219 (var) && ((tvar) = TAILQ_NEXT((var), field), 1); (var) = (tvar)) 220 221#define TAILQ_INIT(head) do { \ 222 TAILQ_FIRST((head)) = NULL; \ 223 (head)->tqh_last = &TAILQ_FIRST((head)); \ 224} while (0) 225 226#define TAILQ_INSERT_HEAD(head, elm, field) do { \ 227 if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ 228 TAILQ_FIRST((head))->field.tqe_prev = &TAILQ_NEXT((elm), field); \ 229 else \ 230 (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 231 TAILQ_FIRST((head)) = (elm); \ 232 (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ 233} while (0) 234 235#define TAILQ_REMOVE(head, elm, field) do { \ 236 if ((TAILQ_NEXT((elm), field)) != NULL) \ 237 TAILQ_NEXT((elm), field)->field.tqe_prev = (elm)->field.tqe_prev; \ 238 else \ 239 (head)->tqh_last = (elm)->field.tqe_prev; \ 240 *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ 241} while (0) 242 243#endif 244