Annotation of Gnu-Mach/i386/i386at/gpl/linux/net/tulip.c, revision 1.1.1.1

1.1       root        1: /* tulip.c: A DEC 21040 ethernet driver for linux. */
                      2: /*
                      3:    NOTICE: this version works with kernels 1.1.82 and later only!
                      4:        Written 1994,1995 by Donald Becker.
                      5: 
                      6:        This software may be used and distributed according to the terms
                      7:        of the GNU Public License, incorporated herein by reference.
                      8: 
                      9:        This driver is for the SMC EtherPower PCI ethernet adapter.
                     10:        It should work with most other DEC 21*40-based ethercards.
                     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: 
                     17: static const char *version = "tulip.c:v0.05 1/20/95 [email protected]\n";
                     18: 
                     19: #include <linux/module.h>
                     20: 
                     21: #include <linux/kernel.h>
                     22: #include <linux/sched.h>
                     23: #include <linux/string.h>
                     24: #include <linux/ptrace.h>
                     25: #include <linux/errno.h>
                     26: #include <linux/ioport.h>
                     27: #include <linux/malloc.h>
                     28: #include <linux/interrupt.h>
                     29: #include <linux/pci.h>
                     30: #include <linux/bios32.h>
                     31: #include <asm/bitops.h>
                     32: #include <asm/io.h>
                     33: #include <asm/dma.h>
                     34: 
                     35: #include <linux/netdevice.h>
                     36: #include <linux/etherdevice.h>
                     37: #include <linux/skbuff.h>
                     38: 
                     39: /* The total size is unusually large: The 21040 aligns each of its 16
                     40:    longword-wide registers on a quadword boundary. */
                     41: #define TULIP_TOTAL_SIZE 0x80
                     42: 
                     43: #ifdef HAVE_DEVLIST
                     44: struct netdev_entry tulip_drv =
                     45: {"Tulip", tulip_pci_probe, TULIP_TOTAL_SIZE, NULL};
                     46: #endif
                     47: 
                     48: #define TULIP_DEBUG 1
                     49: #ifdef TULIP_DEBUG
                     50: int tulip_debug = TULIP_DEBUG;
                     51: #else
                     52: int tulip_debug = 1;
                     53: #endif
                     54: 
                     55: /*
                     56:                                Theory of Operation
                     57: 
                     58: I. Board Compatibility
                     59: 
                     60: This device driver is designed for the DECchip 21040 "Tulip", Digital's
                     61: single-chip ethernet controller for PCI, as used on the SMC EtherPower
                     62: ethernet adapter.
                     63: 
                     64: II. Board-specific settings
                     65: 
                     66: PCI bus devices are configured by the system at boot time, so no jumpers
                     67: need to be set on the board.  The system BIOS should be set to assign the
                     68: PCI INTA signal to an otherwise unused system IRQ line.  While it's
                     69: physically possible to shared PCI interrupt lines, the kernel doesn't
                     70: support it. 
                     71: 
                     72: III. Driver operation
                     73: 
                     74: IIIa. Ring buffers
                     75: The Tulip can use either ring buffers or lists of Tx and Rx descriptors.
                     76: The current driver uses a statically allocated Rx ring of descriptors and
                     77: buffers, and a list of the Tx buffers.
                     78: 
                     79: IIIC. Synchronization
                     80: The driver runs as two independent, single-threaded flows of control.  One
                     81: is the send-packet routine, which enforces single-threaded use by the
                     82: dev->tbusy flag.  The other thread is the interrupt handler, which is single
                     83: threaded by the hardware and other software.
                     84: 
                     85: The send packet thread has partial control over the Tx ring and 'dev->tbusy'
                     86: flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
                     87: queue slot is empty, it clears the tbusy flag when finished otherwise it sets
                     88: the 'tp->tx_full' flag.
                     89: 
                     90: The interrupt handler has exclusive control over the Rx ring and records stats
                     91: from the Tx ring.  (The Tx-done interrupt can't be selectively turned off, so
                     92: we can't avoid the interrupt overhead by having the Tx routine reap the Tx
                     93: stats.)         After reaping the stats, it marks the queue entry as empty by setting
                     94: the 'base' to zero.     Iff the 'tp->tx_full' flag is set, it clears both the
                     95: tx_full and tbusy flags.
                     96: 
                     97: IV. Notes
                     98: 
                     99: Thanks to Duke Kamstra of SMC for providing an EtherPower board.
                    100: 
                    101: The DEC databook doesn't document which Rx filter settings accept broadcast
                    102: packets.  Nor does it document how to configure the part to configure the
                    103: serial subsystem for normal (vs. loopback) operation or how to have it
                    104: autoswitch between internal 10baseT, SIA and AUI transceivers.
                    105: 
                    106: The databook claims that CSR13, CSR14, and CSR15 should each be the last
                    107: register of the set CSR12-15 written.   Hmmm, now how is that possible?
                    108: */
                    109: 
                    110: #define DEC_VENDOR_ID  0x1011          /* Hex 'D' :-> */
                    111: #define DEC_21040_ID   0x0002          /* Change for 21140. */
                    112: 
                    113: /* Keep the ring sizes a power of two for efficiency. */
                    114: #define TX_RING_SIZE   4
                    115: #define RX_RING_SIZE   4
                    116: #define PKT_BUF_SZ             1536                    /* Size of each temporary Rx buffer.*/
                    117: 
                    118: /* Offsets to the Command and Status Registers, "CSRs".  All accesses
                    119:    must be longword instructions and quadword aligned. */
                    120: enum tulip_offsets {
                    121:        CSR0=0,    CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
                    122:        CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
                    123:        CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 };
                    124: 
                    125: /* The Tulip Rx and Tx buffer descriptors. */
                    126: struct tulip_rx_desc {
                    127:        int status;
                    128:        int length;
                    129:        char *buffer1, *buffer2;                        /* We use only buffer 1.  */
                    130: };
                    131: 
                    132: struct tulip_tx_desc {
                    133:        int status;
                    134:        int length;
                    135:        char *buffer1, *buffer2;                        /* We use only buffer 1.  */
                    136: };
                    137: 
                    138: struct tulip_private {
                    139:        char devname[8];                        /* Used only for kernel debugging. */
                    140:        struct tulip_rx_desc rx_ring[RX_RING_SIZE];
                    141:        struct tulip_tx_desc tx_ring[TX_RING_SIZE];
                    142:        /* The saved address of a sent-in-place packet/buffer, for skfree(). */
                    143:        struct sk_buff* tx_skbuff[TX_RING_SIZE];
                    144:        long rx_buffs;                          /* Address of temporary Rx buffers. */
                    145:        struct enet_statistics stats;
                    146:        int setup_frame[48];            /* Pseudo-Tx frame to init address table. */
                    147:        unsigned int cur_rx, cur_tx;            /* The next free ring entry */
                    148:        unsigned int dirty_rx, dirty_tx;        /* The ring entries to be free()ed. */
                    149:        unsigned int tx_full:1;
                    150:        int pad0, pad1;                                         /* Used for 8-byte alignment */
                    151: };
                    152: 
                    153: static void tulip_probe1(int ioaddr, int irq);
                    154: static int tulip_open(struct device *dev);
                    155: static void tulip_init_ring(struct device *dev);
                    156: static int tulip_start_xmit(struct sk_buff *skb, struct device *dev);
                    157: static int tulip_rx(struct device *dev);
                    158: static void tulip_interrupt(int irq, struct pt_regs *regs);
                    159: static int tulip_close(struct device *dev);
                    160: static struct enet_statistics *tulip_get_stats(struct device *dev);
                    161: static void set_multicast_list(struct device *dev);
                    162: static int set_mac_address(struct device *dev, void *addr);
                    163: 
                    164: 
                    165: 
                    166: #ifndef MODULE
                    167: /* This 21040 probe is unlike most other board probes.  We can use memory
                    168:    efficiently by allocating a large contiguous region and dividing it
                    169:    ourselves.  This is done by having the initialization occur before
                    170:    the 'kmalloc()' memory management system is started. */
                    171: 
                    172: int dec21040_init(void)
                    173: {
                    174: 
                    175:     if (pcibios_present()) {
                    176:            int pci_index;
                    177:                for (pci_index = 0; pci_index < 8; pci_index++) {
                    178:                        unsigned char pci_bus, pci_device_fn, pci_irq_line;
                    179:                        unsigned long pci_ioaddr;
                    180:                
                    181:                        if (pcibios_find_device (DEC_VENDOR_ID, DEC_21040_ID, pci_index,
                    182:                                                                         &pci_bus, &pci_device_fn) != 0)
                    183:                                break;
                    184:                        pcibios_read_config_byte(pci_bus, pci_device_fn,
                    185:                                                                         PCI_INTERRUPT_LINE, &pci_irq_line);
                    186:                        pcibios_read_config_dword(pci_bus, pci_device_fn,
                    187:                                                                          PCI_BASE_ADDRESS_0, &pci_ioaddr);
                    188:                        /* Remove I/O space marker in bit 0. */
                    189:                        pci_ioaddr &= ~3;
                    190:                        if (tulip_debug > 2)
                    191:                                printk("Found DEC PCI Tulip at I/O %#lx, IRQ %d.\n",
                    192:                                           pci_ioaddr, pci_irq_line);
                    193:                        tulip_probe1(pci_ioaddr, pci_irq_line);
                    194:                }
                    195:        }
                    196: 
                    197:        return 0;
                    198: }
                    199: #endif
                    200: #ifdef MODULE
                    201: static int tulip_probe(struct device *dev)
                    202: {
                    203:        printk("tulip: This driver does not yet install properly from module!\n");
                    204:        return -1;
                    205: }
                    206: #endif
                    207: 
                    208: static void tulip_probe1(int ioaddr, int irq)
                    209: {
                    210:        static int did_version = 0;                     /* Already printed version info. */
                    211:        struct device *dev;
                    212:        struct tulip_private *tp;
                    213:        int i;
                    214: 
                    215:        if (tulip_debug > 0  &&  did_version++ == 0)
                    216:                printk(version);
                    217: 
                    218:        dev = init_etherdev(0, 0);
                    219: 
                    220:        printk("%s: DEC 21040 Tulip at %#3x,", dev->name, ioaddr);
                    221: 
                    222:        /* Stop the chip's Tx and Rx processes. */
                    223:        outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6);
                    224:        /* Clear the missed-packet counter. */
                    225:        inl(ioaddr + CSR8) & 0xffff;
                    226: 
                    227:        /* The station address ROM is read byte serially.  The register must
                    228:           be polled, waiting for the value to be read bit serially from the
                    229:           EEPROM.
                    230:           */
                    231:        outl(0, ioaddr + CSR9);         /* Reset the pointer with a dummy write. */
                    232:        for (i = 0; i < 6; i++) {
                    233:                int value, boguscnt = 100000;
                    234:                do
                    235:                        value = inl(ioaddr + CSR9);
                    236:                while (value < 0  && --boguscnt > 0);
                    237:                printk(" %2.2x", dev->dev_addr[i] = value);
                    238:        }
                    239:        printk(", IRQ %d\n", irq);
                    240: 
                    241:        /* We do a request_region() only to register /proc/ioports info. */
                    242:        request_region(ioaddr, TULIP_TOTAL_SIZE, "DEC Tulip Ethernet");
                    243: 
                    244:        dev->base_addr = ioaddr;
                    245:        dev->irq = irq;
                    246: 
                    247:        /* Make certain the data structures are quadword aligned. */
                    248:        tp = kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA);
                    249:        dev->priv = tp;
                    250:        tp->rx_buffs = kmalloc(PKT_BUF_SZ*RX_RING_SIZE, GFP_KERNEL | GFP_DMA);
                    251: 
                    252:        /* The Tulip-specific entries in the device structure. */
                    253:        dev->open = &tulip_open;
                    254:        dev->hard_start_xmit = &tulip_start_xmit;
                    255:        dev->stop = &tulip_close;
                    256:        dev->get_stats = &tulip_get_stats;
                    257:        dev->set_multicast_list = &set_multicast_list;
                    258:        dev->set_mac_address = &set_mac_address;
                    259: 
                    260:        return;
                    261: }
                    262: 
                    263: 
                    264: static int
                    265: tulip_open(struct device *dev)
                    266: {
                    267:        struct tulip_private *tp = (struct tulip_private *)dev->priv;
                    268:        int ioaddr = dev->base_addr;
                    269: 
                    270:        /* Reset the chip, holding bit 0 set at least 10 PCI cycles. */
                    271:        outl(0xfff80001, ioaddr + CSR0);
                    272:        SLOW_DOWN_IO;
                    273:        /* Deassert reset.  Set 8 longword cache alignment, 8 longword burst.
                    274:           Cache alignment bits 15:14        Burst length 13:8
                    275:        0000    No alignment  0x00000000 unlimited              0800 8 longwords
                    276:                4000    8  longwords            0100 1 longword         1000 16 longwords
                    277:                8000    16 longwords            0200 2 longwords        2000 32 longwords
                    278:                C000    32  longwords           0400 4 longwords
                    279:           Wait the specified 50 PCI cycles after a reset by initializing
                    280:           Tx and Rx queues and the address filter list. */
                    281:        outl(0xfff84800, ioaddr + CSR0);
                    282: 
                    283:        if (irq2dev_map[dev->irq] != NULL
                    284:                || (irq2dev_map[dev->irq] = dev) == NULL
                    285:                || dev->irq == 0
                    286:                || request_irq(dev->irq, &tulip_interrupt, 0, "DEC 21040 Tulip")) {
                    287:                return -EAGAIN;
                    288:        }
                    289: 
                    290:        if (tulip_debug > 1)
                    291:                printk("%s: tulip_open() irq %d.\n", dev->name, dev->irq);
                    292: 
                    293:        tulip_init_ring(dev);
                    294: 
                    295:        /* Fill the whole address filter table with our physical address. */
                    296:        { 
                    297:                unsigned short *eaddrs = (unsigned short *)dev->dev_addr;
                    298:                int *setup_frm = tp->setup_frame, i;
                    299: 
                    300:                /* You must add the broadcast address when doing perfect filtering! */
                    301:                *setup_frm++ = 0xffff;
                    302:                *setup_frm++ = 0xffff;
                    303:                *setup_frm++ = 0xffff;
                    304:                /* Fill the rest of the accept table with our physical address. */
                    305:                for (i = 1; i < 16; i++) {
                    306:                        *setup_frm++ = eaddrs[0];
                    307:                        *setup_frm++ = eaddrs[1];
                    308:                        *setup_frm++ = eaddrs[2];
                    309:                }
                    310:                /* Put the setup frame on the Tx list. */
                    311:                tp->tx_ring[0].length = 0x08000000 | 192;
                    312:                tp->tx_ring[0].buffer1 = (char *)tp->setup_frame;
                    313:                tp->tx_ring[0].buffer2 = 0;
                    314:                tp->tx_ring[0].status = 0x80000000;
                    315: 
                    316:                tp->cur_tx++, tp->dirty_tx++;
                    317:        }
                    318: 
                    319:        outl((int)tp->rx_ring, ioaddr + CSR3);
                    320:        outl((int)tp->tx_ring, ioaddr + CSR4);
                    321: 
                    322:        /* Turn on the xcvr interface. */
                    323:        outl(0x00000000, ioaddr + CSR13);
                    324:        outl(0x00000004, ioaddr + CSR13);
                    325: 
                    326:        /* Start the chip's Tx and Rx processes. */
                    327:        outl(0xfffe2002, ioaddr + CSR6);
                    328: 
                    329:        /* Trigger an immediate transmit demand to process the setup frame. */
                    330:        outl(0, ioaddr + CSR1);
                    331: 
                    332:        dev->tbusy = 0;
                    333:        dev->interrupt = 0;
                    334:        dev->start = 1;
                    335: 
                    336:        /* Enable interrupts by setting the interrupt mask. */
                    337:        outl(0xFFFFFFFF, ioaddr + CSR7);
                    338: 
                    339:        if (tulip_debug > 2) {
                    340:                printk("%s: Done tulip_open(), CSR0 %8.8x, CSR13 %8.8x.\n",
                    341:                           dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR13));
                    342:        }
                    343:        MOD_INC_USE_COUNT;
                    344:        return 0;
                    345: }
                    346: 
                    347: /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
                    348: static void
                    349: tulip_init_ring(struct device *dev)
                    350: {
                    351:        struct tulip_private *tp = (struct tulip_private *)dev->priv;
                    352:        int i;
                    353: 
                    354:        tp->tx_full = 0;
                    355:        tp->cur_rx = tp->cur_tx = 0;
                    356:        tp->dirty_rx = tp->dirty_tx = 0;
                    357: 
                    358:        for (i = 0; i < RX_RING_SIZE; i++) {
                    359:                tp->rx_ring[i].status = 0x80000000;     /* Owned by Tulip chip */
                    360:                tp->rx_ring[i].length = PKT_BUF_SZ;
                    361:                tp->rx_ring[i].buffer1 = (char *)(tp->rx_buffs + i*PKT_BUF_SZ);
                    362:                tp->rx_ring[i].buffer2 = (char *)&tp->rx_ring[i+1];
                    363:        }
                    364:        /* Mark the last entry as wrapping the ring. */ 
                    365:        tp->rx_ring[i-1].length = PKT_BUF_SZ | 0x02000000;
                    366:        tp->rx_ring[i-1].buffer2 = (char *)&tp->rx_ring[0];
                    367: 
                    368:        /* The Tx buffer descriptor is filled in as needed, but we
                    369:           do need to clear the ownership bit. */
                    370:        for (i = 0; i < TX_RING_SIZE; i++) {
                    371:                tp->tx_ring[i].status = 0x00000000;
                    372:        }
                    373: }
                    374: 
                    375: static int
                    376: tulip_start_xmit(struct sk_buff *skb, struct device *dev)
                    377: {
                    378:        struct tulip_private *tp = (struct tulip_private *)dev->priv;
                    379:        int ioaddr = dev->base_addr;
                    380:        int entry;
                    381: 
                    382:        /* Transmitter timeout, serious problems. */
                    383:        if (dev->tbusy) {
                    384:                int tickssofar = jiffies - dev->trans_start;
                    385:                int i;
                    386:                if (tickssofar < 20)
                    387:                        return 1;
                    388:                printk("%s: transmit timed out, status %8.8x, SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
                    389:                           dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12),
                    390:                           inl(ioaddr + CSR13), inl(ioaddr + CSR14), inl(ioaddr + CSR15));
                    391:                printk("  Rx ring %8.8x: ", (int)tp->rx_ring);
                    392:                for (i = 0; i < RX_RING_SIZE; i++)
                    393:                        printk(" %8.8x", (unsigned int)tp->rx_ring[i].status);
                    394:                printk("\n  Tx ring %8.8x: ", (int)tp->tx_ring);
                    395:                for (i = 0; i < TX_RING_SIZE; i++)
                    396:                        printk(" %8.8x", (unsigned int)tp->tx_ring[i].status);
                    397:                printk("\n");
                    398: 
                    399:                tp->stats.tx_errors++;
                    400:                /* We should reinitialize the hardware here. */
                    401:                dev->tbusy=0;
                    402:                dev->trans_start = jiffies;
                    403:                return 0;
                    404:        }
                    405: 
                    406:        if (skb == NULL || skb->len <= 0) {
                    407:                printk("%s: Obsolete driver layer request made: skbuff==NULL.\n",
                    408:                           dev->name);
                    409:                dev_tint(dev);
                    410:                return 0;
                    411:        }
                    412: 
                    413:        /* Block a timer-based transmit from overlapping.  This could better be
                    414:           done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
                    415:           If this ever occurs the queue layer is doing something evil! */
                    416:        if (set_bit(0, (void*)&dev->tbusy) != 0) {
                    417:                printk("%s: Transmitter access conflict.\n", dev->name);
                    418:                return 1;
                    419:        }
                    420: 
                    421:        /* Caution: the write order is important here, set the base address
                    422:           with the "ownership" bits last. */
                    423: 
                    424:        /* Calculate the next Tx descriptor entry. */
                    425:        entry = tp->cur_tx % TX_RING_SIZE;
                    426: 
                    427:        tp->tx_full = 1;
                    428:        tp->tx_skbuff[entry] = skb;
                    429:        tp->tx_ring[entry].length = skb->len |
                    430:                (entry == TX_RING_SIZE-1 ? 0xe2000000 : 0xe0000000);
                    431:        tp->tx_ring[entry].buffer1 = skb->data;
                    432:        tp->tx_ring[entry].buffer2 = 0;
                    433:        tp->tx_ring[entry].status = 0x80000000; /* Pass ownership to the chip. */
                    434: 
                    435:        tp->cur_tx++;
                    436: 
                    437:        /* Trigger an immediate transmit demand. */
                    438:        outl(0, ioaddr + CSR1);
                    439: 
                    440:        dev->trans_start = jiffies;
                    441: 
                    442:        return 0;
                    443: }
                    444: 
                    445: /* The interrupt handler does all of the Rx thread work and cleans up
                    446:    after the Tx thread. */
                    447: static void tulip_interrupt(int irq, struct pt_regs *regs)
                    448: {
                    449:        struct device *dev = (struct device *)(irq2dev_map[irq]);
                    450:        struct tulip_private *lp;
                    451:        int csr5, ioaddr, boguscnt=10;
                    452: 
                    453:        if (dev == NULL) {
                    454:                printk ("tulip_interrupt(): irq %d for unknown device.\n", irq);
                    455:                return;
                    456:        }
                    457: 
                    458:        ioaddr = dev->base_addr;
                    459:        lp = (struct tulip_private *)dev->priv;
                    460:        if (dev->interrupt)
                    461:                printk("%s: Re-entering the interrupt handler.\n", dev->name);
                    462: 
                    463:        dev->interrupt = 1;
                    464: 
                    465:        do {
                    466:                csr5 = inl(ioaddr + CSR5);
                    467:                /* Acknowledge all of the current interrupt sources ASAP. */
                    468:                outl(csr5 & 0x0001ffff, ioaddr + CSR5);
                    469: 
                    470:                if (tulip_debug > 4)
                    471:                        printk("%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
                    472:                                   dev->name, csr5, inl(dev->base_addr + CSR5));
                    473: 
                    474:                if ((csr5 & 0x00018000) == 0)
                    475:                        break;
                    476: 
                    477:                if (csr5 & 0x0040)                      /* Rx interrupt */
                    478:                        tulip_rx(dev);
                    479: 
                    480:                if (csr5 & 0x0001) {            /* Tx-done interrupt */
                    481:                        int dirty_tx = lp->dirty_tx;
                    482: 
                    483:                        while (dirty_tx < lp->cur_tx) {
                    484:                                int entry = dirty_tx % TX_RING_SIZE;
                    485:                                int status = lp->tx_ring[entry].status;
                    486: 
                    487:                                if (status < 0)
                    488:                                        break;                  /* It still hasn't been Txed */
                    489: 
                    490:                                if (status & 0x8000) {
                    491:                                        /* There was an major error, log it. */
                    492:                                        lp->stats.tx_errors++;
                    493:                                        if (status & 0x4104) lp->stats.tx_aborted_errors++;
                    494:                                        if (status & 0x0C00) lp->stats.tx_carrier_errors++;
                    495:                                        if (status & 0x0200) lp->stats.tx_window_errors++;
                    496:                                        if (status & 0x0002) lp->stats.tx_fifo_errors++;
                    497:                                        if (status & 0x0080) lp->stats.tx_heartbeat_errors++;
                    498: #ifdef ETHER_STATS
                    499:                                        if (status & 0x0100) lp->stats.collisions16++;
                    500: #endif
                    501:                                } else {
                    502: #ifdef ETHER_STATS
                    503:                                        if (status & 0x0001) lp->stats.tx_deferred++;
                    504: #endif
                    505:                                        lp->stats.collisions += (status >> 3) & 15;
                    506:                                        lp->stats.tx_packets++;
                    507:                                }
                    508: 
                    509:                                /* Free the original skb. */
                    510:                                dev_kfree_skb(lp->tx_skbuff[entry], FREE_WRITE);
                    511:                                dirty_tx++;
                    512:                        }
                    513: 
                    514: #ifndef final_version
                    515:                        if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
                    516:                                printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
                    517:                                           dirty_tx, lp->cur_tx, lp->tx_full);
                    518:                                dirty_tx += TX_RING_SIZE;
                    519:                        }
                    520: #endif
                    521: 
                    522:                        if (lp->tx_full && dev->tbusy
                    523:                                && dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
                    524:                                /* The ring is no longer full, clear tbusy. */
                    525:                                lp->tx_full = 0;
                    526:                                dev->tbusy = 0;
                    527:                                mark_bh(NET_BH);
                    528:                        }
                    529: 
                    530:                        lp->dirty_tx = dirty_tx;
                    531:                }
                    532: 
                    533:                /* Log errors. */
                    534:                if (csr5 & 0x8000) {    /* Abnormal error summary bit. */
                    535:                        if (csr5 & 0x0008) lp->stats.tx_errors++; /* Tx babble. */
                    536:                        if (csr5 & 0x0100) {            /* Missed a Rx frame. */
                    537:                                lp->stats.rx_errors++;
                    538:                                lp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
                    539:                        }
                    540:                        if (csr5 & 0x0800) {
                    541:                                printk("%s: Something Wicked happened! %8.8x.\n",
                    542:                                           dev->name, csr5);
                    543:                                /* Hmmmmm, it's not clear what to do here. */
                    544:                        }
                    545:                }
                    546:                if (--boguscnt < 0) {
                    547:                        printk("%s: Too much work at interrupt, csr5=0x%8.8x.\n",
                    548:                                   dev->name, csr5);
                    549:                        /* Clear all interrupt sources. */
                    550:                        outl(0x0001ffff, ioaddr + CSR5);
                    551:                        break;
                    552:                }
                    553:        } while (1);
                    554: 
                    555:        if (tulip_debug > 3)
                    556:                printk("%s: exiting interrupt, csr5=%#4.4x.\n",
                    557:                           dev->name, inl(ioaddr + CSR5));
                    558: 
                    559:        /* Special code for testing *only*. */
                    560:        {
                    561:                static int stopit = 10;
                    562:                if (dev->start == 0  &&  --stopit < 0) {
                    563:                        printk("%s: Emergency stop, looping startup interrupt.\n",
                    564:                                   dev->name);
                    565:                        free_irq(irq);
                    566:                }
                    567:        }
                    568: 
                    569:        dev->interrupt = 0;
                    570:        return;
                    571: }
                    572: 
                    573: static int
                    574: tulip_rx(struct device *dev)
                    575: {
                    576:        struct tulip_private *lp = (struct tulip_private *)dev->priv;
                    577:        int entry = lp->cur_rx % RX_RING_SIZE;
                    578:        int i;
                    579:                
                    580:        if (tulip_debug > 4)
                    581:                printk(" In tulip_rx().\n");
                    582:        /* If we own the next entry, it's a new packet. Send it up. */
                    583:        while (lp->rx_ring[entry].status >= 0) {
                    584:                int status = lp->rx_ring[entry].status;
                    585: 
                    586:                if (tulip_debug > 4)
                    587:                        printk("  tulip_rx() status was %8.8x.\n", status);
                    588:                if ((status & 0x0300) != 0x0300) {
                    589:                        printk("%s: Ethernet frame spanned multiple buffers, status %8.8x!\n",
                    590:                                   dev->name, status);
                    591:                } else if (status & 0x8000) {
                    592:                        /* There was a fatal error. */
                    593:                        lp->stats.rx_errors++; /* end of a packet.*/
                    594:                        if (status & 0x0890) lp->stats.rx_length_errors++;
                    595:                        if (status & 0x0004) lp->stats.rx_frame_errors++;
                    596:                        if (status & 0x0002) lp->stats.rx_crc_errors++;
                    597:                        if (status & 0x0001) lp->stats.rx_fifo_errors++;
                    598:                } else {
                    599:                        /* Malloc up new buffer, compatible with net-2e. */
                    600:                        short pkt_len = lp->rx_ring[entry].status >> 16;
                    601:                        struct sk_buff *skb;
                    602: 
                    603:                        skb = dev_alloc_skb(pkt_len+2);
                    604:                        if (skb == NULL) {
                    605:                                printk("%s: Memory squeeze, deferring packet.\n", dev->name);
                    606:                                /* Check that at least two ring entries are free.
                    607:                                   If not, free one and mark stats->rx_dropped++. */
                    608:                                for (i=0; i < RX_RING_SIZE; i++)
                    609:                                        if (lp->rx_ring[(entry+i) % RX_RING_SIZE].status < 0)
                    610:                                                break;
                    611: 
                    612:                                if (i > RX_RING_SIZE -2) {
                    613:                                        lp->stats.rx_dropped++;
                    614:                                        lp->rx_ring[entry].status = 0x80000000;
                    615:                                        lp->cur_rx++;
                    616:                                }
                    617:                                break;
                    618:                        }
                    619:                        skb->dev = dev;
                    620:                        skb_reserve(skb,2);     /* 16 byte align the data fields */
                    621:                        memcpy(skb_put(skb,pkt_len), lp->rx_ring[entry].buffer1, pkt_len);
                    622:                        skb->protocol=eth_type_trans(skb,dev);
                    623:                        netif_rx(skb);
                    624:                        lp->stats.rx_packets++;
                    625:                }
                    626: 
                    627:                lp->rx_ring[entry].status = 0x80000000;
                    628:                entry = (++lp->cur_rx) % RX_RING_SIZE;
                    629:        }
                    630: 
                    631:        return 0;
                    632: }
                    633: 
                    634: static int
                    635: tulip_close(struct device *dev)
                    636: {
                    637:        int ioaddr = dev->base_addr;
                    638:        struct tulip_private *tp = (struct tulip_private *)dev->priv;
                    639: 
                    640:        dev->start = 0;
                    641:        dev->tbusy = 1;
                    642: 
                    643:        if (tulip_debug > 1)
                    644:                printk("%s: Shutting down ethercard, status was %2.2x.\n",
                    645:                           dev->name, inl(ioaddr + CSR5));
                    646: 
                    647:        /* Disable interrupts by clearing the interrupt mask. */
                    648:        outl(0x00000000, ioaddr + CSR7);
                    649:        /* Stop the chip's Tx and Rx processes. */
                    650:        outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6);
                    651: 
                    652:        tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
                    653: 
                    654:        free_irq(dev->irq);
                    655:        irq2dev_map[dev->irq] = 0;
                    656: 
                    657:        MOD_DEC_USE_COUNT;
                    658:        return 0;
                    659: }
                    660: 
                    661: static struct enet_statistics *
                    662: tulip_get_stats(struct device *dev)
                    663: {
                    664:        struct tulip_private *tp = (struct tulip_private *)dev->priv;
                    665:        short ioaddr = dev->base_addr;
                    666: 
                    667:        tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
                    668: 
                    669:        return &tp->stats;
                    670: }
                    671: 
                    672: /*
                    673:  *     Set or clear the multicast filter for this adaptor.
                    674:  */
                    675: 
                    676: static void set_multicast_list(struct device *dev)
                    677: {
                    678:        short ioaddr = dev->base_addr;
                    679:        int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
                    680: 
                    681:        if (dev->flags&IFF_PROMISC) 
                    682:        {                       /* Set promiscuous. */
                    683:                outl(csr6 | 0x00C0, ioaddr + CSR6);
                    684:                /* Log any net taps. */
                    685:                printk("%s: Promiscuous mode enabled.\n", dev->name);
                    686:        }
                    687:        else if (dev->mc_count > 15 || (dev->flags&IFF_ALLMULTI)) 
                    688:        {
                    689:                /* Too many to filter perfectly -- accept all multicasts. */
                    690:                outl(csr6 | 0x0080, ioaddr + CSR6);
                    691:        }
                    692:        else
                    693:        {
                    694:                struct tulip_private *tp = (struct tulip_private *)dev->priv;
                    695:                struct dev_mc_list *dmi=dev->mc_list;
                    696:                int *setup_frm = tp->setup_frame;
                    697:                unsigned short *eaddrs;
                    698:                int i;
                    699: 
                    700:                /* We have <= 15 addresses that we can use the wonderful
                    701:                   16 address perfect filtering of the Tulip.  Note that only
                    702:                   the low shortword of setup_frame[] is valid. */
                    703:                outl(csr6 | 0x0000, ioaddr + CSR6);
                    704:                i=0;
                    705:                while(dmi) 
                    706:                {
                    707:                        eaddrs=(unsigned short *)dmi->dmi_addr;
                    708:                        dmi=dmi->next;
                    709:                        i++;
                    710:                        *setup_frm++ = *eaddrs++;
                    711:                        *setup_frm++ = *eaddrs++;
                    712:                        *setup_frm++ = *eaddrs++;
                    713:                }
                    714:                /* Fill the rest of the table with our physical address. */
                    715:                eaddrs = (unsigned short *)dev->dev_addr;
                    716:                do {
                    717:                        *setup_frm++ = eaddrs[0];
                    718:                        *setup_frm++ = eaddrs[1];
                    719:                        *setup_frm++ = eaddrs[2];
                    720:                } while (++i < 16);
                    721: 
                    722:                /* Now add this frame to the Tx list. */
                    723:        }
                    724: }
                    725: 
                    726: static int
                    727: set_mac_address(struct device *dev, void *addr)
                    728: {
                    729:        int i;
                    730:        struct sockaddr *sa=(struct sockaddr *)addr;
                    731:        if (dev->start)
                    732:                return -EBUSY;
                    733:        printk("%s: Setting MAC address to ", dev->name);
                    734:        for (i = 0; i < 6; i++)
                    735:                printk(" %2.2x", dev->dev_addr[i] = sa->sa_data[i]);
                    736:        printk(".\n");
                    737:        return 0;
                    738: }
                    739: 
                    740: #ifdef MODULE
                    741: static char devicename[9] = { 0, };
                    742: static struct device dev_tulip = {
                    743:        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
                    744:        0, 0, 0, 0,
                    745:        0, 0,
                    746:        0, 0, 0, NULL, tulip_probe
                    747: };
                    748: 
                    749: static int io = 0;
                    750: static int irq = 0;
                    751: 
                    752: int init_module(void)
                    753: {
                    754:        printk("tulip: Sorry, modularization is not completed\n");
                    755:        return -EIO;
                    756: #if 0
                    757:        if (io == 0)
                    758:          printk("tulip: You should not use auto-probing with insmod!\n");
                    759:        dev_tulip.base_addr = io;
                    760:        dev_tulip.irq       = irq;
                    761:        if (register_netdev(&dev_tulip) != 0) {
                    762:                printk("tulip: register_netdev() returned non-zero.\n");
                    763:                return -EIO;
                    764:        }
                    765:        return 0;
                    766: #endif
                    767: }
                    768: 
                    769: void
                    770: cleanup_module(void)
                    771: {
                    772:        unregister_netdev(&dev_tulip);
                    773: }
                    774: #endif /* MODULE */
                    775: 
                    776: /*
                    777:  * Local variables:
                    778:  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c tulip.c"
                    779:  *  c-indent-level: 4
                    780:  *  tab-width: 4
                    781:  * End:
                    782:  */

unix.superglobalmegacorp.com

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