Annotation of Gnu-Mach/i386/i386at/gpl/linux/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,1994 by Donald Becker.
                      4: 
                      5:        Copyright 1994 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: static const  char *version = "3c509.c:1.03 10/8/94 [email protected]\n";
                     28: 
                     29: #include <linux/module.h>
                     30: 
                     31: #include <linux/config.h>
                     32: #include <linux/kernel.h>
                     33: #include <linux/sched.h>
                     34: #include <linux/string.h>
                     35: #include <linux/interrupt.h>
                     36: #include <linux/ptrace.h>
                     37: #include <linux/errno.h>
                     38: #include <linux/in.h>
                     39: #include <linux/malloc.h>
                     40: #include <linux/ioport.h>
                     41: #include <linux/netdevice.h>
                     42: #include <linux/etherdevice.h>
                     43: #include <linux/skbuff.h>
                     44: #include <linux/config.h>      /* for CONFIG_MCA */
                     45: 
                     46: #include <asm/bitops.h>
                     47: #include <asm/io.h>
                     48: 
                     49: 
                     50: #ifdef EL3_DEBUG
                     51: int el3_debug = EL3_DEBUG;
                     52: #else
                     53: int el3_debug = 2;
                     54: #endif
                     55: 
                     56: /* To minimize the size of the driver source I only define operating
                     57:    constants if they are used several times.  You'll need the manual
                     58:    if you want to understand driver details. */
                     59: /* Offsets from base I/O address. */
                     60: #define EL3_DATA 0x00
                     61: #define EL3_CMD 0x0e
                     62: #define EL3_STATUS 0x0e
                     63: #define ID_PORT 0x100
                     64: #define         EEPROM_READ 0x80
                     65: 
                     66: #define EL3_IO_EXTENT  16
                     67: 
                     68: #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
                     69: 
                     70: 
                     71: /* The top five bits written to EL3_CMD are a command, the lower
                     72:    11 bits are the parameter, if applicable. */
                     73: enum c509cmd {
                     74:        TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
                     75:        RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
                     76:        TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
                     77:        FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrMask = 14<<11,
                     78:        SetReadZero = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
                     79:        SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
                     80:        StatsDisable = 22<<11, StopCoax = 23<<11,};
                     81: 
                     82: /* The SetRxFilter command accepts the following classes: */
                     83: enum RxFilter {
                     84:        RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
                     85: 
                     86: /* Register window 1 offsets, the window used in normal operation. */
                     87: #define TX_FIFO                0x00
                     88: #define RX_FIFO                0x00
                     89: #define RX_STATUS      0x08
                     90: #define TX_STATUS      0x0B
                     91: #define TX_FREE                0x0C            /* Remaining free bytes in Tx buffer. */
                     92: 
                     93: #define WN0_IRQ                0x08            /* Window 0: Set IRQ line in bits 12-15. */
                     94: #define WN4_MEDIA      0x0A            /* Window 4: Various transcvr/media bits. */
                     95: #define  MEDIA_TP      0x00C0          /* Enable link beat and jabber for 10baseT. */
                     96: 
                     97: struct el3_private {
                     98:        struct enet_statistics stats;
                     99: };
                    100: 
                    101: static ushort id_read_eeprom(int index);
                    102: static ushort read_eeprom(short ioaddr, int index);
                    103: static int el3_open(struct device *dev);
                    104: static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
                    105: static void el3_interrupt(int irq, struct pt_regs *regs);
                    106: static void update_stats(int addr, struct device *dev);
                    107: static struct enet_statistics *el3_get_stats(struct device *dev);
                    108: static int el3_rx(struct device *dev);
                    109: static int el3_close(struct device *dev);
                    110: static void set_multicast_list(struct device *dev);
                    111: 
                    112: 
                    113: 
                    114: int el3_probe(struct device *dev)
                    115: {
                    116:        short lrs_state = 0xff, i;
                    117:        ushort ioaddr, irq, if_port;
                    118:        short *phys_addr = (short *)dev->dev_addr;
                    119:        static int current_tag = 0;
                    120: 
                    121:        /* First check all slots of the EISA bus.  The next slot address to
                    122:           probe is kept in 'eisa_addr' to support multiple probe() calls. */
                    123:        if (EISA_bus) {
                    124:                static int eisa_addr = 0x1000;
                    125:                while (eisa_addr < 0x9000) {
                    126:                        ioaddr = eisa_addr;
                    127:                        eisa_addr += 0x1000;
                    128: 
                    129:                        /* Check the standard EISA ID register for an encoded '3Com'. */
                    130:                        if (inw(ioaddr + 0xC80) != 0x6d50)
                    131:                                continue;
                    132: 
                    133:                        /* Change the register set to the configuration window 0. */
                    134:                        outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
                    135: 
                    136:                        irq = inw(ioaddr + WN0_IRQ) >> 12;
                    137:                        if_port = inw(ioaddr + 6)>>14;
                    138:                        for (i = 0; i < 3; i++)
                    139:                                phys_addr[i] = htons(read_eeprom(ioaddr, i));
                    140: 
                    141:                        /* Restore the "Product ID" to the EEPROM read register. */
                    142:                        read_eeprom(ioaddr, 3);
                    143: 
                    144:                        /* Was the EISA code an add-on hack?  Nahhhhh... */
                    145:                        goto found;
                    146:                }
                    147:        }
                    148: 
                    149: #ifdef CONFIG_MCA
                    150:        if (MCA_bus) {
                    151:                mca_adaptor_select_mode(1);
                    152:                for (i = 0; i < 8; i++)
                    153:                        if ((mca_adaptor_id(i) | 1) == 0x627c) {
                    154:                                ioaddr = mca_pos_base_addr(i);
                    155:                                irq = inw(ioaddr + WN0_IRQ) >> 12;
                    156:                                if_port = inw(ioaddr + 6)>>14;
                    157:                                for (i = 0; i < 3; i++)
                    158:                                        phys_addr[i] = htons(read_eeprom(ioaddr, i));
                    159: 
                    160:                                mca_adaptor_select_mode(0);
                    161:                                goto found;
                    162:                        }
                    163:                mca_adaptor_select_mode(0);
                    164: 
                    165:        }
                    166: #endif
                    167: 
                    168:        /* Next check for all ISA bus boards by sending the ID sequence to the
                    169:           ID_PORT.  We find cards past the first by setting the 'current_tag'
                    170:           on cards as they are found.  Cards with their tag set will not
                    171:           respond to subsequent ID sequences. */
                    172: 
                    173:        if (check_region(ID_PORT,1)) {
                    174:          static int once = 1;
                    175:          if (once) printk("3c509: Somebody has reserved 0x%x, can't do ID_PORT lookup, nor card auto-probing\n",ID_PORT);
                    176:          once = 0;
                    177:          return -ENODEV;
                    178:        }
                    179: 
                    180:        outb(0x00, ID_PORT);
                    181:        outb(0x00, ID_PORT);
                    182:        for(i = 0; i < 255; i++) {
                    183:                outb(lrs_state, ID_PORT);
                    184:                lrs_state <<= 1;
                    185:                lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
                    186:        }
                    187: 
                    188:        /* For the first probe, clear all board's tag registers. */
                    189:        if (current_tag == 0)
                    190:                outb(0xd0, ID_PORT);
                    191:        else                            /* Otherwise kill off already-found boards. */
                    192:                outb(0xd8, ID_PORT);
                    193: 
                    194:        if (id_read_eeprom(7) != 0x6d50) {
                    195:                return -ENODEV;
                    196:        }
                    197: 
                    198:        /* Read in EEPROM data, which does contention-select.
                    199:           Only the lowest address board will stay "on-line".
                    200:           3Com got the byte order backwards. */
                    201:        for (i = 0; i < 3; i++) {
                    202:                phys_addr[i] = htons(id_read_eeprom(i));
                    203:        }
                    204: 
                    205:        {
                    206:                unsigned short iobase = id_read_eeprom(8);
                    207:                if_port = iobase >> 14;
                    208:                ioaddr = 0x200 + ((iobase & 0x1f) << 4);
                    209:        }
                    210:        irq = id_read_eeprom(9) >> 12;
                    211: 
                    212:        if (dev->base_addr != 0
                    213:                &&      dev->base_addr != (unsigned short)ioaddr) {
                    214:                return -ENODEV;
                    215:        }
                    216: 
                    217:        /* Set the adaptor tag so that the next card can be found. */
                    218:        outb(0xd0 + ++current_tag, ID_PORT);
                    219: 
                    220:        /* Activate the adaptor at the EEPROM location. */
                    221:        outb(0xff, ID_PORT);
                    222: 
                    223:        EL3WINDOW(0);
                    224:        if (inw(ioaddr) != 0x6d50)
                    225:                return -ENODEV;
                    226: 
                    227:        /* Free the interrupt so that some other card can use it. */
                    228:        outw(0x0f00, ioaddr + WN0_IRQ);
                    229:  found:
                    230:        dev->base_addr = ioaddr;
                    231:        dev->irq = irq;
                    232:        dev->if_port = if_port;
                    233:        request_region(dev->base_addr, EL3_IO_EXTENT, "3c509");
                    234: 
                    235:        {
                    236:                const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
                    237:                printk("%s: 3c509 at %#3.3lx tag %d, %s port, address ",
                    238:                           dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
                    239:        }
                    240: 
                    241:        /* Read in the station address. */
                    242:        for (i = 0; i < 6; i++)
                    243:                printk(" %2.2x", dev->dev_addr[i]);
                    244:        printk(", IRQ %d.\n", dev->irq);
                    245: 
                    246:        /* Make up a EL3-specific-data structure. */
                    247:        dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
                    248:        if (dev->priv == NULL)
                    249:                return -ENOMEM;
                    250:        memset(dev->priv, 0, sizeof(struct el3_private));
                    251: 
                    252:        if (el3_debug > 0)
                    253:                printk(version);
                    254: 
                    255:        /* The EL3-specific entries in the device structure. */
                    256:        dev->open = &el3_open;
                    257:        dev->hard_start_xmit = &el3_start_xmit;
                    258:        dev->stop = &el3_close;
                    259:        dev->get_stats = &el3_get_stats;
                    260:        dev->set_multicast_list = &set_multicast_list;
                    261: 
                    262:        /* Fill in the generic fields of the device structure. */
                    263:        ether_setup(dev);
                    264:        return 0;
                    265: }
                    266: 
                    267: /* Read a word from the EEPROM using the regular EEPROM access register.
                    268:    Assume that we are in register window zero.
                    269:  */
                    270: static ushort read_eeprom(short ioaddr, int index)
                    271: {
                    272:        int timer;
                    273: 
                    274:        outw(EEPROM_READ + index, ioaddr + 10);
                    275:        /* Pause for at least 162 us. for the read to take place. */
                    276:        for (timer = 0; timer < 162*4 + 400; timer++)
                    277:                SLOW_DOWN_IO;
                    278:        return inw(ioaddr + 12);
                    279: }
                    280: 
                    281: /* Read a word from the EEPROM when in the ISA ID probe state. */
                    282: static ushort id_read_eeprom(int index)
                    283: {
                    284:        int timer, bit, word = 0;
                    285: 
                    286:        /* Issue read command, and pause for at least 162 us. for it to complete.
                    287:           Assume extra-fast 16Mhz bus. */
                    288:        outb(EEPROM_READ + index, ID_PORT);
                    289: 
                    290:        /* This should really be done by looking at one of the timer channels. */
                    291:        for (timer = 0; timer < 162*4 + 400; timer++)
                    292:                SLOW_DOWN_IO;
                    293: 
                    294:        for (bit = 15; bit >= 0; bit--)
                    295:                word = (word << 1) + (inb(ID_PORT) & 0x01);
                    296: 
                    297:        if (el3_debug > 3)
                    298:                printk("  3c509 EEPROM word %d %#4.4x.\n", index, word);
                    299: 
                    300:        return word;
                    301: }
                    302: 
                    303: 
                    304: 
                    305: static int
                    306: el3_open(struct device *dev)
                    307: {
                    308:        int ioaddr = dev->base_addr;
                    309:        int i;
                    310: 
                    311:        outw(TxReset, ioaddr + EL3_CMD);
                    312:        outw(RxReset, ioaddr + EL3_CMD);
                    313:        outw(SetReadZero | 0x00, ioaddr + EL3_CMD);
                    314: 
                    315:        if (request_irq(dev->irq, &el3_interrupt, 0, "3c509")) {
                    316:                return -EAGAIN;
                    317:        }
                    318: 
                    319:        EL3WINDOW(0);
                    320:        if (el3_debug > 3)
                    321:                printk("%s: Opening, IRQ %d      status@%x %4.4x.\n", dev->name,
                    322:                           dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
                    323: 
                    324:        /* Activate board: this is probably unnecessary. */
                    325:        outw(0x0001, ioaddr + 4);
                    326: 
                    327:        irq2dev_map[dev->irq] = dev;
                    328: 
                    329:        /* Set the IRQ line. */
                    330:        outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
                    331: 
                    332:        /* Set the station address in window 2 each time opened. */
                    333:        EL3WINDOW(2);
                    334: 
                    335:        for (i = 0; i < 6; i++)
                    336:                outb(dev->dev_addr[i], ioaddr + i);
                    337: 
                    338:        if (dev->if_port == 3)
                    339:                /* Start the thinnet transceiver. We should really wait 50ms...*/
                    340:                outw(StartCoax, ioaddr + EL3_CMD);
                    341:        else if (dev->if_port == 0) {
                    342:                /* 10baseT interface, enabled link beat and jabber check. */
                    343:                EL3WINDOW(4);
                    344:                outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
                    345:        }
                    346: 
                    347:        /* Switch to the stats window, and clear all stats by reading. */
                    348:        outw(StatsDisable, ioaddr + EL3_CMD);
                    349:        EL3WINDOW(6);
                    350:        for (i = 0; i < 9; i++)
                    351:                inb(ioaddr + i);
                    352:        inb(ioaddr + 10);
                    353:        inb(ioaddr + 12);
                    354: 
                    355:        /* Switch to register set 1 for normal use. */
                    356:        EL3WINDOW(1);
                    357: 
                    358:        /* Accept b-case and phys addr only. */
                    359:        outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
                    360:        outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
                    361: 
                    362:        dev->interrupt = 0;
                    363:        dev->tbusy = 0;
                    364:        dev->start = 1;
                    365: 
                    366:        outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
                    367:        outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
                    368:        /* Allow status bits to be seen. */
                    369:        outw(SetReadZero | 0xff, ioaddr + EL3_CMD);
                    370:        outw(AckIntr | 0x69, ioaddr + EL3_CMD); /* Ack IRQ */
                    371:        outw(SetIntrMask | 0x98, ioaddr + EL3_CMD); /* Set interrupt mask. */
                    372: 
                    373:        if (el3_debug > 3)
                    374:                printk("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
                    375:                           dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
                    376: 
                    377:        MOD_INC_USE_COUNT;
                    378:        return 0;                                       /* Always succeed */
                    379: }
                    380: 
                    381: static int
                    382: el3_start_xmit(struct sk_buff *skb, struct device *dev)
                    383: {
                    384:        struct el3_private *lp = (struct el3_private *)dev->priv;
                    385:        int ioaddr = dev->base_addr;
                    386: 
                    387:        /* Transmitter timeout, serious problems. */
                    388:        if (dev->tbusy) {
                    389:                int tickssofar = jiffies - dev->trans_start;
                    390:                if (tickssofar < 10)
                    391:                        return 1;
                    392:                printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
                    393:                           dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS));
                    394:                dev->trans_start = jiffies;
                    395:                /* Issue TX_RESET and TX_START commands. */
                    396:                outw(TxReset, ioaddr + EL3_CMD);
                    397:                outw(TxEnable, ioaddr + EL3_CMD);
                    398:                dev->tbusy = 0;
                    399:        }
                    400: 
                    401:        if (skb == NULL) {
                    402:                dev_tint(dev);
                    403:                return 0;
                    404:        }
                    405: 
                    406:        if (skb->len <= 0)
                    407:                return 0;
                    408: 
                    409:        if (el3_debug > 4) {
                    410:                printk("%s: el3_start_xmit(length = %ld) called, status %4.4x.\n",
                    411:                           dev->name, skb->len, inw(ioaddr + EL3_STATUS));
                    412:        }
                    413: #ifndef final_version
                    414:        {       /* Error-checking code, delete for 1.30. */
                    415:                ushort status = inw(ioaddr + EL3_STATUS);
                    416:                if (status & 0x0001             /* IRQ line active, missed one. */
                    417:                        && inw(ioaddr + EL3_STATUS) & 1) {                      /* Make sure. */
                    418:                        printk("%s: Missed interrupt, status then %04x now %04x"
                    419:                                   "  Tx %2.2x Rx %4.4x.\n", dev->name, status,
                    420:                                   inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
                    421:                                   inw(ioaddr + RX_STATUS));
                    422:                        /* Fake interrupt trigger by masking, acknowledge interrupts. */
                    423:                        outw(SetReadZero | 0x00, ioaddr + EL3_CMD);
                    424:                        outw(AckIntr | 0x69, ioaddr + EL3_CMD); /* Ack IRQ */
                    425:                        outw(SetReadZero | 0xff, ioaddr + EL3_CMD);
                    426:                }
                    427:        }
                    428: #endif
                    429: 
                    430:        /* Avoid timer-based retransmission conflicts. */
                    431:        if (set_bit(0, (void*)&dev->tbusy) != 0)
                    432:                printk("%s: Transmitter access conflict.\n", dev->name);
                    433:        else {
                    434:                /* Put out the doubleword header... */
                    435:                outw(skb->len, ioaddr + TX_FIFO);
                    436:                outw(0x00, ioaddr + TX_FIFO);
                    437:                /* ... and the packet rounded to a doubleword. */
                    438:                outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
                    439: 
                    440:                dev->trans_start = jiffies;
                    441:                if (inw(ioaddr + TX_FREE) > 1536) {
                    442:                        dev->tbusy = 0;
                    443:                } else
                    444:                        /* Interrupt us when the FIFO has room for max-sized packet. */
                    445:                        outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
                    446:        }
                    447: 
                    448:        dev_kfree_skb (skb, FREE_WRITE);
                    449: 
                    450:        /* Clear the Tx status stack. */
                    451:        {
                    452:                short tx_status;
                    453:                int i = 4;
                    454: 
                    455:                while (--i > 0  &&      (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
                    456:                        if (tx_status & 0x38) lp->stats.tx_aborted_errors++;
                    457:                        if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
                    458:                        if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
                    459:                        outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
                    460:                }
                    461:        }
                    462:        return 0;
                    463: }
                    464: 
                    465: /* The EL3 interrupt handler. */
                    466: static void
                    467: el3_interrupt(int irq, struct pt_regs *regs)
                    468: {
                    469:        struct device *dev = (struct device *)(irq2dev_map[irq]);
                    470:        int ioaddr, status;
                    471:        int i = 0;
                    472: 
                    473:        if (dev == NULL) {
                    474:                printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
                    475:                return;
                    476:        }
                    477: 
                    478:        if (dev->interrupt)
                    479:                printk("%s: Re-entering the interrupt handler.\n", dev->name);
                    480:        dev->interrupt = 1;
                    481: 
                    482:        ioaddr = dev->base_addr;
                    483:        status = inw(ioaddr + EL3_STATUS);
                    484: 
                    485:        if (el3_debug > 4)
                    486:                printk("%s: interrupt, status %4.4x.\n", dev->name, status);
                    487: 
                    488:        while ((status = inw(ioaddr + EL3_STATUS)) & 0x91) {
                    489: 
                    490:                if (status & 0x10)
                    491:                        el3_rx(dev);
                    492: 
                    493:                if (status & 0x08) {
                    494:                        if (el3_debug > 5)
                    495:                                printk("        TX room bit was handled.\n");
                    496:                        /* There's room in the FIFO for a full-sized packet. */
                    497:                        outw(AckIntr | 0x08, ioaddr + EL3_CMD);
                    498:                        dev->tbusy = 0;
                    499:                        mark_bh(NET_BH);
                    500:                }
                    501:                if (status & 0x80)                              /* Statistics full. */
                    502:                        update_stats(ioaddr, dev);
                    503: 
                    504:                if (++i > 10) {
                    505:                        printk("%s: Infinite loop in interrupt, status %4.4x.\n",
                    506:                                   dev->name, status);
                    507:                        /* Clear all interrupts. */
                    508:                        outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
                    509:                        break;
                    510:                }
                    511:                /* Acknowledge the IRQ. */
                    512:                outw(AckIntr | 0x41, ioaddr + EL3_CMD); /* Ack IRQ */
                    513: 
                    514:        }
                    515: 
                    516:        if (el3_debug > 4) {
                    517:                printk("%s: exiting interrupt, status %4.4x.\n", dev->name,
                    518:                           inw(ioaddr + EL3_STATUS));
                    519:        }
                    520: 
                    521:        dev->interrupt = 0;
                    522:        return;
                    523: }
                    524: 
                    525: 
                    526: static struct enet_statistics *
                    527: el3_get_stats(struct device *dev)
                    528: {
                    529:        struct el3_private *lp = (struct el3_private *)dev->priv;
                    530:        unsigned long flags;
                    531: 
                    532:        save_flags(flags);
                    533:        cli();
                    534:        update_stats(dev->base_addr, dev);
                    535:        restore_flags(flags);
                    536:        return &lp->stats;
                    537: }
                    538: 
                    539: /*  Update statistics.  We change to register window 6, so this should be run
                    540:        single-threaded if the device is active. This is expected to be a rare
                    541:        operation, and it's simpler for the rest of the driver to assume that
                    542:        window 1 is always valid rather than use a special window-state variable.
                    543:        */
                    544: static void update_stats(int ioaddr, struct device *dev)
                    545: {
                    546:        struct el3_private *lp = (struct el3_private *)dev->priv;
                    547: 
                    548:        if (el3_debug > 5)
                    549:                printk("   Updating the statistics.\n");
                    550:        /* Turn off statistics updates while reading. */
                    551:        outw(StatsDisable, ioaddr + EL3_CMD);
                    552:        /* Switch to the stats window, and read everything. */
                    553:        EL3WINDOW(6);
                    554:        lp->stats.tx_carrier_errors     += inb(ioaddr + 0);
                    555:        lp->stats.tx_heartbeat_errors   += inb(ioaddr + 1);
                    556:        /* Multiple collisions. */              inb(ioaddr + 2);
                    557:        lp->stats.collisions                    += inb(ioaddr + 3);
                    558:        lp->stats.tx_window_errors              += inb(ioaddr + 4);
                    559:        lp->stats.rx_fifo_errors                += inb(ioaddr + 5);
                    560:        lp->stats.tx_packets                    += inb(ioaddr + 6);
                    561:        /* Rx packets   */                              inb(ioaddr + 7);
                    562:        /* Tx deferrals */                              inb(ioaddr + 8);
                    563:        inw(ioaddr + 10);       /* Total Rx and Tx octets. */
                    564:        inw(ioaddr + 12);
                    565: 
                    566:        /* Back to window 1, and turn statistics back on. */
                    567:        EL3WINDOW(1);
                    568:        outw(StatsEnable, ioaddr + EL3_CMD);
                    569:        return;
                    570: }
                    571: 
                    572: static int
                    573: el3_rx(struct device *dev)
                    574: {
                    575:        struct el3_private *lp = (struct el3_private *)dev->priv;
                    576:        int ioaddr = dev->base_addr;
                    577:        short rx_status;
                    578: 
                    579:        if (el3_debug > 5)
                    580:                printk("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
                    581:                           inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
                    582:        while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
                    583:                if (rx_status & 0x4000) { /* Error, update stats. */
                    584:                        short error = rx_status & 0x3800;
                    585:                        lp->stats.rx_errors++;
                    586:                        switch (error) {
                    587:                        case 0x0000:            lp->stats.rx_over_errors++; break;
                    588:                        case 0x0800:            lp->stats.rx_length_errors++; break;
                    589:                        case 0x1000:            lp->stats.rx_frame_errors++; break;
                    590:                        case 0x1800:            lp->stats.rx_length_errors++; break;
                    591:                        case 0x2000:            lp->stats.rx_frame_errors++; break;
                    592:                        case 0x2800:            lp->stats.rx_crc_errors++; break;
                    593:                        }
                    594:                } else {
                    595:                        short pkt_len = rx_status & 0x7ff;
                    596:                        struct sk_buff *skb;
                    597: 
                    598:                        skb = dev_alloc_skb(pkt_len+5);
                    599:                        if (el3_debug > 4)
                    600:                                printk("Receiving packet size %d status %4.4x.\n",
                    601:                                           pkt_len, rx_status);
                    602:                        if (skb != NULL) {
                    603:                                skb->dev = dev;
                    604:                                skb_reserve(skb,2);     /* Align IP on 16 byte boundaries */
                    605: 
                    606:                                /* 'skb->data' points to the start of sk_buff data area. */
                    607:                                insl(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
                    608:                                                        (pkt_len + 3) >> 2);
                    609: 
                    610:                                skb->protocol=eth_type_trans(skb,dev);
                    611:                                netif_rx(skb);
                    612:                                outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
                    613:                                lp->stats.rx_packets++;
                    614:                                continue;
                    615:                        } else if (el3_debug)
                    616:                                printk("%s: Couldn't allocate a sk_buff of size %d.\n",
                    617:                                           dev->name, pkt_len);
                    618:                }
                    619:                lp->stats.rx_dropped++;
                    620:                outw(RxDiscard, ioaddr + EL3_CMD);
                    621:                while (inw(ioaddr + EL3_STATUS) & 0x1000)
                    622:                        printk("        Waiting for 3c509 to discard packet, status %x.\n",
                    623:                                   inw(ioaddr + EL3_STATUS) );
                    624:        }
                    625: 
                    626:        return 0;
                    627: }
                    628: 
                    629: /* 
                    630:  *     Set or clear the multicast filter for this adaptor.
                    631:  */
                    632:  
                    633: static void set_multicast_list(struct device *dev)
                    634: {
                    635:        short ioaddr = dev->base_addr;
                    636:        if (el3_debug > 1) {
                    637:                static int old = 0;
                    638:                if (old != dev->mc_count) {
                    639:                        old = dev->mc_count;
                    640:                        printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
                    641:                }
                    642:        }
                    643:        if (dev->flags&IFF_PROMISC) 
                    644:        {
                    645:                outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
                    646:                         ioaddr + EL3_CMD);
                    647:        }
                    648:        else if (dev->mc_count || (dev->flags&IFF_ALLMULTI)) 
                    649:        {
                    650:                outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
                    651:        } 
                    652:        else
                    653:                outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
                    654: }
                    655: 
                    656: static int
                    657: el3_close(struct device *dev)
                    658: {
                    659:        int ioaddr = dev->base_addr;
                    660: 
                    661:        if (el3_debug > 2)
                    662:                printk("%s: Shutting down ethercard.\n", dev->name);
                    663: 
                    664:        dev->tbusy = 1;
                    665:        dev->start = 0;
                    666: 
                    667:        /* Turn off statistics ASAP.  We update lp->stats below. */
                    668:        outw(StatsDisable, ioaddr + EL3_CMD);
                    669: 
                    670:        /* Disable the receiver and transmitter. */
                    671:        outw(RxDisable, ioaddr + EL3_CMD);
                    672:        outw(TxDisable, ioaddr + EL3_CMD);
                    673: 
                    674:        if (dev->if_port == 3)
                    675:                /* Turn off thinnet power.  Green! */
                    676:                outw(StopCoax, ioaddr + EL3_CMD);
                    677:        else if (dev->if_port == 0) {
                    678:                /* Disable link beat and jabber, if_port may change ere next open(). */
                    679:                EL3WINDOW(4);
                    680:                outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
                    681:        }
                    682: 
                    683:        free_irq(dev->irq);
                    684:        /* Switching back to window 0 disables the IRQ. */
                    685:        EL3WINDOW(0);
                    686:        /* But we explicitly zero the IRQ line select anyway. */
                    687:        outw(0x0f00, ioaddr + WN0_IRQ);
                    688: 
                    689: 
                    690:        irq2dev_map[dev->irq] = 0;
                    691: 
                    692:        update_stats(ioaddr, dev);
                    693:        MOD_DEC_USE_COUNT;
                    694:        return 0;
                    695: }
                    696: 
                    697: #ifdef MODULE
                    698: static char devicename[9] = { 0, };
                    699: static struct device dev_3c509 = {
                    700:        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
                    701:        0, 0, 0, 0,
                    702:        0, 0,
                    703:        0, 0, 0, NULL, el3_probe };
                    704: 
                    705: static int io = 0;
                    706: static int irq = 0;
                    707: 
                    708: int
                    709: init_module(void)
                    710: {
                    711:        dev_3c509.base_addr = io;
                    712:        dev_3c509.irq       = irq;
                    713:        if (!EISA_bus) {
                    714:                printk("3c509: WARNING! Module load-time probing works reliably only for EISA-bus!\n");
                    715:        }
                    716:        if (register_netdev(&dev_3c509) != 0)
                    717:                return -EIO;
                    718:        return 0;
                    719: }
                    720: 
                    721: void
                    722: cleanup_module(void)
                    723: {
                    724:        unregister_netdev(&dev_3c509);
                    725:        kfree_s(dev_3c509.priv,sizeof(struct el3_private));
                    726:        dev_3c509.priv=NULL;
                    727:        /* If we don't do this, we can't re-insmod it later. */
                    728:        release_region(dev_3c509.base_addr, EL3_IO_EXTENT);
                    729: }
                    730: #endif /* MODULE */
                    731: 
                    732: /*
                    733:  * Local variables:
                    734:  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 3c509.c"
                    735:  *  version-control: t
                    736:  *  kept-new-versions: 5
                    737:  *  tab-width: 4
                    738:  * End:
                    739:  */

unix.superglobalmegacorp.com

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