diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2007-11-21 21:19:24 +0100 |
---|---|---|
committer | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2007-11-25 18:35:17 +0100 |
commit | 2439e4bfa111babf4bc07ba20efbf3e36036813e (patch) | |
tree | 21e94282acdc681bdde2ccc270bd401254124d00 /drivers/eepro100.c | |
parent | 352d259130b349fe9593b8dada641bd78a9659e5 (diff) | |
download | u-boot-imx-2439e4bfa111babf4bc07ba20efbf3e36036813e.zip u-boot-imx-2439e4bfa111babf4bc07ba20efbf3e36036813e.tar.gz u-boot-imx-2439e4bfa111babf4bc07ba20efbf3e36036813e.tar.bz2 |
drivers/net : move net drivers to drivers/net
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'drivers/eepro100.c')
-rw-r--r-- | drivers/eepro100.c | 948 |
1 files changed, 0 insertions, 948 deletions
diff --git a/drivers/eepro100.c b/drivers/eepro100.c deleted file mode 100644 index 738146e..0000000 --- a/drivers/eepro100.c +++ /dev/null @@ -1,948 +0,0 @@ -/* - * (C) Copyright 2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <asm/io.h> -#include <pci.h> -#include <miiphy.h> - -#undef DEBUG - -#if defined(CONFIG_CMD_NET) \ - && defined(CONFIG_NET_MULTI) && defined(CONFIG_EEPRO100) - - /* Ethernet chip registers. - */ -#define SCBStatus 0 /* Rx/Command Unit Status *Word* */ -#define SCBIntAckByte 1 /* Rx/Command Unit STAT/ACK byte */ -#define SCBCmd 2 /* Rx/Command Unit Command *Word* */ -#define SCBIntrCtlByte 3 /* Rx/Command Unit Intr.Control Byte */ -#define SCBPointer 4 /* General purpose pointer. */ -#define SCBPort 8 /* Misc. commands and operands. */ -#define SCBflash 12 /* Flash memory control. */ -#define SCBeeprom 14 /* EEPROM memory control. */ -#define SCBCtrlMDI 16 /* MDI interface control. */ -#define SCBEarlyRx 20 /* Early receive byte count. */ -#define SCBGenControl 28 /* 82559 General Control Register */ -#define SCBGenStatus 29 /* 82559 General Status register */ - - /* 82559 SCB status word defnitions - */ -#define SCB_STATUS_CX 0x8000 /* CU finished command (transmit) */ -#define SCB_STATUS_FR 0x4000 /* frame received */ -#define SCB_STATUS_CNA 0x2000 /* CU left active state */ -#define SCB_STATUS_RNR 0x1000 /* receiver left ready state */ -#define SCB_STATUS_MDI 0x0800 /* MDI read/write cycle done */ -#define SCB_STATUS_SWI 0x0400 /* software generated interrupt */ -#define SCB_STATUS_FCP 0x0100 /* flow control pause interrupt */ - -#define SCB_INTACK_MASK 0xFD00 /* all the above */ - -#define SCB_INTACK_TX (SCB_STATUS_CX | SCB_STATUS_CNA) -#define SCB_INTACK_RX (SCB_STATUS_FR | SCB_STATUS_RNR) - - /* System control block commands - */ -/* CU Commands */ -#define CU_NOP 0x0000 -#define CU_START 0x0010 -#define CU_RESUME 0x0020 -#define CU_STATSADDR 0x0040 /* Load Dump Statistics ctrs addr */ -#define CU_SHOWSTATS 0x0050 /* Dump statistics counters. */ -#define CU_ADDR_LOAD 0x0060 /* Base address to add to CU commands */ -#define CU_DUMPSTATS 0x0070 /* Dump then reset stats counters. */ - -/* RUC Commands */ -#define RUC_NOP 0x0000 -#define RUC_START 0x0001 -#define RUC_RESUME 0x0002 -#define RUC_ABORT 0x0004 -#define RUC_ADDR_LOAD 0x0006 /* (seems not to clear on acceptance) */ -#define RUC_RESUMENR 0x0007 - -#define CU_CMD_MASK 0x00f0 -#define RU_CMD_MASK 0x0007 - -#define SCB_M 0x0100 /* 0 = enable interrupt, 1 = disable */ -#define SCB_SWI 0x0200 /* 1 - cause device to interrupt */ - -#define CU_STATUS_MASK 0x00C0 -#define RU_STATUS_MASK 0x003C - -#define RU_STATUS_IDLE (0<<2) -#define RU_STATUS_SUS (1<<2) -#define RU_STATUS_NORES (2<<2) -#define RU_STATUS_READY (4<<2) -#define RU_STATUS_NO_RBDS_SUS ((1<<2)|(8<<2)) -#define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2)) -#define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2)) - - /* 82559 Port interface commands. - */ -#define I82559_RESET 0x00000000 /* Software reset */ -#define I82559_SELFTEST 0x00000001 /* 82559 Selftest command */ -#define I82559_SELECTIVE_RESET 0x00000002 -#define I82559_DUMP 0x00000003 -#define I82559_DUMP_WAKEUP 0x00000007 - - /* 82559 Eeprom interface. - */ -#define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */ -#define EE_CS 0x02 /* EEPROM chip select. */ -#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ -#define EE_WRITE_0 0x01 -#define EE_WRITE_1 0x05 -#define EE_DATA_READ 0x08 /* EEPROM chip data out. */ -#define EE_ENB (0x4800 | EE_CS) -#define EE_CMD_BITS 3 -#define EE_DATA_BITS 16 - - /* The EEPROM commands include the alway-set leading bit. - */ -#define EE_EWENB_CMD (4 << addr_len) -#define EE_WRITE_CMD (5 << addr_len) -#define EE_READ_CMD (6 << addr_len) -#define EE_ERASE_CMD (7 << addr_len) - - /* Receive frame descriptors. - */ -struct RxFD { - volatile u16 status; - volatile u16 control; - volatile u32 link; /* struct RxFD * */ - volatile u32 rx_buf_addr; /* void * */ - volatile u32 count; - - volatile u8 data[PKTSIZE_ALIGN]; -}; - -#define RFD_STATUS_C 0x8000 /* completion of received frame */ -#define RFD_STATUS_OK 0x2000 /* frame received with no errors */ - -#define RFD_CONTROL_EL 0x8000 /* 1=last RFD in RFA */ -#define RFD_CONTROL_S 0x4000 /* 1=suspend RU after receiving frame */ -#define RFD_CONTROL_H 0x0010 /* 1=RFD is a header RFD */ -#define RFD_CONTROL_SF 0x0008 /* 0=simplified, 1=flexible mode */ - -#define RFD_COUNT_MASK 0x3fff -#define RFD_COUNT_F 0x4000 -#define RFD_COUNT_EOF 0x8000 - -#define RFD_RX_CRC 0x0800 /* crc error */ -#define RFD_RX_ALIGNMENT 0x0400 /* alignment error */ -#define RFD_RX_RESOURCE 0x0200 /* out of space, no resources */ -#define RFD_RX_DMA_OVER 0x0100 /* DMA overrun */ -#define RFD_RX_SHORT 0x0080 /* short frame error */ -#define RFD_RX_LENGTH 0x0020 -#define RFD_RX_ERROR 0x0010 /* receive error */ -#define RFD_RX_NO_ADR_MATCH 0x0004 /* no address match */ -#define RFD_RX_IA_MATCH 0x0002 /* individual address does not match */ -#define RFD_RX_TCO 0x0001 /* TCO indication */ - - /* Transmit frame descriptors - */ -struct TxFD { /* Transmit frame descriptor set. */ - volatile u16 status; - volatile u16 command; - volatile u32 link; /* void * */ - volatile u32 tx_desc_addr; /* Always points to the tx_buf_addr element. */ - volatile s32 count; - - volatile u32 tx_buf_addr0; /* void *, frame to be transmitted. */ - volatile s32 tx_buf_size0; /* Length of Tx frame. */ - volatile u32 tx_buf_addr1; /* void *, frame to be transmitted. */ - volatile s32 tx_buf_size1; /* Length of Tx frame. */ -}; - -#define TxCB_CMD_TRANSMIT 0x0004 /* transmit command */ -#define TxCB_CMD_SF 0x0008 /* 0=simplified, 1=flexible mode */ -#define TxCB_CMD_NC 0x0010 /* 0=CRC insert by controller */ -#define TxCB_CMD_I 0x2000 /* generate interrupt on completion */ -#define TxCB_CMD_S 0x4000 /* suspend on completion */ -#define TxCB_CMD_EL 0x8000 /* last command block in CBL */ - -#define TxCB_COUNT_MASK 0x3fff -#define TxCB_COUNT_EOF 0x8000 - - /* The Speedo3 Rx and Tx frame/buffer descriptors. - */ -struct descriptor { /* A generic descriptor. */ - volatile u16 status; - volatile u16 command; - volatile u32 link; /* struct descriptor * */ - - unsigned char params[0]; -}; - -#define CFG_CMD_EL 0x8000 -#define CFG_CMD_SUSPEND 0x4000 -#define CFG_CMD_INT 0x2000 -#define CFG_CMD_IAS 0x0001 /* individual address setup */ -#define CFG_CMD_CONFIGURE 0x0002 /* configure */ - -#define CFG_STATUS_C 0x8000 -#define CFG_STATUS_OK 0x2000 - - /* Misc. - */ -#define NUM_RX_DESC PKTBUFSRX -#define NUM_TX_DESC 1 /* Number of TX descriptors */ - -#define TOUT_LOOP 1000000 - -#define ETH_ALEN 6 - -static struct RxFD rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ -static struct TxFD tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ -static int rx_next; /* RX descriptor ring pointer */ -static int tx_next; /* TX descriptor ring pointer */ -static int tx_threshold; - -/* - * The parameters for a CmdConfigure operation. - * There are so many options that it would be difficult to document - * each bit. We mostly use the default or recommended settings. - */ -static const char i82557_config_cmd[] = { - 22, 0x08, 0, 0, 0, 0, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */ - 0, 0x2E, 0, 0x60, 0, - 0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */ - 0x3f, 0x05, -}; -static const char i82558_config_cmd[] = { - 22, 0x08, 0, 1, 0, 0, 0x22, 0x03, 1, /* 1=Use MII 0=Use AUI */ - 0, 0x2E, 0, 0x60, 0x08, 0x88, - 0x68, 0, 0x40, 0xf2, 0x84, /* Disable FC */ - 0x31, 0x05, -}; - -static void init_rx_ring (struct eth_device *dev); -static void purge_tx_ring (struct eth_device *dev); - -static void read_hw_addr (struct eth_device *dev, bd_t * bis); - -static int eepro100_init (struct eth_device *dev, bd_t * bis); -static int eepro100_send (struct eth_device *dev, volatile void *packet, - int length); -static int eepro100_recv (struct eth_device *dev); -static void eepro100_halt (struct eth_device *dev); - -#if defined(CONFIG_E500) || defined(CONFIG_DB64360) || defined(CONFIG_DB64460) -#define bus_to_phys(a) (a) -#define phys_to_bus(a) (a) -#else -#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) -#endif - -static inline int INW (struct eth_device *dev, u_long addr) -{ - return le16_to_cpu (*(volatile u16 *) (addr + dev->iobase)); -} - -static inline void OUTW (struct eth_device *dev, int command, u_long addr) -{ - *(volatile u16 *) ((addr + dev->iobase)) = cpu_to_le16 (command); -} - -static inline void OUTL (struct eth_device *dev, int command, u_long addr) -{ - *(volatile u32 *) ((addr + dev->iobase)) = cpu_to_le32 (command); -} - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -static inline int INL (struct eth_device *dev, u_long addr) -{ - return le32_to_cpu (*(volatile u32 *) (addr + dev->iobase)); -} - -static int get_phyreg (struct eth_device *dev, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - int cmd; - int timeout = 50; - - /* read requested data */ - cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL (dev, cmd, SCBCtrlMDI); - - do { - udelay(1000); - cmd = INL (dev, SCBCtrlMDI); - } while (!(cmd & (1 << 28)) && (--timeout)); - - if (timeout == 0) - return -1; - - *value = (unsigned short) (cmd & 0xffff); - - return 0; -} - -static int set_phyreg (struct eth_device *dev, unsigned char addr, - unsigned char reg, unsigned short value) -{ - int cmd; - int timeout = 50; - - /* write requested data */ - cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL (dev, cmd | value, SCBCtrlMDI); - - while (!(INL (dev, SCBCtrlMDI) & (1 << 28)) && (--timeout)) - udelay(1000); - - if (timeout == 0) - return -1; - - return 0; -} - -/* Check if given phyaddr is valid, i.e. there is a PHY connected. - * Do this by checking model value field from ID2 register. - */ -static struct eth_device* verify_phyaddr (char *devname, unsigned char addr) -{ - struct eth_device *dev; - unsigned short value; - unsigned char model; - - dev = eth_get_dev_by_name(devname); - if (dev == NULL) { - printf("%s: no such device\n", devname); - return NULL; - } - - /* read id2 register */ - if (get_phyreg(dev, addr, PHY_PHYIDR2, &value) != 0) { - printf("%s: mii read timeout!\n", devname); - return NULL; - } - - /* get model */ - model = (unsigned char)((value >> 4) & 0x003f); - - if (model == 0) { - printf("%s: no PHY at address %d\n", devname, addr); - return NULL; - } - - return dev; -} - -static int eepro100_miiphy_read (char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - struct eth_device *dev; - - dev = verify_phyaddr(devname, addr); - if (dev == NULL) - return -1; - - if (get_phyreg(dev, addr, reg, value) != 0) { - printf("%s: mii read timeout!\n", devname); - return -1; - } - - return 0; -} - -static int eepro100_miiphy_write (char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - struct eth_device *dev; - - dev = verify_phyaddr(devname, addr); - if (dev == NULL) - return -1; - - if (set_phyreg(dev, addr, reg, value) != 0) { - printf("%s: mii write timeout!\n", devname); - return -1; - } - - return 0; -} - -#endif - -/* Wait for the chip get the command. -*/ -static int wait_for_eepro100 (struct eth_device *dev) -{ - int i; - - for (i = 0; INW (dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) { - if (i >= TOUT_LOOP) { - return 0; - } - } - - return 1; -} - -static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER}, - {} -}; - -int eepro100_initialize (bd_t * bis) -{ - pci_dev_t devno; - int card_number = 0; - struct eth_device *dev; - u32 iobase, status; - int idx = 0; - - while (1) { - /* Find PCI device - */ - if ((devno = pci_find_devices (supported, idx++)) < 0) { - break; - } - - pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase); - iobase &= ~0xf; - -#ifdef DEBUG - printf ("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n", - iobase); -#endif - - pci_write_config_dword (devno, - PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - - /* Check if I/O accesses and Bus Mastering are enabled. - */ - pci_read_config_dword (devno, PCI_COMMAND, &status); - if (!(status & PCI_COMMAND_MEMORY)) { - printf ("Error: Can not enable MEM access.\n"); - continue; - } - - if (!(status & PCI_COMMAND_MASTER)) { - printf ("Error: Can not enable Bus Mastering.\n"); - continue; - } - - dev = (struct eth_device *) malloc (sizeof *dev); - - sprintf (dev->name, "i82559#%d", card_number); - dev->priv = (void *) devno; /* this have to come before bus_to_phys() */ - dev->iobase = bus_to_phys (iobase); - dev->init = eepro100_init; - dev->halt = eepro100_halt; - dev->send = eepro100_send; - dev->recv = eepro100_recv; - - eth_register (dev); - -#if defined (CONFIG_MII) || defined(CONFIG_CMD_MII) - /* register mii command access routines */ - miiphy_register(dev->name, - eepro100_miiphy_read, eepro100_miiphy_write); -#endif - - card_number++; - - /* Set the latency timer for value. - */ - pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20); - - udelay (10 * 1000); - - read_hw_addr (dev, bis); - } - - return card_number; -} - - -static int eepro100_init (struct eth_device *dev, bd_t * bis) -{ - int i, status = 0; - int tx_cur; - struct descriptor *ias_cmd, *cfg_cmd; - - /* Reset the ethernet controller - */ - OUTL (dev, I82559_SELECTIVE_RESET, SCBPort); - udelay (20); - - OUTL (dev, I82559_RESET, SCBPort); - udelay (20); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd); - - /* Initialize Rx and Tx rings. - */ - init_rx_ring (dev); - purge_tx_ring (dev); - - /* Tell the adapter where the RX ring is located. - */ - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - - OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer); - OUTW (dev, SCB_M | RUC_START, SCBCmd); - - /* Send the Configure frame */ - tx_cur = tx_next; - tx_next = ((tx_next + 1) % NUM_TX_DESC); - - cfg_cmd = (struct descriptor *) &tx_ring[tx_cur]; - cfg_cmd->command = cpu_to_le16 ((CFG_CMD_SUSPEND | CFG_CMD_CONFIGURE)); - cfg_cmd->status = 0; - cfg_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next])); - - memcpy (cfg_cmd->params, i82558_config_cmd, - sizeof (i82558_config_cmd)); - - if (!wait_for_eepro100 (dev)) { - printf ("Error---CFG_CMD_CONFIGURE: Can not reset ethernet controller.\n"); - goto Done; - } - - OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); - OUTW (dev, SCB_M | CU_START, SCBCmd); - - for (i = 0; - !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C); - i++) { - if (i >= TOUT_LOOP) { - printf ("%s: Tx error buffer not ready\n", dev->name); - goto Done; - } - } - - if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) { - printf ("TX error status = 0x%08X\n", - le16_to_cpu (tx_ring[tx_cur].status)); - goto Done; - } - - /* Send the Individual Address Setup frame - */ - tx_cur = tx_next; - tx_next = ((tx_next + 1) % NUM_TX_DESC); - - ias_cmd = (struct descriptor *) &tx_ring[tx_cur]; - ias_cmd->command = cpu_to_le16 ((CFG_CMD_SUSPEND | CFG_CMD_IAS)); - ias_cmd->status = 0; - ias_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next])); - - memcpy (ias_cmd->params, dev->enetaddr, 6); - - /* Tell the adapter where the TX ring is located. - */ - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - - OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); - OUTW (dev, SCB_M | CU_START, SCBCmd); - - for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C); - i++) { - if (i >= TOUT_LOOP) { - printf ("%s: Tx error buffer not ready\n", - dev->name); - goto Done; - } - } - - if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) { - printf ("TX error status = 0x%08X\n", - le16_to_cpu (tx_ring[tx_cur].status)); - goto Done; - } - - status = 1; - - Done: - return status; -} - -static int eepro100_send (struct eth_device *dev, volatile void *packet, int length) -{ - int i, status = -1; - int tx_cur; - - if (length <= 0) { - printf ("%s: bad packet size: %d\n", dev->name, length); - goto Done; - } - - tx_cur = tx_next; - tx_next = (tx_next + 1) % NUM_TX_DESC; - - tx_ring[tx_cur].command = cpu_to_le16 ( TxCB_CMD_TRANSMIT | - TxCB_CMD_SF | - TxCB_CMD_S | - TxCB_CMD_EL ); - tx_ring[tx_cur].status = 0; - tx_ring[tx_cur].count = cpu_to_le32 (tx_threshold); - tx_ring[tx_cur].link = - cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next])); - tx_ring[tx_cur].tx_desc_addr = - cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_cur].tx_buf_addr0)); - tx_ring[tx_cur].tx_buf_addr0 = - cpu_to_le32 (phys_to_bus ((u_long) packet)); - tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length); - - if (!wait_for_eepro100 (dev)) { - printf ("%s: Tx error ethernet controller not ready.\n", - dev->name); - goto Done; - } - - /* Send the packet. - */ - OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); - OUTW (dev, SCB_M | CU_START, SCBCmd); - - for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C); - i++) { - if (i >= TOUT_LOOP) { - printf ("%s: Tx error buffer not ready\n", dev->name); - goto Done; - } - } - - if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) { - printf ("TX error status = 0x%08X\n", - le16_to_cpu (tx_ring[tx_cur].status)); - goto Done; - } - - status = length; - - Done: - return status; -} - -static int eepro100_recv (struct eth_device *dev) -{ - u16 status, stat; - int rx_prev, length = 0; - - stat = INW (dev, SCBStatus); - OUTW (dev, stat & SCB_STATUS_RNR, SCBStatus); - - for (;;) { - status = le16_to_cpu (rx_ring[rx_next].status); - - if (!(status & RFD_STATUS_C)) { - break; - } - - /* Valid frame status. - */ - if ((status & RFD_STATUS_OK)) { - /* A valid frame received. - */ - length = le32_to_cpu (rx_ring[rx_next].count) & 0x3fff; - - /* Pass the packet up to the protocol - * layers. - */ - NetReceive (rx_ring[rx_next].data, length); - } else { - /* There was an error. - */ - printf ("RX error status = 0x%08X\n", status); - } - - rx_ring[rx_next].control = cpu_to_le16 (RFD_CONTROL_S); - rx_ring[rx_next].status = 0; - rx_ring[rx_next].count = cpu_to_le32 (PKTSIZE_ALIGN << 16); - - rx_prev = (rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC; - rx_ring[rx_prev].control = 0; - - /* Update entry information. - */ - rx_next = (rx_next + 1) % NUM_RX_DESC; - } - - if (stat & SCB_STATUS_RNR) { - - printf ("%s: Receiver is not ready, restart it !\n", dev->name); - - /* Reinitialize Rx ring. - */ - init_rx_ring (dev); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not restart ethernet controller.\n"); - goto Done; - } - - OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer); - OUTW (dev, SCB_M | RUC_START, SCBCmd); - } - - Done: - return length; -} - -static void eepro100_halt (struct eth_device *dev) -{ - /* Reset the ethernet controller - */ - OUTL (dev, I82559_SELECTIVE_RESET, SCBPort); - udelay (20); - - OUTL (dev, I82559_RESET, SCBPort); - udelay (20); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd); - - Done: - return; -} - - /* SROM Read. - */ -static int read_eeprom (struct eth_device *dev, int location, int addr_len) -{ - unsigned short retval = 0; - int read_cmd = location | EE_READ_CMD; - int i; - - OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom); - OUTW (dev, EE_ENB, SCBeeprom); - - /* Shift the read command bits out. */ - for (i = 12; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - - OUTW (dev, EE_ENB | dataval, SCBeeprom); - udelay (1); - OUTW (dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay (1); - } - OUTW (dev, EE_ENB, SCBeeprom); - - for (i = 15; i >= 0; i--) { - OUTW (dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom); - udelay (1); - retval = (retval << 1) | - ((INW (dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0); - OUTW (dev, EE_ENB, SCBeeprom); - udelay (1); - } - - /* Terminate the EEPROM access. */ - OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom); - return retval; -} - -#ifdef CONFIG_EEPRO100_SROM_WRITE -int eepro100_write_eeprom (struct eth_device* dev, int location, int addr_len, unsigned short data) -{ - unsigned short dataval; - int enable_cmd = 0x3f | EE_EWENB_CMD; - int write_cmd = location | EE_WRITE_CMD; - int i; - unsigned long datalong, tmplong; - - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB, SCBeeprom); - - /* Shift the enable command bits out. */ - for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--) - { - dataval = (enable_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay(1); - } - - OUTW(dev, EE_ENB, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB, SCBeeprom); - - - /* Shift the write command bits out. */ - for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--) - { - dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay(1); - } - - /* Write the data */ - datalong= (unsigned long) ((((data) & 0x00ff) << 8) | ( (data) >> 8)); - - for (i = 0; i< EE_DATA_BITS; i++) - { - /* Extract and move data bit to bit DI */ - dataval = ((datalong & 0x8000)>>13) ? EE_DATA_WRITE : 0; - - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - - datalong = datalong << 1; /* Adjust significant data bit*/ - } - - /* Finish up command (toggle CS) */ - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - udelay(1); /* delay for more than 250 ns */ - OUTW(dev, EE_ENB, SCBeeprom); - - /* Wait for programming ready (D0 = 1) */ - tmplong = 10; - do - { - dataval = INW(dev, SCBeeprom); - if (dataval & EE_DATA_READ) - break; - udelay(10000); - } - while (-- tmplong); - - if (tmplong == 0) - { - printf ("Write i82559 eeprom timed out (100 ms waiting for data ready.\n"); - return -1; - } - - /* Terminate the EEPROM access. */ - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - - return 0; -} -#endif - -static void init_rx_ring (struct eth_device *dev) -{ - int i; - - for (i = 0; i < NUM_RX_DESC; i++) { - rx_ring[i].status = 0; - rx_ring[i].control = - (i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0; - rx_ring[i].link = - cpu_to_le32 (phys_to_bus - ((u32) & rx_ring[(i + 1) % NUM_RX_DESC])); - rx_ring[i].rx_buf_addr = 0xffffffff; - rx_ring[i].count = cpu_to_le32 (PKTSIZE_ALIGN << 16); - } - - rx_next = 0; -} - -static void purge_tx_ring (struct eth_device *dev) -{ - int i; - - tx_next = 0; - tx_threshold = 0x01208000; - - for (i = 0; i < NUM_TX_DESC; i++) { - tx_ring[i].status = 0; - tx_ring[i].command = 0; - tx_ring[i].link = 0; - tx_ring[i].tx_desc_addr = 0; - tx_ring[i].count = 0; - - tx_ring[i].tx_buf_addr0 = 0; - tx_ring[i].tx_buf_size0 = 0; - tx_ring[i].tx_buf_addr1 = 0; - tx_ring[i].tx_buf_size1 = 0; - } -} - -static void read_hw_addr (struct eth_device *dev, bd_t * bis) -{ - u16 eeprom[0x40]; - u16 sum = 0; - int i, j; - int addr_len = read_eeprom (dev, 0, 6) == 0xffff ? 8 : 6; - - for (j = 0, i = 0; i < 0x40; i++) { - u16 value = read_eeprom (dev, i, addr_len); - - eeprom[i] = value; - sum += value; - if (i < 3) { - dev->enetaddr[j++] = value; - dev->enetaddr[j++] = value >> 8; - } - } - - if (sum != 0xBABA) { - memset (dev->enetaddr, 0, ETH_ALEN); -#ifdef DEBUG - printf ("%s: Invalid EEPROM checksum %#4.4x, " - "check settings before activating this device!\n", - dev->name, sum); -#endif - } -} - -#endif |