#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 TX_IPG 3 |
| #define RX_BUF_LEN_IDX 0 |
| #define RX_BUF_PAD 4 |
| enum RTL8139_registers |
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 };
| enum RxEarlyStatusBits |
| enum ChipCmdBits |
| enum IntrMaskBits |
| enum IntrStatusBits |
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 };
| enum TxStatusBits |
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 };
| enum RxStatusBits |
| 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 };
| enum MediaStatusBits |
Definition at line 179 of file rtl8139.c.
00179 { 00180 MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08, 00181 MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01, 00182 };
| enum MIIBMCRBits |
Definition at line 184 of file rtl8139.c.
00184 { 00185 BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000, 00186 BMCRRestartNWay=0x0200, BMCRDuplex=0x0100, 00187 };
| enum CSCRBits |
| 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 };
| enum RxConfigBits |
| 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 };
| enum Config1Bits |
| 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.
| 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.
| netdev | Net device |
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.
| netdev | Net device |
| 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.
| 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.
| netdev | Network device | |
| iobuf | I/O buffer |
| 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.
| 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.
| 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.
| pci | PCI device | |
| id | PCI ID |
| 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.
| 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 }
const uint8_t rtl_ee_bits[] [static] |
Initial value:
{
[SPI_BIT_SCLK] = EE_SK,
[SPI_BIT_MOSI] = EE_DI,
[SPI_BIT_MISO] = EE_DO,
[SPI_BIT_SS(0)] = ( EE_CS | EE_M1 ),
}
Definition at line 217 of file rtl8139.c.
Referenced by rtl_spi_read_bit(), and rtl_spi_write_bit().
struct bit_basher_operations rtl_basher_ops [static] |
Initial value:
{
.read = rtl_spi_read_bit,
.write = rtl_spi_write_bit,
}
struct nvo_fragment rtl_nvo_fragments[] [static] |
Initial value:
{
{ 0x20, 0x40 },
{ 0, 0 }
}
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.
struct net_device_operations rtl_operations [static] |
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),
}
| 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,
}
1.5.7.1