From: wdenk Date: Mon, 25 Feb 2002 17:43:46 +0000 (+0000) Subject: * Improved (unified) support for multiple ethernet interfaces X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=c0c2c31b7c227da4b4707a4c0491981e6c1097d9;p=users%2Frw%2Fppcboot.git * Improved (unified) support for multiple ethernet interfaces Now tested on PCIPPCx and Sandpoint 8240 * Removed "icache" / "dcache" from list of standard commands --- diff --git a/CHANGELOG b/CHANGELOG index 715f307..0ac237b 100644 --- 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 0743cdd..aa17727 100644 --- 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" diff --git a/board/evb64260/sdram_init.c b/board/evb64260/sdram_init.c index 0cf1860..d6ce208 100644 --- a/board/evb64260/sdram_init.c +++ b/board/evb64260/sdram_init.c @@ -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 diff --git a/board/pcippc2/Makefile b/board/pcippc2/Makefile index 203723b..66d49b4 100644 --- a/board/pcippc2/Makefile +++ b/board/pcippc2/Makefile @@ -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) diff --git a/board/pcippc2/cpc710_pci.h b/board/pcippc2/cpc710_pci.h index 601652f..3903c4c 100644 --- a/board/pcippc2/cpc710_pci.h +++ b/board/pcippc2/cpc710_pci.h @@ -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 index 0000000..bd01d69 --- /dev/null +++ b/board/pcippc2/dc2114x.c @@ -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 +#include +#include + +#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 diff --git a/board/pcippc2/eepro100.c b/board/pcippc2/eepro100.c index 94a9a28..cf3943c 100644 --- a/board/pcippc2/eepro100.c +++ b/board/pcippc2/eepro100.c @@ -22,11 +22,17 @@ */ #include +#include #include #include #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;ibi_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 diff --git a/board/pcippc2/pci.c b/board/pcippc2/pci.c index a99917d..16144eb 100644 --- a/board/pcippc2/pci.c +++ b/board/pcippc2/pci.c @@ -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); } } } diff --git a/board/pcippc2/pci.h b/board/pcippc2/pci.h index 413f4d4..0921b1f 100644 --- a/board/pcippc2/pci.h +++ b/board/pcippc2/pci.h @@ -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); diff --git a/board/pcippc2/pcippc2.c b/board/pcippc2/pcippc2.c index 35875f8..c8bdc8b 100644 --- a/board/pcippc2/pcippc2.c +++ b/board/pcippc2/pcippc2.c @@ -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 */ + diff --git a/board/pcippc2/pcippc2_fpga.c b/board/pcippc2/pcippc2_fpga.c index 88aa4ae..5fe6294 100644 --- a/board/pcippc2/pcippc2_fpga.c +++ b/board/pcippc2/pcippc2_fpga.c @@ -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) diff --git a/board/sandpoint/eepro100.c b/board/sandpoint/eepro100.c index 255d741..ae6372d 100644 --- a/board/sandpoint/eepro100.c +++ b/board/sandpoint/eepro100.c @@ -1,9 +1,15 @@ #include +#include #include #include #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; iname, "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 diff --git a/board/sandpoint/ppcboot.lds b/board/sandpoint/ppcboot.lds index 8b8b942..a716d27 100644 --- a/board/sandpoint/ppcboot.lds +++ b/board/sandpoint/ppcboot.lds @@ -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) diff --git a/common/board.c b/common/board.c index d351a20..6414a3d 100644 --- a/common/board.c +++ b/common/board.c @@ -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(); /* diff --git a/include/cmd_confdefs.h b/include/cmd_confdefs.h index 65e9e86..8422b80 100644 --- a/include/cmd_confdefs.h +++ b/include/cmd_confdefs.h @@ -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 | \ diff --git a/include/config_CPCI405.h b/include/config_CPCI405.h index 83e0202..c411fa8 100644 --- a/include/config_CPCI405.h +++ b/include/config_CPCI405.h @@ -107,6 +107,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 \ diff --git a/include/config_CRAYL1.h b/include/config_CRAYL1.h index 632ce5e..38ce988 100644 --- a/include/config_CRAYL1.h +++ b/include/config_CRAYL1.h @@ -119,6 +119,7 @@ #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 \ diff --git a/include/config_MIP405.h b/include/config_MIP405.h index 879ce82..c39872c 100644 --- a/include/config_MIP405.h +++ b/include/config_MIP405.h @@ -143,6 +143,7 @@ #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 \ diff --git a/include/config_OCRTC.h b/include/config_OCRTC.h index 00aa7d6..baad410 100644 --- a/include/config_OCRTC.h +++ b/include/config_OCRTC.h @@ -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 \ diff --git a/include/config_PCIPPC2.h b/include/config_PCIPPC2.h index 4a663b8..409c0a9 100644 --- a/include/config_PCIPPC2.h +++ b/include/config_PCIPPC2.h @@ -256,4 +256,9 @@ #define CONFIG_WATCHDOG +#define CONFIG_NET_MULTI /* Multi ethernet cards support */ + +#define CONFIG_EEPRO100 +#define CONFIG_TULIP + #endif /* __CONFIG_H */ diff --git a/include/config_PCIPPC6.h b/include/config_PCIPPC6.h index bbcbacb..f866a15 100644 --- a/include/config_PCIPPC6.h +++ b/include/config_PCIPPC6.h @@ -56,18 +56,18 @@ #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 */ @@ -108,7 +108,7 @@ #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 @@ -189,7 +189,7 @@ * 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 @@ -198,7 +198,7 @@ * 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 @@ -230,8 +230,8 @@ * 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) /* @@ -258,10 +258,14 @@ #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 */ diff --git a/include/config_PIP405.h b/include/config_PIP405.h index fd23267..bd29274 100644 --- a/include/config_PIP405.h +++ b/include/config_PIP405.h @@ -146,6 +146,7 @@ #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 \ diff --git a/include/config_Sandpoint8240.h b/include/config_Sandpoint8240.h index b945324..1c37aa0 100644 --- a/include/config_Sandpoint8240.h +++ b/include/config_Sandpoint8240.h @@ -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 diff --git a/include/net.h b/include/net.h index 0a65b15..535324c 100644 --- a/include/net.h +++ b/include/net.h @@ -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 /**********************************************************************/ diff --git a/net/Makefile b/net/Makefile index a87b81b..db0a69f 100644 --- a/net/Makefile +++ b/net/Makefile @@ -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)