summaryrefslogtreecommitdiffstats
path: root/debian/grub-extras/disabled/gpxe/src/drivers/net/eepro.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/grub-extras/disabled/gpxe/src/drivers/net/eepro.c')
-rw-r--r--debian/grub-extras/disabled/gpxe/src/drivers/net/eepro.c637
1 files changed, 637 insertions, 0 deletions
diff --git a/debian/grub-extras/disabled/gpxe/src/drivers/net/eepro.c b/debian/grub-extras/disabled/gpxe/src/drivers/net/eepro.c
new file mode 100644
index 0000000..a248692
--- /dev/null
+++ b/debian/grub-extras/disabled/gpxe/src/drivers/net/eepro.c
@@ -0,0 +1,637 @@
+#ifdef ALLMULTI
+#error multicast support is not yet implemented
+#endif
+/**************************************************************************
+Etherboot - BOOTP/TFTP Bootstrap Program
+Intel EEPRO/10 NIC driver for Etherboot
+Adapted from Linux eepro.c from kernel 2.2.17
+
+This board accepts a 32 pin EEPROM (29C256), however a test with a
+27C010 shows that this EPROM also works in the socket, but it's not clear
+how repeatably. The two top address pins appear to be held low, thus
+the bottom 32kB of the 27C010 is visible in the CPU's address space.
+To be sure you could put 4 copies of the code in the 27C010, then
+it doesn't matter whether the extra lines are held low or high, just
+hopefully not floating as CMOS chips don't like floating inputs.
+
+Be careful with seating the EPROM as the socket on my board actually
+has 34 pins, the top row of 2 are not used.
+***************************************************************************/
+
+/*
+
+ timlegge 2005-05-18 remove the relocation changes cards that
+ write directly to the hardware don't need it
+*/
+
+/*
+ * 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, or (at
+ * your option) any later version.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include "etherboot.h"
+#include <errno.h>
+#include "nic.h"
+#include <gpxe/isa.h>
+#include <gpxe/ethernet.h>
+
+/* Different 82595 chips */
+#define LAN595 0
+#define LAN595TX 1
+#define LAN595FX 2
+#define LAN595FX_10ISA 3
+
+#define SLOW_DOWN inb(0x80);
+
+/* The station (ethernet) address prefix, used for IDing the board. */
+#define SA_ADDR0 0x00 /* Etherexpress Pro/10 */
+#define SA_ADDR1 0xaa
+#define SA_ADDR2 0x00
+
+#define GetBit(x,y) ((x & (1<<y))>>y)
+
+/* EEPROM Word 0: */
+#define ee_PnP 0 /* Plug 'n Play enable bit */
+#define ee_Word1 1 /* Word 1? */
+#define ee_BusWidth 2 /* 8/16 bit */
+#define ee_FlashAddr 3 /* Flash Address */
+#define ee_FlashMask 0x7 /* Mask */
+#define ee_AutoIO 6 /* */
+#define ee_reserved0 7 /* =0! */
+#define ee_Flash 8 /* Flash there? */
+#define ee_AutoNeg 9 /* Auto Negotiation enabled? */
+#define ee_IO0 10 /* IO Address LSB */
+#define ee_IO0Mask 0x /*...*/
+#define ee_IO1 15 /* IO MSB */
+
+/* EEPROM Word 1: */
+#define ee_IntSel 0 /* Interrupt */
+#define ee_IntMask 0x7
+#define ee_LI 3 /* Link Integrity 0= enabled */
+#define ee_PC 4 /* Polarity Correction 0= enabled */
+#define ee_TPE_AUI 5 /* PortSelection 1=TPE */
+#define ee_Jabber 6 /* Jabber prevention 0= enabled */
+#define ee_AutoPort 7 /* Auto Port Selection 1= Disabled */
+#define ee_SMOUT 8 /* SMout Pin Control 0= Input */
+#define ee_PROM 9 /* Flash EPROM / PROM 0=Flash */
+#define ee_reserved1 10 /* .. 12 =0! */
+#define ee_AltReady 13 /* Alternate Ready, 0=normal */
+#define ee_reserved2 14 /* =0! */
+#define ee_Duplex 15
+
+/* Word2,3,4: */
+#define ee_IA5 0 /*bit start for individual Addr Byte 5 */
+#define ee_IA4 8 /*bit start for individual Addr Byte 5 */
+#define ee_IA3 0 /*bit start for individual Addr Byte 5 */
+#define ee_IA2 8 /*bit start for individual Addr Byte 5 */
+#define ee_IA1 0 /*bit start for individual Addr Byte 5 */
+#define ee_IA0 8 /*bit start for individual Addr Byte 5 */
+
+/* Word 5: */
+#define ee_BNC_TPE 0 /* 0=TPE */
+#define ee_BootType 1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */
+#define ee_BootTypeMask 0x3
+#define ee_NumConn 3 /* Number of Connections 0= One or Two */
+#define ee_FlashSock 4 /* Presence of Flash Socket 0= Present */
+#define ee_PortTPE 5
+#define ee_PortBNC 6
+#define ee_PortAUI 7
+#define ee_PowerMgt 10 /* 0= disabled */
+#define ee_CP 13 /* Concurrent Processing */
+#define ee_CPMask 0x7
+
+/* Word 6: */
+#define ee_Stepping 0 /* Stepping info */
+#define ee_StepMask 0x0F
+#define ee_BoardID 4 /* Manucaturer Board ID, reserved */
+#define ee_BoardMask 0x0FFF
+
+/* Word 7: */
+#define ee_INT_TO_IRQ 0 /* int to IRQ Mapping = 0x1EB8 for Pro/10+ */
+#define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */
+
+/*..*/
+#define ee_SIZE 0x40 /* total EEprom Size */
+#define ee_Checksum 0xBABA /* initial and final value for adding checksum */
+
+
+/* Card identification via EEprom: */
+#define ee_addr_vendor 0x10 /* Word offset for EISA Vendor ID */
+#define ee_addr_id 0x11 /* Word offset for Card ID */
+#define ee_addr_SN 0x12 /* Serial Number */
+#define ee_addr_CRC_8 0x14 /* CRC over last thee Bytes */
+
+
+#define ee_vendor_intel0 0x25 /* Vendor ID Intel */
+#define ee_vendor_intel1 0xD4
+#define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */
+#define ee_id_eepro10p1 0x31
+
+/* now this section could be used by both boards: the oldies and the ee10:
+ * ee10 uses tx buffer before of rx buffer and the oldies the inverse.
+ * (aris)
+ */
+#define RAM_SIZE 0x8000
+
+#define RCV_HEADER 8
+#define RCV_DEFAULT_RAM 0x6000
+#define RCV_RAM rcv_ram
+
+static unsigned rcv_ram = RCV_DEFAULT_RAM;
+
+#define XMT_HEADER 8
+#define XMT_RAM (RAM_SIZE - RCV_RAM)
+
+#define XMT_START ((rcv_start + RCV_RAM) % RAM_SIZE)
+
+#define RCV_LOWER_LIMIT (rcv_start >> 8)
+#define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8)
+#define XMT_LOWER_LIMIT (XMT_START >> 8)
+#define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8)
+
+#define RCV_START_PRO 0x00
+#define RCV_START_10 XMT_RAM
+ /* by default the old driver */
+static unsigned rcv_start = RCV_START_PRO;
+
+#define RCV_DONE 0x0008
+#define RX_OK 0x2000
+#define RX_ERROR 0x0d81
+
+#define TX_DONE_BIT 0x0080
+#define CHAIN_BIT 0x8000
+#define XMT_STATUS 0x02
+#define XMT_CHAIN 0x04
+#define XMT_COUNT 0x06
+
+#define BANK0_SELECT 0x00
+#define BANK1_SELECT 0x40
+#define BANK2_SELECT 0x80
+
+/* Bank 0 registers */
+#define COMMAND_REG 0x00 /* Register 0 */
+#define MC_SETUP 0x03
+#define XMT_CMD 0x04
+#define DIAGNOSE_CMD 0x07
+#define RCV_ENABLE_CMD 0x08
+#define RCV_DISABLE_CMD 0x0a
+#define STOP_RCV_CMD 0x0b
+#define RESET_CMD 0x0e
+#define POWER_DOWN_CMD 0x18
+#define RESUME_XMT_CMD 0x1c
+#define SEL_RESET_CMD 0x1e
+#define STATUS_REG 0x01 /* Register 1 */
+#define RX_INT 0x02
+#define TX_INT 0x04
+#define EXEC_STATUS 0x30
+#define ID_REG 0x02 /* Register 2 */
+#define R_ROBIN_BITS 0xc0 /* round robin counter */
+#define ID_REG_MASK 0x2c
+#define ID_REG_SIG 0x24
+#define AUTO_ENABLE 0x10
+#define INT_MASK_REG 0x03 /* Register 3 */
+#define RX_STOP_MASK 0x01
+#define RX_MASK 0x02
+#define TX_MASK 0x04
+#define EXEC_MASK 0x08
+#define ALL_MASK 0x0f
+#define IO_32_BIT 0x10
+#define RCV_BAR 0x04 /* The following are word (16-bit) registers */
+#define RCV_STOP 0x06
+
+#define XMT_BAR_PRO 0x0a
+#define XMT_BAR_10 0x0b
+static unsigned xmt_bar = XMT_BAR_PRO;
+
+#define HOST_ADDRESS_REG 0x0c
+#define IO_PORT 0x0e
+#define IO_PORT_32_BIT 0x0c
+
+/* Bank 1 registers */
+#define REG1 0x01
+#define WORD_WIDTH 0x02
+#define INT_ENABLE 0x80
+#define INT_NO_REG 0x02
+#define RCV_LOWER_LIMIT_REG 0x08
+#define RCV_UPPER_LIMIT_REG 0x09
+
+#define XMT_LOWER_LIMIT_REG_PRO 0x0a
+#define XMT_UPPER_LIMIT_REG_PRO 0x0b
+#define XMT_LOWER_LIMIT_REG_10 0x0b
+#define XMT_UPPER_LIMIT_REG_10 0x0a
+static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
+static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
+
+/* Bank 2 registers */
+#define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */
+#define XMT_Chain_ErrStop 0x40 /* Interrupt at the end of the chain even if there are errors */
+#define RCV_Discard_BadFrame 0x80 /* Throw bad frames away, and continue to receive others */
+#define REG2 0x02
+#define PRMSC_Mode 0x01
+#define Multi_IA 0x20
+#define REG3 0x03
+#define TPE_BIT 0x04
+#define BNC_BIT 0x20
+#define REG13 0x0d
+#define FDX 0x00
+#define A_N_ENABLE 0x02
+
+#define I_ADD_REG0 0x04
+#define I_ADD_REG1 0x05
+#define I_ADD_REG2 0x06
+#define I_ADD_REG3 0x07
+#define I_ADD_REG4 0x08
+#define I_ADD_REG5 0x09
+
+#define EEPROM_REG_PRO 0x0a
+#define EEPROM_REG_10 0x0b
+static unsigned eeprom_reg = EEPROM_REG_PRO;
+
+#define EESK 0x01
+#define EECS 0x02
+#define EEDI 0x04
+#define EEDO 0x08
+
+/* The horrible routine to read a word from the serial EEPROM. */
+/* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
+
+/* The delay between EEPROM clock transitions. */
+#define eeprom_delay() { udelay(40); }
+#define EE_READ_CMD (6 << 6)
+
+/* do a full reset; data sheet asks for 250us delay */
+#define eepro_full_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(255);
+
+/* do a nice reset */
+#define eepro_sel_reset(ioaddr) \
+ do { \
+ outb ( SEL_RESET_CMD, ioaddr ); \
+ (void) SLOW_DOWN; \
+ (void) SLOW_DOWN; \
+ } while (0)
+
+/* clear all interrupts */
+#define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG)
+
+/* enable rx */
+#define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr)
+
+/* disable rx */
+#define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr)
+
+/* switch bank */
+#define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)
+#define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)
+#define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)
+
+static unsigned int rx_start, tx_start;
+static int tx_last;
+static unsigned int tx_end;
+static int eepro = 0;
+static unsigned int mem_start, mem_end = RCV_DEFAULT_RAM / 1024;
+
+/**************************************************************************
+RESET - Reset adapter
+***************************************************************************/
+static void eepro_reset(struct nic *nic)
+{
+ int temp_reg, i;
+
+ /* put the card in its initial state */
+ eepro_sw2bank2(nic->ioaddr); /* be careful, bank2 now */
+ temp_reg = inb(nic->ioaddr + eeprom_reg);
+ DBG("Stepping %d\n", temp_reg >> 5);
+ if (temp_reg & 0x10) /* check the TurnOff Enable bit */
+ outb(temp_reg & 0xEF, nic->ioaddr + eeprom_reg);
+ for (i = 0; i < ETH_ALEN; i++) /* fill the MAC address */
+ outb(nic->node_addr[i], nic->ioaddr + I_ADD_REG0 + i);
+ temp_reg = inb(nic->ioaddr + REG1);
+ /* setup Transmit Chaining and discard bad RCV frames */
+ outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop
+ | RCV_Discard_BadFrame, nic->ioaddr + REG1);
+ temp_reg = inb(nic->ioaddr + REG2); /* match broadcast */
+ outb(temp_reg | 0x14, nic->ioaddr + REG2);
+ temp_reg = inb(nic->ioaddr + REG3);
+ outb(temp_reg & 0x3F, nic->ioaddr + REG3); /* clear test mode */
+ /* set the receiving mode */
+ eepro_sw2bank1(nic->ioaddr); /* be careful, bank1 now */
+ /* initialise the RCV and XMT upper and lower limits */
+ outb(RCV_LOWER_LIMIT, nic->ioaddr + RCV_LOWER_LIMIT_REG);
+ outb(RCV_UPPER_LIMIT, nic->ioaddr + RCV_UPPER_LIMIT_REG);
+ outb(XMT_LOWER_LIMIT, nic->ioaddr + xmt_lower_limit_reg);
+ outb(XMT_UPPER_LIMIT, nic->ioaddr + xmt_upper_limit_reg);
+ eepro_sw2bank0(nic->ioaddr); /* Switch back to bank 0 */
+ eepro_clear_int(nic->ioaddr);
+ /* Initialise RCV */
+ outw(rx_start = (RCV_LOWER_LIMIT << 8), nic->ioaddr + RCV_BAR);
+ outw(((RCV_UPPER_LIMIT << 8) | 0xFE), nic->ioaddr + RCV_STOP);
+ /* Make sure 1st poll won't find a valid packet header */
+ outw((RCV_LOWER_LIMIT << 8), nic->ioaddr + HOST_ADDRESS_REG);
+ outw(0, nic->ioaddr + IO_PORT);
+ /* Intialise XMT */
+ outw((XMT_LOWER_LIMIT << 8), nic->ioaddr + xmt_bar);
+ eepro_sel_reset(nic->ioaddr);
+ tx_start = tx_end = (unsigned int) (XMT_LOWER_LIMIT << 8);
+ tx_last = 0;
+ eepro_en_rx(nic->ioaddr);
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int eepro_poll(struct nic *nic, int retrieve)
+{
+ unsigned int rcv_car = rx_start;
+ unsigned int rcv_event, rcv_status, rcv_next_frame, rcv_size;
+
+ /* return true if there's an ethernet packet ready to read */
+ /* nic->packet should contain data on return */
+ /* nic->packetlen should contain length of data */
+#if 0
+ if ((inb(nic->ioaddr + STATUS_REG) & 0x40) == 0)
+ return (0);
+ outb(0x40, nic->ioaddr + STATUS_REG);
+#endif
+ outw(rcv_car, nic->ioaddr + HOST_ADDRESS_REG);
+ rcv_event = inw(nic->ioaddr + IO_PORT);
+ if (rcv_event != RCV_DONE)
+ return (0);
+
+ /* FIXME: I'm guessing this might not work with this card, since
+ it looks like once a rcv_event is started it must be completed.
+ maybe there's another way. */
+ if ( ! retrieve ) return 1;
+
+ rcv_status = inw(nic->ioaddr + IO_PORT);
+ rcv_next_frame = inw(nic->ioaddr + IO_PORT);
+ rcv_size = inw(nic->ioaddr + IO_PORT);
+#if 0
+ printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size,
+ inb(nic->ioaddr + STATUS_REG));
+#endif
+ if ((rcv_status & (RX_OK|RX_ERROR)) != RX_OK) {
+ printf("Receive error %hX\n", rcv_status);
+ return (0);
+ }
+ rcv_size &= 0x3FFF;
+ insw(nic->ioaddr + IO_PORT, nic->packet, ((rcv_size + 3) >> 1));
+#if 0
+{
+ int i;
+ for (i = 0; i < 48; i++) {
+ printf("%hhX", nic->packet[i]);
+ putchar(i % 16 == 15 ? '\n' : ' ');
+ }
+}
+#endif
+ nic->packetlen = rcv_size;
+ rcv_car = (rx_start + RCV_HEADER + rcv_size);
+ rx_start = rcv_next_frame;
+/*
+ hex_dump(rcv_car, nic->packetlen);
+*/
+
+ if (rcv_car == 0)
+ rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff);
+ outw(rcv_car - 1, nic->ioaddr + RCV_STOP);
+ return (1);
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static void eepro_transmit(
+ struct nic *nic,
+ const char *d, /* Destination */
+ unsigned int t, /* Type */
+ unsigned int s, /* size */
+ const char *p) /* Packet */
+{
+ unsigned int status, tx_available, last, end, length;
+ unsigned short type;
+ int boguscount = 20;
+
+ length = s + ETH_HLEN;
+ if (tx_end > tx_start)
+ tx_available = XMT_RAM - (tx_end - tx_start);
+ else if (tx_end < tx_start)
+ tx_available = tx_start - tx_end;
+ else
+ tx_available = XMT_RAM;
+ last = tx_end;
+ end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
+ if (end >= (XMT_UPPER_LIMIT << 8)) {
+ last = (XMT_LOWER_LIMIT << 8);
+ end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
+ }
+ outw(last, nic->ioaddr + HOST_ADDRESS_REG);
+ outw(XMT_CMD, nic->ioaddr + IO_PORT);
+ outw(0, nic->ioaddr + IO_PORT);
+ outw(end, nic->ioaddr + IO_PORT);
+ outw(length, nic->ioaddr + IO_PORT);
+ outsw(nic->ioaddr + IO_PORT, d, ETH_ALEN / 2);
+ outsw(nic->ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2);
+ type = htons(t);
+ outsw(nic->ioaddr + IO_PORT, &type, sizeof(type) / 2);
+ outsw(nic->ioaddr + IO_PORT, p, (s + 3) >> 1);
+ /* A dummy read to flush the DRAM write pipeline */
+ status = inw(nic->ioaddr + IO_PORT);
+ outw(last, nic->ioaddr + xmt_bar);
+ outb(XMT_CMD, nic->ioaddr);
+ tx_start = last;
+ tx_last = last;
+ tx_end = end;
+#if 0
+ printf("%d %d\n", tx_start, tx_end);
+#endif
+ while (boguscount > 0) {
+ if (((status = inw(nic->ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) {
+ udelay(40);
+ boguscount--;
+ continue;
+ }
+ if ((status & 0x2000) == 0) {
+ DBG("Transmit status %hX\n", status);
+ }
+ }
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void eepro_disable ( struct nic *nic, struct isa_device *isa __unused ) {
+ eepro_sw2bank0(nic->ioaddr); /* Switch to bank 0 */
+ /* Flush the Tx and disable Rx */
+ outb(STOP_RCV_CMD, nic->ioaddr);
+ tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
+ tx_last = 0;
+ /* Reset the 82595 */
+ eepro_full_reset(nic->ioaddr);
+}
+
+/**************************************************************************
+DISABLE - Enable, Disable, or Force interrupts
+***************************************************************************/
+static void eepro_irq(struct nic *nic __unused, irq_action_t action __unused)
+{
+ switch ( action ) {
+ case DISABLE :
+ break;
+ case ENABLE :
+ break;
+ case FORCE :
+ break;
+ }
+}
+
+static int read_eeprom(uint16_t ioaddr, int location)
+{
+ int i;
+ unsigned short retval = 0;
+ int ee_addr = ioaddr + eeprom_reg;
+ int read_cmd = location | EE_READ_CMD;
+ int ctrl_val = EECS;
+
+ if (eepro == LAN595FX_10ISA) {
+ eepro_sw2bank1(ioaddr);
+ outb(0x00, ioaddr + STATUS_REG);
+ }
+ eepro_sw2bank2(ioaddr);
+ outb(ctrl_val, ee_addr);
+ /* shift the read command bits out */
+ for (i = 8; i >= 0; i--) {
+ short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
+ outb(outval, ee_addr);
+ outb(outval | EESK, ee_addr); /* EEPROM clock tick */
+ eeprom_delay();
+ outb(outval, ee_addr); /* finish EEPROM clock tick */
+ eeprom_delay();
+ }
+ outb(ctrl_val, ee_addr);
+ for (i = 16; i > 0; i--) {
+ outb(ctrl_val | EESK, ee_addr);
+ eeprom_delay();
+ retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
+ outb(ctrl_val, ee_addr);
+ eeprom_delay();
+ }
+ /* terminate the EEPROM access */
+ ctrl_val &= ~EECS;
+ outb(ctrl_val | EESK, ee_addr);
+ eeprom_delay();
+ outb(ctrl_val, ee_addr);
+ eeprom_delay();
+ eepro_sw2bank0(ioaddr);
+ return (retval);
+}
+
+static int eepro_probe1 ( isa_probe_addr_t ioaddr ) {
+ int id, counter;
+
+ id = inb(ioaddr + ID_REG);
+ if ((id & ID_REG_MASK) != ID_REG_SIG)
+ return (0);
+ counter = id & R_ROBIN_BITS;
+ if (((id = inb(ioaddr + ID_REG)) & R_ROBIN_BITS) != (counter + 0x40))
+ return (0);
+ /* yes the 82595 has been found */
+ return (1);
+}
+
+static struct nic_operations eepro_operations = {
+ .connect = dummy_connect,
+ .poll = eepro_poll,
+ .transmit = eepro_transmit,
+ .irq = eepro_irq,
+
+};
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+static int eepro_probe ( struct nic *nic, struct isa_device *isa ) {
+
+ int i, l_eepro = 0;
+ union {
+ unsigned char caddr[ETH_ALEN];
+ unsigned short saddr[ETH_ALEN/2];
+ } station_addr;
+ const char *name;
+
+ nic->irqno = 0;
+ nic->ioaddr = isa->ioaddr;
+
+ station_addr.saddr[2] = read_eeprom(nic->ioaddr,2);
+ if ( ( station_addr.saddr[2] == 0x0000 ) ||
+ ( station_addr.saddr[2] == 0xFFFF ) ) {
+ l_eepro = 3;
+ eepro = LAN595FX_10ISA;
+ eeprom_reg= EEPROM_REG_10;
+ rcv_start = RCV_START_10;
+ xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
+ xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
+ station_addr.saddr[2] = read_eeprom(nic->ioaddr,2);
+ }
+ station_addr.saddr[1] = read_eeprom(nic->ioaddr,3);
+ station_addr.saddr[0] = read_eeprom(nic->ioaddr,4);
+ if (l_eepro)
+ name = "Intel EtherExpress 10 ISA";
+ else if (read_eeprom(nic->ioaddr,7) == ee_FX_INT2IRQ) {
+ name = "Intel EtherExpress Pro/10+ ISA";
+ l_eepro = 2;
+ } else if (station_addr.saddr[0] == SA_ADDR1) {
+ name = "Intel EtherExpress Pro/10 ISA";
+ l_eepro = 1;
+ } else {
+ l_eepro = 0;
+ name = "Intel 82595-based LAN card";
+ }
+ station_addr.saddr[0] = swap16(station_addr.saddr[0]);
+ station_addr.saddr[1] = swap16(station_addr.saddr[1]);
+ station_addr.saddr[2] = swap16(station_addr.saddr[2]);
+ for (i = 0; i < ETH_ALEN; i++) {
+ nic->node_addr[i] = station_addr.caddr[i];
+ }
+
+ DBG ( "%s ioaddr %#hX, addr %s", name, nic->ioaddr, eth_ntoa ( nic->node_addr ) );
+
+ mem_start = RCV_LOWER_LIMIT << 8;
+ if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29)
+ mem_end = RCV_UPPER_LIMIT << 8;
+ else {
+ mem_end = mem_end * 1024 + (RCV_LOWER_LIMIT << 8);
+ rcv_ram = mem_end - (RCV_LOWER_LIMIT << 8);
+ }
+ printf(", Rx mem %dK, if %s\n", (mem_end - mem_start) >> 10,
+ GetBit(read_eeprom(nic->ioaddr,5), ee_BNC_TPE) ? "BNC" : "TP");
+
+ eepro_reset(nic);
+
+ /* point to NIC specific routines */
+ nic->nic_op = &eepro_operations;
+ return 1;
+}
+
+static isa_probe_addr_t eepro_probe_addrs[] = {
+ 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360,
+};
+
+ISA_DRIVER ( eepro_driver, eepro_probe_addrs, eepro_probe1,
+ GENERIC_ISAPNP_VENDOR, 0x828a );
+
+DRIVER ( "eepro", nic_driver, isa_driver, eepro_driver,
+ eepro_probe, eepro_disable );
+
+ISA_ROM ( "eepro", "Intel Etherexpress Pro/10" );
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * c-indent-level: 8
+ * tab-width: 8
+ * End:
+ */