rtl8139.c File Reference

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gpxe/io.h>
#include <errno.h>
#include <unistd.h>
#include <byteswap.h>
#include <gpxe/pci.h>
#include <gpxe/if_ether.h>
#include <gpxe/ethernet.h>
#include <gpxe/iobuf.h>
#include <gpxe/netdevice.h>
#include <gpxe/spi_bit.h>
#include <gpxe/threewire.h>
#include <gpxe/nvo.h>

Go to the source code of this file.

Data Structures

struct  rtl8139_tx
struct  rtl8139_rx
struct  rtl8139_nic

Defines

#define TX_RING_SIZE   4
#define TX_FIFO_THRESH   256
#define RX_FIFO_THRESH   4
#define RX_DMA_BURST   4
#define TX_DMA_BURST   4
#define TX_IPG   3
#define RX_BUF_LEN_IDX   0
#define RX_BUF_LEN   ( (8192 << RX_BUF_LEN_IDX) )
#define RX_BUF_PAD   4
#define EE_M1   0x80
#define EE_M0   0x40
#define EE_CS   0x08
#define EE_SK   0x04
#define EE_DI   0x02
#define EE_DO   0x01
#define EE_MAC   7

Enumerations

enum  RTL8139_registers {
  MAC0 = 0, MAR0 = 8, TxStatus0 = 0x10, TxAddr0 = 0x20,
  RxBuf = 0x30, RxEarlyCnt = 0x34, RxEarlyStatus = 0x36, ChipCmd = 0x37,
  RxBufPtr = 0x38, RxBufAddr = 0x3A, IntrMask = 0x3C, IntrStatus = 0x3E,
  TxConfig = 0x40, RxConfig = 0x44, Timer = 0x48, RxMissed = 0x4C,
  Cfg9346 = 0x50, Config0 = 0x51, Config1 = 0x52, TimerIntrReg = 0x54,
  MediaStatus = 0x58, Config3 = 0x59, MultiIntr = 0x5C, RevisionID = 0x5E,
  TxSummary = 0x60, MII_BMCR = 0x62, MII_BMSR = 0x64, NWayAdvert = 0x66,
  NWayLPAR = 0x68, NWayExpansion = 0x6A, DisconnectCnt = 0x6C, FalseCarrierCnt = 0x6E,
  NWayTestReg = 0x70, RxCnt = 0x72, CSCR = 0x74, PhyParm1 = 0x78,
  TwisterParm = 0x7c, PhyParm2 = 0x80
}
enum  RxEarlyStatusBits { ERGood = 0x08, ERBad = 0x04, EROVW = 0x02, EROK = 0x01 }
enum  ChipCmdBits {
  ChipReset = 0x100, RxReset = 0x20, TxReset = 0x10, RxOff = 0x08,
  RxOn = 0x04, TxOff = 0x02, TxOn = 0x01, CmdReset = 0x10,
  CmdRxEnb = 0x08, CmdTxEnb = 0x04, RxBufEmpty = 0x01
}
enum  IntrMaskBits {
  SERR = 0x8000, TimeOut = 0x4000, LenChg = 0x2000, FOVW = 0x40,
  PUN_LinkChg = 0x20, RXOVW = 0x10, TER = 0x08, TOK = 0x04,
  RER = 0x02, ROK = 0x01
}
enum  IntrStatusBits {
  PCIErr = 0x8000, PCSTimeout = 0x4000, CableLenChange = 0x2000, RxFIFOOver = 0x40,
  RxUnderrun = 0x20, RxOverflow = 0x10, TxErr = 0x08, TxOK = 0x04,
  RxErr = 0x02, RxOK = 0x01
}
enum  TxStatusBits {
  TxHostOwns = 0x2000, TxUnderrun = 0x4000, TxStatOK = 0x8000, TxOutOfWindow = 0x20000000,
  TxAborted = 0x40000000, TxCarrierLost = 0x80000000
}
enum  RxStatusBits {
  RxMulticast = 0x8000, RxPhysical = 0x4000, RxBroadcast = 0x2000, RxBadSymbol = 0x0020,
  RxRunt = 0x0010, RxTooLong = 0x0008, RxCRCErr = 0x0004, RxBadAlign = 0x0002,
  RxStatusOK = 0x0001
}
enum  MediaStatusBits {
  MSRTxFlowEnable = 0x80, MSRRxFlowEnable = 0x40, MSRSpeed10 = 0x08, MSRLinkFail = 0x04,
  MSRRxPauseFlag = 0x02, MSRTxPauseFlag = 0x01
}
enum  MIIBMCRBits {
  BMCRReset = 0x8000, BMCRSpeed100 = 0x2000, BMCRNWayEnable = 0x1000, BMCRRestartNWay = 0x0200,
  BMCRDuplex = 0x0100
}
enum  CSCRBits {
  CSCR_LinkOKBit = 0x0400, CSCR_LinkChangeBit = 0x0800, CSCR_LinkStatusBits = 0x0f000, CSCR_LinkDownOffCmd = 0x003c0,
  CSCR_LinkDownCmd = 0x0f3c0
}
enum  RxConfigBits {
  RxCfgWrap = 0x80, Eeprom9356 = 0x40, AcceptErr = 0x20, AcceptRunt = 0x10,
  AcceptBroadcast = 0x08, AcceptMulticast = 0x04, AcceptMyPhys = 0x02, AcceptAllPhys = 0x01
}
enum  Config1Bits { VPDEnable = 0x02 }

Functions

 FILE_LICENCE (GPL_ANY)
static int rtl_spi_read_bit (struct bit_basher *basher, unsigned int bit_id)
static void rtl_spi_write_bit (struct bit_basher *basher, unsigned int bit_id, unsigned long data)
static void rtl_init_eeprom (struct net_device *netdev)
 Set up for EEPROM access.
static void rtl_reset (struct net_device *netdev)
 Reset NIC.
static int rtl_open (struct net_device *netdev)
 Open NIC.
static void rtl_close (struct net_device *netdev)
 Close NIC.
static int rtl_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static void rtl_poll (struct net_device *netdev)
 Poll for received packets.
static void rtl_irq (struct net_device *netdev, int enable)
 Enable/disable interrupts.
static int rtl_probe (struct pci_device *pci, const struct pci_device_id *id __unused)
 Probe PCI device.
static void rtl_remove (struct pci_device *pci)
 Remove PCI device.

Variables

static const uint8_t rtl_ee_bits []
static struct bit_basher_operations rtl_basher_ops
static struct nvo_fragment rtl_nvo_fragments []
 Portion of EEPROM available for non-volatile stored options.
static struct net_device_operations rtl_operations
 RTL8139 net device operations.
static struct pci_device_id rtl8139_nics []
struct pci_driver rtl8139_driver __pci_driver


Define Documentation

#define TX_RING_SIZE   4

Definition at line 88 of file rtl8139.c.

#define TX_FIFO_THRESH   256

Definition at line 110 of file rtl8139.c.

#define RX_FIFO_THRESH   4

Definition at line 111 of file rtl8139.c.

#define RX_DMA_BURST   4

Definition at line 112 of file rtl8139.c.

#define TX_DMA_BURST   4

Definition at line 113 of file rtl8139.c.

#define TX_IPG   3

Definition at line 114 of file rtl8139.c.

Referenced by rtl_open().

#define RX_BUF_LEN_IDX   0

Definition at line 115 of file rtl8139.c.

Referenced by rtl_open().

#define RX_BUF_LEN   ( (8192 << RX_BUF_LEN_IDX) )

Definition at line 116 of file rtl8139.c.

#define RX_BUF_PAD   4

Definition at line 117 of file rtl8139.c.

Referenced by rtl_open().

#define EE_M1   0x80

Definition at line 207 of file rtl8139.c.

#define EE_M0   0x40

Definition at line 208 of file rtl8139.c.

#define EE_CS   0x08

Definition at line 209 of file rtl8139.c.

#define EE_SK   0x04

Definition at line 210 of file rtl8139.c.

#define EE_DI   0x02

Definition at line 211 of file rtl8139.c.

#define EE_DO   0x01

Definition at line 212 of file rtl8139.c.

#define EE_MAC   7

Definition at line 215 of file rtl8139.c.


Enumeration Type Documentation

Enumerator:
MAC0 
MAR0 
TxStatus0 
TxAddr0 
RxBuf 
RxEarlyCnt 
RxEarlyStatus 
ChipCmd 
RxBufPtr 
RxBufAddr 
IntrMask 
IntrStatus 
TxConfig 
RxConfig 
Timer 
RxMissed 
Cfg9346 
Config0 
Config1 
TimerIntrReg 
MediaStatus 
Config3 
MultiIntr 
RevisionID 
TxSummary 
MII_BMCR 
MII_BMSR 
NWayAdvert 
NWayLPAR 
NWayExpansion 
DisconnectCnt 
FalseCarrierCnt 
NWayTestReg 
RxCnt 
CSCR 
PhyParm1 
TwisterParm 
PhyParm2 

Definition at line 120 of file rtl8139.c.

00120                        {
00121         MAC0=0,                 /* Ethernet hardware address. */
00122         MAR0=8,                 /* Multicast filter. */
00123         TxStatus0=0x10,         /* Transmit status (four 32bit registers). */
00124         TxAddr0=0x20,           /* Tx descriptors (also four 32bit). */
00125         RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
00126         ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
00127         IntrMask=0x3C, IntrStatus=0x3E,
00128         TxConfig=0x40, RxConfig=0x44,
00129         Timer=0x48,             /* general-purpose counter. */
00130         RxMissed=0x4C,          /* 24 bits valid, write clears. */
00131         Cfg9346=0x50, Config0=0x51, Config1=0x52,
00132         TimerIntrReg=0x54,      /* intr if gp counter reaches this value */
00133         MediaStatus=0x58,
00134         Config3=0x59,
00135         MultiIntr=0x5C,
00136         RevisionID=0x5E,        /* revision of the RTL8139 chip */
00137         TxSummary=0x60,
00138         MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
00139         NWayExpansion=0x6A,
00140         DisconnectCnt=0x6C, FalseCarrierCnt=0x6E,
00141         NWayTestReg=0x70,
00142         RxCnt=0x72,             /* packet received counter */
00143         CSCR=0x74,              /* chip status and configuration register */
00144         PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80,   /* undocumented */
00145         /* from 0x84 onwards are a number of power management/wakeup frame
00146          * definitions we will probably never need to know about.  */
00147 };

Enumerator:
ERGood 
ERBad 
EROVW 
EROK 

Definition at line 149 of file rtl8139.c.

00149                        {
00150         ERGood=0x08, ERBad=0x04, EROVW=0x02, EROK=0x01
00151 };

Enumerator:
ChipReset 
RxReset 
TxReset 
RxOff 
RxOn 
TxOff 
TxOn 
CmdReset 
CmdRxEnb 
CmdTxEnb 
RxBufEmpty 

Definition at line 153 of file rtl8139.c.

00153                  {
00154         CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };

Enumerator:
SERR 
TimeOut 
LenChg 
FOVW 
PUN_LinkChg 
RXOVW 
TER 
TOK 
RER 
ROK 

Definition at line 156 of file rtl8139.c.

00156                   {
00157         SERR=0x8000, TimeOut=0x4000, LenChg=0x2000,
00158         FOVW=0x40, PUN_LinkChg=0x20, RXOVW=0x10,
00159         TER=0x08, TOK=0x04, RER=0x02, ROK=0x01
00160 };

Enumerator:
PCIErr 
PCSTimeout 
CableLenChange 
RxFIFOOver 
RxUnderrun 
RxOverflow 
TxErr 
TxOK 
RxErr 
RxOK 

Definition at line 163 of file rtl8139.c.

00163                     {
00164         PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
00165         RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
00166         TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
00167 };

Enumerator:
TxHostOwns 
TxUnderrun 
TxStatOK 
TxOutOfWindow 
TxAborted 
TxCarrierLost 

Definition at line 168 of file rtl8139.c.

00168                   {
00169         TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
00170         TxOutOfWindow=0x20000000, TxAborted=0x40000000,
00171         TxCarrierLost=0x80000000,
00172 };

Enumerator:
RxMulticast 
RxPhysical 
RxBroadcast 
RxBadSymbol 
RxRunt 
RxTooLong 
RxCRCErr 
RxBadAlign 
RxStatusOK 

Definition at line 173 of file rtl8139.c.

00173                   {
00174         RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
00175         RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
00176         RxBadAlign=0x0002, RxStatusOK=0x0001,
00177 };

Enumerator:
MSRTxFlowEnable 
MSRRxFlowEnable 
MSRSpeed10 
MSRLinkFail 
MSRRxPauseFlag 
MSRTxPauseFlag 

Definition at line 179 of file rtl8139.c.

00179                      {
00180         MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08,
00181         MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01,
00182 };

Enumerator:
BMCRReset 
BMCRSpeed100 
BMCRNWayEnable 
BMCRRestartNWay 
BMCRDuplex 

Definition at line 184 of file rtl8139.c.

00184                  {
00185         BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000,
00186         BMCRRestartNWay=0x0200, BMCRDuplex=0x0100,
00187 };

enum CSCRBits

Enumerator:
CSCR_LinkOKBit 
CSCR_LinkChangeBit 
CSCR_LinkStatusBits 
CSCR_LinkDownOffCmd 
CSCR_LinkDownCmd 

Definition at line 189 of file rtl8139.c.

00189               {
00190         CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
00191         CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
00192         CSCR_LinkDownCmd=0x0f3c0,
00193 };

Enumerator:
RxCfgWrap 
Eeprom9356 
AcceptErr 
AcceptRunt 
AcceptBroadcast 
AcceptMulticast 
AcceptMyPhys 
AcceptAllPhys 

Definition at line 195 of file rtl8139.c.

00195                   {
00196         RxCfgWrap=0x80,
00197         Eeprom9356=0x40,
00198         AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
00199         AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
00200 };

Enumerator:
VPDEnable 

Definition at line 202 of file rtl8139.c.

00202                  {
00203         VPDEnable=0x02,
00204 };


Function Documentation

FILE_LICENCE ( GPL_ANY   ) 

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

Definition at line 224 of file rtl8139.c.

References spi_bit_basher::basher, Cfg9346, container_of, inb, rtl8139_nic::ioaddr, rtl_ee_bits, and rtl8139_nic::spibit.

00225                                                     {
00226         struct rtl8139_nic *rtl = container_of ( basher, struct rtl8139_nic,
00227                                                  spibit.basher );
00228         uint8_t mask = rtl_ee_bits[bit_id];
00229         uint8_t eereg;
00230 
00231         eereg = inb ( rtl->ioaddr + Cfg9346 );
00232         return ( eereg & mask );
00233 }

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

Definition at line 235 of file rtl8139.c.

References spi_bit_basher::basher, Cfg9346, container_of, inb, rtl8139_nic::ioaddr, outb, rtl_ee_bits, and rtl8139_nic::spibit.

00236                                                                           {
00237         struct rtl8139_nic *rtl = container_of ( basher, struct rtl8139_nic,
00238                                                  spibit.basher );
00239         uint8_t mask = rtl_ee_bits[bit_id];
00240         uint8_t eereg;
00241 
00242         eereg = inb ( rtl->ioaddr + Cfg9346 );
00243         eereg &= ~mask;
00244         eereg |= ( data & mask );
00245         outb ( eereg, rtl->ioaddr + Cfg9346 );
00246 }

static void rtl_init_eeprom ( struct net_device netdev  )  [static]

Set up for EEPROM access.

Parameters:
netdev Net device

Definition at line 269 of file rtl8139.c.

References spi_bit_basher::basher, spi_device::bus, spi_bit_basher::bus, Config1, DBGC, rtl8139_nic::eeprom, Eeprom9356, init_spi_bit_basher(), inw, rtl8139_nic::ioaddr, spi_bus::mode, rtl8139_nic::nvo, nvo_init(), spi_device::nvs, bit_basher::op, net_device::priv, net_device::refcnt, RxConfig, SPI_MODE_THREEWIRE, rtl8139_nic::spibit, and VPDEnable.

Referenced by rtl_probe().

00269                                                           {
00270         struct rtl8139_nic *rtl = netdev->priv;
00271         int ee9356;
00272         int vpd;
00273 
00274         /* Initialise three-wire bus */
00275         rtl->spibit.basher.op = &rtl_basher_ops;
00276         rtl->spibit.bus.mode = SPI_MODE_THREEWIRE;
00277         init_spi_bit_basher ( &rtl->spibit );
00278 
00279         /* Detect EEPROM type and initialise three-wire device */
00280         ee9356 = ( inw ( rtl->ioaddr + RxConfig ) & Eeprom9356 );
00281         if ( ee9356 ) {
00282                 DBGC ( rtl, "rtl8139 %p EEPROM is an AT93C56\n", rtl );
00283                 init_at93c56 ( &rtl->eeprom, 16 );
00284         } else {
00285                 DBGC ( rtl, "rtl8139 %p EEPROM is an AT93C46\n", rtl );
00286                 init_at93c46 ( &rtl->eeprom, 16 );
00287         }
00288         rtl->eeprom.bus = &rtl->spibit.bus;
00289 
00290         /* Initialise space for non-volatile options, if available */
00291         vpd = ( inw ( rtl->ioaddr + Config1 ) & VPDEnable );
00292         if ( vpd ) {
00293                 DBGC ( rtl, "rtl8139 %p EEPROM in use for VPD; cannot use "
00294                        "for options\n", rtl );
00295         } else {
00296                 nvo_init ( &rtl->nvo, &rtl->eeprom.nvs, rtl_nvo_fragments,
00297                            &netdev->refcnt );
00298         }
00299 }

static void rtl_reset ( struct net_device netdev  )  [static]

Reset NIC.

Parameters:
netdev Net device
Issues a hardware reset and waits for the reset to complete.

Definition at line 308 of file rtl8139.c.

References ChipCmd, CmdReset, rtl8139_nic::ioaddr, mdelay(), memset(), rtl8139_rx::offset, outb, net_device::priv, rtl8139_nic::rx, and rtl8139_nic::tx.

Referenced by rtl_close(), rtl_probe(), and rtl_remove().

00308                                                     {
00309         struct rtl8139_nic *rtl = netdev->priv;
00310 
00311         /* Reset chip */
00312         outb ( CmdReset, rtl->ioaddr + ChipCmd );
00313         mdelay ( 10 );
00314         memset ( &rtl->tx, 0, sizeof ( rtl->tx ) );
00315         rtl->rx.offset = 0;
00316 }

static int rtl_open ( struct net_device netdev  )  [static]

Open NIC.

Parameters:
netdev Net device
Return values:
rc Return status code

Definition at line 324 of file rtl8139.c.

References AcceptBroadcast, AcceptMulticast, AcceptMyPhys, ChipCmd, CmdRxEnb, CmdTxEnb, DBGC, ENOMEM, ETH_ALEN, rtl8139_nic::ioaddr, net_device::ll_addr, MAC0, malloc(), MAR0, outb, outl, net_device::priv, rtl8139_rx::ring, rtl8139_nic::rx, RX_BUF_LEN, RX_BUF_LEN_IDX, RX_BUF_PAD, RX_DMA_BURST, RX_FIFO_THRESH, RxBuf, RxConfig, TX_DMA_BURST, TX_IPG, TxConfig, and virt_to_bus().

00324                                                   {
00325         struct rtl8139_nic *rtl = netdev->priv;
00326         int i;
00327 
00328         /* Program the MAC address */
00329         for ( i = 0 ; i < ETH_ALEN ; i++ )
00330                 outb ( netdev->ll_addr[i], rtl->ioaddr + MAC0 + i );
00331 
00332         /* Set up RX ring */
00333         rtl->rx.ring = malloc ( RX_BUF_LEN + RX_BUF_PAD );
00334         if ( ! rtl->rx.ring )
00335                 return -ENOMEM;
00336         outl ( virt_to_bus ( rtl->rx.ring ), rtl->ioaddr + RxBuf );
00337         DBGC ( rtl, "rtl8139 %p RX ring at %lx\n",
00338                rtl, virt_to_bus ( rtl->rx.ring ) );
00339 
00340         /* Enable TX and RX */
00341         outb ( ( CmdRxEnb | CmdTxEnb ), rtl->ioaddr + ChipCmd );
00342         outl ( ( ( RX_FIFO_THRESH << 13 ) | ( RX_BUF_LEN_IDX << 11 ) |
00343                  ( RX_DMA_BURST << 8 ) | AcceptBroadcast | AcceptMulticast |
00344                  AcceptMyPhys ), rtl->ioaddr + RxConfig );
00345         outl ( 0xffffffffUL, rtl->ioaddr + MAR0 + 0 );
00346         outl ( 0xffffffffUL, rtl->ioaddr + MAR0 + 4 );
00347         outl ( ( ( TX_DMA_BURST << 8 ) | ( TX_IPG << 24 ) ),
00348                rtl->ioaddr + TxConfig );
00349 
00350         return 0;
00351 }

static void rtl_close ( struct net_device netdev  )  [static]

Close NIC.

Parameters:
netdev Net device

Definition at line 358 of file rtl8139.c.

References free(), NULL, net_device::priv, rtl8139_rx::ring, rtl_reset(), and rtl8139_nic::rx.

00358                                                     {
00359         struct rtl8139_nic *rtl = netdev->priv;
00360 
00361         /* Reset the hardware to disable everything in one go */
00362         rtl_reset ( netdev );
00363 
00364         /* Free RX ring */
00365         free ( rtl->rx.ring );
00366         rtl->rx.ring = NULL;
00367 }

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

Transmit packet.

Parameters:
netdev Network device
iobuf I/O buffer
Return values:
rc Return status code

Definition at line 376 of file rtl8139.c.

References io_buffer::data, DBGC, DBGC2, ENOBUFS, ETH_ZLEN, rtl8139_nic::ioaddr, iob_len(), iob_pad(), rtl8139_tx::iobuf, rtl8139_tx::next, NULL, outl, net_device::priv, rtl8139_nic::tx, TX_FIFO_THRESH, TX_RING_SIZE, TxAddr0, TxStatus0, and virt_to_bus().

00377                                                     {
00378         struct rtl8139_nic *rtl = netdev->priv;
00379 
00380         /* Check for space in TX ring */
00381         if ( rtl->tx.iobuf[rtl->tx.next] != NULL ) {
00382                 DBGC ( rtl, "rtl8139 %p TX overflow\n", rtl );
00383                 return -ENOBUFS;
00384         }
00385 
00386         /* Pad and align packet */
00387         iob_pad ( iobuf, ETH_ZLEN );
00388 
00389         /* Add to TX ring */
00390         DBGC2 ( rtl, "rtl8139 %p TX id %d at %lx+%zx\n", rtl, rtl->tx.next,
00391                 virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );
00392         rtl->tx.iobuf[rtl->tx.next] = iobuf;
00393         outl ( virt_to_bus ( iobuf->data ),
00394                rtl->ioaddr + TxAddr0 + 4 * rtl->tx.next );
00395         outl ( ( ( ( TX_FIFO_THRESH & 0x7e0 ) << 11 ) | iob_len ( iobuf ) ),
00396                rtl->ioaddr + TxStatus0 + 4 * rtl->tx.next );
00397         rtl->tx.next = ( rtl->tx.next + 1 ) % TX_RING_SIZE;
00398 
00399         return 0;
00400 }

static void rtl_poll ( struct net_device netdev  )  [static]

Poll for received packets.

Parameters:
netdev Network device

Definition at line 407 of file rtl8139.c.

References alloc_iob(), ChipCmd, DBGC, DBGC2, EINVAL, ENOMEM, IntrStatus, inw, rtl8139_nic::ioaddr, iob_put, rtl8139_tx::iobuf, memcpy, netdev_rx(), netdev_rx_err(), netdev_tx_complete(), NULL, rtl8139_rx::offset, outw, net_device::priv, rtl8139_rx::ring, rtl8139_nic::rx, RX_BUF_LEN, RxBufEmpty, RxBufPtr, RxOK, rtl8139_nic::tx, TX_RING_SIZE, and TxSummary.

00407                                                    {
00408         struct rtl8139_nic *rtl = netdev->priv;
00409         unsigned int status;
00410         unsigned int tsad;
00411         unsigned int rx_status;
00412         unsigned int rx_len;
00413         struct io_buffer *rx_iob;
00414         int wrapped_len;
00415         int i;
00416 
00417         /* Acknowledge interrupts */
00418         status = inw ( rtl->ioaddr + IntrStatus );
00419         if ( ! status )
00420                 return;
00421         outw ( status, rtl->ioaddr + IntrStatus );
00422 
00423         /* Handle TX completions */
00424         tsad = inw ( rtl->ioaddr + TxSummary );
00425         for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
00426                 if ( ( rtl->tx.iobuf[i] != NULL ) && ( tsad & ( 1 << i ) ) ) {
00427                         DBGC2 ( rtl, "rtl8139 %p TX id %d complete\n",
00428                                 rtl, i );
00429                         netdev_tx_complete ( netdev, rtl->tx.iobuf[i] );
00430                         rtl->tx.iobuf[i] = NULL;
00431                 }
00432         }
00433 
00434         /* Handle received packets */
00435         while ( ! ( inw ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ) {
00436                 rx_status = * ( ( uint16_t * )
00437                                 ( rtl->rx.ring + rtl->rx.offset ) );
00438                 rx_len = * ( ( uint16_t * )
00439                              ( rtl->rx.ring + rtl->rx.offset + 2 ) );
00440                 if ( rx_status & RxOK ) {
00441                         DBGC2 ( rtl, "rtl8139 %p RX packet at offset "
00442                                 "%x+%x\n", rtl, rtl->rx.offset, rx_len );
00443 
00444                         rx_iob = alloc_iob ( rx_len );
00445                         if ( ! rx_iob ) {
00446                                 netdev_rx_err ( netdev, NULL, -ENOMEM );
00447                                 /* Leave packet for next call to poll() */
00448                                 break;
00449                         }
00450 
00451                         wrapped_len = ( ( rtl->rx.offset + 4 + rx_len )
00452                                         - RX_BUF_LEN );
00453                         if ( wrapped_len < 0 )
00454                                 wrapped_len = 0;
00455 
00456                         memcpy ( iob_put ( rx_iob, rx_len - wrapped_len ),
00457                                  rtl->rx.ring + rtl->rx.offset + 4,
00458                                  rx_len - wrapped_len );
00459                         memcpy ( iob_put ( rx_iob, wrapped_len ),
00460                                  rtl->rx.ring, wrapped_len );
00461 
00462                         netdev_rx ( netdev, rx_iob );
00463                 } else {
00464                         DBGC ( rtl, "rtl8139 %p RX bad packet (status %#04x "
00465                                "len %d)\n", rtl, rx_status, rx_len );
00466                         netdev_rx_err ( netdev, NULL, -EINVAL );
00467                 }
00468                 rtl->rx.offset = ( ( ( rtl->rx.offset + 4 + rx_len + 3 ) & ~3 )
00469                                    % RX_BUF_LEN );
00470                 outw ( rtl->rx.offset - 16, rtl->ioaddr + RxBufPtr );
00471         }
00472 }

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

Enable/disable interrupts.

Parameters:
netdev Network device
enable Interrupts should be enabled

Definition at line 480 of file rtl8139.c.

References DBGC, IntrMask, rtl8139_nic::ioaddr, outw, net_device::priv, RER, ROK, TER, and TOK.

00480                                                               {
00481         struct rtl8139_nic *rtl = netdev->priv;
00482 
00483         DBGC ( rtl, "rtl8139 %p interrupts %s\n",
00484                rtl, ( enable ? "enabled" : "disabled" ) );
00485         outw ( ( enable ? ( ROK | RER | TOK | TER ) : 0 ),
00486                rtl->ioaddr + IntrMask );
00487 }

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

Probe PCI device.

Parameters:
pci PCI device
id PCI ID
Return values:
rc Return status code

Definition at line 505 of file rtl8139.c.

References adjust_pci_device(), alloc_etherdev(), pci_device::dev, net_device::dev, EE_MAC, rtl8139_nic::eeprom, ENOMEM, ETH_ALEN, net_device::hw_addr, pci_device::ioaddr, rtl8139_nic::ioaddr, memset(), netdev, netdev_init(), netdev_link_up(), netdev_nullify(), netdev_put(), netdev_settings(), rtl8139_nic::nvo, nvo_block::nvs, spi_device::nvs, nvs_read(), pci_set_drvdata(), net_device::priv, register_netdev(), register_nvo(), rtl_init_eeprom(), rtl_reset(), and unregister_netdev().

00506                                                                  {
00507         struct net_device *netdev;
00508         struct rtl8139_nic *rtl;
00509         int rc;
00510 
00511         /* Allocate net device */
00512         netdev = alloc_etherdev ( sizeof ( *rtl ) );
00513         if ( ! netdev )
00514                 return -ENOMEM;
00515         netdev_init ( netdev, &rtl_operations );
00516         rtl = netdev->priv;
00517         pci_set_drvdata ( pci, netdev );
00518         netdev->dev = &pci->dev;
00519         memset ( rtl, 0, sizeof ( *rtl ) );
00520         rtl->ioaddr = pci->ioaddr;
00521 
00522         /* Fix up PCI device */
00523         adjust_pci_device ( pci );
00524 
00525         /* Reset the NIC, set up EEPROM access and read MAC address */
00526         rtl_reset ( netdev );
00527         rtl_init_eeprom ( netdev );
00528         nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->hw_addr, ETH_ALEN );
00529 
00530         /* Mark as link up; we don't yet handle link state */
00531         netdev_link_up ( netdev );
00532         
00533         /* Register network device */
00534         if ( ( rc = register_netdev ( netdev ) ) != 0 )
00535                 goto err_register_netdev;
00536 
00537         /* Register non-volatile storage */
00538         if ( rtl->nvo.nvs ) {
00539                 if ( ( rc = register_nvo ( &rtl->nvo,
00540                                            netdev_settings ( netdev ) ) ) != 0)
00541                         goto err_register_nvo;
00542         }
00543 
00544         return 0;
00545 
00546  err_register_nvo:
00547         unregister_netdev ( netdev );
00548  err_register_netdev:
00549         rtl_reset ( netdev );
00550         netdev_nullify ( netdev );
00551         netdev_put ( netdev );
00552         return rc;
00553 }

static void rtl_remove ( struct pci_device pci  )  [static]

Remove PCI device.

Parameters:
pci PCI device

Definition at line 560 of file rtl8139.c.

References netdev, netdev_nullify(), netdev_put(), rtl8139_nic::nvo, nvo_block::nvs, pci_get_drvdata(), net_device::priv, rtl_reset(), unregister_netdev(), and unregister_nvo().

00560                                                   {
00561         struct net_device *netdev = pci_get_drvdata ( pci );
00562         struct rtl8139_nic *rtl = netdev->priv;
00563 
00564         if ( rtl->nvo.nvs )
00565                 unregister_nvo ( &rtl->nvo );
00566         unregister_netdev ( netdev );
00567         rtl_reset ( netdev );
00568         netdev_nullify ( netdev );
00569         netdev_put ( netdev );
00570 }


Variable Documentation

const uint8_t rtl_ee_bits[] [static]

Initial value:

Definition at line 217 of file rtl8139.c.

Referenced by rtl_spi_read_bit(), and rtl_spi_write_bit().

Initial value:

 {
        .read = rtl_spi_read_bit,
        .write = rtl_spi_write_bit,
}

Definition at line 248 of file rtl8139.c.

struct nvo_fragment rtl_nvo_fragments[] [static]

Initial value:

 {
        { 0x20, 0x40 },
        { 0, 0 }
}
Portion of EEPROM available for non-volatile stored options.

We use offset 0x40 (i.e. address 0x20), length 0x40. This block is marked as VPD in the rtl8139 datasheets, so we use it only if we detect that the card is not supporting VPD.

Definition at line 259 of file rtl8139.c.

Initial value:

 {
        .open           = rtl_open,
        .close          = rtl_close,
        .transmit       = rtl_transmit,
        .poll           = rtl_poll,
        .irq            = rtl_irq,
}
RTL8139 net device operations.

Definition at line 490 of file rtl8139.c.

struct pci_device_id rtl8139_nics[] [static]

Initial value:

 {
PCI_ROM(0x10ec, 0x8129, "rtl8129",       "Realtek 8129", 0),
PCI_ROM(0x10ec, 0x8139, "rtl8139",       "Realtek 8139", 0),
PCI_ROM(0x10ec, 0x8138, "rtl8139b",      "Realtek 8139B", 0),
PCI_ROM(0x1186, 0x1300, "dfe538",        "DFE530TX+/DFE538TX", 0),
PCI_ROM(0x1113, 0x1211, "smc1211-1",     "SMC EZ10/100", 0),
PCI_ROM(0x1112, 0x1211, "smc1211",       "SMC EZ10/100", 0),
PCI_ROM(0x1500, 0x1360, "delta8139",     "Delta Electronics 8139", 0),
PCI_ROM(0x4033, 0x1360, "addtron8139",   "Addtron Technology 8139", 0),
PCI_ROM(0x1186, 0x1340, "dfe690txd",     "D-Link DFE690TXD", 0),
PCI_ROM(0x13d1, 0xab06, "fe2000vx",      "AboCom FE2000VX", 0),
PCI_ROM(0x1259, 0xa117, "allied8139",    "Allied Telesyn 8139", 0),
PCI_ROM(0x14ea, 0xab06, "fnw3603tx",     "Planex FNW-3603-TX", 0),
PCI_ROM(0x14ea, 0xab07, "fnw3800tx",     "Planex FNW-3800-TX", 0),
PCI_ROM(0xffff, 0x8139, "clone-rtl8139", "Cloned 8139", 0),
}

Definition at line 572 of file rtl8139.c.

struct pci_driver rtl8139_driver __pci_driver

Initial value:

 {
        .ids = rtl8139_nics,
        .id_count = ( sizeof ( rtl8139_nics ) / sizeof ( rtl8139_nics[0] ) ),
        .probe = rtl_probe,
        .remove = rtl_remove,
}

Definition at line 589 of file rtl8139.c.


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