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:
#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"
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
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)
#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
--- /dev/null
+/*
+ * 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
*/
#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
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)
{
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.
*/
/* 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
*/
/* 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;
}
}
{
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;
}
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;
}
}
{
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 ( ; ; )
{
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;
/* 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;
}
}
}
-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],
}
Done:
+#endif
return;
}
+
+#endif
#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.
* 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;
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
*
#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 */
#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 */
#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 */
* (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;
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);
}
}
}
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);
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
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)
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 */
+
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)
#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* */
#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;
}
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.
*/
/* 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
*/
/* 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);
}
}
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);
}
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);
}
}
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);
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;
}
}
}
-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],
return;
}
}
+#endif
return;
}
+
+#endif
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)
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();
/*
#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 | \
#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 \
#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 \
#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 \
#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 \
#define CONFIG_WATCHDOG
+#define CONFIG_NET_MULTI /* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100
+#define CONFIG_TULIP
+
#endif /* __CONFIG_H */
#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
#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 */
*/
#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 */
#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 \
#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
*/
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
/**********************************************************************/
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)