diff options
Diffstat (limited to 'bsd_eth_drivers/if_em/e1000_osdep.c')
-rw-r--r-- | bsd_eth_drivers/if_em/e1000_osdep.c | 158 |
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 ); + } +} |