linux/drivers/net/ac3200.c
<<
>>
Prefs
   1/* ac3200.c: A driver for the Ansel Communications EISA ethernet adaptor. */
   2/*
   3        Written 1993, 1994 by Donald Becker.
   4        Copyright 1993 United States Government as represented by the Director,
   5        National Security Agency.  This software may only be used and distributed
   6        according to the terms of the GNU General Public License as modified by SRC,
   7        incorporated herein by reference.
   8
   9        The author may be reached as becker@scyld.com, or C/O
  10        Scyld Computing Corporation
  11        410 Severn Ave., Suite 210
  12        Annapolis MD 21403
  13
  14        This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN
  15        Adapter.  The programming information is from the users manual, as related
  16        by glee@ardnassak.math.clemson.edu.
  17
  18        Changelog:
  19
  20        Paul Gortmaker 05/98    : add support for shared mem above 1MB.
  21
  22  */
  23
  24static const char version[] =
  25        "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
  26
  27#include <linux/module.h>
  28#include <linux/eisa.h>
  29#include <linux/kernel.h>
  30#include <linux/errno.h>
  31#include <linux/string.h>
  32#include <linux/netdevice.h>
  33#include <linux/etherdevice.h>
  34#include <linux/init.h>
  35
  36#include <asm/system.h>
  37#include <asm/io.h>
  38#include <asm/irq.h>
  39
  40#include "8390.h"
  41
  42#define DRV_NAME        "ac3200"
  43
  44/* Offsets from the base address. */
  45#define AC_NIC_BASE     0x00
  46#define AC_SA_PROM      0x16                    /* The station address PROM. */
  47#define AC_ADDR0        0x00                    /* Prefix station address values. */
  48#define AC_ADDR1        0x40
  49#define AC_ADDR2        0x90
  50#define AC_ID_PORT      0xC80
  51#define AC_EISA_ID      0x0110d305
  52#define AC_RESET_PORT   0xC84
  53#define AC_RESET        0x00
  54#define AC_ENABLE       0x01
  55#define AC_CONFIG       0xC90   /* The configuration port. */
  56
  57#define AC_IO_EXTENT 0x20
  58                                /* Actually accessed is:
  59                                                                 * AC_NIC_BASE (0-15)
  60                                                                 * AC_SA_PROM (0-5)
  61                                                                 * AC_ID_PORT (0-3)
  62                                                                 * AC_RESET_PORT
  63                                                                 * AC_CONFIG
  64                                                                 */
  65
  66/* Decoding of the configuration register. */
  67static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
  68static int addrmap[8] =
  69{0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000,  0xD0000, 0 };
  70static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
  71
  72#define config2irq(configval)   config2irqmap[((configval) >> 3) & 7]
  73#define config2mem(configval)   addrmap[(configval) & 7]
  74#define config2name(configval)  port_name[((configval) >> 6) & 3]
  75
  76/* First and last 8390 pages. */
  77#define AC_START_PG             0x00    /* First page of 8390 TX buffer */
  78#define AC_STOP_PG              0x80    /* Last page +1 of the 8390 RX ring */
  79
  80static int ac_probe1(int ioaddr, struct net_device *dev);
  81
  82static int ac_open(struct net_device *dev);
  83static void ac_reset_8390(struct net_device *dev);
  84static void ac_block_input(struct net_device *dev, int count,
  85                                        struct sk_buff *skb, int ring_offset);
  86static void ac_block_output(struct net_device *dev, const int count,
  87                                                        const unsigned char *buf, const int start_page);
  88static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
  89                                        int ring_page);
  90
  91static int ac_close_card(struct net_device *dev);
  92
  93
  94/*      Probe for the AC3200.
  95
  96        The AC3200 can be identified by either the EISA configuration registers,
  97        or the unique value in the station address PROM.
  98        */
  99
 100static int __init do_ac3200_probe(struct net_device *dev)
 101{
 102        unsigned short ioaddr = dev->base_addr;
 103        int irq = dev->irq;
 104        int mem_start = dev->mem_start;
 105
 106        if (ioaddr > 0x1ff)             /* Check a single specified location. */
 107                return ac_probe1(ioaddr, dev);
 108        else if (ioaddr > 0)            /* Don't probe at all. */
 109                return -ENXIO;
 110
 111        if ( ! EISA_bus)
 112                return -ENXIO;
 113
 114        for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
 115                if (ac_probe1(ioaddr, dev) == 0)
 116                        return 0;
 117                dev->irq = irq;
 118                dev->mem_start = mem_start;
 119        }
 120
 121        return -ENODEV;
 122}
 123
 124#ifndef MODULE
 125struct net_device * __init ac3200_probe(int unit)
 126{
 127        struct net_device *dev = alloc_ei_netdev();
 128        int err;
 129
 130        if (!dev)
 131                return ERR_PTR(-ENOMEM);
 132
 133        sprintf(dev->name, "eth%d", unit);
 134        netdev_boot_setup_check(dev);
 135
 136        err = do_ac3200_probe(dev);
 137        if (err)
 138                goto out;
 139        return dev;
 140out:
 141        free_netdev(dev);
 142        return ERR_PTR(err);
 143}
 144#endif
 145
 146static const struct net_device_ops ac_netdev_ops = {
 147        .ndo_open               = ac_open,
 148        .ndo_stop               = ac_close_card,
 149
 150        .ndo_start_xmit         = ei_start_xmit,
 151        .ndo_tx_timeout         = ei_tx_timeout,
 152        .ndo_get_stats          = ei_get_stats,
 153        .ndo_set_multicast_list = ei_set_multicast_list,
 154        .ndo_validate_addr      = eth_validate_addr,
 155        .ndo_set_mac_address    = eth_mac_addr,
 156        .ndo_change_mtu         = eth_change_mtu,
 157#ifdef CONFIG_NET_POLL_CONTROLLER
 158        .ndo_poll_controller    = ei_poll,
 159#endif
 160};
 161
 162static int __init ac_probe1(int ioaddr, struct net_device *dev)
 163{
 164        int i, retval;
 165
 166        if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME))
 167                return -EBUSY;
 168
 169        if (inb_p(ioaddr + AC_ID_PORT) == 0xff) {
 170                retval = -ENODEV;
 171                goto out;
 172        }
 173
 174        if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
 175                retval = -ENODEV;
 176                goto out;
 177        }
 178
 179#ifndef final_version
 180        printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x,"
 181                   " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
 182                   inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
 183                   inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
 184#endif
 185
 186        for (i = 0; i < 6; i++)
 187                dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i);
 188
 189        printk(KERN_DEBUG "AC3200 in EISA slot %d, node %pM",
 190               ioaddr/0x1000, dev->dev_addr);
 191#if 0
 192        /* Check the vendor ID/prefix. Redundant after checking the EISA ID */
 193        if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
 194                || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
 195                || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
 196                printk(", not found (invalid prefix).\n");
 197                retval = -ENODEV;
 198                goto out;
 199        }
 200#endif
 201
 202        /* Assign and allocate the interrupt now. */
 203        if (dev->irq == 0) {
 204                dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
 205                printk(", using");
 206        } else {
 207                dev->irq = irq_canonicalize(dev->irq);
 208                printk(", assigning");
 209        }
 210
 211        retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
 212        if (retval) {
 213                printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
 214                goto out1;
 215        }
 216
 217        printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]);
 218
 219        dev->base_addr = ioaddr;
 220
 221#ifdef notyet
 222        if (dev->mem_start)     {               /* Override the value from the board. */
 223                for (i = 0; i < 7; i++)
 224                        if (addrmap[i] == dev->mem_start)
 225                                break;
 226                if (i >= 7)
 227                        i = 0;
 228                outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
 229        }
 230#endif
 231
 232        dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
 233        dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
 234
 235        printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n",
 236                        dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start);
 237
 238        /*
 239         *  BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
 240         *  the card mem within the region covered by `normal' RAM  !!!
 241         *
 242         *  ioremap() will fail in that case.
 243         */
 244        ei_status.mem = ioremap(dev->mem_start, AC_STOP_PG*0x100);
 245        if (!ei_status.mem) {
 246                printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
 247                printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
 248                printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
 249                retval = -EINVAL;
 250                goto out1;
 251        }
 252        printk("ac3200.c: remapped %dkB card memory to virtual address %p\n",
 253                        AC_STOP_PG/4, ei_status.mem);
 254
 255        dev->mem_start = (unsigned long)ei_status.mem;
 256        dev->mem_end = dev->mem_start + (AC_STOP_PG - AC_START_PG)*256;
 257
 258        ei_status.name = "AC3200";
 259        ei_status.tx_start_page = AC_START_PG;
 260        ei_status.rx_start_page = AC_START_PG + TX_PAGES;
 261        ei_status.stop_page = AC_STOP_PG;
 262        ei_status.word16 = 1;
 263
 264        if (ei_debug > 0)
 265                printk(version);
 266
 267        ei_status.reset_8390 = &ac_reset_8390;
 268        ei_status.block_input = &ac_block_input;
 269        ei_status.block_output = &ac_block_output;
 270        ei_status.get_8390_hdr = &ac_get_8390_hdr;
 271
 272        dev->netdev_ops = &ac_netdev_ops;
 273        NS8390_init(dev, 0);
 274
 275        retval = register_netdev(dev);
 276        if (retval)
 277                goto out2;
 278        return 0;
 279out2:
 280        if (ei_status.reg0)
 281                iounmap(ei_status.mem);
 282out1:
 283        free_irq(dev->irq, dev);
 284out:
 285        release_region(ioaddr, AC_IO_EXTENT);
 286        return retval;
 287}
 288
 289static int ac_open(struct net_device *dev)
 290{
 291#ifdef notyet
 292        /* Someday we may enable the IRQ and shared memory here. */
 293        int ioaddr = dev->base_addr;
 294#endif
 295
 296        ei_open(dev);
 297        return 0;
 298}
 299
 300static void ac_reset_8390(struct net_device *dev)
 301{
 302        ushort ioaddr = dev->base_addr;
 303
 304        outb(AC_RESET, ioaddr + AC_RESET_PORT);
 305        if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
 306
 307        ei_status.txing = 0;
 308        outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
 309        if (ei_debug > 1) printk("reset done\n");
 310
 311        return;
 312}
 313
 314/* Grab the 8390 specific header. Similar to the block_input routine, but
 315   we don't need to be concerned with ring wrap as the header will be at
 316   the start of a page, so we optimize accordingly. */
 317
 318static void
 319ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 320{
 321        void __iomem *hdr_start = ei_status.mem + ((ring_page - AC_START_PG)<<8);
 322        memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 323}
 324
 325/*  Block input and output are easy on shared memory ethercards, the only
 326        complication is when the ring buffer wraps. */
 327
 328static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb,
 329                                                  int ring_offset)
 330{
 331        void __iomem *start = ei_status.mem + ring_offset - AC_START_PG*256;
 332
 333        if (ring_offset + count > AC_STOP_PG*256) {
 334                /* We must wrap the input move. */
 335                int semi_count = AC_STOP_PG*256 - ring_offset;
 336                memcpy_fromio(skb->data, start, semi_count);
 337                count -= semi_count;
 338                memcpy_fromio(skb->data + semi_count,
 339                                ei_status.mem + TX_PAGES*256, count);
 340        } else {
 341                memcpy_fromio(skb->data, start, count);
 342        }
 343}
 344
 345static void ac_block_output(struct net_device *dev, int count,
 346                                                        const unsigned char *buf, int start_page)
 347{
 348        void __iomem *shmem = ei_status.mem + ((start_page - AC_START_PG)<<8);
 349
 350        memcpy_toio(shmem, buf, count);
 351}
 352
 353static int ac_close_card(struct net_device *dev)
 354{
 355        if (ei_debug > 1)
 356                printk("%s: Shutting down ethercard.\n", dev->name);
 357
 358#ifdef notyet
 359        /* We should someday disable shared memory and interrupts. */
 360        outb(0x00, ioaddr + 6); /* Disable interrupts. */
 361        free_irq(dev->irq, dev);
 362#endif
 363
 364        ei_close(dev);
 365        return 0;
 366}
 367
 368#ifdef MODULE
 369#define MAX_AC32_CARDS  4       /* Max number of AC32 cards per module */
 370static struct net_device *dev_ac32[MAX_AC32_CARDS];
 371static int io[MAX_AC32_CARDS];
 372static int irq[MAX_AC32_CARDS];
 373static int mem[MAX_AC32_CARDS];
 374module_param_array(io, int, NULL, 0);
 375module_param_array(irq, int, NULL, 0);
 376module_param_array(mem, int, NULL, 0);
 377MODULE_PARM_DESC(io, "I/O base address(es)");
 378MODULE_PARM_DESC(irq, "IRQ number(s)");
 379MODULE_PARM_DESC(mem, "Memory base address(es)");
 380MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver");
 381MODULE_LICENSE("GPL");
 382
 383static int __init ac3200_module_init(void)
 384{
 385        struct net_device *dev;
 386        int this_dev, found = 0;
 387
 388        for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
 389                if (io[this_dev] == 0 && this_dev != 0)
 390                        break;
 391                dev = alloc_ei_netdev();
 392                if (!dev)
 393                        break;
 394                dev->irq = irq[this_dev];
 395                dev->base_addr = io[this_dev];
 396                dev->mem_start = mem[this_dev];         /* Currently ignored by driver */
 397                if (do_ac3200_probe(dev) == 0) {
 398                        dev_ac32[found++] = dev;
 399                        continue;
 400                }
 401                free_netdev(dev);
 402                printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
 403                break;
 404        }
 405        if (found)
 406                return 0;
 407        return -ENXIO;
 408}
 409
 410static void cleanup_card(struct net_device *dev)
 411{
 412        /* Someday free_irq may be in ac_close_card() */
 413        free_irq(dev->irq, dev);
 414        release_region(dev->base_addr, AC_IO_EXTENT);
 415        iounmap(ei_status.mem);
 416}
 417
 418static void __exit ac3200_module_exit(void)
 419{
 420        int this_dev;
 421
 422        for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
 423                struct net_device *dev = dev_ac32[this_dev];
 424                if (dev) {
 425                        unregister_netdev(dev);
 426                        cleanup_card(dev);
 427                        free_netdev(dev);
 428                }
 429        }
 430}
 431module_init(ac3200_module_init);
 432module_exit(ac3200_module_exit);
 433#endif /* MODULE */
 434