iPXE
eepro100.c
Go to the documentation of this file.
00001 /*
00002  * eepro100.c -- This is a driver for Intel Fast Ethernet Controllers
00003  * (ifec).
00004  *
00005  * Originally written for Etherboot by:
00006  *
00007  *   Copyright (C) AW Computer Systems.
00008  *   written by R.E.Wolff -- R.E.Wolff@BitWizard.nl
00009  *
00010  *   AW Computer Systems is contributing to the free software community
00011  *   by paying for this driver and then putting the result under GPL.
00012  *
00013  *   If you need a Linux device driver, please contact BitWizard for a
00014  *   quote.
00015  *
00016  * This program is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU General Public License as
00018  * published by the Free Software Foundation; either version 2, or (at
00019  * your option) any later version.
00020  *
00021  * This program is distributed in the hope that it will be useful, but
00022  * WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * General Public License for more details.
00025  *
00026  * You should have received a copy of the GNU General Public License
00027  * along with this program; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00029  * 02110-1301, USA.
00030  *
00031  *
00032  *              date       version  by      what
00033  *  Written:    May 29 1997  V0.10  REW     Initial revision.
00034  * changes:     May 31 1997  V0.90  REW     Works!
00035  *              Jun 1  1997  V0.91  REW     Cleanup
00036  *              Jun 2  1997  V0.92  REW     Add some code documentation
00037  *              Jul 25 1997  V1.00  REW     Tested by AW to work in a PROM
00038  *                                          Cleanup for publication
00039  *              Dez 11 2004  V1.10  Kiszka  Add RX ring buffer support
00040  *              Jun    2008  v2.0   mdeck   Updated to iPXE. Changed much.
00041  *
00042  * Cleanups and fixes by Thomas Miletich<thomas.miletich@gmail.com>
00043  *
00044  * This is the etherboot intel etherexpress Pro/100B driver.
00045  *
00046  * It was written from scratch, with Donald Beckers eepro100.c kernel
00047  * driver as a guideline. Mostly the 82557 related definitions and the
00048  * lower level routines have been cut-and-pasted into this source.
00049  *
00050  * The driver was finished before Intel got the NDA out of the closet.
00051  *
00052  * Datasheet is now published and available from 
00053  * ftp://download.intel.com/design/network/manuals/8255X_OpenSDM.pdf
00054  *    - Michael Brown
00055  * */
00056 
00057 FILE_LICENCE ( GPL2_OR_LATER );
00058 
00059 /*
00060  * General Theory of Operation
00061  *
00062  * Initialization
00063  *
00064  * ifec_pci_probe() is called by iPXE during initialization. Typical NIC
00065  * initialization is performed.  EEPROM data is read.
00066  *
00067  * Network Boot
00068  *
00069  * ifec_net_open() is called by iPXE before attempting to network boot from the
00070  * card.  Here, the Command Unit & Receive Unit are initialized.  The tx & rx
00071  * rings are setup.  The MAC address is programmed and the card is configured.
00072  *
00073  * Transmit
00074  *
00075  * ifec_net_transmit() enqueues a packet in the tx ring - active::tcbs[]  The tx
00076  * ring is composed of TCBs linked to each other into a ring.  A tx request
00077  * fills out the next available TCB with a pointer to the packet data.
00078  * The last enqueued tx is always at active::tcb_head.  Thus, a tx request fills
00079  * out the TCB following tcb_head.
00080  * active::tcb_tail points to the TCB we're awaiting completion of.
00081  * ifec_tx_process() checks tcb_tail, and once complete,
00082  * blindly increments tcb_tail to the next ring TCB.
00083  *
00084  * Receive
00085  *
00086  * priv::rfds[] is an array of Receive Frame Descriptors. The RFDs are linked
00087  * together to form a ring.
00088  * ifec_net_poll() calls ifec_rx_process(), which checks the next RFD for
00089  * data.  If we received a packet, we allocate a new io_buffer and copy the
00090  * packet data into it. If alloc_iob() fails, we don't touch the RFD and try
00091  * again on the next poll.
00092  */
00093 
00094 /*
00095  * Debugging levels:
00096  *      - DBG() is for any errors, i.e. failed alloc_iob(), malloc_dma(),
00097  *        TX overflow, corrupted packets, ...
00098  *      - DBG2() is for successful events, like packet received,
00099  *        packet transmitted, and other general notifications.
00100  *      - DBGP() prints the name of each called function on entry
00101  */
00102 
00103 #include <stdint.h>
00104 #include <byteswap.h>
00105 #include <errno.h>
00106 #include <stdio.h>
00107 #include <unistd.h>
00108 #include <ipxe/ethernet.h>
00109 #include <ipxe/if_ether.h>
00110 #include <ipxe/iobuf.h>
00111 #include <ipxe/malloc.h>
00112 #include <ipxe/pci.h>
00113 #include <ipxe/spi_bit.h>
00114 #include <ipxe/timer.h>
00115 #include <ipxe/nvs.h>
00116 #include <ipxe/threewire.h>
00117 #include <ipxe/netdevice.h>
00118 #include "eepro100.h"
00119 
00120 /****************************** Global data **********************************/
00121 
00122 /*
00123  * This is the default configuration command data. The values were copied from
00124  * the Linux kernel initialization for the eepro100.
00125  */
00126 static struct ifec_cfg ifec_cfg = {
00127         .status  = 0,
00128         .command = CmdConfigure | CmdSuspend,
00129         .link    = 0,        /* Filled in later */
00130         .byte = { 22,        /* How many bytes in this array */
00131                   ( TX_FIFO << 4 ) | RX_FIFO,  /* Rx & Tx FIFO limits */
00132                   0, 0,                        /* Adaptive Interframe Spacing */
00133                   RX_DMA_COUNT,                /* Rx DMA max byte count */
00134                   TX_DMA_COUNT + 0x80,         /* Tx DMA max byte count */
00135                   0x32,      /* Many bits. */
00136                   0x03,      /* Discard short receive & Underrun retries */
00137                   1,         /* 1=Use MII  0=Use AUI */
00138                   0,
00139                   0x2E,      /* NSAI, Preamble length, & Loopback*/
00140                   0,         /* Linear priority */
00141                   0x60,      /* L PRI MODE & Interframe spacing */
00142                   0, 0xf2,
00143                   0x48,      /* Promiscuous, Broadcast disable, CRS & CDT */
00144                   0, 0x40,
00145                   0xf2,      /* Stripping, Padding, Receive CRC Transfer */
00146                   0x80,      /* 0x40=Force full-duplex, 0x80=Allowfull-duplex*/
00147                   0x3f,      /* Multiple IA */
00148                   0x0D }     /* Multicast all */
00149 };
00150 
00151 static struct net_device_operations ifec_operations = {
00152         .open     = ifec_net_open,
00153         .close    = ifec_net_close,
00154         .transmit = ifec_net_transmit,
00155         .poll     = ifec_net_poll,
00156         .irq      = ifec_net_irq
00157 };
00158 
00159 /******************* iPXE PCI Device Driver API functions ********************/
00160 
00161 /*
00162  * Initialize the PCI device.
00163  *
00164  * @v pci               The device's associated pci_device structure.
00165  * @v id                The PCI device + vendor id.
00166  * @ret rc              Returns zero if successfully initialized.
00167  *
00168  * This function is called very early on, while iPXE is initializing.
00169  * This is a iPXE PCI Device Driver API function.
00170  */
00171 static int ifec_pci_probe ( struct pci_device *pci )
00172 {
00173         struct net_device *netdev;
00174         struct ifec_private *priv;
00175         int rc;
00176 
00177         DBGP ( "ifec_pci_probe: " );
00178 
00179         if ( pci->ioaddr == 0 )
00180                 return -EINVAL;
00181 
00182         netdev = alloc_etherdev ( sizeof(*priv) );
00183         if ( !netdev )
00184                 return -ENOMEM;
00185 
00186         netdev_init ( netdev, &ifec_operations );
00187         priv = netdev->priv;
00188 
00189         pci_set_drvdata ( pci, netdev );
00190         netdev->dev = &pci->dev;
00191 
00192         /* enable bus master, etc */
00193         adjust_pci_device( pci );
00194 
00195         DBGP ( "pci " );
00196 
00197         memset ( priv, 0, sizeof(*priv) );
00198         priv->ioaddr = pci->ioaddr;
00199 
00200         ifec_reset ( netdev );
00201         DBGP ( "reset " );
00202 
00203         ifec_init_eeprom ( netdev );
00204 
00205         /* read MAC address */
00206         nvs_read ( &priv->eeprom.nvs, EEPROM_ADDR_MAC_0, netdev->hw_addr,
00207                    ETH_ALEN );
00208         /* read mdio_register */
00209         nvs_read ( &priv->eeprom.nvs, EEPROM_ADDR_MDIO_REGISTER,
00210                    &priv->mdio_register, 2 );
00211 
00212         if ( ( rc = register_netdev ( netdev ) ) != 0 )
00213                 goto error;
00214 
00215         netdev_link_up ( netdev );
00216 
00217         DBGP ( "ints\n" );
00218 
00219         return 0;
00220 
00221 error:
00222         ifec_reset     ( netdev );
00223         netdev_nullify ( netdev );
00224         netdev_put     ( netdev );
00225 
00226         return rc;
00227 }
00228 
00229 /*
00230  * Remove a device from the PCI device list.
00231  *
00232  * @v pci               PCI device to remove.
00233  *
00234  * This is a PCI Device Driver API function.
00235  */
00236 static void ifec_pci_remove ( struct pci_device *pci )
00237 {
00238         struct net_device *netdev = pci_get_drvdata ( pci );
00239 
00240         DBGP ( "ifec_pci_remove\n" );
00241 
00242         unregister_netdev ( netdev );
00243         ifec_reset        ( netdev );
00244         netdev_nullify    ( netdev );
00245         netdev_put        ( netdev );
00246 }
00247 
00248 /****************** iPXE Network Device Driver API functions *****************/
00249 
00250 /*
00251  * Close a network device.
00252  *
00253  * @v netdev            Device to close.
00254  *
00255  * This is a iPXE Network Device Driver API function.
00256  */
00257 static void ifec_net_close ( struct net_device *netdev )
00258 {
00259         struct ifec_private *priv = netdev->priv;
00260         unsigned long ioaddr = priv->ioaddr;
00261         unsigned short intr_status;
00262 
00263         DBGP ( "ifec_net_close\n" );
00264 
00265         /* disable interrupts */
00266         ifec_net_irq ( netdev, 0 );
00267 
00268         /* Ack & clear ints */
00269         intr_status = inw ( ioaddr + SCBStatus );
00270         outw ( intr_status, ioaddr + SCBStatus );
00271         inw ( ioaddr + SCBStatus );
00272 
00273         ifec_reset ( netdev );
00274 
00275         /* Free any resources */
00276         ifec_free ( netdev );
00277 }
00278 
00279 /* Interrupts to be masked */
00280 #define INTERRUPT_MASK  ( SCBMaskEarlyRx | SCBMaskFlowCtl )
00281 
00282 /*
00283  * Enable or disable IRQ masking.
00284  *
00285  * @v netdev            Device to control.
00286  * @v enable            Zero to mask off IRQ, non-zero to enable IRQ.
00287  *
00288  * This is a iPXE Network Driver API function.
00289  */
00290 static void ifec_net_irq ( struct net_device *netdev, int enable )
00291 {
00292         struct ifec_private *priv = netdev->priv;
00293         unsigned long ioaddr = priv->ioaddr;
00294 
00295         DBGP ( "ifec_net_irq\n" );
00296 
00297         outw ( enable ? INTERRUPT_MASK : SCBMaskAll, ioaddr + SCBCmd );
00298 }
00299 
00300 /*
00301  * Opens a network device.
00302  *
00303  * @v netdev            Device to be opened.
00304  * @ret rc              Non-zero if failed to open.
00305  *
00306  * This enables tx and rx on the device.
00307  * This is a iPXE Network Device Driver API function.
00308  */
00309 static int ifec_net_open ( struct net_device *netdev )
00310 {
00311         struct ifec_private *priv = netdev->priv;
00312         struct ifec_ias *ias = NULL;
00313         struct ifec_cfg *cfg = NULL;
00314         int i, options;
00315         int rc = -ENOMEM;
00316 
00317         DBGP ( "ifec_net_open: " );
00318 
00319         /* Ensure interrupts are disabled. */
00320         ifec_net_irq ( netdev, 0 );
00321 
00322         /* Initialize Command Unit and Receive Unit base addresses. */
00323         ifec_scb_cmd ( netdev, 0, RUAddrLoad );
00324         ifec_scb_cmd ( netdev, virt_to_bus ( &priv->stats ), CUStatsAddr );
00325         ifec_scb_cmd ( netdev, 0, CUCmdBase );
00326 
00327         /* Initialize both rings */
00328         if ( ( rc = ifec_rx_setup ( netdev ) ) != 0 )
00329                 goto error;
00330         if ( ( rc = ifec_tx_setup ( netdev ) ) != 0 )
00331                 goto error;
00332 
00333         /* Initialize MDIO */
00334         options = 0x00; /* 0x40 = 10mbps half duplex, 0x00 = Autosense */
00335         ifec_mdio_setup ( netdev, options );
00336 
00337         /* Prepare MAC address w/ Individual Address Setup (ias) command.*/
00338         ias = malloc_dma ( sizeof ( *ias ), CB_ALIGN );
00339         if ( !ias ) {
00340                 rc = -ENOMEM;
00341                 goto error;
00342         }
00343         ias->command      = CmdIASetup;
00344         ias->status       = 0;
00345         memcpy ( ias->ia, netdev->ll_addr, ETH_ALEN );
00346 
00347         /* Prepare operating parameters w/ a configure command. */
00348         cfg = malloc_dma ( sizeof ( *cfg ), CB_ALIGN );
00349         if ( !cfg ) {
00350                 rc = -ENOMEM;
00351                 goto error;
00352         }
00353         memcpy ( cfg, &ifec_cfg, sizeof ( *cfg ) );
00354         cfg->link     = virt_to_bus ( priv->tcbs );
00355         cfg->byte[19] = ( options & 0x10 ) ? 0xC0 : 0x80;
00356         ias->link     = virt_to_bus ( cfg );
00357 
00358         /* Issue the ias and configure commands. */
00359         ifec_scb_cmd ( netdev, virt_to_bus ( ias ), CUStart );
00360         ifec_scb_cmd_wait ( netdev );
00361         priv->configured = 1;
00362 
00363         /* Wait up to 10 ms for configuration to initiate */
00364         for ( i = 10; i && !cfg->status; i-- )
00365                 mdelay ( 1 );
00366         if ( ! cfg->status ) {
00367                 DBG ( "Failed to initiate!\n" );
00368                 goto error;
00369         }
00370         free_dma ( ias, sizeof ( *ias ) );
00371         free_dma ( cfg, sizeof ( *cfg ) );
00372         DBG2 ( "cfg " );
00373 
00374         /* Enable rx by sending ring address to card */
00375         if ( priv->rfds[0] != NULL ) {
00376                 ifec_scb_cmd ( netdev, virt_to_bus( priv->rfds[0] ), RUStart );
00377                 ifec_scb_cmd_wait ( netdev );
00378         }
00379         DBG2 ( "rx_start\n" );
00380 
00381         return 0;
00382 
00383 error:
00384         free_dma ( cfg, sizeof ( *cfg ) );
00385         free_dma ( ias, sizeof ( *ias ) );
00386         ifec_free ( netdev );
00387         ifec_reset ( netdev );
00388         return rc;
00389 }
00390 
00391 /*
00392  * This function allows a driver to process events during operation.
00393  *
00394  * @v netdev            Device being polled.
00395  *
00396  * This is called periodically by iPXE to let the driver check the status of
00397  * transmitted packets and to allow the driver to check for received packets.
00398  * This is a iPXE Network Device Driver API function.
00399  */
00400 static void ifec_net_poll ( struct net_device *netdev )
00401 {
00402         struct ifec_private *priv = netdev->priv;
00403         unsigned short intr_status;
00404 
00405         DBGP ( "ifec_net_poll\n" );
00406 
00407         /* acknowledge interrupts ASAP */
00408         intr_status = inw ( priv->ioaddr + SCBStatus );
00409         outw ( intr_status, priv->ioaddr + SCBStatus );
00410         inw ( priv->ioaddr + SCBStatus );
00411 
00412         DBG2 ( "poll - status: 0x%04X\n", intr_status );
00413 
00414         /* anything to do here? */
00415         if ( ( intr_status & ( ~INTERRUPT_MASK ) ) == 0 )
00416                 return;
00417 
00418         /* process received and transmitted packets */
00419         ifec_tx_process ( netdev );
00420         ifec_rx_process ( netdev );
00421 
00422         ifec_check_ru_status ( netdev, intr_status );
00423 
00424         return;
00425 }
00426 
00427 /*
00428  * This transmits a packet.
00429  *
00430  * @v netdev            Device to transmit from.
00431  * @v iobuf             Data to transmit.
00432  * @ret rc              Non-zero if failed to transmit.
00433  *
00434  * This is a iPXE Network Driver API function.
00435  */
00436 static int ifec_net_transmit ( struct net_device *netdev,
00437                                struct io_buffer *iobuf )
00438 {
00439         struct ifec_private *priv = netdev->priv;
00440         struct ifec_tcb *tcb = priv->tcb_head->next;
00441         unsigned long ioaddr = priv->ioaddr;
00442 
00443         DBGP ( "ifec_net_transmit\n" );
00444 
00445         /* Wait for TCB to become available. */
00446         if ( tcb->status || tcb->iob ) {
00447                 DBG ( "TX overflow\n" );
00448                 return -ENOBUFS;
00449         }
00450 
00451         DBG2 ( "transmitting packet (%zd bytes). status = %hX, cmd=%hX\n",
00452                 iob_len ( iobuf ), tcb->status, inw ( ioaddr + SCBCmd ) );
00453 
00454         tcb->command   = CmdSuspend | CmdTx | CmdTxFlex;
00455         tcb->count     = 0x01208000;
00456         tcb->tbd_addr0 = virt_to_bus ( iobuf->data );
00457         tcb->tbd_size0 = 0x3FFF & iob_len ( iobuf );
00458         tcb->iob = iobuf;
00459 
00460         ifec_tx_wake ( netdev );
00461 
00462         /* Append to end of ring. */
00463         priv->tcb_head = tcb;
00464 
00465         return 0;
00466 }
00467 
00468 /*************************** Local support functions *************************/
00469 
00470 /* Define what each GPIO Pin does */
00471 static const uint16_t ifec_ee_bits[] = {
00472         [SPI_BIT_SCLK]  = EE_SHIFT_CLK,
00473         [SPI_BIT_MOSI]  = EE_DATA_WRITE,
00474         [SPI_BIT_MISO]  = EE_DATA_READ,
00475         [SPI_BIT_SS(0)] = EE_ENB,
00476 };
00477 
00478 /*
00479  * Read a single bit from the GPIO pins used for SPI.
00480  * should be called by SPI bitbash functions only
00481  *
00482  * @v basher            Bitbash device
00483  * @v bit_id            Line to be read
00484  */
00485 static int ifec_spi_read_bit ( struct bit_basher *basher,
00486                                unsigned int bit_id )
00487 {
00488         struct ifec_private *priv =
00489                 container_of ( basher, struct ifec_private, spi.basher );
00490         unsigned long ee_addr = priv->ioaddr + CSREeprom;
00491         unsigned int ret = 0;
00492         uint16_t mask;
00493 
00494         DBGP ( "ifec_spi_read_bit\n" );
00495 
00496         mask = ifec_ee_bits[bit_id];
00497         ret = inw (ee_addr);
00498 
00499         return ( ret & mask ) ? 1 : 0;
00500 }
00501 
00502 /*
00503  * Write a single bit to the GPIO pins used for SPI.
00504  * should be called by SPI bitbash functions only
00505  *
00506  * @v basher            Bitbash device
00507  * @v bit_id            Line to write to
00508  * @v data              Value to write
00509  */
00510 static void ifec_spi_write_bit ( struct bit_basher *basher,
00511                                  unsigned int bit_id,
00512                                  unsigned long data )
00513 {
00514         struct ifec_private *priv =
00515                 container_of ( basher, struct ifec_private, spi.basher );
00516         unsigned long ee_addr = priv->ioaddr + CSREeprom;
00517         short val;
00518         uint16_t mask = ifec_ee_bits[bit_id];
00519 
00520         DBGP ( "ifec_spi_write_bit\n" );
00521 
00522         val = inw ( ee_addr );
00523         val &= ~mask;
00524         val |= data & mask;
00525 
00526         outw ( val, ee_addr );
00527 }
00528 
00529 /* set function pointer to SPI read- and write-bit functions */
00530 static struct bit_basher_operations ifec_basher_ops = {
00531         .read = ifec_spi_read_bit,
00532         .write = ifec_spi_write_bit,
00533 };
00534 
00535 /*
00536  * Initialize the eeprom stuff
00537  *
00538  * @v netdev            Network device
00539  */
00540 static void ifec_init_eeprom ( struct net_device *netdev )
00541 {
00542         struct ifec_private *priv = netdev->priv;
00543 
00544         DBGP ( "ifec_init_eeprom\n" );
00545 
00546         priv->spi.basher.op = &ifec_basher_ops;
00547         priv->spi.bus.mode = SPI_MODE_THREEWIRE;
00548         init_spi_bit_basher ( &priv->spi );
00549 
00550         priv->eeprom.bus = &priv->spi.bus;
00551 
00552         /* init as 93c46(93c14 compatible) first, to set the command len,
00553          * block size and word len. Needs to be set for address len detection.
00554          */
00555         init_at93c46 ( &priv->eeprom, 16 );
00556 
00557         /* detect address length, */
00558         threewire_detect_address_len ( &priv->eeprom );
00559 
00560         /* address len == 8 means 93c66 instead of 93c46 */
00561         if ( priv->eeprom.address_len == 8 )
00562                 init_at93c66 ( &priv->eeprom, 16 );
00563 }
00564 
00565 /*
00566  * Support function: ifec_mdio_read
00567  *
00568  * This probably reads a register in the "physical media interface chip".
00569  * -- REW
00570  */
00571 static int ifec_mdio_read ( struct net_device *netdev, int phy_id,
00572                                                        int location )
00573 {
00574         struct ifec_private *priv = netdev->priv;
00575         unsigned long ioaddr = priv->ioaddr;
00576         int val;
00577         int boguscnt = 64*4;     /* <64 usec. to complete, typ 27 ticks */
00578 
00579         DBGP ( "ifec_mdio_read\n" );
00580 
00581         outl ( 0x08000000 | ( location << 16 ) | ( phy_id << 21 ),
00582                ioaddr + CSRCtrlMDI );
00583         do {
00584                 udelay ( 16 );
00585 
00586                 val = inl ( ioaddr + CSRCtrlMDI );
00587 
00588                 if ( --boguscnt < 0 ) {
00589                         DBG ( " ifec_mdio_read() time out with val = %X.\n",
00590                                  val );
00591                         break;
00592                 }
00593         } while (! ( val & 0x10000000 ) );
00594         return val & 0xffff;
00595 }
00596 
00597 /*
00598  * Initializes MDIO.
00599  *
00600  * @v netdev            Network device
00601  * @v options           MDIO options
00602  */
00603 static void ifec_mdio_setup ( struct net_device *netdev, int options )
00604 {
00605         struct ifec_private *priv = netdev->priv;
00606         unsigned short mdio_register = priv->mdio_register;
00607 
00608         DBGP ( "ifec_mdio_setup\n" );
00609 
00610         if (   ( (mdio_register>>8) & 0x3f ) == DP83840
00611             || ( (mdio_register>>8) & 0x3f ) == DP83840A ) {
00612                 int mdi_reg23 = ifec_mdio_read ( netdev, mdio_register
00613                                                   & 0x1f, 23 ) | 0x0422;
00614                 if (CONGENB)
00615                         mdi_reg23 |= 0x0100;
00616                 DBG2 ( "DP83840 specific setup, setting register 23 to "
00617                                                          "%hX.\n", mdi_reg23 );
00618                 ifec_mdio_write ( netdev, mdio_register & 0x1f, 23, mdi_reg23 );
00619         }
00620         DBG2 ( "dp83840 " );
00621         if ( options != 0 ) {
00622                 ifec_mdio_write ( netdev, mdio_register & 0x1f, 0,
00623                                            ( (options & 0x20) ? 0x2000 : 0 ) |
00624                                            ( (options & 0x10) ? 0x0100 : 0 ) );
00625                 DBG2 ( "set mdio_register. " );
00626         }
00627 }
00628 
00629 /*
00630  * Support function: ifec_mdio_write
00631  *
00632  * This probably writes to the "physical media interface chip".
00633  * -- REW
00634  */
00635 static int ifec_mdio_write ( struct net_device *netdev,
00636                              int phy_id, int location, int value )
00637 {
00638         struct ifec_private *priv = netdev->priv;
00639         unsigned long ioaddr = priv->ioaddr;
00640         int val;
00641         int boguscnt = 64*4;     /* <64 usec. to complete, typ 27 ticks */
00642 
00643         DBGP ( "ifec_mdio_write\n" );
00644 
00645         outl ( 0x04000000 | ( location << 16 ) | ( phy_id << 21 ) | value,
00646                ioaddr + CSRCtrlMDI );
00647         do {
00648                 udelay ( 16 );
00649 
00650                 val = inl ( ioaddr + CSRCtrlMDI );
00651                 if ( --boguscnt < 0 ) {
00652                         DBG ( " ifec_mdio_write() time out with val = %X.\n",
00653                               val );
00654                         break;
00655                 }
00656         } while (! ( val & 0x10000000 ) );
00657         return val & 0xffff;
00658 }
00659 
00660 /*
00661  * Resets the hardware.
00662  *
00663  * @v netdev            Network device
00664  */
00665 static void ifec_reset ( struct net_device *netdev )
00666 {
00667         struct ifec_private *priv = netdev->priv;
00668         unsigned long ioaddr = priv->ioaddr;
00669 
00670         DBGP ( "ifec_reset\n" );
00671 
00672         /* do partial reset first */
00673         outl ( PortPartialReset, ioaddr + CSRPort );
00674         inw ( ioaddr + SCBStatus );
00675         udelay ( 20 );
00676 
00677         /* full reset */
00678         outl ( PortReset, ioaddr + CSRPort );
00679         inw ( ioaddr + SCBStatus );
00680         udelay ( 20 );
00681 
00682         /* disable interrupts again */
00683         ifec_net_irq ( netdev, 0 );
00684 }
00685 
00686 /*
00687  * free()s the tx/rx rings.
00688  *
00689  * @v netdev            Network device
00690  */
00691 static void ifec_free ( struct net_device *netdev )
00692 {
00693         struct ifec_private *priv = netdev_priv ( netdev );
00694         int i;
00695 
00696         DBGP ( "ifec_free\n" );
00697 
00698         /* free all allocated receive io_buffers */
00699         for ( i = 0; i < RFD_COUNT; i++ ) {
00700                 free_iob ( priv->rx_iobs[i] );
00701                 priv->rx_iobs[i] = NULL;
00702                 priv->rfds[i] = NULL;
00703         }
00704 
00705         /* free TX ring buffer */
00706         free_dma ( priv->tcbs, TX_RING_BYTES );
00707 
00708         priv->tcbs = NULL;
00709 }
00710 
00711 /*
00712  * Initializes an RFD.
00713  *
00714  * @v rfd               RFD struct to initialize
00715  * @v command           Command word
00716  * @v link              Link value
00717  */
00718 static void ifec_rfd_init ( struct ifec_rfd *rfd, s16 command, u32 link )
00719 {
00720         DBGP ( "ifec_rfd_init\n" );
00721 
00722         rfd->status      = 0;
00723         rfd->command     = command;
00724         rfd->rx_buf_addr = 0xFFFFFFFF;
00725         rfd->count       = 0;
00726         rfd->size        = RFD_PACKET_LEN;
00727         rfd->link        = link;
00728 }
00729 
00730 /*
00731  * Send address of new RFD to card
00732  *
00733  * @v netdev            Network device
00734  */
00735 static void ifec_reprime_ru ( struct net_device *netdev )
00736 {
00737         struct ifec_private *priv = netdev->priv;
00738         int cur_rx = priv->cur_rx;
00739         
00740         DBGP ( "ifec_reprime_ru\n" );
00741         
00742         if ( priv->rfds[cur_rx] != NULL ) {
00743                 ifec_scb_cmd ( netdev, virt_to_bus ( priv->rfds[cur_rx] ),
00744                                RUStart );
00745                 ifec_scb_cmd_wait ( netdev );
00746         }
00747 }
00748 
00749 /*
00750  * Check if reprime of RU needed
00751  *
00752  * @v netdev            Network device
00753  */
00754 static void ifec_check_ru_status ( struct net_device *netdev,
00755                                    unsigned short intr_status )
00756 {
00757         struct ifec_private *priv = netdev->priv;
00758 
00759         DBGP ( "ifec_check_ru_status\n" );
00760 
00761         /*
00762         * The chip may have suspended reception for various reasons.
00763         * Check for that, and re-prime it should this be the case.
00764         */
00765         switch ( ( intr_status >> 2 ) & 0xf ) {
00766                 case 0:  /* Idle */
00767                 case 4:  /* Ready */
00768                         break;
00769                 case 1:  /* Suspended */
00770                 case 2:  /* No resources (RFDs) */
00771                 case 9:  /* Suspended with no more RBDs */
00772                 case 10: /* No resources due to no RBDs */
00773                 case 12: /* Ready with no RBDs */
00774                         DBG ( "ifec_net_poll: RU reprimed.\n" );
00775                         ifec_reprime_ru ( netdev );
00776                         break;
00777                 default:
00778                         /* reserved values */
00779                         DBG ( "ifec_net_poll: RU state anomaly: %i\n",
00780                               ( inw ( priv->ioaddr + SCBStatus ) >> 2 ) & 0xf );
00781                         break;
00782         }
00783 }
00784 
00785 #define RFD_STATUS ( RFD_OK | RFDRxCol | RFDRxErr | RFDShort | \
00786                      RFDDMAOverrun | RFDNoBufs | RFDCRCError )
00787 /*
00788  * Looks for received packets in the rx ring, reports success or error to
00789  * the core accordingly. Starts reallocation of rx ring.
00790  *
00791  * @v netdev            Network device
00792  */
00793 static void ifec_rx_process ( struct net_device *netdev )
00794 {
00795         struct ifec_private *priv   = netdev->priv;
00796         int cur_rx = priv->cur_rx;
00797         struct io_buffer *iob = priv->rx_iobs[cur_rx];
00798         struct ifec_rfd *rfd = priv->rfds[cur_rx];
00799         unsigned int rx_len;
00800         s16 status;
00801 
00802         DBGP ( "ifec_rx_process\n" );
00803 
00804         /* Process any received packets */
00805         while ( iob && rfd && ( status = rfd->status ) ) {
00806                 rx_len = rfd->count & RFDMaskCount;
00807 
00808                 DBG2 ( "Got a packet: Len = %d, cur_rx = %d.\n", rx_len,
00809                        cur_rx );
00810                 DBGIO_HD ( (void*)rfd->packet, 0x30 );
00811 
00812                 if ( ( status & ( RFD_STATUS & ~RFDShort ) ) != RFD_OK ) {
00813                         DBG ( "Corrupted packet received. "
00814                               "Status = %#08hx\n", status );
00815                         netdev_rx_err ( netdev, iob, -EINVAL );
00816                 } else {
00817                         /* Hand off the packet to the network subsystem */
00818                         iob_put ( iob, rx_len );
00819                         DBG2 ( "Received packet: %p, len: %d\n", iob, rx_len );
00820                         netdev_rx ( netdev, iob );
00821                 }
00822 
00823                 /* make sure we don't reuse this RFD */
00824                 priv->rx_iobs[cur_rx] = NULL;
00825                 priv->rfds[cur_rx] = NULL;
00826 
00827                 /* Next RFD */
00828                 priv->cur_rx = ( cur_rx + 1 ) % RFD_COUNT;
00829                 cur_rx = priv->cur_rx;
00830                 iob = priv->rx_iobs[cur_rx];
00831                 rfd = priv->rfds[cur_rx];
00832         }
00833 
00834         ifec_refill_rx_ring ( netdev );
00835 }
00836 
00837 /*
00838  * Allocates io_buffer, set pointers in ifec_private structure accordingly,
00839  * reserves space for RFD header in io_buffer.
00840  *
00841  * @v netdev            Network device
00842  * @v cur               Descriptor number to work on
00843  * @v cmd               Value to set cmd field in RFD to
00844  * @v link              Pointer to ned RFD
00845  * @ret rc              0 on success, negative on failure
00846  */
00847 static int ifec_get_rx_desc ( struct net_device *netdev, int cur, int cmd,
00848                               int link )
00849 {
00850         struct ifec_private *priv = netdev->priv;
00851         struct ifec_rfd *rfd  = priv->rfds[cur];
00852 
00853         DBGP ( "ifec_get_rx_desc\n" );
00854 
00855         priv->rx_iobs[cur] = alloc_iob ( sizeof ( *rfd ) );
00856         if ( ! priv->rx_iobs[cur] ) {
00857                 DBG ( "alloc_iob failed. desc. nr: %d\n", cur );
00858                 priv->rfds[cur] = NULL;
00859                 return -ENOMEM;
00860         }
00861 
00862         /* Initialize new tail. */
00863         priv->rfds[cur] = priv->rx_iobs[cur]->data;
00864         ifec_rfd_init ( priv->rfds[cur], cmd, link );
00865         iob_reserve ( priv->rx_iobs[cur], RFD_HEADER_LEN );
00866 
00867         return 0;
00868 }
00869 
00870 /*
00871  * Allocate new descriptor entries and initialize them if needed
00872  *
00873  * @v netdev            Network device
00874  */
00875 static void ifec_refill_rx_ring ( struct net_device *netdev )
00876 {
00877         struct ifec_private *priv = netdev->priv;
00878         int i, cur_rx;
00879         unsigned short intr_status;
00880 
00881         DBGP ( "ifec_refill_rx_ring\n" );
00882 
00883         for ( i = 0; i < RFD_COUNT; i++ ) {
00884                 cur_rx = ( priv->cur_rx + i ) % RFD_COUNT;
00885                 /* only refill if empty */
00886                 if ( priv->rfds[cur_rx] != NULL ||
00887                      priv->rx_iobs[cur_rx] != NULL )
00888                         continue;
00889 
00890                 DBG2 ( "refilling RFD %d\n", cur_rx );
00891 
00892                 if ( ifec_get_rx_desc ( netdev, cur_rx,
00893                      CmdSuspend | CmdEndOfList, 0 ) == 0 ) {
00894                         if ( i > 0 ) {
00895                                 int prev_rx = ( ( ( cur_rx + RFD_COUNT ) - 1 )
00896                                                 % RFD_COUNT );
00897                                 struct ifec_rfd *rfd = priv->rfds[prev_rx];
00898 
00899                                 rfd->command = 0;
00900                                 rfd->link = virt_to_bus ( priv->rfds[cur_rx] );
00901                         }
00902                 }
00903         }
00904 
00905         intr_status = inw ( priv->ioaddr + SCBStatus );
00906         ifec_check_ru_status ( netdev, intr_status );
00907 }
00908 
00909 /*
00910  * Initial allocation & initialization of the rx ring.
00911  *
00912  * @v netdev            Device of rx ring.
00913  * @ret rc              Non-zero if error occurred
00914  */
00915 static int ifec_rx_setup ( struct net_device *netdev )
00916 {
00917         struct ifec_private *priv = netdev->priv;
00918         int i;
00919 
00920         DBGP ( "ifec_rx_setup\n" );
00921 
00922         priv->cur_rx = 0;
00923 
00924         /* init values for ifec_refill_rx_ring() */
00925         for ( i = 0; i < RFD_COUNT; i++ ) {
00926                 priv->rfds[i] = NULL;
00927                 priv->rx_iobs[i] = NULL;
00928         }
00929         ifec_refill_rx_ring ( netdev );
00930 
00931         return 0;
00932 }
00933 
00934 /*
00935  * Initiates a SCB command.
00936  *
00937  * @v netdev            Network device
00938  * @v ptr               General pointer value for command.
00939  * @v cmd               Command to issue.
00940  * @ret rc              Non-zero if command not issued.
00941  */
00942 static int ifec_scb_cmd ( struct net_device *netdev, u32 ptr, u8 cmd )
00943 {
00944         struct ifec_private *priv = netdev->priv;
00945         unsigned long ioaddr = priv->ioaddr;
00946         int rc;
00947 
00948         DBGP ( "ifec_scb_cmd\n" );
00949 
00950         rc = ifec_scb_cmd_wait ( netdev );      /* Wait until ready */
00951         if ( !rc ) {
00952                 outl ( ptr, ioaddr + SCBPointer );
00953                 outb ( cmd, ioaddr + SCBCmd );          /* Issue command */
00954         }
00955         return rc;
00956 }
00957 
00958 /*
00959  * Wait for command unit to accept a command.
00960  *
00961  * @v cmd_ioaddr        I/O address of command register.
00962  * @ret rc              Non-zero if command timed out.
00963  */
00964 static int ifec_scb_cmd_wait ( struct net_device *netdev )
00965 {
00966         struct ifec_private *priv = netdev->priv;
00967         unsigned long cmd_ioaddr = priv->ioaddr + SCBCmd;
00968         int rc, wait = CU_CMD_TIMEOUT;
00969 
00970         DBGP ( "ifec_scb_cmd_wait\n" );
00971 
00972         for ( ; wait && ( rc = inb ( cmd_ioaddr ) ); wait-- )
00973                 udelay ( 1 );
00974 
00975         if ( !wait )
00976                 DBG ( "ifec_scb_cmd_wait timeout!\n" );
00977         return rc;
00978 }
00979 
00980 /*
00981  * Check status of transmitted packets & perform tx completions.
00982  *
00983  * @v netdev            Network device.
00984  */
00985 static void ifec_tx_process ( struct net_device *netdev )
00986 {
00987         struct ifec_private *priv = netdev->priv;
00988         struct ifec_tcb *tcb = priv->tcb_tail;
00989         s16 status;
00990 
00991         DBGP ( "ifec_tx_process\n" );
00992 
00993         /* Check status of transmitted packets */
00994         while ( ( status = tcb->status ) && tcb->iob ) {
00995                 if ( status & TCB_U ) {
00996                         /* report error to iPXE */
00997                         DBG ( "ifec_tx_process : tx error!\n " );
00998                         netdev_tx_complete_err ( netdev, tcb->iob, -EINVAL );
00999                 } else {
01000                         /* report successful transmit */
01001                         netdev_tx_complete ( netdev, tcb->iob );
01002                 }
01003                 DBG2 ( "tx completion\n" );
01004 
01005                 tcb->iob = NULL;
01006                 tcb->status = 0;
01007 
01008                 priv->tcb_tail = tcb->next;     /* Next TCB */
01009                 tcb = tcb->next;
01010         }
01011 }
01012 
01013 /*
01014  * Allocates & initialize tx resources.
01015  *
01016  * @v netdev            Network device.
01017  * @ret rc              Non-zero if error occurred.
01018  */
01019 static int ifec_tx_setup ( struct net_device *netdev )
01020 {
01021         struct ifec_private *priv = netdev->priv;
01022         struct ifec_tcb *tcb;
01023         int i;
01024 
01025         DBGP ( "ifec_tx_setup\n" );
01026 
01027         /* allocate tx ring */
01028         priv->tcbs = malloc_dma ( TX_RING_BYTES, CB_ALIGN );
01029         if ( !priv->tcbs ) {
01030                 DBG ( "TX-ring allocation failed\n" );
01031                 return -ENOMEM;
01032         }
01033 
01034         tcb = priv->tcb_tail = priv->tcbs;
01035         priv->tx_curr = priv->tx_tail = 0;
01036         priv->tx_cnt = 0;
01037 
01038         for ( i = 0; i < TCB_COUNT; i++, tcb++ ) {
01039                 tcb->status    = 0;
01040                 tcb->count     = 0x01208000;
01041                 tcb->iob       = NULL;
01042                 tcb->tbda_addr = virt_to_bus ( &tcb->tbd_addr0 );
01043                 tcb->link      = virt_to_bus ( tcb + 1 );
01044                 tcb->next      = tcb + 1;
01045         }
01046         /* We point tcb_head at the last TCB, so the first ifec_net_transmit()
01047          * will use the first (head->next) TCB to transmit. */
01048         priv->tcb_head = --tcb;
01049         tcb->link = virt_to_bus ( priv->tcbs );
01050         tcb->next = priv->tcbs;
01051         
01052         return 0;
01053 }
01054 
01055 /*
01056  * Wake up the Command Unit and issue a Resume/Start.
01057  *
01058  * @v netdev            Network device containing Command Unit
01059  *
01060  * The time between clearing the S bit and issuing Resume must be as short as
01061  * possible to prevent a race condition. As noted in linux eepro100.c :
01062  *   Note: Watch out for the potential race condition here: imagine
01063  *      erasing the previous suspend
01064  *              the chip processes the previous command
01065  *              the chip processes the final command, and suspends
01066  *      doing the CU_RESUME
01067  *              the chip processes the next-yet-valid post-final-command.
01068  *   So blindly sending a CU_RESUME is only safe if we do it immediately after
01069  *   erasing the previous CmdSuspend, without the possibility of an intervening
01070  *   delay.
01071  */
01072 void ifec_tx_wake ( struct net_device *netdev )
01073 {
01074         struct ifec_private *priv = netdev->priv;
01075         unsigned long ioaddr = priv->ioaddr;
01076         struct ifec_tcb *tcb = priv->tcb_head->next;
01077 
01078         DBGP ( "ifec_tx_wake\n" );
01079 
01080         /* For the special case of the first transmit, we issue a START. The
01081          * card won't RESUME after the configure command. */
01082         if ( priv->configured ) {
01083                 priv->configured = 0;
01084                 ifec_scb_cmd ( netdev, virt_to_bus ( tcb ), CUStart );
01085                 ifec_scb_cmd_wait ( netdev );
01086                 return;
01087         }
01088 
01089         /* Resume if suspended. */
01090         switch ( ( inw ( ioaddr + SCBStatus ) >> 6 ) & 0x3 ) {
01091         case 0:  /* Idle - We should not reach this state. */
01092                 DBG2 ( "ifec_tx_wake: tx idle!\n" );
01093                 ifec_scb_cmd ( netdev, virt_to_bus ( tcb ), CUStart );
01094                 ifec_scb_cmd_wait ( netdev );
01095                 return;
01096         case 1:  /* Suspended */
01097                 DBG2 ( "s" );
01098                 break;
01099         default: /* Active */
01100                 DBG2 ( "a" );
01101         }
01102         ifec_scb_cmd_wait ( netdev );
01103         outl ( 0, ioaddr + SCBPointer );
01104         priv->tcb_head->command &= ~CmdSuspend;
01105         /* Immediately issue Resume command */
01106         outb ( CUResume, ioaddr + SCBCmd );
01107         ifec_scb_cmd_wait ( netdev );
01108 }
01109 
01110 /*********************************************************************/
01111 
01112 static struct pci_device_id ifec_nics[] = {
01113 PCI_ROM(0x8086, 0x1029, "id1029",        "Intel EtherExpressPro100 ID1029", 0),
01114 PCI_ROM(0x8086, 0x1030, "id1030",        "Intel EtherExpressPro100 ID1030", 0),
01115 PCI_ROM(0x8086, 0x1031, "82801cam",      "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0),
01116 PCI_ROM(0x8086, 0x1032, "eepro100-1032", "Intel PRO/100 VE Network Connection", 0),
01117 PCI_ROM(0x8086, 0x1033, "eepro100-1033", "Intel PRO/100 VM Network Connection", 0),
01118 PCI_ROM(0x8086, 0x1034, "eepro100-1034", "Intel PRO/100 VM Network Connection", 0),
01119 PCI_ROM(0x8086, 0x1035, "eepro100-1035", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0),
01120 PCI_ROM(0x8086, 0x1036, "eepro100-1036", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0),
01121 PCI_ROM(0x8086, 0x1037, "eepro100-1037", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0),
01122 PCI_ROM(0x8086, 0x1038, "id1038",        "Intel PRO/100 VM Network Connection", 0),
01123 PCI_ROM(0x8086, 0x1039, "82562et",       "Intel PRO100 VE 82562ET", 0),
01124 PCI_ROM(0x8086, 0x103a, "id103a",        "Intel Corporation 82559 InBusiness 10/100", 0),
01125 PCI_ROM(0x8086, 0x103b, "82562etb",      "Intel PRO100 VE 82562ETB", 0),
01126 PCI_ROM(0x8086, 0x103c, "eepro100-103c", "Intel PRO/100 VM Network Connection", 0),
01127 PCI_ROM(0x8086, 0x103d, "eepro100-103d", "Intel PRO/100 VE Network Connection", 0),
01128 PCI_ROM(0x8086, 0x103e, "eepro100-103e", "Intel PRO/100 VM Network Connection", 0),
01129 PCI_ROM(0x8086, 0x1051, "prove",         "Intel PRO/100 VE Network Connection", 0),
01130 PCI_ROM(0x8086, 0x1059, "82551qm",       "Intel PRO/100 M Mobile Connection", 0),
01131 PCI_ROM(0x8086, 0x1209, "82559er",       "Intel EtherExpressPro100 82559ER", 0),
01132 PCI_ROM(0x8086, 0x1227, "82865",         "Intel 82865 EtherExpress PRO/100A", 0),
01133 PCI_ROM(0x8086, 0x1228, "82556",         "Intel 82556 EtherExpress PRO/100 Smart", 0),
01134 PCI_ROM(0x8086, 0x1229, "eepro100",      "Intel EtherExpressPro100", 0),
01135 PCI_ROM(0x8086, 0x2449, "82562em",       "Intel EtherExpressPro100 82562EM", 0),
01136 PCI_ROM(0x8086, 0x2459, "82562-1",       "Intel 82562 based Fast Ethernet Connection", 0),
01137 PCI_ROM(0x8086, 0x245d, "82562-2",       "Intel 82562 based Fast Ethernet Connection", 0),
01138 PCI_ROM(0x8086, 0x1050, "82562ez",       "Intel 82562EZ Network Connection", 0),
01139 PCI_ROM(0x8086, 0x1065, "82562-3",       "Intel 82562 based Fast Ethernet Connection", 0),
01140 PCI_ROM(0x8086, 0x5200, "eepro100-5200", "Intel EtherExpress PRO/100 Intelligent Server", 0),
01141 PCI_ROM(0x8086, 0x5201, "eepro100-5201", "Intel EtherExpress PRO/100 Intelligent Server", 0),
01142 PCI_ROM(0x8086, 0x1092, "82562-3",       "Intel Pro/100 VE Network", 0),
01143 PCI_ROM(0x8086, 0x27dc, "eepro100-27dc", "Intel 82801G (ICH7) Chipset Ethernet Controller", 0),
01144 PCI_ROM(0x8086, 0x10fe, "82552",         "Intel 82552 10/100 Network Connection", 0),
01145 };
01146 
01147 /* Cards with device ids 0x1030 to 0x103F, 0x2449, 0x2459 or 0x245D might need
01148  * a workaround for hardware bug on 10 mbit half duplex (see linux driver eepro100.c)
01149  * 2003/03/17 gbaum */
01150 
01151 struct pci_driver ifec_driver __pci_driver = {
01152         .ids      = ifec_nics,
01153         .id_count = ( sizeof (ifec_nics) / sizeof (ifec_nics[0]) ),
01154         .probe    = ifec_pci_probe,
01155         .remove   = ifec_pci_remove
01156 };
01157 
01158 /*
01159  * Local variables:
01160  *  c-basic-offset: 8
01161  *  c-indent-level: 8
01162  *  tab-width: 8
01163  * End:
01164  */