linux/drivers/net/pcmcia/pcnet_cs.c
<<
>>
Prefs
   1/*======================================================================
   2
   3    A PCMCIA ethernet driver for NS8390-based cards
   4
   5    This driver supports the D-Link DE-650 and Linksys EthernetCard
   6    cards, the newer D-Link and Linksys combo cards, Accton EN2212
   7    cards, the RPTI EP400, and the PreMax PE-200 in non-shared-memory
   8    mode, and the IBM Credit Card Adapter, the NE4100, the Thomas
   9    Conrad ethernet card, and the Kingston KNE-PCM/x in shared-memory
  10    mode.  It will also handle the Socket EA card in either mode.
  11
  12    Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net
  13
  14    pcnet_cs.c 1.153 2003/11/09 18:53:09
  15
  16    The network driver code is based on Donald Becker's NE2000 code:
  17
  18    Written 1992,1993 by Donald Becker.
  19    Copyright 1993 United States Government as represented by the
  20    Director, National Security Agency.  This software may be used and
  21    distributed according to the terms of the GNU General Public License,
  22    incorporated herein by reference.
  23    Donald Becker may be reached at becker@scyld.com
  24
  25    Based also on Keith Moore's changes to Don Becker's code, for IBM
  26    CCAE support.  Drivers merged back together, and shared-memory
  27    Socket EA support added, by Ken Raeburn, September 1995.
  28
  29======================================================================*/
  30
  31#include <linux/kernel.h>
  32#include <linux/module.h>
  33#include <linux/init.h>
  34#include <linux/ptrace.h>
  35#include <linux/slab.h>
  36#include <linux/string.h>
  37#include <linux/timer.h>
  38#include <linux/delay.h>
  39#include <linux/ethtool.h>
  40#include <linux/netdevice.h>
  41#include <linux/log2.h>
  42#include <linux/etherdevice.h>
  43#include <linux/mii.h>
  44#include "../8390.h"
  45
  46#include <pcmcia/cs_types.h>
  47#include <pcmcia/cs.h>
  48#include <pcmcia/cistpl.h>
  49#include <pcmcia/ciscode.h>
  50#include <pcmcia/ds.h>
  51#include <pcmcia/cisreg.h>
  52
  53#include <asm/io.h>
  54#include <asm/system.h>
  55#include <asm/byteorder.h>
  56#include <asm/uaccess.h>
  57
  58#define PCNET_CMD       0x00
  59#define PCNET_DATAPORT  0x10    /* NatSemi-defined port window offset. */
  60#define PCNET_RESET     0x1f    /* Issue a read to reset, a write to clear. */
  61#define PCNET_MISC      0x18    /* For IBM CCAE and Socket EA cards */
  62
  63#define PCNET_START_PG  0x40    /* First page of TX buffer */
  64#define PCNET_STOP_PG   0x80    /* Last page +1 of RX ring */
  65
  66/* Socket EA cards have a larger packet buffer */
  67#define SOCKET_START_PG 0x01
  68#define SOCKET_STOP_PG  0xff
  69
  70#define PCNET_RDC_TIMEOUT (2*HZ/100)    /* Max wait in jiffies for Tx RDC */
  71
  72static const char *if_names[] = { "auto", "10baseT", "10base2"};
  73
  74#ifdef PCMCIA_DEBUG
  75static int pc_debug = PCMCIA_DEBUG;
  76module_param(pc_debug, int, 0);
  77#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
  78static char *version =
  79"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
  80#else
  81#define DEBUG(n, args...)
  82#endif
  83
  84/*====================================================================*/
  85
  86/* Module parameters */
  87
  88MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
  89MODULE_DESCRIPTION("NE2000 compatible PCMCIA ethernet driver");
  90MODULE_LICENSE("GPL");
  91
  92#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
  93
  94INT_MODULE_PARM(if_port,        1);     /* Transceiver type */
  95INT_MODULE_PARM(use_big_buf,    1);     /* use 64K packet buffer? */
  96INT_MODULE_PARM(mem_speed,      0);     /* shared mem speed, in ns */
  97INT_MODULE_PARM(delay_output,   0);     /* pause after xmit? */
  98INT_MODULE_PARM(delay_time,     4);     /* in usec */
  99INT_MODULE_PARM(use_shmem,      -1);    /* use shared memory? */
 100INT_MODULE_PARM(full_duplex,    0);     /* full duplex? */
 101
 102/* Ugh!  Let the user hardwire the hardware address for queer cards */
 103static int hw_addr[6] = { 0, /* ... */ };
 104module_param_array(hw_addr, int, NULL, 0);
 105
 106/*====================================================================*/
 107
 108static void mii_phy_probe(struct net_device *dev);
 109static int pcnet_config(struct pcmcia_device *link);
 110static void pcnet_release(struct pcmcia_device *link);
 111static int pcnet_open(struct net_device *dev);
 112static int pcnet_close(struct net_device *dev);
 113static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 114static const struct ethtool_ops netdev_ethtool_ops;
 115static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
 116static void ei_watchdog(u_long arg);
 117static void pcnet_reset_8390(struct net_device *dev);
 118static int set_config(struct net_device *dev, struct ifmap *map);
 119static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
 120                              int stop_pg, int cm_offset);
 121static int setup_dma_config(struct pcmcia_device *link, int start_pg,
 122                            int stop_pg);
 123
 124static void pcnet_detach(struct pcmcia_device *p_dev);
 125
 126static dev_info_t dev_info = "pcnet_cs";
 127
 128/*====================================================================*/
 129
 130typedef struct hw_info_t {
 131    u_int       offset;
 132    u_char      a0, a1, a2;
 133    u_int       flags;
 134} hw_info_t;
 135
 136#define DELAY_OUTPUT    0x01
 137#define HAS_MISC_REG    0x02
 138#define USE_BIG_BUF     0x04
 139#define HAS_IBM_MISC    0x08
 140#define IS_DL10019      0x10
 141#define IS_DL10022      0x20
 142#define HAS_MII         0x40
 143#define USE_SHMEM       0x80    /* autodetected */
 144
 145#define AM79C9XX_HOME_PHY       0x00006B90  /* HomePNA PHY */
 146#define AM79C9XX_ETH_PHY        0x00006B70  /* 10baseT PHY */
 147#define MII_PHYID_REV_MASK      0xfffffff0
 148#define MII_PHYID_REG1          0x02
 149#define MII_PHYID_REG2          0x03
 150
 151static hw_info_t hw_info[] = {
 152    { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT },
 153    { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
 154    { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
 155    { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
 156      DELAY_OUTPUT | HAS_IBM_MISC },
 157    { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
 158    { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
 159    { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
 160    { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
 161    { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
 162    { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
 163    { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
 164      HAS_MISC_REG | HAS_IBM_MISC },
 165    { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
 166    { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
 167    { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
 168      HAS_MISC_REG | HAS_IBM_MISC },
 169    { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
 170      HAS_MISC_REG | HAS_IBM_MISC },
 171    { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
 172      HAS_MISC_REG | HAS_IBM_MISC },
 173    { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
 174      HAS_MISC_REG | HAS_IBM_MISC },
 175    { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
 176      HAS_MISC_REG | HAS_IBM_MISC },
 177    { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
 178      HAS_MISC_REG | HAS_IBM_MISC },
 179    { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17,
 180      HAS_MISC_REG | HAS_IBM_MISC },
 181    { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
 182      HAS_MISC_REG | HAS_IBM_MISC },
 183    { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
 184      HAS_MISC_REG | HAS_IBM_MISC },
 185    { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
 186      HAS_MISC_REG | HAS_IBM_MISC },
 187    { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
 188    { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
 189    { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
 190      HAS_MISC_REG | HAS_IBM_MISC },
 191    { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
 192      HAS_MISC_REG | HAS_IBM_MISC },
 193    { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
 194    { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
 195    { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
 196    { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
 197    { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
 198      HAS_MISC_REG | HAS_IBM_MISC },
 199    { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45,
 200      HAS_MISC_REG | HAS_IBM_MISC },
 201    { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
 202    { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
 203    { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
 204    { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
 205      DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
 206    { /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 },
 207    { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
 208    { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
 209    { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
 210    { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }
 211};
 212
 213#define NR_INFO         ARRAY_SIZE(hw_info)
 214
 215static hw_info_t default_info = { 0, 0, 0, 0, 0 };
 216static hw_info_t dl10019_info = { 0, 0, 0, 0, IS_DL10019|HAS_MII };
 217static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII };
 218
 219typedef struct pcnet_dev_t {
 220        struct pcmcia_device    *p_dev;
 221    dev_node_t          node;
 222    u_int               flags;
 223    void                __iomem *base;
 224    struct timer_list   watchdog;
 225    int                 stale, fast_poll;
 226    u_char              phy_id;
 227    u_char              eth_phy, pna_phy;
 228    u_short             link_status;
 229    u_long              mii_reset;
 230} pcnet_dev_t;
 231
 232static inline pcnet_dev_t *PRIV(struct net_device *dev)
 233{
 234        char *p = netdev_priv(dev);
 235        return (pcnet_dev_t *)(p + sizeof(struct ei_device));
 236}
 237
 238static const struct net_device_ops pcnet_netdev_ops = {
 239        .ndo_open               = pcnet_open,
 240        .ndo_stop               = pcnet_close,
 241        .ndo_set_config         = set_config,
 242        .ndo_start_xmit         = ei_start_xmit,
 243        .ndo_get_stats          = ei_get_stats,
 244        .ndo_do_ioctl           = ei_ioctl,
 245        .ndo_set_multicast_list = ei_set_multicast_list,
 246        .ndo_tx_timeout         = ei_tx_timeout,
 247        .ndo_change_mtu         = eth_change_mtu,
 248        .ndo_set_mac_address    = eth_mac_addr,
 249        .ndo_validate_addr      = eth_validate_addr,
 250#ifdef CONFIG_NET_POLL_CONTROLLER
 251        .ndo_poll_controller    = ei_poll,
 252#endif
 253};
 254
 255/*======================================================================
 256
 257    pcnet_attach() creates an "instance" of the driver, allocating
 258    local data structures for one device.  The device is registered
 259    with Card Services.
 260
 261======================================================================*/
 262
 263static int pcnet_probe(struct pcmcia_device *link)
 264{
 265    pcnet_dev_t *info;
 266    struct net_device *dev;
 267
 268    DEBUG(0, "pcnet_attach()\n");
 269
 270    /* Create new ethernet device */
 271    dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
 272    if (!dev) return -ENOMEM;
 273    info = PRIV(dev);
 274    info->p_dev = link;
 275    link->priv = dev;
 276
 277    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 278    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 279    link->conf.Attributes = CONF_ENABLE_IRQ;
 280    link->conf.IntType = INT_MEMORY_AND_IO;
 281
 282    dev->netdev_ops = &pcnet_netdev_ops;
 283
 284    return pcnet_config(link);
 285} /* pcnet_attach */
 286
 287/*======================================================================
 288
 289    This deletes a driver "instance".  The device is de-registered
 290    with Card Services.  If it has been released, all local data
 291    structures are freed.  Otherwise, the structures will be freed
 292    when the device is released.
 293
 294======================================================================*/
 295
 296static void pcnet_detach(struct pcmcia_device *link)
 297{
 298        struct net_device *dev = link->priv;
 299
 300        DEBUG(0, "pcnet_detach(0x%p)\n", link);
 301
 302        if (link->dev_node)
 303                unregister_netdev(dev);
 304
 305        pcnet_release(link);
 306
 307        free_netdev(dev);
 308} /* pcnet_detach */
 309
 310/*======================================================================
 311
 312    This probes for a card's hardware address, for card types that
 313    encode this information in their CIS.
 314
 315======================================================================*/
 316
 317static hw_info_t *get_hwinfo(struct pcmcia_device *link)
 318{
 319    struct net_device *dev = link->priv;
 320    win_req_t req;
 321    memreq_t mem;
 322    u_char __iomem *base, *virt;
 323    int i, j;
 324
 325    /* Allocate a small memory window */
 326    req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
 327    req.Base = 0; req.Size = 0;
 328    req.AccessSpeed = 0;
 329    i = pcmcia_request_window(&link, &req, &link->win);
 330    if (i != 0) {
 331        cs_error(link, RequestWindow, i);
 332        return NULL;
 333    }
 334
 335    virt = ioremap(req.Base, req.Size);
 336    mem.Page = 0;
 337    for (i = 0; i < NR_INFO; i++) {
 338        mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
 339        pcmcia_map_mem_page(link->win, &mem);
 340        base = &virt[hw_info[i].offset & (req.Size-1)];
 341        if ((readb(base+0) == hw_info[i].a0) &&
 342            (readb(base+2) == hw_info[i].a1) &&
 343            (readb(base+4) == hw_info[i].a2)) {
 344                for (j = 0; j < 6; j++)
 345                    dev->dev_addr[j] = readb(base + (j<<1));
 346                break;
 347        }
 348    }
 349
 350    iounmap(virt);
 351    j = pcmcia_release_window(link->win);
 352    if (j != 0)
 353        cs_error(link, ReleaseWindow, j);
 354    return (i < NR_INFO) ? hw_info+i : NULL;
 355} /* get_hwinfo */
 356
 357/*======================================================================
 358
 359    This probes for a card's hardware address by reading the PROM.
 360    It checks the address against a list of known types, then falls
 361    back to a simple NE2000 clone signature check.
 362
 363======================================================================*/
 364
 365static hw_info_t *get_prom(struct pcmcia_device *link)
 366{
 367    struct net_device *dev = link->priv;
 368    unsigned int ioaddr = dev->base_addr;
 369    u_char prom[32];
 370    int i, j;
 371
 372    /* This is lifted straight from drivers/net/ne.c */
 373    struct {
 374        u_char value, offset;
 375    } program_seq[] = {
 376        {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
 377        {0x48,  EN0_DCFG},      /* Set byte-wide (0x48) access. */
 378        {0x00,  EN0_RCNTLO},    /* Clear the count regs. */
 379        {0x00,  EN0_RCNTHI},
 380        {0x00,  EN0_IMR},       /* Mask completion irq. */
 381        {0xFF,  EN0_ISR},
 382        {E8390_RXOFF, EN0_RXCR},        /* 0x20  Set to monitor */
 383        {E8390_TXOFF, EN0_TXCR},        /* 0x02  and loopback mode. */
 384        {32,    EN0_RCNTLO},
 385        {0x00,  EN0_RCNTHI},
 386        {0x00,  EN0_RSARLO},    /* DMA starting at 0x0000. */
 387        {0x00,  EN0_RSARHI},
 388        {E8390_RREAD+E8390_START, E8390_CMD},
 389    };
 390
 391    pcnet_reset_8390(dev);
 392    mdelay(10);
 393
 394    for (i = 0; i < ARRAY_SIZE(program_seq); i++)
 395        outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
 396
 397    for (i = 0; i < 32; i++)
 398        prom[i] = inb(ioaddr + PCNET_DATAPORT);
 399    for (i = 0; i < NR_INFO; i++) {
 400        if ((prom[0] == hw_info[i].a0) &&
 401            (prom[2] == hw_info[i].a1) &&
 402            (prom[4] == hw_info[i].a2))
 403            break;
 404    }
 405    if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
 406        for (j = 0; j < 6; j++)
 407            dev->dev_addr[j] = prom[j<<1];
 408        return (i < NR_INFO) ? hw_info+i : &default_info;
 409    }
 410    return NULL;
 411} /* get_prom */
 412
 413/*======================================================================
 414
 415    For DL10019 based cards, like the Linksys EtherFast
 416
 417======================================================================*/
 418
 419static hw_info_t *get_dl10019(struct pcmcia_device *link)
 420{
 421    struct net_device *dev = link->priv;
 422    int i;
 423    u_char sum;
 424
 425    for (sum = 0, i = 0x14; i < 0x1c; i++)
 426        sum += inb_p(dev->base_addr + i);
 427    if (sum != 0xff)
 428        return NULL;
 429    for (i = 0; i < 6; i++)
 430        dev->dev_addr[i] = inb_p(dev->base_addr + 0x14 + i);
 431    i = inb(dev->base_addr + 0x1f);
 432    return ((i == 0x91)||(i == 0x99)) ? &dl10022_info : &dl10019_info;
 433}
 434
 435/*======================================================================
 436
 437    For Asix AX88190 based cards
 438
 439======================================================================*/
 440
 441static hw_info_t *get_ax88190(struct pcmcia_device *link)
 442{
 443    struct net_device *dev = link->priv;
 444    unsigned int ioaddr = dev->base_addr;
 445    int i, j;
 446
 447    /* Not much of a test, but the alternatives are messy */
 448    if (link->conf.ConfigBase != 0x03c0)
 449        return NULL;
 450
 451    outb_p(0x01, ioaddr + EN0_DCFG);    /* Set word-wide access. */
 452    outb_p(0x00, ioaddr + EN0_RSARLO);  /* DMA starting at 0x0400. */
 453    outb_p(0x04, ioaddr + EN0_RSARHI);
 454    outb_p(E8390_RREAD+E8390_START, ioaddr + E8390_CMD);
 455
 456    for (i = 0; i < 6; i += 2) {
 457        j = inw(ioaddr + PCNET_DATAPORT);
 458        dev->dev_addr[i] = j & 0xff;
 459        dev->dev_addr[i+1] = j >> 8;
 460    }
 461    printk(KERN_NOTICE "pcnet_cs: this is an AX88190 card!\n");
 462    printk(KERN_NOTICE "pcnet_cs: use axnet_cs instead.\n");
 463    return NULL;
 464}
 465
 466/*======================================================================
 467
 468    This should be totally unnecessary... but when we can't figure
 469    out the hardware address any other way, we'll let the user hard
 470    wire it when the module is initialized.
 471
 472======================================================================*/
 473
 474static hw_info_t *get_hwired(struct pcmcia_device *link)
 475{
 476    struct net_device *dev = link->priv;
 477    int i;
 478
 479    for (i = 0; i < 6; i++)
 480        if (hw_addr[i] != 0) break;
 481    if (i == 6)
 482        return NULL;
 483
 484    for (i = 0; i < 6; i++)
 485        dev->dev_addr[i] = hw_addr[i];
 486
 487    return &default_info;
 488} /* get_hwired */
 489
 490/*======================================================================
 491
 492    pcnet_config() is scheduled to run after a CARD_INSERTION event
 493    is received, to configure the PCMCIA socket, and to make the
 494    ethernet device available to the system.
 495
 496======================================================================*/
 497
 498#define CS_CHECK(fn, ret) \
 499do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 500
 501static int try_io_port(struct pcmcia_device *link)
 502{
 503    int j, ret;
 504    if (link->io.NumPorts1 == 32) {
 505        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 506        if (link->io.NumPorts2 > 0) {
 507            /* for master/slave multifunction cards */
 508            link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
 509            link->irq.Attributes =
 510                IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 511        }
 512    } else {
 513        /* This should be two 16-port windows */
 514        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 515        link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
 516    }
 517    if (link->io.BasePort1 == 0) {
 518        link->io.IOAddrLines = 16;
 519        for (j = 0; j < 0x400; j += 0x20) {
 520            link->io.BasePort1 = j ^ 0x300;
 521            link->io.BasePort2 = (j ^ 0x300) + 0x10;
 522            ret = pcmcia_request_io(link, &link->io);
 523            if (ret == 0)
 524                    return ret;
 525        }
 526        return ret;
 527    } else {
 528        return pcmcia_request_io(link, &link->io);
 529    }
 530}
 531
 532static int pcnet_confcheck(struct pcmcia_device *p_dev,
 533                           cistpl_cftable_entry_t *cfg,
 534                           cistpl_cftable_entry_t *dflt,
 535                           unsigned int vcc,
 536                           void *priv_data)
 537{
 538        int *has_shmem = priv_data;
 539        int i;
 540        cistpl_io_t *io = &cfg->io;
 541
 542        if (cfg->index == 0 || cfg->io.nwin == 0)
 543                return -EINVAL;
 544
 545        /* For multifunction cards, by convention, we configure the
 546           network function with window 0, and serial with window 1 */
 547        if (io->nwin > 1) {
 548                i = (io->win[1].len > io->win[0].len);
 549                p_dev->io.BasePort2 = io->win[1-i].base;
 550                p_dev->io.NumPorts2 = io->win[1-i].len;
 551        } else {
 552                i = p_dev->io.NumPorts2 = 0;
 553        }
 554
 555        *has_shmem = ((cfg->mem.nwin == 1) &&
 556                      (cfg->mem.win[0].len >= 0x4000));
 557        p_dev->io.BasePort1 = io->win[i].base;
 558        p_dev->io.NumPorts1 = io->win[i].len;
 559        p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
 560        if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
 561                return try_io_port(p_dev);
 562
 563        return 0;
 564}
 565
 566static int pcnet_config(struct pcmcia_device *link)
 567{
 568    struct net_device *dev = link->priv;
 569    pcnet_dev_t *info = PRIV(dev);
 570    int last_ret, last_fn, start_pg, stop_pg, cm_offset;
 571    int has_shmem = 0;
 572    hw_info_t *local_hw_info;
 573
 574    DEBUG(0, "pcnet_config(0x%p)\n", link);
 575
 576    last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
 577    if (last_ret) {
 578        cs_error(link, RequestIO, last_ret);
 579        goto failed;
 580    }
 581
 582    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
 583
 584    if (link->io.NumPorts2 == 8) {
 585        link->conf.Attributes |= CONF_ENABLE_SPKR;
 586        link->conf.Status = CCSR_AUDIO_ENA;
 587    }
 588    if ((link->manf_id == MANFID_IBM) &&
 589        (link->card_id == PRODID_IBM_HOME_AND_AWAY))
 590        link->conf.ConfigIndex |= 0x10;
 591
 592    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
 593    dev->irq = link->irq.AssignedIRQ;
 594    dev->base_addr = link->io.BasePort1;
 595    if (info->flags & HAS_MISC_REG) {
 596        if ((if_port == 1) || (if_port == 2))
 597            dev->if_port = if_port;
 598        else
 599            printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n");
 600    } else {
 601        dev->if_port = 0;
 602    }
 603
 604    if ((link->conf.ConfigBase == 0x03c0)
 605        && (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
 606        printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
 607        printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
 608        goto failed;
 609    }
 610
 611    local_hw_info = get_hwinfo(link);
 612    if (local_hw_info == NULL)
 613        local_hw_info = get_prom(link);
 614    if (local_hw_info == NULL)
 615        local_hw_info = get_dl10019(link);
 616    if (local_hw_info == NULL)
 617        local_hw_info = get_ax88190(link);
 618    if (local_hw_info == NULL)
 619        local_hw_info = get_hwired(link);
 620
 621    if (local_hw_info == NULL) {
 622        printk(KERN_NOTICE "pcnet_cs: unable to read hardware net"
 623               " address for io base %#3lx\n", dev->base_addr);
 624        goto failed;
 625    }
 626
 627    info->flags = local_hw_info->flags;
 628    /* Check for user overrides */
 629    info->flags |= (delay_output) ? DELAY_OUTPUT : 0;
 630    if ((link->manf_id == MANFID_SOCKET) &&
 631        ((link->card_id == PRODID_SOCKET_LPE) ||
 632         (link->card_id == PRODID_SOCKET_LPE_CF) ||
 633         (link->card_id == PRODID_SOCKET_EIO)))
 634        info->flags &= ~USE_BIG_BUF;
 635    if (!use_big_buf)
 636        info->flags &= ~USE_BIG_BUF;
 637
 638    if (info->flags & USE_BIG_BUF) {
 639        start_pg = SOCKET_START_PG;
 640        stop_pg = SOCKET_STOP_PG;
 641        cm_offset = 0x10000;
 642    } else {
 643        start_pg = PCNET_START_PG;
 644        stop_pg = PCNET_STOP_PG;
 645        cm_offset = 0;
 646    }
 647
 648    /* has_shmem is ignored if use_shmem != -1 */
 649    if ((use_shmem == 0) || (!has_shmem && (use_shmem == -1)) ||
 650        (setup_shmem_window(link, start_pg, stop_pg, cm_offset) != 0))
 651        setup_dma_config(link, start_pg, stop_pg);
 652
 653    ei_status.name = "NE2000";
 654    ei_status.word16 = 1;
 655    ei_status.reset_8390 = &pcnet_reset_8390;
 656
 657    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 658
 659    if (info->flags & (IS_DL10019|IS_DL10022))
 660        mii_phy_probe(dev);
 661
 662    link->dev_node = &info->node;
 663    SET_NETDEV_DEV(dev, &handle_to_dev(link));
 664
 665    if (register_netdev(dev) != 0) {
 666        printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
 667        link->dev_node = NULL;
 668        goto failed;
 669    }
 670
 671    strcpy(info->node.dev_name, dev->name);
 672
 673    if (info->flags & (IS_DL10019|IS_DL10022)) {
 674        u_char id = inb(dev->base_addr + 0x1a);
 675        printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ",
 676               dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id);
 677        if (info->pna_phy)
 678            printk("PNA, ");
 679    } else {
 680        printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name);
 681    }
 682    printk("io %#3lx, irq %d,", dev->base_addr, dev->irq);
 683    if (info->flags & USE_SHMEM)
 684        printk (" mem %#5lx,", dev->mem_start);
 685    if (info->flags & HAS_MISC_REG)
 686        printk(" %s xcvr,", if_names[dev->if_port]);
 687    printk(" hw_addr %pM\n", dev->dev_addr);
 688    return 0;
 689
 690cs_failed:
 691    cs_error(link, last_fn, last_ret);
 692failed:
 693    pcnet_release(link);
 694    return -ENODEV;
 695} /* pcnet_config */
 696
 697/*======================================================================
 698
 699    After a card is removed, pcnet_release() will unregister the net
 700    device, and release the PCMCIA configuration.  If the device is
 701    still open, this will be postponed until it is closed.
 702
 703======================================================================*/
 704
 705static void pcnet_release(struct pcmcia_device *link)
 706{
 707        pcnet_dev_t *info = PRIV(link->priv);
 708
 709        DEBUG(0, "pcnet_release(0x%p)\n", link);
 710
 711        if (info->flags & USE_SHMEM)
 712                iounmap(info->base);
 713
 714        pcmcia_disable_device(link);
 715}
 716
 717/*======================================================================
 718
 719    The card status event handler.  Mostly, this schedules other
 720    stuff to run after an event is received.  A CARD_REMOVAL event
 721    also sets some flags to discourage the net drivers from trying
 722    to talk to the card any more.
 723
 724======================================================================*/
 725
 726static int pcnet_suspend(struct pcmcia_device *link)
 727{
 728        struct net_device *dev = link->priv;
 729
 730        if (link->open)
 731                netif_device_detach(dev);
 732
 733        return 0;
 734}
 735
 736static int pcnet_resume(struct pcmcia_device *link)
 737{
 738        struct net_device *dev = link->priv;
 739
 740        if (link->open) {
 741                pcnet_reset_8390(dev);
 742                NS8390_init(dev, 1);
 743                netif_device_attach(dev);
 744        }
 745
 746        return 0;
 747}
 748
 749
 750/*======================================================================
 751
 752    MII interface support for DL10019 and DL10022 based cards
 753
 754    On the DL10019, the MII IO direction bit is 0x10; on the DL10022
 755    it is 0x20.  Setting both bits seems to work on both card types.
 756
 757======================================================================*/
 758
 759#define DLINK_GPIO              0x1c
 760#define DLINK_DIAG              0x1d
 761#define DLINK_EEPROM            0x1e
 762
 763#define MDIO_SHIFT_CLK          0x80
 764#define MDIO_DATA_OUT           0x40
 765#define MDIO_DIR_WRITE          0x30
 766#define MDIO_DATA_WRITE0        (MDIO_DIR_WRITE)
 767#define MDIO_DATA_WRITE1        (MDIO_DIR_WRITE | MDIO_DATA_OUT)
 768#define MDIO_DATA_READ          0x10
 769#define MDIO_MASK               0x0f
 770
 771static void mdio_sync(unsigned int addr)
 772{
 773    int bits, mask = inb(addr) & MDIO_MASK;
 774    for (bits = 0; bits < 32; bits++) {
 775        outb(mask | MDIO_DATA_WRITE1, addr);
 776        outb(mask | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr);
 777    }
 778}
 779
 780static int mdio_read(unsigned int addr, int phy_id, int loc)
 781{
 782    u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
 783    int i, retval = 0, mask = inb(addr) & MDIO_MASK;
 784
 785    mdio_sync(addr);
 786    for (i = 13; i >= 0; i--) {
 787        int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
 788        outb(mask | dat, addr);
 789        outb(mask | dat | MDIO_SHIFT_CLK, addr);
 790    }
 791    for (i = 19; i > 0; i--) {
 792        outb(mask, addr);
 793        retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0);
 794        outb(mask | MDIO_SHIFT_CLK, addr);
 795    }
 796    return (retval>>1) & 0xffff;
 797}
 798
 799static void mdio_write(unsigned int addr, int phy_id, int loc, int value)
 800{
 801    u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
 802    int i, mask = inb(addr) & MDIO_MASK;
 803
 804    mdio_sync(addr);
 805    for (i = 31; i >= 0; i--) {
 806        int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
 807        outb(mask | dat, addr);
 808        outb(mask | dat | MDIO_SHIFT_CLK, addr);
 809    }
 810    for (i = 1; i >= 0; i--) {
 811        outb(mask, addr);
 812        outb(mask | MDIO_SHIFT_CLK, addr);
 813    }
 814}
 815
 816/*======================================================================
 817
 818    EEPROM access routines for DL10019 and DL10022 based cards
 819
 820======================================================================*/
 821
 822#define EE_EEP          0x40
 823#define EE_ASIC         0x10
 824#define EE_CS           0x08
 825#define EE_CK           0x04
 826#define EE_DO           0x02
 827#define EE_DI           0x01
 828#define EE_ADOT         0x01    /* DataOut for ASIC */
 829#define EE_READ_CMD     0x06
 830
 831#define DL19FDUPLX      0x0400  /* DL10019 Full duplex mode */
 832
 833static int read_eeprom(unsigned int ioaddr, int location)
 834{
 835    int i, retval = 0;
 836    unsigned int ee_addr = ioaddr + DLINK_EEPROM;
 837    int read_cmd = location | (EE_READ_CMD << 8);
 838
 839    outb(0, ee_addr);
 840    outb(EE_EEP|EE_CS, ee_addr);
 841
 842    /* Shift the read command bits out. */
 843    for (i = 10; i >= 0; i--) {
 844        short dataval = (read_cmd & (1 << i)) ? EE_DO : 0;
 845        outb_p(EE_EEP|EE_CS|dataval, ee_addr);
 846        outb_p(EE_EEP|EE_CS|dataval|EE_CK, ee_addr);
 847    }
 848    outb(EE_EEP|EE_CS, ee_addr);
 849
 850    for (i = 16; i > 0; i--) {
 851        outb_p(EE_EEP|EE_CS | EE_CK, ee_addr);
 852        retval = (retval << 1) | ((inb(ee_addr) & EE_DI) ? 1 : 0);
 853        outb_p(EE_EEP|EE_CS, ee_addr);
 854    }
 855
 856    /* Terminate the EEPROM access. */
 857    outb(0, ee_addr);
 858    return retval;
 859}
 860
 861/*
 862    The internal ASIC registers can be changed by EEPROM READ access
 863    with EE_ASIC bit set.
 864    In ASIC mode, EE_ADOT is used to output the data to the ASIC.
 865*/
 866
 867static void write_asic(unsigned int ioaddr, int location, short asic_data)
 868{
 869        int i;
 870        unsigned int ee_addr = ioaddr + DLINK_EEPROM;
 871        short dataval;
 872        int read_cmd = location | (EE_READ_CMD << 8);
 873
 874        asic_data |= read_eeprom(ioaddr, location);
 875
 876        outb(0, ee_addr);
 877        outb(EE_ASIC|EE_CS|EE_DI, ee_addr);
 878
 879        read_cmd = read_cmd >> 1;
 880
 881        /* Shift the read command bits out. */
 882        for (i = 9; i >= 0; i--) {
 883                dataval = (read_cmd & (1 << i)) ? EE_DO : 0;
 884                outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr);
 885                outb_p(EE_ASIC|EE_CS|EE_DI|dataval|EE_CK, ee_addr);
 886                outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr);
 887        }
 888        // sync
 889        outb(EE_ASIC|EE_CS, ee_addr);
 890        outb(EE_ASIC|EE_CS|EE_CK, ee_addr);
 891        outb(EE_ASIC|EE_CS, ee_addr);
 892
 893        for (i = 15; i >= 0; i--) {
 894                dataval = (asic_data & (1 << i)) ? EE_ADOT : 0;
 895                outb_p(EE_ASIC|EE_CS|dataval, ee_addr);
 896                outb_p(EE_ASIC|EE_CS|dataval|EE_CK, ee_addr);
 897                outb_p(EE_ASIC|EE_CS|dataval, ee_addr);
 898        }
 899
 900        /* Terminate the ASIC access. */
 901        outb(EE_ASIC|EE_DI, ee_addr);
 902        outb(EE_ASIC|EE_DI| EE_CK, ee_addr);
 903        outb(EE_ASIC|EE_DI, ee_addr);
 904
 905        outb(0, ee_addr);
 906}
 907
 908/*====================================================================*/
 909
 910static void set_misc_reg(struct net_device *dev)
 911{
 912    unsigned int nic_base = dev->base_addr;
 913    pcnet_dev_t *info = PRIV(dev);
 914    u_char tmp;
 915
 916    if (info->flags & HAS_MISC_REG) {
 917        tmp = inb_p(nic_base + PCNET_MISC) & ~3;
 918        if (dev->if_port == 2)
 919            tmp |= 1;
 920        if (info->flags & USE_BIG_BUF)
 921            tmp |= 2;
 922        if (info->flags & HAS_IBM_MISC)
 923            tmp |= 8;
 924        outb_p(tmp, nic_base + PCNET_MISC);
 925    }
 926    if (info->flags & IS_DL10022) {
 927        if (info->flags & HAS_MII) {
 928            /* Advertise 100F, 100H, 10F, 10H */
 929            mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1);
 930            /* Restart MII autonegotiation */
 931            mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000);
 932            mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200);
 933            info->mii_reset = jiffies;
 934        } else {
 935            outb(full_duplex ? 4 : 0, nic_base + DLINK_DIAG);
 936        }
 937    } else if (info->flags & IS_DL10019) {
 938        /* Advertise 100F, 100H, 10F, 10H */
 939        mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1);
 940        /* Restart MII autonegotiation */
 941        mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000);
 942        mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200);
 943    }
 944}
 945
 946/*====================================================================*/
 947
 948static void mii_phy_probe(struct net_device *dev)
 949{
 950    pcnet_dev_t *info = PRIV(dev);
 951    unsigned int mii_addr = dev->base_addr + DLINK_GPIO;
 952    int i;
 953    u_int tmp, phyid;
 954
 955    for (i = 31; i >= 0; i--) {
 956        tmp = mdio_read(mii_addr, i, 1);
 957        if ((tmp == 0) || (tmp == 0xffff))
 958            continue;
 959        tmp = mdio_read(mii_addr, i, MII_PHYID_REG1);
 960        phyid = tmp << 16;
 961        phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
 962        phyid &= MII_PHYID_REV_MASK;
 963        DEBUG(0, "%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
 964        if (phyid == AM79C9XX_HOME_PHY) {
 965            info->pna_phy = i;
 966        } else if (phyid != AM79C9XX_ETH_PHY) {
 967            info->eth_phy = i;
 968        }
 969    }
 970}
 971
 972static int pcnet_open(struct net_device *dev)
 973{
 974    int ret;
 975    pcnet_dev_t *info = PRIV(dev);
 976    struct pcmcia_device *link = info->p_dev;
 977    unsigned int nic_base = dev->base_addr;
 978
 979    DEBUG(2, "pcnet_open('%s')\n", dev->name);
 980
 981    if (!pcmcia_dev_present(link))
 982        return -ENODEV;
 983
 984    set_misc_reg(dev);
 985
 986    outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */
 987    ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev);
 988    if (ret)
 989            return ret;
 990
 991    link->open++;
 992
 993    info->phy_id = info->eth_phy;
 994    info->link_status = 0x00;
 995    init_timer(&info->watchdog);
 996    info->watchdog.function = &ei_watchdog;
 997    info->watchdog.data = (u_long)dev;
 998    info->watchdog.expires = jiffies + HZ;
 999    add_timer(&info->watchdog);
1000
1001    return ei_open(dev);
1002} /* pcnet_open */
1003
1004/*====================================================================*/
1005
1006static int pcnet_close(struct net_device *dev)
1007{
1008    pcnet_dev_t *info = PRIV(dev);
1009    struct pcmcia_device *link = info->p_dev;
1010
1011    DEBUG(2, "pcnet_close('%s')\n", dev->name);
1012
1013    ei_close(dev);
1014    free_irq(dev->irq, dev);
1015
1016    link->open--;
1017    netif_stop_queue(dev);
1018    del_timer_sync(&info->watchdog);
1019
1020    return 0;
1021} /* pcnet_close */
1022
1023/*======================================================================
1024
1025    Hard reset the card.  This used to pause for the same period that
1026    a 8390 reset command required, but that shouldn't be necessary.
1027
1028======================================================================*/
1029
1030static void pcnet_reset_8390(struct net_device *dev)
1031{
1032    unsigned int nic_base = dev->base_addr;
1033    int i;
1034
1035    ei_status.txing = ei_status.dmaing = 0;
1036
1037    outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, nic_base + E8390_CMD);
1038
1039    outb(inb(nic_base + PCNET_RESET), nic_base + PCNET_RESET);
1040
1041    for (i = 0; i < 100; i++) {
1042        if ((inb_p(nic_base+EN0_ISR) & ENISR_RESET) != 0)
1043            break;
1044        udelay(100);
1045    }
1046    outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */
1047
1048    if (i == 100)
1049        printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n",
1050               dev->name);
1051    set_misc_reg(dev);
1052
1053} /* pcnet_reset_8390 */
1054
1055/*====================================================================*/
1056
1057static int set_config(struct net_device *dev, struct ifmap *map)
1058{
1059    pcnet_dev_t *info = PRIV(dev);
1060    if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
1061        if (!(info->flags & HAS_MISC_REG))
1062            return -EOPNOTSUPP;
1063        else if ((map->port < 1) || (map->port > 2))
1064            return -EINVAL;
1065        dev->if_port = map->port;
1066        printk(KERN_INFO "%s: switched to %s port\n",
1067               dev->name, if_names[dev->if_port]);
1068        NS8390_init(dev, 1);
1069    }
1070    return 0;
1071}
1072
1073/*====================================================================*/
1074
1075static irqreturn_t ei_irq_wrapper(int irq, void *dev_id)
1076{
1077    struct net_device *dev = dev_id;
1078    pcnet_dev_t *info;
1079    irqreturn_t ret = ei_interrupt(irq, dev_id);
1080
1081    if (ret == IRQ_HANDLED) {
1082            info = PRIV(dev);
1083            info->stale = 0;
1084    }
1085    return ret;
1086}
1087
1088static void ei_watchdog(u_long arg)
1089{
1090    struct net_device *dev = (struct net_device *)arg;
1091    pcnet_dev_t *info = PRIV(dev);
1092    unsigned int nic_base = dev->base_addr;
1093    unsigned int mii_addr = nic_base + DLINK_GPIO;
1094    u_short link;
1095
1096    if (!netif_device_present(dev)) goto reschedule;
1097
1098    /* Check for pending interrupt with expired latency timer: with
1099       this, we can limp along even if the interrupt is blocked */
1100    if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
1101        if (!info->fast_poll)
1102            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
1103        ei_irq_wrapper(dev->irq, dev);
1104        info->fast_poll = HZ;
1105    }
1106    if (info->fast_poll) {
1107        info->fast_poll--;
1108        info->watchdog.expires = jiffies + 1;
1109        add_timer(&info->watchdog);
1110        return;
1111    }
1112
1113    if (!(info->flags & HAS_MII))
1114        goto reschedule;
1115
1116    mdio_read(mii_addr, info->phy_id, 1);
1117    link = mdio_read(mii_addr, info->phy_id, 1);
1118    if (!link || (link == 0xffff)) {
1119        if (info->eth_phy) {
1120            info->phy_id = info->eth_phy = 0;
1121        } else {
1122            printk(KERN_INFO "%s: MII is missing!\n", dev->name);
1123            info->flags &= ~HAS_MII;
1124        }
1125        goto reschedule;
1126    }
1127
1128    link &= 0x0004;
1129    if (link != info->link_status) {
1130        u_short p = mdio_read(mii_addr, info->phy_id, 5);
1131        printk(KERN_INFO "%s: %s link beat\n", dev->name,
1132               (link) ? "found" : "lost");
1133        if (link && (info->flags & IS_DL10022)) {
1134            /* Disable collision detection on full duplex links */
1135            outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG);
1136        } else if (link && (info->flags & IS_DL10019)) {
1137            /* Disable collision detection on full duplex links */
1138            write_asic(dev->base_addr, 4, (p & 0x140) ? DL19FDUPLX : 0);
1139        }
1140        if (link) {
1141            if (info->phy_id == info->eth_phy) {
1142                if (p)
1143                    printk(KERN_INFO "%s: autonegotiation complete: "
1144                           "%sbaseT-%cD selected\n", dev->name,
1145                           ((p & 0x0180) ? "100" : "10"),
1146                           ((p & 0x0140) ? 'F' : 'H'));
1147                else
1148                    printk(KERN_INFO "%s: link partner did not "
1149                           "autonegotiate\n", dev->name);
1150            }
1151            NS8390_init(dev, 1);
1152        }
1153        info->link_status = link;
1154    }
1155    if (info->pna_phy && time_after(jiffies, info->mii_reset + 6*HZ)) {
1156        link = mdio_read(mii_addr, info->eth_phy, 1) & 0x0004;
1157        if (((info->phy_id == info->pna_phy) && link) ||
1158            ((info->phy_id != info->pna_phy) && !link)) {
1159            /* isolate this MII and try flipping to the other one */
1160            mdio_write(mii_addr, info->phy_id, 0, 0x0400);
1161            info->phy_id ^= info->pna_phy ^ info->eth_phy;
1162            printk(KERN_INFO "%s: switched to %s transceiver\n", dev->name,
1163                   (info->phy_id == info->eth_phy) ? "ethernet" : "PNA");
1164            mdio_write(mii_addr, info->phy_id, 0,
1165                       (info->phy_id == info->eth_phy) ? 0x1000 : 0);
1166            info->link_status = 0;
1167            info->mii_reset = jiffies;
1168        }
1169    }
1170
1171reschedule:
1172    info->watchdog.expires = jiffies + HZ;
1173    add_timer(&info->watchdog);
1174}
1175
1176/*====================================================================*/
1177
1178static void netdev_get_drvinfo(struct net_device *dev,
1179                               struct ethtool_drvinfo *info)
1180{
1181        strcpy(info->driver, "pcnet_cs");
1182}
1183
1184static const struct ethtool_ops netdev_ethtool_ops = {
1185        .get_drvinfo            = netdev_get_drvinfo,
1186};
1187
1188/*====================================================================*/
1189
1190
1191static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1192{
1193    pcnet_dev_t *info = PRIV(dev);
1194    struct mii_ioctl_data *data = if_mii(rq);
1195    unsigned int mii_addr = dev->base_addr + DLINK_GPIO;
1196
1197    if (!(info->flags & (IS_DL10019|IS_DL10022)))
1198        return -EINVAL;
1199
1200    switch (cmd) {
1201    case SIOCGMIIPHY:
1202        data->phy_id = info->phy_id;
1203    case SIOCGMIIREG:           /* Read MII PHY register. */
1204        data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f);
1205        return 0;
1206    case SIOCSMIIREG:           /* Write MII PHY register. */
1207        mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in);
1208        return 0;
1209    }
1210    return -EOPNOTSUPP;
1211}
1212
1213/*====================================================================*/
1214
1215static void dma_get_8390_hdr(struct net_device *dev,
1216                             struct e8390_pkt_hdr *hdr,
1217                             int ring_page)
1218{
1219    unsigned int nic_base = dev->base_addr;
1220
1221    if (ei_status.dmaing) {
1222        printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
1223               "[DMAstat:%1x][irqlock:%1x]\n",
1224               dev->name, ei_status.dmaing, ei_status.irqlock);
1225        return;
1226    }
1227
1228    ei_status.dmaing |= 0x01;
1229    outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD);
1230    outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
1231    outb_p(0, nic_base + EN0_RCNTHI);
1232    outb_p(0, nic_base + EN0_RSARLO);           /* On page boundary */
1233    outb_p(ring_page, nic_base + EN0_RSARHI);
1234    outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD);
1235
1236    insw(nic_base + PCNET_DATAPORT, hdr,
1237            sizeof(struct e8390_pkt_hdr)>>1);
1238    /* Fix for big endian systems */
1239    hdr->count = le16_to_cpu(hdr->count);
1240
1241    outb_p(ENISR_RDC, nic_base + EN0_ISR);      /* Ack intr. */
1242    ei_status.dmaing &= ~0x01;
1243}
1244
1245/*====================================================================*/
1246
1247static void dma_block_input(struct net_device *dev, int count,
1248                            struct sk_buff *skb, int ring_offset)
1249{
1250    unsigned int nic_base = dev->base_addr;
1251    int xfer_count = count;
1252    char *buf = skb->data;
1253
1254#ifdef PCMCIA_DEBUG
1255    if ((ei_debug > 4) && (count != 4))
1256        printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
1257#endif
1258    if (ei_status.dmaing) {
1259        printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
1260               "[DMAstat:%1x][irqlock:%1x]\n",
1261               dev->name, ei_status.dmaing, ei_status.irqlock);
1262        return;
1263    }
1264    ei_status.dmaing |= 0x01;
1265    outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD);
1266    outb_p(count & 0xff, nic_base + EN0_RCNTLO);
1267    outb_p(count >> 8, nic_base + EN0_RCNTHI);
1268    outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
1269    outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
1270    outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD);
1271
1272    insw(nic_base + PCNET_DATAPORT,buf,count>>1);
1273    if (count & 0x01)
1274        buf[count-1] = inb(nic_base + PCNET_DATAPORT), xfer_count++;
1275
1276    /* This was for the ALPHA version only, but enough people have been
1277       encountering problems that it is still here. */
1278#ifdef PCMCIA_DEBUG
1279    if (ei_debug > 4) {         /* DMA termination address check... */
1280        int addr, tries = 20;
1281        do {
1282            /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
1283               -- it's broken for Rx on some cards! */
1284            int high = inb_p(nic_base + EN0_RSARHI);
1285            int low = inb_p(nic_base + EN0_RSARLO);
1286            addr = (high << 8) + low;
1287            if (((ring_offset + xfer_count) & 0xff) == (addr & 0xff))
1288                break;
1289        } while (--tries > 0);
1290        if (tries <= 0)
1291            printk(KERN_NOTICE "%s: RX transfer address mismatch,"
1292                   "%#4.4x (expected) vs. %#4.4x (actual).\n",
1293                   dev->name, ring_offset + xfer_count, addr);
1294    }
1295#endif
1296    outb_p(ENISR_RDC, nic_base + EN0_ISR);      /* Ack intr. */
1297    ei_status.dmaing &= ~0x01;
1298} /* dma_block_input */
1299
1300/*====================================================================*/
1301
1302static void dma_block_output(struct net_device *dev, int count,
1303                             const u_char *buf, const int start_page)
1304{
1305    unsigned int nic_base = dev->base_addr;
1306    pcnet_dev_t *info = PRIV(dev);
1307#ifdef PCMCIA_DEBUG
1308    int retries = 0;
1309#endif
1310    u_long dma_start;
1311
1312#ifdef PCMCIA_DEBUG
1313    if (ei_debug > 4)
1314        printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
1315#endif
1316
1317    /* Round the count up for word writes.  Do we need to do this?
1318       What effect will an odd byte count have on the 8390?
1319       I should check someday. */
1320    if (count & 0x01)
1321        count++;
1322    if (ei_status.dmaing) {
1323        printk(KERN_NOTICE "%s: DMAing conflict in dma_block_output."
1324               "[DMAstat:%1x][irqlock:%1x]\n",
1325               dev->name, ei_status.dmaing, ei_status.irqlock);
1326        return;
1327    }
1328    ei_status.dmaing |= 0x01;
1329    /* We should already be in page 0, but to be safe... */
1330    outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base+PCNET_CMD);
1331
1332#ifdef PCMCIA_DEBUG
1333  retry:
1334#endif
1335
1336    outb_p(ENISR_RDC, nic_base + EN0_ISR);
1337
1338    /* Now the normal output. */
1339    outb_p(count & 0xff, nic_base + EN0_RCNTLO);
1340    outb_p(count >> 8,   nic_base + EN0_RCNTHI);
1341    outb_p(0x00, nic_base + EN0_RSARLO);
1342    outb_p(start_page, nic_base + EN0_RSARHI);
1343
1344    outb_p(E8390_RWRITE+E8390_START, nic_base + PCNET_CMD);
1345    outsw(nic_base + PCNET_DATAPORT, buf, count>>1);
1346
1347    dma_start = jiffies;
1348
1349#ifdef PCMCIA_DEBUG
1350    /* This was for the ALPHA version only, but enough people have been
1351       encountering problems that it is still here. */
1352    if (ei_debug > 4) { /* DMA termination address check... */
1353        int addr, tries = 20;
1354        do {
1355            int high = inb_p(nic_base + EN0_RSARHI);
1356            int low = inb_p(nic_base + EN0_RSARLO);
1357            addr = (high << 8) + low;
1358            if ((start_page << 8) + count == addr)
1359                break;
1360        } while (--tries > 0);
1361        if (tries <= 0) {
1362            printk(KERN_NOTICE "%s: Tx packet transfer address mismatch,"
1363                   "%#4.4x (expected) vs. %#4.4x (actual).\n",
1364                   dev->name, (start_page << 8) + count, addr);
1365            if (retries++ == 0)
1366                goto retry;
1367        }
1368    }
1369#endif
1370
1371    while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
1372        if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) {
1373            printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n",
1374                   dev->name);
1375            pcnet_reset_8390(dev);
1376            NS8390_init(dev, 1);
1377            break;
1378        }
1379
1380    outb_p(ENISR_RDC, nic_base + EN0_ISR);      /* Ack intr. */
1381    if (info->flags & DELAY_OUTPUT)
1382        udelay((long)delay_time);
1383    ei_status.dmaing &= ~0x01;
1384}
1385
1386/*====================================================================*/
1387
1388static int setup_dma_config(struct pcmcia_device *link, int start_pg,
1389                            int stop_pg)
1390{
1391    struct net_device *dev = link->priv;
1392
1393    ei_status.tx_start_page = start_pg;
1394    ei_status.rx_start_page = start_pg + TX_PAGES;
1395    ei_status.stop_page = stop_pg;
1396
1397    /* set up block i/o functions */
1398    ei_status.get_8390_hdr = &dma_get_8390_hdr;
1399    ei_status.block_input = &dma_block_input;
1400    ei_status.block_output = &dma_block_output;
1401
1402    return 0;
1403}
1404
1405/*====================================================================*/
1406
1407static void copyin(void *dest, void __iomem *src, int c)
1408{
1409    u_short *d = dest;
1410    u_short __iomem *s = src;
1411    int odd;
1412
1413    if (c <= 0)
1414        return;
1415    odd = (c & 1); c >>= 1;
1416
1417    if (c) {
1418        do { *d++ = __raw_readw(s++); } while (--c);
1419    }
1420    /* get last byte by fetching a word and masking */
1421    if (odd)
1422        *((u_char *)d) = readw(s) & 0xff;
1423}
1424
1425static void copyout(void __iomem *dest, const void *src, int c)
1426{
1427    u_short __iomem *d = dest;
1428    const u_short *s = src;
1429    int odd;
1430
1431    if (c <= 0)
1432        return;
1433    odd = (c & 1); c >>= 1;
1434
1435    if (c) {
1436        do { __raw_writew(*s++, d++); } while (--c);
1437    }
1438    /* copy last byte doing a read-modify-write */
1439    if (odd)
1440        writew((readw(d) & 0xff00) | *(u_char *)s, d);
1441}
1442
1443/*====================================================================*/
1444
1445static void shmem_get_8390_hdr(struct net_device *dev,
1446                               struct e8390_pkt_hdr *hdr,
1447                               int ring_page)
1448{
1449    void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8)
1450                                + (ring_page << 8)
1451                                - (ei_status.rx_start_page << 8);
1452
1453    copyin(hdr, xfer_start, sizeof(struct e8390_pkt_hdr));
1454    /* Fix for big endian systems */
1455    hdr->count = le16_to_cpu(hdr->count);
1456}
1457
1458/*====================================================================*/
1459
1460static void shmem_block_input(struct net_device *dev, int count,
1461                              struct sk_buff *skb, int ring_offset)
1462{
1463    void __iomem *base = ei_status.mem;
1464    unsigned long offset = (TX_PAGES<<8) + ring_offset
1465                                - (ei_status.rx_start_page << 8);
1466    char *buf = skb->data;
1467
1468    if (offset + count > ei_status.priv) {
1469        /* We must wrap the input move. */
1470        int semi_count = ei_status.priv - offset;
1471        copyin(buf, base + offset, semi_count);
1472        buf += semi_count;
1473        offset = TX_PAGES<<8;
1474        count -= semi_count;
1475    }
1476    copyin(buf, base + offset, count);
1477}
1478
1479/*====================================================================*/
1480
1481static void shmem_block_output(struct net_device *dev, int count,
1482                               const u_char *buf, const int start_page)
1483{
1484    void __iomem *shmem = ei_status.mem + (start_page << 8);
1485    shmem -= ei_status.tx_start_page << 8;
1486    copyout(shmem, buf, count);
1487}
1488
1489/*====================================================================*/
1490
1491static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
1492                              int stop_pg, int cm_offset)
1493{
1494    struct net_device *dev = link->priv;
1495    pcnet_dev_t *info = PRIV(dev);
1496    win_req_t req;
1497    memreq_t mem;
1498    int i, window_size, offset, last_ret, last_fn;
1499
1500    window_size = (stop_pg - start_pg) << 8;
1501    if (window_size > 32 * 1024)
1502        window_size = 32 * 1024;
1503
1504    /* Make sure it's a power of two.  */
1505    window_size = roundup_pow_of_two(window_size);
1506
1507    /* Allocate a memory window */
1508    req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
1509    req.Attributes |= WIN_USE_WAIT;
1510    req.Base = 0; req.Size = window_size;
1511    req.AccessSpeed = mem_speed;
1512    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
1513
1514    mem.CardOffset = (start_pg << 8) + cm_offset;
1515    offset = mem.CardOffset % window_size;
1516    mem.CardOffset -= offset;
1517    mem.Page = 0;
1518    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
1519
1520    /* Try scribbling on the buffer */
1521    info->base = ioremap(req.Base, window_size);
1522    for (i = 0; i < (TX_PAGES<<8); i += 2)
1523        __raw_writew((i>>1), info->base+offset+i);
1524    udelay(100);
1525    for (i = 0; i < (TX_PAGES<<8); i += 2)
1526        if (__raw_readw(info->base+offset+i) != (i>>1)) break;
1527    pcnet_reset_8390(dev);
1528    if (i != (TX_PAGES<<8)) {
1529        iounmap(info->base);
1530        pcmcia_release_window(link->win);
1531        info->base = NULL; link->win = NULL;
1532        goto failed;
1533    }
1534
1535    ei_status.mem = info->base + offset;
1536    ei_status.priv = req.Size;
1537    dev->mem_start = (u_long)ei_status.mem;
1538    dev->mem_end = dev->mem_start + req.Size;
1539
1540    ei_status.tx_start_page = start_pg;
1541    ei_status.rx_start_page = start_pg + TX_PAGES;
1542    ei_status.stop_page = start_pg + ((req.Size - offset) >> 8);
1543
1544    /* set up block i/o functions */
1545    ei_status.get_8390_hdr = &shmem_get_8390_hdr;
1546    ei_status.block_input = &shmem_block_input;
1547    ei_status.block_output = &shmem_block_output;
1548
1549    info->flags |= USE_SHMEM;
1550    return 0;
1551
1552cs_failed:
1553    cs_error(link, last_fn, last_ret);
1554failed:
1555    return 1;
1556}
1557
1558/*====================================================================*/
1559
1560static struct pcmcia_device_id pcnet_ids[] = {
1561        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0057, 0x0021),
1562        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0104, 0x000a),
1563        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0xea15),
1564        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0x3341),
1565        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0xc0ab),
1566        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101),
1567        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab),
1568        PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
1569        PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
1570        PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
1571        PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
1572        PCMCIA_PFC_DEVICE_PROD_ID12(0, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
1573        PCMCIA_PFC_DEVICE_PROD_ID12(0, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
1574        PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
1575        PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
1576        PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away 28.8 PC Card       ", 0xb569a6e5, 0x5bd4ff2c),
1577        PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
1578        PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
1579        PCMCIA_MFC_DEVICE_PROD_ID123(0, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
1580        PCMCIA_MFC_DEVICE_PROD_ID2(0, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
1581        PCMCIA_DEVICE_MANF_CARD(0x0057, 0x1004),
1582        PCMCIA_DEVICE_MANF_CARD(0x0104, 0x000d),
1583        PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0075),
1584        PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0145),
1585        PCMCIA_DEVICE_MANF_CARD(0x0149, 0x0230),
1586        PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530),
1587        PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab),
1588        PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110),
1589        PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
1590        PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041),
1591        PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452),
1592        PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300),
1593        PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0307),
1594        PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a),
1595        PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103),
1596        PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121),
1597        PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941),
1598        PCMCIA_DEVICE_PROD_ID1234("Socket", "CF 10/100 Ethernet Card", "Revision B", "05/11/06", 0xb38bcc2e, 0x4de88352, 0xeaca6c8d, 0x7e57c22e),
1599        PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b),
1600        PCMCIA_DEVICE_PROD_ID123("CNet  ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b),
1601        PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e),
1602        PCMCIA_DEVICE_PROD_ID123("Edimax Technology Inc.", "PCMCIA", "Ethernet Card", 0x738a0019, 0x281f1c5d, 0x5e9d92c0),
1603        PCMCIA_DEVICE_PROD_ID123("EFA   ", "EFA207", "ETHERNET", 0x3d294be4, 0xeb9aab6c, 0x3ff7175b),
1604        PCMCIA_DEVICE_PROD_ID123("I-O DATA", "PCLA", "ETHERNET", 0x1d55d7ec, 0xe4c64d34, 0x3ff7175b),
1605        PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCLATE", "ETHERNET", 0x547e66dc, 0x6b260753, 0x3ff7175b),
1606        PCMCIA_DEVICE_PROD_ID123("KingMax Technology Inc.", "EN10-T2", "PCMCIA Ethernet Card", 0x932b7189, 0x699e4436, 0x6f6652e0),
1607        PCMCIA_DEVICE_PROD_ID123("PCMCIA", "PCMCIA-ETHERNET-CARD", "UE2216", 0x281f1c5d, 0xd4cd2f20, 0xb87add82),
1608        PCMCIA_DEVICE_PROD_ID123("PCMCIA", "PCMCIA-ETHERNET-CARD", "UE2620", 0x281f1c5d, 0xd4cd2f20, 0x7d3d83a8),
1609        PCMCIA_DEVICE_PROD_ID1("2412LAN", 0x67f236ab),
1610        PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2212", 0xdfc6b5b2, 0xcb112a11),
1611        PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2216-PCMCIA-ETHERNET", 0xdfc6b5b2, 0x5542bfff),
1612        PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA100-PCM-T V2 100/10M LAN PC Card", 0xbb7fbdd7, 0xcd91cc68),
1613        PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA100-PCM V2", 0x36634a66, 0xc6d05997),
1614        PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8),
1615        PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA-PCM V3", 0x36634a66, 0x62241d96),
1616        PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8010", 0x5070a7f9, 0x82f96e96),
1617        PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8610", 0x5070a7f9, 0x86741224),
1618        PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8002", 0x93b15570, 0x75ec3efb),
1619        PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8002T", 0x93b15570, 0x461c5247),
1620        PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8010", 0x93b15570, 0x82f96e96),
1621        PCMCIA_DEVICE_PROD_ID12("AnyCom", "ECO Ethernet", 0x578ba6e7, 0x0a9888c1),
1622        PCMCIA_DEVICE_PROD_ID12("AnyCom", "ECO Ethernet 10/100", 0x578ba6e7, 0x939fedbd),
1623        PCMCIA_DEVICE_PROD_ID12("AROWANA", "PCMCIA Ethernet LAN Card", 0x313adbc8, 0x08d9f190),
1624        PCMCIA_DEVICE_PROD_ID12("ASANTE", "FriendlyNet PC Card", 0x3a7ade0f, 0x41c64504),
1625        PCMCIA_DEVICE_PROD_ID12("Billionton", "LNT-10TB", 0x552ab682, 0xeeb1ba6a),
1626        PCMCIA_DEVICE_PROD_ID12("CF", "10Base-Ethernet", 0x44ebf863, 0x93ae4d79),
1627        PCMCIA_DEVICE_PROD_ID12("CNet", "CN40BC Ethernet", 0xbc477dde, 0xfba775a7),
1628        PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "BASEline PCMCIA 10 MBit Ethernetadapter", 0xfa2e424d, 0xe9190d8a),
1629        PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "FASTline PCMCIA 10/100 Fast-Ethernet", 0xfa2e424d, 0x3953d9b9),
1630        PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722),
1631        PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2),
1632        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd),
1633        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d),
1634        PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d),
1635        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-T", 0x5261440f, 0x6705fcaa),
1636        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-TD", 0x5261440f, 0x47d5ca83),
1637        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FastEther PCC-TX", 0x5261440f, 0x485e85d9),
1638        PCMCIA_DEVICE_PROD_ID12("Corega,K.K.", "Ethernet LAN Card", 0x110d26d9, 0x9fd2f0a2),
1639        PCMCIA_DEVICE_PROD_ID12("corega,K.K.", "Ethernet LAN Card", 0x9791a90e, 0x9fd2f0a2),
1640        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "(CG-LAPCCTXD)", 0x5261440f, 0x73ec0d88),
1641        PCMCIA_DEVICE_PROD_ID12("CouplerlessPCMCIA", "100BASE", 0xee5af0ad, 0x7c2add04),
1642        PCMCIA_DEVICE_PROD_ID12("CyQ've", "ELA-010", 0x77008979, 0x9d8d445d),
1643        PCMCIA_DEVICE_PROD_ID12("CyQ've", "ELA-110E 10/100M LAN Card", 0x77008979, 0xfd184814),
1644        PCMCIA_DEVICE_PROD_ID12("DataTrek.", "NetCard ", 0x5cd66d9d, 0x84697ce0),
1645        PCMCIA_DEVICE_PROD_ID12("Dayna Communications, Inc.", "CommuniCard E", 0x0c629325, 0xb4e7dbaf),
1646        PCMCIA_DEVICE_PROD_ID12("Digicom", "Palladio LAN 10/100", 0x697403d8, 0xe160b995),
1647        PCMCIA_DEVICE_PROD_ID12("Digicom", "Palladio LAN 10/100 Dongless", 0x697403d8, 0xa6d3b233),
1648        PCMCIA_DEVICE_PROD_ID12("DIGITAL", "DEPCM-XX", 0x69616cb3, 0xe600e76e),
1649        PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-650", 0x1a424a1c, 0xf28c8398),
1650        PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660", 0x1a424a1c, 0xd9a1d05b),
1651        PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660+", 0x1a424a1c, 0x50dcd0ec),
1652        PCMCIA_DEVICE_PROD_ID12("D-Link", "DFE-650", 0x1a424a1c, 0x0f0073f9),
1653        PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 PC Card", 0x725b842d, 0xf1efee84),
1654        PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 Port Attached PC Card", 0x725b842d, 0x2db1f8e9),
1655        PCMCIA_DEVICE_PROD_ID12("Dynalink", "L10BC", 0x55632fd5, 0xdc65f2b1),
1656        PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L10BC", 0x6a26d1cf, 0xdc65f2b1),
1657        PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L10C", 0x6a26d1cf, 0xc4f84efb),
1658        PCMCIA_DEVICE_PROD_ID12("E-CARD", "E-CARD", 0x6701da11, 0x6701da11),
1659        PCMCIA_DEVICE_PROD_ID12("EIGER Labs Inc.", "Ethernet 10BaseT card", 0x53c864c6, 0xedd059f6),
1660        PCMCIA_DEVICE_PROD_ID12("EIGER Labs Inc.", "Ethernet Combo card", 0x53c864c6, 0x929c486c),
1661        PCMCIA_DEVICE_PROD_ID12("Ethernet", "Adapter", 0x00b2e941, 0x4b0d829e),
1662        PCMCIA_DEVICE_PROD_ID12("Ethernet Adapter", "E2000 PCMCIA Ethernet", 0x96767301, 0x71fbbc61),
1663        PCMCIA_DEVICE_PROD_ID12("Ethernet PCMCIA adapter", "EP-210", 0x8dd86181, 0xf2b52517),
1664        PCMCIA_DEVICE_PROD_ID12("Fast Ethernet", "Adapter", 0xb4be14e3, 0x4b0d829e),
1665        PCMCIA_DEVICE_PROD_ID12("Grey Cell", "GCS2000", 0x2a151fac, 0xf00555cb),
1666        PCMCIA_DEVICE_PROD_ID12("Grey Cell", "GCS2220", 0x2a151fac, 0xc1b7e327),
1667        PCMCIA_DEVICE_PROD_ID12("GVC", "NIC-2000p", 0x76e171bd, 0x6eb1c947),
1668        PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "Ethernet", 0xe3736c88, 0x00b2e941),
1669        PCMCIA_DEVICE_PROD_ID12("IC-CARD", "IC-CARD", 0x60cb09a6, 0x60cb09a6),
1670        PCMCIA_DEVICE_PROD_ID12("IC-CARD+", "IC-CARD+", 0x93693494, 0x93693494),
1671        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b),
1672        PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0),
1673        PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956),
1674        PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64),
1675        PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5),
1676        PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3),
1677        PCMCIA_DEVICE_PROD_ID12("Kingston Technology Corp.", "EtheRx PC Card Ethernet Adapter", 0x313c7be3, 0x0afb54a2),
1678        PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-10/100CD", 0x1b7827b2, 0xcda71d1c),
1679        PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDF", 0x1b7827b2, 0xfec71e40),
1680        PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDL/T", 0x1b7827b2, 0x79fba4f7),
1681        PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDS", 0x1b7827b2, 0x931afaab),
1682        PCMCIA_DEVICE_PROD_ID12("LEMEL", "LM-N89TX PRO", 0xbbefb52f, 0xd2897a97),
1683        PCMCIA_DEVICE_PROD_ID12("Linksys", "Combo PCMCIA EthernetCard (EC2T)", 0x0733cc81, 0x32ee8c78),
1684        PCMCIA_DEVICE_PROD_ID12("LINKSYS", "E-CARD", 0xf7cb0b07, 0x6701da11),
1685        PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", 0x0733cc81, 0x453c3f9d),
1686        PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100)", 0x0733cc81, 0x66c5a389),
1687        PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V2)", 0x0733cc81, 0x3a3b28e9),
1688        PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline + 10/100 Network PC Card (PCM100H1)", 0x733cc81, 0x7a3e5c3a),
1689        PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TX", 0x88fcdeda, 0x6d772737),
1690        PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TE", 0x88fcdeda, 0x0e714bee),
1691        PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN20T", 0x88fcdeda, 0x81090922),
1692        PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN10TE", 0x88fcdeda, 0xc1e2521c),
1693        PCMCIA_DEVICE_PROD_ID12("LONGSHINE", "PCMCIA Ethernet Card", 0xf866b0b0, 0x6f6652e0),
1694        PCMCIA_DEVICE_PROD_ID12("MACNICA", "ME1-JEIDA", 0x20841b68, 0xaf8a3578),
1695        PCMCIA_DEVICE_PROD_ID12("Macsense", "MPC-10", 0xd830297f, 0xd265c307),
1696        PCMCIA_DEVICE_PROD_ID12("Matsushita Electric Industrial Co.,LTD.", "CF-VEL211", 0x44445376, 0x8ded41d4),
1697        PCMCIA_DEVICE_PROD_ID12("MAXTECH", "PCN2000", 0x78d64bc0, 0xca0ca4b8),
1698        PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC2-T", 0x481e0094, 0xa2eb0cf3),
1699        PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC2-TX", 0x481e0094, 0x41a6916c),
1700        PCMCIA_DEVICE_PROD_ID12("Microcom C.E.", "Travel Card LAN 10/100", 0x4b91cec7, 0xe70220d6),
1701        PCMCIA_DEVICE_PROD_ID12("Microdyne", "NE4200", 0x2e6da59b, 0x0478e472),
1702        PCMCIA_DEVICE_PROD_ID12("MIDORI ELEC.", "LT-PCMT", 0x648d55c1, 0xbde526c7),
1703        PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover 4100", 0x36e1191f, 0x60c229b9),
1704        PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover NE4100", 0x36e1191f, 0xa6617ec8),
1705        PCMCIA_DEVICE_PROD_ID12("NEC", "PC-9801N-J12", 0x18df0ba0, 0xbc912d76),
1706        PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA410TX", 0x9aa79dc3, 0x60e5bc0e),
1707        PCMCIA_DEVICE_PROD_ID12("Network Everywhere", "Fast Ethernet 10/100 PC Card", 0x820a67b6, 0x31ed1a5f),
1708        PCMCIA_DEVICE_PROD_ID12("NextCom K.K.", "Next Hawk", 0xaedaec74, 0xad050ef1),
1709        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100Mbps Ethernet Card", 0x281f1c5d, 0x6e41773b),
1710        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet", 0x281f1c5d, 0x00b2e941),
1711        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "ETHERNET", 0x281f1c5d, 0x3ff7175b),
1712        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet 10BaseT Card", 0x281f1c5d, 0x4de2f6c8),
1713        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet Card", 0x281f1c5d, 0x5e9d92c0),
1714        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet Combo card", 0x281f1c5d, 0x929c486c),
1715        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "ETHERNET V1.0", 0x281f1c5d, 0x4d8817c8),
1716        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEthernet", 0x281f1c5d, 0xfe871eeb),
1717        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast-Ethernet", 0x281f1c5d, 0x45f1f3b4),
1718        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FAST ETHERNET CARD", 0x281f1c5d, 0xec5dbca7),
1719        PCMCIA_DEVICE_PROD_ID12("PCMCIA LAN", "Ethernet", 0x7500e246, 0x00b2e941),
1720        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "LNT-10TN", 0x281f1c5d, 0xe707f641),
1721        PCMCIA_DEVICE_PROD_ID12("PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
1722        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "UE2212", 0x281f1c5d, 0xbf17199b),
1723        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "    Ethernet NE2000 Compatible", 0x281f1c5d, 0x42d5d7e1),
1724        PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10baseT 3.3V", 0xebf91155, 0x30074c80),
1725        PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10BaseT 3.3V", 0xebf91155, 0x7f5a4f50),
1726        PCMCIA_DEVICE_PROD_ID12("Psion Dacom", "Gold Card Ethernet", 0xf5f025c2, 0x3a30e110),
1727        PCMCIA_DEVICE_PROD_ID12("=RELIA==", "Ethernet", 0xcdd0644a, 0x00b2e941),
1728        PCMCIA_DEVICE_PROD_ID12("RIOS Systems Co.", "PC CARD3 ETHERNET", 0x7dd33481, 0x10b41826),
1729        PCMCIA_DEVICE_PROD_ID12("RP", "1625B Ethernet NE2000 Compatible", 0xe3e66e22, 0xb96150df),
1730        PCMCIA_DEVICE_PROD_ID12("RPTI", "EP400 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4a7e2ae0),
1731        PCMCIA_DEVICE_PROD_ID12("RPTI", "EP401 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4bcbd7fd),
1732        PCMCIA_DEVICE_PROD_ID12("RPTI LTD.", "EP400", 0xc53ac515, 0x81e39388),
1733        PCMCIA_DEVICE_PROD_ID12("SCM", "Ethernet Combo card", 0xbdc3b102, 0x929c486c),
1734        PCMCIA_DEVICE_PROD_ID12("Seiko Epson Corp.", "Ethernet", 0x09928730, 0x00b2e941),
1735        PCMCIA_DEVICE_PROD_ID12("SMC", "EZCard-10-PCMCIA", 0xc4f8b18b, 0xfb21d265),
1736        PCMCIA_DEVICE_PROD_ID12("Socket Communications Inc", "Socket EA PCMCIA LAN Adapter Revision D", 0xc70a4760, 0x2ade483e),
1737        PCMCIA_DEVICE_PROD_ID12("Socket Communications Inc", "Socket EA PCMCIA LAN Adapter Revision E", 0xc70a4760, 0x5dd978a8),
1738        PCMCIA_DEVICE_PROD_ID12("TDK", "LAK-CD031 for PCMCIA", 0x1eae9475, 0x0ed386fa),
1739        PCMCIA_DEVICE_PROD_ID12("Telecom Device K.K.", "SuperSocket RE450T", 0x466b05f0, 0x8b74bc4f),
1740        PCMCIA_DEVICE_PROD_ID12("Telecom Device K.K.", "SuperSocket RE550T", 0x466b05f0, 0x33c8db2a),
1741        PCMCIA_DEVICE_PROD_ID13("Hypertec",  "EP401", 0x8787bec7, 0xf6e4a31e),
1742        PCMCIA_DEVICE_PROD_ID13("KingMax Technology Inc.", "Ethernet Card", 0x932b7189, 0x5e9d92c0),
1743        PCMCIA_DEVICE_PROD_ID13("LONGSHINE", "EP401", 0xf866b0b0, 0xf6e4a31e),
1744        PCMCIA_DEVICE_PROD_ID13("Xircom", "CFE-10", 0x2e3ee845, 0x22a49f89),
1745        PCMCIA_DEVICE_PROD_ID1("CyQ've 10 Base-T LAN CARD", 0x94faf360),
1746        PCMCIA_DEVICE_PROD_ID1("EP-210 PCMCIA LAN CARD.", 0x8850b4de),
1747        PCMCIA_DEVICE_PROD_ID1("ETHER-C16", 0x06a8514f),
1748        PCMCIA_DEVICE_PROD_ID1("NE2000 Compatible", 0x75b8ad5a),
1749        PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078),
1750        /* too generic! */
1751        /* PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100 Ethernet Card", 0x281f1c5d, 0x11b0ffc0), */
1752        PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
1753        PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
1754        PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
1755        PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
1756        PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
1757        PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
1758        PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
1759        PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
1760        PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
1761        PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
1762        PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
1763        PCMCIA_DEVICE_CIS_PROD_ID12("PMX   ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
1764        PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"),
1765        PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b),
1766        PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0",
1767                0xb4be14e3, 0x43ac239b, 0x0877b627),
1768        PCMCIA_DEVICE_NULL
1769};
1770MODULE_DEVICE_TABLE(pcmcia, pcnet_ids);
1771
1772static struct pcmcia_driver pcnet_driver = {
1773        .drv            = {
1774                .name   = "pcnet_cs",
1775        },
1776        .probe          = pcnet_probe,
1777        .remove         = pcnet_detach,
1778        .owner          = THIS_MODULE,
1779        .id_table       = pcnet_ids,
1780        .suspend        = pcnet_suspend,
1781        .resume         = pcnet_resume,
1782};
1783
1784static int __init init_pcnet_cs(void)
1785{
1786    return pcmcia_register_driver(&pcnet_driver);
1787}
1788
1789static void __exit exit_pcnet_cs(void)
1790{
1791    DEBUG(0, "pcnet_cs: unloading\n");
1792    pcmcia_unregister_driver(&pcnet_driver);
1793}
1794
1795module_init(init_pcnet_cs);
1796module_exit(exit_pcnet_cs);
1797