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 (dev->mc_count || 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        dev->trans_start = jiffies;
 539        if(!(using_txbuf == (TXBF0 | TXBF1)))
 540                netif_wake_queue(dev);
 541
 542        dev->stats.tx_packets++;
 543        spin_unlock_irqrestore(&de620_lock, flags);
 544        dev_kfree_skb (skb);
 545        return NETDEV_TX_OK;
 546}
 547
 548/*****************************************************
 549 *
 550 * Handle the network interface interrupts.
 551 *
 552 */
 553static irqreturn_t
 554de620_interrupt(int irq_in, void *dev_id)
 555{
 556        struct net_device *dev = dev_id;
 557        byte irq_status;
 558        int bogus_count = 0;
 559        int again = 0;
 560
 561        spin_lock(&de620_lock);
 562
 563        /* Read the status register (_not_ the status port) */
 564        irq_status = de620_get_register(dev, R_STS);
 565
 566        pr_debug("de620_interrupt (%2.2X)\n", irq_status);
 567
 568        if (irq_status & RXGOOD) {
 569                do {
 570                        again = de620_rx_intr(dev);
 571                        pr_debug("again=%d\n", again);
 572                }
 573                while (again && (++bogus_count < 100));
 574        }
 575
 576        if(de620_tx_buffs(dev) != (TXBF0 | TXBF1))
 577                netif_wake_queue(dev);
 578
 579        spin_unlock(&de620_lock);
 580        return IRQ_HANDLED;
 581}
 582
 583/**************************************
 584 *
 585 * Get a packet from the adapter
 586 *
 587 * Send it "upstairs"
 588 *
 589 */
 590static int de620_rx_intr(struct net_device *dev)
 591{
 592        struct header_buf {
 593                byte            status;
 594                byte            Rx_NextPage;
 595                unsigned short  Rx_ByteCount;
 596        } header_buf;
 597        struct sk_buff *skb;
 598        int size;
 599        byte *buffer;
 600        byte pagelink;
 601        byte curr_page;
 602
 603        pr_debug("de620_rx_intr: next_rx_page = %d\n", next_rx_page);
 604
 605        /* Tell the adapter that we are going to read data, and from where */
 606        de620_send_command(dev, W_CR | RRN);
 607        de620_set_register(dev, W_RSA1, next_rx_page);
 608        de620_set_register(dev, W_RSA0, 0);
 609
 610        /* Deep breath, and away we goooooo */
 611        de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
 612        pr_debug("page status=0x%02x, nextpage=%d, packetsize=%d\n",
 613                header_buf.status, header_buf.Rx_NextPage,
 614                header_buf.Rx_ByteCount);
 615
 616        /* Plausible page header? */
 617        pagelink = header_buf.Rx_NextPage;
 618        if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
 619                /* Ouch... Forget it! Skip all and start afresh... */
 620                printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name);
 621                /* You win some, you lose some. And sometimes plenty... */
 622                adapter_init(dev);
 623                netif_wake_queue(dev);
 624                dev->stats.rx_over_errors++;
 625                return 0;
 626        }
 627
 628        /* OK, this look good, so far. Let's see if it's consistent... */
 629        /* Let's compute the start of the next packet, based on where we are */
 630        pagelink = next_rx_page +
 631                ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
 632
 633        /* Are we going to wrap around the page counter? */
 634        if (pagelink > last_rx_page)
 635                pagelink -= (last_rx_page - first_rx_page + 1);
 636
 637        /* Is the _computed_ next page number equal to what the adapter says? */
 638        if (pagelink != header_buf.Rx_NextPage) {
 639                /* Naah, we'll skip this packet. Probably bogus data as well */
 640                printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name);
 641                next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
 642                de620_send_command(dev, W_DUMMY);
 643                de620_set_register(dev, W_NPRF, next_rx_page);
 644                dev->stats.rx_over_errors++;
 645                return 0;
 646        }
 647        next_rx_page = pagelink;
 648
 649        size = header_buf.Rx_ByteCount - 4;
 650        if ((size < RUNT) || (GIANT < size)) {
 651                printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
 652        }
 653        else { /* Good packet? */
 654                skb = dev_alloc_skb(size+2);
 655                if (skb == NULL) { /* Yeah, but no place to put it... */
 656                        printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
 657                        dev->stats.rx_dropped++;
 658                }
 659                else { /* Yep! Go get it! */
 660                        skb_reserve(skb,2);     /* Align */
 661                        /* skb->data points to the start of sk_buff data area */
 662                        buffer = skb_put(skb,size);
 663                        /* copy the packet into the buffer */
 664                        de620_read_block(dev, buffer, size);
 665                        pr_debug("Read %d bytes\n", size);
 666                        skb->protocol=eth_type_trans(skb,dev);
 667                        netif_rx(skb); /* deliver it "upstairs" */
 668                        /* count all receives */
 669                        dev->stats.rx_packets++;
 670                        dev->stats.rx_bytes += size;
 671                }
 672        }
 673
 674        /* Let's peek ahead to see if we have read the last current packet */
 675        /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
 676        curr_page = de620_get_register(dev, R_CPR);
 677        de620_set_register(dev, W_NPRF, next_rx_page);
 678        pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page);
 679
 680        return (next_rx_page != curr_page); /* That was slightly tricky... */
 681}
 682
 683/*********************************************
 684 *
 685 * Reset the adapter to a known state
 686 *
 687 */
 688static int adapter_init(struct net_device *dev)
 689{
 690        int i;
 691        static int was_down;
 692
 693        if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */
 694                EIPRegister = NCTL0;
 695                if (nic_data.Media != 1)
 696                        EIPRegister |= NIS0;    /* not BNC */
 697        }
 698        else if (nic_data.Model == 2) { /* UTP */
 699                EIPRegister = NCTL0 | NIS0;
 700        }
 701
 702        if (utp)
 703                EIPRegister = NCTL0 | NIS0;
 704        if (bnc)
 705                EIPRegister = NCTL0;
 706
 707        de620_send_command(dev, W_CR | RNOP | CLEAR);
 708        de620_send_command(dev, W_CR | RNOP);
 709
 710        de620_set_register(dev, W_SCR, SCR_DEF);
 711        /* disable recv to wait init */
 712        de620_set_register(dev, W_TCR, RXOFF);
 713
 714        /* Set the node ID in the adapter */
 715        for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */
 716                de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
 717        }
 718
 719        de620_set_register(dev, W_EIP, EIPRegister);
 720
 721        next_rx_page = first_rx_page = DE620_RX_START_PAGE;
 722        if (nic_data.RAM_Size)
 723                last_rx_page = nic_data.RAM_Size - 1;
 724        else /* 64k RAM */
 725                last_rx_page = 255;
 726
 727        de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/
 728        de620_set_register(dev, W_EPR, last_rx_page);  /* End Page Register */
 729        de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/
 730        de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/
 731        de620_send_command(dev, W_DUMMY);
 732        de620_set_delay(dev);
 733
 734        /* Final sanity check: Anybody out there? */
 735        /* Let's hope some bits from the statusregister make a good check */
 736#define CHECK_MASK (  0 | TXSUC |  T16  |  0  | RXCRC | RXSHORT |  0  |  0  )
 737#define CHECK_OK   (  0 |   0   |  0    |  0  |   0   |   0     |  0  |  0  )
 738        /* success:   X     0      0       X      0       0        X     X  */
 739        /* ignore:   EEDI                RXGOOD                   COLS  LNKS*/
 740
 741        if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
 742                printk(KERN_ERR "%s: Something has happened to the DE-620!  Please check it"
 743#ifdef SHUTDOWN_WHEN_LOST
 744                        " and do a new ifconfig"
 745#endif
 746                        "! (%02x)\n", dev->name, i);
 747#ifdef SHUTDOWN_WHEN_LOST
 748                /* Goodbye, cruel world... */
 749                dev->flags &= ~IFF_UP;
 750                de620_close(dev);
 751#endif
 752                was_down = 1;
 753                return 1; /* failed */
 754        }
 755        if (was_down) {
 756                printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name);
 757                was_down = 0;
 758        }
 759
 760        /* All OK, go ahead... */
 761        de620_set_register(dev, W_TCR, TCR_DEF);
 762
 763        return 0; /* all ok */
 764}
 765
 766static const struct net_device_ops de620_netdev_ops = {
 767        .ndo_open               = de620_open,
 768        .ndo_stop               = de620_close,
 769        .ndo_start_xmit         = de620_start_xmit,
 770        .ndo_tx_timeout         = de620_timeout,
 771        .ndo_set_multicast_list = de620_set_multicast_list,
 772        .ndo_change_mtu         = eth_change_mtu,
 773        .ndo_set_mac_address    = eth_mac_addr,
 774        .ndo_validate_addr      = eth_validate_addr,
 775};
 776
 777/******************************************************************************
 778 *
 779 * Only start-up code below
 780 *
 781 */
 782/****************************************
 783 *
 784 * Check if there is a DE-620 connected
 785 */
 786struct net_device * __init de620_probe(int unit)
 787{
 788        byte checkbyte = 0xa5;
 789        struct net_device *dev;
 790        int err = -ENOMEM;
 791        int i;
 792
 793        dev = alloc_etherdev(0);
 794        if (!dev)
 795                goto out;
 796
 797        spin_lock_init(&de620_lock);
 798
 799        /*
 800         * This is where the base_addr and irq gets set.
 801         * Tunable at compile-time and insmod-time
 802         */
 803        dev->base_addr = io;
 804        dev->irq       = irq;
 805
 806        /* allow overriding parameters on command line */
 807        if (unit >= 0) {
 808                sprintf(dev->name, "eth%d", unit);
 809                netdev_boot_setup_check(dev);
 810        }
 811
 812        pr_debug("%s", version);
 813
 814        printk(KERN_INFO "D-Link DE-620 pocket adapter");
 815
 816        if (!request_region(dev->base_addr, 3, "de620")) {
 817                printk(" io 0x%3lX, which is busy.\n", dev->base_addr);
 818                err = -EBUSY;
 819                goto out1;
 820        }
 821
 822        /* Initially, configure basic nibble mode, so we can read the EEPROM */
 823        NIC_Cmd = DEF_NIC_CMD;
 824        de620_set_register(dev, W_EIP, EIPRegister);
 825
 826        /* Anybody out there? */
 827        de620_set_register(dev, W_CPR, checkbyte);
 828        checkbyte = de620_get_register(dev, R_CPR);
 829
 830        if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
 831                printk(" not identified in the printer port\n");
 832                err = -ENODEV;
 833                goto out2;
 834        }
 835
 836        /* else, got it! */
 837        dev->dev_addr[0] = nic_data.NodeID[0];
 838        for (i = 1; i < ETH_ALEN; i++) {
 839                dev->dev_addr[i] = nic_data.NodeID[i];
 840                dev->broadcast[i] = 0xff;
 841        }
 842
 843        printk(", Ethernet Address: %pM", dev->dev_addr);
 844
 845        printk(" (%dk RAM,",
 846                (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
 847
 848        if (nic_data.Media == 1)
 849                printk(" BNC)\n");
 850        else
 851                printk(" UTP)\n");
 852
 853        dev->netdev_ops = &de620_netdev_ops;
 854        dev->watchdog_timeo     = HZ*2;
 855
 856        /* base_addr and irq are already set, see above! */
 857
 858        /* dump eeprom */
 859        pr_debug("\nEEPROM contents:\n"
 860                "RAM_Size = 0x%02X\n"
 861                "NodeID = %pM\n"
 862                "Model = %d\n"
 863                "Media = %d\n"
 864                "SCR = 0x%02x\n", nic_data.RAM_Size, nic_data.NodeID,
 865                nic_data.Model, nic_data.Media, nic_data.SCR);
 866
 867        err = register_netdev(dev);
 868        if (err)
 869                goto out2;
 870        return dev;
 871
 872out2:
 873        release_region(dev->base_addr, 3);
 874out1:
 875        free_netdev(dev);
 876out:
 877        return ERR_PTR(err);
 878}
 879
 880/**********************************
 881 *
 882 * Read info from on-board EEPROM
 883 *
 884 * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_!
 885 */
 886#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
 887
 888static unsigned short __init ReadAWord(struct net_device *dev, int from)
 889{
 890        unsigned short data;
 891        int nbits;
 892
 893        /* cs   [__~~] SET SEND STATE */
 894        /* di   [____]                */
 895        /* sck  [_~~_]                */
 896        sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
 897
 898        /* Send the 9-bit address from where we want to read the 16-bit word */
 899        for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
 900                if (from & 0x0100) { /* bit set? */
 901                        /* cs    [~~~~] SEND 1 */
 902                        /* di    [~~~~]        */
 903                        /* sck   [_~~_]        */
 904                        sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
 905                }
 906                else {
 907                        /* cs    [~~~~] SEND 0 */
 908                        /* di    [____]        */
 909                        /* sck   [_~~_]        */
 910                        sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
 911                }
 912        }
 913
 914        /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */
 915        for (data = 0, nbits = 16; nbits > 0; --nbits) {
 916                /* cs    [~~~~] SEND 0 */
 917                /* di    [____]        */
 918                /* sck   [_~~_]        */
 919                sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
 920                data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
 921        }
 922        /* cs    [____] RESET SEND STATE */
 923        /* di    [____]                  */
 924        /* sck   [_~~_]                  */
 925        sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
 926
 927        return data;
 928}
 929
 930static int __init read_eeprom(struct net_device *dev)
 931{
 932        unsigned short wrd;
 933
 934        /* D-Link Ethernet addresses are in the series  00:80:c8:7X:XX:XX:XX */
 935        wrd = ReadAWord(dev, 0x1aa);    /* bytes 0 + 1 of NodeID */
 936        if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */
 937                return -1; /* Nope, not a DE-620 */
 938        nic_data.NodeID[0] = wrd & 0xff;
 939        nic_data.NodeID[1] = wrd >> 8;
 940
 941        wrd = ReadAWord(dev, 0x1ab);    /* bytes 2 + 3 of NodeID */
 942        if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */
 943                return -1; /* Nope, not a DE-620 */
 944        nic_data.NodeID[2] = wrd & 0xff;
 945        nic_data.NodeID[3] = wrd >> 8;
 946
 947        wrd = ReadAWord(dev, 0x1ac);    /* bytes 4 + 5 of NodeID */
 948        nic_data.NodeID[4] = wrd & 0xff;
 949        nic_data.NodeID[5] = wrd >> 8;
 950
 951        wrd = ReadAWord(dev, 0x1ad);    /* RAM size in pages (256 bytes). 0 = 64k */
 952        nic_data.RAM_Size = (wrd >> 8);
 953
 954        wrd = ReadAWord(dev, 0x1ae);    /* hardware model (CT = 3) */
 955        nic_data.Model = (wrd & 0xff);
 956
 957        wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */
 958        nic_data.Media = (wrd & 0xff);
 959
 960        wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */
 961        nic_data.SCR = (wrd >> 8);
 962
 963        return 0; /* no errors */
 964}
 965
 966/******************************************************************************
 967 *
 968 * Loadable module skeleton
 969 *
 970 */
 971#ifdef MODULE
 972static struct net_device *de620_dev;
 973
 974int __init init_module(void)
 975{
 976        de620_dev = de620_probe(-1);
 977        if (IS_ERR(de620_dev))
 978                return PTR_ERR(de620_dev);
 979        return 0;
 980}
 981
 982void cleanup_module(void)
 983{
 984        unregister_netdev(de620_dev);
 985        release_region(de620_dev->base_addr, 3);
 986        free_netdev(de620_dev);
 987}
 988#endif /* MODULE */
 989MODULE_LICENSE("GPL");
 990