linux/drivers/net/es3210.c
<<
>>
Prefs
   1/*
   2        es3210.c
   3
   4        Linux driver for Racal-Interlan ES3210 EISA Network Adapter
   5
   6        Copyright (C) 1996, Paul Gortmaker.
   7
   8        This software may be used and distributed according to the terms
   9        of the GNU General Public License, incorporated herein by reference.
  10
  11        Information and Code Sources:
  12
  13        1) The existing myriad of Linux 8390 drivers written by Donald Becker.
  14
  15        2) Once again Russ Nelson's asm packet driver provided additional info.
  16
  17        3) Info for getting IRQ and sh-mem gleaned from the EISA cfg files.
  18           Too bad it doesn't work -- see below.
  19
  20        The ES3210 is an EISA shared memory NS8390 implementation. Note
  21        that all memory copies to/from the board must be 32bit transfers.
  22        Which rules out using eth_io_copy_and_sum() in this driver.
  23
  24        Apparently there are two slightly different revisions of the
  25        card, since there are two distinct EISA cfg files (!rii0101.cfg
  26        and !rii0102.cfg) One has media select in the cfg file and the
  27        other doesn't. Hopefully this will work with either.
  28
  29        That is about all I can tell you about it, having never actually
  30        even seen one of these cards. :)  Try http://www.interlan.com
  31        if you want more info.
  32
  33        Thanks go to Mark Salazar for testing v0.02 of this driver.
  34
  35        Bugs, to-fix, etc:
  36
  37        1) The EISA cfg ports that are *supposed* to have the IRQ and shared
  38           mem values just read 0xff all the time. Hrrmpf. Apparently the
  39           same happens with the packet driver as the code for reading
  40           these registers is disabled there. In the meantime, boot with:
  41           ether=<IRQ>,0,0x<shared_mem_addr>,eth0 to override the IRQ and
  42           shared memory detection. (The i/o port detection is okay.)
  43
  44        2) Module support currently untested. Probably works though.
  45
  46*/
  47
  48static const char version[] =
  49        "es3210.c: Driver revision v0.03, 14/09/96\n";
  50
  51#include <linux/module.h>
  52#include <linux/eisa.h>
  53#include <linux/kernel.h>
  54#include <linux/errno.h>
  55#include <linux/string.h>
  56#include <linux/init.h>
  57#include <linux/netdevice.h>
  58#include <linux/etherdevice.h>
  59
  60#include <asm/io.h>
  61#include <asm/system.h>
  62
  63#include "8390.h"
  64
  65static int es_probe1(struct net_device *dev, int ioaddr);
  66
  67static void es_reset_8390(struct net_device *dev);
  68
  69static void es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page);
  70static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset);
  71static void es_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page);
  72
  73#define ES_START_PG     0x00    /* First page of TX buffer              */
  74#define ES_STOP_PG      0x40    /* Last page +1 of RX ring              */
  75
  76#define ES_IO_EXTENT    0x37    /* The cfg file says 0xc90 -> 0xcc7     */
  77#define ES_ID_PORT      0xc80   /* Same for all EISA cards              */
  78#define ES_SA_PROM      0xc90   /* Start of e'net addr.                 */
  79#define ES_RESET_PORT   0xc84   /* From the packet driver source        */
  80#define ES_NIC_OFFSET   0xca0   /* Hello, the 8390 is *here*            */
  81
  82#define ES_ADDR0        0x02    /* 3 byte vendor prefix                 */
  83#define ES_ADDR1        0x07
  84#define ES_ADDR2        0x01
  85
  86/*
  87 * Two card revisions. EISA ID's are always rev. minor, rev. major,, and
  88 * then the three vendor letters stored in 5 bits each, with an "a" = 1.
  89 * For eg: "rii" = 10010 01001 01001 = 0x4929, which is how the EISA
  90 * config utility determines automagically what config file(s) to use.
  91 */
  92#define ES_EISA_ID1     0x01012949      /* !rii0101.cfg                 */
  93#define ES_EISA_ID2     0x02012949      /* !rii0102.cfg                 */
  94
  95#define ES_CFG1         0xcc0   /* IOPORT(1) --> IOPORT(6) in cfg file  */
  96#define ES_CFG2         0xcc1
  97#define ES_CFG3         0xcc2
  98#define ES_CFG4         0xcc3
  99#define ES_CFG5         0xcc4
 100#define ES_CFG6         0xc84   /* NB: 0xc84 is also "reset" port.      */
 101
 102/*
 103 *      You can OR any of the following bits together and assign it
 104 *      to ES_DEBUG to get verbose driver info during operation.
 105 *      Some of these don't do anything yet.
 106 */
 107
 108#define ES_D_PROBE      0x01
 109#define ES_D_RX_PKT     0x02
 110#define ES_D_TX_PKT     0x04
 111#define ED_D_IRQ        0x08
 112
 113#define ES_DEBUG        0
 114
 115static unsigned char lo_irq_map[] __initdata = {3, 4, 5, 6, 7, 9, 10};
 116static unsigned char hi_irq_map[] __initdata = {11, 12, 0, 14, 0, 0, 0, 15};
 117
 118/*
 119 *      Probe for the card. The best way is to read the EISA ID if it
 120 *      is known. Then we check the prefix of the station address
 121 *      PROM for a match against the Racal-Interlan assigned value.
 122 */
 123
 124static int __init do_es_probe(struct net_device *dev)
 125{
 126        unsigned short ioaddr = dev->base_addr;
 127        int irq = dev->irq;
 128        int mem_start = dev->mem_start;
 129
 130        if (ioaddr > 0x1ff)             /* Check a single specified location. */
 131                return es_probe1(dev, ioaddr);
 132        else if (ioaddr > 0)            /* Don't probe at all. */
 133                return -ENXIO;
 134
 135        if (!EISA_bus) {
 136#if ES_DEBUG & ES_D_PROBE
 137                printk("es3210.c: Not EISA bus. Not probing high ports.\n");
 138#endif
 139                return -ENXIO;
 140        }
 141
 142        /* EISA spec allows for up to 16 slots, but 8 is typical. */
 143        for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
 144                if (es_probe1(dev, ioaddr) == 0)
 145                        return 0;
 146                dev->irq = irq;
 147                dev->mem_start = mem_start;
 148        }
 149
 150        return -ENODEV;
 151}
 152
 153#ifndef MODULE
 154struct net_device * __init es_probe(int unit)
 155{
 156        struct net_device *dev = alloc_ei_netdev();
 157        int err;
 158
 159        if (!dev)
 160                return ERR_PTR(-ENOMEM);
 161
 162        sprintf(dev->name, "eth%d", unit);
 163        netdev_boot_setup_check(dev);
 164
 165        err = do_es_probe(dev);
 166        if (err)
 167                goto out;
 168        return dev;
 169out:
 170        free_netdev(dev);
 171        return ERR_PTR(err);
 172}
 173#endif
 174
 175static int __init es_probe1(struct net_device *dev, int ioaddr)
 176{
 177        int i, retval;
 178        unsigned long eisa_id;
 179
 180        if (!request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210"))
 181                return -ENODEV;
 182
 183#if ES_DEBUG & ES_D_PROBE
 184        printk("es3210.c: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + ES_ID_PORT));
 185        printk("es3210.c: config regs: %#x %#x %#x %#x %#x %#x\n",
 186                inb(ioaddr + ES_CFG1), inb(ioaddr + ES_CFG2), inb(ioaddr + ES_CFG3),
 187                inb(ioaddr + ES_CFG4), inb(ioaddr + ES_CFG5), inb(ioaddr + ES_CFG6));
 188#endif
 189
 190/*      Check the EISA ID of the card. */
 191        eisa_id = inl(ioaddr + ES_ID_PORT);
 192        if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) {
 193                retval = -ENODEV;
 194                goto out;
 195        }
 196
 197        for (i = 0; i < ETHER_ADDR_LEN ; i++)
 198                dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i);
 199
 200/*      Check the Racal vendor ID as well. */
 201        if (dev->dev_addr[0] != ES_ADDR0 ||
 202            dev->dev_addr[1] != ES_ADDR1 ||
 203            dev->dev_addr[2] != ES_ADDR2) {
 204                printk("es3210.c: card not found %pM (invalid_prefix).\n",
 205                       dev->dev_addr);
 206                retval = -ENODEV;
 207                goto out;
 208        }
 209
 210        printk("es3210.c: ES3210 rev. %ld at %#x, node %pM",
 211               eisa_id>>24, ioaddr, dev->dev_addr);
 212
 213        /* Snarf the interrupt now. */
 214        if (dev->irq == 0) {
 215                unsigned char hi_irq = inb(ioaddr + ES_CFG2) & 0x07;
 216                unsigned char lo_irq = inb(ioaddr + ES_CFG1) & 0xfe;
 217
 218                if (hi_irq != 0) {
 219                        dev->irq = hi_irq_map[hi_irq - 1];
 220                } else {
 221                        int i = 0;
 222                        while (lo_irq > (1<<i)) i++;
 223                        dev->irq = lo_irq_map[i];
 224                }
 225                printk(" using IRQ %d", dev->irq);
 226#if ES_DEBUG & ES_D_PROBE
 227                printk("es3210.c: hi_irq %#x, lo_irq %#x, dev->irq = %d\n",
 228                                        hi_irq, lo_irq, dev->irq);
 229#endif
 230        } else {
 231                if (dev->irq == 2)
 232                        dev->irq = 9;                   /* Doh! */
 233                printk(" assigning IRQ %d", dev->irq);
 234        }
 235
 236        if (request_irq(dev->irq, ei_interrupt, 0, "es3210", dev)) {
 237                printk (" unable to get IRQ %d.\n", dev->irq);
 238                retval = -EAGAIN;
 239                goto out;
 240        }
 241
 242        if (dev->mem_start == 0) {
 243                unsigned char mem_enabled = inb(ioaddr + ES_CFG2) & 0xc0;
 244                unsigned char mem_bits = inb(ioaddr + ES_CFG3) & 0x07;
 245
 246                if (mem_enabled != 0x80) {
 247                        printk(" shared mem disabled - giving up\n");
 248                        retval = -ENXIO;
 249                        goto out1;
 250                }
 251                dev->mem_start = 0xC0000 + mem_bits*0x4000;
 252                printk(" using ");
 253        } else {
 254                printk(" assigning ");
 255        }
 256
 257        ei_status.mem = ioremap(dev->mem_start, (ES_STOP_PG - ES_START_PG)*256);
 258        if (!ei_status.mem) {
 259                printk("ioremap failed - giving up\n");
 260                retval = -ENXIO;
 261                goto out1;
 262        }
 263
 264        dev->mem_end = dev->mem_start + (ES_STOP_PG - ES_START_PG)*256;
 265
 266        printk("mem %#lx-%#lx\n", dev->mem_start, dev->mem_end-1);
 267
 268#if ES_DEBUG & ES_D_PROBE
 269        if (inb(ioaddr + ES_CFG5))
 270                printk("es3210: Warning - DMA channel enabled, but not used here.\n");
 271#endif
 272        /* Note, point at the 8390, and not the card... */
 273        dev->base_addr = ioaddr + ES_NIC_OFFSET;
 274
 275        ei_status.name = "ES3210";
 276        ei_status.tx_start_page = ES_START_PG;
 277        ei_status.rx_start_page = ES_START_PG + TX_PAGES;
 278        ei_status.stop_page = ES_STOP_PG;
 279        ei_status.word16 = 1;
 280
 281        if (ei_debug > 0)
 282                printk(version);
 283
 284        ei_status.reset_8390 = &es_reset_8390;
 285        ei_status.block_input = &es_block_input;
 286        ei_status.block_output = &es_block_output;
 287        ei_status.get_8390_hdr = &es_get_8390_hdr;
 288
 289        dev->netdev_ops = &ei_netdev_ops;
 290        NS8390_init(dev, 0);
 291
 292        retval = register_netdev(dev);
 293        if (retval)
 294                goto out1;
 295        return 0;
 296out1:
 297        free_irq(dev->irq, dev);
 298out:
 299        release_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT);
 300        return retval;
 301}
 302
 303/*
 304 *      Reset as per the packet driver method. Judging by the EISA cfg
 305 *      file, this just toggles the "Board Enable" bits (bit 2 and 0).
 306 */
 307
 308static void es_reset_8390(struct net_device *dev)
 309{
 310        unsigned short ioaddr = dev->base_addr;
 311        unsigned long end;
 312
 313        outb(0x04, ioaddr + ES_RESET_PORT);
 314        if (ei_debug > 1) printk("%s: resetting the ES3210...", dev->name);
 315
 316        end = jiffies + 2*HZ/100;
 317        while ((signed)(end - jiffies) > 0) continue;
 318
 319        ei_status.txing = 0;
 320        outb(0x01, ioaddr + ES_RESET_PORT);
 321        if (ei_debug > 1) printk("reset done\n");
 322
 323        return;
 324}
 325
 326/*
 327 *      Note: In the following three functions is the implicit assumption
 328 *      that the associated memcpy will only use "rep; movsl" as long as
 329 *      we keep the counts as some multiple of doublewords. This is a
 330 *      requirement of the hardware, and also prevents us from using
 331 *      eth_io_copy_and_sum() since we can't guarantee it will limit
 332 *      itself to doubleword access.
 333 */
 334
 335/*
 336 *      Grab the 8390 specific header. Similar to the block_input routine, but
 337 *      we don't need to be concerned with ring wrap as the header will be at
 338 *      the start of a page, so we optimize accordingly. (A single doubleword.)
 339 */
 340
 341static void
 342es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 343{
 344        void __iomem *hdr_start = ei_status.mem + ((ring_page - ES_START_PG)<<8);
 345        memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 346        hdr->count = (hdr->count + 3) & ~3;     /* Round up allocation. */
 347}
 348
 349/*
 350 *      Block input and output are easy on shared memory ethercards, the only
 351 *      complication is when the ring buffer wraps. The count will already
 352 *      be rounded up to a doubleword value via es_get_8390_hdr() above.
 353 */
 354
 355static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb,
 356                                                  int ring_offset)
 357{
 358        void __iomem *xfer_start = ei_status.mem + ring_offset - ES_START_PG*256;
 359
 360        if (ring_offset + count > ES_STOP_PG*256) {
 361                /* Packet wraps over end of ring buffer. */
 362                int semi_count = ES_STOP_PG*256 - ring_offset;
 363                memcpy_fromio(skb->data, xfer_start, semi_count);
 364                count -= semi_count;
 365                memcpy_fromio(skb->data + semi_count, ei_status.mem, count);
 366        } else {
 367                /* Packet is in one chunk. */
 368                memcpy_fromio(skb->data, xfer_start, count);
 369        }
 370}
 371
 372static void es_block_output(struct net_device *dev, int count,
 373                                const unsigned char *buf, int start_page)
 374{
 375        void __iomem *shmem = ei_status.mem + ((start_page - ES_START_PG)<<8);
 376
 377        count = (count + 3) & ~3;     /* Round up to doubleword */
 378        memcpy_toio(shmem, buf, count);
 379}
 380
 381#ifdef MODULE
 382#define MAX_ES_CARDS    4       /* Max number of ES3210 cards per module */
 383#define NAMELEN         8       /* # of chars for storing dev->name */
 384static struct net_device *dev_es3210[MAX_ES_CARDS];
 385static int io[MAX_ES_CARDS];
 386static int irq[MAX_ES_CARDS];
 387static int mem[MAX_ES_CARDS];
 388
 389module_param_array(io, int, NULL, 0);
 390module_param_array(irq, int, NULL, 0);
 391module_param_array(mem, int, NULL, 0);
 392MODULE_PARM_DESC(io, "I/O base address(es)");
 393MODULE_PARM_DESC(irq, "IRQ number(s)");
 394MODULE_PARM_DESC(mem, "memory base address(es)");
 395MODULE_DESCRIPTION("Racal-Interlan ES3210 EISA ethernet driver");
 396MODULE_LICENSE("GPL");
 397
 398int __init init_module(void)
 399{
 400        struct net_device *dev;
 401        int this_dev, found = 0;
 402
 403        for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
 404                if (io[this_dev] == 0 && this_dev != 0)
 405                        break;
 406                dev = alloc_ei_netdev();
 407                if (!dev)
 408                        break;
 409                dev->irq = irq[this_dev];
 410                dev->base_addr = io[this_dev];
 411                dev->mem_start = mem[this_dev];
 412                if (do_es_probe(dev) == 0) {
 413                        dev_es3210[found++] = dev;
 414                        continue;
 415                }
 416                free_netdev(dev);
 417                printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]);
 418                break;
 419        }
 420        if (found)
 421                return 0;
 422        return -ENXIO;
 423}
 424
 425static void cleanup_card(struct net_device *dev)
 426{
 427        free_irq(dev->irq, dev);
 428        release_region(dev->base_addr, ES_IO_EXTENT);
 429        iounmap(ei_status.mem);
 430}
 431
 432void __exit
 433cleanup_module(void)
 434{
 435        int this_dev;
 436
 437        for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
 438                struct net_device *dev = dev_es3210[this_dev];
 439                if (dev) {
 440                        unregister_netdev(dev);
 441                        cleanup_card(dev);
 442                        free_netdev(dev);
 443                }
 444        }
 445}
 446#endif /* MODULE */
 447
 448