00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 #include <linux/kernel.h>
00135 #include <linux/module.h>
00136 #include <linux/pci.h>
00137 #include <linux/config.h>
00138 #include <linux/module.h>
00139 #include <linux/kernel.h>
00140 #include <linux/sched.h>
00141 #include <linux/string.h>
00142 #include <linux/timer.h>
00143 #include <linux/errno.h>
00144 #include <linux/in.h>
00145 #include <linux/ioport.h>
00146 #include <linux/slab.h>
00147 #include <linux/interrupt.h>
00148 #include <linux/mii.h>
00149 #include <linux/init.h>
00150 #include <linux/netdevice.h>
00151 #include <linux/etherdevice.h>
00152 #include <linux/skbuff.h>
00153 #include <linux/ethtool.h>
00154 #include <linux/highmem.h>
00155 #include <asm/irq.h>
00156 #include <asm/bitops.h>
00157 #include <asm/io.h>
00158 #include <asm/uaccess.h>
00159
00160
00161 #include <rtl_sched.h>
00162 #include <signal.h>
00163 #include <time.h>
00164
00165 #define DRV_NAME "rtl8139"
00166 #define DRV_VERSION "0.1"
00167 #define DRV_RELDATE " 4 2003"
00168
00169 #undef USE_IO_OPS
00170
00171 #ifdef USE_IO_OPS
00172
00173 #define RTL_R8(reg) inb (((unsigned long)ioaddr) + (reg))
00174 #define RTL_R16(reg) inw (((unsigned long)ioaddr) + (reg))
00175 #define RTL_R32(reg) ((unsigned long) inl (((unsigned long)ioaddr) + (reg)))
00176 #define RTL_W8(reg, val8) outb ((val8), ((unsigned long)ioaddr) + (reg))
00177 #define RTL_W16(reg, val16) outw ((val16), ((unsigned long)ioaddr) + (reg))
00178 #define RTL_W32(reg, val32) outl ((val32), ((unsigned long)ioaddr) + (reg))
00179 #define RTL_W8_F RTL_W8
00180 #define RTL_W16_F RTL_W16
00181 #define RTL_W32_F RTL_W32
00182 #undef readb
00183 #undef readw
00184 #undef readl
00185 #undef writeb
00186 #undef writew
00187 #undef writel
00188 #define readb(addr) inb((unsigned long)(addr))
00189 #define readw(addr) inw((unsigned long)(addr))
00190 #define readl(addr) inl((unsigned long)(addr))
00191 #define writeb(val,addr) outb((val),(unsigned long)(addr))
00192 #define writew(val,addr) outw((val),(unsigned long)(addr))
00193 #define writel(val,addr) outl((val),(unsigned long)(addr))
00194
00195 #else
00196
00197
00198
00199 #define RTL_W8_F(reg, val8) do { writeb ((val8), ioaddr + (reg)); readb (ioaddr + (reg)); } while (0)
00200 #define RTL_W16_F(reg, val16) do { writew ((val16), ioaddr + (reg)); readw (ioaddr + (reg)); } while (0)
00201 #define RTL_W32_F(reg, val32) do { writel ((val32), ioaddr + (reg)); readl (ioaddr + (reg)); } while (0)
00202
00203
00204 #if MMIO_FLUSH_AUDIT_COMPLETE
00205
00206
00207 #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
00208 #define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg))
00209 #define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg))
00210
00211 #else
00212
00213
00214 #define RTL_W8 RTL_W8_F
00215 #define RTL_W16 RTL_W16_F
00216 #define RTL_W32 RTL_W32_F
00217
00218 #endif
00219
00220
00221 #define RTL_R8(reg) readb (ioaddr + (reg))
00222 #define RTL_R16(reg) readw (ioaddr + (reg))
00223 #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
00224
00225 #endif
00226
00227
00228
00229
00230 #define MAX_THREADS 10
00231
00232 #define RTL8139_VENDOR_ID 0x10EC
00233 #define RTL8139_DEVICE_ID 0X8139
00234
00235 #define PKT_BUF_SZ 1536
00236
00237 #define RX_BUF_LEN_IDX 2
00238 #define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
00239 #define RX_BUF_PAD 16
00240 #define RX_BUF_WRAP_PAD 2048
00241 #define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
00242
00243 #define MAX_ADDR_LEN 8
00244
00245
00246
00247 #define NUM_TX_DESC 4
00248
00249
00250 #define MAX_ETH_FRAME_SIZE 1536
00251
00252
00253 #define TX_BUF_SIZE MAX_ETH_FRAME_SIZE
00254 #define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC)
00255
00256
00257 #define NUM_TX_DESC 4
00258
00259
00260 #define MAX_ETH_FRAME_SIZE 1536
00261
00262
00263 #define TX_BUF_SIZE MAX_ETH_FRAME_SIZE
00264 #define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC)
00265
00266
00267
00268 #define TX_FIFO_THRESH 256
00269
00270
00271 #define RX_FIFO_THRESH 6
00272 #define RX_DMA_BURST 6
00273 #define TX_DMA_BURST 6
00274
00275
00276
00277 #define TX_TIMEOUT (6*HZ)
00278
00279
00280
00281
00282
00283
00284 #define NUM_CP_TX_DESC 64
00285 #define NUM_CP_RX_DESC 64
00286 #define CP_RX_BUF_SIZE 2000
00287
00288
00289
00290 struct ring_info {
00291 struct sk_buff *skb;
00292 dma_addr_t mapping;
00293 };
00294
00295 typedef enum {
00296 CH_8139 = 0,
00297 CH_8139_K,
00298 CH_8139A,
00299 CH_8139B,
00300 CH_8130,
00301 CH_8139C,
00302 CH_8139CP,
00303 } chip_t;
00304
00305 #define TX_RING_SIZE 16
00306 #define RX_RING_SIZE 32
00307
00308
00309 enum {
00310 HAS_MII_XCVR = 0x010000,
00311 HAS_CHIP_XCVR = 0x020000,
00312 HAS_LNK_CHNG = 0x040000,
00313 };
00314
00315 #define RTL_MIN_IO_SIZE 0x80
00316 #define RTL8139B_IO_SIZE 256
00317
00318 #define RTL8129_CAPS HAS_MII_XCVR
00319 #define RTL8139_CAPS HAS_CHIP_XCVR|HAS_LNK_CHNG
00320
00321
00322 typedef enum {
00323 RTL8139 = 0,
00324 RTL8139_CB,
00325 SMC1211TX,
00326
00327 DELTA8139,
00328 ADDTRON8139,
00329 DFE538TX,
00330 RTL8129,
00331 } board_t;
00332
00333
00334
00335 static struct {
00336 const char *name;
00337 u32 hw_flags;
00338 } board_info[] __devinitdata = {
00339 { "RealTek RTL8139CP Fast Ethernet", RTL8139_CAPS },
00340 { "RealTek RTL8139B PCI/CardBus", RTL8139_CAPS },
00341 { "SMC1211TX EZCard 10/100 (RealTek RTL8139)", RTL8139_CAPS },
00342
00343 { "Delta Electronics 8139 10/100BaseTX", RTL8139_CAPS },
00344 { "Addtron Technolgy 8139 10/100BaseTX", RTL8139_CAPS },
00345 { "D-Link DFE-538TX (RealTek RTL8139)", RTL8139_CAPS },
00346 { "RealTek RTL8129", RTL8129_CAPS },
00347 };
00348
00349
00350
00351
00352 const static struct {
00353 const char *name;
00354 u8 version;
00355 u32 RxConfigMask;
00356 } rtl_chip_info[] = {
00357 { "RTL-8139",
00358 0x40,
00359 0xf0fe0040,
00360 },
00361
00362 { "RTL-8139 rev K",
00363 0x60,
00364 0xf0fe0040,
00365 },
00366
00367 { "RTL-8139A",
00368 0x70,
00369 0xf0fe0040,
00370 },
00371
00372 { "RTL-8139B",
00373 0x78,
00374 0xf0fc0040
00375 },
00376
00377 { "RTL-8130",
00378 0x7C,
00379 0xf0fe0040,
00380 },
00381
00382 { "RTL-8139C",
00383 0x74,
00384 0xf0fc0040,
00385 },
00386
00387 { "RTL-8139CP",
00388 0x76,
00389 0xf0fc0040,
00390 },
00391 };
00392
00393
00394
00395
00396
00397 enum RTL8139_registers {
00398 MAC0 = 0,
00399 MAR0 = 8,
00400 TxStatus0 = 0x10,
00401 TxAddr0 = 0x20,
00402 RxBuf = 0x30,
00403 RxEarlyCnt = 0x34,
00404 RxEarlyStatus = 0x36,
00405 ChipCmd = 0x37,
00406 RxBufPtr = 0x38,
00407 RxBufAddr = 0x3A,
00408 IntrMask = 0x3C,
00409 IntrStatus = 0x3E,
00410 TxConfig = 0x40,
00411 ChipVersion = 0x43,
00412 RxConfig = 0x44,
00413 Timer = 0x48,
00414 RxMissed = 0x4C,
00415 Cfg9346 = 0x50,
00416 Config0 = 0x51,
00417 Config1 = 0x52,
00418 FlashReg = 0x54,
00419 MediaStatus = 0x58,
00420 Config3 = 0x59,
00421 Config4 = 0x5A,
00422 HltClk = 0x5B,
00423 MultiIntr = 0x5C,
00424 TxSummary = 0x60,
00425 BasicModeCtrl = 0x62,
00426 BasicModeStatus = 0x64,
00427 NWayAdvert = 0x66,
00428 NWayLPAR = 0x68,
00429 NWayExpansion = 0x6A,
00430
00431 FIFOTMS = 0x70,
00432 CSCR = 0x74,
00433 PARA78 = 0x78,
00434 PARA7c = 0x7c,
00435 Config5 = 0xD8,
00436
00437 CPlusTxPoll=0xD9, CPlusCmd=0xE0, CPlusRxStartAddr=0xE4,
00438 CPlusTxStartAddr=0x20, CPlusEarlyTxThldReg=0xEC,
00439 };
00440
00441
00442 enum ClearBitMasks {
00443 MultiIntrClear = 0xF000,
00444 ChipCmdClear = 0xE2,
00445 Config1Clear = (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1),
00446 };
00447
00448 enum ChipCmdBits {
00449 CmdReset = 0x10,
00450 CmdRxEnb = 0x08,
00451 CmdTxEnb = 0x04,
00452 RxBufEmpty = 0x01,
00453 };
00454
00455 enum CPlusCmdBits {
00456 CPlusTxEnb = 0x01,
00457 CPlusRxEnb = 0x02,
00458 CPlusCheckSumEnb = 0x20,
00459 };
00460
00461 enum CPlusRxStatusDesc {
00462 CPlusRxRES = 0x00100000,
00463 CPlusRxCRC = 0x00040000,
00464 CPlusRxRUNT= 0x00080000,
00465 CPlusRxRWT = 0x00200000,
00466 CPlusRxFAE = 0x08000000,
00467 CPlusRxIPchecksumBIT = 0x00008000,
00468 CPlusRxUDPIPchecksumBIT = 0x0000C000,
00469 CPlusRxTCPIPchecksumBIT = 0x0000A000,
00470 ProtocolType_NonIP = 0,
00471 ProtocolType_TCPIP = 1,
00472 ProtocolType_UDPIP = 2,
00473 ProtocolType_IP = 3,
00474 };
00475
00476 enum CPlusTxChecksumOffload {
00477 CPlusTxIPchecksumOffload = 0x00040000,
00478 CPlusTxUDPchecksumOffload = 0x00020000,
00479 CPlusTxTCPchecksumOffload = 0x00010000,
00480 };
00481
00482
00483 enum IntrStatusBits {
00484 PCIErr = 0x8000,
00485 PCSTimeout = 0x4000,
00486 RxFIFOOver = 0x40,
00487 RxUnderrun = 0x20,
00488 RxOverflow = 0x10,
00489 TxErr = 0x08,
00490 TxOK = 0x04,
00491 RxErr = 0x02,
00492 RxOK = 0x01,
00493 };
00494 enum TxStatusBits {
00495 TxHostOwns = 0x2000,
00496 TxUnderrun = 0x4000,
00497 TxStatOK = 0x8000,
00498 TxOutOfWindow = 0x20000000,
00499 TxAborted = 0x40000000,
00500 TxCarrierLost = 0x80000000,
00501 };
00502 enum RxStatusBits {
00503 RxMulticast = 0x8000,
00504 RxPhysical = 0x4000,
00505 RxBroadcast = 0x2000,
00506 RxBadSymbol = 0x0020,
00507 RxRunt = 0x0010,
00508 RxTooLong = 0x0008,
00509 RxCRCErr = 0x0004,
00510 RxBadAlign = 0x0002,
00511 RxStatusOK = 0x0001,
00512 };
00513
00514
00515 enum rx_mode_bits {
00516 AcceptErr = 0x20,
00517 AcceptRunt = 0x10,
00518 AcceptBroadcast = 0x08,
00519 AcceptMulticast = 0x04,
00520 AcceptMyPhys = 0x02,
00521 AcceptAllPhys = 0x01,
00522 };
00523
00524
00525 enum tx_config_bits {
00526 TxIFG1 = (1 << 25),
00527 TxIFG0 = (1 << 24),
00528 TxLoopBack = (1 << 18) | (1 << 17),
00529 TxCRC = (1 << 16),
00530 TxClearAbt = (1 << 0),
00531 TxDMAShift = 8,
00532
00533 TxVersionMask = 0x7C800000,
00534 };
00535
00536
00537 enum Config1Bits {
00538 Cfg1_PM_Enable = 0x01,
00539 Cfg1_VPD_Enable = 0x02,
00540 Cfg1_PIO = 0x04,
00541 Cfg1_MMIO = 0x08,
00542 Cfg1_LWAKE = 0x10,
00543 Cfg1_Driver_Load = 0x20,
00544 Cfg1_LED0 = 0x40,
00545 Cfg1_LED1 = 0x80,
00546 };
00547
00548 enum RxConfigBits {
00549
00550 RxCfgEarlyRxNone = 0,
00551 RxCfgEarlyRxShift = 24,
00552
00553
00554 RxCfgFIFOShift = 13,
00555 RxCfgFIFONone = (7 << RxCfgFIFOShift),
00556
00557
00558 RxCfgDMAShift = 8,
00559 RxCfgDMAUnlimited = (7 << RxCfgDMAShift),
00560
00561
00562 RxCfgRcv8K = 0,
00563 RxCfgRcv16K = (1 << 11),
00564 RxCfgRcv32K = (1 << 12),
00565 RxCfgRcv64K = (1 << 11) | (1 << 12),
00566
00567
00568 RxNoWrap = (1 << 7),
00569 };
00570
00571
00572
00573 enum CSCRBits {
00574 CSCR_LinkOKBit = 0x0400,
00575 CSCR_LinkChangeBit = 0x0800,
00576 CSCR_LinkStatusBits = 0x0f000,
00577 CSCR_LinkDownOffCmd = 0x003c0,
00578 CSCR_LinkDownCmd = 0x0f3c0,
00579 };
00580
00581
00582 enum Cfg9346Bits {
00583 Cfg9346_Lock = 0x00,
00584 Cfg9346_Unlock = 0xC0,
00585 };
00586
00587
00588 enum NegotiationBits {
00589 AutoNegotiationEnable = 0x1000,
00590 AutoNegotiationRestart = 0x0200,
00591 AutoNegoAbility10half = 0x21,
00592 AutoNegoAbility10full = 0x41,
00593 AutoNegoAbility100half = 0x81,
00594 AutoNegoAbility100full = 0x101,
00595 };
00596
00597 enum MediaStatusBits {
00598 DuplexMode = 0x0100,
00599 Speed_10 = 0x08,
00600 };
00601
00602
00603
00604 #define MAX_UNITS 8
00605 static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
00606 static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
00607
00608
00609
00610
00611
00612
00613
00614 #define MDIO_DIR 0x80
00615 #define MDIO_DATA_OUT 0x04
00616 #define MDIO_DATA_IN 0x02
00617 #define MDIO_CLK 0x01
00618 #define MDIO_WRITE0 (MDIO_DIR)
00619 #define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
00620
00621 #define rt_rtl8139_mdio_delay(mdio_addr) readb(mdio_addr)
00622 #define mdio_delay(mdio_addr) readb(mdio_addr)
00623
00624
00625 static char mii_2_8139_map[8] = {
00626 BasicModeCtrl,
00627 BasicModeStatus,
00628 0,
00629 0,
00630 NWayAdvert,
00631 NWayLPAR,
00632 NWayExpansion,
00633 0
00634 };
00635
00636
00637
00638
00639 #define TX_BUF_SIZE MAX_ETH_FRAME_SIZE
00640 #define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC)
00641
00642
00643
00644 #define TX_FIFO_THRESH 256
00645
00646 static const u16 rtl8139_intr_mask =
00647 PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
00648 TxErr | TxOK | RxErr | RxOK;
00649
00650 static const unsigned int rtl8139_rx_config =
00651 RxCfgEarlyRxNone | RxCfgRcv32K | RxNoWrap |
00652 (RX_FIFO_THRESH << RxCfgFIFOShift) |
00653 (RX_DMA_BURST << RxCfgDMAShift);
00654
00655
00656
00657
00658 struct rtl8139_private {
00659 void *mmio_addr;
00660 unsigned int mmio_len;
00661 int drv_flags;
00662 struct pci_dev *pci_dev;
00663 struct net_device_stats stats;
00664 unsigned char *rx_ring;
00665 unsigned int cur_rx;
00666 unsigned int tx_flag;
00667 unsigned long cur_tx;
00668 unsigned long dirty_tx;
00669
00670 struct ring_info tx_info[NUM_TX_DESC];
00671 unsigned char *tx_buf[NUM_TX_DESC];
00672 unsigned char *tx_bufs;
00673 dma_addr_t rx_ring_dma;
00674 dma_addr_t tx_bufs_dma;
00675 signed char phys[4];
00676 u16 advertising;
00677 char twistie, twist_row, twist_col;
00678 unsigned int full_duplex:1;
00679 unsigned int duplex_lock:1;
00680 unsigned int default_port:4;
00681 unsigned int media2:4;
00682 unsigned int medialock:1;
00683 unsigned int mediasense:1;
00684 spinlock_t lock;
00685 chip_t chipset;
00686 pid_t thr_pid;
00687 wait_queue_head_t thr_wait;
00688
00689 #if LINUX_VERSION_CODE < 0x20407
00690 struct semaphore thr_exited;
00691 #else
00692 struct completion thr_exited;
00693 #endif
00694
00695
00696
00697 int AutoNegoAbility;
00698 unsigned long CP_cur_tx;
00699 unsigned long CP_dirty_tx;
00700 unsigned long CP_cur_rx;
00701 unsigned char *TxDescArrays;
00702 unsigned char *RxDescArrays;
00703 struct CPlusTxDesc *TxDescArray;
00704 struct CPlusRxDesc *RxDescArray;
00705 unsigned char *RxBufferRings;
00706 unsigned char *RxBufferRing[NUM_CP_RX_DESC];
00707 struct sk_buff* Tx_skbuff[NUM_CP_TX_DESC];
00708
00709 int mtu;
00710 unsigned char dev_addr[MAX_ADDR_LEN];
00711 long ioaddr;
00712 unsigned long rx_packets;
00713 unsigned long rx_frames_for_us;
00714 unsigned char if_port;
00715 int must_free_irq;
00716 int must_free_region;
00717 unsigned char *rx_skbuff[RX_RING_SIZE];
00718 unsigned char *tx_skbuff[TX_RING_SIZE];
00719
00720
00721 };
00722
00723
00724 #define PCI_DEBUG 0
00725 #define EEPROM_CONTENTS_DEBUG 0
00726 #define MAC_ADDRESS_DEBUG 0
00727 #define FUNCTION_CALL_DEBUG 0
00728 #define INITIALIZATION_DEBUG 0
00729 #define RECEIVE_DEBUG 0
00730 #define PACKET_DATA_DEBUG 0
00731 #define INTERRUPT_DEBUG 0
00732 #define TRANSMIT_DEBUG 0
00733 #define ERROR_DEBUG 1
00734
00735 #define SIGALRM2 RTL_SIGUSR1
00736
00737 #define DEBUG(x,y) if(x) printk y
00738
00739 #include <rtl_sync.h>
00740 #include <rtl_core.h>
00741 #include <rtl_printf.h>
00742 #include <time.h>
00743 #include <asm/io.h>
00744 #include <rtl_posixio.h>
00745 #include <sys/mman.h>
00746 #include <errno.h>
00747 #include <unistd.h>
00748 #include <rtl.h>
00749 #include <rtl_malloc.h>
00750 #include <rtl_sema.h>
00751 #include <rtl_sync.h>
00752 #include "memcopy.h"
00753
00754
00755 #define MAX_RX_BUFFER_ENTRIES 50
00756
00757 struct rx_buffer_t{
00758 struct rx_slot_t *first;
00759 struct rx_slot_t *add;
00760 struct rx_slot_t *extract;
00761 }rx_buffer;
00762
00763
00764
00765 struct rx_slot_t{
00766 struct rx_slot_t *next;
00767 unsigned int length;
00768 unsigned char *data;
00769 unsigned char read;
00770 #ifdef TIME_DEBUG
00771 struct timeval begin;
00772 struct timeval end;
00773 #endif
00774 };
00775