linux-bk/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 <../drivers/net/8390.h>
  42
  43#include <pcmcia/version.h>
  44#include <pcmcia/cs_types.h>
  45#include <pcmcia/cs.h>
  46#include <pcmcia/cistpl.h>
  47#include <pcmcia/ciscode.h>
  48#include <pcmcia/ds.h>
  49#include <pcmcia/cisreg.h>
  50
  51#include <asm/io.h>
  52#include <asm/system.h>
  53#include <asm/byteorder.h>
  54#include <asm/uaccess.h>
  55
  56#define PCNET_CMD       0x00
  57#define PCNET_DATAPORT  0x10    /* NatSemi-defined port window offset. */
  58#define PCNET_RESET     0x1f    /* Issue a read to reset, a write to clear. */
  59#define PCNET_MISC      0x18    /* For IBM CCAE and Socket EA cards */
  60
  61#define PCNET_START_PG  0x40    /* First page of TX buffer */
  62#define PCNET_STOP_PG   0x80    /* Last page +1 of RX ring */
  63
  64/* Socket EA cards have a larger packet buffer */
  65#define SOCKET_START_PG 0x01
  66#define SOCKET_STOP_PG  0xff
  67
  68#define PCNET_RDC_TIMEOUT (2*HZ/100)    /* Max wait in jiffies for Tx RDC */
  69
  70static char *if_names[] = { "auto", "10baseT", "10base2"};
  71
  72#ifdef PCMCIA_DEBUG
  73static int pc_debug = PCMCIA_DEBUG;
  74module_param(pc_debug, int, 0);
  75#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
  76static char *version =
  77"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
  78#else
  79#define DEBUG(n, args...)
  80#endif
  81
  82/*====================================================================*/
  83
  84/* Module parameters */
  85
  86MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
  87MODULE_DESCRIPTION("NE2000 compatible PCMCIA ethernet driver");
  88MODULE_LICENSE("GPL");
  89
  90#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
  91
  92INT_MODULE_PARM(if_port,        1);     /* Transceiver type */
  93INT_MODULE_PARM(use_big_buf,    1);     /* use 64K packet buffer? */
  94INT_MODULE_PARM(mem_speed,      0);     /* shared mem speed, in ns */
  95INT_MODULE_PARM(delay_output,   0);     /* pause after xmit? */
  96INT_MODULE_PARM(delay_time,     4);     /* in usec */
  97INT_MODULE_PARM(use_shmem,      -1);    /* use shared memory? */
  98INT_MODULE_PARM(full_duplex,    0);     /* full duplex? */
  99
 100/* Ugh!  Let the user hardwire the hardware address for queer cards */
 101static int hw_addr[6] = { 0, /* ... */ };
 102module_param_array(hw_addr, int, NULL, 0);
 103
 104/*====================================================================*/
 105
 106static void mii_phy_probe(struct net_device *dev);
 107static void pcnet_config(dev_link_t *link);
 108static void pcnet_release(dev_link_t *link);
 109static int pcnet_event(event_t event, int priority,
 110                       event_callback_args_t *args);
 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 struct ethtool_ops netdev_ethtool_ops;
 115static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs);
 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(dev_link_t *link, int start_pg,
 120                              int stop_pg, int cm_offset);
 121static int setup_dma_config(dev_link_t *link, int start_pg,
 122                            int stop_pg);
 123
 124static dev_link_t *pcnet_attach(void);
 125static void pcnet_detach(dev_link_t *);
 126
 127static dev_info_t dev_info = "pcnet_cs";
 128static dev_link_t *dev_list;
 129
 130/*====================================================================*/
 131
 132typedef struct hw_info_t {
 133    u_int       offset;
 134    u_char      a0, a1, a2;
 135    u_int       flags;
 136} hw_info_t;
 137
 138#define DELAY_OUTPUT    0x01
 139#define HAS_MISC_REG    0x02
 140#define USE_BIG_BUF     0x04
 141#define HAS_IBM_MISC    0x08
 142#define IS_DL10019      0x10
 143#define IS_DL10022      0x20
 144#define HAS_MII         0x40
 145#define USE_SHMEM       0x80    /* autodetected */
 146
 147#define AM79C9XX_HOME_PHY       0x00006B90  /* HomePNA PHY */
 148#define AM79C9XX_ETH_PHY        0x00006B70  /* 10baseT PHY */
 149#define MII_PHYID_REV_MASK      0xfffffff0
 150#define MII_PHYID_REG1          0x02
 151#define MII_PHYID_REG2          0x03
 152
 153static hw_info_t hw_info[] = {
 154    { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, 
 155    { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
 156    { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
 157    { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
 158      DELAY_OUTPUT | HAS_IBM_MISC },
 159    { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
 160    { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
 161    { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
 162    { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
 163    { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
 164    { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
 165    { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
 166      HAS_MISC_REG | HAS_IBM_MISC },
 167    { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
 168    { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
 169    { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
 170      HAS_MISC_REG | HAS_IBM_MISC },
 171    { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
 172      HAS_MISC_REG | HAS_IBM_MISC },
 173    { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
 174      HAS_MISC_REG | HAS_IBM_MISC },
 175    { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
 176      HAS_MISC_REG | HAS_IBM_MISC },
 177    { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
 178      HAS_MISC_REG | HAS_IBM_MISC },
 179    { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
 180      HAS_MISC_REG | HAS_IBM_MISC },
 181    { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17,
 182      HAS_MISC_REG | HAS_IBM_MISC },
 183    { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
 184      HAS_MISC_REG | HAS_IBM_MISC },
 185    { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
 186      HAS_MISC_REG | HAS_IBM_MISC },
 187    { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
 188      HAS_MISC_REG | HAS_IBM_MISC },
 189    { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
 190    { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
 191    { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
 192      HAS_MISC_REG | HAS_IBM_MISC },
 193    { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
 194      HAS_MISC_REG | HAS_IBM_MISC },
 195    { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
 196    { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
 197    { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
 198    { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
 199    { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
 200      HAS_MISC_REG | HAS_IBM_MISC },
 201    { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, 
 202      HAS_MISC_REG | HAS_IBM_MISC },
 203    { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
 204    { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
 205    { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
 206    { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
 207      DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
 208    { /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 },
 209    { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
 210    { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
 211    { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
 212    { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }
 213};
 214
 215#define NR_INFO         (sizeof(hw_info)/sizeof(hw_info_t))
 216
 217static hw_info_t default_info = { 0, 0, 0, 0, 0 };
 218static hw_info_t dl10019_info = { 0, 0, 0, 0, IS_DL10019|HAS_MII };
 219static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII };
 220
 221typedef struct pcnet_dev_t {
 222    dev_link_t          link;
 223    dev_node_t          node;
 224    u_int               flags;
 225    void                __iomem *base;
 226    struct timer_list   watchdog;
 227    int                 stale, fast_poll;
 228    u_char              phy_id;
 229    u_char              eth_phy, pna_phy;
 230    u_short             link_status;
 231    u_long              mii_reset;
 232} pcnet_dev_t;
 233
 234static inline pcnet_dev_t *PRIV(struct net_device *dev)
 235{
 236        char *p = netdev_priv(dev);
 237        return (pcnet_dev_t *)(p + sizeof(struct ei_device));
 238}
 239
 240/*======================================================================
 241
 242    pcnet_attach() creates an "instance" of the driver, allocating
 243    local data structures for one device.  The device is registered
 244    with Card Services.
 245
 246======================================================================*/
 247
 248static dev_link_t *pcnet_attach(void)
 249{
 250    pcnet_dev_t *info;
 251    dev_link_t *link;
 252    struct net_device *dev;
 253    client_reg_t client_reg;
 254    int ret;
 255
 256    DEBUG(0, "pcnet_attach()\n");
 257
 258    /* Create new ethernet device */
 259    dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
 260    if (!dev) return NULL;
 261    info = PRIV(dev);
 262    link = &info->link;
 263    link->priv = dev;
 264
 265    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
 266    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 267    link->conf.Attributes = CONF_ENABLE_IRQ;
 268    link->conf.IntType = INT_MEMORY_AND_IO;
 269
 270    SET_MODULE_OWNER(dev);
 271    dev->open = &pcnet_open;
 272    dev->stop = &pcnet_close;
 273    dev->set_config = &set_config;
 274
 275    /* Register with Card Services */
 276    link->next = dev_list;
 277    dev_list = link;
 278    client_reg.dev_info = &dev_info;
 279    client_reg.EventMask =
 280        CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 281        CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
 282        CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
 283    client_reg.event_handler = &pcnet_event;
 284    client_reg.Version = 0x0210;
 285    client_reg.event_callback_args.client_data = link;
 286    ret = pcmcia_register_client(&link->handle, &client_reg);
 287    if (ret != CS_SUCCESS) {
 288        cs_error(link->handle, RegisterClient, ret);
 289        pcnet_detach(link);
 290        return NULL;
 291    }
 292
 293    return link;
 294} /* pcnet_attach */
 295
 296/*======================================================================
 297
 298    This deletes a driver "instance".  The device is de-registered
 299    with Card Services.  If it has been released, all local data
 300    structures are freed.  Otherwise, the structures will be freed
 301    when the device is released.
 302
 303======================================================================*/
 304
 305static void pcnet_detach(dev_link_t *link)
 306{
 307    struct net_device *dev = link->priv;
 308    dev_link_t **linkp;
 309
 310    DEBUG(0, "pcnet_detach(0x%p)\n", link);
 311
 312    /* Locate device structure */
 313    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
 314        if (*linkp == link) break;
 315    if (*linkp == NULL)
 316        return;
 317
 318    if (link->dev)
 319        unregister_netdev(dev);
 320
 321    if (link->state & DEV_CONFIG)
 322        pcnet_release(link);
 323
 324    if (link->handle)
 325        pcmcia_deregister_client(link->handle);
 326
 327    /* Unlink device structure, free bits */
 328    *linkp = link->next;
 329    free_netdev(dev);
 330} /* pcnet_detach */
 331
 332/*======================================================================
 333
 334    This probes for a card's hardware address, for card types that
 335    encode this information in their CIS.
 336
 337======================================================================*/
 338
 339static hw_info_t *get_hwinfo(dev_link_t *link)
 340{
 341    struct net_device *dev = link->priv;
 342    win_req_t req;
 343    memreq_t mem;
 344    u_char __iomem *base, *virt;
 345    int i, j;
 346
 347    /* Allocate a small memory window */
 348    req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
 349    req.Base = 0; req.Size = 0;
 350    req.AccessSpeed = 0;
 351    i = pcmcia_request_window(&link->handle, &req, &link->win);
 352    if (i != CS_SUCCESS) {
 353        cs_error(link->handle, RequestWindow, i);
 354        return NULL;
 355    }
 356
 357    virt = ioremap(req.Base, req.Size);
 358    mem.Page = 0;
 359    for (i = 0; i < NR_INFO; i++) {
 360        mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
 361        pcmcia_map_mem_page(link->win, &mem);
 362        base = &virt[hw_info[i].offset & (req.Size-1)];
 363        if ((readb(base+0) == hw_info[i].a0) &&
 364            (readb(base+2) == hw_info[i].a1) &&
 365            (readb(base+4) == hw_info[i].a2))
 366            break;
 367    }
 368    if (i < NR_INFO) {
 369        for (j = 0; j < 6; j++)
 370            dev->dev_addr[j] = readb(base + (j<<1));
 371    }
 372    
 373    iounmap(virt);
 374    j = pcmcia_release_window(link->win);
 375    if (j != CS_SUCCESS)
 376        cs_error(link->handle, ReleaseWindow, j);
 377    return (i < NR_INFO) ? hw_info+i : NULL;
 378} /* get_hwinfo */
 379
 380/*======================================================================
 381
 382    This probes for a card's hardware address by reading the PROM.
 383    It checks the address against a list of known types, then falls
 384    back to a simple NE2000 clone signature check.
 385
 386======================================================================*/
 387
 388static hw_info_t *get_prom(dev_link_t *link)
 389{
 390    struct net_device *dev = link->priv;
 391    kio_addr_t ioaddr = dev->base_addr;
 392    u_char prom[32];
 393    int i, j;
 394
 395    /* This is lifted straight from drivers/net/ne.c */
 396    struct {
 397        u_char value, offset;
 398    } program_seq[] = {
 399        {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
 400        {0x48,  EN0_DCFG},      /* Set byte-wide (0x48) access. */
 401        {0x00,  EN0_RCNTLO},    /* Clear the count regs. */
 402        {0x00,  EN0_RCNTHI},
 403        {0x00,  EN0_IMR},       /* Mask completion irq. */
 404        {0xFF,  EN0_ISR},
 405        {E8390_RXOFF, EN0_RXCR},        /* 0x20  Set to monitor */
 406        {E8390_TXOFF, EN0_TXCR},        /* 0x02  and loopback mode. */
 407        {32,    EN0_RCNTLO},
 408        {0x00,  EN0_RCNTHI},
 409        {0x00,  EN0_RSARLO},    /* DMA starting at 0x0000. */
 410        {0x00,  EN0_RSARHI},
 411        {E8390_RREAD+E8390_START, E8390_CMD},
 412    };
 413
 414    pcnet_reset_8390(dev);
 415    mdelay(10);
 416
 417    for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
 418        outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
 419
 420    for (i = 0; i < 32; i++)
 421        prom[i] = inb(ioaddr + PCNET_DATAPORT);
 422    for (i = 0; i < NR_INFO; i++) {
 423        if ((prom[0] == hw_info[i].a0) &&
 424            (prom[2] == hw_info[i].a1) &&
 425            (prom[4] == hw_info[i].a2))
 426            break;
 427    }
 428    if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
 429        for (j = 0; j < 6; j++)
 430            dev->dev_addr[j] = prom[j<<1];
 431        return (i < NR_INFO) ? hw_info+i : &default_info;
 432    }
 433    return NULL;
 434} /* get_prom */
 435
 436/*======================================================================
 437
 438    For DL10019 based cards, like the Linksys EtherFast
 439
 440======================================================================*/
 441
 442static hw_info_t *get_dl10019(dev_link_t *link)
 443{
 444    struct net_device *dev = link->priv;
 445    int i;
 446    u_char sum;
 447
 448    for (sum = 0, i = 0x14; i < 0x1c; i++)
 449        sum += inb_p(dev->base_addr + i);
 450    if (sum != 0xff)
 451        return NULL;
 452    for (i = 0; i < 6; i++)
 453        dev->dev_addr[i] = inb_p(dev->base_addr + 0x14 + i);
 454    i = inb(dev->base_addr + 0x1f);
 455    return ((i == 0x91)||(i == 0x99)) ? &dl10022_info : &dl10019_info;
 456}
 457
 458/*======================================================================
 459
 460    For Asix AX88190 based cards
 461
 462======================================================================*/
 463
 464static hw_info_t *get_ax88190(dev_link_t *link)
 465{
 466    struct net_device *dev = link->priv;
 467    kio_addr_t ioaddr = dev->base_addr;
 468    int i, j;
 469
 470    /* Not much of a test, but the alternatives are messy */
 471    if (link->conf.ConfigBase != 0x03c0)
 472        return NULL;
 473
 474    outb_p(0x01, ioaddr + EN0_DCFG);    /* Set word-wide access. */
 475    outb_p(0x00, ioaddr + EN0_RSARLO);  /* DMA starting at 0x0400. */
 476    outb_p(0x04, ioaddr + EN0_RSARHI);
 477    outb_p(E8390_RREAD+E8390_START, ioaddr + E8390_CMD);
 478
 479    for (i = 0; i < 6; i += 2) {
 480        j = inw(ioaddr + PCNET_DATAPORT);
 481        dev->dev_addr[i] = j & 0xff;
 482        dev->dev_addr[i+1] = j >> 8;
 483    }
 484    printk(KERN_NOTICE "pcnet_cs: this is an AX88190 card!\n");
 485    printk(KERN_NOTICE "pcnet_cs: use axnet_cs instead.\n");
 486    return NULL;
 487}
 488
 489/*======================================================================
 490
 491    This should be totally unnecessary... but when we can't figure
 492    out the hardware address any other way, we'll let the user hard
 493    wire it when the module is initialized.
 494
 495======================================================================*/
 496
 497static hw_info_t *get_hwired(dev_link_t *link)
 498{
 499    struct net_device *dev = link->priv;
 500    int i;
 501
 502    for (i = 0; i < 6; i++)
 503        if (hw_addr[i] != 0) break;
 504    if (i == 6)
 505        return NULL;
 506
 507    for (i = 0; i < 6; i++)
 508        dev->dev_addr[i] = hw_addr[i];
 509
 510    return &default_info;
 511} /* get_hwired */
 512
 513/*======================================================================
 514
 515    pcnet_config() is scheduled to run after a CARD_INSERTION event
 516    is received, to configure the PCMCIA socket, and to make the
 517    ethernet device available to the system.
 518
 519======================================================================*/
 520
 521#define CS_CHECK(fn, ret) \
 522do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 523
 524static int try_io_port(dev_link_t *link)
 525{
 526    int j, ret;
 527    if (link->io.NumPorts1 == 32) {
 528        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 529        if (link->io.NumPorts2 > 0) {
 530            /* for master/slave multifunction cards */
 531            link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
 532            link->irq.Attributes = 
 533                IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 534        }
 535    } else {
 536        /* This should be two 16-port windows */
 537        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 538        link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
 539    }
 540    if (link->io.BasePort1 == 0) {
 541        link->io.IOAddrLines = 16;
 542        for (j = 0; j < 0x400; j += 0x20) {
 543            link->io.BasePort1 = j ^ 0x300;
 544            link->io.BasePort2 = (j ^ 0x300) + 0x10;
 545            ret = pcmcia_request_io(link->handle, &link->io);
 546            if (ret == CS_SUCCESS) return ret;
 547        }
 548        return ret;
 549    } else {
 550        return pcmcia_request_io(link->handle, &link->io);
 551    }
 552}
 553
 554static void pcnet_config(dev_link_t *link)
 555{
 556    client_handle_t handle = link->handle;
 557    struct net_device *dev = link->priv;
 558    pcnet_dev_t *info = PRIV(dev);
 559    tuple_t tuple;
 560    cisparse_t parse;
 561    int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
 562    int manfid = 0, prodid = 0, has_shmem = 0;
 563    u_short buf[64];
 564    config_info_t conf;
 565    hw_info_t *hw_info;
 566
 567    DEBUG(0, "pcnet_config(0x%p)\n", link);
 568
 569    tuple.Attributes = 0;
 570    tuple.TupleData = (cisdata_t *)buf;
 571    tuple.TupleDataMax = sizeof(buf);
 572    tuple.TupleOffset = 0;
 573    tuple.DesiredTuple = CISTPL_CONFIG;
 574    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
 575    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
 576    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
 577    link->conf.ConfigBase = parse.config.base;
 578    link->conf.Present = parse.config.rmask[0];
 579
 580    /* Configure card */
 581    link->state |= DEV_CONFIG;
 582
 583    /* Look up current Vcc */
 584    CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
 585    link->conf.Vcc = conf.Vcc;
 586
 587    tuple.DesiredTuple = CISTPL_MANFID;
 588    tuple.Attributes = TUPLE_RETURN_COMMON;
 589    if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) &&
 590        (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) {
 591        manfid = le16_to_cpu(buf[0]);
 592        prodid = le16_to_cpu(buf[1]);
 593    }
 594    
 595    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
 596    tuple.Attributes = 0;
 597    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
 598    while (last_ret == CS_SUCCESS) {
 599        cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
 600        cistpl_io_t *io = &(parse.cftable_entry.io);
 601        
 602        if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
 603                        pcmcia_parse_tuple(handle, &tuple, &parse) != 0 ||
 604                        cfg->index == 0 || cfg->io.nwin == 0)
 605                goto next_entry;
 606        
 607        link->conf.ConfigIndex = cfg->index;
 608        /* For multifunction cards, by convention, we configure the
 609           network function with window 0, and serial with window 1 */
 610        if (io->nwin > 1) {
 611            i = (io->win[1].len > io->win[0].len);
 612            link->io.BasePort2 = io->win[1-i].base;
 613            link->io.NumPorts2 = io->win[1-i].len;
 614        } else {
 615            i = link->io.NumPorts2 = 0;
 616        }
 617        has_shmem = ((cfg->mem.nwin == 1) &&
 618                     (cfg->mem.win[0].len >= 0x4000));
 619        link->io.BasePort1 = io->win[i].base;
 620        link->io.NumPorts1 = io->win[i].len;
 621        link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
 622        if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
 623            last_ret = try_io_port(link);
 624            if (last_ret == CS_SUCCESS) break;
 625        }
 626    next_entry:
 627        last_ret = pcmcia_get_next_tuple(handle, &tuple);
 628    }
 629    if (last_ret != CS_SUCCESS) {
 630        cs_error(handle, RequestIO, last_ret);
 631        goto failed;
 632    }
 633
 634    CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
 635    
 636    if (link->io.NumPorts2 == 8) {
 637        link->conf.Attributes |= CONF_ENABLE_SPKR;
 638        link->conf.Status = CCSR_AUDIO_ENA;
 639    }
 640    if ((manfid == MANFID_IBM) &&
 641        (prodid == PRODID_IBM_HOME_AND_AWAY))
 642        link->conf.ConfigIndex |= 0x10;
 643    
 644    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
 645    dev->irq = link->irq.AssignedIRQ;
 646    dev->base_addr = link->io.BasePort1;
 647    if (info->flags & HAS_MISC_REG) {
 648        if ((if_port == 1) || (if_port == 2))
 649            dev->if_port = if_port;
 650        else
 651            printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n");
 652    } else {
 653        dev->if_port = 0;
 654    }
 655
 656    hw_info = get_hwinfo(link);
 657    if (hw_info == NULL)
 658        hw_info = get_prom(link);
 659    if (hw_info == NULL)
 660        hw_info = get_dl10019(link);
 661    if (hw_info == NULL)
 662        hw_info = get_ax88190(link);
 663    if (hw_info == NULL)
 664        hw_info = get_hwired(link);
 665    
 666    if (hw_info == NULL) {
 667        printk(KERN_NOTICE "pcnet_cs: unable to read hardware net"
 668               " address for io base %#3lx\n", dev->base_addr);
 669        goto failed;
 670    }
 671
 672    info->flags = hw_info->flags;
 673    /* Check for user overrides */
 674    info->flags |= (delay_output) ? DELAY_OUTPUT : 0;
 675    if ((manfid == MANFID_SOCKET) &&
 676        ((prodid == PRODID_SOCKET_LPE) ||
 677         (prodid == PRODID_SOCKET_LPE_CF) ||
 678         (prodid == PRODID_SOCKET_EIO)))
 679        info->flags &= ~USE_BIG_BUF;
 680    if (!use_big_buf)
 681        info->flags &= ~USE_BIG_BUF;
 682    
 683    if (info->flags & USE_BIG_BUF) {
 684        start_pg = SOCKET_START_PG;
 685        stop_pg = SOCKET_STOP_PG;
 686        cm_offset = 0x10000;
 687    } else {
 688        start_pg = PCNET_START_PG;
 689        stop_pg = PCNET_STOP_PG;
 690        cm_offset = 0;
 691    }
 692
 693    /* has_shmem is ignored if use_shmem != -1 */
 694    if ((use_shmem == 0) || (!has_shmem && (use_shmem == -1)) ||
 695        (setup_shmem_window(link, start_pg, stop_pg, cm_offset) != 0))
 696        setup_dma_config(link, start_pg, stop_pg);
 697
 698    ei_status.name = "NE2000";
 699    ei_status.word16 = 1;
 700    ei_status.reset_8390 = &pcnet_reset_8390;
 701
 702    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 703
 704    if (info->flags & (IS_DL10019|IS_DL10022)) {
 705        u_char id = inb(dev->base_addr + 0x1a);
 706        dev->do_ioctl = &ei_ioctl;
 707        mii_phy_probe(dev);
 708        if ((id == 0x30) && !info->pna_phy && (info->eth_phy == 4))
 709            info->eth_phy = 0;
 710    }
 711
 712    link->dev = &info->node;
 713    link->state &= ~DEV_CONFIG_PENDING;
 714    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 715
 716#ifdef CONFIG_NET_POLL_CONTROLLER
 717    dev->poll_controller = ei_poll;
 718#endif
 719
 720    if (register_netdev(dev) != 0) {
 721        printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
 722        link->dev = NULL;
 723        goto failed;
 724    }
 725
 726    strcpy(info->node.dev_name, dev->name);
 727
 728    if (info->flags & (IS_DL10019|IS_DL10022)) {
 729        u_char id = inb(dev->base_addr + 0x1a);
 730        printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ",
 731               dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id);
 732        if (info->pna_phy)
 733            printk("PNA, ");
 734    } else {
 735        printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name);
 736    }
 737    printk("io %#3lx, irq %d,", dev->base_addr, dev->irq);
 738    if (info->flags & USE_SHMEM)
 739        printk (" mem %#5lx,", dev->mem_start);
 740    if (info->flags & HAS_MISC_REG)
 741        printk(" %s xcvr,", if_names[dev->if_port]);
 742    printk(" hw_addr ");
 743    for (i = 0; i < 6; i++)
 744        printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
 745    return;
 746
 747cs_failed:
 748    cs_error(link->handle, last_fn, last_ret);
 749failed:
 750    pcnet_release(link);
 751    link->state &= ~DEV_CONFIG_PENDING;
 752    return;
 753} /* pcnet_config */
 754
 755/*======================================================================
 756
 757    After a card is removed, pcnet_release() will unregister the net
 758    device, and release the PCMCIA configuration.  If the device is
 759    still open, this will be postponed until it is closed.
 760
 761======================================================================*/
 762
 763static void pcnet_release(dev_link_t *link)
 764{
 765    pcnet_dev_t *info = PRIV(link->priv);
 766
 767    DEBUG(0, "pcnet_release(0x%p)\n", link);
 768
 769    if (info->flags & USE_SHMEM) {
 770        iounmap(info->base);
 771        pcmcia_release_window(link->win);
 772    }
 773    pcmcia_release_configuration(link->handle);
 774    pcmcia_release_io(link->handle, &link->io);
 775    pcmcia_release_irq(link->handle, &link->irq);
 776
 777    link->state &= ~DEV_CONFIG;
 778}
 779
 780/*======================================================================
 781
 782    The card status event handler.  Mostly, this schedules other
 783    stuff to run after an event is received.  A CARD_REMOVAL event
 784    also sets some flags to discourage the net drivers from trying
 785    to talk to the card any more.
 786
 787======================================================================*/
 788
 789static int pcnet_event(event_t event, int priority,
 790                       event_callback_args_t *args)
 791{
 792    dev_link_t *link = args->client_data;
 793    struct net_device *dev = link->priv;
 794
 795    DEBUG(2, "pcnet_event(0x%06x)\n", event);
 796
 797    switch (event) {
 798    case CS_EVENT_CARD_REMOVAL:
 799        link->state &= ~DEV_PRESENT;
 800        if (link->state & DEV_CONFIG)
 801            netif_device_detach(dev);
 802        break;
 803    case CS_EVENT_CARD_INSERTION:
 804        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 805        pcnet_config(link);
 806        break;
 807    case CS_EVENT_PM_SUSPEND:
 808        link->state |= DEV_SUSPEND;
 809        /* Fall through... */
 810    case CS_EVENT_RESET_PHYSICAL:
 811        if (link->state & DEV_CONFIG) {
 812            if (link->open)
 813                netif_device_detach(dev);
 814            pcmcia_release_configuration(link->handle);
 815        }
 816        break;
 817    case CS_EVENT_PM_RESUME:
 818        link->state &= ~DEV_SUSPEND;
 819        /* Fall through... */
 820    case CS_EVENT_CARD_RESET:
 821        if (link->state & DEV_CONFIG) {
 822            pcmcia_request_configuration(link->handle, &link->conf);
 823            if (link->open) {
 824                pcnet_reset_8390(dev);
 825                NS8390_init(dev, 1);
 826                netif_device_attach(dev);
 827            }
 828        }
 829        break;
 830    }
 831    return 0;
 832} /* pcnet_event */
 833
 834/*======================================================================
 835
 836    MII interface support for DL10019 and DL10022 based cards
 837
 838    On the DL10019, the MII IO direction bit is 0x10; on the DL10022
 839    it is 0x20.  Setting both bits seems to work on both card types.
 840
 841======================================================================*/
 842
 843#define DLINK_GPIO              0x1c
 844#define DLINK_DIAG              0x1d
 845#define DLINK_EEPROM            0x1e
 846
 847#define MDIO_SHIFT_CLK          0x80
 848#define MDIO_DATA_OUT           0x40
 849#define MDIO_DIR_WRITE          0x30
 850#define MDIO_DATA_WRITE0        (MDIO_DIR_WRITE)
 851#define MDIO_DATA_WRITE1        (MDIO_DIR_WRITE | MDIO_DATA_OUT)
 852#define MDIO_DATA_READ          0x10
 853#define MDIO_MASK               0x0f
 854
 855static void mdio_sync(kio_addr_t addr)
 856{
 857    int bits, mask = inb(addr) & MDIO_MASK;
 858    for (bits = 0; bits < 32; bits++) {
 859        outb(mask | MDIO_DATA_WRITE1, addr);
 860        outb(mask | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr);
 861    }
 862}
 863
 864static int mdio_read(kio_addr_t addr, int phy_id, int loc)
 865{
 866    u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
 867    int i, retval = 0, mask = inb(addr) & MDIO_MASK;
 868
 869    mdio_sync(addr);
 870    for (i = 13; i >= 0; i--) {
 871        int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
 872        outb(mask | dat, addr);
 873        outb(mask | dat | MDIO_SHIFT_CLK, addr);
 874    }
 875    for (i = 19; i > 0; i--) {
 876        outb(mask, addr);
 877        retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0);
 878        outb(mask | MDIO_SHIFT_CLK, addr);
 879    }
 880    return (retval>>1) & 0xffff;
 881}
 882
 883static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value)
 884{
 885    u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
 886    int i, mask = inb(addr) & MDIO_MASK;
 887
 888    mdio_sync(addr);
 889    for (i = 31; i >= 0; i--) {
 890        int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
 891        outb(mask | dat, addr);
 892        outb(mask | dat | MDIO_SHIFT_CLK, addr);
 893    }
 894    for (i = 1; i >= 0; i--) {
 895        outb(mask, addr);
 896        outb(mask | MDIO_SHIFT_CLK, addr);
 897    }
 898}
 899
 900static void mdio_reset(kio_addr_t addr, int phy_id)
 901{
 902    outb_p(0x08, addr);
 903    outb_p(0x0c, addr);
 904    outb_p(0x08, addr);
 905    outb_p(0x0c, addr);
 906    outb_p(0x00, addr);
 907}
 908
 909/*======================================================================
 910
 911    EEPROM access routines for DL10019 and DL10022 based cards
 912
 913======================================================================*/
 914
 915#define EE_EEP          0x40
 916#define EE_ASIC         0x10
 917#define EE_CS           0x08
 918#define EE_CK           0x04
 919#define EE_DO           0x02
 920#define EE_DI           0x01
 921#define EE_ADOT         0x01    /* DataOut for ASIC */
 922#define EE_READ_CMD     0x06
 923
 924#define DL19FDUPLX      0x0400  /* DL10019 Full duplex mode */
 925
 926static int read_eeprom(kio_addr_t ioaddr, int location)
 927{
 928    int i, retval = 0;
 929    kio_addr_t ee_addr = ioaddr + DLINK_EEPROM;
 930    int read_cmd = location | (EE_READ_CMD << 8);
 931
 932    outb(0, ee_addr);
 933    outb(EE_EEP|EE_CS, ee_addr);
 934
 935    /* Shift the read command bits out. */
 936    for (i = 10; i >= 0; i--) {
 937        short dataval = (read_cmd & (1 << i)) ? EE_DO : 0;
 938        outb_p(EE_EEP|EE_CS|dataval, ee_addr);
 939        outb_p(EE_EEP|EE_CS|dataval|EE_CK, ee_addr);
 940    }
 941    outb(EE_EEP|EE_CS, ee_addr);
 942
 943    for (i = 16; i > 0; i--) {
 944        outb_p(EE_EEP|EE_CS | EE_CK, ee_addr);
 945        retval = (retval << 1) | ((inb(ee_addr) & EE_DI) ? 1 : 0);
 946        outb_p(EE_EEP|EE_CS, ee_addr);
 947    }
 948
 949    /* Terminate the EEPROM access. */
 950    outb(0, ee_addr);
 951    return retval;
 952}
 953
 954/*
 955    The internal ASIC registers can be changed by EEPROM READ access
 956    with EE_ASIC bit set.
 957    In ASIC mode, EE_ADOT is used to output the data to the ASIC.
 958*/
 959
 960static void write_asic(kio_addr_t ioaddr, int location, short asic_data)
 961{
 962        int i;
 963        kio_addr_t ee_addr = ioaddr + DLINK_EEPROM;
 964        short dataval;
 965        int read_cmd = location | (EE_READ_CMD << 8);
 966
 967        asic_data |= read_eeprom(ioaddr, location);
 968
 969        outb(0, ee_addr);
 970        outb(EE_ASIC|EE_CS|EE_DI, ee_addr);
 971
 972        read_cmd = read_cmd >> 1;
 973
 974        /* Shift the read command bits out. */
 975        for (i = 9; i >= 0; i--) {
 976                dataval = (read_cmd & (1 << i)) ? EE_DO : 0;
 977                outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr);
 978                outb_p(EE_ASIC|EE_CS|EE_DI|dataval|EE_CK, ee_addr);
 979                outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr);
 980        }
 981        // sync
 982        outb(EE_ASIC|EE_CS, ee_addr);
 983        outb(EE_ASIC|EE_CS|EE_CK, ee_addr);
 984        outb(EE_ASIC|EE_CS, ee_addr);
 985
 986        for (i = 15; i >= 0; i--) {
 987                dataval = (asic_data & (1 << i)) ? EE_ADOT : 0;
 988                outb_p(EE_ASIC|EE_CS|dataval, ee_addr);
 989                outb_p(EE_ASIC|EE_CS|dataval|EE_CK, ee_addr);
 990                outb_p(EE_ASIC|EE_CS|dataval, ee_addr);
 991        }
 992
 993        /* Terminate the ASIC access. */
 994        outb(EE_ASIC|EE_DI, ee_addr);
 995        outb(EE_ASIC|EE_DI| EE_CK, ee_addr);
 996        outb(EE_ASIC|EE_DI, ee_addr);
 997
 998        outb(0, ee_addr);
 999}
1000
1001/*====================================================================*/
1002
1003static void set_misc_reg(struct net_device *dev)
1004{
1005    kio_addr_t nic_base = dev->base_addr;
1006    pcnet_dev_t *info = PRIV(dev);
1007    u_char tmp;
1008    
1009    if (info->flags & HAS_MISC_REG) {
1010        tmp = inb_p(nic_base + PCNET_MISC) & ~3;
1011        if (dev->if_port == 2)
1012            tmp |= 1;
1013        if (info->flags & USE_BIG_BUF)
1014            tmp |= 2;
1015        if (info->flags & HAS_IBM_MISC)
1016            tmp |= 8;
1017        outb_p(tmp, nic_base + PCNET_MISC);
1018    }
1019    if (info->flags & IS_DL10022) {
1020        if (info->flags & HAS_MII) {
1021            mdio_reset(nic_base + DLINK_GPIO, info->eth_phy);
1022            /* Restart MII autonegotiation */
1023            mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000);
1024            mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200);
1025            info->mii_reset = jiffies;
1026        } else {
1027            outb(full_duplex ? 4 : 0, nic_base + DLINK_DIAG);
1028        }
1029    }
1030}
1031
1032/*====================================================================*/
1033
1034static void mii_phy_probe(struct net_device *dev)
1035{
1036    pcnet_dev_t *info = PRIV(dev);
1037    kio_addr_t mii_addr = dev->base_addr + DLINK_GPIO;
1038    int i;
1039    u_int tmp, phyid;
1040
1041    for (i = 31; i >= 0; i--) {
1042        tmp = mdio_read(mii_addr, i, 1);
1043        if ((tmp == 0) || (tmp == 0xffff))
1044            continue;
1045        tmp = mdio_read(mii_addr, i, MII_PHYID_REG1);
1046        phyid = tmp << 16;
1047        phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
1048        phyid &= MII_PHYID_REV_MASK;
1049        DEBUG(0, "%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
1050        if (phyid == AM79C9XX_HOME_PHY) {
1051            info->pna_phy = i;
1052        } else if (phyid != AM79C9XX_ETH_PHY) {
1053            info->eth_phy = i;
1054        }
1055    }
1056}
1057
1058static int pcnet_open(struct net_device *dev)
1059{
1060    pcnet_dev_t *info = PRIV(dev);
1061    dev_link_t *link = &info->link;
1062    
1063    DEBUG(2, "pcnet_open('%s')\n", dev->name);
1064
1065    if (!DEV_OK(link))
1066        return -ENODEV;
1067
1068    link->open++;
1069
1070    set_misc_reg(dev);
1071    request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev);
1072
1073    info->phy_id = info->eth_phy;
1074    info->link_status = 0x00;
1075    init_timer(&info->watchdog);
1076    info->watchdog.function = &ei_watchdog;
1077    info->watchdog.data = (u_long)dev;
1078    info->watchdog.expires = jiffies + HZ;
1079    add_timer(&info->watchdog);
1080
1081    return ei_open(dev);
1082} /* pcnet_open */
1083
1084/*====================================================================*/
1085
1086static int pcnet_close(struct net_device *dev)
1087{
1088    pcnet_dev_t *info = PRIV(dev);
1089    dev_link_t *link = &info->link;
1090
1091    DEBUG(2, "pcnet_close('%s')\n", dev->name);
1092
1093    ei_close(dev);
1094    free_irq(dev->irq, dev);
1095    
1096    link->open--;
1097    netif_stop_queue(dev);
1098    del_timer_sync(&info->watchdog);
1099
1100    return 0;
1101} /* pcnet_close */
1102
1103/*======================================================================
1104
1105    Hard reset the card.  This used to pause for the same period that
1106    a 8390 reset command required, but that shouldn't be necessary.
1107
1108======================================================================*/
1109
1110static void pcnet_reset_8390(struct net_device *dev)
1111{
1112    kio_addr_t nic_base = dev->base_addr;
1113    int i;
1114
1115    ei_status.txing = ei_status.dmaing = 0;
1116
1117    outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, nic_base + E8390_CMD);
1118
1119    outb(inb(nic_base + PCNET_RESET), nic_base + PCNET_RESET);
1120
1121    for (i = 0; i < 100; i++) {
1122        if ((inb_p(nic_base+EN0_ISR) & ENISR_RESET) != 0)
1123            break;
1124        udelay(100);
1125    }
1126    outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */
1127    
1128    if (i == 100)
1129        printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n",
1130               dev->name);
1131    set_misc_reg(dev);
1132    
1133} /* pcnet_reset_8390 */
1134
1135/*====================================================================*/
1136
1137static int set_config(struct net_device *dev, struct ifmap *map)
1138{
1139    pcnet_dev_t *info = PRIV(dev);
1140    if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
1141        if (!(info->flags & HAS_MISC_REG))
1142            return -EOPNOTSUPP;
1143        else if ((map->port < 1) || (map->port > 2))
1144            return -EINVAL;
1145        dev->if_port = map->port;
1146        printk(KERN_INFO "%s: switched to %s port\n",
1147               dev->name, if_names[dev->if_port]);
1148        NS8390_init(dev, 1);
1149    }
1150    return 0;
1151}
1152
1153/*====================================================================*/
1154
1155static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
1156{
1157    struct net_device *dev = dev_id;
1158    pcnet_dev_t *info = PRIV(dev);
1159    irqreturn_t ret = ei_interrupt(irq, dev_id, regs);
1160
1161    if (ret == IRQ_HANDLED)
1162            info->stale = 0;
1163    return ret;
1164}
1165
1166static void ei_watchdog(u_long arg)
1167{
1168    struct net_device *dev = (struct net_device *)arg;
1169    pcnet_dev_t *info = PRIV(dev);
1170    kio_addr_t nic_base = dev->base_addr;
1171    kio_addr_t mii_addr = nic_base + DLINK_GPIO;
1172    u_short link;
1173
1174    if (!netif_device_present(dev)) goto reschedule;
1175
1176    /* Check for pending interrupt with expired latency timer: with
1177       this, we can limp along even if the interrupt is blocked */
1178    outb_p(E8390_NODMA+E8390_PAGE0, nic_base + E8390_CMD);
1179    if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
1180        if (!info->fast_poll)
1181            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
1182        ei_irq_wrapper(dev->irq, dev, NULL);
1183        info->fast_poll = HZ;
1184    }
1185    if (info->fast_poll) {
1186        info->fast_poll--;
1187        info->watchdog.expires = jiffies + 1;
1188        add_timer(&info->watchdog);
1189        return;
1190    }
1191
1192    if (!(info->flags & HAS_MII))
1193        goto reschedule;
1194
1195    mdio_read(mii_addr, info->phy_id, 1);
1196    link = mdio_read(mii_addr, info->phy_id, 1);
1197    if (!link || (link == 0xffff)) {
1198        if (info->eth_phy) {
1199            info->phy_id = info->eth_phy = 0;
1200        } else {
1201            printk(KERN_INFO "%s: MII is missing!\n", dev->name);
1202            info->flags &= ~HAS_MII;
1203        }
1204        goto reschedule;
1205    }
1206
1207    link &= 0x0004;
1208    if (link != info->link_status) {
1209        u_short p = mdio_read(mii_addr, info->phy_id, 5);
1210        printk(KERN_INFO "%s: %s link beat\n", dev->name,
1211               (link) ? "found" : "lost");
1212        if (link && (info->flags & IS_DL10022)) {
1213            /* Disable collision detection on full duplex links */
1214            outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG);
1215        } else if (link && (info->flags & IS_DL10019)) {
1216            /* Disable collision detection on full duplex links */
1217            write_asic(dev->base_addr, 4, (p & 0x140) ? DL19FDUPLX : 0);
1218        }
1219        if (link) {
1220            if (info->phy_id == info->eth_phy) {
1221                if (p)
1222                    printk(KERN_INFO "%s: autonegotiation complete: "
1223                           "%sbaseT-%cD selected\n", dev->name,
1224                           ((p & 0x0180) ? "100" : "10"),
1225                           ((p & 0x0140) ? 'F' : 'H'));
1226                else
1227                    printk(KERN_INFO "%s: link partner did not "
1228                           "autonegotiate\n", dev->name);
1229            }
1230            NS8390_init(dev, 1);
1231        }
1232        info->link_status = link;
1233    }
1234    if (info->pna_phy && time_after(jiffies, info->mii_reset + 6*HZ)) {
1235        link = mdio_read(mii_addr, info->eth_phy, 1) & 0x0004;
1236        if (((info->phy_id == info->pna_phy) && link) ||
1237            ((info->phy_id != info->pna_phy) && !link)) {
1238            /* isolate this MII and try flipping to the other one */
1239            mdio_write(mii_addr, info->phy_id, 0, 0x0400);
1240            info->phy_id ^= info->pna_phy ^ info->eth_phy;
1241            printk(KERN_INFO "%s: switched to %s transceiver\n", dev->name,
1242                   (info->phy_id == info->eth_phy) ? "ethernet" : "PNA");
1243            mdio_write(mii_addr, info->phy_id, 0,
1244                       (info->phy_id == info->eth_phy) ? 0x1000 : 0);
1245            info->link_status = 0;
1246            info->mii_reset = jiffies;
1247        }
1248    }
1249
1250reschedule:
1251    info->watchdog.expires = jiffies + HZ;
1252    add_timer(&info->watchdog);
1253}
1254
1255/*====================================================================*/
1256
1257static void netdev_get_drvinfo(struct net_device *dev,
1258                               struct ethtool_drvinfo *info)
1259{
1260        strcpy(info->driver, "pcnet_cs");
1261}
1262
1263static struct ethtool_ops netdev_ethtool_ops = {
1264        .get_drvinfo            = netdev_get_drvinfo,
1265};
1266
1267/*====================================================================*/
1268
1269
1270static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1271{
1272    pcnet_dev_t *info = PRIV(dev);
1273    u16 *data = (u16 *)&rq->ifr_ifru;
1274    kio_addr_t mii_addr = dev->base_addr + DLINK_GPIO;
1275    switch (cmd) {
1276    case SIOCGMIIPHY:
1277        data[0] = info->phy_id;
1278    case SIOCGMIIREG:           /* Read MII PHY register. */
1279        data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f);
1280        return 0;
1281    case SIOCSMIIREG:           /* Write MII PHY register. */
1282        if (!capable(CAP_NET_ADMIN))
1283            return -EPERM;
1284        mdio_write(mii_addr, data[0], data[1] & 0x1f, data[2]);
1285        return 0;
1286    }
1287    return -EOPNOTSUPP;
1288}
1289
1290/*====================================================================*/
1291
1292static void dma_get_8390_hdr(struct net_device *dev,
1293                             struct e8390_pkt_hdr *hdr,
1294                             int ring_page)
1295{
1296    kio_addr_t nic_base = dev->base_addr;
1297
1298    if (ei_status.dmaing) {
1299        printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
1300               "[DMAstat:%1x][irqlock:%1x]\n",
1301               dev->name, ei_status.dmaing, ei_status.irqlock);
1302        return;
1303    }
1304    
1305    ei_status.dmaing |= 0x01;
1306    outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD);
1307    outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
1308    outb_p(0, nic_base + EN0_RCNTHI);
1309    outb_p(0, nic_base + EN0_RSARLO);           /* On page boundary */
1310    outb_p(ring_page, nic_base + EN0_RSARHI);
1311    outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD);
1312
1313    insw(nic_base + PCNET_DATAPORT, hdr,
1314            sizeof(struct e8390_pkt_hdr)>>1);
1315    /* Fix for big endian systems */
1316    hdr->count = le16_to_cpu(hdr->count);
1317
1318    outb_p(ENISR_RDC, nic_base + EN0_ISR);      /* Ack intr. */
1319    ei_status.dmaing &= ~0x01;
1320}
1321
1322/*====================================================================*/
1323
1324static void dma_block_input(struct net_device *dev, int count,
1325                            struct sk_buff *skb, int ring_offset)
1326{
1327    kio_addr_t nic_base = dev->base_addr;
1328    int xfer_count = count;
1329    char *buf = skb->data;
1330
1331#ifdef PCMCIA_DEBUG
1332    if ((ei_debug > 4) && (count != 4))
1333        printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
1334#endif
1335    if (ei_status.dmaing) {
1336        printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
1337               "[DMAstat:%1x][irqlock:%1x]\n",
1338               dev->name, ei_status.dmaing, ei_status.irqlock);
1339        return;
1340    }
1341    ei_status.dmaing |= 0x01;
1342    outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD);
1343    outb_p(count & 0xff, nic_base + EN0_RCNTLO);
1344    outb_p(count >> 8, nic_base + EN0_RCNTHI);
1345    outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
1346    outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
1347    outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD);
1348
1349    insw(nic_base + PCNET_DATAPORT,buf,count>>1);
1350    if (count & 0x01)
1351        buf[count-1] = inb(nic_base + PCNET_DATAPORT), xfer_count++;
1352
1353    /* This was for the ALPHA version only, but enough people have
1354       encountering problems that it is still here. */
1355#ifdef PCMCIA_DEBUG
1356    if (ei_debug > 4) {         /* DMA termination address check... */
1357        int addr, tries = 20;
1358        do {
1359            /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
1360               -- it's broken for Rx on some cards! */
1361            int high = inb_p(nic_base + EN0_RSARHI);
1362            int low = inb_p(nic_base + EN0_RSARLO);
1363            addr = (high << 8) + low;
1364            if (((ring_offset + xfer_count) & 0xff) == (addr & 0xff))
1365                break;
1366        } while (--tries > 0);
1367        if (tries <= 0)
1368            printk(KERN_NOTICE "%s: RX transfer address mismatch,"
1369                   "%#4.4x (expected) vs. %#4.4x (actual).\n",
1370                   dev->name, ring_offset + xfer_count, addr);
1371    }
1372#endif
1373    outb_p(ENISR_RDC, nic_base + EN0_ISR);      /* Ack intr. */
1374    ei_status.dmaing &= ~0x01;
1375} /* dma_block_input */
1376
1377/*====================================================================*/
1378
1379static void dma_block_output(struct net_device *dev, int count,
1380                             const u_char *buf, const int start_page)
1381{
1382    kio_addr_t nic_base = dev->base_addr;
1383    pcnet_dev_t *info = PRIV(dev);
1384#ifdef PCMCIA_DEBUG
1385    int retries = 0;
1386#endif
1387    u_long dma_start;
1388
1389#ifdef PCMCIA_DEBUG
1390    if (ei_debug > 4)
1391        printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
1392#endif
1393
1394    /* Round the count up for word writes.  Do we need to do this?
1395       What effect will an odd byte count have on the 8390?
1396       I should check someday. */
1397    if (count & 0x01)
1398        count++;
1399    if (ei_status.dmaing) {
1400        printk(KERN_NOTICE "%s: DMAing conflict in dma_block_output."
1401               "[DMAstat:%1x][irqlock:%1x]\n",
1402               dev->name, ei_status.dmaing, ei_status.irqlock);
1403        return;
1404    }
1405    ei_status.dmaing |= 0x01;
1406    /* We should already be in page 0, but to be safe... */
1407    outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base+PCNET_CMD);
1408
1409#ifdef PCMCIA_DEBUG
1410  retry:
1411#endif
1412
1413    outb_p(ENISR_RDC, nic_base + EN0_ISR);
1414
1415    /* Now the normal output. */
1416    outb_p(count & 0xff, nic_base + EN0_RCNTLO);
1417    outb_p(count >> 8,   nic_base + EN0_RCNTHI);
1418    outb_p(0x00, nic_base + EN0_RSARLO);
1419    outb_p(start_page, nic_base + EN0_RSARHI);
1420
1421    outb_p(E8390_RWRITE+E8390_START, nic_base + PCNET_CMD);
1422    outsw(nic_base + PCNET_DATAPORT, buf, count>>1);
1423
1424    dma_start = jiffies;
1425
1426#ifdef PCMCIA_DEBUG
1427    /* This was for the ALPHA version only, but enough people have
1428       encountering problems that it is still here. */
1429    if (ei_debug > 4) { /* DMA termination address check... */
1430        int addr, tries = 20;
1431        do {
1432            int high = inb_p(nic_base + EN0_RSARHI);
1433            int low = inb_p(nic_base + EN0_RSARLO);
1434            addr = (high << 8) + low;
1435            if ((start_page << 8) + count == addr)
1436                break;
1437        } while (--tries > 0);
1438        if (tries <= 0) {
1439            printk(KERN_NOTICE "%s: Tx packet transfer address mismatch,"
1440                   "%#4.4x (expected) vs. %#4.4x (actual).\n",
1441                   dev->name, (start_page << 8) + count, addr);
1442            if (retries++ == 0)
1443                goto retry;
1444        }
1445    }
1446#endif
1447
1448    while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
1449        if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) {
1450            printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n",
1451                   dev->name);
1452            pcnet_reset_8390(dev);
1453            NS8390_init(dev, 1);
1454            break;
1455        }
1456
1457    outb_p(ENISR_RDC, nic_base + EN0_ISR);      /* Ack intr. */
1458    if (info->flags & DELAY_OUTPUT)
1459        udelay((long)delay_time);
1460    ei_status.dmaing &= ~0x01;
1461}
1462
1463/*====================================================================*/
1464
1465static int setup_dma_config(dev_link_t *link, int start_pg,
1466                            int stop_pg)
1467{
1468    struct net_device *dev = link->priv;
1469
1470    ei_status.tx_start_page = start_pg;
1471    ei_status.rx_start_page = start_pg + TX_PAGES;
1472    ei_status.stop_page = stop_pg;
1473
1474    /* set up block i/o functions */
1475    ei_status.get_8390_hdr = &dma_get_8390_hdr;
1476    ei_status.block_input = &dma_block_input;
1477    ei_status.block_output = &dma_block_output;
1478
1479    return 0;
1480}
1481
1482/*====================================================================*/
1483
1484static void copyin(void *dest, void __iomem *src, int c)
1485{
1486    u_short *d = dest;
1487    u_short __iomem *s = src;
1488    int odd;
1489
1490    if (c <= 0)
1491        return;
1492    odd = (c & 1); c >>= 1;
1493
1494    if (c) {
1495        do { *d++ = __raw_readw(s++); } while (--c);
1496    }
1497    /* get last byte by fetching a word and masking */
1498    if (odd)
1499        *((u_char *)d) = readw(s) & 0xff;
1500}
1501
1502static void copyout(void __iomem *dest, const void *src, int c)
1503{
1504    u_short __iomem *d = dest;
1505    const u_short *s = src;
1506    int odd;
1507
1508    if (c <= 0)
1509        return;
1510    odd = (c & 1); c >>= 1;
1511
1512    if (c) {
1513        do { __raw_writew(*s++, d++); } while (--c);
1514    }
1515    /* copy last byte doing a read-modify-write */
1516    if (odd)
1517        writew((readw(d) & 0xff00) | *(u_char *)s, d);
1518}
1519
1520/*====================================================================*/
1521
1522static void shmem_get_8390_hdr(struct net_device *dev,
1523                               struct e8390_pkt_hdr *hdr,
1524                               int ring_page)
1525{
1526    void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8)
1527                                + (ring_page << 8)
1528                                - (ei_status.rx_start_page << 8);
1529    
1530    copyin(hdr, xfer_start, sizeof(struct e8390_pkt_hdr));
1531    /* Fix for big endian systems */
1532    hdr->count = le16_to_cpu(hdr->count);
1533}
1534
1535/*====================================================================*/
1536
1537static void shmem_block_input(struct net_device *dev, int count,
1538                              struct sk_buff *skb, int ring_offset)
1539{
1540    void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8)
1541                                + ring_offset
1542                                - (ei_status.rx_start_page << 8);
1543    char *buf = skb->data;
1544    
1545    if (xfer_start + count > (void __iomem *)ei_status.rmem_end) {
1546        /* We must wrap the input move. */
1547        int semi_count = (void __iomem *)ei_status.rmem_end - xfer_start;
1548        copyin(buf, xfer_start, semi_count);
1549        buf += semi_count;
1550        xfer_start = ei_status.mem + (TX_PAGES<<8);
1551        count -= semi_count;
1552    }
1553    copyin(buf, xfer_start, count);
1554}
1555
1556/*====================================================================*/
1557
1558static void shmem_block_output(struct net_device *dev, int count,
1559                               const u_char *buf, const int start_page)
1560{
1561    void __iomem *shmem = ei_status.mem + (start_page << 8);
1562    shmem -= ei_status.tx_start_page << 8;
1563    copyout(shmem, buf, count);
1564}
1565
1566/*====================================================================*/
1567
1568static int setup_shmem_window(dev_link_t *link, int start_pg,
1569                              int stop_pg, int cm_offset)
1570{
1571    struct net_device *dev = link->priv;
1572    pcnet_dev_t *info = PRIV(dev);
1573    win_req_t req;
1574    memreq_t mem;
1575    int i, window_size, offset, last_ret, last_fn;
1576
1577    window_size = (stop_pg - start_pg) << 8;
1578    if (window_size > 32 * 1024)
1579        window_size = 32 * 1024;
1580
1581    /* Make sure it's a power of two.  */
1582    while ((window_size & (window_size - 1)) != 0)
1583        window_size += window_size & ~(window_size - 1);
1584
1585    /* Allocate a memory window */
1586    req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
1587    req.Attributes |= WIN_USE_WAIT;
1588    req.Base = 0; req.Size = window_size;
1589    req.AccessSpeed = mem_speed;
1590    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
1591
1592    mem.CardOffset = (start_pg << 8) + cm_offset;
1593    offset = mem.CardOffset % window_size;
1594    mem.CardOffset -= offset;
1595    mem.Page = 0;
1596    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
1597
1598    /* Try scribbling on the buffer */
1599    info->base = ioremap(req.Base, window_size);
1600    for (i = 0; i < (TX_PAGES<<8); i += 2)
1601        __raw_writew((i>>1), info->base+offset+i);
1602    udelay(100);
1603    for (i = 0; i < (TX_PAGES<<8); i += 2)
1604        if (__raw_readw(info->base+offset+i) != (i>>1)) break;
1605    pcnet_reset_8390(dev);
1606    if (i != (TX_PAGES<<8)) {
1607        iounmap(info->base);
1608        pcmcia_release_window(link->win);
1609        info->base = NULL; link->win = NULL;
1610        goto failed;
1611    }
1612    
1613    ei_status.mem = info->base + offset;
1614    dev->mem_start = (u_long)ei_status.mem;
1615    dev->mem_end = ei_status.rmem_end = (u_long)info->base + req.Size;
1616
1617    ei_status.tx_start_page = start_pg;
1618    ei_status.rx_start_page = start_pg + TX_PAGES;
1619    ei_status.stop_page = start_pg + ((req.Size - offset) >> 8);
1620
1621    /* set up block i/o functions */
1622    ei_status.get_8390_hdr = &shmem_get_8390_hdr;
1623    ei_status.block_input = &shmem_block_input;
1624    ei_status.block_output = &shmem_block_output;
1625
1626    info->flags |= USE_SHMEM;
1627    return 0;
1628
1629cs_failed:
1630    cs_error(link->handle, last_fn, last_ret);
1631failed:
1632    return 1;
1633}
1634
1635/*====================================================================*/
1636
1637static struct pcmcia_driver pcnet_driver = {
1638        .drv            = {
1639                .name   = "pcnet_cs",
1640        },
1641        .attach         = pcnet_attach,
1642        .detach         = pcnet_detach,
1643        .owner          = THIS_MODULE,
1644};
1645
1646static int __init init_pcnet_cs(void)
1647{
1648    return pcmcia_register_driver(&pcnet_driver);
1649}
1650
1651static void __exit exit_pcnet_cs(void)
1652{
1653    DEBUG(0, "pcnet_cs: unloading\n");
1654    pcmcia_unregister_driver(&pcnet_driver);
1655    BUG_ON(dev_list != NULL);
1656}
1657
1658module_init(init_pcnet_cs);
1659module_exit(exit_pcnet_cs);
1660
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.