123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- #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.
- ***************************************************************************/
-
- /*
- * 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.
- */
-
- /* to get some global routines like printf */
- #include "etherboot.h"
- /* to get the interface to the body of the program */
- #include "nic.h"
- #include "isa.h"
- /* we use timer2 for microsecond waits */
- #include "timer.h"
-
- #undef DEBUG /* only after include files */
-
- /* 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 */
- #define eepro_full_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(40);
-
- /* do a nice reset */
- #define eepro_sel_reset(ioaddr) { \
- outb(SEL_RESET_CMD, ioaddr); \
- SLOW_DOWN; \
- SLOW_DOWN; \
- }
-
- /* 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 short ioaddr = 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(ioaddr); /* be careful, bank2 now */
- temp_reg = inb(ioaddr + eeprom_reg);
- #ifdef DEBUG
- printf("Stepping %d\n", temp_reg >> 5);
- #endif
- if (temp_reg & 0x10) /* check the TurnOff Enable bit */
- outb(temp_reg & 0xEF, ioaddr + eeprom_reg);
- for (i = 0; i < ETH_ALEN; i++) /* fill the MAC address */
- outb(nic->node_addr[i], ioaddr + I_ADD_REG0 + i);
- temp_reg = inb(ioaddr + REG1);
- /* setup Transmit Chaining and discard bad RCV frames */
- outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop
- | RCV_Discard_BadFrame, ioaddr + REG1);
- temp_reg = inb(ioaddr + REG2); /* match broadcast */
- outb(temp_reg | 0x14, ioaddr + REG2);
- temp_reg = inb(ioaddr + REG3);
- outb(temp_reg & 0x3F, ioaddr + REG3); /* clear test mode */
- /* set the receiving mode */
- eepro_sw2bank1(ioaddr); /* be careful, bank1 now */
- /* initialise the RCV and XMT upper and lower limits */
- outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG);
- outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG);
- outb(XMT_LOWER_LIMIT, ioaddr + xmt_lower_limit_reg);
- outb(XMT_UPPER_LIMIT, ioaddr + xmt_upper_limit_reg);
- eepro_sw2bank0(ioaddr); /* Switch back to bank 0 */
- eepro_clear_int(ioaddr);
- /* Initialise RCV */
- rx_start = (unsigned int)bus_to_virt(RCV_LOWER_LIMIT << 8);
- outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR);
- outw(((RCV_UPPER_LIMIT << 8) | 0xFE), ioaddr + RCV_STOP);
- /* Intialise XMT */
- outw((XMT_LOWER_LIMIT << 8), ioaddr + xmt_bar);
- eepro_sel_reset(ioaddr);
- tx_start = tx_end = (unsigned int)bus_to_virt(XMT_LOWER_LIMIT << 8);
- tx_last = 0;
- eepro_en_rx(ioaddr);
- }
-
- /**************************************************************************
- POLL - Wait for a frame
- ***************************************************************************/
- static int eepro_poll(struct nic *nic, int retrieve)
- {
- unsigned int rcv_car = virt_to_bus((void *)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(ioaddr + STATUS_REG) & 0x40) == 0)
- return (0);
- outb(0x40, ioaddr + STATUS_REG);
- #endif
- outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
- rcv_event = inw(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(ioaddr + IO_PORT);
- rcv_next_frame = inw(ioaddr + IO_PORT);
- rcv_size = inw(ioaddr + IO_PORT);
- #if 0
- printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size,
- inb(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(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 = virt_to_bus((void *) (rx_start + RCV_HEADER + rcv_size));
- rx_start = (unsigned int)bus_to_virt(rcv_next_frame << 8);
- if (rcv_car == 0)
- rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff);
- outw(rcv_car - 1, 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, ioaddr + HOST_ADDRESS_REG);
- outw(XMT_CMD, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(end, ioaddr + IO_PORT);
- outw(length, ioaddr + IO_PORT);
- outsw(ioaddr + IO_PORT, d, ETH_ALEN / 2);
- outsw(ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2);
- type = htons(t);
- outsw(ioaddr + IO_PORT, &type, sizeof(type) / 2);
- outsw(ioaddr + IO_PORT, p, (s + 3) >> 1);
- /* A dummy read to flush the DRAM write pipeline */
- status = inw(ioaddr + IO_PORT);
- outw(last, ioaddr + xmt_bar);
- outb(XMT_CMD, 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(ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) {
- udelay(40);
- boguscount--;
- continue;
- }
- #if DEBUG
- if ((status & 0x2000) == 0)
- printf("Transmit status %hX\n", status);
- #endif
- }
- }
-
- /**************************************************************************
- DISABLE - Turn off ethernet interface
- ***************************************************************************/
- static void eepro_disable ( struct nic *nic __unused ) {
- eepro_sw2bank0(ioaddr); /* Switch to bank 0 */
- /* Flush the Tx and disable Rx */
- outb(STOP_RCV_CMD, ioaddr);
- tx_start = tx_end = (unsigned int) (bus_to_virt(XMT_LOWER_LIMIT << 8));
- tx_last = 0;
- /* Reset the 82595 */
- eepro_full_reset(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(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(struct nic *nic)
- {
- int i, id, counter, l_eepro = 0;
- union {
- unsigned char caddr[ETH_ALEN];
- unsigned short saddr[ETH_ALEN/2];
- } station_addr;
- char *name;
-
- 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 */
- station_addr.saddr[2] = read_eeprom(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(2);
- }
- station_addr.saddr[1] = read_eeprom(3);
- station_addr.saddr[0] = read_eeprom(4);
- if (l_eepro)
- name = "Intel EtherExpress 10 ISA";
- else if (read_eeprom(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];
- }
- printf("\n%s ioaddr %#hX, addr %!", name, ioaddr, 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(5), ee_BNC_TPE) ? "BNC" : "TP");
- return (1);
- }
-
- /**************************************************************************
- PROBE - Look for an adapter, this routine's visible to the outside
- ***************************************************************************/
- static int eepro_probe(struct dev *dev, unsigned short *probe_addrs)
- {
- struct nic *nic = (struct nic *)dev;
- unsigned short *p;
- /* same probe list as the Linux driver */
- static unsigned short ioaddrs[] = {
- 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
-
- if (probe_addrs == 0 || probe_addrs[0] == 0)
- probe_addrs = ioaddrs;
- for (p = probe_addrs; (ioaddr = *p) != 0; p++) {
- if (eepro_probe1(nic))
- break;
- }
- if (*p == 0)
- return (0);
-
- nic->irqno = 0;
- nic->ioaddr = *p;
-
- eepro_reset(nic);
- /* point to NIC specific routines */
- static struct nic_operations eepro_operations;
- static struct nic_operations eepro_operations = {
- .connect = dummy_connect,
- .poll = eepro_poll,
- .transmit = eepro_transmit,
- .irq = eepro_irq,
- .disable = eepro_disable,
- }; nic->nic_op = &eepro_operations;
- /* Based on PnP ISA map */
- dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
- dev->devid.device_id = htons(0x828a);
- return 1;
- }
-
- static struct isa_driver eepro_driver __isa_driver = {
- .type = NIC_DRIVER,
- .name = "EEPRO",
- .probe = eepro_probe,
- .ioaddrs = 0,
- };
- ISA_ROM("eepro","Intel Etherexpress Pro/10");
|