linux/drivers/net/smc-ultra32.c
<<
>>
Prefs
   1/*      smc-ultra32.c: An SMC Ultra32 EISA ethernet driver for linux.
   2
   3Sources:
   4
   5        This driver is based on (cloned from) the ISA SMC Ultra driver
   6        written by Donald Becker. Modifications to support the EISA
   7        version of the card by Paul Gortmaker and Leonard N. Zubkoff.
   8
   9        This software may be used and distributed according to the terms
  10        of the GNU General Public License, incorporated herein by reference.
  11
  12Theory of Operation:
  13
  14        The SMC Ultra32C card uses the SMC 83c790 chip which is also
  15        found on the ISA SMC Ultra cards. It has a shared memory mode of
  16        operation that makes it similar to the ISA version of the card.
  17        The main difference is that the EISA card has 32KB of RAM, but
  18        only an 8KB window into that memory. The EISA card also can be
  19        set for a bus-mastering mode of operation via the ECU, but that
  20        is not (and probably will never be) supported by this driver.
  21        The ECU should be run to enable shared memory and to disable the
  22        bus-mastering feature for use with linux.
  23
  24        By programming the 8390 to use only 8KB RAM, the modifications
  25        to the ISA driver can be limited to the probe and initialization
  26        code. This allows easy integration of EISA support into the ISA
  27        driver. However, the driver development kit from SMC provided the
  28        register information for sliding the 8KB window, and hence the 8390
  29        is programmed to use the full 32KB RAM.
  30
  31        Unfortunately this required code changes outside the probe/init
  32        routines, and thus we decided to separate the EISA driver from
  33        the ISA one. In this way, ISA users don't end up with a larger
  34        driver due to the EISA code, and EISA users don't end up with a
  35        larger driver due to the ISA EtherEZ PIO code. The driver is
  36        similar to the 3c503/16 driver, in that the window must be set
  37        back to the 1st 8KB of space for access to the two 8390 Tx slots.
  38
  39        In testing, using only 8KB RAM (3 Tx / 5 Rx) didn't appear to
  40        be a limiting factor, since the EISA bus could get packets off
  41        the card fast enough, but having the use of lots of RAM as Rx
  42        space is extra insurance if interrupt latencies become excessive.
  43
  44*/
  45
  46static const char *version = "smc-ultra32.c: 06/97 v1.00\n";
  47
  48
  49#include <linux/module.h>
  50#include <linux/eisa.h>
  51#include <linux/kernel.h>
  52#include <linux/errno.h>
  53#include <linux/string.h>
  54#include <linux/init.h>
  55#include <linux/interrupt.h>
  56#include <linux/netdevice.h>
  57#include <linux/etherdevice.h>
  58
  59#include <asm/io.h>
  60#include <asm/system.h>
  61
  62#include "8390.h"
  63
  64#define DRV_NAME "smc-ultra32"
  65
  66static int ultra32_probe1(struct net_device *dev, int ioaddr);
  67static int ultra32_open(struct net_device *dev);
  68static void ultra32_reset_8390(struct net_device *dev);
  69static void ultra32_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
  70                                 int ring_page);
  71static void ultra32_block_input(struct net_device *dev, int count,
  72                                struct sk_buff *skb, int ring_offset);
  73static void ultra32_block_output(struct net_device *dev, int count,
  74                                 const unsigned char *buf,
  75                                 const int start_page);
  76static int ultra32_close(struct net_device *dev);
  77
  78#define ULTRA32_CMDREG  0       /* Offset to ASIC command register. */
  79#define  ULTRA32_RESET  0x80    /* Board reset, in ULTRA32_CMDREG. */
  80#define  ULTRA32_MEMENB 0x40    /* Enable the shared memory. */
  81#define ULTRA32_NIC_OFFSET 16   /* NIC register offset from the base_addr. */
  82#define ULTRA32_IO_EXTENT 32
  83#define EN0_ERWCNT              0x08    /* Early receive warning count. */
  84
  85/*
  86 * Defines that apply only to the Ultra32 EISA card. Note that
  87 * "smc" = 10011 01101 00011 = 0x4da3, and hence !smc8010.cfg translates
  88 * into an EISA ID of 0x1080A34D
  89 */
  90#define ULTRA32_BASE    0xca0
  91#define ULTRA32_ID      0x1080a34d
  92#define ULTRA32_IDPORT  (-0x20) /* 0xc80 */
  93/* Config regs 1->7 from the EISA !SMC8010.CFG file. */
  94#define ULTRA32_CFG1    0x04    /* 0xca4 */
  95#define ULTRA32_CFG2    0x05    /* 0xca5 */
  96#define ULTRA32_CFG3    (-0x18) /* 0xc88 */
  97#define ULTRA32_CFG4    (-0x17) /* 0xc89 */
  98#define ULTRA32_CFG5    (-0x16) /* 0xc8a */
  99#define ULTRA32_CFG6    (-0x15) /* 0xc8b */
 100#define ULTRA32_CFG7    0x0d    /* 0xcad */
 101
 102static void cleanup_card(struct net_device *dev)
 103{
 104        int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET;
 105        /* NB: ultra32_close_card() does free_irq */
 106        release_region(ioaddr, ULTRA32_IO_EXTENT);
 107        iounmap(ei_status.mem);
 108}
 109
 110/*      Probe for the Ultra32.  This looks like a 8013 with the station
 111        address PROM at I/O ports <base>+8 to <base>+13, with a checksum
 112        following.
 113*/
 114
 115struct net_device * __init ultra32_probe(int unit)
 116{
 117        struct net_device *dev;
 118        int base;
 119        int irq;
 120        int err = -ENODEV;
 121
 122        if (!EISA_bus)
 123                return ERR_PTR(-ENODEV);
 124
 125        dev = alloc_ei_netdev();
 126
 127        if (!dev)
 128                return ERR_PTR(-ENOMEM);
 129
 130        if (unit >= 0) {
 131                sprintf(dev->name, "eth%d", unit);
 132                netdev_boot_setup_check(dev);
 133        }
 134
 135        irq = dev->irq;
 136
 137        /* EISA spec allows for up to 16 slots, but 8 is typical. */
 138        for (base = 0x1000 + ULTRA32_BASE; base < 0x9000; base += 0x1000) {
 139                if (ultra32_probe1(dev, base) == 0)
 140                        break;
 141                dev->irq = irq;
 142        }
 143        if (base >= 0x9000)
 144                goto out;
 145        err = register_netdev(dev);
 146        if (err)
 147                goto out1;
 148        return dev;
 149out1:
 150        cleanup_card(dev);
 151out:
 152        free_netdev(dev);
 153        return ERR_PTR(err);
 154}
 155
 156
 157static const struct net_device_ops ultra32_netdev_ops = {
 158        .ndo_open               = ultra32_open,
 159        .ndo_stop               = ultra32_close,
 160        .ndo_start_xmit         = ei_start_xmit,
 161        .ndo_tx_timeout         = ei_tx_timeout,
 162        .ndo_get_stats          = ei_get_stats,
 163        .ndo_set_multicast_list = ei_set_multicast_list,
 164        .ndo_validate_addr      = eth_validate_addr,
 165        .ndo_set_mac_address    = eth_mac_addr,
 166        .ndo_change_mtu         = eth_change_mtu,
 167#ifdef CONFIG_NET_POLL_CONTROLLER
 168        .ndo_poll_controller    = ei_poll,
 169#endif
 170};
 171
 172static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
 173{
 174        int i, edge, media, retval;
 175        int checksum = 0;
 176        const char *model_name;
 177        static unsigned version_printed;
 178        /* Values from various config regs. */
 179        unsigned char idreg;
 180        unsigned char reg4;
 181        const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"};
 182
 183        if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME))
 184                return -EBUSY;
 185
 186        if (inb(ioaddr + ULTRA32_IDPORT) == 0xff ||
 187            inl(ioaddr + ULTRA32_IDPORT) != ULTRA32_ID) {
 188                retval = -ENODEV;
 189                goto out;
 190        }
 191
 192        media = inb(ioaddr + ULTRA32_CFG7) & 0x03;
 193        edge = inb(ioaddr + ULTRA32_CFG5) & 0x08;
 194        printk("SMC Ultra32 in EISA Slot %d, Media: %s, %s IRQs.\n",
 195                ioaddr >> 12, ifmap[media],
 196                (edge ? "Edge Triggered" : "Level Sensitive"));
 197
 198        idreg = inb(ioaddr + 7);
 199        reg4 = inb(ioaddr + 4) & 0x7f;
 200
 201        /* Check the ID nibble. */
 202        if ((idreg & 0xf0) != 0x20) {                   /* SMC Ultra */
 203                retval = -ENODEV;
 204                goto out;
 205        }
 206
 207        /* Select the station address register set. */
 208        outb(reg4, ioaddr + 4);
 209
 210        for (i = 0; i < 8; i++)
 211                checksum += inb(ioaddr + 8 + i);
 212        if ((checksum & 0xff) != 0xff) {
 213                retval = -ENODEV;
 214                goto out;
 215        }
 216
 217        if (ei_debug  &&  version_printed++ == 0)
 218                printk(version);
 219
 220        model_name = "SMC Ultra32";
 221
 222        for (i = 0; i < 6; i++)
 223                dev->dev_addr[i] = inb(ioaddr + 8 + i);
 224
 225        printk("%s: %s at 0x%X, %pM",
 226               dev->name, model_name, ioaddr, dev->dev_addr);
 227
 228        /* Switch from the station address to the alternate register set and
 229           read the useful registers there. */
 230        outb(0x80 | reg4, ioaddr + 4);
 231
 232        /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */
 233        outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);
 234
 235        /* Reset RAM addr. */
 236        outb(0x00, ioaddr + 0x0b);
 237
 238        /* Switch back to the station address register set so that the
 239           MS-DOS driver can find the card after a warm boot. */
 240        outb(reg4, ioaddr + 4);
 241
 242        if ((inb(ioaddr + ULTRA32_CFG5) & 0x40) == 0) {
 243                printk("\nsmc-ultra32: Card RAM is disabled!  "
 244                       "Run EISA config utility.\n");
 245                retval = -ENODEV;
 246                goto out;
 247        }
 248        if ((inb(ioaddr + ULTRA32_CFG2) & 0x04) == 0)
 249                printk("\nsmc-ultra32: Ignoring Bus-Master enable bit.  "
 250                       "Run EISA config utility.\n");
 251
 252        if (dev->irq < 2) {
 253                unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15};
 254                int irq = irqmap[inb(ioaddr + ULTRA32_CFG5) & 0x07];
 255                if (irq == 0) {
 256                        printk(", failed to detect IRQ line.\n");
 257                        retval = -EAGAIN;
 258                        goto out;
 259                }
 260                dev->irq = irq;
 261        }
 262
 263        /* The 8390 isn't at the base address, so fake the offset */
 264        dev->base_addr = ioaddr + ULTRA32_NIC_OFFSET;
 265
 266        /* Save RAM address in the unused reg0 to avoid excess inb's. */
 267        ei_status.reg0 = inb(ioaddr + ULTRA32_CFG3) & 0xfc;
 268
 269        dev->mem_start =  0xc0000 + ((ei_status.reg0 & 0x7c) << 11);
 270
 271        ei_status.name = model_name;
 272        ei_status.word16 = 1;
 273        ei_status.tx_start_page = 0;
 274        ei_status.rx_start_page = TX_PAGES;
 275        /* All Ultra32 cards have 32KB memory with an 8KB window. */
 276        ei_status.stop_page = 128;
 277
 278        ei_status.mem = ioremap(dev->mem_start, 0x2000);
 279        if (!ei_status.mem) {
 280                printk(", failed to ioremap.\n");
 281                retval = -ENOMEM;
 282                goto out;
 283        }
 284        dev->mem_end = dev->mem_start + 0x1fff;
 285
 286        printk(", IRQ %d, 32KB memory, 8KB window at 0x%lx-0x%lx.\n",
 287               dev->irq, dev->mem_start, dev->mem_end);
 288        ei_status.block_input = &ultra32_block_input;
 289        ei_status.block_output = &ultra32_block_output;
 290        ei_status.get_8390_hdr = &ultra32_get_8390_hdr;
 291        ei_status.reset_8390 = &ultra32_reset_8390;
 292
 293        dev->netdev_ops = &ultra32_netdev_ops;
 294        NS8390_init(dev, 0);
 295
 296        return 0;
 297out:
 298        release_region(ioaddr, ULTRA32_IO_EXTENT);
 299        return retval;
 300}
 301
 302static int ultra32_open(struct net_device *dev)
 303{
 304        int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC addr */
 305        int irq_flags = (inb(ioaddr + ULTRA32_CFG5) & 0x08) ? 0 : IRQF_SHARED;
 306        int retval;
 307
 308        retval = request_irq(dev->irq, ei_interrupt, irq_flags, dev->name, dev);
 309        if (retval)
 310                return retval;
 311
 312        outb(ULTRA32_MEMENB, ioaddr); /* Enable Shared Memory. */
 313        outb(0x80, ioaddr + ULTRA32_CFG6); /* Enable Interrupts. */
 314        outb(0x84, ioaddr + 5); /* Enable MEM16 & Disable Bus Master. */
 315        outb(0x01, ioaddr + 6); /* Enable Interrupts. */
 316        /* Set the early receive warning level in window 0 high enough not
 317           to receive ERW interrupts. */
 318        outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr);
 319        outb(0xff, dev->base_addr + EN0_ERWCNT);
 320        ei_open(dev);
 321        return 0;
 322}
 323
 324static int ultra32_close(struct net_device *dev)
 325{
 326        int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* CMDREG */
 327
 328        netif_stop_queue(dev);
 329
 330        if (ei_debug > 1)
 331                printk("%s: Shutting down ethercard.\n", dev->name);
 332
 333        outb(0x00, ioaddr + ULTRA32_CFG6); /* Disable Interrupts. */
 334        outb(0x00, ioaddr + 6);         /* Disable interrupts. */
 335        free_irq(dev->irq, dev);
 336
 337        NS8390_init(dev, 0);
 338
 339        return 0;
 340}
 341
 342static void ultra32_reset_8390(struct net_device *dev)
 343{
 344        int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC base addr */
 345
 346        outb(ULTRA32_RESET, ioaddr);
 347        if (ei_debug > 1) printk("resetting Ultra32, t=%ld...", jiffies);
 348        ei_status.txing = 0;
 349
 350        outb(ULTRA32_MEMENB, ioaddr); /* Enable Shared Memory. */
 351        outb(0x80, ioaddr + ULTRA32_CFG6); /* Enable Interrupts. */
 352        outb(0x84, ioaddr + 5); /* Enable MEM16 & Disable Bus Master. */
 353        outb(0x01, ioaddr + 6); /* Enable Interrupts. */
 354        if (ei_debug > 1) printk("reset done\n");
 355        return;
 356}
 357
 358/* Grab the 8390 specific header. Similar to the block_input routine, but
 359   we don't need to be concerned with ring wrap as the header will be at
 360   the start of a page, so we optimize accordingly. */
 361
 362static void ultra32_get_8390_hdr(struct net_device *dev,
 363                                 struct e8390_pkt_hdr *hdr,
 364                                 int ring_page)
 365{
 366        void __iomem *hdr_start = ei_status.mem + ((ring_page & 0x1f) << 8);
 367        unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3;
 368
 369        /* Select correct 8KB Window. */
 370        outb(ei_status.reg0 | ((ring_page & 0x60) >> 5), RamReg);
 371
 372#ifdef __BIG_ENDIAN
 373        /* Officially this is what we are doing, but the readl() is faster */
 374        /* unfortunately it isn't endian aware of the struct               */
 375        memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 376        hdr->count = le16_to_cpu(hdr->count);
 377#else
 378        ((unsigned int*)hdr)[0] = readl(hdr_start);
 379#endif
 380}
 381
 382/* Block input and output are easy on shared memory ethercards, the only
 383   complication is when the ring buffer wraps, or in this case, when a
 384   packet spans an 8KB boundary. Note that the current 8KB segment is
 385   already set by the get_8390_hdr routine. */
 386
 387static void ultra32_block_input(struct net_device *dev,
 388                                int count,
 389                                struct sk_buff *skb,
 390                                int ring_offset)
 391{
 392        void __iomem *xfer_start = ei_status.mem + (ring_offset & 0x1fff);
 393        unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3;
 394
 395        if ((ring_offset & ~0x1fff) != ((ring_offset + count - 1) & ~0x1fff)) {
 396                int semi_count = 8192 - (ring_offset & 0x1FFF);
 397                memcpy_fromio(skb->data, xfer_start, semi_count);
 398                count -= semi_count;
 399                if (ring_offset < 96*256) {
 400                        /* Select next 8KB Window. */
 401                        ring_offset += semi_count;
 402                        outb(ei_status.reg0 | ((ring_offset & 0x6000) >> 13), RamReg);
 403                        memcpy_fromio(skb->data + semi_count, ei_status.mem, count);
 404                } else {
 405                        /* Select first 8KB Window. */
 406                        outb(ei_status.reg0, RamReg);
 407                        memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
 408                }
 409        } else {
 410                memcpy_fromio(skb->data, xfer_start, count);
 411        }
 412}
 413
 414static void ultra32_block_output(struct net_device *dev,
 415                                 int count,
 416                                 const unsigned char *buf,
 417                                 int start_page)
 418{
 419        void __iomem *xfer_start = ei_status.mem + (start_page<<8);
 420        unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3;
 421
 422        /* Select first 8KB Window. */
 423        outb(ei_status.reg0, RamReg);
 424
 425        memcpy_toio(xfer_start, buf, count);
 426}
 427
 428#ifdef MODULE
 429#define MAX_ULTRA32_CARDS   4   /* Max number of Ultra cards per module */
 430static struct net_device *dev_ultra[MAX_ULTRA32_CARDS];
 431
 432MODULE_DESCRIPTION("SMC Ultra32 EISA ethernet driver");
 433MODULE_LICENSE("GPL");
 434
 435int __init init_module(void)
 436{
 437        int this_dev, found = 0;
 438
 439        for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) {
 440                struct net_device *dev = ultra32_probe(-1);
 441                if (IS_ERR(dev))
 442                        break;
 443                dev_ultra[found++] = dev;
 444        }
 445        if (found)
 446                return 0;
 447        printk(KERN_WARNING "smc-ultra32.c: No SMC Ultra32 found.\n");
 448        return -ENXIO;
 449}
 450
 451void __exit cleanup_module(void)
 452{
 453        int this_dev;
 454
 455        for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) {
 456                struct net_device *dev = dev_ultra[this_dev];
 457                if (dev) {
 458                        unregister_netdev(dev);
 459                        cleanup_card(dev);
 460                        free_netdev(dev);
 461                }
 462        }
 463}
 464#endif /* MODULE */
 465
 466