]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
* Improved (unified) support for multiple ethernet interfaces
authorwdenk <wdenk>
Mon, 25 Feb 2002 17:43:46 +0000 (17:43 +0000)
committerwdenk <wdenk>
Mon, 25 Feb 2002 17:43:46 +0000 (17:43 +0000)
  Now tested on PCIPPCx and Sandpoint 8240

* Removed "icache" / "dcache" from list of standard commands

25 files changed:
CHANGELOG
README
board/evb64260/sdram_init.c
board/pcippc2/Makefile
board/pcippc2/cpc710_pci.h
board/pcippc2/dc2114x.c [new file with mode: 0644]
board/pcippc2/eepro100.c
board/pcippc2/pci.c
board/pcippc2/pci.h
board/pcippc2/pcippc2.c
board/pcippc2/pcippc2_fpga.c
board/sandpoint/eepro100.c
board/sandpoint/ppcboot.lds
common/board.c
include/cmd_confdefs.h
include/config_CPCI405.h
include/config_CRAYL1.h
include/config_MIP405.h
include/config_OCRTC.h
include/config_PCIPPC2.h
include/config_PCIPPC6.h
include/config_PIP405.h
include/config_Sandpoint8240.h
include/net.h
net/Makefile

index 715f3075b45818e5fbaf1c91d85606f8b86d5fed..0ac237bf7ab567e660759e55639d928e414d0b81 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,11 @@
 Modifications for 1.1.5:
 ======================================================================
 
+* Improved (unified) support for multiple ethernet interfaces
+  Now tested on PCIPPCx and Sandpoint 8240
+  
+* Removed "icache" / "dcache" from list of standard commands
+
 * Fix TQM8260 config for HIP4 CPUs at 266 MHz
 
 * Patch by Steve Bradshaw, 15 Feb 2002:
diff --git a/README b/README
index 0743cdd508dbc2b47f9b40f2536de2b5b2e832b1..aa17727a3ef019721334d14e1d6d33fd4786a569 100644 (file)
--- a/README
+++ b/README
@@ -420,6 +420,17 @@ The following options need to be configured:
 
                #define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET)
 
+
+       Note:   Don't enable the "icache" and "dcache" commands
+                (configuration option CFG_CMD_CACHE) unless you know
+                what you (and your PPCBoot users) are doing. Data
+                cache cannot be enabled on systems like the 8xx or
+                8260 (where accesses to the IMMR region must be
+                uncached), and it cannot be enabled on all other
+                systems where we (mis-) use the data cache to hold an
+                initial stack and some data.
+
+
                XXX - this list needs to get updated!
 
                 XXX - when using the (yet undocumented) "autoscript"
index 0cf1860582a76bb82a5ac74df3b25e6f697078d2..d6ce208757277fceb1395a7bf8fbcd6e40c5e7d2 100644 (file)
@@ -197,7 +197,7 @@ check_dimm(uchar slot, sdram_info_t *info)
        DP(printf("sdram_banks: %d, banks: %d\n", sdram_banks, info->banks));
 
        /* check if the memory is registered */
-       if (data[21] & (BIT1 & BIT4))
+       if (data[21] & (BIT1 | BIT4))
                info->registered = 1;
 
 #ifdef CONFIG_ECC
index 203723b45c2712838b5c6f02a8550cf37378ff83..66d49b49738346fa22cf2e754c37b75299cae8d6 100644 (file)
@@ -26,7 +26,8 @@ include $(TOPDIR)/config.mk
 LIB    = lib$(BOARD).a
 
 COBJS  = $(BOARD).o cpc710_pci.o flash.o sconsole.o eepro100.o pci.o \
-         fpga_serial.o pcippc2_fpga.o cpc710_init_ram.o i2c.o sym53c8xx.o
+         fpga_serial.o pcippc2_fpga.o cpc710_init_ram.o i2c.o sym53c8xx.o \
+         dc2114x.o
 AOBJS  =
 
 OBJS   = $(COBJS) $(AOBJS)
index 601652fe68b8b14da48f79d56b0ff35a6bc6e657..3903c4c4fcfe0263a4c72642384ba1913bfd3596 100644 (file)
@@ -46,9 +46,6 @@
 
 #define BRIDGE(r, x)           (BRIDGE_##r##_PHYS + HW_BRIDGE_##x)
 
-#define PCI_LOWEST_IOADDR      BRIDGE_LOCAL_IO_BUS
-#define PCI_LOWEST_MEMADDR     BRIDGE_LOCAL_MEM_BUS
-
 #define PCI_LATENCY_TIMER      0xff
 
 #endif
diff --git a/board/pcippc2/dc2114x.c b/board/pcippc2/dc2114x.c
new file mode 100644 (file)
index 0000000..bd01d69
--- /dev/null
@@ -0,0 +1,561 @@
+/*
+ * 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 <ppcboot.h>
+#include <malloc.h>
+#include <net.h>
+
+#include "pci.h"
+
+#undef DEBUG
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+       && defined(CONFIG_TULIP)
+
+/* PCI Registers.
+ */
+#define PCI_CFDA_PSM           0x43
+
+#define CFRV_RN                0x000000f0      /* Revision Number */
+#define CBIO_MASK      0xffffff80
+
+#define WAKEUP         0x00            /* Power Saving Wakeup */
+#define SLEEP          0x80            /* Power Saving Sleep Mode */
+
+
+#define DC2114x_VID    0x1011          /* DC2114[23] Manufacturer */
+#define DC2114x_DID    0x0009          /* Unique Device ID # */
+#define DC2114x_BRK    0x0020          /* CFRV break between DC21142 & DC21143 */
+#define DC21142                (DC2114x_DID << 8 | 0x0010)
+#define DC21143                (DC2114x_DID << 8 | 0x0030)
+
+#define is_DC2114x ((vendor == DC2114x_VID) && (device == DC2114x_DID))
+
+/* Ethernet chip registers.
+        */
+#define DE4X5_BMR      0x000           /* Bus Mode Register */
+#define DE4X5_TPD      0x008           /* Transmit Poll Demand Reg */
+#define DE4X5_RRBA     0x018           /* RX Ring Base Address Reg */
+#define DE4X5_TRBA     0x020           /* TX Ring Base Address Reg */
+#define DE4X5_STS      0x028           /* Status Register */
+#define DE4X5_OMR      0x030           /* Operation Mode Register */
+#define DE4X5_SICR     0x068           /* SIA Connectivity Register */
+#define DE4X5_APROM    0x048           /* Ethernet Address PROM */
+
+/* Register bits.
+        */
+#define BMR_SWR                0x00000001      /* Software Reset */
+#define STS_TS         0x00700000      /* Transmit Process State */
+#define STS_RS         0x000e0000      /* Receive Process State */
+#define OMR_ST         0x00002000      /* Start/Stop Transmission Command */
+#define OMR_SR         0x00000002      /* Start/Stop Receive */
+#define OMR_PS         0x00040000      /* Port Select */
+#define OMR_SDP                0x02000000      /* SD Polarity - MUST BE ASSERTED */
+#define OMR_PM         0x00000080      /* Pass All Multicast */
+
+/* Descriptor bits.
+        */
+#define R_OWN          0x80000000      /* Own Bit */
+#define RD_RER         0x02000000      /* Receive End Of Ring */
+#define RD_LS          0x00000100      /* Last Descriptor */
+#define RD_ES          0x00008000      /* Error Summary */
+#define TD_TER         0x02000000      /* Transmit End Of Ring */
+#define T_OWN          0x80000000      /* Own Bit */
+#define TD_LS          0x40000000      /* Last Segment */
+#define TD_FS          0x20000000      /* First Segment */
+#define TD_ES          0x00008000      /* Error Summary */
+#define TD_SET         0x08000000      /* Setup Packet */
+
+
+#define SROM_HWADD         0x0014      /* Hardware Address offset in SROM */
+#define SROM_RD                0x00004000      /* Read from Boot ROM */
+#define SROM_SR                0x00000800      /* Select Serial ROM when set */
+
+#define DT_IN          0x00000004      /* Serial Data In */
+#define DT_CLK         0x00000002      /* Serial ROM Clock */
+#define DT_CS          0x00000001      /* Serial ROM Chip Select */
+
+#define POLL_DEMAND    1
+
+#define RESET_DE4X5(dev) {\
+    int i;\
+    i=INL(dev, DE4X5_BMR);\
+    udelay(1000);\
+    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
+    udelay(1000);\
+    OUTL(dev, i, DE4X5_BMR);\
+    udelay(1000);\
+    for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\
+    udelay(1000);\
+}
+
+#define START_DE4X5(dev) {\
+    s32 omr; \
+    omr = INL(dev, DE4X5_OMR);\
+    omr |= OMR_ST | OMR_SR;\
+    OUTL(dev, omr, DE4X5_OMR);         /* Enable the TX and/or RX */\
+}
+
+#define STOP_DE4X5(dev) {\
+    s32 omr; \
+    omr = INL(dev, DE4X5_OMR);\
+    omr &= ~(OMR_ST|OMR_SR);\
+    OUTL(dev, omr, DE4X5_OMR);         /* Disable the TX and/or RX */ \
+}
+
+#define NUM_RX_DESC PKTBUFSRX
+#define NUM_TX_DESC 1                  /* Number of TX descriptors   */
+#define RX_BUFF_SZ  PKTSIZE_ALIGN
+
+#define TOUT_LOOP   1000000
+
+#define SETUP_FRAME_LEN 192
+#define ETH_ALEN       6
+
+
+struct de4x5_desc {
+       volatile s32 status;
+       u32 des1;
+       u32 buf;
+       u32 next;
+};
+
+static struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring         */
+static struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring         */
+static int rx_new;                             /* RX descriptor ring pointer */
+static int tx_new;                             /* TX descriptor ring pointer */
+
+static char rxRingSize;
+static char txRingSize;
+
+static void  send_setup_frame(struct eth_device* dev, bd_t * bis);
+static void  read_hw_addr(struct eth_device* dev, bd_t * bis);
+static short srom_rd(struct eth_device* dev, u_long address, u_char offset);
+static void  srom_latch(struct eth_device* dev, u_int command, u_long address);
+static void  srom_command(struct eth_device* dev, u_int command, u_long address);
+static void  srom_address(struct eth_device* dev, u_int command, u_long address, u_char offset);
+static short srom_data(struct eth_device* dev, u_int command, u_long address);
+static void  sendto_srom(struct eth_device* dev, u_int command, u_long addr);
+static int   getfrom_srom(struct eth_device* dev, u_long addr);
+
+static int   dc21x4x_init(struct eth_device* dev, bd_t* bis);
+static int   dc21x4x_send(struct eth_device* dev, volatile void *packet, int length);
+static int   dc21x4x_recv(struct eth_device* dev);
+static void  dc21x4x_halt(struct eth_device* dev);
+
+static int INL(struct eth_device* dev, u_long addr)
+{
+       return le32_to_cpu(*(volatile u_long *)pci_mem_to_phys(addr + dev->iobase));
+}
+
+static void OUTL(struct eth_device* dev, int command, u_long addr)
+{
+       *(volatile u_long *)pci_mem_to_phys(addr + dev->iobase) = cpu_to_le32(command);
+}
+
+int dc21x4x_initialize(bd_t *bis)
+{
+       int                     card_number, i, status = 0;
+       int                     device;
+       int                     cfrv;
+       unsigned char           timer;
+       int                     devbusfn;
+       u_long                  iobase;
+       struct eth_device*      dev;
+
+       for(card_number=i=0; ; i++) {
+               devbusfn = PCI_Find_Device(DC2114x_VID, DC2114x_DID, i);
+               if (devbusfn == -1) {
+                       break;
+               }
+
+               /* Get the chip configuration revision register. */
+               cfrv = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_REVISION, 4);
+
+               device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+
+               if (device != DC21143) {
+                       printf("Error: The chip is not DC21143.\n");
+                       continue;
+               }
+
+               status = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_COMMAND, 2);
+               status |= PCI_CMD_MASTER | PCI_CMD_IOEN | PCI_CMD_MEMEN;
+               PCI_Write_CFG_Reg(devbusfn, PCI_CFG_COMMAND, status, 2);
+
+               /* Check the latency timer for values >= 0x60. */
+               timer = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_LATENCY_TIMER, 1);
+
+               if (timer < 0x60) {
+                       PCI_Write_CFG_Reg(devbusfn, PCI_CFG_LATENCY_TIMER, 0x60, 1);
+               }
+
+               /* read BAR for memory space access */
+               iobase = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_BASE_ADDRESS_1, 4);
+               iobase &= CBIO_MASK;
+
+#ifdef DEBUG
+               printf("dc21x4x: DEC 21142 PCI Device @0x%lx\n", iobase);
+#endif
+
+               dev = (struct eth_device*) malloc(sizeof *dev);
+
+               sprintf(dev->name, "dc21x4x#%d", i);
+               dev->iobase = iobase;
+               dev->priv   = (void*) devbusfn;
+               dev->init   = dc21x4x_init;
+               dev->halt   = dc21x4x_halt;
+               dev->send   = dc21x4x_send;
+               dev->recv   = dc21x4x_recv;
+
+               /* Ensure we're not sleeping. */
+               PCI_Write_CFG_Reg(devbusfn, PCI_CFDA_PSM, WAKEUP, 1);
+
+               udelay(10 * 1000);
+
+               read_hw_addr(dev, bis);
+
+               eth_register(dev);
+
+               card_number++;
+       }
+
+       return card_number;
+}
+
+static int dc21x4x_init(struct eth_device* dev, bd_t* bis)
+{
+       int             i;
+       int             devbusfn = (int) dev->priv;
+
+       /* Ensure we're not sleeping. */
+       PCI_Write_CFG_Reg(devbusfn, PCI_CFDA_PSM, WAKEUP, 1);
+
+       RESET_DE4X5(dev);
+
+       if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
+               printf("Error: Cannot reset ethernet controller.\n");
+               return 0;
+       }
+
+       OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
+
+       for (i = 0; i < NUM_RX_DESC; i++) {
+               rx_ring[i].status = cpu_to_le32(R_OWN);
+               rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
+               rx_ring[i].buf = cpu_to_le32(pci_ram_to_mem((u32) NetRxPackets[i]));
+               rx_ring[i].next = 0;
+       }
+
+       for (i=0; i < NUM_TX_DESC; i++) {
+               tx_ring[i].status = 0;
+               tx_ring[i].des1 = 0;
+               tx_ring[i].buf = 0;
+               tx_ring[i].next = 0;
+       }
+
+       rxRingSize = NUM_RX_DESC;
+       txRingSize = NUM_TX_DESC;
+
+       /* Write the end of list marker to the descriptor lists. */
+       rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
+       tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
+
+       /* Tell the adapter where the TX/RX rings are located. */
+       OUTL(dev, pci_ram_to_mem((u32) &rx_ring), DE4X5_RRBA);
+       OUTL(dev, pci_ram_to_mem((u32) &tx_ring), DE4X5_TRBA);
+
+       START_DE4X5(dev);
+
+       tx_new = 0;
+       rx_new = 0;
+
+       send_setup_frame(dev, bis);
+
+       return 1;
+}
+
+static int dc21x4x_send(struct eth_device* dev, volatile void *packet, int length)
+{
+       int             status = -1;
+       int             i;
+
+       if (length <= 0) {
+               printf("%s: bad packet size: %d\n", dev->name, length);
+               goto Done;
+       }
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("%s: tx error buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       tx_ring[tx_new].buf    = cpu_to_le32(pci_ram_to_mem((u32) packet));
+       tx_ring[tx_new].des1   = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
+       tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+       OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf(".%s: tx buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+#if 0 /* test-only */
+       if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) {
+               printf("TX error status = 0x%08X\n",
+                      le32_to_cpu(tx_ring[tx_new].status));
+               goto Done;
+       }
+#endif
+
+       status = length;
+
+ Done:
+       return status;
+}
+
+static int dc21x4x_recv(struct eth_device* dev)
+{
+       s32             status;
+       int             length    = 0;
+
+       for ( ; ; ) {
+               status = (s32)le32_to_cpu(rx_ring[rx_new].status);
+
+               if (status & R_OWN) {
+                       break;
+               }
+
+               if (status & RD_LS) {
+                       /* Valid frame status.
+                        */
+                       if (status & RD_ES) {
+
+                               /* There was an error.
+                                */
+                               printf("RX error status = 0x%08X\n", status);
+                       } else {
+                               /* A valid frame received.
+                                */
+                               length = (le32_to_cpu(rx_ring[rx_new].status) >> 16);
+
+                               /* Pass the packet up to the protocol
+                                * layers.
+                                */
+                               NetReceive(NetRxPackets[rx_new], length - 4);
+                       }
+
+                       /* Change buffer ownership for this frame, back
+                        * to the adapter.
+                        */
+                       rx_ring[rx_new].status = cpu_to_le32(R_OWN);
+               }
+
+               /* Update entry information.
+                */
+               rx_new = (rx_new + 1) % rxRingSize;
+       }
+
+       return length;
+}
+
+static void dc21x4x_halt(struct eth_device* dev)
+{
+       int             devbusfn = (int) dev->priv;
+
+       STOP_DE4X5(dev);
+       OUTL(dev, 0, DE4X5_SICR);
+       if (devbusfn > 0) {
+               PCI_Write_CFG_Reg(devbusfn, PCI_CFDA_PSM, SLEEP, 1);
+       }
+}
+
+static void read_hw_addr(struct eth_device *dev, bd_t *bis)
+{
+       u_short tmp, *p = (short *)(&dev->enetaddr[0]);
+       int i, j = 0;
+
+       for (i = 0; i < (ETH_ALEN >> 1); i++) {
+               tmp = srom_rd(dev, DE4X5_APROM, (SROM_HWADD >> 1) + i);
+               *p = le16_to_cpu(tmp);
+               j += *p++;
+       }
+
+       if ((j == 0) || (j == 0x2fffd)) {
+               printf("Warning: can't read HW address from SROM.\n");
+               goto Done;
+       }
+
+#ifdef DEBUG
+       for (i = 0; i < ETH_ALEN; i++) {
+               if (dev->enetaddr[i] != bis->bi_enetaddr[i]) {
+                       printf("Warning: HW addresses don't match:\n");
+                       printf("Address in SROM is         "
+                              "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                              dev->enetaddr[0], dev->enetaddr[1],
+                              dev->enetaddr[2], dev->enetaddr[3],
+                              dev->enetaddr[4], dev->enetaddr[5]);
+                       printf("Address used by ppcboot is "
+                              "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                              bis->bi_enetaddr[0], bis->bi_enetaddr[1],
+                              bis->bi_enetaddr[2], bis->bi_enetaddr[3],
+                              bis->bi_enetaddr[4], bis->bi_enetaddr[5]);
+                       goto Done;
+               }
+       }
+#endif
+
+Done:
+       return;
+}
+
+static void send_setup_frame(struct eth_device* dev, bd_t *bis)
+{
+       int             i;
+       char    setup_frame[SETUP_FRAME_LEN];
+       char    *pa = &setup_frame[0];
+
+       memset(pa, 0xff, SETUP_FRAME_LEN);
+
+       for (i = 0; i < ETH_ALEN; i++) {
+               *(pa + (i & 1)) = bis->bi_enetaddr[i];
+               if (i & 0x01) {
+                       pa += 4;
+               }
+       }
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("%s: tx error buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       tx_ring[tx_new].buf = cpu_to_le32(pci_ram_to_mem((u32) &setup_frame[0]));
+       tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN);
+       tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+       OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("%s: tx buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
+               printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status));
+       }
+Done:
+       return;
+}
+
+/* SROM Read.
+ */
+static short
+srom_rd(struct eth_device* dev, u_long addr, u_char offset)
+{
+       sendto_srom(dev, SROM_RD | SROM_SR, addr);
+
+       srom_latch(dev, SROM_RD | SROM_SR | DT_CS, addr);
+       srom_command(dev, SROM_RD | SROM_SR | DT_IN | DT_CS, addr);
+       srom_address(dev, SROM_RD | SROM_SR | DT_CS, addr, offset);
+
+       return srom_data(dev, SROM_RD | SROM_SR | DT_CS, addr);
+}
+
+static void
+srom_latch(struct eth_device* dev, u_int command, u_long addr)
+{
+       sendto_srom(dev, command, addr);
+       sendto_srom(dev, command | DT_CLK, addr);
+       sendto_srom(dev, command, addr);
+}
+
+static void
+srom_command(struct eth_device* dev, u_int command, u_long addr)
+{
+       srom_latch(dev, command, addr);
+       srom_latch(dev, command, addr);
+       srom_latch(dev, (command & 0x0000ff00) | DT_CS, addr);
+}
+
+static void
+srom_address(struct eth_device *dev, u_int command, u_long addr, u_char offset)
+{
+       int i;
+       signed char a;
+
+       a = (char)(offset << 2);
+       for (i=0; i<6; i++, a <<= 1) {
+               srom_latch(dev, command | ((a < 0) ? DT_IN : 0), addr);
+       }
+       udelay(1);
+
+       i = (getfrom_srom(dev, addr) >> 3) & 0x01;
+
+       return;
+}
+
+static short
+srom_data(struct eth_device *dev, u_int command, u_long addr)
+{
+       int i;
+       short word = 0;
+       s32 tmp;
+
+       for (i=0; i<16; i++) {
+               sendto_srom(dev, command  | DT_CLK, addr);
+               tmp = getfrom_srom(dev, addr);
+               sendto_srom(dev, command, addr);
+
+               word = (word << 1) | ((tmp >> 3) & 0x01);
+       }
+
+       sendto_srom(dev, command & 0x0000ff00, addr);
+
+       return word;
+}
+
+static void
+sendto_srom(struct eth_device* dev, u_int command, u_long addr)
+{
+       OUTL(dev, command, addr);
+       udelay(1);
+}
+
+static int
+getfrom_srom(struct eth_device* dev, u_long addr)
+{
+       s32 tmp;
+
+       tmp = INL(dev, addr);
+       udelay(1);
+
+       return tmp;
+}
+
+#endif
index 94a9a282c8f70a8024529fb522a06eeb22125174..cf3943c66a80cb37d0a0ec7ec8fc97508c55a2c6 100644 (file)
  */
 
 #include <ppcboot.h>
+#include <malloc.h>
 #include <net.h>
 #include <asm/io.h>
 
 #include "pci.h"
 
+#undef DEBUG
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
+       defined(CONFIG_EEPRO100)
+
 /* Intel Ethernet */
 #define PCI_VENDOR_ID_INTEL            0x8086
 #define PCI_DEVICE_ID_INTEL_82559ER    0x1209
@@ -216,50 +222,53 @@ static int rx_next;                      /* RX descriptor ring pointer */
 static int tx_next;                      /* TX descriptor ring pointer */
 static int tx_threshold;
 
-static u_long iobase = 0;
-
 static void  init_rx_ring(void);
 static void  purge_tx_ring(void);
 
-static void  check_hw_addr(bd_t * bis);
+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);
 
-static inline int INL(u_long addr)
+static inline int INL(struct eth_device* dev, u_long addr)
 {
-       return le32_to_cpu(*(volatile u32 *)pci_mem_to_phys(addr + iobase));
+       return le32_to_cpu(*(volatile u32 *)pci_mem_to_phys(addr + dev->iobase));
 }
 
-static inline int INW(u_long addr)
+static inline int INW(struct eth_device* dev, u_long addr)
 {
-       return le16_to_cpu(*(volatile u16 *)pci_mem_to_phys(addr + iobase));
+       return le16_to_cpu(*(volatile u16 *)pci_mem_to_phys(addr + dev->iobase));
 }
 
-static inline int INB(u_long addr)
+static inline int INB(struct eth_device* dev, u_long addr)
 {
-       return *(volatile u8 *)(pci_mem_to_phys(addr + iobase));
+       return *(volatile u8 *)(pci_mem_to_phys(addr + dev->iobase));
 }
 
-static inline void OUTB(int command, u_long addr)
+static inline void OUTB(struct eth_device* dev, int command, u_long addr)
 {
-       *(volatile u8 *)(pci_mem_to_phys(addr + iobase)) = command;
+       *(volatile u8 *)(pci_mem_to_phys(addr + dev->iobase)) = command;
 }
 
-static inline void OUTW(int command, u_long addr)
+static inline void OUTW(struct eth_device* dev, int command, u_long addr)
 {
-       *(volatile u16 *)(pci_mem_to_phys(addr + iobase)) = cpu_to_le16(command);
+       *(volatile u16 *)(pci_mem_to_phys(addr + dev->iobase)) = cpu_to_le16(command);
 }
 
-static inline void OUTL(int command, u_long addr)
+static inline void OUTL(struct eth_device *dev, int command, u_long addr)
 {
-       *(volatile u32 *)(pci_mem_to_phys(addr + iobase)) = cpu_to_le32(command);
+       *(volatile u32 *)(pci_mem_to_phys(addr + dev->iobase)) = cpu_to_le32(command);
 }
 
        /* Wait for the chip get the command.
         */
-static int wait_for_eepro100(void
+static int wait_for_eepro100(struct eth_device *dev
 {
        int i;
 
-       for(i = 0; INW(SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++)
+       for(i = 0; INW(dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++)
        {
                if (i >= TOUT_LOOP)
                {
@@ -270,77 +279,104 @@ static int wait_for_eepro100(void)
        return 1;
 }
 
-int eth_init(bd_t *bis)
+int eepro100_initialize(bd_t *bis)
 {
-       int i, status = 0;
-       int devno;
-       int tx_cur;
-       struct descriptor *ias_cmd;
+       int devno, i, card_number, status;
+       struct eth_device* dev;
+       u_long iobase;
 
-       /* Find PCI device 
-        */
-       if ((devno = PCI_Find_Device(PCI_VENDOR_ID_INTEL,
-                                    PCI_DEVICE_ID_INTEL_82559ER)) < 0)
+       for(card_number=i=0; ; i++)
        {
-               printf("Error: Can not find an ethernet card on the PCI bus\n");
-               goto Done;
-       }
+               /* Find PCI device 
+                */
+               if ((devno = PCI_Find_Device(PCI_VENDOR_ID_INTEL,
+                                            PCI_DEVICE_ID_INTEL_82559ER, i)) < 0)
+               {
+                       break;
+               }
 
-       iobase = PCI_Read_CFG_Reg(devno, PCI_CFG_BASE_ADDRESS_0, 4) & ~0xf;
+               iobase = PCI_Read_CFG_Reg(devno, PCI_CFG_BASE_ADDRESS_0, 4) & ~0xf;
 
-       printf("eth: Intel i82559 PCI EtherExpressPro @0x%lx\n", iobase);
-  
-       PCI_Write_CFG_Reg(devno, 
-                         PCI_CFG_COMMAND, 
-                         PCI_CMD_MEMEN | 
-                         PCI_CMD_MASTER, 4);
+#ifdef DEBUG
+               printf("eepro100: Intel i82559 PCI EtherExpressPro @0x%lx\n", iobase);
+#endif
 
-        /* Check if I/O accesses and Bus Mastering are enabled.
-         */
-       status = PCI_Read_CFG_Reg(devno, PCI_CFG_COMMAND, 4);
-       if (!(status & PCI_CMD_MEMEN))
-       {
-               printf("Error: Can not enable MEM access.\n");
-               goto Done;
-       }
+               PCI_Write_CFG_Reg(devno, 
+                                 PCI_CFG_COMMAND, 
+                                 PCI_CMD_MEMEN | 
+                                 PCI_CMD_MASTER, 4);
 
-       if (!(status & PCI_CMD_MASTER))
-       {
-               printf("Error: Can not enable Bus Mastering.\n");
-               goto Done;
-       }
+               /* Check if I/O accesses and Bus Mastering are enabled.
+                */
+               status = PCI_Read_CFG_Reg(devno, PCI_CFG_COMMAND, 4);
+               if (!(status & PCI_CMD_MEMEN))
+               {
+                       printf("Error: Can not enable MEM access.\n");
+                       continue;
+               }
+
+               if (!(status & PCI_CMD_MASTER))
+               {
+                       printf("Error: Can not enable Bus Mastering.\n");
+                       continue;
+               }
+
+               dev = (struct eth_device*) malloc(sizeof *dev);
+
+               sprintf(dev->name, "i82559#%d", i);
+               dev->iobase = iobase;
+               dev->priv   = (void*) devno;
+               dev->init   = eepro100_init;
+               dev->halt   = eepro100_halt;
+               dev->send   = eepro100_send;
+               dev->recv   = eepro100_recv;
+
+               eth_register(dev);
+
+               card_number++;
 
                /* Set the latency timer for value.
                 */
-       PCI_Write_CFG_Reg(devno, PCI_CFG_LATENCY_TIMER, 0x20, 1);
+               PCI_Write_CFG_Reg(devno, PCI_CFG_LATENCY_TIMER, 0x20, 1);
+
+               udelay(10 * 1000);
 
-       udelay(10 * 1000);
+               read_hw_addr(dev, bis);
+       }
+
+       return card_number;
+}
 
-       check_hw_addr(bis);
+
+static int eepro100_init(struct eth_device* dev, bd_t *bis)
+{
+       int i, status = 0;
+       int tx_cur;
+       struct descriptor *ias_cmd;
 
        /* Reset the ethernet controller
         */
-       OUTL(I82559_SELECTIVE_RESET, SCBPort);
+       OUTL(dev, I82559_SELECTIVE_RESET, SCBPort);
        udelay(20);
 
-       OUTL(I82559_RESET, SCBPort);
+       OUTL(dev, I82559_RESET, SCBPort);
        udelay(20);
 
-       if (!wait_for_eepro100())
+       if (!wait_for_eepro100(dev))
        {
                printf("Error: Can not reset ethernet controller.\n");
                goto Done;
        }
-       OUTL(0, SCBPointer);
-       OUTW(SCB_M | RUC_ADDR_LOAD, SCBCmd);
+       OUTL(dev, 0, SCBPointer);
+       OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
 
-       if (!wait_for_eepro100())
+       if (!wait_for_eepro100(dev))
        {
                printf("Error: Can not reset ethernet controller.\n");
                goto Done;
        }
-       OUTL(0, SCBPointer);
-       OUTW(SCB_M | CU_ADDR_LOAD, SCBCmd);
+       OUTL(dev, 0, SCBPointer);
+       OUTW(dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
 
                /* Initialize Rx and Tx rings.
                 */
@@ -349,14 +385,14 @@ int eth_init(bd_t *bis)
 
                /* Tell the adapter where the RX ring is located.
                 */
-       if (!wait_for_eepro100())
+       if (!wait_for_eepro100(dev))
        {
                printf("Error: Can not reset ethernet controller.\n");
                goto Done;
        }
 
-       OUTL(pci_ram_to_mem((u32) &rx_ring[rx_next]), SCBPointer);
-       OUTW(SCB_M | RUC_START, SCBCmd);
+       OUTL(dev, pci_ram_to_mem((u32) &rx_ring[rx_next]), SCBPointer);
+       OUTW(dev, SCB_M | RUC_START, SCBCmd);
 
                /* Send the Individual Address Setup frame
                 */
@@ -372,20 +408,20 @@ int eth_init(bd_t *bis)
 
                /* Tell the adapter where the TX ring is located.
                 */
-       if (!wait_for_eepro100())
+       if (!wait_for_eepro100(dev))
        {
                printf("Error: Can not reset ethernet controller.\n");
                goto Done;
        }
 
-       OUTL(pci_ram_to_mem((u32) &tx_ring[tx_cur]), SCBPointer);
-       OUTW(SCB_M | CU_START, SCBCmd);
+       OUTL(dev, pci_ram_to_mem((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("eth: Tx error buffer not ready\n");
+                       printf("%s: Tx error buffer not ready\n", dev->name);
                        goto Done;
                }
        }
@@ -394,21 +430,23 @@ int eth_init(bd_t *bis)
        {
                printf("TX error status = 0x%08X\n",
                       le16_to_cpu(tx_ring[tx_cur].status));
-               status++;
+               goto Done;
        }
 
+       status = 1;
+
 Done:
        return status;
 }
 
-int eth_send(volatile void *packet, int length)
+static int eepro100_send(struct eth_device* dev, volatile void *packet, int length)
 {
-       int i, status = 0;
+       int i, status = -1;
        int tx_cur;
 
        if (length <= 0)
        {
-               printf("eth: bad packet size: %d\n", length);
+               printf("%s: bad packet size: %d\n", dev->name, length);
                goto Done;
        }
 
@@ -424,22 +462,22 @@ int eth_send(volatile void *packet, int length)
        tx_ring[tx_cur].tx_buf_addr0 = cpu_to_le32(pci_ram_to_mem((u_long) packet));
        tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32(length);
 
-       if (!wait_for_eepro100())
+       if (!wait_for_eepro100(dev))
        {
-               printf("eth: Tx error ethernet controller not ready.\n");
+               printf("%s: Tx error ethernet controller not ready.\n", dev->name);
                goto Done;
        }
 
        /* Send the packet.
         */
-       OUTL(pci_ram_to_mem((u32) &tx_ring[tx_cur]), SCBPointer);
-       OUTW(SCB_M | CU_START, SCBCmd);
+       OUTL(dev, pci_ram_to_mem((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("eth: Tx error buffer not ready\n");
+                       printf("%s: Tx error buffer not ready\n", dev->name);
                        goto Done;
                }
        }
@@ -448,20 +486,22 @@ int eth_send(volatile void *packet, int length)
        {
                printf("TX error status = 0x%08X\n",
                       le16_to_cpu(tx_ring[tx_cur].status));
-               status++;
+               goto Done;
        }
 
+       status = length;
+
  Done:
        return status;
 }
 
-int eth_rx(void)
+static int eepro100_recv(struct eth_device* dev)
 {
        u16 status, stat;
        int rx_prev, length = 0;
 
-       stat = INW(SCBStatus);
-       OUTW(stat & SCB_STATUS_RNR, SCBStatus);
+       stat = INW(dev, SCBStatus);
+       OUTW(dev, stat & SCB_STATUS_RNR, SCBStatus);
 
        for ( ; ; )
        {
@@ -507,56 +547,51 @@ int eth_rx(void)
        if (stat & SCB_STATUS_RNR)
        {
 
-               printf("eth: Receiver is not ready, restart it !\n");
+               printf("%s: Receiver is not ready, restart it !\n", dev->name);
 
                /* Reinitialize Rx ring.
                 */
                init_rx_ring();
 
-               if (!wait_for_eepro100())
+               if (!wait_for_eepro100(dev))
                {
                        printf("Error: Can not restart ethernet controller.\n");
                        goto Done;
                }
 
-               OUTL(pci_ram_to_mem((u32) &rx_ring[rx_next]), SCBPointer);
-               OUTW(SCB_M | RUC_START, SCBCmd);
+               OUTL(dev, pci_ram_to_mem((u32) &rx_ring[rx_next]), SCBPointer);
+               OUTW(dev, SCB_M | RUC_START, SCBCmd);
        }
 
  Done:
        return length;
 }
 
-void eth_halt(void)
+static void eepro100_halt(struct eth_device* dev)
 {
-       if (!iobase) 
-       {
-               goto Done;
-       }
-
        /* Reset the ethernet controller
         */
-       OUTL(I82559_SELECTIVE_RESET, SCBPort);
+       OUTL(dev, I82559_SELECTIVE_RESET, SCBPort);
        udelay(20);
 
-       OUTL(I82559_RESET, SCBPort);
+       OUTL(dev, I82559_RESET, SCBPort);
        udelay(20);
 
-       if (!wait_for_eepro100())
+       if (!wait_for_eepro100(dev))
        {
                printf("Error: Can not reset ethernet controller.\n");
                goto Done;
        }
-       OUTL(0, SCBPointer);
-       OUTW(SCB_M | RUC_ADDR_LOAD, SCBCmd);
+       OUTL(dev, 0, SCBPointer);
+       OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
 
-       if (!wait_for_eepro100())
+       if (!wait_for_eepro100(dev))
        {
                printf("Error: Can not reset ethernet controller.\n");
                goto Done;
        }
-       OUTL(0, SCBPointer);
-       OUTW(SCB_M | CU_ADDR_LOAD, SCBCmd);
+       OUTL(dev, 0, SCBPointer);
+       OUTW(dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
 
  Done:
        return;
@@ -564,38 +599,38 @@ void eth_halt(void)
 
        /* SROM Read.
         */
-static int read_eeprom(long iobase, int location, int addr_len)
+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(EE_ENB & ~EE_CS, SCBeeprom);
-       OUTW(EE_ENB, SCBeeprom);
+       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(EE_ENB | dataval, SCBeeprom);
+               OUTW(dev, EE_ENB | dataval, SCBeeprom);
                udelay(1);
-               OUTW(EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+               OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
                udelay(1);
        }
-       OUTW(EE_ENB, SCBeeprom);
+       OUTW(dev, EE_ENB, SCBeeprom);
 
        for (i = 15; i >= 0; i--) 
        {
-               OUTW(EE_ENB | EE_SHIFT_CLK, SCBeeprom);
+               OUTW(dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom);
                udelay(1);
                retval = (retval << 1) | 
-                       ((INW(SCBeeprom) & EE_DATA_READ) ? 1 : 0);
-               OUTW(EE_ENB, SCBeeprom);
+                       ((INW(dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0);
+               OUTW(dev, EE_ENB, SCBeeprom);
                udelay(1);
        }
 
        /* Terminate the EEPROM access. */
-       OUTW(EE_ENB & ~EE_CS, SCBeeprom);
+       OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
        return retval;
 }
 
@@ -637,40 +672,41 @@ static void purge_tx_ring(void)
        }
 }
 
-static void check_hw_addr(bd_t *bis) 
+static void read_hw_addr(struct eth_device* dev, bd_t *bis) 
 {
        u16 eeprom[0x40];
        u16 sum = 0;
-       u8 hw_addr[ETH_ALEN];
        int i, j;
-       int addr_len = read_eeprom(iobase, 0, 6) == 0xffff ? 8 : 6;
+       int addr_len = read_eeprom(dev, 0, 6) == 0xffff ? 8 : 6;
 
        for (j = 0, i = 0; i < 0x40; i++) 
        {
-               u16 value = read_eeprom(iobase, i, addr_len);
+               u16 value = read_eeprom(dev, i, addr_len);
                eeprom[i] = value;
                sum += value;
                if (i < 3) 
                {
-                       hw_addr[j++] = value;
-                       hw_addr[j++] = value >> 8;
+                       dev->enetaddr[j++] = value;
+                       dev->enetaddr[j++] = value >> 8;
                }
        }
 
+#ifdef DEBUG
        if (sum != 0xBABA)
-               printf("eth: Invalid EEPROM checksum %#4.4x, "
+               printf("%s: Invalid EEPROM checksum %#4.4x, "
                       "check settings before activating this device!\n",
-                      sum);
+                      dev->name, sum);
 
        for (i=0;i<ETH_ALEN;i++) 
        {
-               if (hw_addr[i] != bis->bi_enetaddr[i]) 
+               if (dev->enetaddr[i] != bis->bi_enetaddr[i]) 
                {
                        printf("Warning: HW address don't match:\n");
                        printf("Address in SROM is         "
                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
-                              hw_addr[0], hw_addr[1], hw_addr[2],
-                              hw_addr[3], hw_addr[4], hw_addr[5]);
+                              dev->enetaddr[0], dev->enetaddr[1], 
+                              dev->enetaddr[2], dev->enetaddr[3], 
+                              dev->enetaddr[4], dev->enetaddr[5]);
                        printf("Address used by ppcboot is "
                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
                               bis->bi_enetaddr[0], bis->bi_enetaddr[1], 
@@ -681,5 +717,8 @@ static void check_hw_addr(bd_t *bis)
        }
 
 Done:
+#endif
        return;
 }
+
+#endif
index a99917df680488e1360c1a6205fcfa48bdb2220a..16144eb6db691f4310ab7a0c4980f4d1ae64a3e7 100644 (file)
@@ -36,6 +36,8 @@
 #include "pci.h"
 #include "hardware.h"
 
+#undef DEBUG
+
 /*
  * These are the lowest addresses allowed for PCI configuration.
  * They correspond to lowest available I/O and Memory addresses.
@@ -43,8 +45,8 @@
  * different PLB to PCI regions, each region should have it's own
  * minimum address.
  */
-unsigned long    LowestMemAddr = PCI_LOWEST_MEMADDR;
-unsigned long    LowestIOAddr  = PCI_LOWEST_IOADDR;
+unsigned long    LowestMemBase, LowestMemAddr;
+unsigned long    LowestIOBase,  LowestIOAddr;
 
 unsigned long    MaxBusNum = 0;
 
@@ -115,6 +117,40 @@ int PCI_Scan(int BusNum)
        return Found;
 }
 
+/*
+ * Subroutine:  PCI_Scan_Controller
+ *
+ * Description: Scan through all allowable PCI Buses on the controller 
+ *              and configure those devices.
+ *
+ * Inputs:      BusNum   Bus number where scanning begins
+ *             lIOAddr  Lower I/O and Memory addressed for 
+ *             lMemAddr PCI configuration
+ *
+ * Return:      Number of busses found on the controller.
+ *
+ */
+int PCI_Scan_Controller(int BusNum, unsigned long lMemAddr, unsigned long lIOAddr)
+{
+#ifdef DEBUG
+       printf("Scanning PCI Controller start (bus#%d mem:%lx io:%lx)\n", 
+              BusNum, lMemAddr, lIOAddr);
+#endif
+
+       MaxBusNum     = BusNum;
+       LowestMemBase = LowestMemAddr = lMemAddr;
+       LowestIOBase  = LowestIOAddr  = lIOAddr;
+
+       PCI_Scan(BusNum);
+
+#ifdef DEBUG
+       printf("Scanning PCI Controller finish (bus#%ld mem:%lx io:%lx)\n", 
+              MaxBusNum, LowestMemAddr, LowestIOAddr);
+#endif
+
+       return MaxBusNum - BusNum + 1;
+}
+
 /*
  * Subroutine:  PCI_Config_Device
  *
@@ -170,7 +206,7 @@ void PCI_Config_Device(int BusDevFunc, int NumBaseAddr)
 #ifdef DEBUG
                        printf("  PCI I/O space = 0x%lx bytes\n", AddrDesc);
 #endif
-                       for (AddrProg = PCI_LOWEST_IOADDR;
+                       for (AddrProg = LowestIOBase;
                             AddrProg < LowestIOAddr;
                             AddrProg += AddrDesc) {
                                ;       /* empty */
@@ -195,7 +231,7 @@ void PCI_Config_Device(int BusDevFunc, int NumBaseAddr)
 #ifdef DEBUG
                        printf("  PCI memory space = 0x%lx bytes \n",AddrDesc);
 #endif
-                       for (AddrProg = PCI_LOWEST_MEMADDR;
+                       for (AddrProg = LowestMemBase;
                             AddrProg < LowestMemAddr;
                             AddrProg += AddrDesc) {
                                ;       /* empty */
@@ -239,7 +275,7 @@ void PCI_Config_Device(int BusDevFunc, int NumBaseAddr)
 #ifdef DEBUG
                printf("  PCI Expansion ROM space = 0x%lx bytes\n", AddrDesc);
 #endif
-               for (AddrProg = PCI_LOWEST_MEMADDR;
+               for (AddrProg = LowestMemBase;
                     AddrProg < LowestMemAddr;
                     AddrProg += AddrDesc) {
                        ;       /* empty */
@@ -396,7 +432,7 @@ void PCI_Config_Bridge(int BusDevFunc)
  *              (int)   PCI Bus+Device+Function number
  *
  */
-int PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID)
+int PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID, int Index)
 {
        int     Device;
        int     BusDevFunc;
@@ -412,7 +448,9 @@ int PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID)
 
                        if (PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_VENDOR_ID, 2) == VendorID
                         && PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2) == DeviceID) {
-                               return (BusDevFunc);
+
+                               if (Index-- == 0)
+                                       return (BusDevFunc);
                        }
                }
        }
index 413f4d4dc47c366ab8c1c2326743a07b4e6e317e..0921b1fc101c300efb1120cf8a45b1b9e4a86dd7 100644 (file)
@@ -184,11 +184,12 @@ typedef struct pciHeaderBridge {
 
 unsigned int    PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width);
 int            PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned int Value, int Width);
+int            PCI_Scan_Controller(int BusNum, unsigned long LowestMemAddr, unsigned long LowestIOAddr);
 int             PCI_Scan(int BusNum);
 void            PCI_Config_Device(int BusDevFunc, int NumBaseAddr);
 void            PCI_Config_VGA_Device(int BusDevFunc, int NumBaseAddr);
 void            PCI_Config_Bridge(int BusDevFunc);
-int             PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID);
+int             PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID, int Index);
 void            PCI_Header_Show(int BusDevFunc);
 void            PCI_Dheader_Print(PCI_HEADER_DEVICE * pD);
 void            PCI_Bheader_Print(PCI_HEADER_BRIDGE * pB);
index 35875f853a47af13f00d8a76007726a45769da09..c8bdc8b630677907b4b5e76dfb9126df21a2c00f 100644 (file)
@@ -128,7 +128,8 @@ void pci_init (bd_t * bd)
        cpc710_pci_init ();
 
 #ifdef CONFIG_PCI_PNP
-       PCI_Scan (0);
+       PCI_Scan_Controller (0, BRIDGE_LOCAL_MEM_BUS, BRIDGE_LOCAL_IO_BUS);
+       PCI_Scan_Controller (1, BRIDGE_CPCI_MEM_BUS, BRIDGE_CPCI_IO_BUS);
 #endif
 
        /* FPGA requires no retry timeouts to be enabled
@@ -151,6 +152,13 @@ void pcippc2_wdt_init (void)
        pcippc2_wdt_init_done = 1;
 }
 
+void pcippc2_wdt_done (void)
+{
+       out8 (FPGA (WDT, CTRL), 0x0);
+
+       pcippc2_wdt_init_done = 0;
+}
+
 void pcippc2_wdt_reset (void)
 {
        if (pcippc2_wdt_init_done == 1)
@@ -166,4 +174,39 @@ void watchdog_reset (void)
                enable_interrupts ();
 }
 
-#endif
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+int do_wd (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+       uchar reg, val;
+
+       switch (argc) {
+       case 1:
+               printf ("Watchdog timer status is %s\n", 
+                       pcippc2_wdt_init_done == 1 ? "on" : "off");
+
+               return 0;
+       case 2:
+               if (!strcmp(argv[1],"on")) {
+                       pcippc2_wdt_init();
+                       printf("Watchdog timer now is on\n");
+
+                       return 0;
+
+               } else if (!strcmp(argv[1],"off")) {
+                       pcippc2_wdt_done();
+                       printf("Watchdog timer now is off\n");
+
+                       return 0;
+
+               } else
+                       break;
+       default:
+               break;
+       }
+       printf ("Usage:\n%s\n", cmdtp->usage);
+       return 1;
+}
+
+#endif /* CFG_CMD_BSP */
+#endif /* CONFIG_WATCHDOG */
+
index 88aa4aec87e11ce790899c6894a23b630f09e97c..5fe629439160adde8197d27232de4af9e2f94a2a 100644 (file)
@@ -35,7 +35,7 @@ u32           pcippc2_fpga1_phys;
 
 void pcippc2_fpga_init (void)
 {
-  u32                  bdf = PCI_Find_Device(FPGA_VENDOR_ID, FPGA_DEVICE_ID);
+  u32                  bdf = PCI_Find_Device(FPGA_VENDOR_ID, FPGA_DEVICE_ID, 0);
   u32                  addr;
 
   if (bdf == -1)
index 255d741e11c172af1b6716e9c82549e52285480d..ae6372df5fa7719d69b974c74cb5042f19adf6e6 100644 (file)
@@ -1,9 +1,15 @@
 #include <ppcboot.h>
+#include <malloc.h>
 #include <mpc824x.h>
 #include <net.h>
 
 #include "pci.h"
 
+#undef DEBUG
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
+       defined(CONFIG_EEPRO100)
+
        /* Ethernet chip registers.
         */
 #define SCBStatus              0       /* Rx/Command Unit Status *Word* */
@@ -181,60 +187,59 @@ struct descriptor {                       /* A generic descriptor. */
 
 #define ETH_ALEN               6
 
-#define MAX_CARD               2       /* Maximum number of the cards */
-
 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;
 
-static u_long iobase;
-static u_long card[MAX_CARD];
-static int    card_current, card_number = 0;
-
 static void init_rx_ring (void);
 static void purge_tx_ring (void);
 
-static void check_hw_addr (bd_t * bis);
+static void read_hw_addr (struct eth_device* dev, bd_t * bis);
 
-static inline int INL (u_long addr)
+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);
+
+static inline int INL (struct eth_device* dev, u_long addr)
 {
-       return le32_to_cpu (*(volatile u32 *) (addr + iobase));
+       return le32_to_cpu (*(volatile u32 *) (addr + dev->iobase));
 }
 
-static inline int INW (u_long addr)
+static inline int INW (struct eth_device* dev, u_long addr)
 {
-       return le16_to_cpu (*(volatile u16 *) (addr + iobase));
+       return le16_to_cpu (*(volatile u16 *) (addr + dev->iobase));
 }
 
-static inline int INB (u_long addr)
+static inline int INB (struct eth_device* dev, u_long addr)
 {
-       return *(volatile u8 *) (addr + iobase);
+       return *(volatile u8 *) (addr + dev->iobase);
 }
 
-static inline void OUTB (int command, u_long addr)
+static inline void OUTB (struct eth_device* dev, int command, u_long addr)
 {
-       *(volatile u8 *) (addr + iobase) = command;
+       *(volatile u8 *) (addr + dev->iobase) = command;
 }
 
-static inline void OUTW (int command, u_long addr)
+static inline void OUTW (struct eth_device* dev, int command, u_long addr)
 {
-       *(volatile u16 *) (addr + iobase) = cpu_to_le16 (command);
+       *(volatile u16 *) (addr + dev->iobase) = cpu_to_le16 (command);
 }
 
-static inline void OUTL (int command, u_long addr)
+static inline void OUTL (struct eth_device* dev, int command, u_long addr)
 {
-       *(volatile u32 *) (addr + iobase) = cpu_to_le32 (command);
+       *(volatile u32 *) (addr + dev->iobase) = cpu_to_le32 (command);
 }
 
        /* Wait for the chip get the command.
         */
-static int wait_for_eepro100 (void)
+static int wait_for_eepro100 (struct eth_device* dev)
 {
        int i;
 
-       for (i = 0; INW (SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) {
+       for (i = 0; INW (dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) {
                if (i >= TOUT_LOOP) {
                        return 0;
                }
@@ -243,112 +248,113 @@ static int wait_for_eepro100 (void)
        return 1;
 }
 
-static int card_find (bd_t * bis)
+int eepro100_initialize (bd_t * bis)
 {
-       int i, status = 0;
+       int card_number, i, status = 0;
        int bus, devno, func;
-
-       for (i=0; i<MAX_CARD; i++)
+       struct eth_device *dev;
+       u_long iobase;
+       static int supported[] = { 
+               PCI_DEVICE_ID_INTEL_82557, 
+               PCI_DEVICE_ID_INTEL_82559, 
+               -1 
+       }, *devid;
+
+       for (card_number = i = 0, devid = supported; *devid != -1; devid++)
        {
-               /* Find PCI device
-                */
-               if ((pci_dev_find (PCI_VENDOR_ID_INTEL,
-                                  PCI_DEVICE_ID_INTEL_82557,
-                                  i, &bus, &devno, &func) != TRUE) &&
-                   (pci_dev_find (PCI_VENDOR_ID_INTEL,
-                                  PCI_DEVICE_ID_INTEL_82559,
-                                  i, &bus, &devno, &func) != TRUE)) {
-                       break;
-               }
-
-               pci_config_inl (bus, devno, func,
-                               PCI_CFG_BASE_ADDRESS_0, (uint32 *) & iobase);
-               iobase &= PCI_MEMBASE_MASK;
-
-               card[card_number] = iobase;
-               card_current      = card_number;
-
-               printf ("eth%d: Intel i82559 PCI EtherExpressPro @0x%lX"
-                       "(bus=%d, device=%d, func=%d)\n",
-                       card_current, iobase, bus, devno, func);
-
-               pci_config_outl (bus, devno, func,
-                                PCI_CFG_COMMAND,
-                                PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE);
-
-               /* Check if I/O accesses and Bus Mastering are enabled.
-                */
-               pci_config_inl (bus, devno, func, PCI_CFG_COMMAND, &status);
+               for (; ; i++)
+               {
+                       /* Find PCI device
+                        */
+                       if (pci_dev_find (PCI_VENDOR_ID_INTEL,
+                                         *devid,
+                                         i, &bus, &devno, &func) != TRUE) {
+                               break;
+                       }
+
+                       pci_config_inl (bus, devno, func,
+                                       PCI_CFG_BASE_ADDRESS_0, (uint32 *) & iobase);
+                       iobase &= PCI_MEMBASE_MASK;
+
+#ifdef DEBUG
+                       printf ("eepro100: Intel i82559 PCI EtherExpressPro @0x%lX"
+                               "(bus=%d, device=%d, func=%d)\n",
+                               iobase, bus, devno, func);
+#endif
+
+                       pci_config_outl (bus, devno, func,
+                                        PCI_CFG_COMMAND,
+                                        PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE);
+
+                       /* Check if I/O accesses and Bus Mastering are enabled.
+                        */
+                       pci_config_inl (bus, devno, func, PCI_CFG_COMMAND, &status);
 
-               if (!(status & PCI_CMD_MEM_ENABLE)) {
-                       puts ("Error: Can not enable MEM access\n");
-                       continue;
-               }
+                       if (!(status & PCI_CMD_MEM_ENABLE)) {
+                               puts ("Error: Can not enable MEM access\n");
+                               continue;
+                       }
 
-               if (!(status & PCI_CMD_MASTER_ENABLE)) {
-                       puts ("Error: Can not enable Bus Mastering\n");
-                       continue;
-               }
+                       if (!(status & PCI_CMD_MASTER_ENABLE)) {
+                               puts ("Error: Can not enable Bus Mastering\n");
+                               continue;
+                       }
 
-               /* Set the latency timer for value.
-                */
-               pci_config_outb (bus, devno, func,
-                                PCI_CFG_LATENCY_TIMER, PCI_LATENCY_TIMER);
+                       dev = (struct eth_device*) malloc(sizeof *dev);
 
-               udelay (10 * 1000);
+                       sprintf(dev->name, "i82559#%d", i);
+                       dev->iobase = iobase;
+                       dev->priv   = (void*) devno;
+                       dev->init   = eepro100_init;
+                       dev->halt   = eepro100_halt;
+                       dev->send   = eepro100_send;
+                       dev->recv   = eepro100_recv;
 
-               check_hw_addr (bis);
+                       card_number++;
 
-               /* Reset the ethernet controller
-                */
-               OUTL (I82559_SELECTIVE_RESET, SCBPort);
-               udelay (20);
+                       eth_register(dev);
 
-               OUTL (I82559_RESET, SCBPort);
-               udelay (20);
+                       /* Set the latency timer for value.
+                        */
+                       pci_config_outb (bus, devno, func,
+                                        PCI_CFG_LATENCY_TIMER, PCI_LATENCY_TIMER);
 
-               if (!wait_for_eepro100 ()) {
-                       puts ("Error: Can not reset ethernet controller\n");
-                       continue;
-               }
-               OUTL (0, SCBPointer);
-               OUTW (SCB_M | RUC_ADDR_LOAD, SCBCmd);
+                       udelay (10 * 1000);
 
-               if (!wait_for_eepro100 ()) {
-                       puts ("Error: Can not reset ethernet controller\n");
-                       continue;
+                       read_hw_addr (dev, bis);
                }
-               OUTL (0, SCBPointer);
-               OUTW (SCB_M | CU_ADDR_LOAD, SCBCmd);
-
-               card_number++;
        }
 
        return card_number;
 }
 
-static void card_set_current (int num) {
-       card_current = num;
-
-       iobase = card[card_current];
-
-       printf ("eth%d: using Intel i82559 PCI EtherExpressPro @0x%lX\n", card_current, iobase);
-}
-
-int eth_init (bd_t * bis)
+static int eepro100_init (struct eth_device* dev, bd_t * bis)
 {
        int i, status = 0;
        int tx_cur;
        struct descriptor *ias_cmd;
 
-       if (card_number == 0) {
-               if (!card_find (bis)) {
-                       puts ("Error: Can not find any ethernet card on the PCI bus\n");
-                       return (status);
-               }
+       /* Reset the ethernet controller
+        */
+       OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);
+       udelay (20);
+
+       OUTL (dev, I82559_RESET, SCBPort);
+       udelay (20);
 
-               card_set_current (0);
+       if (!wait_for_eepro100 (dev)) {
+               puts ("Error: Can not reset ethernet controller\n");
+               return (status);
        }
+       OUTL (dev, 0, SCBPointer);
+       OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
+
+       if (!wait_for_eepro100 (dev)) {
+               puts ("Error: Can not reset ethernet controller\n");
+               return (status);
+       }
+       OUTL (dev, 0, SCBPointer);
+       OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
 
        /* Initialize Rx and Tx rings.
         */
@@ -357,13 +363,13 @@ int eth_init (bd_t * bis)
 
        /* Tell the adapter where the RX ring is located.
         */
-       if (!wait_for_eepro100 ()) {
+       if (!wait_for_eepro100 (dev)) {
                puts ("Error: Can not reset ethernet controller\n");
                return (status);
        }
 
-       OUTL ((u32) & rx_ring[rx_next], SCBPointer);
-       OUTW (SCB_M | RUC_START, SCBCmd);
+       OUTL (dev, (u32) & rx_ring[rx_next], SCBPointer);
+       OUTW (dev, SCB_M | RUC_START, SCBCmd);
 
        /* Send the Individual Address Setup frame
         */
@@ -379,19 +385,19 @@ int eth_init (bd_t * bis)
 
        /* Tell the adapter where the TX ring is located.
         */
-       if (!wait_for_eepro100 ()) {
+       if (!wait_for_eepro100 (dev)) {
                puts ("Error: Can not reset ethernet controller\n");
                return (status);
        }
 
-       OUTL ((u32) & tx_ring[tx_cur], SCBPointer);
-       OUTW (SCB_M | CU_START, SCBCmd);
+       OUTL (dev, (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 ("eth%d: Tx error buffer not ready\n", card_current);
+                       printf ("%s: Tx error buffer not ready\n", dev->name);
                        return (status);
                }
        }
@@ -399,27 +405,21 @@ int eth_init (bd_t * bis)
        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));
-               status++;
+               return (status);
        }
 
-       return (status);
-}
+       status = 1;
 
-void eth_try_another (void)
-{
-       card_set_current ((card_current + 1) % card_number);
+       return (status);
 }
 
-int eth_send (volatile void *packet, int length)
+static int eepro100_send (struct eth_device *dev, volatile void *packet, int length)
 {
-       int i, status = 0;
+       int i, status = -1;
        int tx_cur;
 
-       if (card_number == 0)
-               return (status);
-
        if (length <= 0) {
-               printf ("eth%d: bad packet size: %d\n", card_current, length);
+               printf ("%s: bad packet size: %d\n", dev->name, length);
                return (status);
        }
 
@@ -437,21 +437,21 @@ int eth_send (volatile void *packet, int length)
        tx_ring[tx_cur].tx_buf_addr0 = cpu_to_le32 ((u_long) packet);
        tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length);
 
-       if (!wait_for_eepro100 ()) {
-               printf ("eth%d: Tx error ethernet controller not ready\n", card_current);
+       if (!wait_for_eepro100 (dev)) {
+               printf ("%s: Tx error ethernet controller not ready\n", dev->name);
                return (status);
        }
 
        /* Send the packet.
         */
-       OUTL ((u32) & tx_ring[tx_cur], SCBPointer);
-       OUTW (SCB_M | CU_START, SCBCmd);
+       OUTL (dev, (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 ("eth%d: Tx error buffer not ready\n", card_current);
+                       printf ("%s: Tx error buffer not ready\n", dev->name);
                        return (status);
                }
        }
@@ -459,22 +459,21 @@ int eth_send (volatile void *packet, int length)
        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));
-               status++;
+               return (status);
        }
 
+       status = length;
+
        return (status);
 }
 
-int eth_rx (void)
+static int eepro100_recv (struct eth_device *dev)
 {
        u16 status, stat;
        int rx_prev, length = 0;
 
-       if (card_number == 0)
-               return (length);
-
-       stat = INW (SCBStatus);
-       OUTW (stat & SCB_STATUS_RNR, SCBStatus);
+       stat = INW (dev, SCBStatus);
+       OUTW (dev, stat & SCB_STATUS_RNR, SCBStatus);
 
        for (;;) {
                status = le16_to_cpu (rx_ring[rx_next].status);
@@ -514,88 +513,84 @@ int eth_rx (void)
 
        if (stat & SCB_STATUS_RNR) {
 
-               printf ("eth%d: Receiver is not ready, restart it\n", card_current);
+               printf ("%s: Receiver is not ready, restart it\n", dev->name);
 
                /* Reinitialize Rx ring.
                 */
                init_rx_ring ();
 
-               if (!wait_for_eepro100 ()) {
+               if (!wait_for_eepro100 (dev)) {
                        puts ("Error: Can not restart ethernet controller\n");
                        return (length);
                }
 
-               OUTL ((u32) & rx_ring[rx_next], SCBPointer);
-               OUTW (SCB_M | RUC_START, SCBCmd);
+               OUTL (dev, (u32) & rx_ring[rx_next], SCBPointer);
+               OUTW (dev, SCB_M | RUC_START, SCBCmd);
        }
 
        return (length);
 }
 
-void eth_halt (void)
+static void eepro100_halt (struct eth_device* dev)
 {
-       if (card_number == 0) {
-               return;
-       }
-
        /* Reset the ethernet controller
         */
-       OUTL (I82559_SELECTIVE_RESET, SCBPort);
+       OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);
        udelay (20);
 
-       OUTL (I82559_RESET, SCBPort);
+       OUTL (dev, I82559_RESET, SCBPort);
        udelay (20);
 
-       if (!wait_for_eepro100 ()) {
+       if (!wait_for_eepro100 (dev)) {
                puts ("Error: Can not reset ethernet controller\n");
                return;
        }
-       OUTL (0, SCBPointer);
-       OUTW (SCB_M | RUC_ADDR_LOAD, SCBCmd);
+       OUTL (dev, 0, SCBPointer);
+       OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
 
-       if (!wait_for_eepro100 ()) {
+       if (!wait_for_eepro100 (dev)) {
                puts ("Error: Can not reset ethernet controller\n");
                return;
        }
-       OUTL (0, SCBPointer);
-       OUTW (SCB_M | CU_ADDR_LOAD, SCBCmd);
+       OUTL (dev, 0, SCBPointer);
+       OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
 
        return;
 }
 
        /* SROM Read.
         */
-static int read_eeprom (long iobase, int location, int addr_len)
+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 (EE_ENB & ~EE_CS, SCBeeprom);
-       OUTW (EE_ENB, SCBeeprom);
+       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 (EE_ENB | dataval, SCBeeprom);
+               OUTW (dev, EE_ENB | dataval, SCBeeprom);
                udelay (1);
-               OUTW (EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+               OUTW (dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
                udelay (1);
        }
-       OUTW (EE_ENB, SCBeeprom);
+       OUTW (dev, EE_ENB, SCBeeprom);
 
        for (i = 15; i >= 0; i--) {
-               OUTW (EE_ENB | EE_SHIFT_CLK, SCBeeprom);
+               OUTW (dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom);
                udelay (1);
                retval = (retval << 1) |
-                               ((INW (SCBeeprom) & EE_DATA_READ) ? 1 : 0);
-               OUTW (EE_ENB, SCBeeprom);
+                               ((INW (dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0);
+               OUTW (dev, EE_ENB, SCBeeprom);
                udelay (1);
        }
 
        /* Terminate the EEPROM access. */
-       OUTW (EE_ENB & ~EE_CS, SCBeeprom);
+       OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom);
        return retval;
 }
 
@@ -636,38 +631,39 @@ static void purge_tx_ring (void)
        }
 }
 
-static void check_hw_addr (bd_t * bis)
+static void read_hw_addr (struct eth_device *dev, bd_t * bis)
 {
        u16 eeprom[0x40];
        u16 sum = 0;
-       u8 hw_addr[ETH_ALEN];
        int i, j;
-       int addr_len = read_eeprom (iobase, 0, 6) == 0xffff ? 8 : 6;
+       int addr_len = read_eeprom (dev, 0, 6) == 0xffff ? 8 : 6;
 
        for (j = 0, i = 0; i < 0x40; i++) {
-               u16 value = read_eeprom (iobase, i, addr_len);
+               u16 value = read_eeprom (dev, i, addr_len);
 
                eeprom[i] = value;
                sum += value;
                if (i < 3) {
-                       hw_addr[j++] = value;
-                       hw_addr[j++] = value >> 8;
+                       dev->enetaddr[j++] = value;
+                       dev->enetaddr[j++] = value >> 8;
                }
        }
 
        if (sum != 0xBABA) {
-               printf ("eth%d: Invalid EEPROM checksum %#4.4x, "
+               printf ("%s: Invalid EEPROM checksum %#4.4x, "
                        "check settings before activating this device!\n",
-                       card_current, sum);
+                       dev->name, sum);
        }
 
+#ifdef DEBUG
        for (i = 0; i < ETH_ALEN; i++) {
-               if (hw_addr[i] != bis->bi_enetaddr[i]) {
+               if (dev->enetaddr[i] != bis->bi_enetaddr[i]) {
                        printf ("Warning: HW address don't match:\n");
                        printf ("Address in SROM is         "
                                "%02X:%02X:%02X:%02X:%02X:%02X\n",
-                               hw_addr[0], hw_addr[1], hw_addr[2],
-                               hw_addr[3], hw_addr[4], hw_addr[5]);
+                               dev->enetaddr[0], dev->enetaddr[1], 
+                               dev->enetaddr[2], dev->enetaddr[3], 
+                               dev->enetaddr[4], dev->enetaddr[5]);
                        printf ("Address used by ppcboot is "
                                "%02X:%02X:%02X:%02X:%02X:%02X\n",
                                bis->bi_enetaddr[0], bis->bi_enetaddr[1],
@@ -676,6 +672,9 @@ static void check_hw_addr (bd_t * bis)
                        return;
                }
        }
+#endif
 
        return;
 }
+
+#endif
index 8b8b9428e1ee745fcfb6c0684a504fa4017a9db7..a716d2753eeebba218dbb438f0dd4f35b82e5881 100644 (file)
@@ -56,7 +56,6 @@ SECTIONS
     cpu/mpc824x/start.o        (.text)
                common/board.o (.text)
     ppc/ppcstring.o    (.text)
-    ppc/crc32.o                (.text)
 
                . = DEFINED(env_offset) ? env_offset : .;
     common/environment.o (.text)
index d351a2059599ac2fe2e9a456e6aed7194e1a3c4d..6414a3ddfae0d3e2f962fabed32c7c0e0f7b7efc 100644 (file)
@@ -785,6 +785,12 @@ void    board_init_r  (bd_t *bd, ulong dest_addr)
     doc_init();
 #endif
 
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI)
+    WATCHDOG_RESET();
+    puts ("Net:   ");
+    eth_initialize(bd);
+#endif
+
 #ifdef CONFIG_LAST_STAGE_INIT
     WATCHDOG_RESET();
     /*
index 65e9e86f03138d7cd16cfd86a930322ad81a79ef..8422b802069e99a8017916d5deb3603e69df765d 100644 (file)
@@ -78,6 +78,7 @@
 #define CFG_CMD_NONSTD (CFG_CMD_ASKENV | \
                        CFG_CMD_BEDBUG  | \
                        CFG_CMD_BSP     | \
+                       CFG_CMD_CACHE   | \
                        CFG_CMD_DATE    | \
                        CFG_CMD_DHCP    | \
                        CFG_CMD_DOC     | \
index 83e0202ac1f6064af2f2cfb97058a9d8bfd641cc..c411fa8434a38e6548652770073f22e9c6ff7ba1 100644 (file)
 
 #undef  CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
 #define CFG_IGNORE_405_UART_ERRATA_59   /* ignore ppc405gp errata #59   */
+#define CFG_BASE_BAUD       691200
 
 /* The following table includes the supported baudrates */
 #define CFG_BAUDRATE_TABLE      \
index 632ce5ee5af2d57e143ef155c239d6b9e255ae48..38ce988ddb5035abe47374f01ce328144e01b1e8 100644 (file)
 
 
 #undef  CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
+#define CFG_BASE_BAUD       691200
 
 /* The following table includes the supported baudrates */
 #define CFG_BAUDRATE_TABLE      \
index 879ce82ce5891c5efb78af48c6d0824a975ee696..c39872cfb1ddcc53b96c961b922d3cf33d891613 100644 (file)
 
 #undef CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
 #define CFG_IGNORE_405_UART_ERRATA_59
+#define CFG_BASE_BAUD       691200
 
 /* The following table includes the supported baudrates */
 #define CFG_BAUDRATE_TABLE     \
index 00aa7d6d7ad1dc89e87bf611441e68b3f6eb4b2f..baad410eb3b2cb350b00975d045096b5c0ebb588 100644 (file)
@@ -89,6 +89,7 @@
 
 #undef  CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
 #define CFG_IGNORE_405_UART_ERRATA_59   /* ignore ppc405gp errata #59   */
+#define CFG_BASE_BAUD       691200
 
 /* The following table includes the supported baudrates */
 #define CFG_BAUDRATE_TABLE      \
index 4a663b8ec655fa6a317f0614680d5a43e3fb136a..409c0a983b3604626158b90ef96ded2d67b2a5e0 100644 (file)
 
 #define CONFIG_WATCHDOG
 
+#define CONFIG_NET_MULTI                       /* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100
+#define CONFIG_TULIP
+
 #endif /* __CONFIG_H */
index bbcbacb7c4db306ec2e9e20b85230b0f1aa29a9e..f866a1571b7440ceea0b8f0afb59cc38335771e3 100644 (file)
 #define CONFIG_BOOTDELAY       5
 
 #define CONFIG_BOOTP_MASK      (CONFIG_BOOTP_DEFAULT | \
-                                CONFIG_BOOTP_BOOTFILESIZE)
+                                CONFIG_BOOTP_BOOTFILESIZE)
 
 #define CONFIG_MAC_PARTITION
 #define CONFIG_DOS_PARTITION
 
-#define CONFIG_COMMANDS                (CONFIG_CMD_DFL | \
-                                CFG_CMD_ASKENV | \
+#define CONFIG_COMMANDS                (CONFIG_CMD_DFL | \
+                                CFG_CMD_ASKENV | \
                                 CFG_CMD_DHCP   | \
                                 CFG_CMD_PCI    | \
                                 CFG_CMD_DOC    | \
                                 CFG_CMD_DATE | \
-         CFG_CMD_SCSI )
+        CFG_CMD_SCSI )
 
 
 #define CONFIG_PCI             1
@@ -84,9 +84,9 @@
 #define CFG_LONGHELP                   /* undef to save memory         */
 #define CFG_PROMPT     "=> "           /* Monitor Command Prompt       */
 
-#define        CFG_HUSH_PARSER         1       /* use "hush" command parser    */
+#define CFG_HUSH_PARSER                1       /* use "hush" command parser    */
 #ifdef CFG_HUSH_PARSER
-#define        CFG_PROMPT_HUSH_PS2     "> "
+#define CFG_PROMPT_HUSH_PS2    "> "
 #endif
 #define CFG_CBSIZE     256             /* Console I/O Buffer Size      */
 
@@ -94,7 +94,7 @@
  */
 #define CFG_PBSIZE     (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
 
-#define        CFG_MAXARGS     64              /* max number of command args   */
+#define CFG_MAXARGS    64              /* max number of command args   */
 #define CFG_BARGSIZE   CFG_CBSIZE      /* Boot Argument Buffer Size    */
 #define CFG_LOAD_ADDR  0x00100000      /* Default load address         */
 
 #define CFG_FLASH_MAX_SIZE  0x00100000
 /* Maximum amount of RAM.
  */
-#define CFG_MAX_RAM_SIZE    0x20000000  /* 512Mb                       */
+#define CFG_MAX_RAM_SIZE    0x20000000 /* 512Mb                        */
 
 #define CFG_RESET_ADDRESS   0xFFF00100
 
  * For the detail description refer to the PCIPPC2 user's manual.
  */
 #define CFG_HZ               1000
-#define CFG_BUS_HZ            100000000 /* bus speed - 100 mhz          */
+#define CFG_BUS_HZ           100000000 /* bus speed - 100 mhz          */
 #define CFG_CPU_CLK          300000000
 #define CFG_BUS_CLK          100000000
 
  * have to be in the first 8 MB of memory, since this is
  * the maximum mapped by the Linux kernel during initialization.
  */
-#define CFG_BOOTMAPSZ        (8 << 20) /* Initial Memory map for Linux */
+#define CFG_BOOTMAPSZ        (8 << 20) /* Initial Memory map for Linux */
 
 /*-----------------------------------------------------------------------
  * FLASH organization
  * L2 cache
  */
 #undef CFG_L2
-#define L2_INIT   (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \
-                   L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT)
+#define L2_INIT          (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \
+                  L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT)
 #define L2_ENABLE (L2_INIT | L2CR_L2E)
 
 /*
 
 #define CONFIG_WATCHDOG
 
+#define CONFIG_NET_MULTI               /* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100
+#define CONFIG_TULIP
 
 
 #define CONFIG_SCSI_SYM53C8XX
-#define CONFIG_SCSI_DEV_ID     0x000B   /* 53c896 */
+#define CONFIG_SCSI_DEV_ID     0x000B  /* 53c896 */
 #define CFG_SCSI_MAX_LUN       8       /* number of supported LUNs */
 #define CFG_SCSI_MAX_SCSI_ID   15      /* maximum SCSI ID (0..6) */
 #define CFG_SCSI_MAX_DEVICE    CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN /* maximum Target devices */
index fd23267e0f6067699196cb17205a8b17fe844464..bd29274947be2c25adff2f25eab1677bbb979e2d 100644 (file)
 
 #undef CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
 #define CFG_IGNORE_405_UART_ERRATA_59
+#define CFG_BASE_BAUD       691200
 
 /* The following table includes the supported baudrates */
 #define CFG_BAUDRATE_TABLE     \
index b94532401444cd9ffde0339c12ea5cb38849a497..1c37aa0eebee9d8fa40d8f3d19970be98627dcff 100644 (file)
@@ -77,6 +77,8 @@
 
 #define CONFIG_NET_MULTI                       /* Multi ethernet cards support */
 
+#define CONFIG_EEPRO100
+
 #define PCI_ENET0_IOADDR       0x80000000
 #define PCI_ENET0_MEMADDR      0x80000000
 #define        PCI_ENET1_IOADDR        0x81000000
index 0a65b15bed9e4ecb3a89601fbb62832a32e409c1..535324c95e7a1fc724c20ebe4096676e9582a3c0 100644 (file)
@@ -48,15 +48,40 @@ typedef void        rxhand_f(uchar *, unsigned, unsigned, unsigned);
  */
 typedef void   thand_f(void);
 
+#ifdef CONFIG_NET_MULTI
 
+#define NAMESIZE 16
+
+enum eth_state_t {
+       ETH_STATE_INIT,
+       ETH_STATE_PASSIVE,
+       ETH_STATE_ACTIVE
+};
+
+struct eth_device {
+       char name[NAMESIZE];
+       unsigned char enetaddr[6];
+       int iobase;
+       int state;
+       
+       int  (*init) (struct eth_device*, bd_t*);
+       int  (*send) (struct eth_device*, volatile void* pachet, int length);
+       int  (*recv) (struct eth_device*);
+       void (*halt) (struct eth_device*);
+
+       struct eth_device *next;
+       void *priv;
+};
+
+extern int eth_initialize(bd_t *bis);          /* Initialize network subsystem */
+extern int eth_register(struct eth_device* dev);/* Register network device     */
+extern void eth_try_another(void);             /* Change the device            */
+#endif
 
 extern int eth_init(bd_t *bis);                        /* Initialize the device        */
 extern int eth_send(volatile void *packet, int length);           /* Send a packet     */
 extern int eth_rx(void);                       /* Check for received packets   */
 extern void eth_halt(void);                    /* stop SCC                     */
-#ifdef CONFIG_NET_MULTI
-extern void eth_try_another(void);             /* Change the device            */
-#endif
 
 
 /**********************************************************************/
index a87b81b856d198154b9da0f030f96e1c110eb889..db0a69fae003748d6d54d6e16543cd8a77f1aa5b 100644 (file)
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
 
 LIB    = libnet.a
 
-OBJS   = net.o tftp.o bootp.o rarp.o arp.o
+OBJS   = net.o tftp.o bootp.o rarp.o arp.o eth.o
 all:   $(LIB)
 
 $(LIB):        $(START) $(OBJS)