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

1.1     ! root        1: static const char *version =
        !             2:        "de600.c: $Revision: 1.1 $,  Bjorn Ekwall ([email protected])\n";
        !             3: /*
        !             4:  *     de600.c
        !             5:  *
        !             6:  *     Linux driver for the D-Link DE-600 Ethernet pocket adapter.
        !             7:  *
        !             8:  *     Portions (C) Copyright 1993, 1994 by Bjorn Ekwall
        !             9:  *     The Author may be reached as [email protected]
        !            10:  *
        !            11:  *     Based on adapter information gathered from DE600.ASM by D-Link Inc.,
        !            12:  *     as included on disk C in the v.2.11 of PC/TCP from FTP Software.
        !            13:  *     For DE600.asm:
        !            14:  *             Portions (C) Copyright 1990 D-Link, Inc.
        !            15:  *             Copyright, 1988-1992, Russell Nelson, Crynwr Software
        !            16:  *
        !            17:  *     Adapted to the sample network driver core for linux,
        !            18:  *     written by: Donald Becker <[email protected]>
        !            19:  *     C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
        !            20:  *
        !            21:  *     compile-command:
        !            22:  *     "gcc -D__KERNEL__  -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer \
        !            23:  *      -m486 -c de600.c
        !            24:  *
        !            25:  **************************************************************/
        !            26: /*
        !            27:  *     This program is free software; you can redistribute it and/or modify
        !            28:  *     it under the terms of the GNU General Public License as published by
        !            29:  *     the Free Software Foundation; either version 2, or (at your option)
        !            30:  *     any later version.
        !            31:  *
        !            32:  *     This program is distributed in the hope that it will be useful,
        !            33:  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            34:  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            35:  *     GNU General Public License for more details.
        !            36:  *
        !            37:  *     You should have received a copy of the GNU General Public License
        !            38:  *     along with this program; if not, write to the Free Software
        !            39:  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
        !            40:  *
        !            41:  **************************************************************/
        !            42: /* Add another "; SLOW_DOWN_IO" here if your adapter won't work OK: */
        !            43: #define DE600_SLOW_DOWN SLOW_DOWN_IO; SLOW_DOWN_IO; SLOW_DOWN_IO
        !            44: 
        !            45:  /*
        !            46:  * If you still have trouble reading/writing to the adapter,
        !            47:  * modify the following "#define": (see <asm/io.h> for more info)
        !            48: #define REALLY_SLOW_IO
        !            49:  */
        !            50: #define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */
        !            51: 
        !            52: /*
        !            53:  * If you want to enable automatic continuous checking for the DE600,
        !            54:  * keep this #define enabled.
        !            55:  * It doesn't cost much per packet, so I think it is worth it!
        !            56:  * If you disagree, comment away the #define, and live with it...
        !            57:  *
        !            58:  */
        !            59: #define CHECK_LOST_DE600
        !            60: 
        !            61: /*
        !            62:  * Enable this #define if you want the adapter to do a "ifconfig down" on
        !            63:  * itself when we have detected that something is possibly wrong with it.
        !            64:  * The default behaviour is to retry with "adapter_init()" until success.
        !            65:  * This should be used for debugging purposes only.
        !            66:  * (Depends on the CHECK_LOST_DE600 above)
        !            67:  *
        !            68:  */
        !            69: #define SHUTDOWN_WHEN_LOST
        !            70: 
        !            71: /*
        !            72:  * See comment at "de600_rspace()"!
        !            73:  * This is an *ugly* hack, but for now it achieves its goal of
        !            74:  * faking a TCP flow-control that will not flood the poor DE600.
        !            75:  *
        !            76:  * Tricks TCP to announce a small max window (max 2 fast packets please :-)
        !            77:  *
        !            78:  * Comment away at your own risk!
        !            79:  *
        !            80:  * Update: Use the more general per-device maxwindow parameter instead.
        !            81:  */
        !            82: #undef FAKE_SMALL_MAX
        !            83: 
        !            84: /* use 0 for production, 1 for verification, >2 for debug */
        !            85: #ifdef DE600_DEBUG
        !            86: #define PRINTK(x) if (de600_debug >= 2) printk x
        !            87: #else
        !            88: #define DE600_DEBUG 0
        !            89: #define PRINTK(x) /**/
        !            90: #endif
        !            91: unsigned int de600_debug = DE600_DEBUG;
        !            92: 
        !            93: #include <linux/module.h>
        !            94: 
        !            95: #include <linux/kernel.h>
        !            96: #include <linux/sched.h>
        !            97: #include <linux/types.h>
        !            98: #include <linux/fcntl.h>
        !            99: #include <linux/string.h>
        !           100: #include <linux/interrupt.h>
        !           101: #include <linux/ioport.h>
        !           102: #include <asm/io.h>
        !           103: #include <linux/in.h>
        !           104: #include <linux/ptrace.h>
        !           105: #include <asm/system.h>
        !           106: #include <linux/errno.h>
        !           107: 
        !           108: #include <linux/inet.h>
        !           109: #include <linux/netdevice.h>
        !           110: #include <linux/etherdevice.h>
        !           111: #include <linux/skbuff.h>
        !           112: 
        !           113: #ifdef FAKE_SMALL_MAX
        !           114: static unsigned long de600_rspace(struct sock *sk);
        !           115: #include <net/sock.h>
        !           116: #endif
        !           117: 
        !           118: #define netstats enet_statistics
        !           119: typedef unsigned char byte;
        !           120: 
        !           121: /**************************************************
        !           122:  *                                                *
        !           123:  * Definition of D-Link Ethernet Pocket adapter   *
        !           124:  *                                                *
        !           125:  **************************************************/
        !           126: /*
        !           127:  * D-Link Ethernet pocket adapter ports
        !           128:  */
        !           129: /*
        !           130:  * OK, so I'm cheating, but there are an awful lot of
        !           131:  * reads and writes in order to get anything in and out
        !           132:  * of the DE-600 with 4 bits at a time in the parallel port,
        !           133:  * so every saved instruction really helps :-)
        !           134:  *
        !           135:  * That is, I don't care what the device struct says
        !           136:  * but hope that Space.c will keep the rest of the drivers happy.
        !           137:  */
        !           138: #ifndef DE600_IO
        !           139: #define DE600_IO 0x378
        !           140: #endif
        !           141: 
        !           142: #define DATA_PORT      (DE600_IO)
        !           143: #define STATUS_PORT    (DE600_IO + 1)
        !           144: #define COMMAND_PORT   (DE600_IO + 2)
        !           145: 
        !           146: #ifndef DE600_IRQ
        !           147: #define DE600_IRQ      7
        !           148: #endif
        !           149: /*
        !           150:  * It really should look like this, and autoprobing as well...
        !           151:  *
        !           152: #define DATA_PORT      (dev->base_addr + 0)
        !           153: #define STATUS_PORT    (dev->base_addr + 1)
        !           154: #define COMMAND_PORT   (dev->base_addr + 2)
        !           155: #define DE600_IRQ      dev->irq
        !           156:  */
        !           157: 
        !           158: /*
        !           159:  * D-Link COMMAND_PORT commands
        !           160:  */
        !           161: #define SELECT_NIC     0x04 /* select Network Interface Card */
        !           162: #define SELECT_PRN     0x1c /* select Printer */
        !           163: #define NML_PRN                0xec /* normal Printer situation */
        !           164: #define IRQEN          0x10 /* enable IRQ line */
        !           165: 
        !           166: /*
        !           167:  * D-Link STATUS_PORT
        !           168:  */
        !           169: #define RX_BUSY                0x80
        !           170: #define RX_GOOD                0x40
        !           171: #define TX_FAILED16    0x10
        !           172: #define TX_BUSY                0x08
        !           173: 
        !           174: /*
        !           175:  * D-Link DATA_PORT commands
        !           176:  * command in low 4 bits
        !           177:  * data in high 4 bits
        !           178:  * select current data nibble with HI_NIBBLE bit
        !           179:  */
        !           180: #define WRITE_DATA     0x00 /* write memory */
        !           181: #define READ_DATA      0x01 /* read memory */
        !           182: #define STATUS         0x02 /* read  status register */
        !           183: #define COMMAND                0x03 /* write command register (see COMMAND below) */
        !           184: #define NULL_COMMAND   0x04 /* null command */
        !           185: #define RX_LEN         0x05 /* read  received packet length */
        !           186: #define TX_ADDR                0x06 /* set adapter transmit memory address */
        !           187: #define RW_ADDR                0x07 /* set adapter read/write memory address */
        !           188: #define HI_NIBBLE      0x08 /* read/write the high nibble of data,
        !           189:                                or-ed with rest of command */
        !           190: 
        !           191: /*
        !           192:  * command register, accessed through DATA_PORT with low bits = COMMAND
        !           193:  */
        !           194: #define RX_ALL         0x01 /* PROMISCUOUS */
        !           195: #define RX_BP          0x02 /* default: BROADCAST & PHYSICAL ADDRESS */
        !           196: #define RX_MBP         0x03 /* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
        !           197: 
        !           198: #define TX_ENABLE      0x04 /* bit 2 */
        !           199: #define RX_ENABLE      0x08 /* bit 3 */
        !           200: 
        !           201: #define RESET          0x80 /* set bit 7 high */
        !           202: #define STOP_RESET     0x00 /* set bit 7 low */
        !           203: 
        !           204: /*
        !           205:  * data to command register
        !           206:  * (high 4 bits in write to DATA_PORT)
        !           207:  */
        !           208: #define RX_PAGE2_SELECT        0x10 /* bit 4, only 2 pages to select */
        !           209: #define RX_BASE_PAGE   0x20 /* bit 5, always set when specifying RX_ADDR */
        !           210: #define FLIP_IRQ       0x40 /* bit 6 */
        !           211: 
        !           212: /*
        !           213:  * D-Link adapter internal memory:
        !           214:  *
        !           215:  * 0-2K 1:st transmit page (send from pointer up to 2K)
        !           216:  * 2-4K        2:nd transmit page (send from pointer up to 4K)
        !           217:  *
        !           218:  * 4-6K 1:st receive page (data from 4K upwards)
        !           219:  * 6-8K 2:nd receive page (data from 6K upwards)
        !           220:  *
        !           221:  * 8K+ Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
        !           222:  */
        !           223: #define MEM_2K         0x0800 /* 2048 */
        !           224: #define MEM_4K         0x1000 /* 4096 */
        !           225: #define MEM_6K         0x1800 /* 6144 */
        !           226: #define NODE_ADDRESS   0x2000 /* 8192 */
        !           227: 
        !           228: #define RUNT 60                /* Too small Ethernet packet */
        !           229: 
        !           230: /**************************************************
        !           231:  *                                                *
        !           232:  *             End of definition                  *
        !           233:  *                                                *
        !           234:  **************************************************/
        !           235: 
        !           236: /*
        !           237:  * Index to functions, as function prototypes.
        !           238:  */
        !           239: /* Routines used internally. (See "convenience macros") */
        !           240: static byte    de600_read_status(struct device *dev);
        !           241: static byte    de600_read_byte(unsigned char type, struct device *dev);
        !           242: 
        !           243: /* Put in the device structure. */
        !           244: static int     de600_open(struct device *dev);
        !           245: static int     de600_close(struct device *dev);
        !           246: static struct netstats *get_stats(struct device *dev);
        !           247: static int     de600_start_xmit(struct sk_buff *skb, struct device *dev);
        !           248: 
        !           249: /* Dispatch from interrupts. */
        !           250: static void    de600_interrupt(int irq, void *dev_id, struct pt_regs *regs);
        !           251: static int     de600_tx_intr(struct device *dev, int irq_status);
        !           252: static void    de600_rx_intr(struct device *dev);
        !           253: 
        !           254: /* Initialization */
        !           255: static void    trigger_interrupt(struct device *dev);
        !           256: int            de600_probe(struct device *dev);
        !           257: static int     adapter_init(struct device *dev);
        !           258: 
        !           259: /*
        !           260:  * D-Link driver variables:
        !           261:  */
        !           262: static volatile int            rx_page         = 0;
        !           263: 
        !           264: #define TX_PAGES 2
        !           265: static volatile int            tx_fifo[TX_PAGES];
        !           266: static volatile int            tx_fifo_in = 0;
        !           267: static volatile int            tx_fifo_out = 0;
        !           268: static volatile int            free_tx_pages = TX_PAGES;
        !           269: static int                     was_down = 0;
        !           270: 
        !           271: /*
        !           272:  * Convenience macros/functions for D-Link adapter
        !           273:  */
        !           274: 
        !           275: #define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
        !           276: #define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
        !           277: 
        !           278: /* Thanks for hints from Mark Burton <[email protected]> */
        !           279: #define de600_put_byte(data) ( \
        !           280:        outb_p(((data) << 4)   | WRITE_DATA            , DATA_PORT), \
        !           281:        outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
        !           282: 
        !           283: /*
        !           284:  * The first two outb_p()'s below could perhaps be deleted if there
        !           285:  * would be more delay in the last two. Not certain about it yet...
        !           286:  */
        !           287: #define de600_put_command(cmd) ( \
        !           288:        outb_p(( rx_page        << 4)   | COMMAND            , DATA_PORT), \
        !           289:        outb_p(( rx_page        & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
        !           290:        outb_p(((rx_page | cmd) << 4)   | COMMAND            , DATA_PORT), \
        !           291:        outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
        !           292: 
        !           293: #define de600_setup_address(addr,type) ( \
        !           294:        outb_p((((addr) << 4) & 0xf0) | type            , DATA_PORT), \
        !           295:        outb_p(( (addr)       & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
        !           296:        outb_p((((addr) >> 4) & 0xf0) | type            , DATA_PORT), \
        !           297:        outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
        !           298: 
        !           299: #define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
        !           300: 
        !           301: /* Flip bit, only 2 pages */
        !           302: #define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
        !           303: 
        !           304: #define tx_page_adr(a) (((a) + 1) * MEM_2K)
        !           305: 
        !           306: static inline byte
        !           307: de600_read_status(struct device *dev)
        !           308: {
        !           309:        byte status;
        !           310: 
        !           311:        outb_p(STATUS, DATA_PORT);
        !           312:        status = inb(STATUS_PORT);
        !           313:        outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
        !           314: 
        !           315:        return status;
        !           316: }
        !           317: 
        !           318: static inline byte
        !           319: de600_read_byte(unsigned char type, struct device *dev) { /* dev used by macros */
        !           320:        byte lo;
        !           321: 
        !           322:        (void)outb_p((type), DATA_PORT);
        !           323:        lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
        !           324:        (void)outb_p((type) | HI_NIBBLE, DATA_PORT);
        !           325:        return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
        !           326: }
        !           327: 
        !           328: /*
        !           329:  * Open/initialize the board.  This is called (in the current kernel)
        !           330:  * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
        !           331:  *
        !           332:  * This routine should set everything up anew at each open, even
        !           333:  * registers that "should" only need to be set once at boot, so that
        !           334:  * there is a non-reboot way to recover if something goes wrong.
        !           335:  */
        !           336: static int
        !           337: de600_open(struct device *dev)
        !           338: {
        !           339:        if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600", NULL)) {
        !           340:                printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
        !           341:                return 1;
        !           342:        }
        !           343:        irq2dev_map[DE600_IRQ] = dev;
        !           344: 
        !           345:        MOD_INC_USE_COUNT;
        !           346:        dev->start = 1;
        !           347:        if (adapter_init(dev)) {
        !           348:                return 1;
        !           349:        }
        !           350: 
        !           351:        return 0;
        !           352: }
        !           353: 
        !           354: /*
        !           355:  * The inverse routine to de600_open().
        !           356:  */
        !           357: static int
        !           358: de600_close(struct device *dev)
        !           359: {
        !           360:        select_nic();
        !           361:        rx_page = 0;
        !           362:        de600_put_command(RESET);
        !           363:        de600_put_command(STOP_RESET);
        !           364:        de600_put_command(0);
        !           365:        select_prn();
        !           366: 
        !           367:        if (dev->start) {
        !           368:                free_irq(DE600_IRQ, NULL);
        !           369:                irq2dev_map[DE600_IRQ] = NULL;
        !           370:                dev->start = 0;
        !           371:                MOD_DEC_USE_COUNT;
        !           372:        }
        !           373:        return 0;
        !           374: }
        !           375: 
        !           376: static struct netstats *
        !           377: get_stats(struct device *dev)
        !           378: {
        !           379:     return (struct netstats *)(dev->priv);
        !           380: }
        !           381: 
        !           382: static inline void
        !           383: trigger_interrupt(struct device *dev)
        !           384: {
        !           385:        de600_put_command(FLIP_IRQ);
        !           386:        select_prn();
        !           387:        DE600_SLOW_DOWN;
        !           388:        select_nic();
        !           389:        de600_put_command(0);
        !           390: }
        !           391: 
        !           392: /*
        !           393:  * Copy a buffer to the adapter transmit page memory.
        !           394:  * Start sending.
        !           395:  */
        !           396: static int
        !           397: de600_start_xmit(struct sk_buff *skb, struct device *dev)
        !           398: {
        !           399:        int     transmit_from;
        !           400:        int     len;
        !           401:        int     tickssofar;
        !           402:        byte    *buffer = skb->data;
        !           403: 
        !           404:        /*
        !           405:         * If some higher layer thinks we've missed a
        !           406:         * tx-done interrupt we are passed NULL.
        !           407:         * Caution: dev_tint() handles the cli()/sti() itself.
        !           408:         */
        !           409: 
        !           410:        if (skb == NULL) {
        !           411:                dev_tint(dev);
        !           412:                return 0;
        !           413:        }
        !           414: 
        !           415:        if (free_tx_pages <= 0) {       /* Do timeouts, to avoid hangs. */
        !           416:                tickssofar = jiffies - dev->trans_start;
        !           417: 
        !           418:                if (tickssofar < 5)
        !           419:                        return 1;
        !           420: 
        !           421:                /* else */
        !           422:                printk("%s: transmit timed out (%d), %s?\n",
        !           423:                        dev->name,
        !           424:                        tickssofar,
        !           425:                        "network cable problem"
        !           426:                        );
        !           427:                /* Restart the adapter. */
        !           428:                if (adapter_init(dev)) {
        !           429:                        return 1;
        !           430:                }
        !           431:        }
        !           432: 
        !           433:        /* Start real output */
        !           434:        PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
        !           435: 
        !           436:        if ((len = skb->len) < RUNT)
        !           437:                len = RUNT;
        !           438: 
        !           439:        cli();
        !           440:        select_nic();
        !           441:        tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
        !           442:        tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
        !           443: 
        !           444: #ifdef CHECK_LOST_DE600
        !           445:        /* This costs about 40 instructions per packet... */
        !           446:        de600_setup_address(NODE_ADDRESS, RW_ADDR);
        !           447:        de600_read_byte(READ_DATA, dev);
        !           448:        if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
        !           449:                if (adapter_init(dev)) {
        !           450:                        sti();
        !           451:                        return 1;
        !           452:                }
        !           453:        }
        !           454: #endif
        !           455: 
        !           456:        de600_setup_address(transmit_from, RW_ADDR);
        !           457:        for ( ; len > 0; --len, ++buffer)
        !           458:                de600_put_byte(*buffer);
        !           459: 
        !           460:        if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
        !           461:                dev->trans_start = jiffies;
        !           462:                dev->tbusy = 0; /* allow more packets into adapter */
        !           463:                /* Send page and generate a faked interrupt */
        !           464:                de600_setup_address(transmit_from, TX_ADDR);
        !           465:                de600_put_command(TX_ENABLE);
        !           466:        }
        !           467:        else {
        !           468:                dev->tbusy = !free_tx_pages;
        !           469:                select_prn();
        !           470:        }
        !           471:        
        !           472:        sti(); /* interrupts back on */
        !           473:        
        !           474: #ifdef FAKE_SMALL_MAX
        !           475:        /* This will "patch" the socket TCP proto at an early moment */
        !           476:        if (skb->sk && (skb->sk->protocol == IPPROTO_TCP) &&
        !           477:                (skb->sk->prot->rspace != &de600_rspace))
        !           478:                skb->sk->prot->rspace = de600_rspace; /* Ugh! */
        !           479: #endif
        !           480: 
        !           481:        dev_kfree_skb (skb, FREE_WRITE);
        !           482: 
        !           483:        return 0;
        !           484: }
        !           485: 
        !           486: /*
        !           487:  * The typical workload of the driver:
        !           488:  * Handle the network interface interrupts.
        !           489:  */
        !           490: static void
        !           491: de600_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        !           492: {
        !           493:        struct device   *dev = irq2dev_map[irq];
        !           494:        byte            irq_status;
        !           495:        int             retrig = 0;
        !           496:        int             boguscount = 0;
        !           497: 
        !           498:        /* This might just as well be deleted now, no crummy drivers present :-) */
        !           499:        if ((dev == NULL) || (dev->start == 0) || (DE600_IRQ != irq)) {
        !           500:                printk("%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
        !           501:                return;
        !           502:        }
        !           503: 
        !           504:        dev->interrupt = 1;
        !           505:        select_nic();
        !           506:        irq_status = de600_read_status(dev);
        !           507: 
        !           508:        do {
        !           509:                PRINTK(("de600_interrupt (%02X)\n", irq_status));
        !           510: 
        !           511:                if (irq_status & RX_GOOD)
        !           512:                        de600_rx_intr(dev);
        !           513:                else if (!(irq_status & RX_BUSY))
        !           514:                        de600_put_command(RX_ENABLE);
        !           515: 
        !           516:                /* Any transmission in progress? */
        !           517:                if (free_tx_pages < TX_PAGES)
        !           518:                        retrig = de600_tx_intr(dev, irq_status);
        !           519:                else
        !           520:                        retrig = 0;
        !           521: 
        !           522:                irq_status = de600_read_status(dev);
        !           523:        } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
        !           524:        /*
        !           525:         * Yeah, it _looks_ like busy waiting, smells like busy waiting
        !           526:         * and I know it's not PC, but please, it will only occur once
        !           527:         * in a while and then only for a loop or so (< 1ms for sure!)
        !           528:         */
        !           529: 
        !           530:        /* Enable adapter interrupts */
        !           531:        dev->interrupt = 0;
        !           532:        select_prn();
        !           533: 
        !           534:        if (retrig)
        !           535:                trigger_interrupt(dev);
        !           536: 
        !           537:        sti();
        !           538:        return;
        !           539: }
        !           540: 
        !           541: static int
        !           542: de600_tx_intr(struct device *dev, int irq_status)
        !           543: {
        !           544:        /*
        !           545:         * Returns 1 if tx still not done
        !           546:         */
        !           547: 
        !           548:        mark_bh(NET_BH);
        !           549:        /* Check if current transmission is done yet */
        !           550:        if (irq_status & TX_BUSY)
        !           551:                return 1; /* tx not done, try again */
        !           552: 
        !           553:        /* else */
        !           554:        /* If last transmission OK then bump fifo index */
        !           555:        if (!(irq_status & TX_FAILED16)) {
        !           556:                tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
        !           557:                ++free_tx_pages;
        !           558:                ((struct netstats *)(dev->priv))->tx_packets++;
        !           559:                dev->tbusy = 0;
        !           560:        }
        !           561: 
        !           562:        /* More to send, or resend last packet? */
        !           563:        if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
        !           564:                dev->trans_start = jiffies;
        !           565:                de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
        !           566:                de600_put_command(TX_ENABLE);
        !           567:                return 1;
        !           568:        }
        !           569:        /* else */
        !           570: 
        !           571:        return 0;
        !           572: }
        !           573: 
        !           574: /*
        !           575:  * We have a good packet, get it out of the adapter.
        !           576:  */
        !           577: static void
        !           578: de600_rx_intr(struct device *dev)
        !           579: {
        !           580:        struct sk_buff  *skb;
        !           581:        int             i;
        !           582:        int             read_from;
        !           583:        int             size;
        !           584:        register unsigned char  *buffer;
        !           585: 
        !           586:        cli();
        !           587:        /* Get size of received packet */
        !           588:        size = de600_read_byte(RX_LEN, dev);    /* low byte */
        !           589:        size += (de600_read_byte(RX_LEN, dev) << 8);    /* high byte */
        !           590:        size -= 4;      /* Ignore trailing 4 CRC-bytes */
        !           591: 
        !           592:        /* Tell adapter where to store next incoming packet, enable receiver */
        !           593:        read_from = rx_page_adr();
        !           594:        next_rx_page();
        !           595:        de600_put_command(RX_ENABLE);
        !           596:        sti();
        !           597: 
        !           598:        if ((size < 32)  ||  (size > 1535)) {
        !           599:                printk("%s: Bogus packet size %d.\n", dev->name, size);
        !           600:                if (size > 10000)
        !           601:                        adapter_init(dev);
        !           602:                return;
        !           603:        }
        !           604: 
        !           605:        skb = dev_alloc_skb(size+2);
        !           606:        sti();
        !           607:        if (skb == NULL) {
        !           608:                printk("%s: Couldn't allocate a sk_buff of size %d.\n",
        !           609:                        dev->name, size);
        !           610:                return;
        !           611:        }
        !           612:        /* else */
        !           613: 
        !           614:        skb->dev = dev;
        !           615:        skb_reserve(skb,2);     /* Align */
        !           616:        
        !           617:        /* 'skb->data' points to the start of sk_buff data area. */
        !           618:        buffer = skb_put(skb,size);
        !           619: 
        !           620:        /* copy the packet into the buffer */
        !           621:        de600_setup_address(read_from, RW_ADDR);
        !           622:        for (i = size; i > 0; --i, ++buffer)
        !           623:                *buffer = de600_read_byte(READ_DATA, dev);
        !           624:        
        !           625:        ((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */
        !           626: 
        !           627:        skb->protocol=eth_type_trans(skb,dev);
        !           628:        
        !           629:        netif_rx(skb);
        !           630:        /*
        !           631:         * If any worth-while packets have been received, netif_rx()
        !           632:         * has done a mark_bh(INET_BH) for us and will work on them
        !           633:         * when we get to the bottom-half routine.
        !           634:         */
        !           635: }
        !           636: 
        !           637: int
        !           638: de600_probe(struct device *dev)
        !           639: {
        !           640:        int     i;
        !           641:        static struct netstats de600_netstats;
        !           642:        /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
        !           643: 
        !           644:        printk("%s: D-Link DE-600 pocket adapter", dev->name);
        !           645:        /* Alpha testers must have the version number to report bugs. */
        !           646:        if (de600_debug > 1)
        !           647:                printk(version);
        !           648: 
        !           649:        /* probe for adapter */
        !           650:        rx_page = 0;
        !           651:        select_nic();
        !           652:        (void)de600_read_status(dev);
        !           653:        de600_put_command(RESET);
        !           654:        de600_put_command(STOP_RESET);
        !           655:        if (de600_read_status(dev) & 0xf0) {
        !           656:                printk(": not at I/O %#3x.\n", DATA_PORT);
        !           657:                return ENODEV;
        !           658:        }
        !           659: 
        !           660:        /*
        !           661:         * Maybe we found one,
        !           662:         * have to check if it is a D-Link DE-600 adapter...
        !           663:         */
        !           664: 
        !           665:        /* Get the adapter ethernet address from the ROM */
        !           666:        de600_setup_address(NODE_ADDRESS, RW_ADDR);
        !           667:        for (i = 0; i < ETH_ALEN; i++) {
        !           668:                dev->dev_addr[i] = de600_read_byte(READ_DATA, dev);
        !           669:                dev->broadcast[i] = 0xff;
        !           670:        }
        !           671: 
        !           672:        /* Check magic code */
        !           673:        if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
        !           674:                /* OK, install real address */
        !           675:                dev->dev_addr[0] = 0x00;
        !           676:                dev->dev_addr[1] = 0x80;
        !           677:                dev->dev_addr[2] = 0xc8;
        !           678:                dev->dev_addr[3] &= 0x0f;
        !           679:                dev->dev_addr[3] |= 0x70;
        !           680:        } else {
        !           681:                printk(" not identified in the printer port\n");
        !           682:                return ENODEV;
        !           683:        }
        !           684: 
        !           685: #if 0 /* Not yet */
        !           686:        if (check_region(DE600_IO, 3)) {
        !           687:                printk(", port 0x%x busy\n", DE600_IO);
        !           688:                return EBUSY;
        !           689:        }
        !           690: #endif
        !           691:        request_region(DE600_IO, 3, "de600");
        !           692: 
        !           693:        printk(", Ethernet Address: %02X", dev->dev_addr[0]);
        !           694:        for (i = 1; i < ETH_ALEN; i++)
        !           695:                printk(":%02X",dev->dev_addr[i]);
        !           696:        printk("\n");
        !           697: 
        !           698:        /* Initialize the device structure. */
        !           699:        /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
        !           700:        dev->priv = &de600_netstats;
        !           701: 
        !           702:        memset(dev->priv, 0, sizeof(struct netstats));
        !           703:        dev->get_stats = get_stats;
        !           704: 
        !           705:        dev->open = de600_open;
        !           706:        dev->stop = de600_close;
        !           707:        dev->hard_start_xmit = &de600_start_xmit;
        !           708: 
        !           709:        ether_setup(dev);
        !           710:        
        !           711:        dev->flags&=~IFF_MULTICAST;
        !           712:        
        !           713:        select_prn();
        !           714:        return 0;
        !           715: }
        !           716: 
        !           717: static int
        !           718: adapter_init(struct device *dev)
        !           719: {
        !           720:        int     i;
        !           721:        long flags;
        !           722: 
        !           723:        save_flags(flags);
        !           724:        cli();
        !           725: 
        !           726:        select_nic();
        !           727:        rx_page = 0; /* used by RESET */
        !           728:        de600_put_command(RESET);
        !           729:        de600_put_command(STOP_RESET);
        !           730: #ifdef CHECK_LOST_DE600
        !           731:        /* Check if it is still there... */
        !           732:        /* Get the some bytes of the adapter ethernet address from the ROM */
        !           733:        de600_setup_address(NODE_ADDRESS, RW_ADDR);
        !           734:        de600_read_byte(READ_DATA, dev);
        !           735:        if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
        !           736:            (de600_read_byte(READ_DATA, dev) != 0x15)) {
        !           737:        /* was: if (de600_read_status(dev) & 0xf0) { */
        !           738:                printk("Something has happened to the DE-600!  Please check it"
        !           739: #ifdef SHUTDOWN_WHEN_LOST
        !           740:                        " and do a new ifconfig"
        !           741: #endif /* SHUTDOWN_WHEN_LOST */
        !           742:                        "!\n");
        !           743: #ifdef SHUTDOWN_WHEN_LOST
        !           744:                /* Goodbye, cruel world... */
        !           745:                dev->flags &= ~IFF_UP;
        !           746:                de600_close(dev);
        !           747: #endif /* SHUTDOWN_WHEN_LOST */
        !           748:                was_down = 1;
        !           749:                dev->tbusy = 1;         /* Transmit busy...  */
        !           750:                restore_flags(flags);
        !           751:                return 1; /* failed */
        !           752:        }
        !           753: #endif /* CHECK_LOST_DE600 */
        !           754:        if (was_down) {
        !           755:                printk("Thanks, I feel much better now!\n");
        !           756:                was_down = 0;
        !           757:        }
        !           758: 
        !           759:        dev->tbusy = 0;         /* Transmit busy...  */
        !           760:        dev->interrupt = 0;
        !           761:        tx_fifo_in = 0;
        !           762:        tx_fifo_out = 0;
        !           763:        free_tx_pages = TX_PAGES;
        !           764: 
        !           765:        /* set the ether address. */
        !           766:        de600_setup_address(NODE_ADDRESS, RW_ADDR);
        !           767:        for (i = 0; i < ETH_ALEN; i++)
        !           768:                de600_put_byte(dev->dev_addr[i]);
        !           769: 
        !           770:        /* where to start saving incoming packets */
        !           771:        rx_page = RX_BP | RX_BASE_PAGE;
        !           772:        de600_setup_address(MEM_4K, RW_ADDR);
        !           773:        /* Enable receiver */
        !           774:        de600_put_command(RX_ENABLE);
        !           775:        select_prn();
        !           776:        restore_flags(flags);
        !           777: 
        !           778:        return 0; /* OK */
        !           779: }
        !           780: 
        !           781: #ifdef FAKE_SMALL_MAX
        !           782: /*
        !           783:  *     The new router code (coming soon 8-) ) will fix this properly.
        !           784:  */
        !           785: #define DE600_MIN_WINDOW 1024
        !           786: #define DE600_MAX_WINDOW 2048
        !           787: #define DE600_TCP_WINDOW_DIFF 1024
        !           788: /*
        !           789:  * Copied from "net/inet/sock.c"
        !           790:  *
        !           791:  * Sets a lower max receive window in order to achieve <= 2
        !           792:  * packets arriving at the adapter in fast succession.
        !           793:  * (No way that a DE-600 can keep up with a net saturated
        !           794:  *  with packets homing in on it :-( )
        !           795:  *
        !           796:  * Since there are only 2 receive buffers in the DE-600
        !           797:  * and it takes some time to copy from the adapter,
        !           798:  * this is absolutely necessary for any TCP performance whatsoever!
        !           799:  *
        !           800:  * Note that the returned window info will never be smaller than
        !           801:  * DE600_MIN_WINDOW, i.e. 1024
        !           802:  * This differs from the standard function, that can return an
        !           803:  * arbitrarily small window!
        !           804:  */
        !           805: #define min(a,b)       ((a)<(b)?(a):(b))
        !           806: static unsigned long
        !           807: de600_rspace(struct sock *sk)
        !           808: {
        !           809:   int amt;
        !           810: 
        !           811:   if (sk != NULL) {
        !           812: /*
        !           813:  * Hack! You might want to play with commenting away the following line,
        !           814:  * if you know what you do!
        !           815:        sk->max_unacked = DE600_MAX_WINDOW - DE600_TCP_WINDOW_DIFF;
        !           816:  */
        !           817: 
        !           818:        if (sk->rmem_alloc >= sk->rcvbuf-2*DE600_MIN_WINDOW) return(0);
        !           819:        amt = min((sk->rcvbuf-sk->rmem_alloc)/2/*-DE600_MIN_WINDOW*/, DE600_MAX_WINDOW);
        !           820:        if (amt < 0) return(0);
        !           821:        return(amt);
        !           822:   }
        !           823:   return(0);
        !           824: }
        !           825: #endif
        !           826: 
        !           827: #ifdef MODULE
        !           828: static char nullname[8];
        !           829: static struct device de600_dev = {
        !           830:        nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de600_probe };
        !           831: 
        !           832: int
        !           833: init_module(void)
        !           834: {
        !           835:        if (register_netdev(&de600_dev) != 0)
        !           836:                return -EIO;
        !           837:        return 0;
        !           838: }
        !           839: 
        !           840: void
        !           841: cleanup_module(void)
        !           842: {
        !           843:        unregister_netdev(&de600_dev);
        !           844:        release_region(DE600_IO, 3);
        !           845: }
        !           846: #endif /* MODULE */
        !           847: /*
        !           848:  * Local variables:
        !           849:  *  kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
        !           850:  *  module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
        !           851:  *  compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
        !           852:  * End:
        !           853:  */

unix.superglobalmegacorp.com

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