linux/drivers/net/ethernet/8390/e2100.c
<<
>>
Prefs
   1/* e2100.c: A Cabletron E2100 series ethernet driver for linux. */
   2/*
   3        Written 1993-1994 by Donald Becker.
   4
   5        Copyright 1994 by Donald Becker.
   6        Copyright 1993 United States Government as represented by the
   7        Director, National Security Agency.  This software may be used and
   8        distributed according to the terms of the GNU General Public License,
   9        incorporated herein by reference.
  10
  11        This is a driver for the Cabletron E2100 series ethercards.
  12
  13        The Author may be reached as becker@scyld.com, or C/O
  14        Scyld Computing Corporation
  15        410 Severn Ave., Suite 210
  16        Annapolis MD 21403
  17
  18        The E2100 series ethercard is a fairly generic shared memory 8390
  19        implementation.  The only unusual aspect is the way the shared memory
  20        registers are set: first you do an inb() in what is normally the
  21        station address region, and the low three bits of next outb() *address*
  22        is used as the write value for that register.  Either someone wasn't
  23        too used to dem bit en bites, or they were trying to obfuscate the
  24        programming interface.
  25
  26        There is an additional complication when setting the window on the packet
  27        buffer.  You must first do a read into the packet buffer region with the
  28        low 8 address bits the address setting the page for the start of the packet
  29        buffer window, and then do the above operation.  See mem_on() for details.
  30
  31        One bug on the chip is that even a hard reset won't disable the memory
  32        window, usually resulting in a hung machine if mem_off() isn't called.
  33        If this happens, you must power down the machine for about 30 seconds.
  34*/
  35
  36static const char version[] =
  37        "e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
  38
  39#include <linux/module.h>
  40#include <linux/kernel.h>
  41#include <linux/errno.h>
  42#include <linux/string.h>
  43#include <linux/ioport.h>
  44#include <linux/netdevice.h>
  45#include <linux/etherdevice.h>
  46#include <linux/init.h>
  47#include <linux/interrupt.h>
  48#include <linux/delay.h>
  49
  50#include <asm/io.h>
  51#include <asm/system.h>
  52
  53#include "8390.h"
  54
  55#define DRV_NAME "e2100"
  56
  57static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
  58
  59/* Offsets from the base_addr.
  60   Read from the ASIC register, and the low three bits of the next outb()
  61   address is used to set the corresponding register. */
  62#define E21_NIC_OFFSET  0               /* Offset to the 8390 NIC. */
  63#define E21_ASIC                0x10
  64#define E21_MEM_ENABLE  0x10
  65#define  E21_MEM_ON             0x05    /* Enable memory in 16 bit mode. */
  66#define  E21_MEM_ON_8   0x07    /* Enable memory in  8 bit mode. */
  67#define E21_MEM_BASE    0x11
  68#define E21_IRQ_LOW             0x12    /* The low three bits of the IRQ number. */
  69#define E21_IRQ_HIGH    0x14    /* The high IRQ bit and media select ...  */
  70#define E21_MEDIA               0x14    /* (alias). */
  71#define  E21_ALT_IFPORT 0x02    /* Set to use the other (BNC,AUI) port. */
  72#define  E21_BIG_MEM    0x04    /* Use a bigger (64K) buffer (we don't) */
  73#define E21_SAPROM              0x10    /* Offset to station address data. */
  74#define E21_IO_EXTENT    0x20
  75
  76static inline void mem_on(short port, volatile char __iomem *mem_base,
  77                                                  unsigned char start_page )
  78{
  79        /* This is a little weird: set the shared memory window by doing a
  80           read.  The low address bits specify the starting page. */
  81        readb(mem_base+start_page);
  82        inb(port + E21_MEM_ENABLE);
  83        outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
  84}
  85
  86static inline void mem_off(short port)
  87{
  88        inb(port + E21_MEM_ENABLE);
  89        outb(0x00, port + E21_MEM_ENABLE);
  90}
  91
  92/* In other drivers I put the TX pages first, but the E2100 window circuitry
  93   is designed to have a 4K Tx region last. The windowing circuitry wraps the
  94   window at 0x2fff->0x0000 so that the packets at e.g. 0x2f00 in the RX ring
  95   appear contiguously in the window. */
  96#define E21_RX_START_PG         0x00    /* First page of RX buffer */
  97#define E21_RX_STOP_PG          0x30    /* Last page +1 of RX ring */
  98#define E21_BIG_RX_STOP_PG      0xF0    /* Last page +1 of RX ring */
  99#define E21_TX_START_PG         E21_RX_STOP_PG  /* First page of TX buffer */
 100
 101static int e21_probe1(struct net_device *dev, int ioaddr);
 102
 103static int e21_open(struct net_device *dev);
 104static void e21_reset_8390(struct net_device *dev);
 105static void e21_block_input(struct net_device *dev, int count,
 106                                                   struct sk_buff *skb, int ring_offset);
 107static void e21_block_output(struct net_device *dev, int count,
 108                                                         const unsigned char *buf, int start_page);
 109static void e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
 110                                                        int ring_page);
 111static int e21_open(struct net_device *dev);
 112static int e21_close(struct net_device *dev);
 113
 114
 115/*  Probe for the E2100 series ethercards.  These cards have an 8390 at the
 116        base address and the station address at both offset 0x10 and 0x18.  I read
 117        the station address from offset 0x18 to avoid the dataport of NE2000
 118        ethercards, and look for Ctron's unique ID (first three octets of the
 119        station address).
 120 */
 121
 122static int  __init do_e2100_probe(struct net_device *dev)
 123{
 124        int *port;
 125        int base_addr = dev->base_addr;
 126        int irq = dev->irq;
 127
 128        if (base_addr > 0x1ff)          /* Check a single specified location. */
 129                return e21_probe1(dev, base_addr);
 130        else if (base_addr != 0)        /* Don't probe at all. */
 131                return -ENXIO;
 132
 133        for (port = e21_probe_list; *port; port++) {
 134                dev->irq = irq;
 135                if (e21_probe1(dev, *port) == 0)
 136                        return 0;
 137        }
 138
 139        return -ENODEV;
 140}
 141
 142#ifndef MODULE
 143struct net_device * __init e2100_probe(int unit)
 144{
 145        struct net_device *dev = alloc_ei_netdev();
 146        int err;
 147
 148        if (!dev)
 149                return ERR_PTR(-ENOMEM);
 150
 151        sprintf(dev->name, "eth%d", unit);
 152        netdev_boot_setup_check(dev);
 153
 154        err = do_e2100_probe(dev);
 155        if (err)
 156                goto out;
 157        return dev;
 158out:
 159        free_netdev(dev);
 160        return ERR_PTR(err);
 161}
 162#endif
 163
 164static const struct net_device_ops e21_netdev_ops = {
 165        .ndo_open               = e21_open,
 166        .ndo_stop               = e21_close,
 167
 168        .ndo_start_xmit         = ei_start_xmit,
 169        .ndo_tx_timeout         = ei_tx_timeout,
 170        .ndo_get_stats          = ei_get_stats,
 171        .ndo_set_rx_mode        = ei_set_multicast_list,
 172        .ndo_validate_addr      = eth_validate_addr,
 173        .ndo_set_mac_address    = eth_mac_addr,
 174        .ndo_change_mtu         = eth_change_mtu,
 175#ifdef CONFIG_NET_POLL_CONTROLLER
 176        .ndo_poll_controller    = ei_poll,
 177#endif
 178};
 179
 180static int __init e21_probe1(struct net_device *dev, int ioaddr)
 181{
 182        int i, status, retval;
 183        unsigned char *station_addr = dev->dev_addr;
 184        static unsigned version_printed;
 185
 186        if (!request_region(ioaddr, E21_IO_EXTENT, DRV_NAME))
 187                return -EBUSY;
 188
 189        /* First check the station address for the Ctron prefix. */
 190        if (inb(ioaddr + E21_SAPROM + 0) != 0x00 ||
 191            inb(ioaddr + E21_SAPROM + 1) != 0x00 ||
 192            inb(ioaddr + E21_SAPROM + 2) != 0x1d) {
 193                retval = -ENODEV;
 194                goto out;
 195        }
 196
 197        /* Verify by making certain that there is a 8390 at there. */
 198        outb(E8390_NODMA + E8390_STOP, ioaddr);
 199        udelay(1);      /* we want to delay one I/O cycle - which is 2MHz */
 200        status = inb(ioaddr);
 201        if (status != 0x21 && status != 0x23) {
 202                retval = -ENODEV;
 203                goto out;
 204        }
 205
 206        /* Read the station address PROM.  */
 207        for (i = 0; i < 6; i++)
 208                station_addr[i] = inb(ioaddr + E21_SAPROM + i);
 209
 210        inb(ioaddr + E21_MEDIA);                /* Point to media selection. */
 211        outb(0, ioaddr + E21_ASIC);     /* and disable the secondary interface. */
 212
 213        if (ei_debug  &&  version_printed++ == 0)
 214                printk(version);
 215
 216        for (i = 0; i < 6; i++)
 217                printk(" %02X", station_addr[i]);
 218
 219        if (dev->irq < 2) {
 220                static const int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4};
 221                for (i = 0; i < ARRAY_SIZE(irqlist); i++)
 222                        if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
 223                                dev->irq = irqlist[i];
 224                                break;
 225                        }
 226                if (i >= ARRAY_SIZE(irqlist)) {
 227                        printk(" unable to get IRQ %d.\n", dev->irq);
 228                        retval = -EAGAIN;
 229                        goto out;
 230                }
 231        } else if (dev->irq == 2)       /* Fixup luser bogosity: IRQ2 is really IRQ9 */
 232                dev->irq = 9;
 233
 234        /* The 8390 is at the base address. */
 235        dev->base_addr = ioaddr;
 236
 237        ei_status.name = "E2100";
 238        ei_status.word16 = 1;
 239        ei_status.tx_start_page = E21_TX_START_PG;
 240        ei_status.rx_start_page = E21_RX_START_PG;
 241        ei_status.stop_page = E21_RX_STOP_PG;
 242        ei_status.saved_irq = dev->irq;
 243
 244        /* Check the media port used.  The port can be passed in on the
 245           low mem_end bits. */
 246        if (dev->mem_end & 15)
 247                dev->if_port = dev->mem_end & 7;
 248        else {
 249                dev->if_port = 0;
 250                inb(ioaddr + E21_MEDIA);        /* Turn automatic media detection on. */
 251                for(i = 0; i < 6; i++)
 252                        if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) {
 253                                dev->if_port = 1;
 254                                break;
 255                        }
 256        }
 257
 258        /* Never map in the E21 shared memory unless you are actively using it.
 259           Also, the shared memory has effective only one setting -- spread all
 260           over the 128K region! */
 261        if (dev->mem_start == 0)
 262                dev->mem_start = 0xd0000;
 263
 264        ei_status.mem = ioremap(dev->mem_start, 2*1024);
 265        if (!ei_status.mem) {
 266                printk("unable to remap memory\n");
 267                retval = -EAGAIN;
 268                goto out;
 269        }
 270
 271#ifdef notdef
 272        /* These values are unused.  The E2100 has a 2K window into the packet
 273           buffer.  The window can be set to start on any page boundary. */
 274        ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
 275        dev->mem_end = ei_status.rmem_end = dev->mem_start + 2*1024;
 276#endif
 277
 278        printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq,
 279                   dev->if_port ? "secondary" : "primary", dev->mem_start);
 280
 281        ei_status.reset_8390 = &e21_reset_8390;
 282        ei_status.block_input = &e21_block_input;
 283        ei_status.block_output = &e21_block_output;
 284        ei_status.get_8390_hdr = &e21_get_8390_hdr;
 285
 286        dev->netdev_ops = &e21_netdev_ops;
 287        NS8390_init(dev, 0);
 288
 289        retval = register_netdev(dev);
 290        if (retval)
 291                goto out;
 292        return 0;
 293out:
 294        release_region(ioaddr, E21_IO_EXTENT);
 295        return retval;
 296}
 297
 298static int
 299e21_open(struct net_device *dev)
 300{
 301        short ioaddr = dev->base_addr;
 302        int retval;
 303
 304        if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev)))
 305                return retval;
 306
 307        /* Set the interrupt line and memory base on the hardware. */
 308        inb(ioaddr + E21_IRQ_LOW);
 309        outb(0, ioaddr + E21_ASIC + (dev->irq & 7));
 310        inb(ioaddr + E21_IRQ_HIGH);                     /* High IRQ bit, and if_port. */
 311        outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
 312                   + (dev->if_port ? E21_ALT_IFPORT : 0));
 313        inb(ioaddr + E21_MEM_BASE);
 314        outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
 315
 316        ei_open(dev);
 317        return 0;
 318}
 319
 320static void
 321e21_reset_8390(struct net_device *dev)
 322{
 323        short ioaddr = dev->base_addr;
 324
 325        outb(0x01, ioaddr);
 326        if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies);
 327        ei_status.txing = 0;
 328
 329        /* Set up the ASIC registers, just in case something changed them. */
 330
 331        if (ei_debug > 1) printk("reset done\n");
 332}
 333
 334/* Grab the 8390 specific header. We put the 2k window so the header page
 335   appears at the start of the shared memory. */
 336
 337static void
 338e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 339{
 340
 341        short ioaddr = dev->base_addr;
 342        char __iomem *shared_mem = ei_status.mem;
 343
 344        mem_on(ioaddr, shared_mem, ring_page);
 345
 346#ifdef notdef
 347        /* Officially this is what we are doing, but the readl() is faster */
 348        memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
 349#else
 350        ((unsigned int*)hdr)[0] = readl(shared_mem);
 351#endif
 352
 353        /* Turn off memory access: we would need to reprogram the window anyway. */
 354        mem_off(ioaddr);
 355
 356}
 357
 358/*  Block input and output are easy on shared memory ethercards.
 359        The E21xx makes block_input() especially easy by wrapping the top
 360        ring buffer to the bottom automatically. */
 361static void
 362e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
 363{
 364        short ioaddr = dev->base_addr;
 365        char __iomem *shared_mem = ei_status.mem;
 366
 367        mem_on(ioaddr, shared_mem, (ring_offset>>8));
 368
 369        memcpy_fromio(skb->data, ei_status.mem + (ring_offset & 0xff), count);
 370
 371        mem_off(ioaddr);
 372}
 373
 374static void
 375e21_block_output(struct net_device *dev, int count, const unsigned char *buf,
 376                                 int start_page)
 377{
 378        short ioaddr = dev->base_addr;
 379        volatile char __iomem *shared_mem = ei_status.mem;
 380
 381        /* Set the shared memory window start by doing a read, with the low address
 382           bits specifying the starting page. */
 383        readb(shared_mem + start_page);
 384        mem_on(ioaddr, shared_mem, start_page);
 385
 386        memcpy_toio(shared_mem, buf, count);
 387        mem_off(ioaddr);
 388}
 389
 390static int
 391e21_close(struct net_device *dev)
 392{
 393        short ioaddr = dev->base_addr;
 394
 395        if (ei_debug > 1)
 396                printk("%s: Shutting down ethercard.\n", dev->name);
 397
 398        free_irq(dev->irq, dev);
 399        dev->irq = ei_status.saved_irq;
 400
 401        /* Shut off the interrupt line and secondary interface. */
 402        inb(ioaddr + E21_IRQ_LOW);
 403        outb(0, ioaddr + E21_ASIC);
 404        inb(ioaddr + E21_IRQ_HIGH);                     /* High IRQ bit, and if_port. */
 405        outb(0, ioaddr + E21_ASIC);
 406
 407        ei_close(dev);
 408
 409        /* Double-check that the memory has been turned off, because really
 410           really bad things happen if it isn't. */
 411        mem_off(ioaddr);
 412
 413        return 0;
 414}
 415
 416
 417#ifdef MODULE
 418#define MAX_E21_CARDS   4       /* Max number of E21 cards per module */
 419static struct net_device *dev_e21[MAX_E21_CARDS];
 420static int io[MAX_E21_CARDS];
 421static int irq[MAX_E21_CARDS];
 422static int mem[MAX_E21_CARDS];
 423static int xcvr[MAX_E21_CARDS];         /* choose int. or ext. xcvr */
 424
 425module_param_array(io, int, NULL, 0);
 426module_param_array(irq, int, NULL, 0);
 427module_param_array(mem, int, NULL, 0);
 428module_param_array(xcvr, int, NULL, 0);
 429MODULE_PARM_DESC(io, "I/O base address(es)");
 430MODULE_PARM_DESC(irq, "IRQ number(s)");
 431MODULE_PARM_DESC(mem, " memory base address(es)");
 432MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
 433MODULE_DESCRIPTION("Cabletron E2100 ISA ethernet driver");
 434MODULE_LICENSE("GPL");
 435
 436/* This is set up so that only a single autoprobe takes place per call.
 437ISA device autoprobes on a running machine are not recommended. */
 438
 439int __init init_module(void)
 440{
 441        struct net_device *dev;
 442        int this_dev, found = 0;
 443
 444        for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
 445                if (io[this_dev] == 0)  {
 446                        if (this_dev != 0) break; /* only autoprobe 1st one */
 447                        printk(KERN_NOTICE "e2100.c: Presently autoprobing (not recommended) for a single card.\n");
 448                }
 449                dev = alloc_ei_netdev();
 450                if (!dev)
 451                        break;
 452                dev->irq = irq[this_dev];
 453                dev->base_addr = io[this_dev];
 454                dev->mem_start = mem[this_dev];
 455                dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
 456                if (do_e2100_probe(dev) == 0) {
 457                        dev_e21[found++] = dev;
 458                        continue;
 459                }
 460                free_netdev(dev);
 461                printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
 462                break;
 463        }
 464        if (found)
 465                return 0;
 466        return -ENXIO;
 467}
 468
 469static void cleanup_card(struct net_device *dev)
 470{
 471        /* NB: e21_close() handles free_irq */
 472        iounmap(ei_status.mem);
 473        release_region(dev->base_addr, E21_IO_EXTENT);
 474}
 475
 476void __exit
 477cleanup_module(void)
 478{
 479        int this_dev;
 480
 481        for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
 482                struct net_device *dev = dev_e21[this_dev];
 483                if (dev) {
 484                        unregister_netdev(dev);
 485                        cleanup_card(dev);
 486                        free_netdev(dev);
 487                }
 488        }
 489}
 490#endif /* MODULE */
 491