00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 FILE_LICENCE ( GPL_ANY );
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 #include <stdint.h>
00072 #include <stdlib.h>
00073 #include <stdio.h>
00074 #include <string.h>
00075 #include <gpxe/io.h>
00076 #include <errno.h>
00077 #include <unistd.h>
00078 #include <byteswap.h>
00079 #include <gpxe/pci.h>
00080 #include <gpxe/if_ether.h>
00081 #include <gpxe/ethernet.h>
00082 #include <gpxe/iobuf.h>
00083 #include <gpxe/netdevice.h>
00084 #include <gpxe/spi_bit.h>
00085 #include <gpxe/threewire.h>
00086 #include <gpxe/nvo.h>
00087
00088 #define TX_RING_SIZE 4
00089
00090 struct rtl8139_tx {
00091 unsigned int next;
00092 struct io_buffer *iobuf[TX_RING_SIZE];
00093 };
00094
00095 struct rtl8139_rx {
00096 void *ring;
00097 unsigned int offset;
00098 };
00099
00100 struct rtl8139_nic {
00101 unsigned short ioaddr;
00102 struct rtl8139_tx tx;
00103 struct rtl8139_rx rx;
00104 struct spi_bit_basher spibit;
00105 struct spi_device eeprom;
00106 struct nvo_block nvo;
00107 };
00108
00109
00110 #define TX_FIFO_THRESH 256
00111 #define RX_FIFO_THRESH 4
00112 #define RX_DMA_BURST 4
00113 #define TX_DMA_BURST 4
00114 #define TX_IPG 3
00115 #define RX_BUF_LEN_IDX 0
00116 #define RX_BUF_LEN ( (8192 << RX_BUF_LEN_IDX) )
00117 #define RX_BUF_PAD 4
00118
00119
00120 enum RTL8139_registers {
00121 MAC0=0,
00122 MAR0=8,
00123 TxStatus0=0x10,
00124 TxAddr0=0x20,
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,
00130 RxMissed=0x4C,
00131 Cfg9346=0x50, Config0=0x51, Config1=0x52,
00132 TimerIntrReg=0x54,
00133 MediaStatus=0x58,
00134 Config3=0x59,
00135 MultiIntr=0x5C,
00136 RevisionID=0x5E,
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,
00143 CSCR=0x74,
00144 PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80,
00145
00146
00147 };
00148
00149 enum RxEarlyStatusBits {
00150 ERGood=0x08, ERBad=0x04, EROVW=0x02, EROK=0x01
00151 };
00152
00153 enum ChipCmdBits {
00154 CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
00155
00156 enum IntrMaskBits {
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 };
00161
00162
00163 enum IntrStatusBits {
00164 PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
00165 RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
00166 TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
00167 };
00168 enum TxStatusBits {
00169 TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
00170 TxOutOfWindow=0x20000000, TxAborted=0x40000000,
00171 TxCarrierLost=0x80000000,
00172 };
00173 enum RxStatusBits {
00174 RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
00175 RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
00176 RxBadAlign=0x0002, RxStatusOK=0x0001,
00177 };
00178
00179 enum MediaStatusBits {
00180 MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08,
00181 MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01,
00182 };
00183
00184 enum MIIBMCRBits {
00185 BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000,
00186 BMCRRestartNWay=0x0200, BMCRDuplex=0x0100,
00187 };
00188
00189 enum CSCRBits {
00190 CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
00191 CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
00192 CSCR_LinkDownCmd=0x0f3c0,
00193 };
00194
00195 enum RxConfigBits {
00196 RxCfgWrap=0x80,
00197 Eeprom9356=0x40,
00198 AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
00199 AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
00200 };
00201
00202 enum Config1Bits {
00203 VPDEnable=0x02,
00204 };
00205
00206
00207 #define EE_M1 0x80
00208 #define EE_M0 0x40
00209 #define EE_CS 0x08
00210 #define EE_SK 0x04
00211 #define EE_DI 0x02
00212 #define EE_DO 0x01
00213
00214
00215 #define EE_MAC 7
00216
00217 static const uint8_t rtl_ee_bits[] = {
00218 [SPI_BIT_SCLK] = EE_SK,
00219 [SPI_BIT_MOSI] = EE_DI,
00220 [SPI_BIT_MISO] = EE_DO,
00221 [SPI_BIT_SS(0)] = ( EE_CS | EE_M1 ),
00222 };
00223
00224 static int rtl_spi_read_bit ( struct bit_basher *basher,
00225 unsigned int bit_id ) {
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 }
00234
00235 static void rtl_spi_write_bit ( struct bit_basher *basher,
00236 unsigned int bit_id, unsigned long data ) {
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 }
00247
00248 static struct bit_basher_operations rtl_basher_ops = {
00249 .read = rtl_spi_read_bit,
00250 .write = rtl_spi_write_bit,
00251 };
00252
00253
00254
00255
00256
00257
00258
00259 static struct nvo_fragment rtl_nvo_fragments[] = {
00260 { 0x20, 0x40 },
00261 { 0, 0 }
00262 };
00263
00264
00265
00266
00267
00268
00269 static void rtl_init_eeprom ( struct net_device *netdev ) {
00270 struct rtl8139_nic *rtl = netdev->priv;
00271 int ee9356;
00272 int vpd;
00273
00274
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
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
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 }
00300
00301
00302
00303
00304
00305
00306
00307
00308 static void rtl_reset ( struct net_device *netdev ) {
00309 struct rtl8139_nic *rtl = netdev->priv;
00310
00311
00312 outb ( CmdReset, rtl->ioaddr + ChipCmd );
00313 mdelay ( 10 );
00314 memset ( &rtl->tx, 0, sizeof ( rtl->tx ) );
00315 rtl->rx.offset = 0;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324 static int rtl_open ( struct net_device *netdev ) {
00325 struct rtl8139_nic *rtl = netdev->priv;
00326 int i;
00327
00328
00329 for ( i = 0 ; i < ETH_ALEN ; i++ )
00330 outb ( netdev->ll_addr[i], rtl->ioaddr + MAC0 + i );
00331
00332
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
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 }
00352
00353
00354
00355
00356
00357
00358 static void rtl_close ( struct net_device *netdev ) {
00359 struct rtl8139_nic *rtl = netdev->priv;
00360
00361
00362 rtl_reset ( netdev );
00363
00364
00365 free ( rtl->rx.ring );
00366 rtl->rx.ring = NULL;
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376 static int rtl_transmit ( struct net_device *netdev,
00377 struct io_buffer *iobuf ) {
00378 struct rtl8139_nic *rtl = netdev->priv;
00379
00380
00381 if ( rtl->tx.iobuf[rtl->tx.next] != NULL ) {
00382 DBGC ( rtl, "rtl8139 %p TX overflow\n", rtl );
00383 return -ENOBUFS;
00384 }
00385
00386
00387 iob_pad ( iobuf, ETH_ZLEN );
00388
00389
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 }
00401
00402
00403
00404
00405
00406
00407 static void rtl_poll ( struct net_device *netdev ) {
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
00418 status = inw ( rtl->ioaddr + IntrStatus );
00419 if ( ! status )
00420 return;
00421 outw ( status, rtl->ioaddr + IntrStatus );
00422
00423
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
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
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 }
00473
00474
00475
00476
00477
00478
00479
00480 static void rtl_irq ( struct net_device *netdev, int enable ) {
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 }
00488
00489
00490 static struct net_device_operations rtl_operations = {
00491 .open = rtl_open,
00492 .close = rtl_close,
00493 .transmit = rtl_transmit,
00494 .poll = rtl_poll,
00495 .irq = rtl_irq,
00496 };
00497
00498
00499
00500
00501
00502
00503
00504
00505 static int rtl_probe ( struct pci_device *pci,
00506 const struct pci_device_id *id __unused ) {
00507 struct net_device *netdev;
00508 struct rtl8139_nic *rtl;
00509 int rc;
00510
00511
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
00523 adjust_pci_device ( pci );
00524
00525
00526 rtl_reset ( netdev );
00527 rtl_init_eeprom ( netdev );
00528 nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->hw_addr, ETH_ALEN );
00529
00530
00531 netdev_link_up ( netdev );
00532
00533
00534 if ( ( rc = register_netdev ( netdev ) ) != 0 )
00535 goto err_register_netdev;
00536
00537
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 }
00554
00555
00556
00557
00558
00559
00560 static void rtl_remove ( struct pci_device *pci ) {
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 }
00571
00572 static struct pci_device_id rtl8139_nics[] = {
00573 PCI_ROM(0x10ec, 0x8129, "rtl8129", "Realtek 8129", 0),
00574 PCI_ROM(0x10ec, 0x8139, "rtl8139", "Realtek 8139", 0),
00575 PCI_ROM(0x10ec, 0x8138, "rtl8139b", "Realtek 8139B", 0),
00576 PCI_ROM(0x1186, 0x1300, "dfe538", "DFE530TX+/DFE538TX", 0),
00577 PCI_ROM(0x1113, 0x1211, "smc1211-1", "SMC EZ10/100", 0),
00578 PCI_ROM(0x1112, 0x1211, "smc1211", "SMC EZ10/100", 0),
00579 PCI_ROM(0x1500, 0x1360, "delta8139", "Delta Electronics 8139", 0),
00580 PCI_ROM(0x4033, 0x1360, "addtron8139", "Addtron Technology 8139", 0),
00581 PCI_ROM(0x1186, 0x1340, "dfe690txd", "D-Link DFE690TXD", 0),
00582 PCI_ROM(0x13d1, 0xab06, "fe2000vx", "AboCom FE2000VX", 0),
00583 PCI_ROM(0x1259, 0xa117, "allied8139", "Allied Telesyn 8139", 0),
00584 PCI_ROM(0x14ea, 0xab06, "fnw3603tx", "Planex FNW-3603-TX", 0),
00585 PCI_ROM(0x14ea, 0xab07, "fnw3800tx", "Planex FNW-3800-TX", 0),
00586 PCI_ROM(0xffff, 0x8139, "clone-rtl8139", "Cloned 8139", 0),
00587 };
00588
00589 struct pci_driver rtl8139_driver __pci_driver = {
00590 .ids = rtl8139_nics,
00591 .id_count = ( sizeof ( rtl8139_nics ) / sizeof ( rtl8139_nics[0] ) ),
00592 .probe = rtl_probe,
00593 .remove = rtl_remove,
00594 };