1N/A * eepro100.c -- This file implements the eepro100 driver for etherboot. 1N/A * Copyright (C) AW Computer Systems. 1N/A * written by R.E.Wolff -- R.E.Wolff@BitWizard.nl 1N/A * AW Computer Systems is contributing to the free software community 1N/A * by paying for this driver and then putting the result under GPL. 1N/A * If you need a Linux device driver, please contact BitWizard for a 1N/A * This program is free software; you can redistribute it and/or 1N/A * modify it under the terms of the GNU General Public License as 1N/A * published by the Free Software Foundation; either version 2, or (at 1N/A * your option) any later version. 1N/A * This program is distributed in the hope that it will be useful, but 1N/A * WITHOUT ANY WARRANTY; without even the implied warranty of 1N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1N/A * General Public License for more details. 1N/A * You should have received a copy of the GNU General Public License 1N/A * along with this program; if not, write to the Free Software 1N/A * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 1N/A * date version by what 1N/A * Written: May 29 1997 V0.10 REW Initial revision. 1N/A * changes: May 31 1997 V0.90 REW Works! 1N/A * Jun 1 1997 V0.91 REW Cleanup 1N/A * Jun 2 1997 V0.92 REW Add some code documentation 1N/A * Jul 25 1997 V1.00 REW Tested by AW to work in a PROM 1N/A * Cleanup for publication 1N/A * This is the etherboot intel etherexpress Pro/100B driver. 1N/A * It was written from scratch, with Donald Beckers eepro100.c kernel 1N/A * driver as a guideline. Mostly the 82557 related definitions and the 1N/A * lower level routines have been cut-and-pasted into this source. 1N/A * The driver was finished before Intel got the NDA out of the closet. 1N/A * I still don't have the docs. 1N/A/* Philosophy of this driver. 1N/A * Using the pci.c functions of the Etherboot code, the 82557 chip is detected. 1N/A * It is verified that the BIOS initialized everything properly and if 1N/A * something is missing it is done now. 1N/A * The chip is then initialized to "know" its ethernet address, and to 1N/A * start recieving packets. The Linux driver has a whole transmit and 1N/A * recieve ring of buffers. This is neat if you need high performance: 1N/A * you can write the buffers asynchronously to the chip reading the 1N/A * buffers and transmitting them over the network. Performance is NOT 1N/A * an issue here. We can boot a 400k kernel in about two 1N/A * seconds. (Theory: 0.4 seconds). Booting a system is going to take 1N/A * about half a minute anyway, so getting 10 times closer to the 1N/A * theoretical limit is going to make a difference of a few percent. 1N/A * Transmitting and recieving. 1N/A * We have only one transmit descriptor. It has two buffer descriptors: 1N/A * one for the header, and the other for the data. 1N/A * We have only one receive buffer. The chip is told to recieve packets, 1N/A * and suspend itself once it got one. The recieve (poll) routine simply 1N/A * looks at the recieve buffer to see if there is already a packet there. 1N/A * if there is, the buffer is copied, and the reciever is restarted. 1N/A * The Etherboot framework moves the code to the 48k segment from 1N/A * 0x94000 to 0xa0000. There is just a little room between the end of 1N/A * this driver and the 0xa0000 address. If you compile in too many 1N/A * features, this will overflow. 1N/A * The number under "hex" in the output of size that scrolls by while 1N/A * compiling should be less than 8000. Maybe even the stack is up there, 1N/A * so that you need even more headroom. 1N/A/* The etherboot authors seem to dislike the argument ordering in 1N/A * outb macros that Linux uses. I disklike the confusion that this 1N/A * has caused even more.... This file uses the Linux argument ordering. */ 1N/A/* Sorry not us. It's inherited code from FreeBSD. [The authors] */ 1N/A /* The rest are Rx and Tx commands. */ 1N/A/***********************************************************************/ 1N/A/* I82557 related defines */ 1N/A/***********************************************************************/ 1N/A/* Serial EEPROM section. 1N/A A "bit" grungy, but we work our way through bit-by-bit :->. */ 1N/A/* EEPROM_Ctrl bits. */ 1N/A#
define EE_CS 0x02 /* EEPROM chip select. */ 1N/A/* The EEPROM commands include the alway-set leading bit. */ 1N/A/* The SCB accepts the following controls for the Tx and Rx units: */ 1N/A#
define CU_CMD_BASE 0x0060 /* Base address to add to add CU commands. */ 1N/A#
define DRVR_INT 0x0200 /* Driver generated interrupt. */ 1N/A/* Commands that can be put in a command list entry. */ 1N/A /* And some extra flags: */ 1N/A CmdIntr =
0x2000,
/* Interrupt after completion. */ 1N/A CmdTxFlex =
0x0008,
/* Use "Flexible mode" for CmdTx command. */ 1N/A/* How to wait for the command unit to accept a command. 1N/A Typically this takes 0 ticks. */ 1N/A printf(
"Command %2.2x was not immediately accepted, %d ticks!\n",
1N/A/* Elements of the dump_statistics block. This block must be lword aligned. */ 1N/A/* A speedo3 TX buffer descriptor with two buffers... */ 1N/A /* This constitutes two "TBD" entries: hdr and data */ 1N/Astruct RxFD {
/* Receive frame descriptor. */ 1N/Astatic int congenb = 0;
/* Enable congestion control in the DP83840. */ 1N/Astatic int txfifo =
8;
/* Tx FIFO threshold in 4 byte units, 0-15 */ 1N/Astatic int rxfifo =
8;
/* Rx FIFO threshold, default 32 bytes. */ 1N/Astatic int txdmacount = 0;
/* Tx DMA burst length, 0-127, default 0. */ 1N/Astatic int rxdmacount = 0;
/* Rx DMA length, 0 means no preemption. */ 1N/A/* I don't understand a byte in this structure. It was copied from the 1N/A * Linux kernel initialization for the eepro100. -- REW */ 1N/A 0, 0, 0,
/* filled in later */ 1N/A {
22,
0x08, 0, 0, 0,
0x80,
0x32,
0x03,
1,
/* 1=Use MII 0=Use AUI */ 1N/A 0,
0x2E, 0,
0x60, 0,
1N/A 0xf2,
0x48, 0,
0x40,
0xf2,
0x80,
/* 0x40=Force full-duplex */ 1N/A/***********************************************************************/ 1N/A/* Locally used functions */ 1N/A/***********************************************************************/ 1N/A/* Support function: mdio_write 1N/A * This probably writes to the "physical media interface chip". 1N/A }
while (! (
val &
0x10000000));
1N/A/* Support function: mdio_read 1N/A * This probably reads a register in the "physical media interface chip". 1N/A }
while (! (
val &
0x10000000));
1N/A/* The fixes for the code were kindly provided by Dragan Stancevic 1N/A <visitor@valinux.com> to strictly follow Intel specifications of EEPROM 1N/A The publicly available sheet 64486302 (sec. 3.1) specifies 1us access 1N/A interval for serial EEPROM. However, it looks like that there is an 1N/A additional requirement dictating larger udelay's in the code below. 1N/A /* Shift the command bits out. */ 1N/A /* Terminate the EEPROM access. */ 1N/A/* function: eepro100_transmit 1N/A * This transmits a packet. 1N/A * Arguments: char d[6]: destination ethernet address. 1N/A * unsigned short t: ethernet protocol type. 1N/A * unsigned short s: size of the data-part of the packet. 1N/A * char *p: the data for the packet. 1N/A /* Acknowledge all of the current interrupt sources ASAP. */ 1N/A printf (
"transmitting type %hX packet (%d bytes). status = %hX, cmd=%hX\n",
1N/A * Sometimes the receiver stops making progress. This routine knows how to 1N/A * get it going again, without losing packets or being otherwise nasty like 1N/A * a chip reset would be. Previously the driver had a whole sequence 1N/A * of if RxSuspended, if it's no buffers do one thing, if it's no resources, 1N/A * do another, etc. But those things don't really matter. Separate logic 1N/A * in the ISR provides for allocating buffers--the other half of operation 1N/A * is just making sure the receiver is active. speedo_rx_soft_reset does that. 1N/A * This problem with the old, more involved algorithm is shown up under 1N/A * Put the hardware into a known state. 1N/A/* function: eepro100_poll / eth_poll 1N/A * This recieves a packet from the network. 1N/A * returns: 1 if a packet was recieved. 1N/A * 0 if no pacet was recieved. 1N/A * returns the packet in the array nic->packet. 1N/A * returns the length of the packet in nic->packetlen. 1N/A /* There is a packet ready */ 1N/A * The chip may have suspended reception for various reasons. 1N/A * Check for that, and re-prime it should this be the case. 1N/A case 1:
/* Suspended */ 1N/A case 2:
/* No resources (RxFDs) */ 1N/A case 9:
/* Suspended with no more RBDs */ 1N/A case 10:
/* No resources due to no RBDs */ 1N/A case 12:
/* Ready with no RBDs */ 1N/A case 3:
case 5:
case 6:
case 7:
case 8:
1N/A case 11:
case 13:
case 14:
case 15:
1N/A /* these are all reserved values */ 1N/A /* Ok. We got a packet. Now restart the reciever.... */ 1N/A/* function: eepro100_disable 1N/A * resets the card. This is used to allow Etherboot or Linux 1N/A * to probe the card again from a "virginal" state.... 1N/A/* from eepro100_reset */ 1N/A/* from eepro100_disable */ 1N/A /* See if this PartialReset solves the problem with interfering with 1N/A kernel operation after Etherboot hands over. - Ken 20001102 */ 1N/A /* The following is from the Intel e100 driver. 1N/A * This hopefully solves the problem with hanging hard DOS images. */ 1N/A /* wait for the reset to take effect */ 1N/A /* Mask off our interrupt line -- it is unmasked after reset */ 1N/A /* Disable interrupts on our PCI board by setting the mask bit */ 1N/A /* ack and clear intrs */ 1N/A/* exported function: eepro100_probe / eth_probe 1N/A * initializes a card 1N/A * leaves the ioaddress of the 82557 chip in the variable ioaddr. 1N/A * leaves the 82557 initialized, and ready to recieve packets. 1N/A /* we cache only the first few words of the EEPROM data 1N/A be careful not to access beyond this array */ 1N/A /* Copy IRQ from PCI information */ 1N/A /* nic->irqno = pci->irq; */ 1N/A printf(
"eepro100: Invalid EEPROM checksum %#hX, " 1N/A "check settings before activating this device!\n",
sum);
1N/A /* INIT RX stuff. */ 1N/A /* Start the reciever.... */ 1N/A /* INIT TX stuff. */ 1N/A /* options = 0x40; */ /* 10mbps half duplex... */ 1N/A printf(
" DP83840 specific setup, setting register 23 to %hX.\n",
1N/A ((
options &
0x10) ?
0x0100 : 0));
/* Full duplex? */ 1N/A /* Read the status register once to disgard stale data */ 1N/A /* Check to see if the network cable is plugged in. 1N/A * This allows for faster failure if there is nothing 1N/A/*********************************************************************/ 1N/A/* Hexdump a number of bytes from memory... */ 1N/A for (i=0;i < ( (n>
16)?
16:n);i++)
1N/APCI_ROM(
0x8086,
0x1029,
"id1029",
"Intel EtherExpressPro100 ID1029"),
1N/APCI_ROM(
0x8086,
0x1030,
"id1030",
"Intel EtherExpressPro100 ID1030"),
1N/APCI_ROM(
0x8086,
0x1031,
"82801cam",
"Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
1N/APCI_ROM(
0x8086,
0x1032,
"eepro100-1032",
"Intel PRO/100 VE Network Connection"),
1N/APCI_ROM(
0x8086,
0x1033,
"eepro100-1033",
"Intel PRO/100 VM Network Connection"),
1N/APCI_ROM(
0x8086,
0x1034,
"eepro100-1034",
"Intel PRO/100 VM Network Connection"),
1N/APCI_ROM(
0x8086,
0x1035,
"eepro100-1035",
"Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
1N/APCI_ROM(
0x8086,
0x1036,
"eepro100-1036",
"Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
1N/APCI_ROM(
0x8086,
0x1037,
"eepro100-1037",
"Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
1N/APCI_ROM(
0x8086,
0x1038,
"id1038",
"Intel PRO/100 VM Network Connection"),
1N/APCI_ROM(
0x8086,
0x1039,
"82562et",
"Intel PRO100 VE 82562ET"),
1N/APCI_ROM(
0x8086,
0x103a,
"id103a",
"Intel Corporation 82559 InBusiness 10/100"),
1N/APCI_ROM(
0x8086,
0x103b,
"82562etb",
"Intel PRO100 VE 82562ETB"),
1N/APCI_ROM(
0x8086,
0x103c,
"eepro100-103c",
"Intel PRO/100 VM Network Connection"),
1N/APCI_ROM(
0x8086,
0x103d,
"eepro100-103d",
"Intel PRO/100 VE Network Connection"),
1N/APCI_ROM(
0x8086,
0x103e,
"eepro100-103e",
"Intel PRO/100 VM Network Connection"),
1N/APCI_ROM(
0x8086,
0x1059,
"82551qm",
"Intel PRO/100 M Mobile Connection"),
1N/APCI_ROM(
0x8086,
0x1209,
"82559er",
"Intel EtherExpressPro100 82559ER"),
1N/APCI_ROM(
0x8086,
0x1227,
"82865",
"Intel 82865 EtherExpress PRO/100A"),
1N/APCI_ROM(
0x8086,
0x1228,
"82556",
"Intel 82556 EtherExpress PRO/100 Smart"),
1N/APCI_ROM(
0x8086,
0x1229,
"eepro100",
"Intel EtherExpressPro100"),
1N/APCI_ROM(
0x8086,
0x2449,
"82562em",
"Intel EtherExpressPro100 82562EM"),
1N/APCI_ROM(
0x8086,
0x2459,
"82562-1",
"Intel 82562 based Fast Ethernet Connection"),
1N/APCI_ROM(
0x8086,
0x245d,
"82562-2",
"Intel 82562 based Fast Ethernet Connection"),
1N/APCI_ROM(
0x8086,
0x1050,
"82562ez",
"Intel 82562EZ Network Connection"),
1N/APCI_ROM(
0x8086,
0x5200,
"eepro100-5200",
"Intel EtherExpress PRO/100 Intelligent Server"),
1N/APCI_ROM(
0x8086,
0x5201,
"eepro100-5201",
"Intel EtherExpress PRO/100 Intelligent Server"),
1N/A/* Cards with device ids 0x1030 to 0x103F, 0x2449, 0x2459 or 0x245D might need 1N/A * a workaround for hardware bug on 10 mbit half duplex (see linux driver eepro100.c) 1N/A * 2003/03/17 gbaum */