linux-bk/drivers/net/de600.c
<<
>>
Prefs
   1static const char version[] = "de600.c: $Revision: 1.41-2.5 $,  Bjorn Ekwall (bj0rn@blox.se)\n";
   2/*
   3 *      de600.c
   4 *
   5 *      Linux driver for the D-Link DE-600 Ethernet pocket adapter.
   6 *
   7 *      Portions (C) Copyright 1993, 1994 by Bjorn Ekwall
   8 *      The Author may be reached as bj0rn@blox.se
   9 *
  10 *      Based on adapter information gathered from DE600.ASM by D-Link Inc.,
  11 *      as included on disk C in the v.2.11 of PC/TCP from FTP Software.
  12 *      For DE600.asm:
  13 *              Portions (C) Copyright 1990 D-Link, Inc.
  14 *              Copyright, 1988-1992, Russell Nelson, Crynwr Software
  15 *
  16 *      Adapted to the sample network driver core for linux,
  17 *      written by: Donald Becker <becker@super.org>
  18 *              (Now at <becker@scyld.com>)
  19 *
  20 **************************************************************/
  21/*
  22 *      This program is free software; you can redistribute it and/or modify
  23 *      it under the terms of the GNU General Public License as published by
  24 *      the Free Software Foundation; either version 2, or (at your option)
  25 *      any later version.
  26 *
  27 *      This program is distributed in the hope that it will be useful,
  28 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  29 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  30 *      GNU General Public License for more details.
  31 *
  32 *      You should have received a copy of the GNU General Public License
  33 *      along with this program; if not, write to the Free Software
  34 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  35 *
  36 **************************************************************/
  37
  38/* Add more time here if your adapter won't work OK: */
  39#define DE600_SLOW_DOWN udelay(delay_time)
  40
  41 /*
  42 * If you still have trouble reading/writing to the adapter,
  43 * modify the following "#define": (see <asm/io.h> for more info)
  44#define REALLY_SLOW_IO
  45 */
  46#define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */
  47
  48/* use 0 for production, 1 for verification, >2 for debug */
  49#ifdef DE600_DEBUG
  50#define PRINTK(x) if (de600_debug >= 2) printk x
  51#else
  52#define DE600_DEBUG 0
  53#define PRINTK(x) /**/
  54#endif
  55
  56#include <linux/module.h>
  57#include <linux/kernel.h>
  58#include <linux/types.h>
  59#include <linux/fcntl.h>
  60#include <linux/string.h>
  61#include <linux/interrupt.h>
  62#include <linux/ioport.h>
  63#include <linux/in.h>
  64#include <asm/system.h>
  65#include <linux/errno.h>
  66#include <linux/init.h>
  67#include <linux/delay.h>
  68#include <linux/inet.h>
  69#include <linux/netdevice.h>
  70#include <linux/etherdevice.h>
  71#include <linux/skbuff.h>
  72
  73#include <asm/io.h>
  74
  75#include "de600.h"
  76
  77static unsigned int de600_debug = DE600_DEBUG;
  78MODULE_PARM(de600_debug, "i");
  79MODULE_PARM_DESC(de600_debug, "DE-600 debug level (0-2)");
  80
  81static unsigned int check_lost = 1;
  82MODULE_PARM(check_lost, "i");
  83MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
  84
  85static unsigned int delay_time = 10;
  86MODULE_PARM(delay_time, "i");
  87MODULE_PARM_DESC(delay_time, "DE-600 deley on I/O in microseconds");
  88
  89
  90/*
  91 * D-Link driver variables:
  92 */
  93
  94static volatile int             rx_page;
  95
  96#define TX_PAGES 2
  97static volatile int             tx_fifo[TX_PAGES];
  98static volatile int             tx_fifo_in;
  99static volatile int             tx_fifo_out;
 100static volatile int             free_tx_pages = TX_PAGES;
 101static int                      was_down;
 102static spinlock_t               de600_lock;
 103
 104static inline u8 de600_read_status(struct net_device *dev)
 105{
 106        u8 status;
 107
 108        outb_p(STATUS, DATA_PORT);
 109        status = inb(STATUS_PORT);
 110        outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
 111
 112        return status;
 113}
 114
 115static inline u8 de600_read_byte(unsigned char type, struct net_device *dev)
 116{
 117        /* dev used by macros */
 118        u8 lo;
 119        outb_p((type), DATA_PORT);
 120        lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
 121        outb_p((type) | HI_NIBBLE, DATA_PORT);
 122        return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
 123}
 124
 125/*
 126 * Open/initialize the board.  This is called (in the current kernel)
 127 * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
 128 *
 129 * This routine should set everything up anew at each open, even
 130 * registers that "should" only need to be set once at boot, so that
 131 * there is a non-reboot way to recover if something goes wrong.
 132 */
 133
 134static int de600_open(struct net_device *dev)
 135{
 136        unsigned long flags;
 137        int ret = request_irq(DE600_IRQ, de600_interrupt, 0, dev->name, dev);
 138        if (ret) {
 139                printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
 140                return ret;
 141        }
 142        spin_lock_irqsave(&de600_lock, flags);
 143        ret = adapter_init(dev);
 144        spin_unlock_irqrestore(&de600_lock, flags);
 145        return ret;
 146}
 147
 148/*
 149 * The inverse routine to de600_open().
 150 */
 151
 152static int de600_close(struct net_device *dev)
 153{
 154        select_nic();
 155        rx_page = 0;
 156        de600_put_command(RESET);
 157        de600_put_command(STOP_RESET);
 158        de600_put_command(0);
 159        select_prn();
 160        free_irq(DE600_IRQ, dev);
 161        return 0;
 162}
 163
 164static struct net_device_stats *get_stats(struct net_device *dev)
 165{
 166        return (struct net_device_stats *)(dev->priv);
 167}
 168
 169static inline void trigger_interrupt(struct net_device *dev)
 170{
 171        de600_put_command(FLIP_IRQ);
 172        select_prn();
 173        DE600_SLOW_DOWN;
 174        select_nic();
 175        de600_put_command(0);
 176}
 177
 178/*
 179 * Copy a buffer to the adapter transmit page memory.
 180 * Start sending.
 181 */
 182 
 183static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
 184{
 185        unsigned long flags;
 186        int     transmit_from;
 187        int     len;
 188        int     tickssofar;
 189        u8      *buffer = skb->data;
 190        int     i;
 191
 192        if (free_tx_pages <= 0) {       /* Do timeouts, to avoid hangs. */
 193                tickssofar = jiffies - dev->trans_start;
 194                if (tickssofar < 5)
 195                        return 1;
 196                /* else */
 197                printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
 198                /* Restart the adapter. */
 199                spin_lock_irqsave(&de600_lock, flags);
 200                if (adapter_init(dev)) {
 201                        spin_unlock_irqrestore(&de600_lock, flags);
 202                        return 1;
 203                }
 204                spin_unlock_irqrestore(&de600_lock, flags);
 205        }
 206
 207        /* Start real output */
 208        PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
 209
 210        if ((len = skb->len) < RUNT)
 211                len = RUNT;
 212
 213        spin_lock_irqsave(&de600_lock, flags);
 214        select_nic();
 215        tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
 216        tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
 217
 218        if(check_lost)
 219        {
 220                /* This costs about 40 instructions per packet... */
 221                de600_setup_address(NODE_ADDRESS, RW_ADDR);
 222                de600_read_byte(READ_DATA, dev);
 223                if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
 224                        if (adapter_init(dev)) {
 225                                spin_unlock_irqrestore(&de600_lock, flags);
 226                                return 1;
 227                        }
 228                }
 229        }
 230
 231        de600_setup_address(transmit_from, RW_ADDR);
 232        for (i = 0;  i < skb->len ; ++i, ++buffer)
 233                de600_put_byte(*buffer);
 234        for (; i < len; ++i)
 235                de600_put_byte(0);
 236
 237        if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
 238                dev->trans_start = jiffies;
 239                netif_start_queue(dev); /* allow more packets into adapter */
 240                /* Send page and generate a faked interrupt */
 241                de600_setup_address(transmit_from, TX_ADDR);
 242                de600_put_command(TX_ENABLE);
 243        }
 244        else {
 245                if (free_tx_pages)
 246                        netif_start_queue(dev);
 247                else
 248                        netif_stop_queue(dev);
 249                select_prn();
 250        }
 251        spin_unlock_irqrestore(&de600_lock, flags);
 252        dev_kfree_skb(skb);
 253        return 0;
 254}
 255
 256/*
 257 * The typical workload of the driver:
 258 * Handle the network interface interrupts.
 259 */
 260
 261static irqreturn_t de600_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 262{
 263        struct net_device       *dev = dev_id;
 264        u8              irq_status;
 265        int             retrig = 0;
 266        int             boguscount = 0;
 267
 268        /* This might just as well be deleted now, no crummy drivers present :-) */
 269        if ((dev == NULL) || (DE600_IRQ != irq)) {
 270                printk(KERN_ERR "%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
 271                return IRQ_NONE;
 272        }
 273
 274        spin_lock(&de600_lock);
 275        
 276        select_nic();
 277        irq_status = de600_read_status(dev);
 278
 279        do {
 280                PRINTK(("de600_interrupt (%02X)\n", irq_status));
 281
 282                if (irq_status & RX_GOOD)
 283                        de600_rx_intr(dev);
 284                else if (!(irq_status & RX_BUSY))
 285                        de600_put_command(RX_ENABLE);
 286
 287                /* Any transmission in progress? */
 288                if (free_tx_pages < TX_PAGES)
 289                        retrig = de600_tx_intr(dev, irq_status);
 290                else
 291                        retrig = 0;
 292
 293                irq_status = de600_read_status(dev);
 294        } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
 295        /*
 296         * Yeah, it _looks_ like busy waiting, smells like busy waiting
 297         * and I know it's not PC, but please, it will only occur once
 298         * in a while and then only for a loop or so (< 1ms for sure!)
 299         */
 300
 301        /* Enable adapter interrupts */
 302        select_prn();
 303        if (retrig)
 304                trigger_interrupt(dev);
 305        spin_unlock(&de600_lock);
 306        return IRQ_HANDLED;
 307}
 308
 309static int de600_tx_intr(struct net_device *dev, int irq_status)
 310{
 311        /*
 312         * Returns 1 if tx still not done
 313         */
 314
 315        /* Check if current transmission is done yet */
 316        if (irq_status & TX_BUSY)
 317                return 1; /* tx not done, try again */
 318
 319        /* else */
 320        /* If last transmission OK then bump fifo index */
 321        if (!(irq_status & TX_FAILED16)) {
 322                tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
 323                ++free_tx_pages;
 324                ((struct net_device_stats *)(dev->priv))->tx_packets++;
 325                netif_wake_queue(dev);
 326        }
 327
 328        /* More to send, or resend last packet? */
 329        if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
 330                dev->trans_start = jiffies;
 331                de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
 332                de600_put_command(TX_ENABLE);
 333                return 1;
 334        }
 335        /* else */
 336
 337        return 0;
 338}
 339
 340/*
 341 * We have a good packet, get it out of the adapter.
 342 */
 343static void de600_rx_intr(struct net_device *dev)
 344{
 345        struct sk_buff  *skb;
 346        int             i;
 347        int             read_from;
 348        int             size;
 349        unsigned char   *buffer;
 350
 351        /* Get size of received packet */
 352        size = de600_read_byte(RX_LEN, dev);    /* low byte */
 353        size += (de600_read_byte(RX_LEN, dev) << 8);    /* high byte */
 354        size -= 4;      /* Ignore trailing 4 CRC-bytes */
 355
 356        /* Tell adapter where to store next incoming packet, enable receiver */
 357        read_from = rx_page_adr();
 358        next_rx_page();
 359        de600_put_command(RX_ENABLE);
 360
 361        if ((size < 32)  ||  (size > 1535)) {
 362                printk(KERN_WARNING "%s: Bogus packet size %d.\n", dev->name, size);
 363                if (size > 10000)
 364                        adapter_init(dev);
 365                return;
 366        }
 367
 368        skb = dev_alloc_skb(size+2);
 369        if (skb == NULL) {
 370                printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
 371                return;
 372        }
 373        /* else */
 374
 375        skb->dev = dev;
 376        skb_reserve(skb,2);     /* Align */
 377
 378        /* 'skb->data' points to the start of sk_buff data area. */
 379        buffer = skb_put(skb,size);
 380
 381        /* copy the packet into the buffer */
 382        de600_setup_address(read_from, RW_ADDR);
 383        for (i = size; i > 0; --i, ++buffer)
 384                *buffer = de600_read_byte(READ_DATA, dev);
 385
 386        skb->protocol=eth_type_trans(skb,dev);
 387
 388        netif_rx(skb);
 389
 390        /* update stats */
 391        dev->last_rx = jiffies;
 392        ((struct net_device_stats *)(dev->priv))->rx_packets++; /* count all receives */
 393        ((struct net_device_stats *)(dev->priv))->rx_bytes += size; /* count all received bytes */
 394
 395        /*
 396         * If any worth-while packets have been received, netif_rx()
 397         * will work on them when we get to the tasklets.
 398         */
 399}
 400
 401int __init de600_probe(struct net_device *dev)
 402{
 403        int     i;
 404        static struct net_device_stats de600_netstats;
 405        /*dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);*/
 406
 407        SET_MODULE_OWNER(dev);
 408
 409        printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
 410        /* Alpha testers must have the version number to report bugs. */
 411        if (de600_debug > 1)
 412                printk(version);
 413
 414        /* probe for adapter */
 415        rx_page = 0;
 416        select_nic();
 417        (void)de600_read_status(dev);
 418        de600_put_command(RESET);
 419        de600_put_command(STOP_RESET);
 420        if (de600_read_status(dev) & 0xf0) {
 421                printk(": not at I/O %#3x.\n", DATA_PORT);
 422                return -ENODEV;
 423        }
 424
 425        /*
 426         * Maybe we found one,
 427         * have to check if it is a D-Link DE-600 adapter...
 428         */
 429
 430        /* Get the adapter ethernet address from the ROM */
 431        de600_setup_address(NODE_ADDRESS, RW_ADDR);
 432        for (i = 0; i < ETH_ALEN; i++) {
 433                dev->dev_addr[i] = de600_read_byte(READ_DATA, dev);
 434                dev->broadcast[i] = 0xff;
 435        }
 436
 437        /* Check magic code */
 438        if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
 439                /* OK, install real address */
 440                dev->dev_addr[0] = 0x00;
 441                dev->dev_addr[1] = 0x80;
 442                dev->dev_addr[2] = 0xc8;
 443                dev->dev_addr[3] &= 0x0f;
 444                dev->dev_addr[3] |= 0x70;
 445        } else {
 446                printk(" not identified in the printer port\n");
 447                return -ENODEV;
 448        }
 449
 450        if (!request_region(DE600_IO, 3, "de600")) {
 451                printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO);
 452                return -EBUSY;
 453        }
 454
 455        printk(", Ethernet Address: %02X", dev->dev_addr[0]);
 456        for (i = 1; i < ETH_ALEN; i++)
 457                printk(":%02X",dev->dev_addr[i]);
 458        printk("\n");
 459
 460        /* Initialize the device structure. */
 461        dev->priv = &de600_netstats;
 462
 463        memset(dev->priv, 0, sizeof(struct net_device_stats));
 464        dev->get_stats = get_stats;
 465
 466        dev->open = de600_open;
 467        dev->stop = de600_close;
 468        dev->hard_start_xmit = &de600_start_xmit;
 469
 470        ether_setup(dev);
 471
 472        dev->flags&=~IFF_MULTICAST;
 473
 474        select_prn();
 475        return 0;
 476}
 477
 478static int adapter_init(struct net_device *dev)
 479{
 480        int     i;
 481
 482        select_nic();
 483        rx_page = 0; /* used by RESET */
 484        de600_put_command(RESET);
 485        de600_put_command(STOP_RESET);
 486
 487        /* Check if it is still there... */
 488        /* Get the some bytes of the adapter ethernet address from the ROM */
 489        de600_setup_address(NODE_ADDRESS, RW_ADDR);
 490        de600_read_byte(READ_DATA, dev);
 491        if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
 492            (de600_read_byte(READ_DATA, dev) != 0x15)) {
 493        /* was: if (de600_read_status(dev) & 0xf0) { */
 494                printk("Something has happened to the DE-600!  Please check it and do a new ifconfig!\n");
 495                /* Goodbye, cruel world... */
 496                dev->flags &= ~IFF_UP;
 497                de600_close(dev);
 498                was_down = 1;
 499                netif_stop_queue(dev); /* Transmit busy...  */
 500                return 1; /* failed */
 501        }
 502
 503        if (was_down) {
 504                printk(KERN_INFO "%s: Thanks, I feel much better now!\n", dev->name);
 505                was_down = 0;
 506        }
 507
 508        tx_fifo_in = 0;
 509        tx_fifo_out = 0;
 510        free_tx_pages = TX_PAGES;
 511
 512
 513        /* set the ether address. */
 514        de600_setup_address(NODE_ADDRESS, RW_ADDR);
 515        for (i = 0; i < ETH_ALEN; i++)
 516                de600_put_byte(dev->dev_addr[i]);
 517
 518        /* where to start saving incoming packets */
 519        rx_page = RX_BP | RX_BASE_PAGE;
 520        de600_setup_address(MEM_4K, RW_ADDR);
 521        /* Enable receiver */
 522        de600_put_command(RX_ENABLE);
 523        select_prn();
 524
 525        netif_start_queue(dev);
 526
 527        return 0; /* OK */
 528}
 529
 530static struct net_device de600_dev;
 531
 532static int __init de600_init(void)
 533{
 534        spin_lock_init(&de600_lock);
 535        de600_dev.init = de600_probe;
 536        if (register_netdev(&de600_dev) != 0)
 537                return -EIO;
 538        return 0;
 539}
 540
 541static void __exit de600_exit(void)
 542{
 543        unregister_netdev(&de600_dev);
 544        release_region(DE600_IO, 3);
 545}
 546
 547module_init(de600_init);
 548module_exit(de600_exit);
 549
 550MODULE_LICENSE("GPL");
 551
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.