From patchwork Mon Sep 13 15:52:26 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyle Moffett X-Patchwork-Id: 71848 Return-Path: X-Original-To: wd@gemini.denx.de Delivered-To: wd@gemini.denx.de Received: from diddl.denx.de (diddl.denx.de [10.0.0.6]) by gemini.denx.de (Postfix) with ESMTP id 017D015242D for ; Mon, 13 Sep 2010 17:54:20 +0200 (CEST) Received: from diddl.denx.de (localhost.localdomain [127.0.0.1]) by diddl.denx.de (Postfix) with ESMTP id E28F431463C1 for ; Mon, 13 Sep 2010 17:54:19 +0200 (MEST) Received: from pop.mnet-online.de by diddl.denx.de with POP3 (fetchmail-6.3.17) for (single-drop); Mon, 13 Sep 2010 17:54:19 +0200 (MEST) Received: from murder ([192.168.6.180]) by backend2 (Cyrus v2.2.12) with LMTPA; Mon, 13 Sep 2010 17:53:54 +0200 X-Sieve: CMU Sieve 2.2 Received: from mail.m-online.net (localhost [127.0.0.1]) by frontend3.mail.m-online.net (Cyrus v2.2.12) with LMTPA; Mon, 13 Sep 2010 17:53:53 +0200 Received: from scanner-4.m-online.net (scanner-4.mail.m-online.net [192.168.1.18]) by mail.m-online.net (Postfix) with ESMTP id BF8411C000B2; Mon, 13 Sep 2010 17:53:53 +0200 (CEST) Received: from mxin-2.m-online.net ([192.168.1.21]) by scanner-4.m-online.net (scanner-4.m-online.net [192.168.1.18]) (amavisd-new, port 10026) with ESMTP id 00440-05-5; Mon, 13 Sep 2010 17:53:52 +0200 (CEST) Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by mxin-2.m-online.net (Postfix) with ESMTP id 0025D46C0BF; Mon, 13 Sep 2010 17:53:50 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8E6AB280EB; Mon, 13 Sep 2010 17:53:00 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QsuOqw-KEAhZ; Mon, 13 Sep 2010 17:53:00 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C4F79280EE; Mon, 13 Sep 2010 17:52:45 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D7631280E5 for ; Mon, 13 Sep 2010 17:52:42 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RkPuGK9T4nFw for ; Mon, 13 Sep 2010 17:52:42 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from firewall1 (wsip-70-167-241-26.dc.dc.cox.net [70.167.241.26]) by theia.denx.de (Postfix) with ESMTP id 2CFFA280B8 for ; Mon, 13 Sep 2010 17:52:35 +0200 (CEST) Received: from eternium.exmeritus.com (firewall2.exmeritus.com [10.13.38.2]) by firewall1 (Postfix) with ESMTP id 75979AC083; Mon, 13 Sep 2010 11:52:34 -0400 (EDT) From: Kyle Moffett To: u-boot@lists.denx.de Date: Mon, 13 Sep 2010 11:52:26 -0400 Message-Id: <1284393146-22142-5-git-send-email-Kyle.D.Moffett@boeing.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1284393146-22142-1-git-send-email-Kyle.D.Moffett@boeing.com> References: <1284393146-22142-1-git-send-email-Kyle.D.Moffett@boeing.com> Cc: Kyle Moffett , Kyle Moffett , Ben Warren Subject: [U-Boot] [PATCH 5/5] e1000: Add a small SPI driver wrapper around the EEPROM code X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de X-Virus-Scanned: by amavisd-new at m-online.net 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 --- 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 #include +#ifdef CONFIG_E1000_SPI +#include +#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;