From f552470eec83d3587c603922404ea5115c6963a7 Mon Sep 17 00:00:00 2001 From: Till Straumann Date: Thu, 21 Jul 2011 23:24:54 +0000 Subject: 2011-07-21 Till Straumann * if_em/e1000_osdep.h, if_em/e1000_osdep.c, if_em/if_em.c: added e1000_register()/e1000_unregister() to keep track of devices that are 'in-use'. This allows for sharing the low-level code between bsdnet and standalone drivers (e.g., for PtP GigE links). --- bsd_eth_drivers/if_em/e1000_osdep.c | 95 +++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 10 deletions(-) (limited to 'bsd_eth_drivers/if_em/e1000_osdep.c') diff --git a/bsd_eth_drivers/if_em/e1000_osdep.c b/bsd_eth_drivers/if_em/e1000_osdep.c index 781e99d..eec749b 100644 --- a/bsd_eth_drivers/if_em/e1000_osdep.c +++ b/bsd_eth_drivers/if_em/e1000_osdep.c @@ -49,34 +49,57 @@ POSSIBILITY OF SUCH DAMAGE. #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 = hw->back; - pci_write_config_word( s->bus, s->dev, s->fun, reg, *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 = hw->back; - pci_read_config_word( s->bus, s->dev, s->fun, reg, 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) { -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) ); +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) { -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) ); +uint16_t v = (hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE); + e1000_write_pci_cfg( hw, PCIR_COMMAND, &v ); } /* @@ -115,6 +138,7 @@ void e1000_free_dev_spec_struct(struct e1000_hw *hw) { free ( hw->dev_spec ); + hw->dev_spec = 0; } @@ -156,3 +180,54 @@ struct timespec then, now; 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= 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; isig = PCISIG_INVAL; + break; + } + } + rtems_interrupt_enable(key); +} -- cgit v1.2.3