linux-bk/drivers/net/de600.c
<<
>>
Prefs
   1static const char version[] =
   2        "de600.c: $Revision: 1.40 $,  Bjorn Ekwall (bj0rn@blox.se)\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 bj0rn@blox.se
  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 <becker@super.org>
  19 *              (Now at <becker@scyld.com>)
  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 more time here if your adapter won't work OK: */
  43#define DE600_SLOW_DOWN udelay(delay_time)
  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
  92#include <linux/module.h>
  93
  94#include <linux/kernel.h>
  95#include <linux/sched.h>
  96#include <linux/types.h>
  97#include <linux/fcntl.h>
  98#include <linux/string.h>
  99#include <linux/interrupt.h>
 100#include <linux/ioport.h>
 101#include <asm/io.h>
 102#include <linux/in.h>
 103#include <asm/system.h>
 104#include <linux/errno.h>
 105#include <linux/init.h>
 106#include <linux/delay.h>
 107
 108#include <linux/inet.h>
 109#include <linux/netdevice.h>
 110#include <linux/etherdevice.h>
 111#include <linux/skbuff.h>
 112
 113static unsigned int de600_debug = DE600_DEBUG;
 114MODULE_PARM(de600_debug, "i");
 115MODULE_PARM_DESC(de600_debug, "DE-600 debug level (0-2)");
 116
 117static unsigned int delay_time = 10;
 118MODULE_PARM(delay_time, "i");
 119MODULE_PARM_DESC(delay_time, "DE-600 deley on I/O in microseconds");
 120
 121#ifdef FAKE_SMALL_MAX
 122static unsigned long de600_rspace(struct sock *sk);
 123#include <net/sock.h>
 124#endif
 125
 126typedef unsigned char byte;
 127
 128/**************************************************
 129 *                                                *
 130 * Definition of D-Link Ethernet Pocket adapter   *
 131 *                                                *
 132 **************************************************/
 133/*
 134 * D-Link Ethernet pocket adapter ports
 135 */
 136/*
 137 * OK, so I'm cheating, but there are an awful lot of
 138 * reads and writes in order to get anything in and out
 139 * of the DE-600 with 4 bits at a time in the parallel port,
 140 * so every saved instruction really helps :-)
 141 *
 142 * That is, I don't care what the device struct says
 143 * but hope that Space.c will keep the rest of the drivers happy.
 144 */
 145#ifndef DE600_IO
 146#define DE600_IO 0x378
 147#endif
 148
 149#define DATA_PORT       (DE600_IO)
 150#define STATUS_PORT     (DE600_IO + 1)
 151#define COMMAND_PORT    (DE600_IO + 2)
 152
 153#ifndef DE600_IRQ
 154#define DE600_IRQ       7
 155#endif
 156/*
 157 * It really should look like this, and autoprobing as well...
 158 *
 159#define DATA_PORT       (dev->base_addr + 0)
 160#define STATUS_PORT     (dev->base_addr + 1)
 161#define COMMAND_PORT    (dev->base_addr + 2)
 162#define DE600_IRQ       dev->irq
 163 */
 164
 165/*
 166 * D-Link COMMAND_PORT commands
 167 */
 168#define SELECT_NIC      0x04 /* select Network Interface Card */
 169#define SELECT_PRN      0x1c /* select Printer */
 170#define NML_PRN         0xec /* normal Printer situation */
 171#define IRQEN           0x10 /* enable IRQ line */
 172
 173/*
 174 * D-Link STATUS_PORT
 175 */
 176#define RX_BUSY         0x80
 177#define RX_GOOD         0x40
 178#define TX_FAILED16     0x10
 179#define TX_BUSY         0x08
 180
 181/*
 182 * D-Link DATA_PORT commands
 183 * command in low 4 bits
 184 * data in high 4 bits
 185 * select current data nibble with HI_NIBBLE bit
 186 */
 187#define WRITE_DATA      0x00 /* write memory */
 188#define READ_DATA       0x01 /* read memory */
 189#define STATUS          0x02 /* read  status register */
 190#define COMMAND         0x03 /* write command register (see COMMAND below) */
 191#define NULL_COMMAND    0x04 /* null command */
 192#define RX_LEN          0x05 /* read  received packet length */
 193#define TX_ADDR         0x06 /* set adapter transmit memory address */
 194#define RW_ADDR         0x07 /* set adapter read/write memory address */
 195#define HI_NIBBLE       0x08 /* read/write the high nibble of data,
 196                                or-ed with rest of command */
 197
 198/*
 199 * command register, accessed through DATA_PORT with low bits = COMMAND
 200 */
 201#define RX_ALL          0x01 /* PROMISCUOUS */
 202#define RX_BP           0x02 /* default: BROADCAST & PHYSICAL ADDRESS */
 203#define RX_MBP          0x03 /* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
 204
 205#define TX_ENABLE       0x04 /* bit 2 */
 206#define RX_ENABLE       0x08 /* bit 3 */
 207
 208#define RESET           0x80 /* set bit 7 high */
 209#define STOP_RESET      0x00 /* set bit 7 low */
 210
 211/*
 212 * data to command register
 213 * (high 4 bits in write to DATA_PORT)
 214 */
 215#define RX_PAGE2_SELECT 0x10 /* bit 4, only 2 pages to select */
 216#define RX_BASE_PAGE    0x20 /* bit 5, always set when specifying RX_ADDR */
 217#define FLIP_IRQ        0x40 /* bit 6 */
 218
 219/*
 220 * D-Link adapter internal memory:
 221 *
 222 * 0-2K 1:st transmit page (send from pointer up to 2K)
 223 * 2-4K 2:nd transmit page (send from pointer up to 4K)
 224 *
 225 * 4-6K 1:st receive page (data from 4K upwards)
 226 * 6-8K 2:nd receive page (data from 6K upwards)
 227 *
 228 * 8K+  Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
 229 */
 230#define MEM_2K          0x0800 /* 2048 */
 231#define MEM_4K          0x1000 /* 4096 */
 232#define MEM_6K          0x1800 /* 6144 */
 233#define NODE_ADDRESS    0x2000 /* 8192 */
 234
 235#define RUNT 60         /* Too small Ethernet packet */
 236
 237/**************************************************
 238 *                                                *
 239 *             End of definition                  *
 240 *                                                *
 241 **************************************************/
 242
 243/*
 244 * Index to functions, as function prototypes.
 245 */
 246/* Routines used internally. (See "convenience macros") */
 247static byte     de600_read_status(struct net_device *dev);
 248static byte     de600_read_byte(unsigned char type, struct net_device *dev);
 249
 250/* Put in the device structure. */
 251static int      de600_open(struct net_device *dev);
 252static int      de600_close(struct net_device *dev);
 253static struct net_device_stats *get_stats(struct net_device *dev);
 254static int      de600_start_xmit(struct sk_buff *skb, struct net_device *dev);
 255
 256/* Dispatch from interrupts. */
 257static void     de600_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 258static int      de600_tx_intr(struct net_device *dev, int irq_status);
 259static void     de600_rx_intr(struct net_device *dev);
 260
 261/* Initialization */
 262static void     trigger_interrupt(struct net_device *dev);
 263int             de600_probe(struct net_device *dev);
 264static int      adapter_init(struct net_device *dev);
 265
 266/*
 267 * D-Link driver variables:
 268 */
 269static volatile int             rx_page;
 270
 271#define TX_PAGES 2
 272static volatile int             tx_fifo[TX_PAGES];
 273static volatile int             tx_fifo_in;
 274static volatile int             tx_fifo_out;
 275static volatile int             free_tx_pages = TX_PAGES;
 276static int                      was_down;
 277
 278/*
 279 * Convenience macros/functions for D-Link adapter
 280 */
 281
 282#define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
 283#define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
 284
 285/* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
 286#define de600_put_byte(data) ( \
 287        outb_p(((data) << 4)   | WRITE_DATA            , DATA_PORT), \
 288        outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
 289
 290/*
 291 * The first two outb_p()'s below could perhaps be deleted if there
 292 * would be more delay in the last two. Not certain about it yet...
 293 */
 294#define de600_put_command(cmd) ( \
 295        outb_p(( rx_page        << 4)   | COMMAND            , DATA_PORT), \
 296        outb_p(( rx_page        & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
 297        outb_p(((rx_page | cmd) << 4)   | COMMAND            , DATA_PORT), \
 298        outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
 299
 300#define de600_setup_address(addr,type) ( \
 301        outb_p((((addr) << 4) & 0xf0) | type            , DATA_PORT), \
 302        outb_p(( (addr)       & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
 303        outb_p((((addr) >> 4) & 0xf0) | type            , DATA_PORT), \
 304        outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
 305
 306#define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
 307
 308/* Flip bit, only 2 pages */
 309#define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
 310
 311#define tx_page_adr(a) (((a) + 1) * MEM_2K)
 312
 313static inline byte
 314de600_read_status(struct net_device *dev)
 315{
 316        byte status;
 317
 318        outb_p(STATUS, DATA_PORT);
 319        status = inb(STATUS_PORT);
 320        outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
 321
 322        return status;
 323}
 324
 325static inline byte
 326de600_read_byte(unsigned char type, struct net_device *dev) { /* dev used by macros */
 327        byte lo;
 328
 329        (void)outb_p((type), DATA_PORT);
 330        lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
 331        (void)outb_p((type) | HI_NIBBLE, DATA_PORT);
 332        return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
 333}
 334
 335/*
 336 * Open/initialize the board.  This is called (in the current kernel)
 337 * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
 338 *
 339 * This routine should set everything up anew at each open, even
 340 * registers that "should" only need to be set once at boot, so that
 341 * there is a non-reboot way to recover if something goes wrong.
 342 */
 343static int
 344de600_open(struct net_device *dev)
 345{
 346        int ret = request_irq(DE600_IRQ, de600_interrupt, 0, dev->name, dev);
 347        if (ret) {
 348                printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
 349                return ret;
 350        }
 351
 352        if (adapter_init(dev))
 353                return -EIO;
 354
 355        return 0;
 356}
 357
 358/*
 359 * The inverse routine to de600_open().
 360 */
 361static int
 362de600_close(struct net_device *dev)
 363{
 364        select_nic();
 365        rx_page = 0;
 366        de600_put_command(RESET);
 367        de600_put_command(STOP_RESET);
 368        de600_put_command(0);
 369        select_prn();
 370
 371        if (netif_running(dev)) { /* perhaps not needed? */
 372                free_irq(DE600_IRQ, dev);
 373        }
 374        return 0;
 375}
 376
 377static struct net_device_stats *
 378get_stats(struct net_device *dev)
 379{
 380    return (struct net_device_stats *)(dev->priv);
 381}
 382
 383static inline void
 384trigger_interrupt(struct net_device *dev)
 385{
 386        de600_put_command(FLIP_IRQ);
 387        select_prn();
 388        DE600_SLOW_DOWN;
 389        select_nic();
 390        de600_put_command(0);
 391}
 392
 393/*
 394 * Copy a buffer to the adapter transmit page memory.
 395 * Start sending.
 396 */
 397static int
 398de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
 399{
 400        unsigned long flags;
 401        int     transmit_from;
 402        int     len;
 403        int     tickssofar;
 404        byte    *buffer = skb->data;
 405
 406        if (free_tx_pages <= 0) {       /* Do timeouts, to avoid hangs. */
 407                tickssofar = jiffies - dev->trans_start;
 408
 409                if (tickssofar < 5)
 410                        return 1;
 411
 412                /* else */
 413                printk("%s: transmit timed out (%d), %s?\n",
 414                        dev->name,
 415                        tickssofar,
 416                        "network cable problem"
 417                        );
 418                /* Restart the adapter. */
 419                if (adapter_init(dev)) {
 420                        return 1;
 421                }
 422        }
 423
 424        /* Start real output */
 425        PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
 426
 427        if ((len = skb->len) < RUNT)
 428                len = RUNT;
 429
 430        save_flags(flags);
 431        cli();
 432        select_nic();
 433        tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
 434        tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
 435
 436#ifdef CHECK_LOST_DE600
 437        /* This costs about 40 instructions per packet... */
 438        de600_setup_address(NODE_ADDRESS, RW_ADDR);
 439        de600_read_byte(READ_DATA, dev);
 440        if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
 441                if (adapter_init(dev)) {
 442                        restore_flags(flags);
 443                        return 1;
 444                }
 445        }
 446#endif
 447
 448        de600_setup_address(transmit_from, RW_ADDR);
 449        for ( ; len > 0; --len, ++buffer)
 450                de600_put_byte(*buffer);
 451
 452        if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
 453                dev->trans_start = jiffies;
 454                netif_start_queue(dev); /* allow more packets into adapter */
 455                /* Send page and generate a faked interrupt */
 456                de600_setup_address(transmit_from, TX_ADDR);
 457                de600_put_command(TX_ENABLE);
 458        }
 459        else {
 460                if (free_tx_pages)
 461                        netif_start_queue(dev);
 462                else
 463                        netif_stop_queue(dev);
 464                select_prn();
 465        }
 466
 467        restore_flags(flags);
 468
 469#ifdef FAKE_SMALL_MAX
 470        /* This will "patch" the socket TCP proto at an early moment */
 471        if (skb->sk && (skb->sk->protocol == IPPROTO_TCP) &&
 472                (skb->sk->prot->rspace != &de600_rspace))
 473                skb->sk->prot->rspace = de600_rspace; /* Ugh! */
 474#endif
 475
 476        dev_kfree_skb (skb);
 477
 478        return 0;
 479}
 480
 481/*
 482 * The typical workload of the driver:
 483 * Handle the network interface interrupts.
 484 */
 485static void
 486de600_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 487{
 488        struct net_device       *dev = dev_id;
 489        byte            irq_status;
 490        int             retrig = 0;
 491        int             boguscount = 0;
 492
 493        /* This might just as well be deleted now, no crummy drivers present :-) */
 494        if ((dev == NULL) || (DE600_IRQ != irq)) {
 495                printk("%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
 496                return;
 497        }
 498
 499        select_nic();
 500        irq_status = de600_read_status(dev);
 501
 502        do {
 503                PRINTK(("de600_interrupt (%02X)\n", irq_status));
 504
 505                if (irq_status & RX_GOOD)
 506                        de600_rx_intr(dev);
 507                else if (!(irq_status & RX_BUSY))
 508                        de600_put_command(RX_ENABLE);
 509
 510                /* Any transmission in progress? */
 511                if (free_tx_pages < TX_PAGES)
 512                        retrig = de600_tx_intr(dev, irq_status);
 513                else
 514                        retrig = 0;
 515
 516                irq_status = de600_read_status(dev);
 517        } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
 518        /*
 519         * Yeah, it _looks_ like busy waiting, smells like busy waiting
 520         * and I know it's not PC, but please, it will only occur once
 521         * in a while and then only for a loop or so (< 1ms for sure!)
 522         */
 523
 524        /* Enable adapter interrupts */
 525        select_prn();
 526
 527        if (retrig)
 528                trigger_interrupt(dev);
 529
 530        return;
 531}
 532
 533static int
 534de600_tx_intr(struct net_device *dev, int irq_status)
 535{
 536        /*
 537         * Returns 1 if tx still not done
 538         */
 539
 540        /* Check if current transmission is done yet */
 541        if (irq_status & TX_BUSY)
 542                return 1; /* tx not done, try again */
 543
 544        /* else */
 545        /* If last transmission OK then bump fifo index */
 546        if (!(irq_status & TX_FAILED16)) {
 547                tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
 548                ++free_tx_pages;
 549                ((struct net_device_stats *)(dev->priv))->tx_packets++;
 550                netif_wake_queue(dev);
 551        }
 552
 553        /* More to send, or resend last packet? */
 554        if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
 555                dev->trans_start = jiffies;
 556                de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
 557                de600_put_command(TX_ENABLE);
 558                return 1;
 559        }
 560        /* else */
 561
 562        return 0;
 563}
 564
 565/*
 566 * We have a good packet, get it out of the adapter.
 567 */
 568static void
 569de600_rx_intr(struct net_device *dev)
 570{
 571        struct sk_buff  *skb;
 572        unsigned long flags;
 573        int             i;
 574        int             read_from;
 575        int             size;
 576        register unsigned char  *buffer;
 577
 578        save_flags(flags);
 579        cli();
 580
 581        /* Get size of received packet */
 582        size = de600_read_byte(RX_LEN, dev);    /* low byte */
 583        size += (de600_read_byte(RX_LEN, dev) << 8);    /* high byte */
 584        size -= 4;      /* Ignore trailing 4 CRC-bytes */
 585
 586        /* Tell adapter where to store next incoming packet, enable receiver */
 587        read_from = rx_page_adr();
 588        next_rx_page();
 589        de600_put_command(RX_ENABLE);
 590
 591        restore_flags(flags);
 592
 593        if ((size < 32)  ||  (size > 1535)) {
 594                printk("%s: Bogus packet size %d.\n", dev->name, size);
 595                if (size > 10000)
 596                        adapter_init(dev);
 597                return;
 598        }
 599
 600        skb = dev_alloc_skb(size+2);
 601        if (skb == NULL) {
 602                printk("%s: Couldn't allocate a sk_buff of size %d.\n",
 603                        dev->name, size);
 604                return;
 605        }
 606        /* else */
 607
 608        skb->dev = dev;
 609        skb_reserve(skb,2);     /* Align */
 610
 611        /* 'skb->data' points to the start of sk_buff data area. */
 612        buffer = skb_put(skb,size);
 613
 614        /* copy the packet into the buffer */
 615        de600_setup_address(read_from, RW_ADDR);
 616        for (i = size; i > 0; --i, ++buffer)
 617                *buffer = de600_read_byte(READ_DATA, dev);
 618
 619        skb->protocol=eth_type_trans(skb,dev);
 620
 621        netif_rx(skb);
 622
 623        /* update stats */
 624        dev->last_rx = jiffies;
 625        ((struct net_device_stats *)(dev->priv))->rx_packets++; /* count all receives */
 626        ((struct net_device_stats *)(dev->priv))->rx_bytes += size; /* count all received bytes */
 627
 628        /*
 629         * If any worth-while packets have been received, netif_rx()
 630         * has done a mark_bh(INET_BH) for us and will work on them
 631         * when we get to the bottom-half routine.
 632         */
 633}
 634
 635int __init 
 636de600_probe(struct net_device *dev)
 637{
 638        int     i;
 639        static struct net_device_stats de600_netstats;
 640        /*dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);*/
 641
 642        SET_MODULE_OWNER(dev);
 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 = &de600_netstats;
 700
 701        memset(dev->priv, 0, sizeof(struct net_device_stats));
 702        dev->get_stats = get_stats;
 703
 704        dev->open = de600_open;
 705        dev->stop = de600_close;
 706        dev->hard_start_xmit = &de600_start_xmit;
 707
 708        ether_setup(dev);
 709
 710        dev->flags&=~IFF_MULTICAST;
 711
 712        select_prn();
 713        return 0;
 714}
 715
 716static int
 717adapter_init(struct net_device *dev)
 718{
 719        int     i;
 720       unsigned long flags;
 721
 722        save_flags(flags);
 723        cli();
 724
 725        select_nic();
 726        rx_page = 0; /* used by RESET */
 727        de600_put_command(RESET);
 728        de600_put_command(STOP_RESET);
 729#ifdef CHECK_LOST_DE600
 730        /* Check if it is still there... */
 731        /* Get the some bytes of the adapter ethernet address from the ROM */
 732        de600_setup_address(NODE_ADDRESS, RW_ADDR);
 733        de600_read_byte(READ_DATA, dev);
 734        if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
 735            (de600_read_byte(READ_DATA, dev) != 0x15)) {
 736        /* was: if (de600_read_status(dev) & 0xf0) { */
 737                printk("Something has happened to the DE-600!  Please check it"
 738#ifdef SHUTDOWN_WHEN_LOST
 739                        " and do a new ifconfig"
 740#endif /* SHUTDOWN_WHEN_LOST */
 741                        "!\n");
 742#ifdef SHUTDOWN_WHEN_LOST
 743                /* Goodbye, cruel world... */
 744                dev->flags &= ~IFF_UP;
 745                de600_close(dev);
 746#endif /* SHUTDOWN_WHEN_LOST */
 747                was_down = 1;
 748                netif_stop_queue(dev); /* Transmit busy...  */
 749                restore_flags(flags);
 750                return 1; /* failed */
 751        }
 752#endif /* CHECK_LOST_DE600 */
 753        if (was_down) {
 754                printk("Thanks, I feel much better now!\n");
 755                was_down = 0;
 756        }
 757
 758        netif_start_queue(dev);
 759        tx_fifo_in = 0;
 760        tx_fifo_out = 0;
 761        free_tx_pages = TX_PAGES;
 762
 763        /* set the ether address. */
 764        de600_setup_address(NODE_ADDRESS, RW_ADDR);
 765        for (i = 0; i < ETH_ALEN; i++)
 766                de600_put_byte(dev->dev_addr[i]);
 767
 768        /* where to start saving incoming packets */
 769        rx_page = RX_BP | RX_BASE_PAGE;
 770        de600_setup_address(MEM_4K, RW_ADDR);
 771        /* Enable receiver */
 772        de600_put_command(RX_ENABLE);
 773        select_prn();
 774        restore_flags(flags);
 775
 776        return 0; /* OK */
 777}
 778
 779#ifdef FAKE_SMALL_MAX
 780/*
 781 *      The new router code (coming soon 8-) ) will fix this properly.
 782 */
 783#define DE600_MIN_WINDOW 1024
 784#define DE600_MAX_WINDOW 2048
 785#define DE600_TCP_WINDOW_DIFF 1024
 786/*
 787 * Copied from "net/inet/sock.c"
 788 *
 789 * Sets a lower max receive window in order to achieve <= 2
 790 * packets arriving at the adapter in fast succession.
 791 * (No way that a DE-600 can keep up with a net saturated
 792 *  with packets homing in on it :-( )
 793 *
 794 * Since there are only 2 receive buffers in the DE-600
 795 * and it takes some time to copy from the adapter,
 796 * this is absolutely necessary for any TCP performance whatsoever!
 797 *
 798 * Note that the returned window info will never be smaller than
 799 * DE600_MIN_WINDOW, i.e. 1024
 800 * This differs from the standard function, that can return an
 801 * arbitrarily small window!
 802 */
 803static unsigned long
 804de600_rspace(struct sock *sk)
 805{
 806  int amt;
 807
 808  if (sk != NULL) {
 809/*
 810 * Hack! You might want to play with commenting away the following line,
 811 * if you know what you do!
 812        sk->max_unacked = DE600_MAX_WINDOW - DE600_TCP_WINDOW_DIFF;
 813 */
 814
 815        if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf-2*DE600_MIN_WINDOW) return(0);
 816        amt = min_t(int, (sk->rcvbuf-atomic_read(&sk->rmem_alloc))/2/*-DE600_MIN_WINDOW*/, DE600_MAX_WINDOW);
 817        if (amt < 0) return(0);
 818        return(amt);
 819  }
 820  return(0);
 821}
 822#endif
 823
 824#ifdef MODULE
 825static struct net_device de600_dev;
 826
 827int
 828init_module(void)
 829{
 830        de600_dev.init = de600_probe;
 831        if (register_netdev(&de600_dev) != 0)
 832                return -EIO;
 833        return 0;
 834}
 835
 836void
 837cleanup_module(void)
 838{
 839        unregister_netdev(&de600_dev);
 840        release_region(DE600_IO, 3);
 841}
 842#endif /* MODULE */
 843
 844MODULE_LICENSE("GPL");
 845
 846/*
 847 * Local variables:
 848 *  kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
 849 *  module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
 850 *  compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
 851 * End:
 852 */
 853
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.