Annotation of Gnu-Mach/linux/src/drivers/net/rtl8139.c, revision 1.1

1.1     ! root        1: /* rtl8139.c: A RealTek RTL8129/8139 Fast Ethernet driver for Linux. */
        !             2: /*
        !             3:        Written 1997-1998 by Donald Becker.
        !             4: 
        !             5:        This software may be used and distributed according to the terms
        !             6:        of the GNU Public License, incorporated herein by reference.
        !             7:     All other rights reserved.
        !             8: 
        !             9:        This driver is for boards based on the RTL8129 and RTL8139 PCI ethernet
        !            10:        chips.
        !            11: 
        !            12:        The author may be reached as [email protected], or C/O
        !            13:        Center of Excellence in Space Data and Information Sciences
        !            14:           Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
        !            15: 
        !            16:        Support and updates available at
        !            17:        http://cesdis.gsfc.nasa.gov/linux/drivers/rtl8139.html
        !            18: 
        !            19:        Twister-tuning code contributed by Kinston <[email protected]>.
        !            20: */
        !            21: 
        !            22: static const char *version =
        !            23: "rtl8139.c:v0.99B 4/7/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/rtl8139.html\n";
        !            24: 
        !            25: /* A few user-configurable values. */
        !            26: /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
        !            27: static int max_interrupt_work = 10;
        !            28: 
        !            29: /* Size of the in-memory receive ring. */
        !            30: #define RX_BUF_LEN_IDX 3                       /* 0==8K, 1==16K, 2==32K, 3==64K */
        !            31: #define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
        !            32: /* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
        !            33: #define TX_BUF_SIZE    1536
        !            34: 
        !            35: /* PCI Tuning Parameters
        !            36:    Threshold is bytes transferred to chip before transmission starts. */
        !            37: #define TX_FIFO_THRESH 256     /* In bytes, rounded down to 32 byte units. */
        !            38: 
        !            39: /* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024. */
        !            40: #define RX_FIFO_THRESH 4               /* Rx buffer level before first PCI xfer.  */
        !            41: #define RX_DMA_BURST   4               /* Maximum PCI burst, '4' is 256 bytes */
        !            42: #define TX_DMA_BURST   4
        !            43: 
        !            44: /* Operational parameters that usually are not changed. */
        !            45: /* Time in jiffies before concluding the transmitter is hung. */
        !            46: #define TX_TIMEOUT  ((4000*HZ)/1000)
        !            47: 
        !            48: #ifdef MODULE
        !            49: #ifdef MODVERSIONS
        !            50: #include <linux/modversions.h>
        !            51: #endif
        !            52: #include <linux/module.h>
        !            53: #include <linux/version.h>
        !            54: #else
        !            55: #define MOD_INC_USE_COUNT
        !            56: #define MOD_DEC_USE_COUNT
        !            57: #endif
        !            58: 
        !            59: #include <linux/kernel.h>
        !            60: #include <linux/sched.h>
        !            61: #include <linux/string.h>
        !            62: #include <linux/timer.h>
        !            63: #include <linux/ptrace.h>
        !            64: #include <linux/errno.h>
        !            65: #include <linux/ioport.h>
        !            66: #include <linux/malloc.h>
        !            67: #include <linux/interrupt.h>
        !            68: #include <linux/pci.h>
        !            69: #include <linux/bios32.h>
        !            70: #include <asm/processor.h>             /* Processor type for cache alignment. */
        !            71: #include <asm/bitops.h>
        !            72: #include <asm/io.h>
        !            73: #include <asm/dma.h>
        !            74: 
        !            75: #include <linux/netdevice.h>
        !            76: #include <linux/etherdevice.h>
        !            77: #include <linux/skbuff.h>
        !            78: 
        !            79: #define RUN_AT(x) (jiffies + (x))
        !            80: 
        !            81: #include <linux/delay.h>
        !            82: 
        !            83: #if (LINUX_VERSION_CODE < 0x20123)
        !            84: #define test_and_set_bit(val, addr) set_bit(val, addr)
        !            85: #endif
        !            86: 
        !            87: /* The I/O extent. */
        !            88: #define RTL8129_TOTAL_SIZE 0x80
        !            89: 
        !            90: #ifdef HAVE_DEVLIST
        !            91: struct netdev_entry rtl8139_drv =
        !            92: {"RTL8139", rtl8139_probe, RTL8129_TOTAL_SIZE, NULL};
        !            93: #endif
        !            94: 
        !            95: static int rtl8129_debug = 1;
        !            96: 
        !            97: /*
        !            98:                                Theory of Operation
        !            99: 
        !           100: I. Board Compatibility
        !           101: 
        !           102: This device driver is designed for the RealTek RTL8129, the RealTek Fast
        !           103: Ethernet controllers for PCI.  This chip is used on a few clone boards.
        !           104: 
        !           105: 
        !           106: II. Board-specific settings
        !           107: 
        !           108: PCI bus devices are configured by the system at boot time, so no jumpers
        !           109: need to be set on the board.  The system BIOS will assign the
        !           110: PCI INTA signal to a (preferably otherwise unused) system IRQ line.
        !           111: Note: Kernel versions earlier than 1.3.73 do not support shared PCI
        !           112: interrupt lines.
        !           113: 
        !           114: III. Driver operation
        !           115: 
        !           116: IIIa. Rx Ring buffers
        !           117: 
        !           118: The receive unit uses a single linear ring buffer rather than the more
        !           119: common (and more efficient) descriptor-based architecture.  Incoming frames
        !           120: are sequentially stored into the Rx region, and the host copies them into
        !           121: skbuffs.
        !           122: 
        !           123: Comment: While it is theoretically possible to process many frames in place,
        !           124: any delay in Rx processing would cause us to drop frames.  More importantly,
        !           125: the Linux protocol stack is not designed to operate in this manner.
        !           126: 
        !           127: IIIb. Tx operation
        !           128: 
        !           129: The RTL8129 uses a fixed set of four Tx descriptors in register space.
        !           130: In a stunningly bad design choice, Tx frames must be 32 bit aligned.  Linux
        !           131: aligns the IP header on word boundaries, and 14 byte ethernet header means
        !           132: that almost all frames will need to be copied to an alignment buffer.
        !           133: 
        !           134: IVb. References
        !           135: 
        !           136: http://www.realtek.com.tw/cn/cn.html
        !           137: http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
        !           138: 
        !           139: IVc. Errata
        !           140: 
        !           141: */
        !           142: 
        !           143: #ifndef PCI_VENDOR_ID_REALTEK
        !           144: #define PCI_VENDOR_ID_REALTEK          0x10ec
        !           145: #endif
        !           146: #ifndef PCI_DEVICE_ID_REALTEK_8129
        !           147: #define PCI_DEVICE_ID_REALTEK_8129     0x8129
        !           148: #endif
        !           149: #ifndef PCI_DEVICE_ID_REALTEK_8139
        !           150: #define PCI_DEVICE_ID_REALTEK_8139     0x8139
        !           151: #endif
        !           152: 
        !           153: /* The rest of these values should never change. */
        !           154: #define NUM_TX_DESC    4                       /* Number of Tx descriptor registers. */
        !           155: 
        !           156: /* Symbolic offsets to registers. */
        !           157: enum RTL8129_registers {
        !           158:        MAC0=0,                                         /* Ethernet hardware address. */
        !           159:        MAR0=8,                                         /* Multicast filter. */
        !           160:        TxStat0=0x10,                           /* Transmit status (Four 32bit registers). */
        !           161:        TxAddr0=0x20,                           /* Tx descriptors (also four 32bit). */
        !           162:        RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
        !           163:        ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
        !           164:        IntrMask=0x3C, IntrStatus=0x3E,
        !           165:        TxConfig=0x40, RxConfig=0x44,
        !           166:        Timer=0x48,                                     /* A general-purpose counter. */
        !           167:        RxMissed=0x4C,                          /* 24 bits valid, write clears. */
        !           168:        Cfg9346=0x50, Config0=0x51, Config1=0x52,
        !           169:        FlashReg=0x54, GPPinData=0x58, GPPinDir=0x59, MII_SMI=0x5A, HltClk=0x5B,
        !           170:        MultiIntr=0x5C, TxSummary=0x60,
        !           171:        BMCR=0x62, BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68, NWayExpansion=0x6A,
        !           172:        /* Undocumented registers, but required for proper operation. */
        !           173:        FIFOTMS=0x70,   /* FIFO Test Mode Select */
        !           174:        CSCR=0x74,      /* Chip Status and Configuration Register. */
        !           175:        PARA78=0x78, PARA7c=0x7c,       /* Magic transceiver parameter register. */
        !           176: };
        !           177: 
        !           178: enum ChipCmdBits {
        !           179:        CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
        !           180: 
        !           181: /* Interrupt register bits, using my own meaningful names. */
        !           182: enum IntrStatusBits {
        !           183:        PCIErr=0x8000, PCSTimeout=0x4000,
        !           184:        RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
        !           185:        TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
        !           186: };
        !           187: enum TxStatusBits {
        !           188:        TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
        !           189:        TxOutOfWindow=0x20000000, TxAborted=0x40000000, TxCarrierLost=0x80000000,
        !           190: };
        !           191: enum RxStatusBits {
        !           192:        RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
        !           193:        RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
        !           194:        RxBadAlign=0x0002, RxStatusOK=0x0001,
        !           195: };
        !           196: 
        !           197: enum CSCRBits {
        !           198:        CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
        !           199:        CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
        !           200:        CSCR_LinkDownCmd=0x0f3c0,
        !           201: };     
        !           202: 
        !           203: /* Twister tuning parameters from RealTek.  Completely undocumented. */
        !           204: unsigned long param[4][4]={
        !           205:        {0x0cb39de43,0x0cb39ce43,0x0fb38de03,0x0cb38de43},
        !           206:        {0x0cb39de43,0x0cb39ce43,0x0cb39ce83,0x0cb39ce83},
        !           207:        {0x0cb39de43,0x0cb39ce43,0x0cb39ce83,0x0cb39ce83},
        !           208:        {0x0bb39de43,0x0bb39ce43,0x0bb39ce83,0x0bb39ce83}
        !           209: };
        !           210: 
        !           211: struct rtl8129_private {
        !           212:        char devname[8];                        /* Used only for kernel debugging. */
        !           213:        const char *product_name;
        !           214:        struct device *next_module;
        !           215:        int chip_id;
        !           216:        int chip_revision;
        !           217: #if LINUX_VERSION_CODE > 0x20139
        !           218:        struct net_device_stats stats;
        !           219: #else
        !           220:        struct enet_statistics stats;
        !           221: #endif
        !           222:        struct timer_list timer;        /* Media selection timer. */
        !           223:        unsigned int cur_rx, cur_tx;            /* The next free and used entries */
        !           224:        unsigned int dirty_rx, dirty_tx;
        !           225:        /* The saved address of a sent-in-place packet/buffer, for skfree(). */
        !           226:        struct sk_buff* tx_skbuff[NUM_TX_DESC];
        !           227:        unsigned char *tx_buf[NUM_TX_DESC];     /* Tx bounce buffers */
        !           228:        unsigned char *rx_ring;
        !           229:        unsigned char *tx_bufs;                         /* Tx bounce buffer region. */
        !           230:        unsigned char mc_filter[8];                     /* Current multicast filter. */
        !           231:        char phys[4];                                           /* MII device addresses. */
        !           232:        int in_interrupt;                                       /* Alpha needs word-wide lock. */
        !           233:        unsigned int tx_full:1;                         /* The Tx queue is full. */
        !           234:        unsigned int full_duplex:1;                     /* Full-duplex operation requested. */
        !           235:        unsigned int default_port:4;            /* Last dev->if_port value. */
        !           236:        unsigned int media2:4;                          /* Secondary monitored media port. */
        !           237:        unsigned int medialock:1;                       /* Don't sense media type. */
        !           238:        unsigned int mediasense:1;                      /* Media sensing in progress. */
        !           239: };
        !           240: 
        !           241: #ifdef MODULE
        !           242: /* Used to pass the full-duplex flag, etc. */
        !           243: static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
        !           244: static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1};
        !           245: #if LINUX_VERSION_CODE > 0x20118
        !           246: MODULE_AUTHOR("Donald Becker <[email protected]>");
        !           247: MODULE_DESCRIPTION("RealTek RTL8129/8139 Fast Ethernet driver");
        !           248: MODULE_PARM(debug, "i");
        !           249: MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
        !           250: MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
        !           251: MODULE_PARM(max_interrupt_work, "i");
        !           252: #endif
        !           253: #endif
        !           254: 
        !           255: static struct device *rtl8129_probe1(struct device *dev, int ioaddr, int irq,
        !           256:                                                                         int chip_id, int options, int card_idx);
        !           257: static int rtl8129_open(struct device *dev);
        !           258: static int read_eeprom(int ioaddr, int location);
        !           259: static int mdio_read(int ioaddr, int phy_id, int location);
        !           260: static void rtl8129_timer(unsigned long data);
        !           261: static void rtl8129_tx_timeout(struct device *dev);
        !           262: static void rtl8129_init_ring(struct device *dev);
        !           263: static int rtl8129_start_xmit(struct sk_buff *skb, struct device *dev);
        !           264: static int rtl8129_rx(struct device *dev);
        !           265: static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
        !           266: static int rtl8129_close(struct device *dev);
        !           267: static struct enet_statistics *rtl8129_get_stats(struct device *dev);
        !           268: static void set_rx_mode(struct device *dev);
        !           269: 
        !           270: 
        !           271: #ifdef MODULE
        !           272: /* A list of all installed RTL8129 devices, for removing the driver module. */
        !           273: static struct device *root_rtl8129_dev = NULL;
        !           274: #endif
        !           275: 
        !           276: int rtl8139_probe(struct device *dev)
        !           277: {
        !           278:        int cards_found = 0;
        !           279:        static int pci_index = 0;       /* Static, for multiple probe calls. */
        !           280: 
        !           281:        /* Ideally we would detect all network cards in slot order.  That would
        !           282:           be best done a central PCI probe dispatch, which wouldn't work
        !           283:           well with the current structure.  So instead we detect just the
        !           284:           Rtl81*9 cards in slot order. */
        !           285: 
        !           286:        if (pcibios_present()) {
        !           287:                unsigned char pci_bus, pci_device_fn;
        !           288: 
        !           289:                for (;pci_index < 0xff; pci_index++) {
        !           290:                        u8 pci_irq_line, pci_latency;
        !           291:                        u16 pci_command, new_command, vendor, device;
        !           292:                        u32 pci_ioaddr;
        !           293: 
        !           294:                        if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
        !           295: #ifdef REVERSE_PROBE_ORDER
        !           296:                                                                        0xff - pci_index,
        !           297: #else
        !           298:                                                                        pci_index,
        !           299: #endif
        !           300:                                                                        &pci_bus, &pci_device_fn)
        !           301:                                != PCIBIOS_SUCCESSFUL)
        !           302:                                break;
        !           303:                        pcibios_read_config_word(pci_bus, pci_device_fn,
        !           304:                                                                         PCI_VENDOR_ID, &vendor);
        !           305:                        if (vendor != PCI_VENDOR_ID_REALTEK)
        !           306:                                continue;
        !           307: 
        !           308:                        pcibios_read_config_word(pci_bus, pci_device_fn,
        !           309:                                                                         PCI_DEVICE_ID, &device);
        !           310:                        pcibios_read_config_byte(pci_bus, pci_device_fn,
        !           311:                                                                         PCI_INTERRUPT_LINE, &pci_irq_line);
        !           312:                        pcibios_read_config_dword(pci_bus, pci_device_fn,
        !           313:                                                                          PCI_BASE_ADDRESS_0, &pci_ioaddr);
        !           314:                        /* Remove I/O space marker in bit 0. */
        !           315:                        pci_ioaddr &= ~3;
        !           316: 
        !           317:                        if (device != PCI_DEVICE_ID_REALTEK_8129
        !           318:                                &&  device != PCI_DEVICE_ID_REALTEK_8139) {
        !           319:                                printk(KERN_NOTICE "Unknown RealTek PCI ethernet chip type "
        !           320:                                           "%4.4x detected: not configured.\n", device);
        !           321:                                continue;
        !           322:                        }
        !           323:                        if (check_region(pci_ioaddr, RTL8129_TOTAL_SIZE))
        !           324:                                continue;
        !           325: 
        !           326:                        /* Activate the card: fix for brain-damaged Win98 BIOSes. */
        !           327:                        pcibios_read_config_word(pci_bus, pci_device_fn,
        !           328:                                                                         PCI_COMMAND, &pci_command);
        !           329:                        new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
        !           330:                        if (pci_command != new_command) {
        !           331:                                printk(KERN_INFO "  The PCI BIOS has not enabled this"
        !           332:                                           " device!  Updating PCI config %4.4x->%4.4x.\n",
        !           333:                                           pci_command, new_command);
        !           334:                                pcibios_write_config_word(pci_bus, pci_device_fn,
        !           335:                                                                                  PCI_COMMAND, new_command);
        !           336:                        }
        !           337: 
        !           338: #ifdef MODULE
        !           339:                        dev = rtl8129_probe1(dev, pci_ioaddr, pci_irq_line, device,
        !           340:                                                                 options[cards_found], cards_found);
        !           341: #else
        !           342:                        dev = rtl8129_probe1(dev, pci_ioaddr, pci_irq_line, device,
        !           343:                                                                 dev ? dev->mem_start : 0, -1);
        !           344: #endif
        !           345: 
        !           346:                        if (dev) {
        !           347:                                pcibios_read_config_byte(pci_bus, pci_device_fn,
        !           348:                                                                                 PCI_LATENCY_TIMER, &pci_latency);
        !           349:                                if (pci_latency < 32) {
        !           350:                                        printk(KERN_NOTICE"  PCI latency timer (CFLT) is "
        !           351:                                                   "unreasonably low at %d.  Setting to 64 clocks.\n",
        !           352:                                                   pci_latency);
        !           353:                                        pcibios_write_config_byte(pci_bus, pci_device_fn,
        !           354:                                                                                          PCI_LATENCY_TIMER, 64);
        !           355:                                } else if (rtl8129_debug > 1)
        !           356:                                        printk(KERN_INFO"  PCI latency timer (CFLT) is %#x.\n",
        !           357:                                                   pci_latency);
        !           358:                                dev = 0;
        !           359:                                cards_found++;
        !           360:                        }
        !           361:                }
        !           362:        }
        !           363: 
        !           364: #if defined (MODULE)
        !           365:        return cards_found;
        !           366: #else
        !           367:        return cards_found ? 0 : -ENODEV;
        !           368: #endif
        !           369: }
        !           370: 
        !           371: static struct device *rtl8129_probe1(struct device *dev, int ioaddr, int irq,
        !           372:                                                                   int chip_id, int options, int card_idx)
        !           373: {
        !           374:        static int did_version = 0;                     /* Already printed version info. */
        !           375:        struct rtl8129_private *tp;
        !           376:        int i;
        !           377: 
        !           378:        if (rtl8129_debug > 0  &&  did_version++ == 0)
        !           379:                printk(KERN_INFO "%s", version);
        !           380: 
        !           381:        dev = init_etherdev(dev, 0);
        !           382: 
        !           383:        printk(KERN_INFO "%s: RealTek RTL%x at %#3x, IRQ %d, ",
        !           384:                   dev->name, chip_id, ioaddr, irq);
        !           385: 
        !           386:        /* Bring the chip out of low-power mode. */
        !           387:        outb(0x00, ioaddr + Config1);
        !           388: 
        !           389:        /* Perhaps this should be read from the EEPROM? */
        !           390:        for (i = 0; i < 6; i++)
        !           391:                dev->dev_addr[i] = inb(ioaddr + MAC0 + i);
        !           392: 
        !           393:        for (i = 0; i < 5; i++)
        !           394:                printk("%2.2x:", dev->dev_addr[i]);
        !           395:        printk("%2.2x.\n", dev->dev_addr[i]);
        !           396: 
        !           397:        if (rtl8129_debug > 1) {
        !           398:                printk(KERN_INFO "%s: EEPROM contents\n", dev->name);
        !           399:                for (i = 0; i < 64; i++)
        !           400:                        printk(" %4.4x%s", read_eeprom(ioaddr, i),
        !           401:                                   i%16 == 15 ? "\n"KERN_INFO : "");
        !           402:        }
        !           403: 
        !           404:        /* We do a request_region() to register /proc/ioports info. */
        !           405:        request_region(ioaddr, RTL8129_TOTAL_SIZE, "RealTek RTL8129/39 Fast Ethernet");
        !           406: 
        !           407:        dev->base_addr = ioaddr;
        !           408:        dev->irq = irq;
        !           409: 
        !           410:        /* Some data structures must be quadword aligned. */
        !           411:        tp = kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA);
        !           412:        memset(tp, 0, sizeof(*tp));
        !           413:        dev->priv = tp;
        !           414: 
        !           415: #ifdef MODULE
        !           416:        tp->next_module = root_rtl8129_dev;
        !           417:        root_rtl8129_dev = dev;
        !           418: #endif
        !           419: 
        !           420:        tp->chip_id = chip_id;
        !           421: 
        !           422:        /* Find the connected MII xcvrs.
        !           423:           Doing this in open() would allow detecting external xcvrs later, but
        !           424:           takes too much time. */
        !           425:        if (chip_id == 0x8129) {
        !           426:                int phy, phy_idx;
        !           427:                for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
        !           428:                         phy++) {
        !           429:                        int mii_status = mdio_read(ioaddr, phy, 1);
        !           430: 
        !           431:                        if (mii_status != 0xffff  && mii_status != 0x0000) {
        !           432:                                tp->phys[phy_idx++] = phy;
        !           433:                                printk(KERN_INFO "%s: MII transceiver found at address %d.\n",
        !           434:                                           dev->name, phy);
        !           435:                        }
        !           436:                }
        !           437:                if (phy_idx == 0) {
        !           438:                        printk(KERN_INFO "%s: No MII transceivers found!  Assuming SYM "
        !           439:                                   "transceiver.\n",
        !           440:                                   dev->name);
        !           441:                        tp->phys[0] = -1;
        !           442:                }
        !           443:        } else {
        !           444:                        tp->phys[0] = -1;
        !           445:        }
        !           446: 
        !           447:        /* Put the chip into low-power mode. */
        !           448:        outb(0xC0, ioaddr + Cfg9346);
        !           449:        outb(0x03, ioaddr + Config1);
        !           450:        outb('H', ioaddr + HltClk);             /* 'R' would leave the clock running. */
        !           451: 
        !           452:        /* The lower four bits are the media type. */
        !           453:        if (options > 0) {
        !           454:                tp->full_duplex = (options & 16) ? 1 : 0;
        !           455:                tp->default_port = options & 15;
        !           456:                if (tp->default_port)
        !           457:                        tp->medialock = 1;
        !           458:        }
        !           459: #ifdef MODULE
        !           460:        if (card_idx >= 0) {
        !           461:                if (full_duplex[card_idx] >= 0)
        !           462:                        tp->full_duplex = full_duplex[card_idx];
        !           463:        }
        !           464: #endif
        !           465: 
        !           466:        /* The Rtl8129-specific entries in the device structure. */
        !           467:        dev->open = &rtl8129_open;
        !           468:        dev->hard_start_xmit = &rtl8129_start_xmit;
        !           469:        dev->stop = &rtl8129_close;
        !           470:        dev->get_stats = &rtl8129_get_stats;
        !           471:        dev->set_multicast_list = &set_rx_mode;
        !           472: 
        !           473:        return dev;
        !           474: }
        !           475: 
        !           476: /* Serial EEPROM section. */
        !           477: 
        !           478: /*  EEPROM_Ctrl bits. */
        !           479: #define EE_SHIFT_CLK   0x04    /* EEPROM shift clock. */
        !           480: #define EE_CS                  0x08    /* EEPROM chip select. */
        !           481: #define EE_DATA_WRITE  0x02    /* EEPROM chip data in. */
        !           482: #define EE_WRITE_0             0x00
        !           483: #define EE_WRITE_1             0x02
        !           484: #define EE_DATA_READ   0x01    /* EEPROM chip data out. */
        !           485: #define EE_ENB                 (0x80 | EE_CS)
        !           486: 
        !           487: /* Delay between EEPROM clock transitions.
        !           488:    No extra delay is needed with 33Mhz PCI, but 66Mhz is untested.
        !           489:  */
        !           490: 
        !           491: #ifdef _LINUX_DELAY_H
        !           492: #define eeprom_delay(nanosec)  udelay(1)
        !           493: #else
        !           494: #define eeprom_delay(nanosec)  do { ; } while (0)
        !           495: #endif
        !           496: 
        !           497: /* The EEPROM commands include the alway-set leading bit. */
        !           498: #define EE_WRITE_CMD   (5 << 6)
        !           499: #define EE_READ_CMD            (6 << 6)
        !           500: #define EE_ERASE_CMD   (7 << 6)
        !           501: 
        !           502: static int read_eeprom(int ioaddr, int location)
        !           503: {
        !           504:        int i;
        !           505:        unsigned retval = 0;
        !           506:        int ee_addr = ioaddr + Cfg9346;
        !           507:        int read_cmd = location | EE_READ_CMD;
        !           508: 
        !           509:        outb(EE_ENB & ~EE_CS, ee_addr);
        !           510:        outb(EE_ENB, ee_addr);
        !           511: 
        !           512:        /* Shift the read command bits out. */
        !           513:        for (i = 10; i >= 0; i--) {
        !           514:                int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
        !           515:                outb(EE_ENB | dataval, ee_addr);
        !           516:                eeprom_delay(100);
        !           517:                outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
        !           518:                eeprom_delay(150);
        !           519:                outb(EE_ENB | dataval, ee_addr);        /* Finish EEPROM a clock tick. */
        !           520:                eeprom_delay(250);
        !           521:        }
        !           522:        outb(EE_ENB, ee_addr);
        !           523: 
        !           524:        for (i = 16; i > 0; i--) {
        !           525:                outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
        !           526:                eeprom_delay(100);
        !           527:                retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
        !           528:                outb(EE_ENB, ee_addr);
        !           529:                eeprom_delay(100);
        !           530:        }
        !           531: 
        !           532:        /* Terminate the EEPROM access. */
        !           533:        outb(~EE_CS, ee_addr);
        !           534:        return retval;
        !           535: }
        !           536: 
        !           537: /* MII serial management: mostly bogus for now. */
        !           538: /* Read and write the MII management registers using software-generated
        !           539:    serial MDIO protocol.
        !           540:    The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
        !           541:    met by back-to-back PCI I/O cycles, but we insert a delay to avoid
        !           542:    "overclocking" issues. */
        !           543: #define MDIO_DIR               0x80
        !           544: #define MDIO_DATA_OUT  0x04
        !           545: #define MDIO_DATA_IN   0x02
        !           546: #define MDIO_CLK               0x01
        !           547: #ifdef _LINUX_DELAY_H
        !           548: #define mdio_delay()   udelay(1) /* Really 400ns. */
        !           549: #else
        !           550: #define mdio_delay()   do { ; } while (0)
        !           551: #endif
        !           552: 
        !           553: /* Syncronize the MII management interface by shifting 32 one bits out. */
        !           554: static void mdio_sync(int ioaddr)
        !           555: {
        !           556:        int i;
        !           557:        int mdio_addr = ioaddr + MII_SMI;
        !           558: 
        !           559:        for (i = 32; i >= 0; i--) {
        !           560:                outb(MDIO_DIR | MDIO_DATA_OUT, mdio_addr);
        !           561:                mdio_delay();
        !           562:                outb(MDIO_DIR | MDIO_DATA_OUT | MDIO_CLK, mdio_addr);
        !           563:                mdio_delay();
        !           564:        }
        !           565:        return;
        !           566: }
        !           567: static int mdio_read(int ioaddr, int phy_id, int location)
        !           568: {
        !           569:        int i;
        !           570:        int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
        !           571:        int retval = 0;
        !           572:        int mdio_addr = ioaddr + MII_SMI;
        !           573: 
        !           574:        mdio_sync(ioaddr);
        !           575:        /* Shift the read command bits out. */
        !           576:        for (i = 15; i >= 0; i--) {
        !           577:                int dataval =
        !           578:                  (read_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
        !           579: 
        !           580:                outb(MDIO_DIR | dataval, mdio_addr);
        !           581:                mdio_delay();
        !           582:                outb(MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
        !           583:                mdio_delay();
        !           584:        }
        !           585: 
        !           586:        /* Read the two transition, 16 data, and wire-idle bits. */
        !           587:        for (i = 19; i > 0; i--) {
        !           588:                outb(0, mdio_addr);
        !           589:                mdio_delay();
        !           590:                retval = (retval << 1) | ((inb(mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
        !           591:                outb(MDIO_CLK, mdio_addr);
        !           592:                mdio_delay();
        !           593:        }
        !           594:        return (retval>>1) & 0xffff;
        !           595: }
        !           596: 
        !           597: static int
        !           598: rtl8129_open(struct device *dev)
        !           599: {
        !           600:        struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
        !           601:        int ioaddr = dev->base_addr;
        !           602:        int i;
        !           603:        int full_duplex = 0;
        !           604: 
        !           605:        /* Soft reset the chip. */
        !           606:        outb(CmdReset, ioaddr + ChipCmd);
        !           607: 
        !           608:        if (request_irq(dev->irq, &rtl8129_interrupt, SA_SHIRQ, dev->name, dev)) {
        !           609:                return -EAGAIN;
        !           610:        }
        !           611: 
        !           612:        MOD_INC_USE_COUNT;
        !           613: 
        !           614:        tp->tx_bufs = kmalloc(TX_BUF_SIZE * NUM_TX_DESC, GFP_KERNEL);
        !           615:        tp->rx_ring = kmalloc(RX_BUF_LEN + 16, GFP_KERNEL);
        !           616:        if (tp->tx_bufs == NULL ||  tp->rx_ring == NULL) {
        !           617:                if (tp->tx_bufs)
        !           618:                        kfree(tp->tx_bufs);
        !           619:                if (rtl8129_debug > 0)
        !           620:                        printk(KERN_ERR "%s: Couldn't allocate a %d byte receive ring.\n",
        !           621:                                   dev->name, RX_BUF_LEN);
        !           622:                return -ENOMEM;
        !           623:        }
        !           624:        rtl8129_init_ring(dev);
        !           625: 
        !           626:        /* Check that the chip has finished the reset. */
        !           627:        for (i = 1000; i > 0; i--)
        !           628:                if ((inb(ioaddr + ChipCmd) & CmdReset) == 0)
        !           629:                        break;
        !           630: 
        !           631:        for (i = 0; i < 6; i++)
        !           632:                outb(dev->dev_addr[i], ioaddr + MAC0 + i);
        !           633: 
        !           634:        /* Must enable Tx/Rx before setting transfer thresholds! */
        !           635:        outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
        !           636:        outl((RX_FIFO_THRESH << 13) | (RX_BUF_LEN_IDX << 11) | (RX_DMA_BURST<<8),
        !           637:                 ioaddr + RxConfig);
        !           638:        outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig);
        !           639: 
        !           640:        full_duplex = tp->full_duplex;
        !           641:        if (tp->phys[0] >= 0  ||  tp->chip_id == 0x8139) {
        !           642:                u16 mii_reg5;
        !           643:                if (tp->chip_id == 0x8139)
        !           644:                        mii_reg5 = inw(ioaddr + NWayLPAR);
        !           645:                else
        !           646:                        mii_reg5 = mdio_read(ioaddr, tp->phys[0], 5);
        !           647:                if (mii_reg5 == 0xffff)
        !           648:                        ;                                       /* Not there */
        !           649:                else if ((mii_reg5 & 0x0100) == 0x0100
        !           650:                                 || (mii_reg5 & 0x00C0) == 0x0040)
        !           651:                        full_duplex = 1;
        !           652:                if (rtl8129_debug > 1)
        !           653:                        printk(KERN_INFO"%s: Setting %s%s-duplex based on"
        !           654:                                   " auto-negotiated partner ability %4.4x.\n", dev->name,
        !           655:                                   mii_reg5 == 0 ? "" :
        !           656:                                   (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
        !           657:                                   full_duplex ? "full" : "half", mii_reg5);
        !           658:        }
        !           659: 
        !           660:        outb(0xC0, ioaddr + Cfg9346);
        !           661:        outb(full_duplex ? 0x60 : 0x20, ioaddr + Config1);
        !           662:        outb(0x00, ioaddr + Cfg9346);
        !           663: 
        !           664:        outl(virt_to_bus(tp->rx_ring), ioaddr + RxBuf);
        !           665: 
        !           666:        /* Start the chip's Tx and Rx process. */
        !           667:        outl(0, ioaddr + RxMissed);
        !           668:        set_rx_mode(dev);
        !           669: 
        !           670:        outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
        !           671: 
        !           672:        dev->tbusy = 0;
        !           673:        dev->interrupt = 0;
        !           674:        dev->start = 1;
        !           675: 
        !           676:        /* Enable all known interrupts by setting the interrupt mask. */
        !           677:        outw(PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver
        !           678:                | TxErr | TxOK | RxErr | RxOK, ioaddr + IntrMask);
        !           679: 
        !           680:        if (rtl8129_debug > 1)
        !           681:                printk(KERN_DEBUG"%s: rtl8129_open() ioaddr %4.4x IRQ %d"
        !           682:                           " GP Pins %2.2x %s-duplex.\n",
        !           683:                           dev->name, ioaddr, dev->irq, inb(ioaddr + GPPinData),
        !           684:                           full_duplex ? "full" : "half");
        !           685: 
        !           686:        /* Set the timer to switch to check for link beat and perhaps switch
        !           687:           to an alternate media type. */
        !           688:        init_timer(&tp->timer);
        !           689:        tp->timer.expires = RUN_AT((24*HZ)/10);                 /* 2.4 sec. */
        !           690:        tp->timer.data = (unsigned long)dev;
        !           691:        tp->timer.function = &rtl8129_timer;                            /* timer handler */
        !           692:        add_timer(&tp->timer);
        !           693: 
        !           694:        return 0;
        !           695: }
        !           696: 
        !           697: static void rtl8129_timer(unsigned long data)
        !           698: {
        !           699:        struct device *dev = (struct device *)data;
        !           700:        struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
        !           701:        int ioaddr = dev->base_addr;
        !           702:        int next_tick = 0;
        !           703: 
        !           704:        if (tp->chip_id == 0x8139) {
        !           705:                u16 mii_reg5 = inw(ioaddr + NWayLPAR);
        !           706:                if ((mii_reg5 & 0x0100) == 0x0100
        !           707:                        || (mii_reg5 & 0x00C0) == 0x0040)
        !           708:                        if ( ! tp->full_duplex) {
        !           709:                                tp->full_duplex = 1;
        !           710:                                if (rtl8129_debug > 0)
        !           711:                                        printk(KERN_INFO "%s: Switching to full-duplex based on "
        !           712:                                                   "link partner ability of %4.4x.\n",
        !           713:                                                   dev->name, mii_reg5);
        !           714:                                outb(0xC0, ioaddr + Cfg9346);
        !           715:                                outb(tp->full_duplex ? 0x60 : 0x20, ioaddr + Config1);
        !           716:                                outb(0x00, ioaddr + Cfg9346);
        !           717:                        }
        !           718:        }
        !           719:        if (rtl8129_debug > 2) {
        !           720:                if (tp->chip_id == 0x8129)
        !           721:                        printk(KERN_DEBUG"%s: Media selection tick, GP pins %2.2x.\n",
        !           722:                                   dev->name, inb(ioaddr + GPPinData));
        !           723:                else
        !           724:                        printk(KERN_DEBUG"%s: Media selection tick, Link partner %4.4x.\n",
        !           725:                                   dev->name, inw(ioaddr + NWayLPAR));
        !           726:                printk(KERN_DEBUG"%s:  Other registers are IntMask %4.4x IntStatus %4.4x"
        !           727:                           " RxStatus %4.4x.\n",
        !           728:                           dev->name, inw(ioaddr + IntrMask), inw(ioaddr + IntrStatus),
        !           729:                           inl(ioaddr + RxEarlyStatus));
        !           730:                printk(KERN_DEBUG"%s:  Chip config %2.2x %2.2x.\n",
        !           731:                           dev->name, inb(ioaddr + Config0), inb(ioaddr + Config1));
        !           732:        }
        !           733: 
        !           734:        if (next_tick) {
        !           735:                tp->timer.expires = RUN_AT(next_tick);
        !           736:                add_timer(&tp->timer);
        !           737:        }
        !           738: }
        !           739: 
        !           740: static void rtl8129_tx_timeout(struct device *dev)
        !           741: {
        !           742:        struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
        !           743:        int ioaddr = dev->base_addr;
        !           744:        int i;
        !           745: 
        !           746:        /* Disable interrupts by clearing the interrupt mask. */
        !           747:        outw(0x0000, ioaddr + IntrMask);
        !           748: 
        !           749:        if (rtl8129_debug > 0)
        !           750:                printk(KERN_WARNING "%s: Transmit timeout, status %2.2x %4.4x.\n",
        !           751:                           dev->name, inb(ioaddr + ChipCmd), inw(ioaddr + IntrStatus));
        !           752:        /* Emit info to figure out what went wrong. */
        !           753:        for (i = 0; i < NUM_TX_DESC; i++)
        !           754:                printk(KERN_DEBUG"%s:  Tx descriptor %d is %8.8x.%s\n",
        !           755:                           dev->name, i, inl(ioaddr + TxStat0 + i*4),
        !           756:                           i == tp->dirty_tx % NUM_TX_DESC ? " (queue head)" : "");
        !           757:        if (tp->chip_id == 0x8129) {
        !           758:                int mii_reg;
        !           759:                printk(KERN_DEBUG"%s: MII #%d registers are:", dev->name, tp->phys[0]);
        !           760:                for (mii_reg = 0; mii_reg < 8; mii_reg++)
        !           761:                        printk(" %4.4x", mdio_read(ioaddr, tp->phys[0], mii_reg));
        !           762:                printk(".\n");
        !           763:        } else {
        !           764:                printk(KERN_DEBUG"%s: MII status register is %4.4x.\n",
        !           765:                           dev->name, inw(ioaddr + BMSR));
        !           766:        }
        !           767: 
        !           768:        /* Soft reset the chip. */
        !           769:        outb(CmdReset, ioaddr + ChipCmd);
        !           770:        for (i = 0; i < 6; i++)
        !           771:                outb(dev->dev_addr[i], ioaddr + MAC0 + i);
        !           772: 
        !           773:        {                                                       /* Save the unsent Tx packets. */
        !           774:                struct sk_buff *saved_skb[NUM_TX_DESC], *skb;
        !           775:                int j = 0;
        !           776:                for (; tp->cur_tx - tp->dirty_tx > 0 ; tp->dirty_tx++)
        !           777:                        saved_skb[j++] = tp->tx_skbuff[tp->dirty_tx % NUM_TX_DESC];
        !           778:                tp->dirty_tx = tp->cur_tx = 0;
        !           779: 
        !           780:                for (i = 0; i < j; i++) {
        !           781:                        skb = tp->tx_skbuff[i] = saved_skb[i];
        !           782:                        if ((long)skb->data & 3) {              /* Must use alignment buffer. */
        !           783:                                memcpy(tp->tx_buf[i], skb->data, skb->len);
        !           784:                                outl(virt_to_bus(tp->tx_buf[i]), ioaddr + TxAddr0 + i*4);
        !           785:                        } else
        !           786:                                outl(virt_to_bus(skb->data), ioaddr + TxAddr0 + i*4);
        !           787:                        /* Note: the chip doesn't have auto-pad! */
        !           788:                        outl(((TX_FIFO_THRESH<<11) & 0x003f0000) |
        !           789:                                 (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN),
        !           790:                                 ioaddr + TxStat0 + i*4);
        !           791:                }
        !           792:                tp->cur_tx = i;
        !           793:                while (i < NUM_TX_DESC)
        !           794:                        tp->tx_skbuff[i] = 0;
        !           795:                if (tp->cur_tx - tp->dirty_tx < NUM_TX_DESC) {/* Typical path */
        !           796:                        dev->tbusy = 0;
        !           797:                } else {
        !           798:                        tp->tx_full = 1;
        !           799:                }
        !           800:        }
        !           801: 
        !           802:        /* Must enable Tx/Rx before setting transfer thresholds! */
        !           803:        set_rx_mode(dev);
        !           804:        outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
        !           805:        outl((RX_FIFO_THRESH << 13) | (RX_BUF_LEN_IDX << 11) | (RX_DMA_BURST<<8),
        !           806:                 ioaddr + RxConfig);
        !           807:        outl((TX_DMA_BURST<<8), ioaddr + TxConfig);
        !           808: 
        !           809:        dev->trans_start = jiffies;
        !           810:        tp->stats.tx_errors++;
        !           811:        /* Enable all known interrupts by setting the interrupt mask. */
        !           812:        outw(PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver
        !           813:                 | TxErr | TxOK | RxErr | RxOK, ioaddr + IntrMask);
        !           814:        return;
        !           815: }
        !           816: 
        !           817: 
        !           818: /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
        !           819: static void
        !           820: rtl8129_init_ring(struct device *dev)
        !           821: {
        !           822:        struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
        !           823:        int i;
        !           824: 
        !           825:        tp->tx_full = 0;
        !           826:        tp->cur_rx = tp->cur_tx = 0;
        !           827:        tp->dirty_rx = tp->dirty_tx = 0;
        !           828: 
        !           829:        for (i = 0; i < NUM_TX_DESC; i++) {
        !           830:                tp->tx_skbuff[i] = 0;
        !           831:                tp->tx_buf[i] = &tp->tx_bufs[i*TX_BUF_SIZE];
        !           832:        }
        !           833: }
        !           834: 
        !           835: static int
        !           836: rtl8129_start_xmit(struct sk_buff *skb, struct device *dev)
        !           837: {
        !           838:        struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
        !           839:        int ioaddr = dev->base_addr;
        !           840:        int entry;
        !           841: 
        !           842:        /* Block a timer-based transmit from overlapping.  This could better be
        !           843:           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
        !           844:        if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
        !           845:                if (jiffies - dev->trans_start < TX_TIMEOUT)
        !           846:                        return 1;
        !           847:                rtl8129_tx_timeout(dev);
        !           848:                return 1;
        !           849:        }
        !           850: 
        !           851:        /* Calculate the next Tx descriptor entry. */
        !           852:        entry = tp->cur_tx % NUM_TX_DESC;
        !           853: 
        !           854:        tp->tx_skbuff[entry] = skb;
        !           855:        if ((long)skb->data & 3) {                      /* Must use alignment buffer. */
        !           856:                memcpy(tp->tx_buf[entry], skb->data, skb->len);
        !           857:                outl(virt_to_bus(tp->tx_buf[entry]), ioaddr + TxAddr0 + entry*4);
        !           858:        } else
        !           859:                outl(virt_to_bus(skb->data), ioaddr + TxAddr0 + entry*4);
        !           860:        /* Note: the chip doesn't have auto-pad! */
        !           861:        outl(((TX_FIFO_THRESH<<11) & 0x003f0000) |
        !           862:                 (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN),
        !           863:                 ioaddr + TxStat0 + entry*4);
        !           864: 
        !           865:        if (++tp->cur_tx - tp->dirty_tx < NUM_TX_DESC) {/* Typical path */
        !           866:                dev->tbusy = 0;
        !           867:        } else {
        !           868:                tp->tx_full = 1;
        !           869:        }
        !           870: 
        !           871:        dev->trans_start = jiffies;
        !           872:        if (rtl8129_debug > 4)
        !           873:                printk(KERN_DEBUG"%s: Queued Tx packet at %p size %ld to slot %d.\n",
        !           874:                           dev->name, skb->data, skb->len, entry);
        !           875: 
        !           876:        return 0;
        !           877: }
        !           878: 
        !           879: /* The interrupt handler does all of the Rx thread work and cleans up
        !           880:    after the Tx thread. */
        !           881: static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
        !           882: {
        !           883:        struct device *dev = (struct device *)dev_instance;
        !           884:        struct rtl8129_private *tp;
        !           885:        int ioaddr, boguscnt = max_interrupt_work;
        !           886:        int status;
        !           887: 
        !           888:        if (dev == NULL) {
        !           889:                printk (KERN_ERR"rtl8139_interrupt(): IRQ %d for unknown device.\n",
        !           890:                                irq);
        !           891:                return;
        !           892:        }
        !           893: 
        !           894:        ioaddr = dev->base_addr;
        !           895:        tp = (struct rtl8129_private *)dev->priv;
        !           896:        if (test_and_set_bit(0, (void*)&tp->in_interrupt)) {
        !           897:                printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
        !           898:                return;
        !           899:        }
        !           900:        dev->interrupt = 1;
        !           901: 
        !           902:        do {
        !           903:                status = inw(ioaddr + IntrStatus);
        !           904:                /* Acknowledge all of the current interrupt sources ASAP. */
        !           905:                outw(status, ioaddr + IntrStatus);
        !           906: 
        !           907:                if (rtl8129_debug > 4)
        !           908:                        printk(KERN_DEBUG"%s: interrupt  status=%#4.4x new intstat=%#4.4x.\n",
        !           909:                                   dev->name, status, inw(ioaddr + IntrStatus));
        !           910: 
        !           911:                if ((status & (PCIErr|PCSTimeout|RxUnderrun|RxOverflow|RxFIFOOver
        !           912:                                           |TxErr|TxOK|RxErr|RxOK)) == 0)
        !           913:                        break;
        !           914: 
        !           915:                if (status & (RxOK|RxUnderrun|RxOverflow|RxFIFOOver))/* Rx interrupt */
        !           916:                        rtl8129_rx(dev);
        !           917: 
        !           918:                if (status & (TxOK | TxErr)) {
        !           919:                        unsigned int dirty_tx;
        !           920: 
        !           921:                        for (dirty_tx = tp->dirty_tx; dirty_tx < tp->cur_tx; dirty_tx++) {
        !           922:                                int entry = dirty_tx % NUM_TX_DESC;
        !           923:                                int txstatus = inl(ioaddr + TxStat0 + entry*4);
        !           924: 
        !           925:                                if ( ! (txstatus & TxHostOwns))
        !           926:                                        break;                  /* It still hasn't been Txed */
        !           927: 
        !           928:                                /* Note: TxCarrierLost is always asserted at 100mbps. */
        !           929:                                if (txstatus & (TxOutOfWindow | TxAborted)) {
        !           930:                                        /* There was an major error, log it. */
        !           931: #ifndef final_version
        !           932:                                        if (rtl8129_debug > 1)
        !           933:                                                printk(KERN_NOTICE"%s: Transmit error, Tx status %8.8x.\n",
        !           934:                                                           dev->name, txstatus);
        !           935: #endif
        !           936:                                        tp->stats.tx_errors++;
        !           937:                                        if (txstatus&TxAborted) {
        !           938:                                                tp->stats.tx_aborted_errors++;
        !           939:                                                outl((TX_DMA_BURST<<8)|0x03000001, ioaddr + TxConfig);
        !           940:                                        }
        !           941:                                        if (txstatus&TxCarrierLost) tp->stats.tx_carrier_errors++;
        !           942:                                        if (txstatus&TxOutOfWindow) tp->stats.tx_window_errors++;
        !           943: #ifdef ETHER_STATS
        !           944:                                        if ((txstatus & 0x0f000000) == 0x0f000000)
        !           945:                                                tp->stats.collisions16++;
        !           946: #endif
        !           947:                                } else {
        !           948: #ifdef ETHER_STATS
        !           949:                                        /* No count for tp->stats.tx_deferred */
        !           950: #endif
        !           951:                                        if (txstatus & TxUnderrun) {
        !           952:                                                /* Todo: increase the Tx FIFO threshold. */
        !           953:                                                tp->stats.tx_fifo_errors++;
        !           954:                                        }
        !           955:                                        tp->stats.collisions += (txstatus >> 24) & 15;
        !           956: #if LINUX_VERSION_CODE > 0x20119
        !           957:                                        tp->stats.tx_bytes += txstatus & 0x7ff;
        !           958: #endif
        !           959:                                        tp->stats.tx_packets++;
        !           960:                                }
        !           961: 
        !           962:                                /* Free the original skb. */
        !           963:                                dev_kfree_skb(tp->tx_skbuff[entry], FREE_WRITE);
        !           964:                                tp->tx_skbuff[entry] = 0;
        !           965:                        }
        !           966: 
        !           967: #ifndef final_version
        !           968:                        if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
        !           969:                                printk(KERN_ERR"%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
        !           970:                                           dev->name, dirty_tx, tp->cur_tx, tp->tx_full);
        !           971:                                dirty_tx += NUM_TX_DESC;
        !           972:                        }
        !           973: #endif
        !           974: 
        !           975:                        if (tp->tx_full && dev->tbusy
        !           976:                                && dirty_tx > tp->cur_tx - NUM_TX_DESC) {
        !           977:                                /* The ring is no longer full, clear tbusy. */
        !           978:                                tp->tx_full = 0;
        !           979:                                dev->tbusy = 0;
        !           980:                                mark_bh(NET_BH);
        !           981:                        }
        !           982: 
        !           983:                        tp->dirty_tx = dirty_tx;
        !           984:                }
        !           985: 
        !           986:                /* Check uncommon events with one test. */
        !           987:                if (status & (PCIErr|PCSTimeout |RxUnderrun|RxOverflow|RxFIFOOver
        !           988:                                          |TxErr|RxErr)) {
        !           989:                        /* Update the error count. */
        !           990:                        tp->stats.rx_missed_errors += inl(ioaddr + RxMissed);
        !           991:                        outl(0, ioaddr + RxMissed);
        !           992: 
        !           993:                        if (status & (RxUnderrun | RxOverflow | RxErr | RxFIFOOver))
        !           994:                                tp->stats.rx_errors++;
        !           995: 
        !           996:                        if (status & (PCSTimeout)) tp->stats.rx_length_errors++;
        !           997:                        if (status & (RxUnderrun|RxFIFOOver)) tp->stats.rx_fifo_errors++;
        !           998:                        if (status & RxOverflow) {
        !           999:                                tp->stats.rx_over_errors++;
        !          1000:                                tp->cur_rx = inw(ioaddr + RxBufAddr) % RX_BUF_LEN;
        !          1001:                                outw(tp->cur_rx - 16, ioaddr + RxBufPtr);
        !          1002:                        }
        !          1003:                        /* Error sources cleared above. */
        !          1004:                }
        !          1005:                if (--boguscnt < 0) {
        !          1006:                        printk(KERN_WARNING"%s: Too much work at interrupt, "
        !          1007:                                   "IntrStatus=0x%4.4x.\n",
        !          1008:                                   dev->name, status);
        !          1009:                        /* Clear all interrupt sources. */
        !          1010:                        outw(0xffff, ioaddr + IntrStatus);
        !          1011:                        break;
        !          1012:                }
        !          1013:        } while (1);
        !          1014: 
        !          1015:        if (rtl8129_debug > 3)
        !          1016:                printk(KERN_DEBUG"%s: exiting interrupt, intr_status=%#4.4x.\n",
        !          1017:                           dev->name, inl(ioaddr + IntrStatus));
        !          1018: 
        !          1019:        dev->interrupt = 0;
        !          1020:        clear_bit(0, (void*)&tp->in_interrupt);
        !          1021:        return;
        !          1022: }
        !          1023: 
        !          1024: /* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
        !          1025:    field alignments and semantics. */
        !          1026: static int
        !          1027: rtl8129_rx(struct device *dev)
        !          1028: {
        !          1029:        struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
        !          1030:        int ioaddr = dev->base_addr;
        !          1031:        unsigned char *rx_ring = tp->rx_ring;
        !          1032:        u16 cur_rx = tp->cur_rx;
        !          1033: 
        !          1034:        if (rtl8129_debug > 4)
        !          1035:                printk(KERN_DEBUG"%s: In rtl8129_rx(), current %4.4x BufAddr %4.4x,"
        !          1036:                           " free to %4.4x, Cmd %2.2x.\n",
        !          1037:                           dev->name, cur_rx, inw(ioaddr + RxBufAddr),
        !          1038:                           inw(ioaddr + RxBufPtr), inb(ioaddr + ChipCmd));
        !          1039: 
        !          1040:        while ((inb(ioaddr + ChipCmd) & 1) == 0) {
        !          1041:                int ring_offset = cur_rx % RX_BUF_LEN;
        !          1042:                u32 rx_status = *(u32*)(rx_ring + ring_offset);
        !          1043:                int rx_size = rx_status >> 16;
        !          1044: 
        !          1045:                if (rtl8129_debug > 4) {
        !          1046:                        int i;
        !          1047:                        printk(KERN_DEBUG"%s:  rtl8129_rx() status %4.4x, size %4.4x, cur %4.4x.\n",
        !          1048:                                   dev->name, rx_status, rx_size, cur_rx);
        !          1049:                        printk(KERN_DEBUG"%s: Frame contents ", dev->name);
        !          1050:                        for (i = 0; i < 70; i++)
        !          1051:                                printk(" %2.2x", rx_ring[ring_offset + i]);
        !          1052:                        printk(".\n");
        !          1053:                }
        !          1054:                if (rx_status & RxTooLong) {
        !          1055:                        if (rtl8129_debug > 0)
        !          1056:                                printk(KERN_NOTICE"%s: Oversized Ethernet frame, status %4.4x!\n",
        !          1057:                                           dev->name, rx_status);
        !          1058:                        tp->stats.rx_length_errors++;
        !          1059:                } else if (rx_status &
        !          1060:                                   (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) {
        !          1061:                        if (rtl8129_debug > 1)
        !          1062:                                printk(KERN_DEBUG"%s: Ethernet frame had errors,"
        !          1063:                                           " status %4.4x.\n", dev->name, rx_status);
        !          1064:                        tp->stats.rx_errors++;
        !          1065:                        if (rx_status & (RxBadSymbol|RxBadAlign))
        !          1066:                                tp->stats.rx_frame_errors++;
        !          1067:                        if (rx_status & (RxRunt|RxTooLong)) tp->stats.rx_length_errors++;
        !          1068:                        if (rx_status & RxCRCErr) tp->stats.rx_crc_errors++;
        !          1069:                        /* Reset the receiver, based on RealTek recommendation. (Bug?) */
        !          1070:                        tp->cur_rx = 0;
        !          1071:                        outb(CmdTxEnb, ioaddr + ChipCmd);
        !          1072:                        outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
        !          1073:                        outl((RX_FIFO_THRESH << 13) | (RX_BUF_LEN_IDX << 11) |
        !          1074:                                 (RX_DMA_BURST<<8), ioaddr + RxConfig);
        !          1075:                } else {
        !          1076:                        /* Malloc up new buffer, compatible with net-2e. */
        !          1077:                        /* Omit the four octet CRC from the length. */
        !          1078:                        struct sk_buff *skb;
        !          1079: 
        !          1080:                        skb = dev_alloc_skb(rx_size + 2);
        !          1081:                        if (skb == NULL) {
        !          1082:                                printk(KERN_WARNING"%s: Memory squeeze, deferring packet.\n",
        !          1083:                                           dev->name);
        !          1084:                                /* We should check that some rx space is free.
        !          1085:                                   If not, free one and mark stats->rx_dropped++. */
        !          1086:                                tp->stats.rx_dropped++;
        !          1087:                                break;
        !          1088:                        }
        !          1089:                        skb->dev = dev;
        !          1090:                        skb_reserve(skb, 2);    /* 16 byte align the IP fields. */
        !          1091:                        if (ring_offset+rx_size+4 > RX_BUF_LEN) {
        !          1092:                                int semi_count = RX_BUF_LEN - ring_offset - 4;
        !          1093:                                memcpy(skb_put(skb, semi_count), &rx_ring[ring_offset + 4],
        !          1094:                                           semi_count);
        !          1095:                                memcpy(skb_put(skb, rx_size-semi_count), rx_ring,
        !          1096:                                           rx_size-semi_count);
        !          1097:                                if (rtl8129_debug > 4) {
        !          1098:                                        int i;
        !          1099:                                        printk(KERN_DEBUG"%s:  Frame wrap @%d",
        !          1100:                                                   dev->name, semi_count);
        !          1101:                                        for (i = 0; i < 16; i++)
        !          1102:                                                printk(" %2.2x", rx_ring[i]);
        !          1103:                                        printk(".\n");
        !          1104:                                        memset(rx_ring, 0xcc, 16);
        !          1105:                                }
        !          1106:                        } else
        !          1107:                                memcpy(skb_put(skb, rx_size), &rx_ring[ring_offset + 4],
        !          1108:                                           rx_size);
        !          1109:                        skb->protocol = eth_type_trans(skb, dev);
        !          1110:                        netif_rx(skb);
        !          1111: #if LINUX_VERSION_CODE > 0x20119
        !          1112:                        tp->stats.rx_bytes += rx_size;
        !          1113: #endif
        !          1114:                        tp->stats.rx_packets++;
        !          1115:                }
        !          1116: 
        !          1117:                cur_rx += rx_size + 4;
        !          1118:                cur_rx = (cur_rx + 3) & ~3;
        !          1119:                outw(cur_rx - 16, ioaddr + RxBufPtr);
        !          1120:        }
        !          1121:        if (rtl8129_debug > 4)
        !          1122:                printk(KERN_DEBUG"%s: Done rtl8129_rx(), current %4.4x BufAddr %4.4x,"
        !          1123:                           " free to %4.4x, Cmd %2.2x.\n",
        !          1124:                           dev->name, cur_rx, inw(ioaddr + RxBufAddr),
        !          1125:                           inw(ioaddr + RxBufPtr), inb(ioaddr + ChipCmd));
        !          1126:        tp->cur_rx = cur_rx;
        !          1127:        return 0;
        !          1128: }
        !          1129: 
        !          1130: static int
        !          1131: rtl8129_close(struct device *dev)
        !          1132: {
        !          1133:        int ioaddr = dev->base_addr;
        !          1134:        struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
        !          1135:        int i;
        !          1136: 
        !          1137:        dev->start = 0;
        !          1138:        dev->tbusy = 1;
        !          1139: 
        !          1140:        if (rtl8129_debug > 1)
        !          1141:                printk(KERN_DEBUG"%s: Shutting down ethercard, status was 0x%4.4x.\n",
        !          1142:                           dev->name, inw(ioaddr + IntrStatus));
        !          1143: 
        !          1144:        /* Disable interrupts by clearing the interrupt mask. */
        !          1145:        outw(0x0000, ioaddr + IntrMask);
        !          1146: 
        !          1147:        /* Stop the chip's Tx and Rx DMA processes. */
        !          1148:        outb(0x00, ioaddr + ChipCmd);
        !          1149: 
        !          1150:        /* Update the error counts. */
        !          1151:        tp->stats.rx_missed_errors += inl(ioaddr + RxMissed);
        !          1152:        outl(0, ioaddr + RxMissed);
        !          1153: 
        !          1154:        del_timer(&tp->timer);
        !          1155: 
        !          1156:        free_irq(dev->irq, dev);
        !          1157: 
        !          1158:        for (i = 0; i < NUM_TX_DESC; i++) {
        !          1159:                if (tp->tx_skbuff[i])
        !          1160:                        dev_kfree_skb(tp->tx_skbuff[i], FREE_WRITE);
        !          1161:                tp->tx_skbuff[i] = 0;
        !          1162:        }
        !          1163:        kfree(tp->rx_ring);
        !          1164:        kfree(tp->tx_bufs);
        !          1165: 
        !          1166:        /* Green! Put the chip in low-power mode. */
        !          1167:        outb(0xC0, ioaddr + Cfg9346);
        !          1168:        outb(0x03, ioaddr + Config1);
        !          1169:        outb('H', ioaddr + HltClk);             /* 'R' would leave the clock running. */
        !          1170: 
        !          1171:        MOD_DEC_USE_COUNT;
        !          1172: 
        !          1173:        return 0;
        !          1174: }
        !          1175: 
        !          1176: static struct enet_statistics *
        !          1177: rtl8129_get_stats(struct device *dev)
        !          1178: {
        !          1179:        struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
        !          1180:        int ioaddr = dev->base_addr;
        !          1181: 
        !          1182:        if (dev->start) {
        !          1183:                tp->stats.rx_missed_errors += inl(ioaddr + RxMissed);
        !          1184:                outl(0, ioaddr + RxMissed);
        !          1185:        }
        !          1186: 
        !          1187:        return &tp->stats;
        !          1188: }
        !          1189: 
        !          1190: /* Set or clear the multicast filter for this adaptor.
        !          1191:    Note that we only use exclusion around actually queueing the
        !          1192:    new frame, not around filling tp->setup_frame.  This is non-deterministic
        !          1193:    when re-entered but still correct. */
        !          1194: 
        !          1195: /* The little-endian AUTODIN II ethernet CRC calculation.
        !          1196:    N.B. Do not use for bulk data, use a table-based routine instead.
        !          1197:    This is common code and should be moved to net/core/crc.c */
        !          1198: static unsigned const ethernet_polynomial_le = 0xedb88320U;
        !          1199: static inline unsigned ether_crc_le(int length, unsigned char *data)
        !          1200: {
        !          1201:        unsigned int crc = 0xffffffff;  /* Initial value. */
        !          1202:        while(--length >= 0) {
        !          1203:                unsigned char current_octet = *data++;
        !          1204:                int bit;
        !          1205:                for (bit = 8; --bit >= 0; current_octet >>= 1) {
        !          1206:                        if ((crc ^ current_octet) & 1) {
        !          1207:                                crc >>= 1;
        !          1208:                                crc ^= ethernet_polynomial_le;
        !          1209:                        } else
        !          1210:                                crc >>= 1;
        !          1211:                }
        !          1212:        }
        !          1213:        return crc;
        !          1214: }
        !          1215: 
        !          1216: static void set_rx_mode(struct device *dev)
        !          1217: {
        !          1218:        int ioaddr = dev->base_addr;
        !          1219:        struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
        !          1220:        unsigned char mc_filter[8];              /* Multicast hash filter */
        !          1221:        int i;
        !          1222: 
        !          1223:        if (dev->flags & IFF_PROMISC) {                 /* Set promiscuous. */
        !          1224:                /* Unconditionally log net taps. */
        !          1225:                printk(KERN_NOTICE"%s: Promiscuous mode enabled.\n", dev->name);
        !          1226:                memset(mc_filter, 0xff, sizeof(mc_filter));
        !          1227:                outb(0x0F, ioaddr + RxConfig);
        !          1228:        } else if ((dev->mc_count > 1000)  ||  (dev->flags & IFF_ALLMULTI)) {
        !          1229:                /* Too many to filter perfectly -- accept all multicasts. */
        !          1230:                memset(mc_filter, 0xff, sizeof(mc_filter));
        !          1231:                outb(0x0E, ioaddr + RxConfig);
        !          1232:        } else if (dev->mc_count == 0) {
        !          1233:                outb(0x0A, ioaddr + RxConfig);
        !          1234:                return;
        !          1235:        } else {
        !          1236:                struct dev_mc_list *mclist;
        !          1237: 
        !          1238:                memset(mc_filter, 0, sizeof(mc_filter));
        !          1239:                for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
        !          1240:                         i++, mclist = mclist->next)
        !          1241:                        set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f,
        !          1242:                                        mc_filter);
        !          1243:        }
        !          1244:        /* ToDo: perhaps we need to stop the Tx and Rx process here? */
        !          1245:        if (memcmp(mc_filter, tp->mc_filter, sizeof(mc_filter))) {
        !          1246:                for (i = 0; i < 2; i++)
        !          1247:                        outl(((u32 *)mc_filter)[i], ioaddr + MAR0 + i*4);
        !          1248:                memcpy(tp->mc_filter, mc_filter, sizeof(mc_filter));
        !          1249:        }
        !          1250:        if (rtl8129_debug > 3)
        !          1251:                printk(KERN_DEBUG"%s:   set_rx_mode(%4.4x) done -- Rx config %8.8x.\n",
        !          1252:                           dev->name, dev->flags, inl(ioaddr + RxConfig));
        !          1253:        return;
        !          1254: }
        !          1255: 
        !          1256: #ifdef MODULE
        !          1257: 
        !          1258: /* An additional parameter that may be passed in... */
        !          1259: static int debug = -1;
        !          1260: 
        !          1261: int
        !          1262: init_module(void)
        !          1263: {
        !          1264:        int cards_found;
        !          1265: 
        !          1266:        if (debug >= 0)
        !          1267:                rtl8129_debug = debug;
        !          1268: 
        !          1269:        root_rtl8129_dev = NULL;
        !          1270:        cards_found = rtl8139_probe(0);
        !          1271: 
        !          1272:        return cards_found ? 0 : -ENODEV;
        !          1273: }
        !          1274: 
        !          1275: void
        !          1276: cleanup_module(void)
        !          1277: {
        !          1278:        struct device *next_dev;
        !          1279: 
        !          1280:        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
        !          1281:        while (root_rtl8129_dev) {
        !          1282:                next_dev = ((struct rtl8129_private *)root_rtl8129_dev->priv)->next_module;
        !          1283:                unregister_netdev(root_rtl8129_dev);
        !          1284:                release_region(root_rtl8129_dev->base_addr, RTL8129_TOTAL_SIZE);
        !          1285:                kfree(root_rtl8129_dev);
        !          1286:                root_rtl8129_dev = next_dev;
        !          1287:        }
        !          1288: }
        !          1289: 
        !          1290: #endif  /* MODULE */
        !          1291: 
        !          1292: /*
        !          1293:  * Local variables:
        !          1294:  *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c rtl8139.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
        !          1295:  *  SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c rtl8139.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
        !          1296:  *  c-indent-level: 4
        !          1297:  *  c-basic-offset: 4
        !          1298:  *  tab-width: 4
        !          1299:  * End:
        !          1300:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.