summaryrefslogtreecommitdiffstats
path: root/bsd_eth_drivers/if_em/e1000_osdep.c
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 /bsd_eth_drivers/if_em/e1000_osdep.c
parent2010-07-23 Till Straumann <Till.Straumann@TU-Berlin.de> (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).
Diffstat (limited to 'bsd_eth_drivers/if_em/e1000_osdep.c')
-rw-r--r--bsd_eth_drivers/if_em/e1000_osdep.c158
1 files changed, 158 insertions, 0 deletions
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 );
+ }
+}