summaryrefslogtreecommitdiffstats
path: root/bsd_eth_drivers/if_em
diff options
context:
space:
mode:
Diffstat (limited to 'bsd_eth_drivers/if_em')
-rw-r--r--bsd_eth_drivers/if_em/.cvsignore1
-rw-r--r--bsd_eth_drivers/if_em/Makefile.am4
-rw-r--r--bsd_eth_drivers/if_em/e1000_osdep.c233
-rw-r--r--bsd_eth_drivers/if_em/e1000_osdep.h277
-rw-r--r--bsd_eth_drivers/if_em/if_em.c43
5 files changed, 445 insertions, 113 deletions
diff --git a/bsd_eth_drivers/if_em/.cvsignore b/bsd_eth_drivers/if_em/.cvsignore
new file mode 100644
index 0000000..70845e0
--- /dev/null
+++ b/bsd_eth_drivers/if_em/.cvsignore
@@ -0,0 +1 @@
+Makefile.in
diff --git a/bsd_eth_drivers/if_em/Makefile.am b/bsd_eth_drivers/if_em/Makefile.am
index 1a6a12f..f1e26b0 100644
--- a/bsd_eth_drivers/if_em/Makefile.am
+++ b/bsd_eth_drivers/if_em/Makefile.am
@@ -4,6 +4,7 @@ AUTOMAKE_OPTIONS=foreign
include $(top_srcdir)/rtems-pre.am
libif_em_a_SOURCES = if_em.c
+libif_em_a_SOURCES += e1000_osdep.c
libif_em_a_SOURCES += e1000_80003es2lan.c e1000_82540.c e1000_82541.c
libif_em_a_SOURCES += e1000_82543.c e1000_82571.c e1000_82575.c
libif_em_a_SOURCES += e1000_api.c e1000_mac.c e1000_manage.c
@@ -15,6 +16,8 @@ libif_em_a_SOURCES += e1000_defines.h e1000_hw.h e1000_ich8lan.h
libif_em_a_SOURCES += e1000_mac.h e1000_manage.h e1000_nvm.h
libif_em_a_SOURCES += e1000_osdep.h e1000_phy.h e1000_regs.h if_em.h
+if_em.$(OBJEXT): AM_SRC_CPPFLAGS=-D_KERNEL
+
EXTRA_libif_em_a_SOURCES = e1000_82542.c e1000_ich8lan.c
CPPFLAGS_82542_SUPPORT_NO = -DNO_82542_SUPPORT
@@ -35,5 +38,6 @@ AM_CPPFLAGS += -I$(srcdir)
AM_CPPFLAGS += -I$(srcdir)/../libbsdport -I../libbsdport -I../libbsdport/dummyheaders
AM_CPPFLAGS += $(CPPFLAGS_82542_SUPPORT_$(ENBL_82542_SUPPORT))
AM_CPPFLAGS += $(CPPFLAGS_ICH8LAN_SUPPORT_$(ENBL_ICH8LAN_SUPPORT))
+AM_CPPFLAGS += $(AM_SRC_CPPFLAGS)
include $(top_srcdir)/rtems.am
diff --git a/bsd_eth_drivers/if_em/e1000_osdep.c b/bsd_eth_drivers/if_em/e1000_osdep.c
new file mode 100644
index 0000000..eec749b
--- /dev/null
+++ b/bsd_eth_drivers/if_em/e1000_osdep.c
@@ -0,0 +1,233 @@
+/**************************************************************************
+
+Copyright (c) 2001-2007, Intel Corporation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+/*
+ * NOTE: the following routines using the e1000
+ * naming style are provided to the shared
+ * code which expects that rather than 'em'
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/pci.h>
+#include <e1000_api.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+
+#ifndef PCIR_COMMAND
+#define PCIR_COMMAND PCI_COMMAND
+#endif
+
+#define PCISIG_INVAL 0xffffffff
+
+#define PCISIG_MK(b,d,f) ( ((b)<<8) | (((d)&0x1f)<<3) | ((f)&7) )
+
+#define PCISIG_BUS(sig) ( ((sig) >> 8) & 0xffffff )
+#define PCISIG_DEV(sig) ( ((sig) >> 3) & 0x1f )
+#define PCISIG_FUN(sig) ( (sig) & 0x07 )
+
+
+static uint32_t e1k_devs[]={
+ PCISIG_INVAL,
+ PCISIG_INVAL,
+ PCISIG_INVAL,
+ PCISIG_INVAL,
+ PCISIG_INVAL,
+ PCISIG_INVAL,
+ PCISIG_INVAL,
+ PCISIG_INVAL
+};
+
+#define N_E1K_DEVS (sizeof(e1k_devs)/sizeof(e1k_devs[0]))
+
+void
+e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
+{
+struct e1000_pcisig *s_p = hw->back;
+uint32_t s = s_p->sig;
+
+ pci_write_config_word( PCISIG_BUS(s), PCISIG_DEV(s), PCISIG_FUN(s), reg, *value );
+}
+
+void
+e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
+{
+struct e1000_pcisig *s_p = hw->back;
+uint32_t s = s_p->sig;
+ pci_read_config_word( PCISIG_BUS(s), PCISIG_DEV(s), PCISIG_FUN(s), reg, value );
+}
+
+void
+e1000_pci_set_mwi(struct e1000_hw *hw)
+{
+uint16_t v = (hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE);
+ e1000_write_pci_cfg( hw, PCIR_COMMAND, &v );
+}
+
+void
+e1000_pci_clear_mwi(struct e1000_hw *hw)
+{
+uint16_t v = (hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE);
+ e1000_write_pci_cfg( hw, PCIR_COMMAND, &v );
+}
+
+/*
+ * Read the PCI Express capabilities
+ */
+int32_t
+e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
+{
+ int32_t error = E1000_SUCCESS;
+ uint16_t cap_off;
+
+ switch (hw->mac.type) {
+
+ case e1000_82571:
+ case e1000_82572:
+ case e1000_82573:
+ case e1000_80003es2lan:
+ cap_off = 0xE0;
+ e1000_read_pci_cfg(hw, cap_off + reg, value);
+ break;
+ default:
+ error = ~E1000_NOT_IMPLEMENTED;
+ break;
+ }
+
+ return (error);
+}
+
+int32_t
+e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, uint32_t size)
+{
+ return (hw->dev_spec = calloc(1, size)) ? 0 : ENOMEM;
+}
+
+void
+e1000_free_dev_spec_struct(struct e1000_hw *hw)
+{
+ free ( hw->dev_spec );
+ hw->dev_spec = 0;
+}
+
+
+void
+e1000_udelay(unsigned usecs)
+{
+rtems_interval clock_f, ticks;
+uint64_t tmp;
+struct timespec then, now;
+ rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &clock_f );
+
+ /* round up to next tick:
+ floor( f*T + .5 ) = floor( f*T_us/1e6 + 0.5 )
+ = floor( (f * T_us + 5e5) / 1e6 )
+ */
+ tmp = (uint64_t)clock_f * (uint64_t)usecs;
+
+ if ( tmp < 500000ULL ) {
+ /* less than half a tick -- busy wait */
+ clock_gettime( CLOCK_REALTIME, &then );
+ then.tv_sec += usecs/1000000;
+ then.tv_nsec += (usecs % 1000000)*1000;
+ if ( then.tv_nsec >= 1000000000 ) {
+ then.tv_nsec -= 1000000000;
+ then.tv_sec++;
+ }
+
+ do {
+ clock_gettime( CLOCK_REALTIME, &now );
+
+ } while ( now.tv_sec < then.tv_sec ||
+ (now.tv_sec == then.tv_sec && now.tv_nsec < then.tv_nsec) );
+ } else {
+ tmp += 500000ULL;
+ tmp /= 1000000ULL;
+
+ ticks = (rtems_interval)tmp;
+
+ rtems_task_wake_after( ticks );
+ }
+}
+
+int
+e1000_register(struct e1000_pcisig *s_p, unsigned b, unsigned d, unsigned f )
+{
+int i,j,key;
+uint32_t sig = PCISIG_MK(b,d,f);
+
+ if ( PCISIG_INVAL == sig )
+ return -1;
+
+ j = -1;
+
+ rtems_interrupt_disable(key);
+ for ( i = 0; i<N_E1K_DEVS; i++ ) {
+ if ( PCISIG_INVAL == e1k_devs[i] ) {
+ j = i;
+ } else if ( sig == e1k_devs[i] ) {
+ j = -1;
+ break;
+ }
+ }
+ if ( j >= 0 ) {
+ e1k_devs[j] = sig;
+ if ( s_p )
+ s_p->sig = sig;
+ }
+ rtems_interrupt_enable(key);
+
+ return j < 0;
+}
+
+void
+e1000_unregister(struct e1000_pcisig *s_p)
+{
+int i,key;
+uint32_t sig = s_p ? s_p->sig : PCISIG_INVAL;
+
+ if ( PCISIG_INVAL == sig )
+ return;
+
+ rtems_interrupt_disable(key);
+ for ( i = 0; i<N_E1K_DEVS; i++ ) {
+ if ( sig == e1k_devs[i] ) {
+ e1k_devs[i] = PCISIG_INVAL;
+ if ( s_p )
+ s_p->sig = PCISIG_INVAL;
+ break;
+ }
+ }
+ rtems_interrupt_enable(key);
+}
diff --git a/bsd_eth_drivers/if_em/e1000_osdep.h b/bsd_eth_drivers/if_em/e1000_osdep.h
index b5aa603..c6796f1 100644
--- a/bsd_eth_drivers/if_em/e1000_osdep.h
+++ b/bsd_eth_drivers/if_em/e1000_osdep.h
@@ -37,29 +37,17 @@ POSSIBILITY OF SUCH DAMAGE.
#define _FREEBSD_OS_H_
#include <rtems.h>
-#define _KERNEL
-#include <rtems/rtems_bsdnet_internal.h>
#include <bsp.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
#include <rtems/pci.h>
-
-#define ASSERT(x) if(!(x)) panic("EM: x")
+#include <vm/vm.h> /* for non-_KERNEL boolean_t :-( */
/* The happy-fun DELAY macro is defined in /usr/src/sys/i386/include/clock.h */
-#define usec_delay(x) DELAY(x)
-#define msec_delay(x) DELAY(1000*(x))
+#define usec_delay(x) e1000_udelay(x)
+#define msec_delay(x) e1000_udelay(1000*(x))
/* TODO: Should we be paranoid about delaying in interrupt context? */
-#define msec_delay_irq(x) DELAY(1000*(x))
-#include <rtems_udelay.h>
+#define msec_delay_irq(x) msec_delay(x)
+
+void e1000_udelay(unsigned);
#define MSGOUT(S, A, B) printf(S "\n", A, B)
#define DEBUGFUNC(F) DEBUGOUT(F);
@@ -69,13 +57,16 @@ POSSIBILITY OF SUCH DAMAGE.
#define DEBUGOUT3(S,A,B,C)
#define DEBUGOUT7(S,A,B,C,D,E,F,G)
+
#define STATIC static
+
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
+
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
@@ -92,90 +83,86 @@ typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8 ;
-#include <devicet.h>
+typedef volatile uint32_t __uint32_va_t __attribute__((may_alias));
+typedef volatile uint16_t __uint16_va_t __attribute__((may_alias));
-struct e1000_osdep
-{
- uint32_t mem_bus_space_handle;
- uint32_t io_bus_space_handle;
- uint32_t flash_bus_space_handle;
- /* these are currently unused; present for freebsd compatibility only */
- uint32_t mem_bus_space_tag;
- uint32_t io_bus_space_tag;
- uint32_t flash_bus_space_tag;
- device_t dev;
+struct e1000_pcisig {
+ uint32_t sig;
};
-typedef volatile uint32_t __attribute__((may_alias)) *__uint32_a_p_t;
-typedef volatile uint16_t __attribute__((may_alias)) *__uint16_a_p_t;
-typedef volatile uint8_t __attribute__((may_alias)) * __uint8_a_p_t;
+/* Register an instance; if this returns nonzero
+ * then registration failed and the device with
+ * the pci signature passed in MUST NOT be used
+ * (since it is already in use by another driver).
+ */
+int
+e1000_register(struct e1000_pcisig *sig_p_out, unsigned bus, unsigned dev, unsigned fun);
+
+void
+e1000_unregister(struct e1000_pcisig *sig_p);
+#ifdef NO_82542_SUPPORT
+#define E1000_REGISTER(hw, reg) reg
+#else
+#define E1000_REGISTER(hw, reg) (((hw)->mac.type >= e1000_82543) \
+ ? reg : e1000_translate_register_82542(reg))
+#endif
+
+#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, E1000_STATUS)
+
+/* Provide our own I/O so that the low-level driver API can
+ * be used independently from the BSD stuff.
+ * This is useful for people who want to use an e1000 adapter
+ * for special ethernet links that do not use BSD TCP/IP.
+ */
#ifdef __PPC__
-#include <libcpu/io.h>
-static inline uint8_t __in_8(uint32_t base, uint32_t offset)
-{
-__uint8_a_p_t a = (__uint8_a_p_t)(base+offset);
-uint8_t rval;
- __asm__ __volatile__(
- "sync;\n"
- "lbz%U1%X1 %0,%1;\n"
- "twi 0,%0,0;\n"
- "isync" : "=r" (rval) : "m"(*a));
- return rval;
-}
-static inline void __out_8(uint32_t base, uint32_t offset, uint8_t val)
-{
-__uint8_a_p_t a = (__uint8_a_p_t)(base+offset);
- __asm__ __volatile__(
- "stb%U0%X0 %1,%0; eieio" : "=m" (*a) : "r"(val)
- );
-}
+#include <libcpu/io.h>
-static inline uint16_t __in_le16(uint32_t base, uint32_t offset)
+static inline uint16_t __in_le16(uint8_t *base, uint32_t offset)
{
-__uint16_a_p_t a = (__uint16_a_p_t)(base+offset);
uint16_t rval;
- __asm__ __volatile__(
- "sync;\n"
- "lhbrx %0,0,%1;\n"
- "twi 0,%0,0;\n"
- "isync" : "=r" (rval) : "r"(a), "m"(*a));
- return rval;
+ __asm__ __volatile__(
+ "lhbrx %0,%2,%1; eieio\n"
+ : "=r" (rval)
+ : "r"(base), "b"(offset), "m"(*(__uint16_va_t*)(base + offset))
+ );
+ return rval;
}
-static inline void __out_le16(uint32_t base, uint32_t offset, uint16_t val)
+static inline void __out_le16(uint8_t *base, uint32_t offset, uint16_t val)
{
-__uint16_a_p_t a = (__uint16_a_p_t)(base+offset);
- __asm__ __volatile__(
- "sync; sthbrx %1,0,%2" : "=m" (*a) : "r"(val), "r"(a)
- );
+ __asm__ __volatile__(
+ "sthbrx %1,%3,%2; eieio"
+ : "=o"(*(__uint16_va_t*)(base+offset))
+ : "r"(val), "r"(base), "b"(offset)
+ );
}
-static inline uint32_t __in_le32(uint32_t base, uint32_t offset)
+static inline uint32_t __in_le32(uint8_t *base, uint32_t offset)
{
-__uint32_a_p_t a = (__uint32_a_p_t)(base+offset);
uint32_t rval;
- __asm__ __volatile__(
- "sync;\n"
- "lwbrx %0,0,%1;\n"
- "twi 0,%0,0;\n"
- "isync" : "=r" (rval) : "r"(a), "m"(*a));
- return rval;
+ __asm__ __volatile__(
+ "lwbrx %0,%2,%1; eieio\n"
+ : "=r" (rval)
+ : "r"(base), "b"(offset), "m"(*(__uint32_va_t*)(base + offset))
+ );
+ return rval;
}
-static inline void __out_le32(uint32_t base, uint32_t offset, uint32_t val)
+static inline void __out_le32(uint8_t *base, uint32_t offset, uint32_t val)
{
-__uint32_a_p_t a = (__uint32_a_p_t)(base+offset);
- __asm__ __volatile__(
- "sync; stwbrx %1,0,%2" : "=m" (*a) : "r"(val), "r"(a)
- );
+ __asm__ __volatile__(
+ "stwbrx %1,%3,%2; eieio"
+ : "=o"(*(__uint32_va_t*)(base+offset))
+ : "r"(val), "r"(base), "b"(offset)
+ );
}
#ifdef _IO_BASE
-static inline void __outport_dword(uint32_t base, uint32_t off, uint32_t val)
+static inline void __outport_dword(unsigned long base, uint32_t off, uint32_t val)
{
- __out_le32(_IO_BASE+base+off,0,val);
+ __out_le32((uint8_t*)(_IO_BASE+base), off, val);
}
#else
#error "_IO_BASE needs to be defined by BSP (bsp.h)"
@@ -183,60 +170,81 @@ static inline void __outport_dword(uint32_t base, uint32_t off, uint32_t val)
#elif defined(__i386__)
#include <libcpu/cpu.h>
-static inline uint8_t __in_8(uint32_t base, uint32_t offset)
-{
-__uint8_a_p_t a = (__uint8_a_p_t)(base+offset);
- return *a;
-}
-
-static inline void __out_8(uint32_t base, uint32_t offset, uint8_t val)
-{
-__uint8_a_p_t a = (__uint8_a_p_t)(base+offset);
- *a = val;
-}
-static inline uint16_t __in_le16(uint32_t base, uint32_t offset)
+static inline uint16_t __in_le16(uint8_t *base, uint32_t offset)
{
-__uint16_a_p_t a = (__uint16_a_p_t)(base+offset);
- return *a;
+ return *(__uint16_va_t*)(base + offset);
}
-static inline void __out_le16(uint32_t base, uint32_t offset, uint16_t val)
+static inline void __out_le16(uint8_t *base, uint32_t offset, uint16_t val)
{
-__uint16_a_p_t a = (__uint16_a_p_t)(base+offset);
- *a = val;
+ *(__uint16_va_t*)(base + offset) = val;
}
-static inline uint32_t __in_le32(uint32_t base, uint32_t offset)
+static inline uint32_t __in_le32(uint8_t *base, uint32_t offset)
{
-__uint32_a_p_t a = (__uint32_a_p_t)(base+offset);
- return *a;
+ return *(__uint32_va_t*)(base + offset);
}
-static inline void __out_le32(uint32_t base, uint32_t offset, uint32_t val)
+static inline void __out_le32(uint8_t *base, uint32_t offset, uint32_t val)
{
-__uint32_a_p_t a = (__uint32_a_p_t)(base+offset);
- *a = val;
+ *(__uint32_va_t*)(base + offset) = val;
}
-
-static inline void __outport_dword(uint32_t base, uint32_t off, uint32_t val)
+static inline void __outport_dword(unsigned long base, uint32_t off, uint32_t val)
{
i386_outport_long( (base + off), val );
}
#else
-#error "not ported to this CPU architecture yet"
+#warning "not ported to this CPU architecture yet -- using libbsdport I/O"
+#define USE_LIBBSDPORT_IO
#endif
-#ifdef NO_82542_SUPPORT
-#define E1000_REGISTER(hw, reg) reg
-#else
-#define E1000_REGISTER(hw, reg) (((hw)->mac.type >= e1000_82543) \
- ? reg : e1000_translate_register_82542(reg))
+#if defined(USE_LIBBSDPORT_IO) && !defined(_KERNEL)
+#define _KERNEL
#endif
-#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, E1000_STATUS)
+#ifdef _KERNEL
+#ifndef __INSIDE_RTEMS_BSD_TCPIP_STACK__
+#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
+#endif
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/rtems_bsdnet_internal.h>
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+
+#define ASSERT(x) if(!(x)) panic("EM: x")
+
+#include <devicet.h>
+
+struct e1000_osdep
+{
+ /* struct e1000_pcisig MUST be first since
+ * 'back' pointer is cast to (struct e1000_pcisig *)
+ * in e1000_osdep.c!
+ */
+ struct e1000_pcisig pcisig;
+ uint32_t mem_bus_space_handle;
+ uint32_t io_bus_space_handle;
+ uint32_t flash_bus_space_handle;
+ /* these are currently unused; present for freebsd compatibility only */
+ uint32_t mem_bus_space_tag;
+ uint32_t io_bus_space_tag;
+ uint32_t flash_bus_space_tag;
+ device_t dev;
+};
+#endif
+
+#ifdef USE_LIBBSDPORT_IO
#define USE_EXPLICIT_BUSTAGS
@@ -393,5 +401,52 @@ static inline void __outport_dword(uint32_t base, uint32_t off, uint32_t val)
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
#endif /* USE_EXPLICIT_BUSTAGS */
+#else /* USE_LIBBSDPORT_IO */
+
+/* Read from an absolute offset in the adapter's memory space */
+#define E1000_READ_OFFSET(hw, offset) \
+ __in_le32((hw)->hw_addr, offset)
+
+/* Write to an absolute offset in the adapter's memory space */
+#define E1000_WRITE_OFFSET(hw, offset, value) \
+ __out_le32((hw)->hw_addr, offset, value)
+
+/* Register READ/WRITE macros */
+
+#define E1000_READ_REG(hw, reg) \
+ __in_le32((hw)->hw_addr, E1000_REGISTER(hw, reg))
+
+#define E1000_WRITE_REG(hw, reg, value) \
+ __out_le32((hw)->hw_addr, E1000_REGISTER(hw, reg), value)
+
+#define E1000_READ_REG_ARRAY(hw, reg, index) \
+ __in_le32((hw)->hw_addr, E1000_REGISTER(hw, reg) + ((index)<< 2))
+
+#define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \
+ __out_le32((hw)->hw_addr, E1000_REGISTER(hw, reg) + ((index)<< 2), value)
+
+#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
+#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
+
+#define E1000_WRITE_REG_IO(hw, reg, value) do { \
+ __outport_dword((hw)->io_base, 0, reg); \
+ __outport_dword((hw)->io_base, 4, value); \
+ } while (0)
+
+#define E1000_READ_FLASH_REG(hw, reg) \
+ __in_le32( (hw)->flash_address, reg )
+
+#define E1000_READ_FLASH_REG16(hw, reg) \
+ __in_le16( (hw)->flash_address, reg )
+
+#define E1000_WRITE_FLASH_REG(hw, reg, value) \
+ __out_le32( (hw)->flash_address, reg, value )
+
+#define E1000_WRITE_FLASH_REG16(hw, reg, value) \
+ __out_le16( (hw)->flash_address, reg, value )
+
+#endif /* USE_LIBBSDPORT_IO */
+
+
#endif /* _FREEBSD_OS_H_ */
diff --git a/bsd_eth_drivers/if_em/if_em.c b/bsd_eth_drivers/if_em/if_em.c
index 71d1227..f0e06d6 100644
--- a/bsd_eth_drivers/if_em/if_em.c
+++ b/bsd_eth_drivers/if_em/if_em.c
@@ -413,8 +413,6 @@ TUNABLE_INT("hw.em.rx_process_limit", &em_rx_process_limit);
#endif
#ifdef __rtems__
-int em_bootverbose = 0;
-#define bootverbose em_bootverbose
#undef static
#define static static
#endif
@@ -461,6 +459,22 @@ em_probe(device_t dev)
((pci_subdevice_id == ent->subdevice_id) ||
(ent->subdevice_id == PCI_ANY_ID))) {
+#ifdef __rtems__
+ /* Copy PCI signature to the low-level (bsd-agnostic)
+ * support struct and register with ll-support. This
+ * step also detects if the device is already in use.
+ */
+ {
+ struct adapter *adapter = device_get_softc(dev);
+
+ if ( e1000_register( &adapter->osdep.pcisig,
+ dev->bushdr.pci.bus,
+ dev->bushdr.pci.dev,
+ dev->bushdr.pci.fun ) ) {
+ return (EBUSY);
+ }
+ }
+#endif
sprintf(adapter_name, "%s %s",
em_strings[ent->index],
em_driver_version);
@@ -825,6 +839,10 @@ err_pci:
em_free_pci_resources(adapter);
EM_LOCK_DESTROY(adapter);
+#ifdef __rtems__
+ e1000_unregister( &adapter->osdep.pcisig );
+#endif
+
return (error);
}
@@ -900,6 +918,10 @@ em_detach(device_t dev)
EM_LOCK_DESTROY(adapter);
+#ifdef __rtems__
+ e1000_unregister( &adapter->osdep.pcisig );
+#endif
+
return (0);
}
@@ -2663,7 +2685,11 @@ em_allocate_pci_resources(struct adapter *adapter)
rman_get_bustag(adapter->res_memory);
adapter->osdep.mem_bus_space_handle =
rman_get_bushandle(adapter->res_memory);
+#ifndef __rtems__
adapter->hw.hw_addr = (uint8_t*)&adapter->osdep.mem_bus_space_handle;
+#else
+ adapter->hw.hw_addr = (uint8_t*)adapter->res_memory;
+#endif
/* Only older adapters use IO mapping */
if ((adapter->hw.mac.type >= e1000_82543) && /* __rtems__ >82542 -> >= 82543 */
@@ -2691,7 +2717,12 @@ em_allocate_pci_resources(struct adapter *adapter)
"ioport\n");
return (ENXIO);
}
+#ifndef __rtems__
adapter->hw.io_base = 0;
+#else
+ adapter->hw.io_base = (unsigned long)adapter->res_ioport
+ & PCI_BASE_ADDRESS_IO_MASK;
+#endif
adapter->osdep.io_bus_space_tag =
rman_get_bustag(adapter->res_ioport);
adapter->osdep.io_bus_space_handle =
@@ -3281,9 +3312,15 @@ em_initialize_transmit_unit(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_TDT, 0);
E1000_WRITE_REG(&adapter->hw, E1000_TDH, 0);
+#ifndef __rtems__
HW_DEBUGOUT2("Base = %x, Length = %x\n",
E1000_READ_REG(&adapter->hw, E1000_TDBAL),
E1000_READ_REG(&adapter->hw, E1000_TDLEN));
+#else
+ HW_DEBUGOUT2("Base = %x, Length = %x\n",
+ (unsigned)E1000_READ_REG(&adapter->hw, E1000_TDBAL),
+ (unsigned)E1000_READ_REG(&adapter->hw, E1000_TDLEN));
+#endif
/* Set the default values for the Tx Inter Packet Gap timer */
switch (adapter->hw.mac.type) {
@@ -4769,6 +4806,7 @@ em_is_valid_ether_addr(uint8_t *addr)
return (TRUE);
}
+#ifndef __rtems__
/*
* NOTE: the following routines using the e1000
* naming style are provided to the shared
@@ -4851,6 +4889,7 @@ e1000_free_dev_spec_struct(struct e1000_hw *hw)
free(hw->dev_spec, M_DEVBUF);
return;
}
+#endif
/*
* Enable PCI Wake On Lan capability