linux-bk/drivers/net/pcmcia/fmvj18x_cs.c
<<
>>
Prefs
   1/*======================================================================
   2    fmvj18x_cs.c 2.8 2002/03/23
   3
   4    A fmvj18x (and its compatibles) PCMCIA client driver
   5
   6    Contributed by Shingo Fujimoto, shingo@flab.fujitsu.co.jp
   7
   8    TDK LAK-CD021 and CONTEC C-NET(PC)C support added by 
   9    Nobuhiro Katayama, kata-n@po.iijnet.or.jp
  10
  11    The PCMCIA client code is based on code written by David Hinds.
  12    Network code is based on the "FMV-18x driver" by Yutaka TAMIYA
  13    but is actually largely Donald Becker's AT1700 driver, which
  14    carries the following attribution:
  15
  16    Written 1993-94 by Donald Becker.
  17
  18    Copyright 1993 United States Government as represented by the
  19    Director, National Security Agency.
  20    
  21    This software may be used and distributed according to the terms
  22    of the GNU General Public License, incorporated herein by reference.
  23    
  24    The author may be reached as becker@scyld.com, or C/O
  25    Scyld Computing Corporation
  26    410 Severn Ave., Suite 210
  27    Annapolis MD 21403
  28   
  29======================================================================*/
  30
  31#define DRV_NAME        "fmvj18x_cs"
  32#define DRV_VERSION     "2.8"
  33
  34#include <linux/module.h>
  35#include <linux/kernel.h>
  36#include <linux/init.h>
  37#include <linux/ptrace.h>
  38#include <linux/slab.h>
  39#include <linux/string.h>
  40#include <linux/timer.h>
  41#include <linux/interrupt.h>
  42#include <linux/in.h>
  43#include <linux/delay.h>
  44#include <linux/ethtool.h>
  45#include <linux/netdevice.h>
  46#include <linux/etherdevice.h>
  47#include <linux/skbuff.h>
  48#include <linux/if_arp.h>
  49#include <linux/ioport.h>
  50#include <linux/crc32.h>
  51
  52#include <pcmcia/version.h>
  53#include <pcmcia/cs_types.h>
  54#include <pcmcia/cs.h>
  55#include <pcmcia/cistpl.h>
  56#include <pcmcia/ciscode.h>
  57#include <pcmcia/ds.h>
  58
  59#include <asm/uaccess.h>
  60#include <asm/io.h>
  61#include <asm/system.h>
  62
  63/*====================================================================*/
  64
  65/* Module parameters */
  66
  67MODULE_DESCRIPTION("fmvj18x and compatible PCMCIA ethernet driver");
  68MODULE_LICENSE("GPL");
  69
  70#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
  71
  72/* Bit map of interrupts to choose from */
  73/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
  74INT_MODULE_PARM(irq_mask, 0xdeb8);
  75static int irq_list[4] = { -1 };
  76MODULE_PARM(irq_list, "1-4i");
  77
  78/* SRAM configuration */
  79/* 0:4KB*2 TX buffer   else:8KB*2 TX buffer */
  80INT_MODULE_PARM(sram_config, 0);
  81
  82#ifdef PCMCIA_DEBUG
  83INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
  84#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
  85static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
  86#else
  87#define DEBUG(n, args...)
  88#endif
  89
  90/*====================================================================*/
  91/*
  92    PCMCIA event handlers
  93 */
  94static void fmvj18x_config(dev_link_t *link);
  95static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
  96static int fmvj18x_setup_mfc(dev_link_t *link);
  97static void fmvj18x_release(dev_link_t *link);
  98static int fmvj18x_event(event_t event, int priority,
  99                          event_callback_args_t *args);
 100static dev_link_t *fmvj18x_attach(void);
 101static void fmvj18x_detach(dev_link_t *);
 102
 103/*
 104    LAN controller(MBH86960A) specific routines
 105 */
 106static int fjn_config(struct net_device *dev, struct ifmap *map);
 107static int fjn_open(struct net_device *dev);
 108static int fjn_close(struct net_device *dev);
 109static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev);
 110static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 111static void fjn_rx(struct net_device *dev);
 112static void fjn_reset(struct net_device *dev);
 113static struct net_device_stats *fjn_get_stats(struct net_device *dev);
 114static void set_rx_mode(struct net_device *dev);
 115static void fjn_tx_timeout(struct net_device *dev);
 116static struct ethtool_ops netdev_ethtool_ops;
 117
 118static dev_info_t dev_info = "fmvj18x_cs";
 119static dev_link_t *dev_list;
 120
 121/*
 122    card type
 123 */
 124typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN, 
 125               XXX10304
 126} cardtype_t;
 127
 128/*
 129    driver specific data structure
 130*/
 131typedef struct local_info_t {
 132    dev_link_t link;
 133    dev_node_t node;
 134    struct net_device_stats stats;
 135    long open_time;
 136    uint tx_started:1;
 137    uint tx_queue;
 138    u_short tx_queue_len;
 139    cardtype_t cardtype;
 140    u_short sent;
 141    u_char mc_filter[8];
 142} local_info_t;
 143
 144#define MC_FILTERBREAK 64
 145
 146/*====================================================================*/
 147/* 
 148    ioport offset from the base address 
 149 */
 150#define TX_STATUS               0 /* transmit status register */
 151#define RX_STATUS               1 /* receive status register */
 152#define TX_INTR                 2 /* transmit interrupt mask register */
 153#define RX_INTR                 3 /* receive interrupt mask register */
 154#define TX_MODE                 4 /* transmit mode register */
 155#define RX_MODE                 5 /* receive mode register */
 156#define CONFIG_0                6 /* configuration register 0 */
 157#define CONFIG_1                7 /* configuration register 1 */
 158
 159#define NODE_ID                 8 /* node ID register            (bank 0) */
 160#define MAR_ADR                 8 /* multicast address registers (bank 1) */
 161
 162#define DATAPORT                8 /* buffer mem port registers   (bank 2) */
 163#define TX_START               10 /* transmit start register */
 164#define COL_CTRL               11 /* 16 collision control register */
 165#define BMPR12                 12 /* reserved */
 166#define BMPR13                 13 /* reserved */
 167#define RX_SKIP                14 /* skip received packet register */
 168
 169#define LAN_CTRL               16 /* LAN card control register */
 170
 171#define MAC_ID               0x1a /* hardware address */
 172#define UNGERMANN_MAC_ID     0x18 /* UNGERMANN-BASS hardware address */
 173
 174/* 
 175    control bits 
 176 */
 177#define ENA_TMT_OK           0x80
 178#define ENA_TMT_REC          0x20
 179#define ENA_COL              0x04
 180#define ENA_16_COL           0x02
 181#define ENA_TBUS_ERR         0x01
 182
 183#define ENA_PKT_RDY          0x80
 184#define ENA_BUS_ERR          0x40
 185#define ENA_LEN_ERR          0x08
 186#define ENA_ALG_ERR          0x04
 187#define ENA_CRC_ERR          0x02
 188#define ENA_OVR_FLO          0x01
 189
 190/* flags */
 191#define F_TMT_RDY            0x80 /* can accept new packet */
 192#define F_NET_BSY            0x40 /* carrier is detected */
 193#define F_TMT_OK             0x20 /* send packet successfully */
 194#define F_SRT_PKT            0x10 /* short packet error */
 195#define F_COL_ERR            0x04 /* collision error */
 196#define F_16_COL             0x02 /* 16 collision error */
 197#define F_TBUS_ERR           0x01 /* bus read error */
 198
 199#define F_PKT_RDY            0x80 /* packet(s) in buffer */
 200#define F_BUS_ERR            0x40 /* bus read error */
 201#define F_LEN_ERR            0x08 /* short packet */
 202#define F_ALG_ERR            0x04 /* frame error */
 203#define F_CRC_ERR            0x02 /* CRC error */
 204#define F_OVR_FLO            0x01 /* overflow error */
 205
 206#define F_BUF_EMP            0x40 /* receive buffer is empty */
 207
 208#define F_SKP_PKT            0x05 /* drop packet in buffer */
 209
 210/* default bitmaps */
 211#define D_TX_INTR  ( ENA_TMT_OK )
 212#define D_RX_INTR  ( ENA_PKT_RDY | ENA_LEN_ERR \
 213                   | ENA_ALG_ERR | ENA_CRC_ERR | ENA_OVR_FLO )
 214#define TX_STAT_M  ( F_TMT_RDY )
 215#define RX_STAT_M  ( F_PKT_RDY | F_LEN_ERR \
 216                   | F_ALG_ERR | F_CRC_ERR | F_OVR_FLO )
 217
 218/* commands */
 219#define D_TX_MODE            0x06 /* no tests, detect carrier */
 220#define ID_MATCHED           0x02 /* (RX_MODE) */
 221#define RECV_ALL             0x03 /* (RX_MODE) */
 222#define CONFIG0_DFL          0x5a /* 16bit bus, 4K x 2 Tx queues */
 223#define CONFIG0_DFL_1        0x5e /* 16bit bus, 8K x 2 Tx queues */
 224#define CONFIG0_RST          0xda /* Data Link Controller off (CONFIG_0) */
 225#define CONFIG0_RST_1        0xde /* Data Link Controller off (CONFIG_0) */
 226#define BANK_0               0xa0 /* bank 0 (CONFIG_1) */
 227#define BANK_1               0xa4 /* bank 1 (CONFIG_1) */
 228#define BANK_2               0xa8 /* bank 2 (CONFIG_1) */
 229#define CHIP_OFF             0x80 /* contrl chip power off (CONFIG_1) */
 230#define DO_TX                0x80 /* do transmit packet */
 231#define SEND_PKT             0x81 /* send a packet */
 232#define AUTO_MODE            0x07 /* Auto skip packet on 16 col detected */
 233#define MANU_MODE            0x03 /* Stop and skip packet on 16 col */
 234#define TDK_AUTO_MODE        0x47 /* Auto skip packet on 16 col detected */
 235#define TDK_MANU_MODE        0x43 /* Stop and skip packet on 16 col */
 236#define INTR_OFF             0x0d /* LAN controller ignores interrupts */
 237#define INTR_ON              0x1d /* LAN controller will catch interrupts */
 238
 239#define TX_TIMEOUT              ((400*HZ)/1000)
 240
 241#define BANK_0U              0x20 /* bank 0 (CONFIG_1) */
 242#define BANK_1U              0x24 /* bank 1 (CONFIG_1) */
 243#define BANK_2U              0x28 /* bank 2 (CONFIG_1) */
 244
 245static dev_link_t *fmvj18x_attach(void)
 246{
 247    local_info_t *lp;
 248    dev_link_t *link;
 249    struct net_device *dev;
 250    client_reg_t client_reg;
 251    int i, ret;
 252    
 253    DEBUG(0, "fmvj18x_attach()\n");
 254
 255    /* Make up a FMVJ18x specific data structure */
 256    dev = alloc_etherdev(sizeof(local_info_t));
 257    if (!dev)
 258        return NULL;
 259    lp = dev->priv;
 260    link = &lp->link;
 261    link->priv = dev;
 262
 263    /* The io structure describes IO port mapping */
 264    link->io.NumPorts1 = 32;
 265    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 266    link->io.IOAddrLines = 5;
 267
 268    /* Interrupt setup */
 269    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 270    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
 271    if (irq_list[0] == -1)
 272        link->irq.IRQInfo2 = irq_mask;
 273    else
 274        for (i = 0; i < 4; i++)
 275            link->irq.IRQInfo2 |= 1 << irq_list[i];
 276    link->irq.Handler = &fjn_interrupt;
 277    link->irq.Instance = dev;
 278    
 279    /* General socket configuration */
 280    link->conf.Attributes = CONF_ENABLE_IRQ;
 281    link->conf.Vcc = 50;
 282    link->conf.IntType = INT_MEMORY_AND_IO;
 283
 284    /* The FMVJ18x specific entries in the device structure. */
 285    SET_MODULE_OWNER(dev);
 286    dev->hard_start_xmit = &fjn_start_xmit;
 287    dev->set_config = &fjn_config;
 288    dev->get_stats = &fjn_get_stats;
 289    dev->set_multicast_list = &set_rx_mode;
 290    dev->open = &fjn_open;
 291    dev->stop = &fjn_close;
 292#ifdef HAVE_TX_TIMEOUT
 293    dev->tx_timeout = fjn_tx_timeout;
 294    dev->watchdog_timeo = TX_TIMEOUT;
 295#endif
 296    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 297    
 298    /* Register with Card Services */
 299    link->next = dev_list;
 300    dev_list = link;
 301    client_reg.dev_info = &dev_info;
 302    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 303    client_reg.EventMask =
 304        CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 305        CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
 306        CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
 307    client_reg.event_handler = &fmvj18x_event;
 308    client_reg.Version = 0x0210;
 309    client_reg.event_callback_args.client_data = link;
 310    ret = CardServices(RegisterClient, &link->handle, &client_reg);
 311    if (ret != 0) {
 312        cs_error(link->handle, RegisterClient, ret);
 313        fmvj18x_detach(link);
 314        return NULL;
 315    }
 316
 317    return link;
 318} /* fmvj18x_attach */
 319
 320/*====================================================================*/
 321
 322static void fmvj18x_detach(dev_link_t *link)
 323{
 324    struct net_device *dev = link->priv;
 325    dev_link_t **linkp;
 326    
 327    DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
 328    
 329    /* Locate device structure */
 330    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
 331        if (*linkp == link) break;
 332    if (*linkp == NULL)
 333        return;
 334
 335    if (link->state & DEV_CONFIG) {
 336        fmvj18x_release(link);
 337        if (link->state & DEV_STALE_CONFIG)
 338            return;
 339    }
 340
 341    /* Break the link with Card Services */
 342    if (link->handle)
 343        CardServices(DeregisterClient, link->handle);
 344    
 345    /* Unlink device structure, free pieces */
 346    *linkp = link->next;
 347    if (link->dev) {
 348        unregister_netdev(dev);
 349        free_netdev(dev);
 350    } else
 351        kfree(dev);
 352    
 353} /* fmvj18x_detach */
 354
 355/*====================================================================*/
 356
 357#define CS_CHECK(fn, args...) \
 358while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
 359
 360static int mfc_try_io_port(dev_link_t *link)
 361{
 362    int i, ret;
 363    static ioaddr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
 364
 365    for (i = 0; i < 5; i++) {
 366        link->io.BasePort2 = serial_base[i];
 367        link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
 368        if (link->io.BasePort2 == 0) {
 369            link->io.NumPorts2 = 0;
 370            printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
 371        }
 372        ret = CardServices(RequestIO, link->handle, &link->io);
 373        if (ret == CS_SUCCESS) return ret;
 374    }
 375    return ret;
 376}
 377
 378static int ungermann_try_io_port(dev_link_t *link)
 379{
 380    int ret;
 381    ioaddr_t ioaddr;
 382    /*
 383        Ungermann-Bass Access/CARD accepts 0x300,0x320,0x340,0x360
 384        0x380,0x3c0 only for ioport.
 385    */
 386    for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) {
 387        link->io.BasePort1 = ioaddr;
 388        ret = CardServices(RequestIO, link->handle, &link->io);
 389        if (ret == CS_SUCCESS) {
 390            /* calculate ConfigIndex value */
 391            link->conf.ConfigIndex = 
 392                ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22;
 393            return ret;
 394        }
 395    }
 396    return ret; /* RequestIO failed */
 397}
 398
 399static void fmvj18x_config(dev_link_t *link)
 400{
 401    client_handle_t handle = link->handle;
 402    struct net_device *dev = link->priv;
 403    local_info_t *lp = dev->priv;
 404    tuple_t tuple;
 405    cisparse_t parse;
 406    u_short buf[32];
 407    int i, last_fn, last_ret, ret;
 408    ioaddr_t ioaddr;
 409    cardtype_t cardtype;
 410    char *card_name = "unknown";
 411    u_char *node_id;
 412
 413    DEBUG(0, "fmvj18x_config(0x%p)\n", link);
 414
 415    /*
 416       This reads the card's CONFIG tuple to find its configuration
 417       registers.
 418    */
 419    tuple.DesiredTuple = CISTPL_CONFIG;
 420    CS_CHECK(GetFirstTuple, handle, &tuple);
 421    tuple.TupleData = (u_char *)buf;
 422    tuple.TupleDataMax = 64;
 423    tuple.TupleOffset = 0;
 424    CS_CHECK(GetTupleData, handle, &tuple);
 425    CS_CHECK(ParseTuple, handle, &tuple, &parse);
 426    
 427    /* Configure card */
 428    link->state |= DEV_CONFIG;
 429
 430    link->conf.ConfigBase = parse.config.base; 
 431    link->conf.Present = parse.config.rmask[0];
 432
 433    tuple.DesiredTuple = CISTPL_FUNCE;
 434    tuple.TupleOffset = 0;
 435    if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) {
 436        /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
 437        tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
 438        CS_CHECK(GetFirstTuple, handle, &tuple);
 439        CS_CHECK(GetTupleData, handle, &tuple);
 440        CS_CHECK(ParseTuple, handle, &tuple, &parse);
 441        link->conf.ConfigIndex = parse.cftable_entry.index;
 442        tuple.DesiredTuple = CISTPL_MANFID;
 443        if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS)
 444            CS_CHECK(GetTupleData, handle, &tuple);
 445        else
 446            buf[0] = 0xffff;
 447        switch (le16_to_cpu(buf[0])) {
 448        case MANFID_TDK:
 449            cardtype = TDK;
 450            if (le16_to_cpu(buf[1]) == PRODID_TDK_CF010) {
 451                cs_status_t status;
 452                CardServices(GetStatus, handle, &status);
 453                if (status.CardState & CS_EVENT_3VCARD)
 454                    link->conf.Vcc = 33; /* inserted in 3.3V slot */
 455            } else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410) {
 456                /* MultiFunction Card */
 457                link->conf.ConfigBase = 0x800;
 458                link->conf.ConfigIndex = 0x47;
 459                link->io.NumPorts2 = 8;
 460            }
 461            break;
 462        case MANFID_CONTEC:
 463            cardtype = CONTEC;
 464            break;
 465        case MANFID_FUJITSU:
 466            if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10302)
 467                /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302),
 468                   but these are MBH10304 based card. */ 
 469                cardtype = MBH10304;
 470            else if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304)
 471                cardtype = MBH10304;
 472            else
 473                cardtype = LA501;
 474            break;
 475        default:
 476            cardtype = MBH10304;
 477        }
 478    } else {
 479        /* old type card */
 480        tuple.DesiredTuple = CISTPL_MANFID;
 481        if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS)
 482            CS_CHECK(GetTupleData, handle, &tuple);
 483        else
 484            buf[0] = 0xffff;
 485        switch (le16_to_cpu(buf[0])) {
 486        case MANFID_FUJITSU:
 487            if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) {
 488                cardtype = XXX10304;    /* MBH10304 with buggy CIS */
 489                link->conf.ConfigIndex = 0x20;
 490            } else {
 491                cardtype = MBH10302;    /* NextCom NC5310, etc. */
 492                link->conf.ConfigIndex = 1;
 493            }
 494            break;
 495        case MANFID_UNGERMANN:
 496            cardtype = UNGERMANN;
 497            break;
 498        default:
 499            cardtype = MBH10302;
 500            link->conf.ConfigIndex = 1;
 501        }
 502    }
 503
 504    if (link->io.NumPorts2 != 0) {
 505        link->irq.Attributes =
 506                IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
 507        ret = mfc_try_io_port(link);
 508        if (ret != CS_SUCCESS) goto cs_failed;
 509    } else if (cardtype == UNGERMANN) {
 510        ret = ungermann_try_io_port(link);
 511        if (ret != CS_SUCCESS) goto cs_failed;
 512    } else { 
 513        CS_CHECK(RequestIO, link->handle, &link->io);
 514    }
 515    CS_CHECK(RequestIRQ, link->handle, &link->irq);
 516    CS_CHECK(RequestConfiguration, link->handle, &link->conf);
 517    dev->irq = link->irq.AssignedIRQ;
 518    dev->base_addr = link->io.BasePort1;
 519    if (register_netdev(dev) != 0) {
 520        printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
 521        goto failed;
 522    }
 523
 524    if (link->io.BasePort2 != 0)
 525        fmvj18x_setup_mfc(link);
 526
 527    ioaddr = dev->base_addr;
 528
 529    /* Reset controller */
 530    if (sram_config == 0) 
 531        outb(CONFIG0_RST, ioaddr + CONFIG_0);
 532    else
 533        outb(CONFIG0_RST_1, ioaddr + CONFIG_0);
 534
 535    /* Power On chip and select bank 0 */
 536    if (cardtype == MBH10302)
 537        outb(BANK_0, ioaddr + CONFIG_1);
 538    else
 539        outb(BANK_0U, ioaddr + CONFIG_1);
 540    
 541    /* Set hardware address */
 542    switch (cardtype) {
 543    case MBH10304:
 544    case TDK:
 545    case LA501:
 546    case CONTEC:
 547        tuple.DesiredTuple = CISTPL_FUNCE;
 548        tuple.TupleOffset = 0;
 549        CS_CHECK(GetFirstTuple, handle, &tuple);
 550        tuple.TupleOffset = 0;
 551        CS_CHECK(GetTupleData, handle, &tuple);
 552        if (cardtype == MBH10304) {
 553            /* MBH10304's CIS_FUNCE is corrupted */
 554            node_id = &(tuple.TupleData[5]);
 555            card_name = "FMV-J182";
 556        } else {
 557            while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
 558                CS_CHECK(GetNextTuple, handle, &tuple) ;
 559                CS_CHECK(GetTupleData, handle, &tuple) ;
 560            }
 561            node_id = &(tuple.TupleData[2]);
 562            if( cardtype == TDK ) {
 563                card_name = "TDK LAK-CD021";
 564            } else if( cardtype == LA501 ) {
 565                card_name = "LA501";
 566            } else {
 567                card_name = "C-NET(PC)C";
 568            }
 569        }
 570        /* Read MACID from CIS */
 571        for (i = 0; i < 6; i++)
 572            dev->dev_addr[i] = node_id[i];
 573        break;
 574    case UNGERMANN:
 575        /* Read MACID from register */
 576        for (i = 0; i < 6; i++) 
 577            dev->dev_addr[i] = inb(ioaddr + UNGERMANN_MAC_ID + i);
 578        card_name = "Access/CARD";
 579        break;
 580    case XXX10304:
 581        /* Read MACID from Buggy CIS */
 582        if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
 583            printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
 584            unregister_netdev(dev);
 585            goto failed;
 586        }
 587        for (i = 0 ; i < 6; i++) {
 588            dev->dev_addr[i] = tuple.TupleData[i];
 589        }
 590        card_name = "FMV-J182";
 591        break;
 592    case MBH10302:
 593    default:
 594        /* Read MACID from register */
 595        for (i = 0; i < 6; i++) 
 596            dev->dev_addr[i] = inb(ioaddr + MAC_ID + i);
 597        card_name = "FMV-J181";
 598        break;
 599    }
 600
 601    strcpy(lp->node.dev_name, dev->name);
 602    link->dev = &lp->node;
 603
 604    lp->cardtype = cardtype;
 605    /* print current configuration */
 606    printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, hw_addr ", 
 607           dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", 
 608           dev->base_addr, dev->irq);
 609    for (i = 0; i < 6; i++)
 610        printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
 611
 612    link->state &= ~DEV_CONFIG_PENDING;
 613    return;
 614    
 615cs_failed:
 616    /* All Card Services errors end up here */
 617    cs_error(link->handle, last_fn, last_ret);
 618failed:
 619    fmvj18x_release(link);
 620    link->state &= ~DEV_CONFIG_PENDING;
 621
 622} /* fmvj18x_config */
 623/*====================================================================*/
 624
 625static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id)
 626{
 627    win_req_t req;
 628    memreq_t mem;
 629    u_char *base;
 630    int i, j;
 631
 632    /* Allocate a small memory window */
 633    req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
 634    req.Base = 0; req.Size = 0;
 635    req.AccessSpeed = 0;
 636    link->win = (window_handle_t)link->handle;
 637    i = CardServices(RequestWindow, &link->win, &req);
 638    if (i != CS_SUCCESS) {
 639        cs_error(link->handle, RequestWindow, i);
 640        return -1;
 641    }
 642
 643    base = ioremap(req.Base, req.Size);
 644    mem.Page = 0;
 645    mem.CardOffset = 0;
 646    CardServices(MapMemPage, link->win, &mem);
 647
 648    /*
 649     *  MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
 650     *  22 0d xx xx xx 04 06 yy yy yy yy yy yy ff
 651     *  'xx' is garbage.
 652     *  'yy' is MAC address.
 653    */ 
 654    for (i = 0; i < 0x200; i++) {
 655        if (readb(base+i*2) == 0x22) {  
 656            if (readb(base+(i-1)*2) == 0xff
 657             && readb(base+(i+5)*2) == 0x04
 658             && readb(base+(i+6)*2) == 0x06
 659             && readb(base+(i+13)*2) == 0xff) 
 660                break;
 661        }
 662    }
 663
 664    if (i != 0x200) {
 665        for (j = 0 ; j < 6; j++,i++) {
 666            node_id[j] = readb(base+(i+7)*2);
 667        }
 668    }
 669
 670    iounmap(base);
 671    j = CardServices(ReleaseWindow, link->win);
 672    if (j != CS_SUCCESS)
 673        cs_error(link->handle, ReleaseWindow, j);
 674    return (i != 0x200) ? 0 : -1;
 675
 676} /* fmvj18x_get_hwinfo */
 677/*====================================================================*/
 678
 679static int fmvj18x_setup_mfc(dev_link_t *link)
 680{
 681    win_req_t req;
 682    memreq_t mem;
 683    u_char *base;
 684    int i, j;
 685    struct net_device *dev = link->priv;
 686    ioaddr_t ioaddr;
 687
 688    /* Allocate a small memory window */
 689    req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
 690    req.Base = 0; req.Size = 0;
 691    req.AccessSpeed = 0;
 692    link->win = (window_handle_t)link->handle;
 693    i = CardServices(RequestWindow, &link->win, &req);
 694    if (i != CS_SUCCESS) {
 695        cs_error(link->handle, RequestWindow, i);
 696        return -1;
 697    }
 698
 699    base = ioremap(req.Base, req.Size);
 700    mem.Page = 0;
 701    mem.CardOffset = 0;
 702    CardServices(MapMemPage, link->win, &mem);
 703
 704    ioaddr = dev->base_addr;
 705    writeb(0x47, base+0x800);   /* Config Option Register of LAN */
 706    writeb(0x0, base+0x802);    /* Config and Status Register */
 707
 708    writeb(ioaddr & 0xff, base+0x80a);          /* I/O Base(Low) of LAN */
 709    writeb((ioaddr >> 8) & 0xff, base+0x80c);   /* I/O Base(High) of LAN */
 710   
 711    writeb(0x45, base+0x820);   /* Config Option Register of Modem */
 712    writeb(0x8, base+0x822);    /* Config and Status Register */
 713
 714    iounmap(base);
 715    j = CardServices(ReleaseWindow, link->win);
 716    if (j != CS_SUCCESS)
 717        cs_error(link->handle, ReleaseWindow, j);
 718    return 0;
 719
 720}
 721/*====================================================================*/
 722
 723static void fmvj18x_release(dev_link_t *link)
 724{
 725
 726    DEBUG(0, "fmvj18x_release(0x%p)\n", link);
 727
 728    /*
 729       If the device is currently in use, we won't release until it
 730       is actually closed.
 731    */
 732    if (link->open) {
 733        DEBUG(1, "fmvj18x_cs: release postponed, '%s' "
 734              "still open\n", link->dev->dev_name);
 735        link->state |= DEV_STALE_CONFIG;
 736        return;
 737    }
 738
 739    /* Don't bother checking to see if these succeed or not */
 740    CardServices(ReleaseWindow, link->win);
 741    CardServices(ReleaseConfiguration, link->handle);
 742    CardServices(ReleaseIO, link->handle, &link->io);
 743    CardServices(ReleaseIRQ, link->handle, &link->irq);
 744    
 745    link->state &= ~DEV_CONFIG;
 746
 747    if (link->state & DEV_STALE_CONFIG)
 748            fmvj18x_detach(link);
 749}
 750
 751/*====================================================================*/
 752
 753static int fmvj18x_event(event_t event, int priority,
 754                          event_callback_args_t *args)
 755{
 756    dev_link_t *link = args->client_data;
 757    struct net_device *dev = link->priv;
 758
 759    DEBUG(1, "fmvj18x_event(0x%06x)\n", event);
 760    
 761    switch (event) {
 762    case CS_EVENT_CARD_REMOVAL:
 763        link->state &= ~DEV_PRESENT;
 764        if (link->state & DEV_CONFIG) {
 765            netif_device_detach(dev);
 766            fmvj18x_release(link);
 767        }
 768        break;
 769    case CS_EVENT_CARD_INSERTION:
 770        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 771        fmvj18x_config(link);
 772        break;
 773    case CS_EVENT_PM_SUSPEND:
 774        link->state |= DEV_SUSPEND;
 775        /* Fall through... */
 776    case CS_EVENT_RESET_PHYSICAL:
 777        if (link->state & DEV_CONFIG) {
 778            if (link->open)
 779                netif_device_detach(dev);
 780            CardServices(ReleaseConfiguration, link->handle);
 781        }
 782        break;
 783    case CS_EVENT_PM_RESUME:
 784        link->state &= ~DEV_SUSPEND;
 785        /* Fall through... */
 786    case CS_EVENT_CARD_RESET:
 787        if (link->state & DEV_CONFIG) {
 788            CardServices(RequestConfiguration, link->handle, &link->conf);
 789            if (link->open) {
 790                fjn_reset(dev);
 791                netif_device_attach(dev);
 792            }
 793        }
 794        break;
 795    }
 796    return 0;
 797} /* fmvj18x_event */
 798
 799static struct pcmcia_driver fmvj18x_cs_driver = {
 800        .owner          = THIS_MODULE,
 801        .drv            = {
 802                .name   = "fmvj18x_cs",
 803        },
 804        .attach         = fmvj18x_attach,
 805        .detach         = fmvj18x_detach,
 806};
 807
 808static int __init init_fmvj18x_cs(void)
 809{
 810        return pcmcia_register_driver(&fmvj18x_cs_driver);
 811}
 812
 813static void __exit exit_fmvj18x_cs(void)
 814{
 815        pcmcia_unregister_driver(&fmvj18x_cs_driver);
 816        while (dev_list != NULL)
 817                fmvj18x_detach(dev_list);
 818}
 819
 820module_init(init_fmvj18x_cs);
 821module_exit(exit_fmvj18x_cs);
 822
 823/*====================================================================*/
 824
 825static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 826{
 827    struct net_device *dev = dev_id;
 828    local_info_t *lp = dev->priv;
 829    ioaddr_t ioaddr;
 830    unsigned short tx_stat, rx_stat;
 831
 832    if (lp == NULL) {
 833        printk(KERN_NOTICE "fjn_interrupt(): irq %d for "
 834               "unknown device.\n", irq);
 835        return IRQ_NONE;
 836    }
 837    ioaddr = dev->base_addr;
 838
 839    /* avoid multiple interrupts */
 840    outw(0x0000, ioaddr + TX_INTR);
 841
 842    /* wait for a while */
 843    udelay(1);
 844
 845    /* get status */
 846    tx_stat = inb(ioaddr + TX_STATUS);
 847    rx_stat = inb(ioaddr + RX_STATUS);
 848
 849    /* clear status */
 850    outb(tx_stat, ioaddr + TX_STATUS);
 851    outb(rx_stat, ioaddr + RX_STATUS);
 852    
 853    DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
 854    DEBUG(4, "               tx_status %02x.\n", tx_stat);
 855    
 856    if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
 857        /* there is packet(s) in rx buffer */
 858        fjn_rx(dev);
 859    }
 860    if (tx_stat & F_TMT_RDY) {
 861        lp->stats.tx_packets += lp->sent ;
 862        lp->sent = 0 ;
 863        if (lp->tx_queue) {
 864            outb(DO_TX | lp->tx_queue, ioaddr + TX_START);
 865            lp->sent = lp->tx_queue ;
 866            lp->tx_queue = 0;
 867            lp->tx_queue_len = 0;
 868            dev->trans_start = jiffies;
 869        } else {
 870            lp->tx_started = 0;
 871        }
 872        netif_wake_queue(dev);
 873    }
 874    DEBUG(4, "%s: exiting interrupt,\n", dev->name);
 875    DEBUG(4, "    tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
 876
 877    outb(D_TX_INTR, ioaddr + TX_INTR);
 878    outb(D_RX_INTR, ioaddr + RX_INTR);
 879    return IRQ_HANDLED;
 880
 881} /* fjn_interrupt */
 882
 883/*====================================================================*/
 884
 885static void fjn_tx_timeout(struct net_device *dev)
 886{
 887    struct local_info_t *lp = (struct local_info_t *)dev->priv;
 888    ioaddr_t ioaddr = dev->base_addr;
 889
 890    printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n",
 891           dev->name, htons(inw(ioaddr + TX_STATUS)),
 892           inb(ioaddr + TX_STATUS) & F_TMT_RDY
 893           ? "IRQ conflict" : "network cable problem");
 894    printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x "
 895           "%04x %04x %04x %04x %04x.\n",
 896           dev->name, htons(inw(ioaddr + 0)),
 897           htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),
 898           htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
 899           htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
 900           htons(inw(ioaddr +14)));
 901    lp->stats.tx_errors++;
 902    /* ToDo: We should try to restart the adaptor... */
 903    local_irq_disable();
 904    fjn_reset(dev);
 905
 906    lp->tx_started = 0;
 907    lp->tx_queue = 0;
 908    lp->tx_queue_len = 0;
 909    lp->sent = 0;
 910    lp->open_time = jiffies;
 911    local_irq_enable();
 912    netif_wake_queue(dev);
 913}
 914
 915static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
 916{
 917    struct local_info_t *lp = (struct local_info_t *)dev->priv;
 918    ioaddr_t ioaddr = dev->base_addr;
 919    short length = skb->len;
 920    
 921    if (length < ETH_ZLEN)
 922    {
 923        skb = skb_padto(skb, ETH_ZLEN);
 924        if (skb == NULL)
 925                return 0;
 926        length = ETH_ZLEN;
 927    }
 928
 929    netif_stop_queue(dev);
 930
 931    {
 932        unsigned char *buf = skb->data;
 933
 934        if (length > ETH_FRAME_LEN) {
 935            printk(KERN_NOTICE "%s: Attempting to send a large packet"
 936                   " (%d bytes).\n", dev->name, length);
 937            return 1;
 938        }
 939
 940        DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
 941              dev->name, (unsigned long)skb->len);
 942        lp->stats.tx_bytes += skb->len;
 943
 944        /* Disable both interrupts. */
 945        outw(0x0000, ioaddr + TX_INTR);
 946
 947        /* wait for a while */
 948        udelay(1);
 949
 950        outw(length, ioaddr + DATAPORT);
 951        outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
 952
 953        lp->tx_queue++;
 954        lp->tx_queue_len += ((length+3) & ~1);
 955
 956        if (lp->tx_started == 0) {
 957            /* If the Tx is idle, always trigger a transmit. */
 958            outb(DO_TX | lp->tx_queue, ioaddr + TX_START);
 959            lp->sent = lp->tx_queue ;
 960            lp->tx_queue = 0;
 961            lp->tx_queue_len = 0;
 962            dev->trans_start = jiffies;
 963            lp->tx_started = 1;
 964            netif_start_queue(dev);
 965        } else {
 966            if( sram_config == 0 ) {
 967                if (lp->tx_queue_len < (4096 - (ETH_FRAME_LEN +2)) )
 968                    /* Yes, there is room for one more packet. */
 969                    netif_start_queue(dev);
 970            } else {
 971                if (lp->tx_queue_len < (8192 - (ETH_FRAME_LEN +2)) && 
 972                                                lp->tx_queue < 127 )
 973                    /* Yes, there is room for one more packet. */
 974                    netif_start_queue(dev);
 975            }
 976        }
 977
 978        /* Re-enable interrupts */
 979        outb(D_TX_INTR, ioaddr + TX_INTR);
 980        outb(D_RX_INTR, ioaddr + RX_INTR);
 981    }
 982    dev_kfree_skb (skb);
 983
 984    return 0;
 985} /* fjn_start_xmit */
 986
 987/*====================================================================*/
 988
 989static void fjn_reset(struct net_device *dev)
 990{
 991    struct local_info_t *lp = (struct local_info_t *)dev->priv;
 992    ioaddr_t ioaddr = dev->base_addr;
 993    int i;
 994
 995    DEBUG(4, "fjn_reset(%s) called.\n",dev->name);
 996
 997    /* Reset controller */
 998    if( sram_config == 0 ) 
 999        outb(CONFIG0_RST, ioaddr + CONFIG_0);
1000    else
1001        outb(CONFIG0_RST_1, ioaddr + CONFIG_0);
1002
1003    /* Power On chip and select bank 0 */
1004    if (lp->cardtype == MBH10302)
1005        outb(BANK_0, ioaddr + CONFIG_1);
1006    else
1007        outb(BANK_0U, ioaddr + CONFIG_1);
1008
1009    /* Set Tx modes */
1010    outb(D_TX_MODE, ioaddr + TX_MODE);
1011    /* set Rx modes */
1012    outb(ID_MATCHED, ioaddr + RX_MODE);
1013
1014    /* Set hardware address */
1015    for (i = 0; i < 6; i++) 
1016        outb(dev->dev_addr[i], ioaddr + NODE_ID + i);
1017
1018    /* Switch to bank 1 */
1019    if (lp->cardtype == MBH10302)
1020        outb(BANK_1, ioaddr + CONFIG_1);
1021    else
1022        outb(BANK_1U, ioaddr + CONFIG_1);
1023
1024    /* set the multicast table to accept none. */
1025    for (i = 0; i < 6; i++) 
1026        outb(0x00, ioaddr + MAR_ADR + i);
1027
1028    /* Switch to bank 2 (runtime mode) */
1029    if (lp->cardtype == MBH10302)
1030        outb(BANK_2, ioaddr + CONFIG_1);
1031    else
1032        outb(BANK_2U, ioaddr + CONFIG_1);
1033
1034    /* set 16col ctrl bits */
1035    if( lp->cardtype == TDK || lp->cardtype == CONTEC) 
1036        outb(TDK_AUTO_MODE, ioaddr + COL_CTRL);
1037    else
1038        outb(AUTO_MODE, ioaddr + COL_CTRL);
1039
1040    /* clear Reserved Regs */
1041    outb(0x00, ioaddr + BMPR12);
1042    outb(0x00, ioaddr + BMPR13);
1043
1044    /* reset Skip packet reg. */
1045    outb(0x01, ioaddr + RX_SKIP);
1046
1047    /* Enable Tx and Rx */
1048    if( sram_config == 0 )
1049        outb(CONFIG0_DFL, ioaddr + CONFIG_0);
1050    else
1051        outb(CONFIG0_DFL_1, ioaddr + CONFIG_0);
1052
1053    /* Init receive pointer ? */
1054    inw(ioaddr + DATAPORT);
1055    inw(ioaddr + DATAPORT);
1056
1057    /* Clear all status */
1058    outb(0xff, ioaddr + TX_STATUS);
1059    outb(0xff, ioaddr + RX_STATUS);
1060
1061    if (lp->cardtype == MBH10302)
1062        outb(INTR_OFF, ioaddr + LAN_CTRL);
1063
1064    /* Turn on Rx interrupts */
1065    outb(D_TX_INTR, ioaddr + TX_INTR);
1066    outb(D_RX_INTR, ioaddr + RX_INTR);
1067
1068    /* Turn on interrupts from LAN card controller */
1069    if (lp->cardtype == MBH10302)
1070        outb(INTR_ON, ioaddr + LAN_CTRL);
1071} /* fjn_reset */
1072
1073/*====================================================================*/
1074
1075static void fjn_rx(struct net_device *dev)
1076{
1077    struct local_info_t *lp = (struct local_info_t *)dev->priv;
1078    ioaddr_t ioaddr = dev->base_addr;
1079    int boguscount = 10;        /* 5 -> 10: by agy 19940922 */
1080
1081    DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",
1082          dev->name, inb(ioaddr + RX_STATUS));
1083
1084    while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
1085        u_short status = inw(ioaddr + DATAPORT);
1086
1087        DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n",
1088              dev->name, inb(ioaddr + RX_MODE), status);
1089#ifndef final_version
1090        if (status == 0) {
1091            outb(F_SKP_PKT, ioaddr + RX_SKIP);
1092            break;
1093        }
1094#endif
1095        if ((status & 0xF0) != 0x20) {  /* There was an error. */
1096            lp->stats.rx_errors++;
1097            if (status & F_LEN_ERR) lp->stats.rx_length_errors++;
1098            if (status & F_ALG_ERR) lp->stats.rx_frame_errors++;
1099            if (status & F_CRC_ERR) lp->stats.rx_crc_errors++;
1100            if (status & F_OVR_FLO) lp->stats.rx_over_errors++;
1101        } else {
1102            u_short pkt_len = inw(ioaddr + DATAPORT);
1103            /* Malloc up new buffer. */
1104            struct sk_buff *skb;
1105
1106            if (pkt_len > 1550) {
1107                printk(KERN_NOTICE "%s: The FMV-18x claimed a very "
1108                       "large packet, size %d.\n", dev->name, pkt_len);
1109                outb(F_SKP_PKT, ioaddr + RX_SKIP);
1110                lp->stats.rx_errors++;
1111                break;
1112            }
1113            skb = dev_alloc_skb(pkt_len+2);
1114            if (skb == NULL) {
1115                printk(KERN_NOTICE "%s: Memory squeeze, dropping "
1116                       "packet (len %d).\n", dev->name, pkt_len);
1117                outb(F_SKP_PKT, ioaddr + RX_SKIP);
1118                lp->stats.rx_dropped++;
1119                break;
1120            }
1121            skb->dev = dev;
1122
1123            skb_reserve(skb, 2);
1124            insw(ioaddr + DATAPORT, skb_put(skb, pkt_len),
1125                 (pkt_len + 1) >> 1);
1126            skb->protocol = eth_type_trans(skb, dev);
1127
1128#ifdef PCMCIA_DEBUG
1129            if (pc_debug > 5) {
1130                int i;
1131                printk(KERN_DEBUG "%s: Rxed packet of length %d: ",
1132                       dev->name, pkt_len);
1133                for (i = 0; i < 14; i++)
1134                    printk(" %02x", skb->data[i]);
1135                printk(".\n");
1136            }
1137#endif
1138
1139            netif_rx(skb);
1140            dev->last_rx = jiffies;
1141            lp->stats.rx_packets++;
1142            lp->stats.rx_bytes += pkt_len;
1143        }
1144        if (--boguscount <= 0)
1145            break;
1146    }
1147
1148    /* If any worth-while packets have been received, dev_rint()
1149           has done a netif_wake_queue() for us and will work on them
1150           when we get to the bottom-half routine. */
1151/*
1152    if (lp->cardtype != TDK) {
1153        int i;
1154        for (i = 0; i < 20; i++) {
1155            if ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == F_BUF_EMP)
1156                break;
1157            (void)inw(ioaddr + DATAPORT);  /+ dummy status read +/
1158            outb(F_SKP_PKT, ioaddr + RX_SKIP);
1159        }
1160
1161        if (i > 0)
1162            DEBUG(5, "%s: Exint Rx packet with mode %02x after "
1163                  "%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);
1164    }
1165*/
1166
1167    return;
1168} /* fjn_rx */
1169
1170/*====================================================================*/
1171
1172static void netdev_get_drvinfo(struct net_device *dev,
1173                               struct ethtool_drvinfo *info)
1174{
1175        strcpy(info->driver, DRV_NAME);
1176        strcpy(info->version, DRV_VERSION);
1177        sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
1178}
1179
1180#ifdef PCMCIA_DEBUG
1181static u32 netdev_get_msglevel(struct net_device *dev)
1182{
1183        return pc_debug;
1184}
1185
1186static void netdev_set_msglevel(struct net_device *dev, u32 level)
1187{
1188        pc_debug = level;
1189}
1190#endif /* PCMCIA_DEBUG */
1191
1192static struct ethtool_ops netdev_ethtool_ops = {
1193        .get_drvinfo            = netdev_get_drvinfo,
1194#ifdef PCMCIA_DEBUG
1195        .get_msglevel           = netdev_get_msglevel,
1196        .set_msglevel           = netdev_set_msglevel,
1197#endif /* PCMCIA_DEBUG */
1198};
1199
1200static int fjn_config(struct net_device *dev, struct ifmap *map){
1201    return 0;
1202}
1203
1204static int fjn_open(struct net_device *dev)
1205{
1206    struct local_info_t *lp = (struct local_info_t *)dev->priv;
1207    dev_link_t *link = &lp->link;
1208
1209    DEBUG(4, "fjn_open('%s').\n", dev->name);
1210
1211    if (!DEV_OK(link))
1212        return -ENODEV;
1213    
1214    link->open++;
1215    
1216    fjn_reset(dev);
1217    
1218    lp->tx_started = 0;
1219    lp->tx_queue = 0;
1220    lp->tx_queue_len = 0;
1221    lp->open_time = jiffies;
1222    netif_start_queue(dev);
1223    
1224    return 0;
1225} /* fjn_open */
1226
1227/*====================================================================*/
1228
1229static int fjn_close(struct net_device *dev)
1230{
1231    struct local_info_t *lp = (struct local_info_t *)dev->priv;
1232    dev_link_t *link = &lp->link;
1233    ioaddr_t ioaddr = dev->base_addr;
1234
1235    DEBUG(4, "fjn_close('%s').\n", dev->name);
1236
1237    lp->open_time = 0;
1238    netif_stop_queue(dev);
1239
1240    /* Set configuration register 0 to disable Tx and Rx. */
1241    if( sram_config == 0 ) 
1242        outb(CONFIG0_RST ,ioaddr + CONFIG_0);
1243    else
1244        outb(CONFIG0_RST_1 ,ioaddr + CONFIG_0);
1245
1246    /* Update the statistics -- ToDo. */
1247
1248    /* Power-down the chip.  Green, green, green! */
1249    outb(CHIP_OFF ,ioaddr + CONFIG_1);
1250
1251    /* Set the ethernet adaptor disable IRQ */
1252    if (lp->cardtype == MBH10302)
1253        outb(INTR_OFF, ioaddr + LAN_CTRL);
1254
1255    link->open--;
1256    if (link->state & DEV_STALE_CONFIG)
1257            fmvj18x_release(link);
1258
1259    return 0;
1260} /* fjn_close */
1261
1262/*====================================================================*/
1263
1264static struct net_device_stats *fjn_get_stats(struct net_device *dev)
1265{
1266    local_info_t *lp = (local_info_t *)dev->priv;
1267    return &lp->stats;
1268} /* fjn_get_stats */
1269
1270/*====================================================================*/
1271
1272/*
1273  Set the multicast/promiscuous mode for this adaptor.
1274*/
1275
1276static void set_rx_mode(struct net_device *dev)
1277{
1278    ioaddr_t ioaddr = dev->base_addr;
1279    struct local_info_t *lp = (struct local_info_t *)dev->priv;
1280    u_char mc_filter[8];                 /* Multicast hash filter */
1281    u_long flags;
1282    int i;
1283    
1284    if (dev->flags & IFF_PROMISC) {
1285        /* Unconditionally log net taps. */
1286        printk("%s: Promiscuous mode enabled.\n", dev->name);
1287        memset(mc_filter, 0xff, sizeof(mc_filter));
1288        outb(3, ioaddr + RX_MODE);      /* Enable promiscuous mode */
1289    } else if (dev->mc_count > MC_FILTERBREAK
1290               ||  (dev->flags & IFF_ALLMULTI)) {
1291        /* Too many to filter perfectly -- accept all multicasts. */
1292        memset(mc_filter, 0xff, sizeof(mc_filter));
1293        outb(2, ioaddr + RX_MODE);      /* Use normal mode. */
1294    } else if (dev->mc_count == 0) {
1295        memset(mc_filter, 0x00, sizeof(mc_filter));
1296        outb(1, ioaddr + RX_MODE);      /* Ignore almost all multicasts. */
1297    } else {
1298        struct dev_mc_list *mclist;
1299        int i;
1300        
1301        memset(mc_filter, 0, sizeof(mc_filter));
1302        for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
1303             i++, mclist = mclist->next) {
1304            unsigned int bit =
1305                ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;
1306            mc_filter[bit >> 3] |= (1 << bit);
1307        }
1308    }
1309
1310    local_irq_save(flags); 
1311    if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
1312        int saved_bank = inb(ioaddr + CONFIG_1);
1313        /* Switch to bank 1 and set the multicast table. */
1314        outb(0xe4, ioaddr + CONFIG_1);
1315        for (i = 0; i < 8; i++)
1316            outb(mc_filter[i], ioaddr + 8 + i);
1317        memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
1318        outb(saved_bank, ioaddr + CONFIG_1);
1319    }
1320    local_irq_restore(flags);
1321}
1322
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.