summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2011-07-20 17:25:21 +0000
committerTill Straumann <strauman@slac.stanford.edu>2011-07-20 17:25:21 +0000
commit88f653ad2e278a42c3c1c480022820abdeea233f (patch)
tree56329574a0093a9db1385b31124d9e92136afec3
parent9d32a19998f9b70249bdf9daa8efde9262d71b9e (diff)
downloadlibbsdport-88f653ad2e278a42c3c1c480022820abdeea233f.tar.bz2
2011-07-20 Till Straumann <Till.Straumann@TU-Berlin.de>
* if_em/Makefile.am, if_em/e1000_osdep.h, if_em/e1000_osdep.c, if_em/if_em.c: added e1000_osdep.c which implements all os-dependent parts in a bsdnet-agnostic fashion. Hence, the low-level driver can be used w/o bsdnet. FIXES: dependency on bsdnet initialization; PCI bus header was not initialized when not used via bsdnet (lanIpBasic driver crashed).
-rw-r--r--bsd_eth_drivers/ChangeLog12
-rw-r--r--bsd_eth_drivers/if_em/Makefile.am5
-rw-r--r--bsd_eth_drivers/if_em/e1000_osdep.c158
-rw-r--r--bsd_eth_drivers/if_em/e1000_osdep.h91
-rw-r--r--bsd_eth_drivers/if_em/if_em.c14
5 files changed, 241 insertions, 39 deletions
diff --git a/bsd_eth_drivers/ChangeLog b/bsd_eth_drivers/ChangeLog
index c07d347..8d56291 100644
--- a/bsd_eth_drivers/ChangeLog
+++ b/bsd_eth_drivers/ChangeLog
@@ -1,4 +1,14 @@
-2010-07-23 Till Straumann <Till.Straumann@TU-Berlin.de>
+2011-07-20 Till Straumann <Till.Straumann@TU-Berlin.de>
+
+ * if_em/Makefile.am, if_em/e1000_osdep.h, if_em/e1000_osdep.c,
+ if_em/if_em.c: added e1000_osdep.c which implements all
+ os-dependent parts in a bsdnet-agnostic fashion. Hence, the
+ low-level driver can be used w/o bsdnet.
+ FIXES: dependency on bsdnet initialization; PCI bus header
+ was not initialized when not used via bsdnet (lanIpBasic driver
+ crashed).
+
+2010-07-23 Till Straumann <Till.Straumann@TU-Berlin.de>
* libbsdport/devicet.c: Initialize libbspExt.
diff --git a/bsd_eth_drivers/if_em/Makefile.am b/bsd_eth_drivers/if_em/Makefile.am
index a795ef8..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
@@ -31,10 +34,10 @@ libif_em_a_DEPENDENCIES = $(libif_em_a_LIBADD)
lib_LIBRARIES = libif_em.a
-AM_CPPFLAGS += -D_KERNEL
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..781e99d
--- /dev/null
+++ b/bsd_eth_drivers/if_em/e1000_osdep.c
@@ -0,0 +1,158 @@
+/**************************************************************************
+
+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
+
+void
+e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
+{
+struct e1000_pcisig *s = hw->back;
+ pci_write_config_word( s->bus, s->dev, s->fun, reg, *value );
+}
+
+void
+e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
+{
+struct e1000_pcisig *s = hw->back;
+ pci_read_config_word( s->bus, s->dev, s->fun, reg, value );
+}
+
+void
+e1000_pci_set_mwi(struct e1000_hw *hw)
+{
+struct e1000_pcisig *s = hw->back;
+ pci_write_config_word( s->bus, s->dev, s->fun, PCIR_COMMAND,
+ (hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE) );
+}
+
+void
+e1000_pci_clear_mwi(struct e1000_hw *hw)
+{
+struct e1000_pcisig *s = hw->back;
+ pci_write_config_word( s->bus, s->dev, s->fun, PCIR_COMMAND,
+ (hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE) );
+}
+
+/*
+ * 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 );
+}
+
+
+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 );
+ }
+}
diff --git a/bsd_eth_drivers/if_em/e1000_osdep.h b/bsd_eth_drivers/if_em/e1000_osdep.h
index 96a7d84..134c4cc 100644
--- a/bsd_eth_drivers/if_em/e1000_osdep.h
+++ b/bsd_eth_drivers/if_em/e1000_osdep.h
@@ -41,31 +41,13 @@ POSSIBILITY OF SUCH DAMAGE.
#include <rtems/pci.h>
#include <vm/vm.h> /* for non-_KERNEL boolean_t :-( */
-#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")
-
/* 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);
@@ -75,22 +57,8 @@ POSSIBILITY OF SUCH DAMAGE.
#define DEBUGOUT3(S,A,B,C)
#define DEBUGOUT7(S,A,B,C,D,E,F,G)
-#include <devicet.h>
-
-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;
-};
#define STATIC static
-#endif
#ifndef FALSE
#define FALSE 0
@@ -118,6 +86,12 @@ typedef int8_t s8 ;
typedef volatile uint32_t __uint32_va_t __attribute__((may_alias));
typedef volatile uint16_t __uint16_va_t __attribute__((may_alias));
+struct e1000_pcisig {
+ uint16_t bus;
+ uint8_t dev;
+ uint8_t fun;
+};
+
#ifdef NO_82542_SUPPORT
#define E1000_REGISTER(hw, reg) reg
#else
@@ -218,6 +192,49 @@ static inline void __outport_dword(unsigned long base, uint32_t off, uint32_t va
#define USE_LIBBSDPORT_IO
#endif
+#if defined(USE_LIBBSDPORT_IO) && !defined(_KERNEL)
+#define _KERNEL
+#endif
+
+#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
diff --git a/bsd_eth_drivers/if_em/if_em.c b/bsd_eth_drivers/if_em/if_em.c
index 05d4216..9d2f8d5 100644
--- a/bsd_eth_drivers/if_em/if_em.c
+++ b/bsd_eth_drivers/if_em/if_em.c
@@ -441,6 +441,18 @@ em_probe(device_t dev)
INIT_DEBUGOUT("em_probe: begin");
+#ifdef __rtems__
+ /* copy PCI signature to the low-level (bsd-agnostic) support
+ * struct.
+ */
+ {
+ struct adapter *adapter = device_get_softc(dev);
+ adapter->osdep.pcisig.bus = dev->bushdr.pci.bus;
+ adapter->osdep.pcisig.dev = dev->bushdr.pci.dev;
+ adapter->osdep.pcisig.fun = dev->bushdr.pci.fun;
+ }
+#endif
+
pci_vendor_id = pci_get_vendor(dev);
if (pci_vendor_id != EM_VENDOR_ID)
return (ENXIO);
@@ -4782,6 +4794,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
@@ -4864,6 +4877,7 @@ e1000_free_dev_spec_struct(struct e1000_hw *hw)
free(hw->dev_spec, M_DEVBUF);
return;
}
+#endif
/*
* Enable PCI Wake On Lan capability