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