To make it possible to use the "sspi" command with the e1000 firmware EEPROM we add a small "generic SPI" driver wrapper around the existing e1000 SPI backend.
Signed-off-by: Kyle Moffett <kyle.d.moff...@boeing.com> --- drivers/net/e1000.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++- drivers/net/e1000.h | 7 ++++ 2 files changed, 98 insertions(+), 1 deletions(-) diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 4ff845a..70457f1 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -5259,7 +5259,7 @@ e1000_initialize(bd_t * bis) return i; } -#ifdef CONFIG_CMD_E1000 +#if defined(CONFIG_E1000_SPI) || defined(CONFIG_CMD_E1000) static struct e1000_hw *e1000_find_card(unsigned int cardnum) { struct e1000_hw *hw; @@ -5338,6 +5338,96 @@ static int e1000_spi_xfer(struct e1000_hw *hw, unsigned int bitlen, return 0; } +#endif /* defined(CONFIG_E1000_SPI) || defined(CONFIG_CMD_E1000) */ + +#ifdef CONFIG_E1000_SPI +static inline struct e1000_hw *e1000_hw_from_spi(struct spi_slave *spi) +{ + return container_of(spi, struct e1000_hw, spi); +} + +/* Not sure why all of these are necessary */ +void spi_init_r(void) { /* Nothing to do */ } +void spi_init_f(void) { /* Nothing to do */ } +void spi_init(void) { /* Nothing to do */ } + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + /* Find the right PCI device */ + struct e1000_hw *hw = e1000_find_card(bus); + if (!hw) { + printf("ERROR: No such e1000 device: e1000#%u\n", bus); + return NULL; + } + + /* Make sure it has an SPI chip */ + if (hw->eeprom.type != e1000_eeprom_spi) { + printf("%s: No attached SPI EEPROM found!\n", hw->nic->name); + return NULL; + } + + /* Argument sanity checks */ + if (cs != 0) { + printf("%s: No such SPI chip: %u\n", hw->nic->name, cs); + return NULL; + } + if (mode != SPI_MODE_0) { + printf("%s: Cannot support SPI modes other than MODE-0\n", + hw->nic->name); + return NULL; + } + + /* TODO: Use max_hz somehow */ + printf("%s: EEPROM SPI access requested\n", hw->nic->name); + return &hw->spi; +} + +void spi_free_slave(struct spi_slave *spi) +{ + struct e1000_hw *hw = e1000_hw_from_spi(spi); + printf("%s: EEPROM SPI access released\n", hw->nic->name); +} + +int spi_claim_bus(struct spi_slave *spi) +{ + struct e1000_hw *hw = e1000_hw_from_spi(spi); + + if (e1000_acquire_eeprom(hw)) { + printf("%s: EEPROM SPI cannot be acquired!", hw->nic->name); + return -1; + } + + return 0; +} + +void spi_release_bus(struct spi_slave *spi) +{ + struct e1000_hw *hw = e1000_hw_from_spi(spi); + e1000_release_eeprom(hw); +} + +/* Skinny wrapper around e1000_spi_xfer */ +int spi_xfer(struct spi_slave *spi, unsigned int bitlen, + const void *dout_mem, void *din_mem, unsigned long flags) +{ + struct e1000_hw *hw = e1000_hw_from_spi(spi); + int ret; + + if (flags & SPI_XFER_BEGIN) + e1000_standby_eeprom(hw); + + ret = e1000_spi_xfer(hw, bitlen, dout_mem, din_mem, TRUE); + + if (flags & SPI_XFER_END) + e1000_standby_eeprom(hw); + + return ret; +} + +#endif /* CONFIG_E1000_SPI */ + +#ifdef CONFIG_CMD_E1000 /* The EEPROM opcodes */ #define SPI_EEPROM_ENABLE_WR 0x06 diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 68a3409..f504c90 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -41,6 +41,10 @@ #include <asm/io.h> #include <pci.h> +#ifdef CONFIG_E1000_SPI +#include <spi.h> +#endif + #define E1000_ERR(args...) printf("e1000: " args) #ifdef E1000_DEBUG @@ -1046,6 +1050,9 @@ typedef enum { struct e1000_hw { struct list_head list_node; struct eth_device *nic; +#ifdef CONFIG_E1000_SPI + struct spi_slave spi; +#endif unsigned int cardnum; pci_dev_t pdev; -- 1.7.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot