eepro100.c File Reference

#include <stdint.h>
#include <byteswap.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <gpxe/ethernet.h>
#include <gpxe/if_ether.h>
#include <gpxe/iobuf.h>
#include <gpxe/malloc.h>
#include <gpxe/pci.h>
#include <gpxe/spi_bit.h>
#include <gpxe/timer.h>
#include <gpxe/nvs.h>
#include <gpxe/threewire.h>
#include <gpxe/netdevice.h>
#include "eepro100.h"

Go to the source code of this file.

Defines

#define INTERRUPT_MASK   ( SCBMaskEarlyRx | SCBMaskFlowCtl )
#define RFD_STATUS

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static int ifec_pci_probe (struct pci_device *pci, const struct pci_device_id *id __unused)
static void ifec_pci_remove (struct pci_device *pci)
static void ifec_net_close (struct net_device *netdev)
static void ifec_net_irq (struct net_device *netdev, int enable)
static int ifec_net_open (struct net_device *netdev)
static void ifec_net_poll (struct net_device *netdev)
static int ifec_net_transmit (struct net_device *netdev, struct io_buffer *iobuf)
static int ifec_spi_read_bit (struct bit_basher *basher, unsigned int bit_id)
static void ifec_spi_write_bit (struct bit_basher *basher, unsigned int bit_id, unsigned long data)
static void ifec_init_eeprom (struct net_device *netdev)
static int ifec_link_check (struct net_device *netdev)
static void ifec_link_update (struct net_device *netdev)
static int ifec_mdio_read (struct net_device *netdev, int phy_id, int location)
static void ifec_mdio_setup (struct net_device *netdev, int options)
static int ifec_mdio_write (struct net_device *netdev, int phy_id, int location, int value)
static void ifec_reset (struct net_device *netdev)
static void ifec_free (struct net_device *netdev)
static void ifec_rfd_init (struct ifec_rfd *rfd, s16 command, u32 link)
static void ifec_reprime_ru (struct net_device *netdev)
static void ifec_check_ru_status (struct net_device *netdev, unsigned short intr_status)
static void ifec_rx_process (struct net_device *netdev)
static int ifec_get_rx_desc (struct net_device *netdev, int cur, int cmd, int link)
static void ifec_refill_rx_ring (struct net_device *netdev)
static int ifec_rx_setup (struct net_device *netdev)
static int ifec_scb_cmd (struct net_device *netdev, u32 ptr, u8 cmd)
static int ifec_scb_cmd_wait (struct net_device *netdev)
static void ifec_tx_process (struct net_device *netdev)
static int ifec_tx_setup (struct net_device *netdev)
void ifec_tx_wake (struct net_device *netdev)

Variables

static struct ifec_cfg ifec_cfg
static struct net_device_operations ifec_operations
static const uint16_t ifec_ee_bits []
static struct bit_basher_operations ifec_basher_ops
static struct pci_device_id ifec_nics []
struct pci_driver ifec_driver __pci_driver


Define Documentation

#define INTERRUPT_MASK   ( SCBMaskEarlyRx | SCBMaskFlowCtl )

Definition at line 280 of file eepro100.c.

Referenced by ifec_net_irq(), and ifec_net_poll().

#define RFD_STATUS

Value:

Definition at line 830 of file eepro100.c.

Referenced by ifec_rx_process().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static int ifec_pci_probe ( struct pci_device pci,
const struct pci_device_id *id  __unused 
) [static]

Definition at line 170 of file eepro100.c.

References adjust_pci_device(), alloc_etherdev(), DBGP, pci_device::dev, net_device::dev, ifec_private::eeprom, EEPROM_ADDR_MAC_0, EEPROM_ADDR_MDIO_REGISTER, EINVAL, ENOMEM, ETH_ALEN, net_device::hw_addr, ifec_init_eeprom(), ifec_link_update(), ifec_reset(), ifec_private::ioaddr, pci_device::ioaddr, ifec_private::mdio_register, memset(), netdev, netdev_init(), netdev_nullify(), netdev_put(), spi_device::nvs, nvs_read(), pci_set_drvdata(), net_device::priv, priv, and register_netdev().

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         ifec_link_update ( netdev );    /* Update link state */
00213 
00214         if ( ( rc = register_netdev ( netdev ) ) != 0 )
00215                 goto error;
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 }

static void ifec_pci_remove ( struct pci_device pci  )  [static]

Definition at line 236 of file eepro100.c.

References DBGP, ifec_reset(), netdev, netdev_nullify(), netdev_put(), pci_get_drvdata(), and unregister_netdev().

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 }

static void ifec_net_close ( struct net_device netdev  )  [static]

Definition at line 257 of file eepro100.c.

References DBGP, ifec_free(), ifec_net_irq(), ifec_reset(), inw, ifec_private::ioaddr, ioaddr, outw, net_device::priv, priv, and SCBStatus.

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 }

static void ifec_net_irq ( struct net_device netdev,
int  enable 
) [static]

Definition at line 290 of file eepro100.c.

References DBGP, INTERRUPT_MASK, ifec_private::ioaddr, ioaddr, outw, net_device::priv, priv, SCBCmd, and SCBMaskAll.

Referenced by ifec_net_close(), ifec_net_open(), and ifec_reset().

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 }

static int ifec_net_open ( struct net_device netdev  )  [static]

Definition at line 309 of file eepro100.c.

References ifec_cfg::byte, CB_ALIGN, cfg, CmdIASetup, ifec_ias::command, ifec_private::configured, CUCmdBase, CUStart, CUStatsAddr, DBG, DBG2, DBGP, ENOMEM, ETH_ALEN, free_dma(), ifec_ias::ia, ifec_free(), ifec_mdio_setup(), ifec_net_irq(), ifec_reset(), ifec_rx_setup(), ifec_scb_cmd(), ifec_scb_cmd_wait(), ifec_tx_setup(), ifec_ias::link, ifec_cfg::link, net_device::ll_addr, malloc_dma(), mdelay(), memcpy, NULL, options, net_device::priv, priv, ifec_private::rfds, RUAddrLoad, RUStart, ifec_private::stats, ifec_cfg::status, ifec_ias::status, ifec_private::tcbs, and virt_to_bus().

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 }

static void ifec_net_poll ( struct net_device netdev  )  [static]

Definition at line 400 of file eepro100.c.

References DBG2, DBGP, ifec_check_ru_status(), ifec_link_update(), ifec_rx_process(), ifec_tx_process(), INTERRUPT_MASK, inw, ifec_private::ioaddr, LINK_CHECK_PERIOD, outw, net_device::priv, priv, and SCBStatus.

00401 {
00402         struct ifec_private *priv = netdev->priv;
00403         static int linkpoll = 0;
00404         unsigned short intr_status;
00405 
00406         DBGP ( "ifec_net_poll\n" );
00407 
00408         /* acknowledge interrupts ASAP */
00409         intr_status = inw ( priv->ioaddr + SCBStatus );
00410         outw ( intr_status, priv->ioaddr + SCBStatus );
00411         inw ( priv->ioaddr + SCBStatus );
00412 
00413         DBG2 ( "poll - status: 0x%04X\n", intr_status );
00414 
00415         if ( ++linkpoll > LINK_CHECK_PERIOD ) {
00416                 linkpoll = 0;
00417                 ifec_link_update ( netdev );    /* Update link state */
00418         }
00419 
00420         /* anything to do here? */
00421         if ( ( intr_status & ( ~INTERRUPT_MASK ) ) == 0 )
00422                 return;
00423 
00424         /* process received and transmitted packets */
00425         ifec_tx_process ( netdev );
00426         ifec_rx_process ( netdev );
00427 
00428         ifec_check_ru_status ( netdev, intr_status );
00429 
00430         return;
00431 }

static int ifec_net_transmit ( struct net_device netdev,
struct io_buffer iobuf 
) [static]

Definition at line 442 of file eepro100.c.

References CmdSuspend, CmdTx, CmdTxFlex, ifec_tcb::command, ifec_tcb::count, io_buffer::data, DBG, DBG2, DBGP, ENOBUFS, ifec_tx_wake(), inw, ifec_private::ioaddr, ioaddr, ifec_tcb::iob, iob_len(), ifec_tcb::next, net_device::priv, priv, SCBCmd, ifec_tcb::status, ifec_tcb::tbd_addr0, ifec_tcb::tbd_size0, ifec_private::tcb_head, and virt_to_bus().

00444 {
00445         struct ifec_private *priv = netdev->priv;
00446         struct ifec_tcb *tcb = priv->tcb_head->next;
00447         unsigned long ioaddr = priv->ioaddr;
00448 
00449         DBGP ( "ifec_net_transmit\n" );
00450 
00451         /* Wait for TCB to become available. */
00452         if ( tcb->status || tcb->iob ) {
00453                 DBG ( "TX overflow\n" );
00454                 return -ENOBUFS;
00455         }
00456 
00457         DBG2 ( "transmitting packet (%d bytes). status = %hX, cmd=%hX\n",
00458                 iob_len ( iobuf ), tcb->status, inw ( ioaddr + SCBCmd ) );
00459 
00460         tcb->command   = CmdSuspend | CmdTx | CmdTxFlex;
00461         tcb->count     = 0x01208000;
00462         tcb->tbd_addr0 = virt_to_bus ( iobuf->data );
00463         tcb->tbd_size0 = 0x3FFF & iob_len ( iobuf );
00464         tcb->iob = iobuf;
00465 
00466         ifec_tx_wake ( netdev );
00467 
00468         /* Append to end of ring. */
00469         priv->tcb_head = tcb;
00470 
00471         return 0;
00472 }

static int ifec_spi_read_bit ( struct bit_basher basher,
unsigned int  bit_id 
) [static]

Definition at line 491 of file eepro100.c.

References spi_bit_basher::basher, container_of, CSREeprom, DBGP, inw, ifec_private::ioaddr, priv, and ifec_private::spi.

00493 {
00494         struct ifec_private *priv =
00495                 container_of ( basher, struct ifec_private, spi.basher );
00496         unsigned long ee_addr = priv->ioaddr + CSREeprom;
00497         unsigned int ret = 0;
00498         uint16_t mask;
00499 
00500         DBGP ( "ifec_spi_read_bit\n" );
00501 
00502         mask = ifec_ee_bits[bit_id];
00503         ret = inw (ee_addr);
00504 
00505         return ( ret & mask ) ? 1 : 0;
00506 }

static void ifec_spi_write_bit ( struct bit_basher basher,
unsigned int  bit_id,
unsigned long  data 
) [static]

Definition at line 516 of file eepro100.c.

References spi_bit_basher::basher, container_of, CSREeprom, DBGP, inw, ifec_private::ioaddr, outw, priv, and ifec_private::spi.

00519 {
00520         struct ifec_private *priv =
00521                 container_of ( basher, struct ifec_private, spi.basher );
00522         unsigned long ee_addr = priv->ioaddr + CSREeprom;
00523         short val;
00524         uint16_t mask = ifec_ee_bits[bit_id];
00525 
00526         DBGP ( "ifec_spi_write_bit\n" );
00527 
00528         val = inw ( ee_addr );
00529         val &= ~mask;
00530         val |= data & mask;
00531 
00532         outw ( val, ee_addr );
00533 }

static void ifec_init_eeprom ( struct net_device netdev  )  [static]

Definition at line 546 of file eepro100.c.

References spi_device::address_len, spi_bit_basher::basher, spi_device::bus, spi_bit_basher::bus, DBGP, ifec_private::eeprom, init_spi_bit_basher(), spi_bus::mode, bit_basher::op, net_device::priv, priv, ifec_private::spi, SPI_MODE_THREEWIRE, and threewire_detect_address_len().

Referenced by ifec_pci_probe().

00547 {
00548         struct ifec_private *priv = netdev->priv;
00549 
00550         DBGP ( "ifec_init_eeprom\n" );
00551 
00552         priv->spi.basher.op = &ifec_basher_ops;
00553         priv->spi.bus.mode = SPI_MODE_THREEWIRE;
00554         init_spi_bit_basher ( &priv->spi );
00555 
00556         priv->eeprom.bus = &priv->spi.bus;
00557 
00558         /* init as 93c46(93c14 compatible) first, to set the command len,
00559          * block size and word len. Needs to be set for address len detection.
00560          */
00561         init_at93c46 ( &priv->eeprom, 16 );
00562 
00563         /* detect address length, */
00564         threewire_detect_address_len ( &priv->eeprom );
00565 
00566         /* address len == 8 means 93c66 instead of 93c46 */
00567         if ( priv->eeprom.address_len == 8 )
00568                 init_at93c66 ( &priv->eeprom, 16 );
00569 }

static int ifec_link_check ( struct net_device netdev  )  [static]

Definition at line 577 of file eepro100.c.

References DBGP, ifec_mdio_read(), ifec_private::mdio_register, net_device::priv, and priv.

Referenced by ifec_link_update().

00578 {
00579         struct ifec_private *priv = netdev->priv;
00580         unsigned short mdio_register = priv->mdio_register;
00581 
00582         DBGP ( "ifec_link_check\n" );
00583 
00584         /* Read the status register once to discard stale data */
00585         ifec_mdio_read ( netdev, mdio_register & 0x1f, 1 );
00586         /* Check to see if network cable is plugged in. */
00587         if ( ! ( ifec_mdio_read ( netdev, mdio_register & 0x1f, 1 )
00588                   & ( 1 << 2 ) ) ) {
00589                 return 0;
00590         }
00591         return 1;
00592 }

static void ifec_link_update ( struct net_device netdev  )  [static]

Definition at line 599 of file eepro100.c.

References DBGP, ifec_link_check(), netdev_link_down(), and netdev_link_up().

Referenced by ifec_net_poll(), and ifec_pci_probe().

00600 {
00601         DBGP ( "ifec_link_update\n" );
00602 
00603         /* Update link state */
00604         if ( ifec_link_check ( netdev ) )
00605                 netdev_link_up ( netdev );
00606         else
00607                 netdev_link_down ( netdev );
00608 }

static int ifec_mdio_read ( struct net_device netdev,
int  phy_id,
int  location 
) [static]

Definition at line 616 of file eepro100.c.

References CSRCtrlMDI, DBG, DBGP, inl, ifec_private::ioaddr, ioaddr, outl, net_device::priv, priv, and udelay().

Referenced by ifec_link_check(), and ifec_mdio_setup().

00618 {
00619         struct ifec_private *priv = netdev->priv;
00620         unsigned long ioaddr = priv->ioaddr;
00621         int val;
00622         int boguscnt = 64*4;     /* <64 usec. to complete, typ 27 ticks */
00623 
00624         DBGP ( "ifec_mdio_read\n" );
00625 
00626         outl ( 0x08000000 | ( location << 16 ) | ( phy_id << 21 ),
00627                ioaddr + CSRCtrlMDI );
00628         do {
00629                 udelay ( 16 );
00630 
00631                 val = inl ( ioaddr + CSRCtrlMDI );
00632 
00633                 if ( --boguscnt < 0 ) {
00634                         DBG ( " ifec_mdio_read() time out with val = %X.\n",
00635                                  val );
00636                         break;
00637                 }
00638         } while (! ( val & 0x10000000 ) );
00639         return val & 0xffff;
00640 }

static void ifec_mdio_setup ( struct net_device netdev,
int  options 
) [static]

Definition at line 648 of file eepro100.c.

References CONGENB, DBG2, DBGP, DP83840, DP83840A, ifec_mdio_read(), ifec_mdio_write(), ifec_private::mdio_register, net_device::priv, and priv.

Referenced by ifec_net_open().

00649 {
00650         struct ifec_private *priv = netdev->priv;
00651         unsigned short mdio_register = priv->mdio_register;
00652 
00653         DBGP ( "ifec_mdio_setup\n" );
00654 
00655         if (   ( (mdio_register>>8) & 0x3f ) == DP83840
00656             || ( (mdio_register>>8) & 0x3f ) == DP83840A ) {
00657                 int mdi_reg23 = ifec_mdio_read ( netdev, mdio_register
00658                                                   & 0x1f, 23 ) | 0x0422;
00659                 if (CONGENB)
00660                         mdi_reg23 |= 0x0100;
00661                 DBG2 ( "DP83840 specific setup, setting register 23 to "
00662                                                          "%hX.\n", mdi_reg23 );
00663                 ifec_mdio_write ( netdev, mdio_register & 0x1f, 23, mdi_reg23 );
00664         }
00665         DBG2 ( "dp83840 " );
00666         if ( options != 0 ) {
00667                 ifec_mdio_write ( netdev, mdio_register & 0x1f, 0,
00668                                            ( (options & 0x20) ? 0x2000 : 0 ) |
00669                                            ( (options & 0x10) ? 0x0100 : 0 ) );
00670                 DBG2 ( "set mdio_register. " );
00671         }
00672 }

static int ifec_mdio_write ( struct net_device netdev,
int  phy_id,
int  location,
int  value 
) [static]

Definition at line 680 of file eepro100.c.

References CSRCtrlMDI, DBG, DBGP, inl, ifec_private::ioaddr, ioaddr, outl, net_device::priv, priv, and udelay().

Referenced by ifec_mdio_setup().

00682 {
00683         struct ifec_private *priv = netdev->priv;
00684         unsigned long ioaddr = priv->ioaddr;
00685         int val;
00686         int boguscnt = 64*4;     /* <64 usec. to complete, typ 27 ticks */
00687 
00688         DBGP ( "ifec_mdio_write\n" );
00689 
00690         outl ( 0x04000000 | ( location << 16 ) | ( phy_id << 21 ) | value,
00691                ioaddr + CSRCtrlMDI );
00692         do {
00693                 udelay ( 16 );
00694 
00695                 val = inl ( ioaddr + CSRCtrlMDI );
00696                 if ( --boguscnt < 0 ) {
00697                         DBG ( " ifec_mdio_write() time out with val = %X.\n",
00698                               val );
00699                         break;
00700                 }
00701         } while (! ( val & 0x10000000 ) );
00702         return val & 0xffff;
00703 }

static void ifec_reset ( struct net_device netdev  )  [static]

Definition at line 710 of file eepro100.c.

References CSRPort, DBGP, ifec_net_irq(), inw, ifec_private::ioaddr, ioaddr, outl, PortPartialReset, PortReset, net_device::priv, priv, SCBStatus, and udelay().

Referenced by ifec_net_close(), ifec_net_open(), ifec_pci_probe(), and ifec_pci_remove().

00711 {
00712         struct ifec_private *priv = netdev->priv;
00713         unsigned long ioaddr = priv->ioaddr;
00714 
00715         DBGP ( "ifec_reset\n" );
00716 
00717         /* do partial reset first */
00718         outl ( PortPartialReset, ioaddr + CSRPort );
00719         inw ( ioaddr + SCBStatus );
00720         udelay ( 20 );
00721 
00722         /* full reset */
00723         outl ( PortReset, ioaddr + CSRPort );
00724         inw ( ioaddr + SCBStatus );
00725         udelay ( 20 );
00726 
00727         /* disable interrupts again */
00728         ifec_net_irq ( netdev, 0 );
00729 }

static void ifec_free ( struct net_device netdev  )  [static]

Definition at line 736 of file eepro100.c.

References DBGP, free_dma(), free_iob(), netdev_priv(), NULL, priv, RFD_COUNT, ifec_private::rfds, ifec_private::rx_iobs, ifec_private::tcbs, and TX_RING_BYTES.

Referenced by ifec_net_close(), and ifec_net_open().

00737 {
00738         struct ifec_private *priv = netdev_priv ( netdev );
00739         int i;
00740 
00741         DBGP ( "ifec_free\n" );
00742 
00743         /* free all allocated receive io_buffers */
00744         for ( i = 0; i < RFD_COUNT; i++ ) {
00745                 free_iob ( priv->rx_iobs[i] );
00746                 priv->rx_iobs[i] = NULL;
00747                 priv->rfds[i] = NULL;
00748         }
00749 
00750         /* free TX ring buffer */
00751         free_dma ( priv->tcbs, TX_RING_BYTES );
00752 
00753         priv->tcbs = NULL;
00754 }

static void ifec_rfd_init ( struct ifec_rfd rfd,
s16  command,
u32  link 
) [static]

Definition at line 763 of file eepro100.c.

References ifec_rfd::command, ifec_rfd::count, DBGP, ifec_rfd::link, RFD_PACKET_LEN, ifec_rfd::rx_buf_addr, ifec_rfd::size, and ifec_rfd::status.

Referenced by ifec_get_rx_desc().

00764 {
00765         DBGP ( "ifec_rfd_init\n" );
00766 
00767         rfd->status      = 0;
00768         rfd->command     = command;
00769         rfd->rx_buf_addr = 0xFFFFFFFF;
00770         rfd->count       = 0;
00771         rfd->size        = RFD_PACKET_LEN;
00772         rfd->link        = link;
00773 }

static void ifec_reprime_ru ( struct net_device netdev  )  [static]

Definition at line 780 of file eepro100.c.

References ifec_private::cur_rx, cur_rx, DBGP, ifec_scb_cmd(), ifec_scb_cmd_wait(), NULL, net_device::priv, priv, ifec_private::rfds, RUStart, and virt_to_bus().

Referenced by ifec_check_ru_status().

00781 {
00782         struct ifec_private *priv = netdev->priv;
00783         int cur_rx = priv->cur_rx;
00784         
00785         DBGP ( "ifec_reprime_ru\n" );
00786         
00787         if ( priv->rfds[cur_rx] != NULL ) {
00788                 ifec_scb_cmd ( netdev, virt_to_bus ( priv->rfds[cur_rx] ),
00789                                RUStart );
00790                 ifec_scb_cmd_wait ( netdev );
00791         }
00792 }

static void ifec_check_ru_status ( struct net_device netdev,
unsigned short  intr_status 
) [static]

Definition at line 799 of file eepro100.c.

References DBG, DBGP, ifec_reprime_ru(), inw, ifec_private::ioaddr, net_device::priv, priv, and SCBStatus.

Referenced by ifec_net_poll(), and ifec_refill_rx_ring().

00801 {
00802         struct ifec_private *priv = netdev->priv;
00803 
00804         DBGP ( "ifec_check_ru_status\n" );
00805 
00806         /*
00807         * The chip may have suspended reception for various reasons.
00808         * Check for that, and re-prime it should this be the case.
00809         */
00810         switch ( ( intr_status >> 2 ) & 0xf ) {
00811                 case 0:  /* Idle */
00812                 case 4:  /* Ready */
00813                         break;
00814                 case 1:  /* Suspended */
00815                 case 2:  /* No resources (RFDs) */
00816                 case 9:  /* Suspended with no more RBDs */
00817                 case 10: /* No resources due to no RBDs */
00818                 case 12: /* Ready with no RBDs */
00819                         DBG ( "ifec_net_poll: RU reprimed.\n" );
00820                         ifec_reprime_ru ( netdev );
00821                         break;
00822                 default:
00823                         /* reserved values */
00824                         DBG ( "ifec_net_poll: RU state anomaly: %i\n",
00825                               ( inw ( priv->ioaddr + SCBStatus ) >> 2 ) & 0xf );
00826                         break;
00827         }
00828 }

static void ifec_rx_process ( struct net_device netdev  )  [static]

Definition at line 838 of file eepro100.c.

References ifec_rfd::count, ifec_private::cur_rx, cur_rx, DBG, DBG2, DBGIO_HD, DBGP, EINVAL, ifec_refill_rx_ring(), iob_put, netdev_rx(), netdev_rx_err(), NULL, ifec_rfd::packet, net_device::priv, priv, RFD_COUNT, RFD_OK, RFD_STATUS, RFDMaskCount, ifec_private::rfds, ifec_private::rx_iobs, and ifec_rfd::status.

Referenced by ifec_net_poll().

00839 {
00840         struct ifec_private *priv   = netdev->priv;
00841         int cur_rx = priv->cur_rx;
00842         struct io_buffer *iob = priv->rx_iobs[cur_rx];
00843         struct ifec_rfd *rfd = priv->rfds[cur_rx];
00844         unsigned int rx_len;
00845         s16 status;
00846 
00847         DBGP ( "ifec_rx_process\n" );
00848 
00849         /* Process any received packets */
00850         while ( iob && rfd && ( status = rfd->status ) ) {
00851                 rx_len = rfd->count & RFDMaskCount;
00852 
00853                 DBG2 ( "Got a packet: Len = %d, cur_rx = %d.\n", rx_len,
00854                        cur_rx );
00855                 DBGIO_HD ( (void*)rfd->packet, 0x30 );
00856 
00857                 if ( ( status & RFD_STATUS ) != RFD_OK ) {
00858                         DBG ( "Corrupted packet received. "
00859                               "Status = %#08hx\n", status );
00860                         netdev_rx_err ( netdev, iob, -EINVAL );
00861                 } else {
00862                         /* Hand off the packet to the network subsystem */
00863                         iob_put ( iob, rx_len );
00864                         DBG2 ( "Received packet: %p, len: %d\n", iob, rx_len );
00865                         netdev_rx ( netdev, iob );
00866                 }
00867 
00868                 /* make sure we don't reuse this RFD */
00869                 priv->rx_iobs[cur_rx] = NULL;
00870                 priv->rfds[cur_rx] = NULL;
00871 
00872                 /* Next RFD */
00873                 priv->cur_rx = ( cur_rx + 1 ) % RFD_COUNT;
00874                 cur_rx = priv->cur_rx;
00875                 iob = priv->rx_iobs[cur_rx];
00876                 rfd = priv->rfds[cur_rx];
00877         }
00878 
00879         ifec_refill_rx_ring ( netdev );
00880 }

static int ifec_get_rx_desc ( struct net_device netdev,
int  cur,
int  cmd,
int  link 
) [static]

Definition at line 892 of file eepro100.c.

References alloc_iob(), io_buffer::data, DBG, DBGP, ENOMEM, ifec_rfd_init(), iob_reserve, NULL, net_device::priv, priv, RFD_HEADER_LEN, ifec_private::rfds, and ifec_private::rx_iobs.

Referenced by ifec_refill_rx_ring().

00894 {
00895         struct ifec_private *priv = netdev->priv;
00896         struct ifec_rfd *rfd  = priv->rfds[cur];
00897 
00898         DBGP ( "ifec_get_rx_desc\n" );
00899 
00900         priv->rx_iobs[cur] = alloc_iob ( sizeof ( *rfd ) );
00901         if ( ! priv->rx_iobs[cur] ) {
00902                 DBG ( "alloc_iob failed. desc. nr: %d\n", cur );
00903                 priv->rfds[cur] = NULL;
00904                 return -ENOMEM;
00905         }
00906 
00907         /* Initialize new tail. */
00908         priv->rfds[cur] = priv->rx_iobs[cur]->data;
00909         ifec_rfd_init ( priv->rfds[cur], cmd, link );
00910         iob_reserve ( priv->rx_iobs[cur], RFD_HEADER_LEN );
00911 
00912         return 0;
00913 }

static void ifec_refill_rx_ring ( struct net_device netdev  )  [static]

Definition at line 920 of file eepro100.c.

References CmdEndOfList, CmdSuspend, ifec_rfd::command, ifec_private::cur_rx, cur_rx, DBG2, DBGP, ifec_check_ru_status(), ifec_get_rx_desc(), inw, ifec_private::ioaddr, ifec_rfd::link, NULL, net_device::priv, priv, RFD_COUNT, ifec_private::rfds, ifec_private::rx_iobs, SCBStatus, and virt_to_bus().

Referenced by ifec_rx_process(), and ifec_rx_setup().

00921 {
00922         struct ifec_private *priv = netdev->priv;
00923         int i, cur_rx;
00924         unsigned short intr_status;
00925 
00926         DBGP ( "ifec_refill_rx_ring\n" );
00927 
00928         for ( i = 0; i < RFD_COUNT; i++ ) {
00929                 cur_rx = ( priv->cur_rx + i ) % RFD_COUNT;
00930                 /* only refill if empty */
00931                 if ( priv->rfds[cur_rx] != NULL ||
00932                      priv->rx_iobs[cur_rx] != NULL )
00933                         continue;
00934 
00935                 DBG2 ( "refilling RFD %d\n", cur_rx );
00936 
00937                 if ( ifec_get_rx_desc ( netdev, cur_rx,
00938                      CmdSuspend | CmdEndOfList, 0 ) == 0 ) {
00939                         if ( i > 0 ) {
00940                                 int prev_rx = ( ( ( cur_rx + RFD_COUNT ) - 1 )
00941                                                 % RFD_COUNT );
00942                                 struct ifec_rfd *rfd = priv->rfds[prev_rx];
00943 
00944                                 rfd->command = 0;
00945                                 rfd->link = virt_to_bus ( priv->rfds[cur_rx] );
00946                         }
00947                 }
00948         }
00949 
00950         intr_status = inw ( priv->ioaddr + SCBStatus );
00951         ifec_check_ru_status ( netdev, intr_status );
00952 }

static int ifec_rx_setup ( struct net_device netdev  )  [static]

Definition at line 960 of file eepro100.c.

References ifec_private::cur_rx, DBGP, ifec_refill_rx_ring(), NULL, net_device::priv, priv, RFD_COUNT, ifec_private::rfds, and ifec_private::rx_iobs.

Referenced by ifec_net_open().

00961 {
00962         struct ifec_private *priv = netdev->priv;
00963         int i;
00964 
00965         DBGP ( "ifec_rx_setup\n" );
00966 
00967         priv->cur_rx = 0;
00968 
00969         /* init values for ifec_refill_rx_ring() */
00970         for ( i = 0; i < RFD_COUNT; i++ ) {
00971                 priv->rfds[i] = NULL;
00972                 priv->rx_iobs[i] = NULL;
00973         }
00974         ifec_refill_rx_ring ( netdev );
00975 
00976         return 0;
00977 }

static int ifec_scb_cmd ( struct net_device netdev,
u32  ptr,
u8  cmd 
) [static]

Definition at line 987 of file eepro100.c.

References DBGP, ifec_scb_cmd_wait(), ifec_private::ioaddr, ioaddr, outb, outl, net_device::priv, priv, SCBCmd, and SCBPointer.

Referenced by ifec_net_open(), ifec_reprime_ru(), and ifec_tx_wake().

00988 {
00989         struct ifec_private *priv = netdev->priv;
00990         unsigned long ioaddr = priv->ioaddr;
00991         int rc;
00992 
00993         DBGP ( "ifec_scb_cmd\n" );
00994 
00995         rc = ifec_scb_cmd_wait ( netdev );      /* Wait until ready */
00996         if ( !rc ) {
00997                 outl ( ptr, ioaddr + SCBPointer );
00998                 outb ( cmd, ioaddr + SCBCmd );          /* Issue command */
00999         }
01000         return rc;
01001 }

static int ifec_scb_cmd_wait ( struct net_device netdev  )  [static]

Definition at line 1009 of file eepro100.c.

References CU_CMD_TIMEOUT, DBG, DBGP, inb, ifec_private::ioaddr, net_device::priv, priv, SCBCmd, and udelay().

Referenced by ifec_net_open(), ifec_reprime_ru(), ifec_scb_cmd(), and ifec_tx_wake().

01010 {
01011         struct ifec_private *priv = netdev->priv;
01012         unsigned long cmd_ioaddr = priv->ioaddr + SCBCmd;
01013         int rc, wait = CU_CMD_TIMEOUT;
01014 
01015         DBGP ( "ifec_scb_cmd_wait\n" );
01016 
01017         for ( ; wait && ( rc = inb ( cmd_ioaddr ) ); wait-- )
01018                 udelay ( 1 );
01019 
01020         if ( !wait )
01021                 DBG ( "ifec_scb_cmd_wait timeout!\n" );
01022         return rc;
01023 }

static void ifec_tx_process ( struct net_device netdev  )  [static]

Definition at line 1030 of file eepro100.c.

References DBG, DBG2, DBGP, EINVAL, ifec_tcb::iob, netdev_tx_complete(), netdev_tx_complete_err(), ifec_tcb::next, NULL, net_device::priv, priv, ifec_tcb::status, ifec_private::tcb_tail, and TCB_U.

Referenced by ifec_net_poll().

01031 {
01032         struct ifec_private *priv = netdev->priv;
01033         struct ifec_tcb *tcb = priv->tcb_tail;
01034         s16 status;
01035 
01036         DBGP ( "ifec_tx_process\n" );
01037 
01038         /* Check status of transmitted packets */
01039         while ( ( status = tcb->status ) && tcb->iob ) {
01040                 if ( status & TCB_U ) {
01041                         /* report error to gPXE */
01042                         DBG ( "ifec_tx_process : tx error!\n " );
01043                         netdev_tx_complete_err ( netdev, tcb->iob, -EINVAL );
01044                 } else {
01045                         /* report successful transmit */
01046                         netdev_tx_complete ( netdev, tcb->iob );
01047                 }
01048                 DBG2 ( "tx completion\n" );
01049 
01050                 tcb->iob = NULL;
01051                 tcb->status = 0;
01052 
01053                 priv->tcb_tail = tcb->next;     /* Next TCB */
01054                 tcb = tcb->next;
01055         }
01056 }

static int ifec_tx_setup ( struct net_device netdev  )  [static]

Definition at line 1064 of file eepro100.c.

References CB_ALIGN, ifec_tcb::count, DBG, DBGP, ENOMEM, ifec_tcb::iob, ifec_tcb::link, malloc_dma(), ifec_tcb::next, NULL, net_device::priv, priv, ifec_tcb::status, ifec_tcb::tbd_addr0, ifec_tcb::tbda_addr, TCB_COUNT, ifec_private::tcb_head, ifec_private::tcb_tail, ifec_private::tcbs, ifec_private::tx_cnt, ifec_private::tx_curr, TX_RING_BYTES, ifec_private::tx_tail, and virt_to_bus().

Referenced by ifec_net_open().

01065 {
01066         struct ifec_private *priv = netdev->priv;
01067         struct ifec_tcb *tcb;
01068         int i;
01069 
01070         DBGP ( "ifec_tx_setup\n" );
01071 
01072         /* allocate tx ring */
01073         priv->tcbs = malloc_dma ( TX_RING_BYTES, CB_ALIGN );
01074         if ( !priv->tcbs ) {
01075                 DBG ( "TX-ring allocation failed\n" );
01076                 return -ENOMEM;
01077         }
01078 
01079         tcb = priv->tcb_tail = priv->tcbs;
01080         priv->tx_curr = priv->tx_tail = 0;
01081         priv->tx_cnt = 0;
01082 
01083         for ( i = 0; i < TCB_COUNT; i++, tcb++ ) {
01084                 tcb->status    = 0;
01085                 tcb->count     = 0x01208000;
01086                 tcb->iob       = NULL;
01087                 tcb->tbda_addr = virt_to_bus ( &tcb->tbd_addr0 );
01088                 tcb->link      = virt_to_bus ( tcb + 1 );
01089                 tcb->next      = tcb + 1;
01090         }
01091         /* We point tcb_head at the last TCB, so the first ifec_net_transmit()
01092          * will use the first (head->next) TCB to transmit. */
01093         priv->tcb_head = --tcb;
01094         tcb->link = virt_to_bus ( priv->tcbs );
01095         tcb->next = priv->tcbs;
01096         
01097         return 0;
01098 }

void ifec_tx_wake ( struct net_device netdev  ) 

Definition at line 1117 of file eepro100.c.

References CmdSuspend, ifec_tcb::command, ifec_private::configured, CUResume, CUStart, DBG2, DBGP, ifec_scb_cmd(), ifec_scb_cmd_wait(), inw, ifec_private::ioaddr, ioaddr, ifec_tcb::next, outb, outl, net_device::priv, priv, SCBCmd, SCBPointer, SCBStatus, ifec_private::tcb_head, and virt_to_bus().

Referenced by ifec_net_transmit().

01118 {
01119         struct ifec_private *priv = netdev->priv;
01120         unsigned long ioaddr = priv->ioaddr;
01121         struct ifec_tcb *tcb = priv->tcb_head->next;
01122 
01123         DBGP ( "ifec_tx_wake\n" );
01124 
01125         /* For the special case of the first transmit, we issue a START. The
01126          * card won't RESUME after the configure command. */
01127         if ( priv->configured ) {
01128                 priv->configured = 0;
01129                 ifec_scb_cmd ( netdev, virt_to_bus ( tcb ), CUStart );
01130                 ifec_scb_cmd_wait ( netdev );
01131                 return;
01132         }
01133 
01134         /* Resume if suspended. */
01135         switch ( ( inw ( ioaddr + SCBStatus ) >> 6 ) & 0x3 ) {
01136         case 0:  /* Idle - We should not reach this state. */
01137                 DBG2 ( "ifec_tx_wake: tx idle!\n" );
01138                 ifec_scb_cmd ( netdev, virt_to_bus ( tcb ), CUStart );
01139                 ifec_scb_cmd_wait ( netdev );
01140                 return;
01141         case 1:  /* Suspended */
01142                 DBG2 ( "s" );
01143                 break;
01144         default: /* Active */
01145                 DBG2 ( "a" );
01146         }
01147         ifec_scb_cmd_wait ( netdev );
01148         outl ( 0, ioaddr + SCBPointer );
01149         priv->tcb_head->command &= ~CmdSuspend;
01150         /* Immediately issue Resume command */
01151         outb ( CUResume, ioaddr + SCBCmd );
01152         ifec_scb_cmd_wait ( netdev );
01153 }


Variable Documentation

struct ifec_cfg ifec_cfg [static]

Initial value:

 {
        .status  = 0,
        .command = CmdConfigure | CmdSuspend,
        .link    = 0,        
        .byte = { 22,        
                  ( TX_FIFO << 4 ) | RX_FIFO,  
                  0, 0,                        
                  RX_DMA_COUNT,                
                  TX_DMA_COUNT + 0x80,         
                  0x32,      
                  0x03,      
                  1,         
                  0,
                  0x2E,      
                  0,         
                  0x60,      
                  0, 0xf2,
                  0x48,      
                  0, 0x40,
                  0xf2,      
                  0x80,      
                  0x3f,      
                  0x0D }     
}

Definition at line 125 of file eepro100.c.

Initial value:

 {
        .open     = ifec_net_open,
        .close    = ifec_net_close,
        .transmit = ifec_net_transmit,
        .poll     = ifec_net_poll,
        .irq      = ifec_net_irq
}

Definition at line 150 of file eepro100.c.

const uint16_t ifec_ee_bits[] [static]

Initial value:

Definition at line 477 of file eepro100.c.

Initial value:

 {
        .read = ifec_spi_read_bit,
        .write = ifec_spi_write_bit,
}

Definition at line 536 of file eepro100.c.

struct pci_device_id ifec_nics[] [static]

Definition at line 1157 of file eepro100.c.

struct pci_driver ifec_driver __pci_driver

Initial value:

 {
        .ids      = ifec_nics,
        .id_count = ( sizeof (ifec_nics) / sizeof (ifec_nics[0]) ),
        .probe    = ifec_pci_probe,
        .remove   = ifec_pci_remove
}

Definition at line 1194 of file eepro100.c.


Generated on Tue Apr 6 20:01:31 2010 for gPXE by  doxygen 1.5.7.1