Annotation of Gnu-Mach/linux/src/drivers/net/de620.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  *     de620.c $Revision: 1.1 $ BETA
                      3:  *
                      4:  *
                      5:  *     Linux driver for the D-Link DE-620 Ethernet pocket adapter.
                      6:  *
                      7:  *     Portions (C) Copyright 1993, 1994 by Bjorn Ekwall <[email protected]>
                      8:  *
                      9:  *     Based on adapter information gathered from DOS packetdriver
                     10:  *     sources from D-Link Inc:  (Special thanks to Henry Ngai of D-Link.)
                     11:  *             Portions (C) Copyright D-Link SYSTEM Inc. 1991, 1992
                     12:  *             Copyright, 1988, Russell Nelson, Crynwr Software
                     13:  *
                     14:  *     Adapted to the sample network driver core for linux,
                     15:  *     written by: Donald Becker <[email protected]>
                     16:  *             (Now at <[email protected]>
                     17:  *
                     18:  *     Valuable assistance from:
                     19:  *             J. Joshua Kopper <[email protected]>
                     20:  *             Olav Kvittem <[email protected]>
                     21:  *             Germano Caronni <[email protected]>
                     22:  *             Jeremy Fitzhardinge <[email protected]>
                     23:  *
                     24:  *****************************************************************************/
                     25: /*
                     26:  *     This program is free software; you can redistribute it and/or modify
                     27:  *     it under the terms of the GNU General Public License as published by
                     28:  *     the Free Software Foundation; either version 2, or (at your option)
                     29:  *     any later version.
                     30:  *
                     31:  *     This program is distributed in the hope that it will be useful,
                     32:  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     33:  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     34:  *     GNU General Public License for more details.
                     35:  *
                     36:  *     You should have received a copy of the GNU General Public License
                     37:  *     along with this program; if not, write to the Free Software
                     38:  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
                     39:  *
                     40:  *****************************************************************************/
                     41: static const char *version =
                     42:        "de620.c: $Revision: 1.1 $,  Bjorn Ekwall <[email protected]>\n";
                     43: 
                     44: /***********************************************************************
                     45:  *
                     46:  * "Tuning" section.
                     47:  *
                     48:  * Compile-time options: (see below for descriptions)
                     49:  * -DDE620_IO=0x378    (lpt1)
                     50:  * -DDE620_IRQ=7       (lpt1)
                     51:  * -DDE602_DEBUG=...
                     52:  * -DSHUTDOWN_WHEN_LOST
                     53:  * -DCOUNT_LOOPS
                     54:  * -DLOWSPEED
                     55:  * -DREAD_DELAY
                     56:  * -DWRITE_DELAY
                     57:  */
                     58: 
                     59: /*
                     60:  * This driver assumes that the printer port is a "normal",
                     61:  * dumb, uni-directional port!
                     62:  * If your port is "fancy" in any way, please try to set it to "normal"
                     63:  * with your BIOS setup.  I have no access to machines with bi-directional
                     64:  * ports, so I can't test such a driver :-(
                     65:  * (Yes, I _know_ it is possible to use DE620 with bidirectional ports...)
                     66:  *
                     67:  * There are some clones of DE620 out there, with different names.
                     68:  * If the current driver does not recognize a clone, try to change
                     69:  * the following #define to:
                     70:  *
                     71:  * #define DE620_CLONE 1
                     72:  */
                     73: #define DE620_CLONE 0
                     74: 
                     75: /*
                     76:  * If the adapter has problems with high speeds, enable this #define
                     77:  * otherwise full printerport speed will be attempted.
                     78:  *
                     79:  * You can tune the READ_DELAY/WRITE_DELAY below if you enable LOWSPEED
                     80:  *
                     81: #define LOWSPEED
                     82:  */
                     83: 
                     84: #ifndef READ_DELAY
                     85: #define READ_DELAY 100 /* adapter internal read delay in 100ns units */
                     86: #endif
                     87: 
                     88: #ifndef WRITE_DELAY
                     89: #define WRITE_DELAY 100        /* adapter internal write delay in 100ns units */
                     90: #endif
                     91: 
                     92: /*
                     93:  * Enable this #define if you want the adapter to do a "ifconfig down" on
                     94:  * itself when we have detected that something is possibly wrong with it.
                     95:  * The default behaviour is to retry with "adapter_init()" until success.
                     96:  * This should be used for debugging purposes only.
                     97:  *
                     98: #define SHUTDOWN_WHEN_LOST
                     99:  */
                    100: 
                    101: /*
                    102:  * Enable debugging by "-DDE620_DEBUG=3" when compiling,
                    103:  * OR in "./CONFIG"
                    104:  * OR by enabling the following #define
                    105:  *
                    106:  * use 0 for production, 1 for verification, >2 for debug
                    107:  *
                    108: #define DE620_DEBUG 3
                    109:  */
                    110: 
                    111: #ifdef LOWSPEED
                    112: /*
                    113:  * Enable this #define if you want to see debugging output that show how long
                    114:  * we have to wait before the DE-620 is ready for the next read/write/command.
                    115:  *
                    116: #define COUNT_LOOPS
                    117:  */
                    118: #endif
                    119: 
                    120: #include <linux/module.h>
                    121: 
                    122: #include <linux/kernel.h>
                    123: #include <linux/sched.h>
                    124: #include <linux/types.h>
                    125: #include <linux/fcntl.h>
                    126: #include <linux/string.h>
                    127: #include <linux/interrupt.h>
                    128: #include <linux/ioport.h>
                    129: #include <asm/io.h>
                    130: #include <linux/in.h>
                    131: #include <linux/ptrace.h>
                    132: #include <asm/system.h>
                    133: #include <linux/errno.h>
                    134: 
                    135: #include <linux/inet.h>
                    136: #include <linux/netdevice.h>
                    137: #include <linux/etherdevice.h>
                    138: #include <linux/skbuff.h>
                    139: 
                    140: /* Constant definitions for the DE-620 registers, commands and bits */
                    141: #include "de620.h"
                    142: 
                    143: #define netstats enet_statistics
                    144: typedef unsigned char byte;
                    145: 
                    146: /*******************************************************
                    147:  *                                                     *
                    148:  * Definition of D-Link DE-620 Ethernet Pocket adapter *
                    149:  * See also "de620.h"                                  *
                    150:  *                                                     *
                    151:  *******************************************************/
                    152: #ifndef DE620_IO /* Compile-time configurable */
                    153: #define DE620_IO 0x378
                    154: #endif
                    155: 
                    156: #ifndef DE620_IRQ /* Compile-time configurable */
                    157: #define DE620_IRQ      7
                    158: #endif
                    159: 
                    160: #define DATA_PORT      (dev->base_addr)
                    161: #define STATUS_PORT    (dev->base_addr + 1)
                    162: #define COMMAND_PORT   (dev->base_addr + 2)
                    163: 
                    164: #define RUNT 60                /* Too small Ethernet packet */
                    165: #define GIANT 1514     /* largest legal size packet, no fcs */
                    166: 
                    167: #ifdef DE620_DEBUG /* Compile-time configurable */
                    168: #define PRINTK(x) if (de620_debug >= 2) printk x
                    169: #else
                    170: #define DE620_DEBUG 0
                    171: #define PRINTK(x) /**/
                    172: #endif
                    173: 
                    174: 
                    175: /*
                    176:  * Force media with insmod:
                    177:  *     insmod de620.o bnc=1
                    178:  * or
                    179:  *     insmod de620.o utp=1
                    180:  *
                    181:  * Force io and/or irq with insmod:
                    182:  *     insmod de620.o io=0x378 irq=7
                    183:  *
                    184:  * Make a clone skip the Ethernet-address range check:
                    185:  *     insmod de620.o clone=1
                    186:  */
                    187: static int bnc = 0;
                    188: static int utp = 0;
                    189: static int io  = DE620_IO;
                    190: static int irq = DE620_IRQ;
                    191: static int clone = DE620_CLONE;
                    192: 
                    193: static unsigned int de620_debug = DE620_DEBUG;
                    194: 
                    195: /***********************************************
                    196:  *                                             *
                    197:  * Index to functions, as function prototypes. *
                    198:  *                                             *
                    199:  ***********************************************/
                    200: 
                    201: /*
                    202:  * Routines used internally. (See also "convenience macros.. below")
                    203:  */
                    204: 
                    205: /* Put in the device structure. */
                    206: static int     de620_open(struct device *);
                    207: static int     de620_close(struct device *);
                    208: static struct netstats *get_stats(struct device *);
                    209: static void    de620_set_multicast_list(struct device *);
                    210: static int     de620_start_xmit(struct sk_buff *, struct device *);
                    211: 
                    212: /* Dispatch from interrupts. */
                    213: static void    de620_interrupt(int, void *, struct pt_regs *);
                    214: static int     de620_rx_intr(struct device *);
                    215: 
                    216: /* Initialization */
                    217: static int     adapter_init(struct device *);
                    218: int            de620_probe(struct device *);
                    219: static int     read_eeprom(struct device *);
                    220: 
                    221: 
                    222: /*
                    223:  * D-Link driver variables:
                    224:  */
                    225: #define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX
                    226: #define        TCR_DEF RXPB                    /* not used: | TXSUCINT | T16INT */
                    227: #define DE620_RX_START_PAGE 12         /* 12 pages (=3k) reserved for tx */
                    228: #define DEF_NIC_CMD IRQEN | ICEN | DS1
                    229: 
                    230: static volatile byte   NIC_Cmd;
                    231: static volatile byte   next_rx_page;
                    232: static byte            first_rx_page;
                    233: static byte            last_rx_page;
                    234: static byte            EIPRegister;
                    235: 
                    236: static struct nic {
                    237:        byte    NodeID[6];
                    238:        byte    RAM_Size;
                    239:        byte    Model;
                    240:        byte    Media;
                    241:        byte    SCR;
                    242: } nic_data;
                    243: 
                    244: /**********************************************************
                    245:  *                                                        *
                    246:  * Convenience macros/functions for D-Link DE-620 adapter *
                    247:  *                                                        *
                    248:  **********************************************************/
                    249: #define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1))
                    250: #define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT);
                    251: 
                    252: /* Check for ready-status, and return a nibble (high 4 bits) for data input */
                    253: #ifdef COUNT_LOOPS
                    254: static int tot_cnt;
                    255: #endif
                    256: static inline byte
                    257: de620_ready(struct device *dev)
                    258: {
                    259:        byte value;
                    260:        register short int cnt = 0;
                    261: 
                    262:        while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000))
                    263:                ++cnt;
                    264: 
                    265: #ifdef COUNT_LOOPS
                    266:        tot_cnt += cnt;
                    267: #endif
                    268:        return value & 0xf0; /* nibble */
                    269: }
                    270: 
                    271: static inline void
                    272: de620_send_command(struct device *dev, byte cmd)
                    273: {
                    274:        de620_ready(dev);
                    275:        if (cmd == W_DUMMY)
                    276:                outb(NIC_Cmd, COMMAND_PORT);
                    277: 
                    278:        outb(cmd, DATA_PORT);
                    279: 
                    280:        outb(NIC_Cmd ^ CS0, COMMAND_PORT);
                    281:        de620_ready(dev);
                    282:        outb(NIC_Cmd, COMMAND_PORT);
                    283: }
                    284: 
                    285: static inline void
                    286: de620_put_byte(struct device *dev, byte value)
                    287: {
                    288:        /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
                    289:        de620_ready(dev);
                    290:        outb(value, DATA_PORT);
                    291:        de620_flip_ds(dev);
                    292: }
                    293: 
                    294: static inline byte
                    295: de620_read_byte(struct device *dev)
                    296: {
                    297:        byte value;
                    298: 
                    299:        /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
                    300:        value = de620_ready(dev); /* High nibble */
                    301:        de620_flip_ds(dev);
                    302:        value |= de620_ready(dev) >> 4; /* Low nibble */
                    303:        return value;
                    304: }
                    305: 
                    306: static inline void
                    307: de620_write_block(struct device *dev, byte *buffer, int count)
                    308: {
                    309: #ifndef LOWSPEED
                    310:        byte uflip = NIC_Cmd ^ (DS0 | DS1);
                    311:        byte dflip = NIC_Cmd;
                    312: #else /* LOWSPEED */
                    313: #ifdef COUNT_LOOPS
                    314:        int bytes = count;
                    315: #endif /* COUNT_LOOPS */
                    316: #endif /* LOWSPEED */
                    317: 
                    318: #ifdef LOWSPEED
                    319: #ifdef COUNT_LOOPS
                    320:        tot_cnt = 0;
                    321: #endif /* COUNT_LOOPS */
                    322:        /* No further optimization useful, the limit is in the adapter. */
                    323:        for ( ; count > 0; --count, ++buffer) {
                    324:                de620_put_byte(dev,*buffer);
                    325:        }
                    326:        de620_send_command(dev,W_DUMMY);
                    327: #ifdef COUNT_LOOPS
                    328:        /* trial debug output: loops per byte in de620_ready() */
                    329:        printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
                    330: #endif /* COUNT_LOOPS */
                    331: #else /* not LOWSPEED */
                    332:        for ( ; count > 0; count -=2) {
                    333:                outb(*buffer++, DATA_PORT);
                    334:                outb(uflip, COMMAND_PORT);
                    335:                outb(*buffer++, DATA_PORT);
                    336:                outb(dflip, COMMAND_PORT);
                    337:        }
                    338:        de620_send_command(dev,W_DUMMY);
                    339: #endif /* LOWSPEED */
                    340: }
                    341: 
                    342: static inline void
                    343: de620_read_block(struct device *dev, byte *data, int count)
                    344: {
                    345: #ifndef LOWSPEED
                    346:        byte value;
                    347:        byte uflip = NIC_Cmd ^ (DS0 | DS1);
                    348:        byte dflip = NIC_Cmd;
                    349: #else /* LOWSPEED */
                    350: #ifdef COUNT_LOOPS
                    351:        int bytes = count;
                    352: 
                    353:        tot_cnt = 0;
                    354: #endif /* COUNT_LOOPS */
                    355: #endif /* LOWSPEED */
                    356: 
                    357: #ifdef LOWSPEED
                    358:        /* No further optimization useful, the limit is in the adapter. */
                    359:        while (count-- > 0) {
                    360:                *data++ = de620_read_byte(dev);
                    361:                de620_flip_ds(dev);
                    362:        }
                    363: #ifdef COUNT_LOOPS
                    364:        /* trial debug output: loops per byte in de620_ready() */
                    365:        printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
                    366: #endif /* COUNT_LOOPS */
                    367: #else /* not LOWSPEED */
                    368:        while (count-- > 0) {
                    369:                value = inb(STATUS_PORT) & 0xf0; /* High nibble */
                    370:                outb(uflip, COMMAND_PORT);
                    371:                *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */
                    372:                outb(dflip , COMMAND_PORT);
                    373:        }
                    374: #endif /* LOWSPEED */
                    375: }
                    376: 
                    377: static inline void
                    378: de620_set_delay(struct device *dev)
                    379: {
                    380:        de620_ready(dev);
                    381:        outb(W_DFR, DATA_PORT);
                    382:        outb(NIC_Cmd ^ CS0, COMMAND_PORT);
                    383: 
                    384:        de620_ready(dev);
                    385: #ifdef LOWSPEED
                    386:        outb(WRITE_DELAY, DATA_PORT);
                    387: #else
                    388:        outb(0, DATA_PORT);
                    389: #endif
                    390:        de620_flip_ds(dev);
                    391: 
                    392:        de620_ready(dev);
                    393: #ifdef LOWSPEED
                    394:        outb(READ_DELAY, DATA_PORT);
                    395: #else
                    396:        outb(0, DATA_PORT);
                    397: #endif
                    398:        de620_flip_ds(dev);
                    399: }
                    400: 
                    401: static inline void
                    402: de620_set_register(struct device *dev, byte reg, byte value)
                    403: {
                    404:        de620_ready(dev);
                    405:        outb(reg, DATA_PORT);
                    406:        outb(NIC_Cmd ^ CS0, COMMAND_PORT);
                    407: 
                    408:        de620_put_byte(dev, value);
                    409: }
                    410: 
                    411: static inline byte
                    412: de620_get_register(struct device *dev, byte reg)
                    413: {
                    414:        byte value;
                    415: 
                    416:        de620_send_command(dev,reg);
                    417:        value = de620_read_byte(dev);
                    418:        de620_send_command(dev,W_DUMMY);
                    419: 
                    420:        return value;
                    421: }
                    422: 
                    423: /*********************************************************************
                    424:  *
                    425:  * Open/initialize the board.
                    426:  *
                    427:  * This routine should set everything up anew at each open, even
                    428:  * registers that "should" only need to be set once at boot, so that
                    429:  * there is a non-reboot way to recover if something goes wrong.
                    430:  *
                    431:  */
                    432: static int
                    433: de620_open(struct device *dev)
                    434: {
                    435:        if (request_irq(dev->irq, de620_interrupt, 0, "de620", NULL)) {
                    436:                printk ("%s: unable to get IRQ %d\n", dev->name, dev->irq);
                    437:                return 1;
                    438:        }
                    439:        irq2dev_map[dev->irq] = dev;
                    440: 
                    441:        MOD_INC_USE_COUNT;
                    442:        if (adapter_init(dev)) {
                    443:                return 1;
                    444:        }
                    445:        dev->start = 1;
                    446:        return 0;
                    447: }
                    448: 
                    449: /************************************************
                    450:  *
                    451:  * The inverse routine to de620_open().
                    452:  *
                    453:  */
                    454: static int
                    455: de620_close(struct device *dev)
                    456: {
                    457:        /* disable recv */
                    458:        de620_set_register(dev, W_TCR, RXOFF);
                    459: 
                    460:        free_irq(dev->irq, NULL);
                    461:        irq2dev_map[dev->irq] = NULL;
                    462: 
                    463:        dev->start = 0;
                    464:        MOD_DEC_USE_COUNT;
                    465:        return 0;
                    466: }
                    467: 
                    468: /*********************************************
                    469:  *
                    470:  * Return current statistics
                    471:  *
                    472:  */
                    473: static struct netstats *
                    474: get_stats(struct device *dev)
                    475: {
                    476:        return (struct netstats *)(dev->priv);
                    477: }
                    478: 
                    479: /*********************************************
                    480:  *
                    481:  * Set or clear the multicast filter for this adaptor.
                    482:  * (no real multicast implemented for the DE-620, but she can be promiscuous...)
                    483:  *
                    484:  */
                    485: 
                    486: static void de620_set_multicast_list(struct device *dev)
                    487: {
                    488:        if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 
                    489:        { /* Enable promiscuous mode */
                    490:                /*
                    491:                 *      We must make the kernel realise we had to move
                    492:                 *      into promisc mode or we start all out war on
                    493:                 *      the cable. - AC
                    494:                 */
                    495:                dev->flags|=IFF_PROMISC;                
                    496:        
                    497:                de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
                    498:        }
                    499:        else 
                    500:        { /* Disable promiscuous mode, use normal mode */
                    501:                de620_set_register(dev, W_TCR, TCR_DEF);
                    502:        }
                    503: }
                    504: 
                    505: /*******************************************************
                    506:  *
                    507:  * Copy a buffer to the adapter transmit page memory.
                    508:  * Start sending.
                    509:  */
                    510: static int
                    511: de620_start_xmit(struct sk_buff *skb, struct device *dev)
                    512: {
                    513:        unsigned long flags;
                    514:        int len;
                    515:        int tickssofar;
                    516:        byte *buffer = skb->data;
                    517:        byte using_txbuf;
                    518: 
                    519:        /*
                    520:         * If some higher layer thinks we've missed a
                    521:         * tx-done interrupt we are passed NULL.
                    522:         * Caution: dev_tint() handles the cli()/sti() itself.
                    523:         */
                    524: 
                    525:        if (skb == NULL) {
                    526:                dev_tint(dev);
                    527:                return 0;
                    528:        }
                    529: 
                    530:        using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */
                    531:        dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
                    532: 
                    533:        if (dev->tbusy) {       /* Do timeouts, to avoid hangs. */
                    534:                tickssofar = jiffies - dev->trans_start;
                    535: 
                    536:                if (tickssofar < 5)
                    537:                        return 1;
                    538: 
                    539:                /* else */
                    540:                printk("%s: transmit timed out (%d), %s?\n",
                    541:                        dev->name,
                    542:                        tickssofar,
                    543:                        "network cable problem"
                    544:                        );
                    545:                /* Restart the adapter. */
                    546:                if (adapter_init(dev)) /* maybe close it */
                    547:                        return 1;
                    548:        }
                    549: 
                    550:        if ((len = skb->len) < RUNT)
                    551:                len = RUNT;
                    552:        if (len & 1) /* send an even number of bytes */
                    553:                ++len;
                    554: 
                    555:        /* Start real output */
                    556:        save_flags(flags);
                    557:        cli();
                    558: 
                    559:        PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
                    560:                (int)skb->len, using_txbuf));
                    561: 
                    562:        /* select a free tx buffer. if there is one... */
                    563:        switch (using_txbuf) {
                    564:        default: /* both are free: use TXBF0 */
                    565:        case TXBF1: /* use TXBF0 */
                    566:                de620_send_command(dev,W_CR | RW0);
                    567:                using_txbuf |= TXBF0;
                    568:                break;
                    569: 
                    570:        case TXBF0: /* use TXBF1 */
                    571:                de620_send_command(dev,W_CR | RW1);
                    572:                using_txbuf |= TXBF1;
                    573:                break;
                    574: 
                    575:        case (TXBF0 | TXBF1): /* NONE!!! */
                    576:                printk("de620: Ouch! No tx-buffer available!\n");
                    577:                restore_flags(flags);
                    578:                return 1;
                    579:                break;
                    580:        }
                    581:        de620_write_block(dev, buffer, len);
                    582: 
                    583:        dev->trans_start = jiffies;
                    584:        dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
                    585: 
                    586:        ((struct netstats *)(dev->priv))->tx_packets++;
                    587:        
                    588:        restore_flags(flags); /* interrupts maybe back on */
                    589:        
                    590:        dev_kfree_skb (skb, FREE_WRITE);
                    591: 
                    592:        return 0;
                    593: }
                    594: 
                    595: /*****************************************************
                    596:  *
                    597:  * Handle the network interface interrupts.
                    598:  *
                    599:  */
                    600: static void
                    601: de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs)
                    602: {
                    603:        struct device *dev = irq2dev_map[irq_in];
                    604:        byte irq_status;
                    605:        int bogus_count = 0;
                    606:        int again = 0;
                    607: 
                    608:        /* This might be deleted now, no crummy drivers present :-) Or..? */
                    609:        if ((dev == NULL) || (irq != irq_in)) {
                    610:                printk("%s: bogus interrupt %d\n", dev?dev->name:"de620", irq_in);
                    611:                return;
                    612:        }
                    613: 
                    614:        cli();
                    615:        dev->interrupt = 1;
                    616: 
                    617:        /* Read the status register (_not_ the status port) */
                    618:        irq_status = de620_get_register(dev, R_STS);
                    619: 
                    620:        PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
                    621: 
                    622:        if (irq_status & RXGOOD) {
                    623:                do {
                    624:                        again = de620_rx_intr(dev);
                    625:                        PRINTK(("again=%d\n", again));
                    626:                }
                    627:                while (again && (++bogus_count < 100));
                    628:        }
                    629: 
                    630:        dev->tbusy = (de620_tx_buffs(dev) == (TXBF0 | TXBF1)); /* Boolean! */
                    631: 
                    632:        dev->interrupt = 0;
                    633:        sti();
                    634:        return;
                    635: }
                    636: 
                    637: /**************************************
                    638:  *
                    639:  * Get a packet from the adapter
                    640:  *
                    641:  * Send it "upstairs"
                    642:  *
                    643:  */
                    644: static int
                    645: de620_rx_intr(struct device *dev)
                    646: {
                    647:        struct header_buf {
                    648:                byte            status;
                    649:                byte            Rx_NextPage;
                    650:                unsigned short  Rx_ByteCount;
                    651:        } header_buf;
                    652:        struct sk_buff *skb;
                    653:        int size;
                    654:        byte *buffer;
                    655:        byte pagelink;
                    656:        byte curr_page;
                    657: 
                    658:        PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
                    659: 
                    660:        /* Tell the adapter that we are going to read data, and from where */
                    661:        de620_send_command(dev, W_CR | RRN);
                    662:        de620_set_register(dev, W_RSA1, next_rx_page);
                    663:        de620_set_register(dev, W_RSA0, 0);
                    664: 
                    665:        /* Deep breath, and away we goooooo */
                    666:        de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
                    667:        PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
                    668:        header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
                    669: 
                    670:        /* Plausible page header? */
                    671:        pagelink = header_buf.Rx_NextPage;
                    672:        if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
                    673:                /* Ouch... Forget it! Skip all and start afresh... */
                    674:                printk("%s: Ring overrun? Restoring...\n", dev->name);
                    675:                /* You win some, you loose some. And sometimes plenty... */
                    676:                adapter_init(dev);
                    677:                ((struct netstats *)(dev->priv))->rx_over_errors++;
                    678:                return 0;
                    679:        }
                    680: 
                    681:        /* OK, this look good, so far. Let's see if it's consistent... */
                    682:        /* Let's compute the start of the next packet, based on where we are */
                    683:        pagelink = next_rx_page +
                    684:                ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
                    685: 
                    686:        /* Are we going to wrap around the page counter? */
                    687:        if (pagelink > last_rx_page)
                    688:                pagelink -= (last_rx_page - first_rx_page + 1);
                    689: 
                    690:        /* Is the _computed_ next page number equal to what the adapter says? */
                    691:        if (pagelink != header_buf.Rx_NextPage) {
                    692:                /* Naah, we'll skip this packet. Probably bogus data as well */
                    693:                printk("%s: Page link out of sync! Restoring...\n", dev->name);
                    694:                next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
                    695:                de620_send_command(dev, W_DUMMY);
                    696:                de620_set_register(dev, W_NPRF, next_rx_page);
                    697:                ((struct netstats *)(dev->priv))->rx_over_errors++;
                    698:                return 0;
                    699:        }
                    700:        next_rx_page = pagelink;
                    701: 
                    702:        size = header_buf.Rx_ByteCount - 4;
                    703:        if ((size < RUNT) || (GIANT < size)) {
                    704:                printk("%s: Illegal packet size: %d!\n", dev->name, size);
                    705:        }
                    706:        else { /* Good packet? */
                    707:                skb = dev_alloc_skb(size+2);
                    708:                if (skb == NULL) { /* Yeah, but no place to put it... */
                    709:                        printk("%s: Couldn't allocate a sk_buff of size %d.\n",
                    710:                                dev->name, size);
                    711:                        ((struct netstats *)(dev->priv))->rx_dropped++;
                    712:                }
                    713:                else { /* Yep! Go get it! */
                    714:                        skb_reserve(skb,2);     /* Align */
                    715:                        skb->dev = dev;
                    716:                        skb->free = 1;
                    717:                        /* skb->data points to the start of sk_buff data area */
                    718:                        buffer = skb_put(skb,size);
                    719:                        /* copy the packet into the buffer */
                    720:                        de620_read_block(dev, buffer, size);
                    721:                        PRINTK(("Read %d bytes\n", size));
                    722:                        skb->protocol=eth_type_trans(skb,dev);
                    723:                        netif_rx(skb); /* deliver it "upstairs" */
                    724:                        /* count all receives */
                    725:                        ((struct netstats *)(dev->priv))->rx_packets++;
                    726:                }
                    727:        }
                    728: 
                    729:        /* Let's peek ahead to see if we have read the last current packet */
                    730:        /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
                    731:        curr_page = de620_get_register(dev, R_CPR);
                    732:        de620_set_register(dev, W_NPRF, next_rx_page);
                    733:        PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
                    734: 
                    735:        return (next_rx_page != curr_page); /* That was slightly tricky... */
                    736: }
                    737: 
                    738: /*********************************************
                    739:  *
                    740:  * Reset the adapter to a known state
                    741:  *
                    742:  */
                    743: static int
                    744: adapter_init(struct device *dev)
                    745: {
                    746:        int i;
                    747:        static int was_down = 0;
                    748: 
                    749:        if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */
                    750:                EIPRegister = NCTL0;
                    751:                if (nic_data.Media != 1)
                    752:                        EIPRegister |= NIS0;    /* not BNC */
                    753:        }
                    754:        else if (nic_data.Model == 2) { /* UTP */
                    755:                EIPRegister = NCTL0 | NIS0;
                    756:        }
                    757: 
                    758:        if (utp)
                    759:                EIPRegister = NCTL0 | NIS0;
                    760:        if (bnc)
                    761:                EIPRegister = NCTL0;
                    762: 
                    763:        de620_send_command(dev, W_CR | RNOP | CLEAR);
                    764:        de620_send_command(dev, W_CR | RNOP);
                    765: 
                    766:        de620_set_register(dev, W_SCR, SCR_DEF);
                    767:        /* disable recv to wait init */
                    768:        de620_set_register(dev, W_TCR, RXOFF);
                    769: 
                    770:        /* Set the node ID in the adapter */
                    771:        for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */
                    772:                de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
                    773:        }
                    774: 
                    775:        de620_set_register(dev, W_EIP, EIPRegister);
                    776: 
                    777:        next_rx_page = first_rx_page = DE620_RX_START_PAGE;
                    778:        if (nic_data.RAM_Size)
                    779:                last_rx_page = nic_data.RAM_Size - 1;
                    780:        else /* 64k RAM */
                    781:                last_rx_page = 255;
                    782: 
                    783:        de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/
                    784:        de620_set_register(dev, W_EPR, last_rx_page);  /* End Page Register */
                    785:        de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/
                    786:        de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/
                    787:        de620_send_command(dev, W_DUMMY);
                    788:        de620_set_delay(dev);
                    789: 
                    790:        /* Final sanity check: Anybody out there? */
                    791:        /* Let's hope some bits from the statusregister make a good check */
                    792: #define CHECK_MASK (  0 | TXSUC |  T16  |  0  | RXCRC | RXSHORT |  0  |  0  )
                    793: #define CHECK_OK   (  0 |   0   |  0    |  0  |   0   |   0     |  0  |  0  )
                    794:         /* success:   X     0      0       X      0       0        X     X  */
                    795:         /* ignore:   EEDI                RXGOOD                   COLS  LNKS*/
                    796: 
                    797:        if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
                    798:                printk("Something has happened to the DE-620!  Please check it"
                    799: #ifdef SHUTDOWN_WHEN_LOST
                    800:                        " and do a new ifconfig"
                    801: #endif
                    802:                        "! (%02x)\n", i);
                    803: #ifdef SHUTDOWN_WHEN_LOST
                    804:                /* Goodbye, cruel world... */
                    805:                dev->flags &= ~IFF_UP;
                    806:                de620_close(dev);
                    807: #endif
                    808:                was_down = 1;
                    809:                return 1; /* failed */
                    810:        }
                    811:        if (was_down) {
                    812:                printk("Thanks, I feel much better now!\n");
                    813:                was_down = 0;
                    814:        }
                    815: 
                    816:        /* All OK, go ahead... */
                    817:        de620_set_register(dev, W_TCR, TCR_DEF);
                    818: 
                    819:        return 0; /* all ok */
                    820: }
                    821: 
                    822: /******************************************************************************
                    823:  *
                    824:  * Only start-up code below
                    825:  *
                    826:  */
                    827: /****************************************
                    828:  *
                    829:  * Check if there is a DE-620 connected
                    830:  */
                    831: int
                    832: de620_probe(struct device *dev)
                    833: {
                    834:        static struct netstats de620_netstats;
                    835:        int i;
                    836:        byte checkbyte = 0xa5;
                    837: 
                    838:        /*
                    839:         * This is where the base_addr and irq gets set.
                    840:         * Tunable at compile-time and insmod-time
                    841:         */
                    842:        dev->base_addr = io;
                    843:        dev->irq       = irq;
                    844: 
                    845:        if (de620_debug)
1.1.1.2 ! root      846:                printk("%s", version);
1.1       root      847: 
                    848:        printk("D-Link DE-620 pocket adapter");
                    849: 
                    850:        /* Initially, configure basic nibble mode, so we can read the EEPROM */
                    851:        NIC_Cmd = DEF_NIC_CMD;
                    852:        de620_set_register(dev, W_EIP, EIPRegister);
                    853: 
                    854:        /* Anybody out there? */
                    855:        de620_set_register(dev, W_CPR, checkbyte);
                    856:        checkbyte = de620_get_register(dev, R_CPR);
                    857: 
                    858:        if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
                    859:                printk(" not identified in the printer port\n");
                    860:                return ENODEV;
                    861:        }
                    862: 
                    863: #if 0 /* Not yet */
                    864:        if (check_region(dev->base_addr, 3)) {
                    865:                printk(", port 0x%x busy\n", dev->base_addr);
                    866:                return EBUSY;
                    867:        }
                    868: #endif
                    869:        request_region(dev->base_addr, 3, "de620");
                    870: 
                    871:        /* else, got it! */
                    872:        printk(", Ethernet Address: %2.2X",
                    873:                dev->dev_addr[0] = nic_data.NodeID[0]);
                    874:        for (i = 1; i < ETH_ALEN; i++) {
                    875:                printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]);
                    876:                dev->broadcast[i] = 0xff;
                    877:        }
                    878: 
                    879:        printk(" (%dk RAM,",
                    880:                (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
                    881: 
                    882:        if (nic_data.Media == 1)
                    883:                printk(" BNC)\n");
                    884:        else
                    885:                printk(" UTP)\n");
                    886: 
                    887:        /* Initialize the device structure. */
                    888:        /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
                    889:        dev->priv = &de620_netstats;
                    890: 
                    891:        memset(dev->priv, 0, sizeof(struct netstats));
                    892:        dev->get_stats = get_stats;
                    893:        dev->open = de620_open;
                    894:        dev->stop = de620_close;
                    895:        dev->hard_start_xmit = &de620_start_xmit;
                    896:        dev->set_multicast_list = &de620_set_multicast_list;
                    897:        /* base_addr and irq are already set, see above! */
                    898: 
                    899:        ether_setup(dev);
                    900:        
                    901:        /* dump eeprom */
                    902:        if (de620_debug) {
                    903:                printk("\nEEPROM contents:\n");
                    904:                printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
                    905:                printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n",
                    906:                        nic_data.NodeID[0], nic_data.NodeID[1],
                    907:                        nic_data.NodeID[2], nic_data.NodeID[3],
                    908:                        nic_data.NodeID[4], nic_data.NodeID[5]);
                    909:                printk("Model = %d\n", nic_data.Model);
                    910:                printk("Media = %d\n", nic_data.Media);
                    911:                printk("SCR = 0x%02x\n", nic_data.SCR);
                    912:        }
                    913: 
                    914:        return 0;
                    915: }
                    916: 
                    917: /**********************************
                    918:  *
                    919:  * Read info from on-board EEPROM
                    920:  *
                    921:  * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_!
                    922:  */
                    923: #define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
                    924: 
                    925: static unsigned short
                    926: ReadAWord(struct device *dev, int from)
                    927: {
                    928:        unsigned short data;
                    929:        int nbits;
                    930: 
                    931:        /* cs   [__~~] SET SEND STATE */
                    932:        /* di   [____]                */
                    933:        /* sck  [_~~_]                */
                    934:        sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
                    935: 
                    936:        /* Send the 9-bit address from where we want to read the 16-bit word */
                    937:        for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
                    938:                if (from & 0x0100) { /* bit set? */
                    939:                        /* cs    [~~~~] SEND 1 */
                    940:                        /* di    [~~~~]        */
                    941:                        /* sck   [_~~_]        */
                    942:                        sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
                    943:                }
                    944:                else {
                    945:                        /* cs    [~~~~] SEND 0 */
                    946:                        /* di    [____]        */
                    947:                        /* sck   [_~~_]        */
                    948:                        sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
                    949:                }
                    950:        }
                    951: 
                    952:        /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */
                    953:        for (data = 0, nbits = 16; nbits > 0; --nbits) {
                    954:                /* cs    [~~~~] SEND 0 */
                    955:                /* di    [____]        */
                    956:                /* sck   [_~~_]        */
                    957:                sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
                    958:                data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
                    959:        }
                    960:        /* cs    [____] RESET SEND STATE */
                    961:        /* di    [____]                  */
                    962:        /* sck   [_~~_]                  */
                    963:        sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
                    964: 
                    965:        return data;
                    966: }
                    967: 
                    968: static int
                    969: read_eeprom(struct device *dev)
                    970: {
                    971:        unsigned short wrd;
                    972: 
                    973:        /* D-Link Ethernet addresses are in the series  00:80:c8:7X:XX:XX:XX */
                    974:        wrd = ReadAWord(dev, 0x1aa);    /* bytes 0 + 1 of NodeID */
                    975:        if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */
                    976:                return -1; /* Nope, not a DE-620 */
                    977:        nic_data.NodeID[0] = wrd & 0xff;
                    978:        nic_data.NodeID[1] = wrd >> 8;
                    979: 
                    980:        wrd = ReadAWord(dev, 0x1ab);    /* bytes 2 + 3 of NodeID */
                    981:        if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */
                    982:                return -1; /* Nope, not a DE-620 */
                    983:        nic_data.NodeID[2] = wrd & 0xff;
                    984:        nic_data.NodeID[3] = wrd >> 8;
                    985: 
                    986:        wrd = ReadAWord(dev, 0x1ac);    /* bytes 4 + 5 of NodeID */
                    987:        nic_data.NodeID[4] = wrd & 0xff;
                    988:        nic_data.NodeID[5] = wrd >> 8;
                    989: 
                    990:        wrd = ReadAWord(dev, 0x1ad);    /* RAM size in pages (256 bytes). 0 = 64k */
                    991:        nic_data.RAM_Size = (wrd >> 8);
                    992: 
                    993:        wrd = ReadAWord(dev, 0x1ae);    /* hardware model (CT = 3) */
                    994:        nic_data.Model = (wrd & 0xff);
                    995: 
                    996:        wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */
                    997:        nic_data.Media = (wrd & 0xff);
                    998: 
                    999:        wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */
                   1000:        nic_data.SCR = (wrd >> 8);
                   1001: 
                   1002:        return 0; /* no errors */
                   1003: }
                   1004: 
                   1005: /******************************************************************************
                   1006:  *
                   1007:  * Loadable module skeleton
                   1008:  *
                   1009:  */
                   1010: #ifdef MODULE
                   1011: static char nullname[8] = "";
                   1012: static struct device de620_dev = {
                   1013:        nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de620_probe };
                   1014: 
                   1015: int
                   1016: init_module(void)
                   1017: {
                   1018:        if (register_netdev(&de620_dev) != 0)
                   1019:                return -EIO;
                   1020:        return 0;
                   1021: }
                   1022: 
                   1023: void
                   1024: cleanup_module(void)
                   1025: {
                   1026:        unregister_netdev(&de620_dev);
                   1027:        release_region(de620_dev.base_addr, 3);
                   1028: }
                   1029: #endif /* MODULE */
                   1030: 
                   1031: /*
                   1032:  * (add '-DMODULE' when compiling as loadable module)
                   1033:  *
                   1034:  * compile-command:
                   1035:  *     gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 \
                   1036:  *      -fomit-frame-pointer -m486 \
                   1037:  *     -I/usr/src/linux/include -I../../net/inet -c de620.c
                   1038: */
                   1039: /*
                   1040:  * Local variables:
                   1041:  *  kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
                   1042:  *  module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
                   1043:  *  compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
                   1044:  * End:
                   1045:  */

unix.superglobalmegacorp.com

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