Annotation of Gnu-Mach/linux/src/drivers/net/3c509.c, revision 1.1.1.1

1.1       root        1: /* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
                      2: /*
                      3:        Written 1993-1998 by Donald Becker.
                      4: 
                      5:        Copyright 1994-1998 by Donald Becker.
                      6:        Copyright 1993 United States Government as represented by the
                      7:        Director, National Security Agency.      This software may be used and
                      8:        distributed according to the terms of the GNU Public License,
                      9:        incorporated herein by reference.
                     10: 
                     11:        This driver is for the 3Com EtherLinkIII series.
                     12: 
                     13:        The author may be reached as [email protected] or
                     14:        C/O Center of Excellence in Space Data and Information Sciences
                     15:                Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
                     16: 
                     17:        Known limitations:
                     18:        Because of the way 3c509 ISA detection works it's difficult to predict
                     19:        a priori which of several ISA-mode cards will be detected first.
                     20: 
                     21:        This driver does not use predictive interrupt mode, resulting in higher
                     22:        packet latency but lower overhead.  If interrupts are disabled for an
                     23:        unusually long time it could also result in missed packets, but in
                     24:        practice this rarely happens.
                     25: 
                     26: 
                     27:        FIXES:
                     28:                Alan Cox:       Removed the 'Unexpected interrupt' bug.
                     29:                Michael Meskes: Upgraded to Donald Becker's version 1.07.
                     30:                Alan Cox:       Increased the eeprom delay. Regardless of 
                     31:                                what the docs say some people definitely
                     32:                                get problems with lower (but in card spec)
                     33:                                delays
                     34:                v1.10 4/21/97 Fixed module code so that multiple cards may be detected,
                     35:                                other cleanups.  -djb
                     36:                v1.13 9/8/97 Made 'max_interrupt_work' an insmod-settable variable -djb
                     37:                v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb
                     38:                v1.15 1/31/98 Faster recovery for Tx errors. -djb
                     39:                v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb
                     40: */
                     41: 
                     42: static char *version = "3c509.c:1.16 2/3/98 [email protected]\n";
                     43: /* A few values that may be tweaked. */
                     44: 
                     45: /* Time in jiffies before concluding the transmitter is hung. */
                     46: #define TX_TIMEOUT  (400*HZ/1000)
                     47: /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
                     48: static int max_interrupt_work = 10;
                     49: 
                     50: #include <linux/module.h>
                     51: 
                     52: #include <linux/config.h>
                     53: #include <linux/kernel.h>
                     54: #include <linux/sched.h>
                     55: #include <linux/string.h>
                     56: #include <linux/interrupt.h>
                     57: #include <linux/ptrace.h>
                     58: #include <linux/errno.h>
                     59: #include <linux/in.h>
                     60: #include <linux/malloc.h>
                     61: #include <linux/ioport.h>
                     62: #include <linux/netdevice.h>
                     63: #include <linux/etherdevice.h>
                     64: #include <linux/skbuff.h>
                     65: #include <linux/config.h>      /* for CONFIG_MCA */
                     66: #include <linux/delay.h>       /* for udelay() */
                     67: 
                     68: #include <asm/bitops.h>
                     69: #include <asm/io.h>
                     70: 
                     71: #ifdef EL3_DEBUG
                     72: int el3_debug = EL3_DEBUG;
                     73: #else
                     74: int el3_debug = 2;
                     75: #endif
                     76: 
                     77: /* To minimize the size of the driver source I only define operating
                     78:    constants if they are used several times.  You'll need the manual
                     79:    anyway if you want to understand driver details. */
                     80: /* Offsets from base I/O address. */
                     81: #define EL3_DATA 0x00
                     82: #define EL3_CMD 0x0e
                     83: #define EL3_STATUS 0x0e
                     84: #define         EEPROM_READ 0x80
                     85: 
                     86: #define EL3_IO_EXTENT  16
                     87: 
                     88: #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
                     89: 
                     90: 
                     91: /* The top five bits written to EL3_CMD are a command, the lower
                     92:    11 bits are the parameter, if applicable. */
                     93: enum c509cmd {
                     94:        TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
                     95:        RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
                     96:        TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
                     97:        FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
                     98:        SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
                     99:        SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
                    100:        StatsDisable = 22<<11, StopCoax = 23<<11,};
                    101: 
                    102: enum c509status {
                    103:        IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
                    104:        TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
                    105:        IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000, };
                    106: 
                    107: /* The SetRxFilter command accepts the following classes: */
                    108: enum RxFilter {
                    109:        RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
                    110: 
                    111: /* Register window 1 offsets, the window used in normal operation. */
                    112: #define TX_FIFO                0x00
                    113: #define RX_FIFO                0x00
                    114: #define RX_STATUS      0x08
                    115: #define TX_STATUS      0x0B
                    116: #define TX_FREE                0x0C            /* Remaining free bytes in Tx buffer. */
                    117: 
                    118: #define WN0_IRQ                0x08            /* Window 0: Set IRQ line in bits 12-15. */
                    119: #define WN4_MEDIA      0x0A            /* Window 4: Various transcvr/media bits. */
                    120: #define  MEDIA_TP      0x00C0          /* Enable link beat and jabber for 10baseT. */
                    121: 
                    122: /*
                    123:  * Must be a power of two (we use a binary and in the
                    124:  * circular queue)
                    125:  */
                    126: #define SKB_QUEUE_SIZE 64
                    127: 
                    128: struct el3_private {
                    129:        struct enet_statistics stats;
                    130:        struct device *next_dev;
                    131:        /* skb send-queue */
                    132:        int head, size;
                    133:        struct sk_buff *queue[SKB_QUEUE_SIZE];
                    134: };
                    135: static int id_port = 0x110;            /* Start with 0x110 to avoid new sound cards.*/
                    136: static struct device *el3_root_dev = NULL;
                    137: 
                    138: static ushort id_read_eeprom(int index);
                    139: static ushort read_eeprom(int ioaddr, int index);
                    140: static int el3_open(struct device *dev);
                    141: static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
                    142: static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
                    143: static void update_stats(int addr, struct device *dev);
                    144: static struct enet_statistics *el3_get_stats(struct device *dev);
                    145: static int el3_rx(struct device *dev);
                    146: static int el3_close(struct device *dev);
                    147: static void set_multicast_list(struct device *dev);
                    148: 
                    149: 
                    150: 
                    151: int el3_probe(struct device *dev)
                    152: {
                    153:        short lrs_state = 0xff, i;
                    154:        int ioaddr, irq, if_port;
                    155:        u16 phys_addr[3];
                    156:        static int current_tag = 0;
                    157: 
                    158:        /* First check all slots of the EISA bus.  The next slot address to
                    159:           probe is kept in 'eisa_addr' to support multiple probe() calls. */
                    160:        if (EISA_bus) {
                    161:                static int eisa_addr = 0x1000;
                    162:                while (eisa_addr < 0x9000) {
                    163:                        ioaddr = eisa_addr;
                    164:                        eisa_addr += 0x1000;
                    165: 
                    166:                        /* Check the standard EISA ID register for an encoded '3Com'. */
                    167:                        if (inw(ioaddr + 0xC80) != 0x6d50)
                    168:                                continue;
                    169: 
                    170:                        /* Change the register set to the configuration window 0. */
                    171:                        outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
                    172: 
                    173:                        irq = inw(ioaddr + WN0_IRQ) >> 12;
                    174:                        if_port = inw(ioaddr + 6)>>14;
                    175:                        for (i = 0; i < 3; i++)
                    176:                                phys_addr[i] = htons(read_eeprom(ioaddr, i));
                    177: 
                    178:                        /* Restore the "Product ID" to the EEPROM read register. */
                    179:                        read_eeprom(ioaddr, 3);
                    180: 
                    181:                        /* Was the EISA code an add-on hack?  Nahhhhh... */
                    182:                        goto found;
                    183:                }
                    184:        }
                    185: 
                    186: #ifdef CONFIG_MCA
                    187:        if (MCA_bus) {
                    188:                mca_adaptor_select_mode(1);
                    189:                for (i = 0; i < 8; i++)
                    190:                        if ((mca_adaptor_id(i) | 1) == 0x627c) {
                    191:                                ioaddr = mca_pos_base_addr(i);
                    192:                                irq = inw(ioaddr + WN0_IRQ) >> 12;
                    193:                                if_port = inw(ioaddr + 6)>>14;
                    194:                                for (i = 0; i < 3; i++)
                    195:                                        phys_addr[i] = htons(read_eeprom(ioaddr, i));
                    196: 
                    197:                                mca_adaptor_select_mode(0);
                    198:                                goto found;
                    199:                        }
                    200:                mca_adaptor_select_mode(0);
                    201: 
                    202:        }
                    203: #endif
                    204: 
                    205:        /* Reset the ISA PnP mechanism on 3c509b. */
                    206:        outb(0x02, 0x279);           /* Select PnP config control register. */
                    207:        outb(0x02, 0xA79);           /* Return to WaitForKey state. */
                    208:        /* Select an open I/O location at 0x1*0 to do contention select. */
                    209:        for ( ; id_port < 0x200; id_port += 0x10) {
                    210:                if (check_region(id_port, 1))
                    211:                        continue;
                    212:                outb(0x00, id_port);
                    213:                outb(0xff, id_port);
                    214:                if (inb(id_port) & 0x01)
                    215:                        break;
                    216:        }
                    217:        if (id_port >= 0x200) {             /* GCC optimizes this test out. */
                    218:                /* Rare -- do we really need a warning? */
                    219:                printk(" WARNING: No I/O port available for 3c509 activation.\n");
                    220:                return -ENODEV;
                    221:        }
                    222:        /* Next check for all ISA bus boards by sending the ID sequence to the
                    223:           ID_PORT.  We find cards past the first by setting the 'current_tag'
                    224:           on cards as they are found.  Cards with their tag set will not
                    225:           respond to subsequent ID sequences. */
                    226: 
                    227:        outb(0x00, id_port);
                    228:        outb(0x00, id_port);
                    229:        for(i = 0; i < 255; i++) {
                    230:                outb(lrs_state, id_port);
                    231:                lrs_state <<= 1;
                    232:                lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
                    233:        }
                    234: 
                    235:        /* For the first probe, clear all board's tag registers. */
                    236:        if (current_tag == 0)
                    237:                outb(0xd0, id_port);
                    238:        else                            /* Otherwise kill off already-found boards. */
                    239:                outb(0xd8, id_port);
                    240: 
                    241:        if (id_read_eeprom(7) != 0x6d50) {
                    242:                return -ENODEV;
                    243:        }
                    244: 
                    245:        /* Read in EEPROM data, which does contention-select.
                    246:           Only the lowest address board will stay "on-line".
                    247:           3Com got the byte order backwards. */
                    248:        for (i = 0; i < 3; i++) {
                    249:                phys_addr[i] = htons(id_read_eeprom(i));
                    250:        }
                    251: 
                    252:        {
                    253:                unsigned int iobase = id_read_eeprom(8);
                    254:                if_port = iobase >> 14;
                    255:                ioaddr = 0x200 + ((iobase & 0x1f) << 4);
                    256:        }
                    257:        irq = id_read_eeprom(9) >> 12;
                    258: 
                    259:        if (dev) {                                      /* Set passed-in IRQ or I/O Addr. */
                    260:                if (dev->irq > 1  &&  dev->irq < 16)
                    261:                        irq = dev->irq;
                    262: 
                    263:                if (dev->base_addr) {
                    264:                        if (dev->mem_end == 0x3c509                     /* Magic key */
                    265:                                && dev->base_addr >= 0x200  &&  dev->base_addr <= 0x3e0)
                    266:                                ioaddr = dev->base_addr & 0x3f0;
                    267:                        else if (dev->base_addr != ioaddr)
                    268:                                return -ENODEV;
                    269:                }
                    270:        }
                    271: 
                    272:        /* Set the adaptor tag so that the next card can be found. */
                    273:        outb(0xd0 + ++current_tag, id_port);
                    274: 
                    275:        /* Activate the adaptor at the EEPROM location. */
                    276:        outb((ioaddr >> 4) | 0xe0, id_port);
                    277: 
                    278:        EL3WINDOW(0);
                    279:        if (inw(ioaddr) != 0x6d50)
                    280:                return -ENODEV;
                    281: 
                    282:        /* Free the interrupt so that some other card can use it. */
                    283:        outw(0x0f00, ioaddr + WN0_IRQ);
                    284:  found:
                    285:        if (dev == NULL) {
                    286:                dev = init_etherdev(dev, sizeof(struct el3_private));
                    287:        }
                    288:        memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
                    289:        dev->base_addr = ioaddr;
                    290:        dev->irq = irq;
                    291:        dev->if_port = (dev->mem_start & 0x1f) ? dev->mem_start & 3 : if_port;
                    292: 
                    293:        request_region(dev->base_addr, EL3_IO_EXTENT, "3c509");
                    294: 
                    295:        {
                    296:                const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
                    297:                printk("%s: 3c509 at %#3.3lx tag %d, %s port, address ",
                    298:                           dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
                    299:        }
                    300: 
                    301:        /* Read in the station address. */
                    302:        for (i = 0; i < 6; i++)
                    303:                printk(" %2.2x", dev->dev_addr[i]);
                    304:        printk(", IRQ %d.\n", dev->irq);
                    305: 
                    306:        /* Make up a EL3-specific-data structure. */
                    307:        if (dev->priv == NULL)
                    308:                dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
                    309:        if (dev->priv == NULL)
                    310:                return -ENOMEM;
                    311:        memset(dev->priv, 0, sizeof(struct el3_private));
                    312: 
                    313:        ((struct el3_private *)dev->priv)->next_dev = el3_root_dev;
                    314:        el3_root_dev = dev;
                    315: 
                    316:        if (el3_debug > 0)
                    317:                printk(version);
                    318: 
                    319:        /* The EL3-specific entries in the device structure. */
                    320:        dev->open = &el3_open;
                    321:        dev->hard_start_xmit = &el3_start_xmit;
                    322:        dev->stop = &el3_close;
                    323:        dev->get_stats = &el3_get_stats;
                    324:        dev->set_multicast_list = &set_multicast_list;
                    325: 
                    326:        /* Fill in the generic fields of the device structure. */
                    327:        ether_setup(dev);
                    328:        return 0;
                    329: }
                    330: 
                    331: /* Read a word from the EEPROM using the regular EEPROM access register.
                    332:    Assume that we are in register window zero.
                    333:  */
                    334: static ushort read_eeprom(int ioaddr, int index)
                    335: {
                    336:        outw(EEPROM_READ + index, ioaddr + 10);
                    337:        /* Pause for at least 162 us. for the read to take place. */
                    338:        udelay (500);
                    339:        return inw(ioaddr + 12);
                    340: }
                    341: 
                    342: /* Read a word from the EEPROM when in the ISA ID probe state. */
                    343: static ushort id_read_eeprom(int index)
                    344: {
                    345:        int bit, word = 0;
                    346: 
                    347:        /* Issue read command, and pause for at least 162 us. for it to complete.
                    348:           Assume extra-fast 16Mhz bus. */
                    349:        outb(EEPROM_READ + index, id_port);
                    350: 
                    351:        /* Pause for at least 162 us. for the read to take place. */
                    352:        udelay (500);
                    353:        
                    354:        for (bit = 15; bit >= 0; bit--)
                    355:                word = (word << 1) + (inb(id_port) & 0x01);
                    356: 
                    357:        if (el3_debug > 3)
                    358:                printk("  3c509 EEPROM word %d %#4.4x.\n", index, word);
                    359: 
                    360:        return word;
                    361: }
                    362: 
                    363: 
                    364: 
                    365: static int
                    366: el3_open(struct device *dev)
                    367: {
                    368:        int ioaddr = dev->base_addr;
                    369:        int i;
                    370: 
                    371:        outw(TxReset, ioaddr + EL3_CMD);
                    372:        outw(RxReset, ioaddr + EL3_CMD);
                    373:        outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
                    374: 
                    375:        if (request_irq(dev->irq, &el3_interrupt, 0, "3c509", dev)) {
                    376:                return -EAGAIN;
                    377:        }
                    378: 
                    379:        EL3WINDOW(0);
                    380:        if (el3_debug > 3)
                    381:                printk("%s: Opening, IRQ %d      status@%x %4.4x.\n", dev->name,
                    382:                           dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
                    383: 
                    384:        /* Activate board: this is probably unnecessary. */
                    385:        outw(0x0001, ioaddr + 4);
                    386: 
                    387:        /* Set the IRQ line. */
                    388:        outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
                    389: 
                    390:        /* Set the station address in window 2 each time opened. */
                    391:        EL3WINDOW(2);
                    392: 
                    393:        for (i = 0; i < 6; i++)
                    394:                outb(dev->dev_addr[i], ioaddr + i);
                    395: 
                    396:        if (dev->if_port == 3)
                    397:                /* Start the thinnet transceiver. We should really wait 50ms...*/
                    398:                outw(StartCoax, ioaddr + EL3_CMD);
                    399:        else if (dev->if_port == 0) {
                    400:                /* 10baseT interface, enabled link beat and jabber check. */
                    401:                EL3WINDOW(4);
                    402:                outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
                    403:        }
                    404: 
                    405:        /* Switch to the stats window, and clear all stats by reading. */
                    406:        outw(StatsDisable, ioaddr + EL3_CMD);
                    407:        EL3WINDOW(6);
                    408:        for (i = 0; i < 9; i++)
                    409:                inb(ioaddr + i);
                    410:        inw(ioaddr + 10);
                    411:        inw(ioaddr + 12);
                    412: 
                    413:        /* Switch to register set 1 for normal use. */
                    414:        EL3WINDOW(1);
                    415: 
                    416:        /* Accept b-case and phys addr only. */
                    417:        outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
                    418:        outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
                    419: 
                    420:        dev->interrupt = 0;
                    421:        dev->tbusy = 0;
                    422:        dev->start = 1;
                    423: 
                    424:        outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
                    425:        outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
                    426:        /* Allow status bits to be seen. */
                    427:        outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
                    428:        /* Ack all pending events, and set active indicator mask. */
                    429:        outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
                    430:                 ioaddr + EL3_CMD);
                    431:        outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
                    432:                 ioaddr + EL3_CMD);
                    433: 
                    434:        if (el3_debug > 3)
                    435:                printk("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
                    436:                           dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
                    437: 
                    438:        MOD_INC_USE_COUNT;
                    439:        return 0;                                       /* Always succeed */
                    440: }
                    441: 
                    442: static int
                    443: el3_start_xmit(struct sk_buff *skb, struct device *dev)
                    444: {
                    445:        struct el3_private *lp = (struct el3_private *)dev->priv;
                    446:        int ioaddr = dev->base_addr;
                    447: 
                    448:        /* Transmitter timeout, serious problems. */
                    449:        if (dev->tbusy) {
                    450:                int tickssofar = jiffies - dev->trans_start;
                    451:                if (tickssofar < TX_TIMEOUT)
                    452:                        return 1;
                    453:                printk("%s: transmit timed out, Tx_status %2.2x status %4.4x "
                    454:                           "Tx FIFO room %d.\n",
                    455:                           dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
                    456:                           inw(ioaddr + TX_FREE));
                    457:                lp->stats.tx_errors++;
                    458:                dev->trans_start = jiffies;
                    459:                /* Issue TX_RESET and TX_START commands. */
                    460:                outw(TxReset, ioaddr + EL3_CMD);
                    461:                outw(TxEnable, ioaddr + EL3_CMD);
                    462:                dev->tbusy = 0;
                    463:        }
                    464: 
                    465:        if (el3_debug > 4) {
                    466:                printk("%s: el3_start_xmit(length = %ld) called, status %4.4x.\n",
                    467:                           dev->name, skb->len, inw(ioaddr + EL3_STATUS));
                    468:        }
                    469: #if 0
                    470: #ifndef final_version
                    471:        {       /* Error-checking code, delete someday. */
                    472:                ushort status = inw(ioaddr + EL3_STATUS);
                    473:                if (status & 0x0001             /* IRQ line active, missed one. */
                    474:                        && inw(ioaddr + EL3_STATUS) & 1) {                      /* Make sure. */
                    475:                        printk("%s: Missed interrupt, status then %04x now %04x"
                    476:                                   "  Tx %2.2x Rx %4.4x.\n", dev->name, status,
                    477:                                   inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
                    478:                                   inw(ioaddr + RX_STATUS));
                    479:                        /* Fake interrupt trigger by masking, acknowledge interrupts. */
                    480:                        outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
                    481:                        outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
                    482:                                 ioaddr + EL3_CMD);
                    483:                        outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
                    484:                }
                    485:        }
                    486: #endif
                    487: #endif
                    488:        /* Avoid timer-based retransmission conflicts. */
                    489:        if (set_bit(0, (void*)&dev->tbusy) != 0)
                    490:                printk("%s: Transmitter access conflict.\n", dev->name);
                    491:        else {
                    492:                /* Put out the doubleword header... */
                    493:                outw(skb->len, ioaddr + TX_FIFO);
                    494:                outw(0x00, ioaddr + TX_FIFO);
                    495:                /* ... and the packet rounded to a doubleword. */
                    496: #ifdef  __powerpc__
                    497:                outsl_unswapped(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
                    498: #else
                    499:                outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
                    500: #endif
                    501: 
                    502:                dev->trans_start = jiffies;
                    503:                if (inw(ioaddr + TX_FREE) > 1536) {
                    504:                        dev->tbusy = 0;
                    505:                } else
                    506:                        /* Interrupt us when the FIFO has room for max-sized packet. */
                    507:                        outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
                    508:        }
                    509: 
                    510:        dev_kfree_skb (skb, FREE_WRITE);
                    511: 
                    512:        /* Clear the Tx status stack. */
                    513:        {
                    514:                short tx_status;
                    515:                int i = 4;
                    516: 
                    517:                while (--i > 0  &&      (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
                    518:                        if (tx_status & 0x38) lp->stats.tx_aborted_errors++;
                    519:                        if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
                    520:                        if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
                    521:                        outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
                    522:                }
                    523:        }
                    524:        return 0;
                    525: }
                    526: 
                    527: /* The EL3 interrupt handler. */
                    528: static void
                    529: el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                    530: {
                    531:        struct device *dev = (struct device *)dev_id;
                    532:        int ioaddr, status;
                    533:        int i = max_interrupt_work;
                    534: 
                    535:        if (dev == NULL) {
                    536:                printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
                    537:                return;
                    538:        }
                    539: 
                    540:        if (dev->interrupt)
                    541:                printk("%s: Re-entering the interrupt handler.\n", dev->name);
                    542:        dev->interrupt = 1;
                    543: 
                    544:        ioaddr = dev->base_addr;
                    545:        status = inw(ioaddr + EL3_STATUS);
                    546: 
                    547:        if (el3_debug > 4)
                    548:                printk("%s: interrupt, status %4.4x.\n", dev->name, status);
                    549: 
                    550:        while ((status = inw(ioaddr + EL3_STATUS)) &
                    551:                   (IntLatch | RxComplete | StatsFull)) {
                    552: 
                    553:                if (status & RxComplete)
                    554:                        el3_rx(dev);
                    555: 
                    556:                if (status & TxAvailable) {
                    557:                        if (el3_debug > 5)
                    558:                                printk("        TX room bit was handled.\n");
                    559:                        /* There's room in the FIFO for a full-sized packet. */
                    560:                        outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
                    561:                        dev->tbusy = 0;
                    562:                        mark_bh(NET_BH);
                    563:                }
                    564:                if (status & (AdapterFailure | RxEarly | StatsFull | TxComplete)) {
                    565:                        /* Handle all uncommon interrupts. */
                    566:                        if (status & StatsFull)                         /* Empty statistics. */
                    567:                                update_stats(ioaddr, dev);
                    568:                        if (status & RxEarly) {                         /* Rx early is unused. */
                    569:                                el3_rx(dev);
                    570:                                outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
                    571:                        }
                    572:                        if (status & TxComplete) {                      /* Really Tx error. */
                    573:                                struct el3_private *lp = (struct el3_private *)dev->priv;
                    574:                                short tx_status;
                    575:                                int i = 4;
                    576: 
                    577:                                while (--i>0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
                    578:                                        if (tx_status & 0x38) lp->stats.tx_aborted_errors++;
                    579:                                        if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
                    580:                                        if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
                    581:                                        outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
                    582:                                }
                    583:                        }
                    584:                        if (status & AdapterFailure) {
                    585:                                /* Adapter failure requires Rx reset and reinit. */
                    586:                                outw(RxReset, ioaddr + EL3_CMD);
                    587:                                /* Set the Rx filter to the current state. */
                    588:                                outw(SetRxFilter | RxStation | RxBroadcast
                    589:                                         | (dev->flags & IFF_ALLMULTI ? RxMulticast : 0)
                    590:                                         | (dev->flags & IFF_PROMISC ? RxProm : 0),
                    591:                                         ioaddr + EL3_CMD);
                    592:                                outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
                    593:                                outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);
                    594:                        }
                    595:                }
                    596: 
                    597:                if (--i < 0) {
                    598:                        printk("%s: Infinite loop in interrupt, status %4.4x.\n",
                    599:                                   dev->name, status);
                    600:                        /* Clear all interrupts. */
                    601:                        outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
                    602:                        break;
                    603:                }
                    604:                /* Acknowledge the IRQ. */
                    605:                outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); /* Ack IRQ */
                    606:        }
                    607: 
                    608:        if (el3_debug > 4) {
                    609:                printk("%s: exiting interrupt, status %4.4x.\n", dev->name,
                    610:                           inw(ioaddr + EL3_STATUS));
                    611:        }
                    612: 
                    613:        dev->interrupt = 0;
                    614:        return;
                    615: }
                    616: 
                    617: 
                    618: static struct enet_statistics *
                    619: el3_get_stats(struct device *dev)
                    620: {
                    621:        struct el3_private *lp = (struct el3_private *)dev->priv;
                    622:        unsigned long flags;
                    623: 
                    624:        save_flags(flags);
                    625:        cli();
                    626:        update_stats(dev->base_addr, dev);
                    627:        restore_flags(flags);
                    628:        return &lp->stats;
                    629: }
                    630: 
                    631: /*  Update statistics.  We change to register window 6, so this should be run
                    632:        single-threaded if the device is active. This is expected to be a rare
                    633:        operation, and it's simpler for the rest of the driver to assume that
                    634:        window 1 is always valid rather than use a special window-state variable.
                    635:        */
                    636: static void update_stats(int ioaddr, struct device *dev)
                    637: {
                    638:        struct el3_private *lp = (struct el3_private *)dev->priv;
                    639: 
                    640:        if (el3_debug > 5)
                    641:                printk("   Updating the statistics.\n");
                    642:        /* Turn off statistics updates while reading. */
                    643:        outw(StatsDisable, ioaddr + EL3_CMD);
                    644:        /* Switch to the stats window, and read everything. */
                    645:        EL3WINDOW(6);
                    646:        lp->stats.tx_carrier_errors     += inb(ioaddr + 0);
                    647:        lp->stats.tx_heartbeat_errors   += inb(ioaddr + 1);
                    648:        /* Multiple collisions. */              inb(ioaddr + 2);
                    649:        lp->stats.collisions                    += inb(ioaddr + 3);
                    650:        lp->stats.tx_window_errors              += inb(ioaddr + 4);
                    651:        lp->stats.rx_fifo_errors                += inb(ioaddr + 5);
                    652:        lp->stats.tx_packets                    += inb(ioaddr + 6);
                    653:        /* Rx packets   */                              inb(ioaddr + 7);
                    654:        /* Tx deferrals */                              inb(ioaddr + 8);
                    655:        inw(ioaddr + 10);       /* Total Rx and Tx octets. */
                    656:        inw(ioaddr + 12);
                    657: 
                    658:        /* Back to window 1, and turn statistics back on. */
                    659:        EL3WINDOW(1);
                    660:        outw(StatsEnable, ioaddr + EL3_CMD);
                    661:        return;
                    662: }
                    663: 
                    664: static int
                    665: el3_rx(struct device *dev)
                    666: {
                    667:        struct el3_private *lp = (struct el3_private *)dev->priv;
                    668:        int ioaddr = dev->base_addr;
                    669:        short rx_status;
                    670: 
                    671:        if (el3_debug > 5)
                    672:                printk("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
                    673:                           inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
                    674:        while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
                    675:                if (rx_status & 0x4000) { /* Error, update stats. */
                    676:                        short error = rx_status & 0x3800;
                    677: 
                    678:                        outw(RxDiscard, ioaddr + EL3_CMD);
                    679:                        lp->stats.rx_errors++;
                    680:                        switch (error) {
                    681:                        case 0x0000:            lp->stats.rx_over_errors++; break;
                    682:                        case 0x0800:            lp->stats.rx_length_errors++; break;
                    683:                        case 0x1000:            lp->stats.rx_frame_errors++; break;
                    684:                        case 0x1800:            lp->stats.rx_length_errors++; break;
                    685:                        case 0x2000:            lp->stats.rx_frame_errors++; break;
                    686:                        case 0x2800:            lp->stats.rx_crc_errors++; break;
                    687:                        }
                    688:                } else {
                    689:                        short pkt_len = rx_status & 0x7ff;
                    690:                        struct sk_buff *skb;
                    691: 
                    692:                        skb = dev_alloc_skb(pkt_len+5);
                    693:                        if (el3_debug > 4)
                    694:                                printk("Receiving packet size %d status %4.4x.\n",
                    695:                                           pkt_len, rx_status);
                    696:                        if (skb != NULL) {
                    697:                                skb->dev = dev;
                    698:                                skb_reserve(skb, 2);     /* Align IP on 16 byte */
                    699: 
                    700:                                /* 'skb->data' points to the start of sk_buff data area. */
                    701: #ifdef  __powerpc__
                    702:                                insl_unswapped(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
                    703:                                                           (pkt_len + 3) >> 2);
                    704: #else
                    705:                                insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len),
                    706:                                         (pkt_len + 3) >> 2);
                    707: #endif
                    708: 
                    709:                                outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
                    710:                                skb->protocol = eth_type_trans(skb,dev);
                    711:                                netif_rx(skb);
                    712:                                lp->stats.rx_packets++;
                    713:                                continue;
                    714:                        }
                    715:                        outw(RxDiscard, ioaddr + EL3_CMD);
                    716:                        lp->stats.rx_dropped++;
                    717:                        if (el3_debug)
                    718:                                printk("%s: Couldn't allocate a sk_buff of size %d.\n",
                    719:                                           dev->name, pkt_len);
                    720:                }
                    721:                inw(ioaddr + EL3_STATUS);                               /* Delay. */
                    722:                while (inw(ioaddr + EL3_STATUS) & 0x1000)
                    723:                        printk("        Waiting for 3c509 to discard packet, status %x.\n",
                    724:                                   inw(ioaddr + EL3_STATUS) );
                    725:        }
                    726: 
                    727:        return 0;
                    728: }
                    729: 
                    730: /*
                    731:  *     Set or clear the multicast filter for this adaptor.
                    732:  */
                    733: static void
                    734: set_multicast_list(struct device *dev)
                    735: {
                    736:        int ioaddr = dev->base_addr;
                    737:        if (el3_debug > 1) {
                    738:                static int old = 0;
                    739:                if (old != dev->mc_count) {
                    740:                        old = dev->mc_count;
                    741:                        printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
                    742:                }
                    743:        }
                    744:        if (dev->flags&IFF_PROMISC) {
                    745:                outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
                    746:                         ioaddr + EL3_CMD);
                    747:        }
                    748:        else if (dev->mc_count || (dev->flags&IFF_ALLMULTI)) {
                    749:                outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast, ioaddr + EL3_CMD);
                    750:        }
                    751:        else
                    752:                 outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
                    753: }
                    754: 
                    755: static int
                    756: el3_close(struct device *dev)
                    757: {
                    758:        int ioaddr = dev->base_addr;
                    759: 
                    760:        if (el3_debug > 2)
                    761:                printk("%s: Shutting down ethercard.\n", dev->name);
                    762: 
                    763:        dev->tbusy = 1;
                    764:        dev->start = 0;
                    765: 
                    766:        /* Turn off statistics ASAP.  We update lp->stats below. */
                    767:        outw(StatsDisable, ioaddr + EL3_CMD);
                    768: 
                    769:        /* Disable the receiver and transmitter. */
                    770:        outw(RxDisable, ioaddr + EL3_CMD);
                    771:        outw(TxDisable, ioaddr + EL3_CMD);
                    772: 
                    773:        if (dev->if_port == 3)
                    774:                /* Turn off thinnet power.  Green! */
                    775:                outw(StopCoax, ioaddr + EL3_CMD);
                    776:        else if (dev->if_port == 0) {
                    777:                /* Disable link beat and jabber, if_port may change ere next open(). */
                    778:                EL3WINDOW(4);
                    779:                outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
                    780:        }
                    781: 
                    782:        free_irq(dev->irq, dev);
                    783:        /* Switching back to window 0 disables the IRQ. */
                    784:        EL3WINDOW(0);
                    785:        /* But we explicitly zero the IRQ line select anyway. */
                    786:        outw(0x0f00, ioaddr + WN0_IRQ);
                    787: 
                    788:        update_stats(ioaddr, dev);
                    789:        MOD_DEC_USE_COUNT;
                    790:        return 0;
                    791: }
                    792: 
                    793: #ifdef MODULE
                    794: /* Parameters that may be passed into the module. */
                    795: static int debug = -1;
                    796: static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
                    797: static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1};
                    798: 
                    799: int
                    800: init_module(void)
                    801: {
                    802:        int el3_cards = 0;
                    803: 
                    804:        if (debug >= 0)
                    805:                el3_debug = debug;
                    806: 
                    807:        el3_root_dev = NULL;
                    808:        while (el3_probe(0) == 0) {
                    809:                if (irq[el3_cards] > 1)
                    810:                        el3_root_dev->irq = irq[el3_cards];
                    811:                if (xcvr[el3_cards] >= 0)
                    812:                        el3_root_dev->if_port = xcvr[el3_cards];
                    813:                el3_cards++;
                    814:        }
                    815: 
                    816:        return el3_cards ? 0 : -ENODEV;
                    817: }
                    818: 
                    819: void
                    820: cleanup_module(void)
                    821: {
                    822:        struct device *next_dev;
                    823: 
                    824:        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
                    825:        while (el3_root_dev) {
                    826:                next_dev = ((struct el3_private *)el3_root_dev->priv)->next_dev;
                    827:                unregister_netdev(el3_root_dev);
                    828:                release_region(el3_root_dev->base_addr, EL3_IO_EXTENT);
                    829:                kfree(el3_root_dev);
                    830:                el3_root_dev = next_dev;
                    831:        }
                    832: }
                    833: #endif /* MODULE */
                    834: 
                    835: /*
                    836:  * Local variables:
                    837:  *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c509.c"
                    838:  *  version-control: t
                    839:  *  kept-new-versions: 5
                    840:  *  tab-width: 4
                    841:  * End:
                    842:  */

unix.superglobalmegacorp.com

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