Annotation of Gnu-Mach/linux/pcmcia-cs/clients/smc91c92_cs.c, revision 1.1

1.1     ! root        1: /*======================================================================
        !             2: 
        !             3:     A PCMCIA ethernet driver for SMC91c92-based cards.
        !             4: 
        !             5:     This driver supports Megahertz PCMCIA ethernet cards; and
        !             6:     Megahertz, Motorola, Ositech, and Psion Dacom ethernet/modem
        !             7:     multifunction cards.
        !             8: 
        !             9:     Copyright (C) 1999 David A. Hinds -- [email protected]
        !            10: 
        !            11:     smc91c92_cs.c 1.123 2003/08/25 15:57:41
        !            12: 
        !            13:     This driver contains code written by Donald Becker
        !            14:     ([email protected]), Rowan Hughes ([email protected]),
        !            15:     David Hinds ([email protected]), and Erik Stahlman
        !            16:     ([email protected]).  Donald wrote the SMC 91c92 code using parts of
        !            17:     Erik's SMC 91c94 driver.  Rowan wrote a similar driver, and I've
        !            18:     incorporated some parts of his driver here.  I (Dave) wrote most
        !            19:     of the PCMCIA glue code, and the Ositech support code.  Kelly
        !            20:     Stephens ([email protected]) added support for the Motorola
        !            21:     Mariner, with help from Allen Brost.
        !            22: 
        !            23:     This software may be used and distributed according to the terms of
        !            24:     the GNU General Public License, incorporated herein by reference.
        !            25: 
        !            26: ======================================================================*/
        !            27: 
        !            28: #include <linux/module.h>
        !            29: #include <linux/kernel.h>
        !            30: #include <linux/init.h>
        !            31: #include <linux/sched.h>
        !            32: #include <linux/slab.h>
        !            33: #include <linux/string.h>
        !            34: #include <linux/timer.h>
        !            35: #include <linux/interrupt.h>
        !            36: #include <linux/delay.h>
        !            37: #include <linux/crc32.h>
        !            38: #include <asm/io.h>
        !            39: #include <asm/system.h>
        !            40: #include <asm/uaccess.h>
        !            41: 
        !            42: #include <linux/netdevice.h>
        !            43: #include <linux/etherdevice.h>
        !            44: #include <linux/skbuff.h>
        !            45: #include <linux/if_arp.h>
        !            46: #include <linux/ioport.h>
        !            47: 
        !            48: #include <pcmcia/version.h>
        !            49: #include <pcmcia/cs_types.h>
        !            50: #include <pcmcia/cs.h>
        !            51: #include <pcmcia/cistpl.h>
        !            52: #include <pcmcia/cisreg.h>
        !            53: #include <pcmcia/ciscode.h>
        !            54: #include <pcmcia/ds.h>
        !            55: 
        !            56: /* Ositech Seven of Diamonds firmware */
        !            57: #include "ositech.h"
        !            58: 
        !            59: /*====================================================================*/
        !            60: 
        !            61: static char *if_names[] = { "auto", "10baseT", "10base2"};
        !            62: 
        !            63: /* Module parameters */
        !            64: 
        !            65: MODULE_DESCRIPTION("SMC 91c92 series PCMCIA ethernet driver");
        !            66: MODULE_LICENSE("GPL");
        !            67: 
        !            68: #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
        !            69: 
        !            70: /*
        !            71:   Transceiver/media type.
        !            72:    0 = auto
        !            73:    1 = 10baseT (and autoselect if #define AUTOSELECT),
        !            74:    2 = AUI/10base2,
        !            75: */
        !            76: INT_MODULE_PARM(if_port, 0);
        !            77: 
        !            78: /* Bit map of interrupts to choose from. */
        !            79: INT_MODULE_PARM(irq_mask, 0xdeb8);
        !            80: static int irq_list[4] = { -1 };
        !            81: MODULE_PARM(irq_list, "1-4i");
        !            82: 
        !            83: #ifdef PCMCIA_DEBUG
        !            84: INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
        !            85: static const char *version =
        !            86: "smc91c92_cs.c 0.09 1996/8/4 Donald Becker, [email protected].\n";
        !            87: #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
        !            88: #else
        !            89: #define DEBUG(n, args...)
        !            90: #endif
        !            91: 
        !            92: /*====================================================================*/
        !            93: 
        !            94: /* Operational parameter that usually are not changed. */
        !            95: 
        !            96: /* Time in jiffies before concluding Tx hung */
        !            97: #define TX_TIMEOUT             ((400*HZ)/1000)
        !            98: 
        !            99: /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
        !           100: #define INTR_WORK              4
        !           101: 
        !           102: /* Times to check the check the chip before concluding that it doesn't
        !           103:    currently have room for another Tx packet. */
        !           104: #define MEMORY_WAIT_TIME               8
        !           105: 
        !           106: static dev_info_t dev_info = "smc91c92_cs";
        !           107: 
        !           108: static dev_link_t *dev_list;
        !           109: 
        !           110: struct smc_private {
        !           111:     dev_link_t                 link;
        !           112:     struct net_device          dev;
        !           113:     u_short                    manfid;
        !           114:     u_short                    cardid;
        !           115:     struct net_device_stats    stats;
        !           116:     dev_node_t                 node;
        !           117:     struct sk_buff             *saved_skb;
        !           118:     int                                packets_waiting;
        !           119:     caddr_t                    base;
        !           120:     u_short                    cfg;
        !           121:     struct timer_list          media;
        !           122:     int                                watchdog, tx_err;
        !           123:     u_short                    media_status;
        !           124:     u_short                    fast_poll;
        !           125:     u_short                    link_status;
        !           126:     int                                phy_id;
        !           127:     int                                duplex;
        !           128:     int                                rx_ovrn;
        !           129: };
        !           130: 
        !           131: /* Special definitions for Megahertz multifunction cards */
        !           132: #define MEGAHERTZ_ISR          0x0380
        !           133: 
        !           134: /* Special function registers for Motorola Mariner */
        !           135: #define MOT_LAN                        0x0000
        !           136: #define MOT_UART               0x0020
        !           137: #define MOT_EEPROM             0x20
        !           138: 
        !           139: #define MOT_NORMAL \
        !           140: (COR_LEVEL_REQ | COR_FUNC_ENA | COR_ADDR_DECODE | COR_IREQ_ENA)
        !           141: 
        !           142: /* Special function registers for Ositech cards */
        !           143: #define OSITECH_AUI_CTL                0x0c
        !           144: #define OSITECH_PWRDOWN                0x0d
        !           145: #define OSITECH_RESET          0x0e
        !           146: #define OSITECH_ISR            0x0f
        !           147: #define OSITECH_AUI_PWR                0x0c
        !           148: #define OSITECH_RESET_ISR      0x0e
        !           149: 
        !           150: #define OSI_AUI_PWR            0x40
        !           151: #define OSI_LAN_PWRDOWN                0x02
        !           152: #define OSI_MODEM_PWRDOWN      0x01
        !           153: #define OSI_LAN_RESET          0x02
        !           154: #define OSI_MODEM_RESET                0x01
        !           155: 
        !           156: /* Symbolic constants for the SMC91c9* series chips, from Erik Stahlman. */
        !           157: #define        BANK_SELECT             14              /* Window select register. */
        !           158: #define SMC_SELECT_BANK(x)  { outw(x, ioaddr + BANK_SELECT); }
        !           159: 
        !           160: /* Bank 0 registers. */
        !           161: #define        TCR             0       /* transmit control register */
        !           162: #define         TCR_CLEAR      0       /* do NOTHING */
        !           163: #define  TCR_ENABLE    0x0001  /* if this is 1, we can transmit */
        !           164: #define         TCR_PAD_EN     0x0080  /* pads short packets to 64 bytes */
        !           165: #define  TCR_MONCSN    0x0400  /* Monitor Carrier. */
        !           166: #define  TCR_FDUPLX    0x0800  /* Full duplex mode. */
        !           167: #define         TCR_NORMAL TCR_ENABLE | TCR_PAD_EN
        !           168: 
        !           169: #define EPH            2       /* Ethernet Protocol Handler report. */
        !           170: #define  EPH_TX_SUC    0x0001
        !           171: #define  EPH_SNGLCOL   0x0002
        !           172: #define  EPH_MULCOL    0x0004
        !           173: #define  EPH_LTX_MULT  0x0008
        !           174: #define  EPH_16COL     0x0010
        !           175: #define  EPH_SQET      0x0020
        !           176: #define  EPH_LTX_BRD   0x0040
        !           177: #define  EPH_TX_DEFR   0x0080
        !           178: #define  EPH_LAT_COL   0x0200
        !           179: #define  EPH_LOST_CAR  0x0400
        !           180: #define  EPH_EXC_DEF   0x0800
        !           181: #define  EPH_CTR_ROL   0x1000
        !           182: #define  EPH_RX_OVRN   0x2000
        !           183: #define  EPH_LINK_OK   0x4000
        !           184: #define  EPH_TX_UNRN   0x8000
        !           185: #define MEMINFO                8       /* Memory Information Register */
        !           186: #define MEMCFG         10      /* Memory Configuration Register */
        !           187: 
        !           188: /* Bank 1 registers. */
        !           189: #define CONFIG                 0
        !           190: #define  CFG_MII_SELECT                0x8000  /* 91C100 only */
        !           191: #define  CFG_NO_WAIT           0x1000
        !           192: #define  CFG_FULL_STEP         0x0400
        !           193: #define  CFG_SET_SQLCH         0x0200
        !           194: #define  CFG_AUI_SELECT                0x0100
        !           195: #define  CFG_16BIT             0x0080
        !           196: #define  CFG_DIS_LINK          0x0040
        !           197: #define  CFG_STATIC            0x0030
        !           198: #define  CFG_IRQ_SEL_1         0x0004
        !           199: #define  CFG_IRQ_SEL_0         0x0002
        !           200: #define BASE_ADDR              2
        !           201: #define        ADDR0                   4
        !           202: #define        GENERAL                 10
        !           203: #define        CONTROL                 12
        !           204: #define  CTL_STORE             0x0001
        !           205: #define  CTL_RELOAD            0x0002
        !           206: #define  CTL_EE_SELECT         0x0004
        !           207: #define  CTL_TE_ENABLE         0x0020
        !           208: #define  CTL_CR_ENABLE         0x0040
        !           209: #define  CTL_LE_ENABLE         0x0080
        !           210: #define  CTL_AUTO_RELEASE      0x0800
        !           211: #define         CTL_POWERDOWN          0x2000
        !           212: 
        !           213: /* Bank 2 registers. */
        !           214: #define MMU_CMD                0
        !           215: #define         MC_ALLOC       0x20    /* or with number of 256 byte packets */
        !           216: #define         MC_RESET       0x40
        !           217: #define  MC_RELEASE    0x80    /* remove and release the current rx packet */
        !           218: #define  MC_FREEPKT    0xA0    /* Release packet in PNR register */
        !           219: #define  MC_ENQUEUE    0xC0    /* Enqueue the packet for transmit */
        !           220: #define        PNR_ARR         2
        !           221: #define FIFO_PORTS     4
        !           222: #define  FP_RXEMPTY    0x8000
        !           223: #define        POINTER         6
        !           224: #define  PTR_AUTO_INC  0x0040
        !           225: #define  PTR_READ      0x2000
        !           226: #define         PTR_AUTOINC    0x4000
        !           227: #define         PTR_RCV        0x8000
        !           228: #define        DATA_1          8
        !           229: #define        INTERRUPT       12
        !           230: #define  IM_RCV_INT            0x1
        !           231: #define         IM_TX_INT              0x2
        !           232: #define         IM_TX_EMPTY_INT        0x4
        !           233: #define         IM_ALLOC_INT           0x8
        !           234: #define         IM_RX_OVRN_INT         0x10
        !           235: #define         IM_EPH_INT             0x20
        !           236: 
        !           237: #define        RCR             4
        !           238: enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002,
        !           239:             RxEnable = 0x0100, RxStripCRC = 0x0200};
        !           240: #define  RCR_SOFTRESET 0x8000  /* resets the chip */
        !           241: #define         RCR_STRIP_CRC  0x200   /* strips CRC */
        !           242: #define  RCR_ENABLE    0x100   /* IFF this is set, we can receive packets */
        !           243: #define  RCR_ALMUL     0x4     /* receive all multicast packets */
        !           244: #define         RCR_PROMISC    0x2     /* enable promiscuous mode */
        !           245: 
        !           246: /* the normal settings for the RCR register : */
        !           247: #define         RCR_NORMAL     (RCR_STRIP_CRC | RCR_ENABLE)
        !           248: #define  RCR_CLEAR     0x0             /* set it to a base state */
        !           249: #define        COUNTER         6
        !           250: 
        !           251: /* BANK 3 -- not the same values as in smc9194! */
        !           252: #define        MULTICAST0      0
        !           253: #define        MULTICAST2      2
        !           254: #define        MULTICAST4      4
        !           255: #define        MULTICAST6      6
        !           256: #define MGMT           8
        !           257: #define REVISION       0x0a
        !           258: 
        !           259: /* Transmit status bits. */
        !           260: #define TS_SUCCESS 0x0001
        !           261: #define TS_16COL   0x0010
        !           262: #define TS_LATCOL  0x0200
        !           263: #define TS_LOSTCAR 0x0400
        !           264: 
        !           265: /* Receive status bits. */
        !           266: #define RS_ALGNERR     0x8000
        !           267: #define RS_BADCRC      0x2000
        !           268: #define RS_ODDFRAME    0x1000
        !           269: #define RS_TOOLONG     0x0800
        !           270: #define RS_TOOSHORT    0x0400
        !           271: #define RS_MULTICAST   0x0001
        !           272: #define RS_ERRORS      (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
        !           273: 
        !           274: #define set_bits(v, p) outw(inw(p)|(v), (p))
        !           275: #define mask_bits(v, p) outw(inw(p)&(v), (p))
        !           276: 
        !           277: /*====================================================================*/
        !           278: 
        !           279: static dev_link_t *smc91c92_attach(void);
        !           280: static void smc91c92_detach(dev_link_t *);
        !           281: static void smc91c92_config(dev_link_t *link);
        !           282: static void smc91c92_release(u_long arg);
        !           283: static int smc91c92_event(event_t event, int priority,
        !           284:                          event_callback_args_t *args);
        !           285: 
        !           286: static int smc_open(struct net_device *dev);
        !           287: static int smc_close(struct net_device *dev);
        !           288: static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
        !           289: static void smc_tx_timeout(struct net_device *dev);
        !           290: static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev);
        !           291: static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
        !           292: static void smc_rx(struct net_device *dev);
        !           293: static struct net_device_stats *smc_get_stats(struct net_device *dev);
        !           294: static void set_rx_mode(struct net_device *dev);
        !           295: static int s9k_config(struct net_device *dev, struct ifmap *map);
        !           296: static void smc_set_xcvr(struct net_device *dev, int if_port);
        !           297: static void smc_reset(struct net_device *dev);
        !           298: static void media_check(u_long arg);
        !           299: static void mdio_sync(ioaddr_t addr);
        !           300: static int mdio_read(struct net_device *dev, int phy_id, int loc);
        !           301: static void mdio_write(struct net_device *dev, int phy_id, int loc, int value);
        !           302: 
        !           303: /*======================================================================
        !           304: 
        !           305:     This bit of code is used to avoid unregistering network devices
        !           306:     at inappropriate times.  2.2 and later kernels are fairly picky
        !           307:     about when this can happen.
        !           308: 
        !           309: ======================================================================*/
        !           310: 
        !           311: static void flush_stale_links(void)
        !           312: {
        !           313:     dev_link_t *link, *next;
        !           314:     for (link = dev_list; link; link = next) {
        !           315:        next = link->next;
        !           316:        if (link->state & DEV_STALE_LINK)
        !           317:            smc91c92_detach(link);
        !           318:     }
        !           319: }
        !           320: 
        !           321: /*====================================================================*/
        !           322: 
        !           323: static void cs_error(client_handle_t handle, int func, int ret)
        !           324: {
        !           325:     error_info_t err = { func, ret };
        !           326:     CardServices(ReportError, handle, &err);
        !           327: }
        !           328: 
        !           329: /*======================================================================
        !           330: 
        !           331:   smc91c92_attach() creates an "instance" of the driver, allocating
        !           332:   local data structures for one device.  The device is registered
        !           333:   with Card Services.
        !           334: 
        !           335: ======================================================================*/
        !           336: 
        !           337: static dev_link_t *smc91c92_attach(void)
        !           338: {
        !           339:     client_reg_t client_reg;
        !           340:     struct smc_private *smc;
        !           341:     dev_link_t *link;
        !           342:     struct net_device *dev;
        !           343:     int i, ret;
        !           344: 
        !           345:     DEBUG(0, "smc91c92_attach()\n");
        !           346:     flush_stale_links();
        !           347: 
        !           348:     /* Create new ethernet device */
        !           349:     smc = kmalloc(sizeof(struct smc_private), GFP_KERNEL);
        !           350:     if (!smc) return NULL;
        !           351:     memset(smc, 0, sizeof(struct smc_private));
        !           352:     link = &smc->link; dev = &smc->dev;
        !           353: 
        !           354:     init_timer(&link->release);
        !           355:     link->release.function = &smc91c92_release;
        !           356:     link->release.data = (u_long)link;
        !           357:     link->io.NumPorts1 = 16;
        !           358:     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        !           359:     link->io.IOAddrLines = 4;
        !           360:     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
        !           361:     link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
        !           362:     if (irq_list[0] == -1)
        !           363:        link->irq.IRQInfo2 = irq_mask;
        !           364:     else
        !           365:        for (i = 0; i < 4; i++)
        !           366:            link->irq.IRQInfo2 |= 1 << irq_list[i];
        !           367:     link->irq.Handler = &smc_interrupt;
        !           368:     link->conf.Attributes = CONF_ENABLE_IRQ;
        !           369:     link->conf.Vcc = 50;
        !           370:     link->conf.IntType = INT_MEMORY_AND_IO;
        !           371: 
        !           372:     /* The SMC91c92-specific entries in the device structure. */
        !           373:     dev->hard_start_xmit = &smc_start_xmit;
        !           374:     dev->get_stats = &smc_get_stats;
        !           375:     dev->set_config = &s9k_config;
        !           376:     dev->set_multicast_list = &set_rx_mode;
        !           377:     ether_setup(dev);
        !           378:     init_dev_name(dev, smc->node);
        !           379:     dev->open = &smc_open;
        !           380:     dev->stop = &smc_close;
        !           381:     dev->do_ioctl = &smc_ioctl;
        !           382: #ifdef HAVE_TX_TIMEOUT
        !           383:     dev->tx_timeout = smc_tx_timeout;
        !           384:     dev->watchdog_timeo = TX_TIMEOUT;
        !           385: #endif
        !           386:     dev->priv = link->priv = link->irq.Instance = smc;
        !           387: 
        !           388:     /* Register with Card Services */
        !           389:     link->next = dev_list;
        !           390:     dev_list = link;
        !           391:     client_reg.dev_info = &dev_info;
        !           392:     client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
        !           393:     client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
        !           394:        CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
        !           395:        CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
        !           396:     client_reg.event_handler = &smc91c92_event;
        !           397:     client_reg.Version = 0x0210;
        !           398:     client_reg.event_callback_args.client_data = link;
        !           399:     ret = CardServices(RegisterClient, &link->handle, &client_reg);
        !           400:     if (ret != 0) {
        !           401:        cs_error(link->handle, RegisterClient, ret);
        !           402:        smc91c92_detach(link);
        !           403:        return NULL;
        !           404:     }
        !           405: 
        !           406:     return link;
        !           407: } /* smc91c92_attach */
        !           408: 
        !           409: /*======================================================================
        !           410: 
        !           411:     This deletes a driver "instance".  The device is de-registered
        !           412:     with Card Services.  If it has been released, all local data
        !           413:     structures are freed.  Otherwise, the structures will be freed
        !           414:     when the device is released.
        !           415: 
        !           416: ======================================================================*/
        !           417: 
        !           418: static void smc91c92_detach(dev_link_t *link)
        !           419: {
        !           420:     struct smc_private *smc = link->priv;
        !           421:     dev_link_t **linkp;
        !           422: 
        !           423:     DEBUG(0, "smc91c92_detach(0x%p)\n", link);
        !           424: 
        !           425:     /* Locate device structure */
        !           426:     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
        !           427:        if (*linkp == link) break;
        !           428:     if (*linkp == NULL)
        !           429:        return;
        !           430: 
        !           431:     del_timer(&link->release);
        !           432:     if (link->state & DEV_CONFIG) {
        !           433:        smc91c92_release((u_long)link);
        !           434:        if (link->state & DEV_STALE_CONFIG) {
        !           435:            link->state |= DEV_STALE_LINK;
        !           436:            return;
        !           437:        }
        !           438:     }
        !           439: 
        !           440:     if (link->handle)
        !           441:        CardServices(DeregisterClient, link->handle);
        !           442: 
        !           443:     /* Unlink device structure, free bits */
        !           444:     *linkp = link->next;
        !           445:     if (link->dev)
        !           446:        unregister_netdev(&smc->dev);
        !           447:     kfree(smc);
        !           448: 
        !           449: } /* smc91c92_detach */
        !           450: 
        !           451: /*====================================================================*/
        !           452: 
        !           453: static int cvt_ascii_address(struct net_device *dev, char *s)
        !           454: {
        !           455:     int i, j, da, c;
        !           456: 
        !           457:     if (strlen(s) != 12)
        !           458:        return -1;
        !           459:     for (i = 0; i < 6; i++) {
        !           460:        da = 0;
        !           461:        for (j = 0; j < 2; j++) {
        !           462:            c = *s++;
        !           463:            da <<= 4;
        !           464:            da += ((c >= '0') && (c <= '9')) ?
        !           465:                (c - '0') : ((c & 0x0f) + 9);
        !           466:        }
        !           467:        dev->dev_addr[i] = da;
        !           468:     }
        !           469:     return 0;
        !           470: }
        !           471: 
        !           472: /*====================================================================*/
        !           473: 
        !           474: static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
        !           475:                     cisparse_t *parse)
        !           476: {
        !           477:     int i;
        !           478:     i = CardServices(fn, handle, tuple);
        !           479:     if (i != CS_SUCCESS) return i;
        !           480:     i = CardServices(GetTupleData, handle, tuple);
        !           481:     if (i != CS_SUCCESS) return i;
        !           482:     return CardServices(ParseTuple, handle, tuple, parse);
        !           483: }
        !           484: 
        !           485: #define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
        !           486: #define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
        !           487: 
        !           488: /*======================================================================
        !           489: 
        !           490:     Configuration stuff for Megahertz cards
        !           491: 
        !           492:     mhz_3288_power() is used to power up a 3288's ethernet chip.
        !           493:     mhz_mfc_config() handles socket setup for multifunction (1144
        !           494:     and 3288) cards.  mhz_setup() gets a card's hardware ethernet
        !           495:     address.
        !           496: 
        !           497: ======================================================================*/
        !           498: 
        !           499: static int mhz_3288_power(dev_link_t *link)
        !           500: {
        !           501:     struct smc_private *smc = link->priv;
        !           502:     u_char tmp;
        !           503: 
        !           504:     /* Read the ISR twice... */
        !           505:     readb(smc->base+MEGAHERTZ_ISR);
        !           506:     udelay(5);
        !           507:     readb(smc->base+MEGAHERTZ_ISR);
        !           508: 
        !           509:     /* Pause 200ms... */
        !           510:     mdelay(200);
        !           511: 
        !           512:     /* Now read and write the COR... */
        !           513:     tmp = readb(smc->base + link->conf.ConfigBase + CISREG_COR);
        !           514:     udelay(5);
        !           515:     writeb(tmp, smc->base + link->conf.ConfigBase + CISREG_COR);
        !           516: 
        !           517:     return 0;
        !           518: }
        !           519: 
        !           520: static int mhz_mfc_config(dev_link_t *link)
        !           521: {
        !           522:     struct smc_private *smc = link->priv;
        !           523:     struct net_device *dev = &smc->dev;
        !           524:     tuple_t tuple;
        !           525:     cisparse_t parse;
        !           526:     u_char buf[255];
        !           527:     cistpl_cftable_entry_t *cf = &parse.cftable_entry;
        !           528:     win_req_t req;
        !           529:     memreq_t mem;
        !           530:     int i, k;
        !           531: 
        !           532:     link->conf.Attributes |= CONF_ENABLE_SPKR;
        !           533:     link->conf.Status = CCSR_AUDIO_ENA;
        !           534:     link->irq.Attributes =
        !           535:        IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
        !           536:     link->io.IOAddrLines = 16;
        !           537:     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
        !           538:     link->io.NumPorts2 = 8;
        !           539: 
        !           540:     tuple.Attributes = tuple.TupleOffset = 0;
        !           541:     tuple.TupleData = (cisdata_t *)buf;
        !           542:     tuple.TupleDataMax = sizeof(buf);
        !           543:     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
        !           544: 
        !           545:     i = first_tuple(link->handle, &tuple, &parse);
        !           546:     /* The Megahertz combo cards have modem-like CIS entries, so
        !           547:        we have to explicitly try a bunch of port combinations. */
        !           548:     while (i == CS_SUCCESS) {
        !           549:        link->conf.ConfigIndex = cf->index;
        !           550:        link->io.BasePort2 = cf->io.win[0].base;
        !           551:        for (k = 0; k < 0x400; k += 0x10) {
        !           552:            if (k & 0x80) continue;
        !           553:            link->io.BasePort1 = k ^ 0x300;
        !           554:            i = CardServices(RequestIO, link->handle, &link->io);
        !           555:            if (i == CS_SUCCESS) break;
        !           556:        }
        !           557:        if (i == CS_SUCCESS) break;
        !           558:        i = next_tuple(link->handle, &tuple, &parse);
        !           559:     }
        !           560:     if (i != CS_SUCCESS)
        !           561:        return i;
        !           562:     dev->base_addr = link->io.BasePort1;
        !           563: 
        !           564:     /* Allocate a memory window, for accessing the ISR */
        !           565:     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
        !           566:     req.Base = req.Size = 0;
        !           567:     req.AccessSpeed = 0;
        !           568:     link->win = (window_handle_t)link->handle;
        !           569:     i = CardServices(RequestWindow, &link->win, &req);
        !           570:     if (i != CS_SUCCESS)
        !           571:        return i;
        !           572:     smc->base = ioremap(req.Base, req.Size);
        !           573:     mem.CardOffset = mem.Page = 0;
        !           574:     if (smc->manfid == MANFID_MOTOROLA)
        !           575:        mem.CardOffset = link->conf.ConfigBase;
        !           576:     i = CardServices(MapMemPage, link->win, &mem);
        !           577: 
        !           578:     if ((i == CS_SUCCESS)
        !           579:        && (smc->manfid == MANFID_MEGAHERTZ)
        !           580:        && (smc->cardid == PRODID_MEGAHERTZ_EM3288))
        !           581:        mhz_3288_power(link);
        !           582: 
        !           583:     return i;
        !           584: }
        !           585: 
        !           586: static int mhz_setup(dev_link_t *link)
        !           587: {
        !           588:     client_handle_t handle = link->handle;
        !           589:     struct smc_private *smc = link->priv;
        !           590:     struct net_device *dev = &smc->dev;
        !           591:     tuple_t tuple;
        !           592:     cisparse_t parse;
        !           593:     u_char buf[255], *station_addr;
        !           594: 
        !           595:     tuple.Attributes = tuple.TupleOffset = 0;
        !           596:     tuple.TupleData = buf;
        !           597:     tuple.TupleDataMax = sizeof(buf);
        !           598: 
        !           599:     /* Read the station address from the CIS.  It is stored as the last
        !           600:        (fourth) string in the Version 1 Version/ID tuple. */
        !           601:     tuple.DesiredTuple = CISTPL_VERS_1;
        !           602:     if (first_tuple(handle, &tuple, &parse) != CS_SUCCESS)
        !           603:        return -1;
        !           604:     /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
        !           605:     if (next_tuple(handle, &tuple, &parse) != CS_SUCCESS)
        !           606:        first_tuple(handle, &tuple, &parse);
        !           607:     if (parse.version_1.ns > 3) {
        !           608:        station_addr = parse.version_1.str + parse.version_1.ofs[3];
        !           609:        if (cvt_ascii_address(dev, station_addr) == 0)
        !           610:            return 0;
        !           611:     }
        !           612: 
        !           613:     /* Another possibility: for the EM3288, in a special tuple */
        !           614:     tuple.DesiredTuple = 0x81;
        !           615:     if (CardServices(GetFirstTuple, handle, &tuple) != CS_SUCCESS)
        !           616:        return -1;
        !           617:     if (CardServices(GetTupleData, handle, &tuple) != CS_SUCCESS)
        !           618:        return -1;
        !           619:     buf[12] = '\0';
        !           620:     if (cvt_ascii_address(dev, buf) == 0)
        !           621:        return 0;
        !           622: 
        !           623:     return -1;
        !           624: }
        !           625: 
        !           626: /*======================================================================
        !           627: 
        !           628:     Configuration stuff for the Motorola Mariner
        !           629: 
        !           630:     mot_config() writes directly to the Mariner configuration
        !           631:     registers because the CIS is just bogus.
        !           632: 
        !           633: ======================================================================*/
        !           634: 
        !           635: static void mot_config(dev_link_t *link)
        !           636: {
        !           637:     struct smc_private *smc = link->priv;
        !           638:     struct net_device *dev = &smc->dev;
        !           639:     ioaddr_t ioaddr = dev->base_addr;
        !           640:     ioaddr_t iouart = link->io.BasePort2;
        !           641: 
        !           642:     /* Set UART base address and force map with COR bit 1 */
        !           643:     writeb(iouart & 0xff,        smc->base + MOT_UART + CISREG_IOBASE_0);
        !           644:     writeb((iouart >> 8) & 0xff, smc->base + MOT_UART + CISREG_IOBASE_1);
        !           645:     writeb(MOT_NORMAL,           smc->base + MOT_UART + CISREG_COR);
        !           646: 
        !           647:     /* Set SMC base address and force map with COR bit 1 */
        !           648:     writeb(ioaddr & 0xff,        smc->base + MOT_LAN + CISREG_IOBASE_0);
        !           649:     writeb((ioaddr >> 8) & 0xff, smc->base + MOT_LAN + CISREG_IOBASE_1);
        !           650:     writeb(MOT_NORMAL,           smc->base + MOT_LAN + CISREG_COR);
        !           651: 
        !           652:     /* Wait for things to settle down */
        !           653:     mdelay(100);
        !           654: }
        !           655: 
        !           656: static int mot_setup(dev_link_t *link)
        !           657: {
        !           658:     struct smc_private *smc = link->priv;
        !           659:     struct net_device *dev = &smc->dev;
        !           660:     ioaddr_t ioaddr = dev->base_addr;
        !           661:     int i, wait, loop;
        !           662:     u_int addr;
        !           663: 
        !           664:     /* Read Ethernet address from Serial EEPROM */
        !           665: 
        !           666:     for (i = 0; i < 3; i++) {
        !           667:        SMC_SELECT_BANK(2);
        !           668:        outw(MOT_EEPROM + i, ioaddr + POINTER);
        !           669:        SMC_SELECT_BANK(1);
        !           670:        outw((CTL_RELOAD | CTL_EE_SELECT), ioaddr + CONTROL);
        !           671: 
        !           672:        for (loop = wait = 0; loop < 200; loop++) {
        !           673:            udelay(10);
        !           674:            wait = ((CTL_RELOAD | CTL_STORE) & inw(ioaddr + CONTROL));
        !           675:            if (wait == 0) break;
        !           676:        }
        !           677:        
        !           678:        if (wait)
        !           679:            return -1;
        !           680:        
        !           681:        addr = inw(ioaddr + GENERAL);
        !           682:        dev->dev_addr[2*i]   = addr & 0xff;
        !           683:        dev->dev_addr[2*i+1] = (addr >> 8) & 0xff;
        !           684:     }
        !           685: 
        !           686:     return 0;
        !           687: }
        !           688: 
        !           689: /*====================================================================*/
        !           690: 
        !           691: static int smc_config(dev_link_t *link)
        !           692: {
        !           693:     struct smc_private *smc = link->priv;
        !           694:     struct net_device *dev = &smc->dev;
        !           695:     tuple_t tuple;
        !           696:     cisparse_t parse;
        !           697:     u_char buf[255];
        !           698:     cistpl_cftable_entry_t *cf = &parse.cftable_entry;
        !           699:     int i;
        !           700: 
        !           701:     tuple.Attributes = tuple.TupleOffset = 0;
        !           702:     tuple.TupleData = (cisdata_t *)buf;
        !           703:     tuple.TupleDataMax = sizeof(buf);
        !           704:     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
        !           705: 
        !           706:     link->io.NumPorts1 = 16;
        !           707:     i = first_tuple(link->handle, &tuple, &parse);
        !           708:     while (i != CS_NO_MORE_ITEMS) {
        !           709:        if (i == CS_SUCCESS) {
        !           710:            link->conf.ConfigIndex = cf->index;
        !           711:            link->io.BasePort1 = cf->io.win[0].base;
        !           712:            link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
        !           713:            i = CardServices(RequestIO, link->handle, &link->io);
        !           714:            if (i == CS_SUCCESS) break;
        !           715:        }
        !           716:        i = next_tuple(link->handle, &tuple, &parse);
        !           717:     }
        !           718:     if (i == CS_SUCCESS)
        !           719:        dev->base_addr = link->io.BasePort1;
        !           720:     return i;
        !           721: }
        !           722: 
        !           723: static int smc_setup(dev_link_t *link)
        !           724: {
        !           725:     client_handle_t handle = link->handle;
        !           726:     struct smc_private *smc = link->priv;
        !           727:     struct net_device *dev = &smc->dev;
        !           728:     tuple_t tuple;
        !           729:     cisparse_t parse;
        !           730:     cistpl_lan_node_id_t *node_id;
        !           731:     u_char buf[255], *station_addr;
        !           732:     int i;
        !           733: 
        !           734:     tuple.Attributes = tuple.TupleOffset = 0;
        !           735:     tuple.TupleData = buf;
        !           736:     tuple.TupleDataMax = sizeof(buf);
        !           737: 
        !           738:     /* Check for a LAN function extension tuple */
        !           739:     tuple.DesiredTuple = CISTPL_FUNCE;
        !           740:     i = first_tuple(handle, &tuple, &parse);
        !           741:     while (i == CS_SUCCESS) {
        !           742:        if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID)
        !           743:            break;
        !           744:        i = next_tuple(handle, &tuple, &parse);
        !           745:     }
        !           746:     if (i == CS_SUCCESS) {
        !           747:        node_id = (cistpl_lan_node_id_t *)parse.funce.data;
        !           748:        if (node_id->nb == 6) {
        !           749:            for (i = 0; i < 6; i++)
        !           750:                dev->dev_addr[i] = node_id->id[i];
        !           751:            return 0;
        !           752:        }
        !           753:     }
        !           754: 
        !           755:     /* Try the third string in the Version 1 Version/ID tuple. */
        !           756:     tuple.DesiredTuple = CISTPL_VERS_1;
        !           757:     if (first_tuple(handle, &tuple, &parse) != CS_SUCCESS)
        !           758:        return -1;
        !           759:     station_addr = parse.version_1.str + parse.version_1.ofs[2];
        !           760:     if (cvt_ascii_address(dev, station_addr) == 0)
        !           761:        return 0;
        !           762: 
        !           763:     return -1;
        !           764: }
        !           765: 
        !           766: /*====================================================================*/
        !           767: 
        !           768: static int osi_config(dev_link_t *link)
        !           769: {
        !           770:     struct smc_private *smc = link->priv;
        !           771:     struct net_device *dev = &smc->dev;
        !           772:     static ioaddr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
        !           773:     int i, j;
        !           774: 
        !           775:     link->conf.Attributes |= CONF_ENABLE_SPKR;
        !           776:     link->conf.Status = CCSR_AUDIO_ENA;
        !           777:     link->irq.Attributes =
        !           778:        IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
        !           779:     link->io.NumPorts1 = 64;
        !           780:     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
        !           781:     link->io.NumPorts2 = 8;
        !           782:     link->io.IOAddrLines = 16;
        !           783: 
        !           784:     /* Enable Hard Decode, LAN, Modem */
        !           785:     link->conf.ConfigIndex = 0x23;
        !           786: 
        !           787:     for (i = j = 0; j < 4; j++) {
        !           788:        link->io.BasePort2 = com[j];
        !           789:        i = CardServices(RequestIO, link->handle, &link->io);
        !           790:        if (i == CS_SUCCESS) break;
        !           791:     }
        !           792:     if (i != CS_SUCCESS) {
        !           793:        /* Fallback: turn off hard decode */
        !           794:        link->conf.ConfigIndex = 0x03;
        !           795:        link->io.NumPorts2 = 0;
        !           796:        i = CardServices(RequestIO, link->handle, &link->io);
        !           797:     }
        !           798:     dev->base_addr = link->io.BasePort1 + 0x10;
        !           799:     return i;
        !           800: }
        !           801: 
        !           802: static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid)
        !           803: {
        !           804:     client_handle_t handle = link->handle;
        !           805:     struct smc_private *smc = link->priv;
        !           806:     struct net_device *dev = &smc->dev;
        !           807:     tuple_t tuple;
        !           808:     u_char buf[255];
        !           809:     int i;
        !           810: 
        !           811:     tuple.Attributes = TUPLE_RETURN_COMMON;
        !           812:     tuple.TupleData = buf;
        !           813:     tuple.TupleDataMax = sizeof(buf);
        !           814:     tuple.TupleOffset = 0;
        !           815: 
        !           816:     /* Read the station address from tuple 0x90, subtuple 0x04 */
        !           817:     tuple.DesiredTuple = 0x90;
        !           818:     i = CardServices(GetFirstTuple, handle, &tuple);
        !           819:     while (i == CS_SUCCESS) {
        !           820:        i = CardServices(GetTupleData, handle, &tuple);
        !           821:        if ((i != CS_SUCCESS) || (buf[0] == 0x04))
        !           822:            break;
        !           823:        i = CardServices(GetNextTuple, handle, &tuple);
        !           824:     }
        !           825:     if (i != CS_SUCCESS)
        !           826:        return -1;
        !           827:     for (i = 0; i < 6; i++)
        !           828:        dev->dev_addr[i] = buf[i+2];
        !           829: 
        !           830:     if (((manfid == MANFID_OSITECH) &&
        !           831:         (cardid == PRODID_OSITECH_SEVEN)) ||
        !           832:        ((manfid == MANFID_PSION) &&
        !           833:         (cardid == PRODID_PSION_NET100))) {
        !           834:        /* Download the Seven of Diamonds firmware */
        !           835:        for (i = 0; i < sizeof(__Xilinx7OD); i++) {
        !           836:            outb(__Xilinx7OD[i], link->io.BasePort1+2);
        !           837:            udelay(50);
        !           838:        }
        !           839:     } else if (manfid == MANFID_OSITECH) {
        !           840:        /* Make sure both functions are powered up */
        !           841:        set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
        !           842:        /* Now, turn on the interrupt for both card functions */
        !           843:        set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
        !           844:        DEBUG(2, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
        !           845:              inw(link->io.BasePort1 + OSITECH_AUI_PWR),
        !           846:              inw(link->io.BasePort1 + OSITECH_RESET_ISR));
        !           847:     }
        !           848: 
        !           849:     return 0;
        !           850: }
        !           851: 
        !           852: /*======================================================================
        !           853: 
        !           854:     This verifies that the chip is some SMC91cXX variant, and returns
        !           855:     the revision code if successful.  Otherwise, it returns -ENODEV.
        !           856: 
        !           857: ======================================================================*/
        !           858: 
        !           859: static int check_sig(dev_link_t *link)
        !           860: {
        !           861:     struct smc_private *smc = link->priv;
        !           862:     struct net_device *dev = &smc->dev;
        !           863:     ioaddr_t ioaddr = dev->base_addr;
        !           864:     int width;
        !           865:     u_short s;
        !           866: 
        !           867:     SMC_SELECT_BANK(1);
        !           868:     if (inw(ioaddr + BANK_SELECT) >> 8 != 0x33) {
        !           869:        /* Try powering up the chip */
        !           870:        outw(0, ioaddr + CONTROL);
        !           871:        mdelay(55);
        !           872:     }
        !           873: 
        !           874:     /* Try setting bus width */
        !           875:     width = (link->io.Attributes1 == IO_DATA_PATH_WIDTH_AUTO);
        !           876:     s = inb(ioaddr + CONFIG);
        !           877:     if (width)
        !           878:        s |= CFG_16BIT;
        !           879:     else
        !           880:        s &= ~CFG_16BIT;
        !           881:     outb(s, ioaddr + CONFIG);
        !           882: 
        !           883:     /* Check Base Address Register to make sure bus width is OK */
        !           884:     s = inw(ioaddr + BASE_ADDR);
        !           885:     if ((inw(ioaddr + BANK_SELECT) >> 8 == 0x33) &&
        !           886:        ((s >> 8) != (s & 0xff))) {
        !           887:        SMC_SELECT_BANK(3);
        !           888:        s = inw(ioaddr + REVISION);
        !           889:        return (s & 0xff);
        !           890:     }
        !           891: 
        !           892:     if (width) {
        !           893:        event_callback_args_t args;
        !           894:        printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
        !           895:        args.client_data = link;
        !           896:        smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
        !           897:        CardServices(ReleaseIO, link->handle, &link->io);
        !           898:        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        !           899:        CardServices(RequestIO, link->handle, &link->io);
        !           900:        smc91c92_event(CS_EVENT_CARD_RESET, 0, &args);
        !           901:        return check_sig(link);
        !           902:     }
        !           903:     return -ENODEV;
        !           904: }
        !           905: 
        !           906: /*======================================================================
        !           907: 
        !           908:     smc91c92_config() is scheduled to run after a CARD_INSERTION event
        !           909:     is received, to configure the PCMCIA socket, and to make the
        !           910:     ethernet device available to the system.
        !           911: 
        !           912: ======================================================================*/
        !           913: 
        !           914: #define CS_EXIT_TEST(ret, svc, label) \
        !           915: if (ret != CS_SUCCESS) { cs_error(link->handle, svc, ret); goto label; }
        !           916: 
        !           917: static void smc91c92_config(dev_link_t *link)
        !           918: {
        !           919:     client_handle_t handle = link->handle;
        !           920:     struct smc_private *smc = link->priv;
        !           921:     struct net_device *dev = &smc->dev;
        !           922:     tuple_t tuple;
        !           923:     cisparse_t parse;
        !           924:     u_short buf[32];
        !           925:     char *name;
        !           926:     int i, j, rev;
        !           927:     ioaddr_t ioaddr;
        !           928: 
        !           929:     DEBUG(0, "smc91c92_config(0x%p)\n", link);
        !           930: 
        !           931:     tuple.Attributes = tuple.TupleOffset = 0;
        !           932:     tuple.TupleData = (cisdata_t *)buf;
        !           933:     tuple.TupleDataMax = sizeof(buf);
        !           934: 
        !           935:     tuple.DesiredTuple = CISTPL_CONFIG;
        !           936:     i = first_tuple(handle, &tuple, &parse);
        !           937:     CS_EXIT_TEST(i, ParseTuple, config_failed);
        !           938:     link->conf.ConfigBase = parse.config.base;
        !           939:     link->conf.Present = parse.config.rmask[0];
        !           940: 
        !           941:     tuple.DesiredTuple = CISTPL_MANFID;
        !           942:     tuple.Attributes = TUPLE_RETURN_COMMON;
        !           943:     if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
        !           944:        smc->manfid = parse.manfid.manf;
        !           945:        smc->cardid = parse.manfid.card;
        !           946:     }
        !           947: 
        !           948:     /* Configure card */
        !           949:     link->state |= DEV_CONFIG;
        !           950: 
        !           951:     if ((smc->manfid == MANFID_OSITECH) &&
        !           952:        (smc->cardid != PRODID_OSITECH_SEVEN)) {
        !           953:        i = osi_config(link);
        !           954:     } else if ((smc->manfid == MANFID_MOTOROLA) ||
        !           955:               ((smc->manfid == MANFID_MEGAHERTZ) &&
        !           956:                ((smc->cardid == PRODID_MEGAHERTZ_VARIOUS) ||
        !           957:                 (smc->cardid == PRODID_MEGAHERTZ_EM3288)))) {
        !           958:        i = mhz_mfc_config(link);
        !           959:     } else {
        !           960:        i = smc_config(link);
        !           961:     }
        !           962:     CS_EXIT_TEST(i, RequestIO, config_failed);
        !           963: 
        !           964:     i = CardServices(RequestIRQ, link->handle, &link->irq);
        !           965:     CS_EXIT_TEST(i, RequestIRQ, config_failed);
        !           966:     i = CardServices(RequestConfiguration, link->handle, &link->conf);
        !           967:     CS_EXIT_TEST(i, RequestConfiguration, config_failed);
        !           968: 
        !           969:     if (smc->manfid == MANFID_MOTOROLA)
        !           970:        mot_config(link);
        !           971: 
        !           972:     dev->irq = link->irq.AssignedIRQ;
        !           973: 
        !           974:     if ((if_port >= 0) && (if_port <= 2))
        !           975:        dev->if_port = if_port;
        !           976:     else
        !           977:        printk(KERN_NOTICE "smc91c92_cs: invalid if_port requested\n");
        !           978: 
        !           979:     if (register_netdev(dev) != 0) {
        !           980:        printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
        !           981:        goto config_undo;
        !           982:     }
        !           983: 
        !           984:     switch (smc->manfid) {
        !           985:     case MANFID_OSITECH:
        !           986:     case MANFID_PSION:
        !           987:        i = osi_setup(link, smc->manfid, smc->cardid); break;
        !           988:     case MANFID_SMC:
        !           989:     case MANFID_NEW_MEDIA:
        !           990:        i = smc_setup(link); break;
        !           991:     case 0x128: /* For broken Megahertz cards */
        !           992:     case MANFID_MEGAHERTZ:
        !           993:        i = mhz_setup(link); break;
        !           994:     case MANFID_MOTOROLA:
        !           995:     default: /* get the hw address from EEPROM */
        !           996:        i = mot_setup(link); break;
        !           997:     }
        !           998: 
        !           999:     if (i != 0) {
        !          1000:        printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n");
        !          1001:        goto config_undo;
        !          1002:     }
        !          1003: 
        !          1004:     copy_dev_name(smc->node, dev);
        !          1005:     link->dev = &smc->node;
        !          1006:     smc->duplex = 0;
        !          1007:     smc->rx_ovrn = 0;
        !          1008: 
        !          1009:     rev = check_sig(link);
        !          1010:     name = "???";
        !          1011:     if (rev > 0)
        !          1012:        switch (rev >> 4) {
        !          1013:        case 3: name = "92"; break;
        !          1014:        case 4: name = ((rev & 15) >= 6) ? "96" : "94"; break;
        !          1015:        case 5: name = "95"; break;
        !          1016:        case 7: name = "100"; break;
        !          1017:        case 8: name = "100-FD"; break;
        !          1018:        case 9: name = "110"; break;
        !          1019:        }
        !          1020:     printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, "
        !          1021:           "hw_addr ", dev->name, name, (rev & 0x0f), dev->base_addr,
        !          1022:           dev->irq);
        !          1023:     for (i = 0; i < 6; i++)
        !          1024:        printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
        !          1025: 
        !          1026:     ioaddr = dev->base_addr;
        !          1027:     if (rev > 0) {
        !          1028:        u_long mir, mcr;
        !          1029:        SMC_SELECT_BANK(0);
        !          1030:        mir = inw(ioaddr + MEMINFO) & 0xff;
        !          1031:        if (mir == 0xff) mir++;
        !          1032:        /* Get scale factor for memory size */
        !          1033:        mcr = ((rev >> 4) > 3) ? inw(ioaddr + MEMCFG) : 0x0200;
        !          1034:        mir *= 128 * (1<<((mcr >> 9) & 7));
        !          1035:        if (mir & 0x3ff)
        !          1036:            printk(KERN_INFO "  %lu byte", mir);
        !          1037:        else
        !          1038:            printk(KERN_INFO "  %lu kb", mir>>10);
        !          1039:        SMC_SELECT_BANK(1);
        !          1040:        smc->cfg = inw(ioaddr + CONFIG) & ~CFG_AUI_SELECT;
        !          1041:        smc->cfg |= CFG_NO_WAIT | CFG_16BIT | CFG_STATIC;
        !          1042:        if (smc->manfid == MANFID_OSITECH)
        !          1043:            smc->cfg |= CFG_IRQ_SEL_1 | CFG_IRQ_SEL_0;
        !          1044:        if ((rev >> 4) >= 7)
        !          1045:            smc->cfg |= CFG_MII_SELECT;
        !          1046:        printk(" buffer, %s xcvr\n", (smc->cfg & CFG_MII_SELECT) ?
        !          1047:               "MII" : if_names[dev->if_port]);
        !          1048:     }
        !          1049: 
        !          1050:     if (smc->cfg & CFG_MII_SELECT) {
        !          1051:        SMC_SELECT_BANK(3);
        !          1052: 
        !          1053:        for (i = 0; i < 32; i++) {
        !          1054:            j = mdio_read(dev, i, 1);
        !          1055:            if ((j != 0) && (j != 0xffff)) break;
        !          1056:        }
        !          1057:        smc->phy_id = (i < 32) ? i : -1;
        !          1058:        if (i < 32) {
        !          1059:            DEBUG(0, "  MII transceiver at index %d, status %x.\n", i, j);
        !          1060:        } else {
        !          1061:            printk(KERN_NOTICE "  No MII transceivers found!\n");
        !          1062:        }
        !          1063: 
        !          1064:        SMC_SELECT_BANK(0);
        !          1065:     }
        !          1066: 
        !          1067:     link->state &= ~DEV_CONFIG_PENDING;
        !          1068:     return;
        !          1069: 
        !          1070: config_undo:
        !          1071:     unregister_netdev(dev);
        !          1072: config_failed:                 /* CS_EXIT_TEST() calls jump to here... */
        !          1073:     smc91c92_release((u_long)link);
        !          1074:     link->state &= ~DEV_CONFIG_PENDING;
        !          1075: 
        !          1076: } /* smc91c92_config */
        !          1077: 
        !          1078: /*======================================================================
        !          1079: 
        !          1080:     After a card is removed, smc91c92_release() will unregister the net
        !          1081:     device, and release the PCMCIA configuration.  If the device is
        !          1082:     still open, this will be postponed until it is closed.
        !          1083: 
        !          1084: ======================================================================*/
        !          1085: 
        !          1086: static void smc91c92_release(u_long arg)
        !          1087: {
        !          1088:     dev_link_t *link = (dev_link_t *)arg;
        !          1089:     struct smc_private *smc = link->priv;
        !          1090: 
        !          1091:     DEBUG(0, "smc91c92_release(0x%p)\n", link);
        !          1092: 
        !          1093:     if (link->open) {
        !          1094:        DEBUG(1, "smc91c92_cs: release postponed, '%s' still open\n",
        !          1095:              link->dev->dev_name);
        !          1096:        link->state |= DEV_STALE_CONFIG;
        !          1097:        return;
        !          1098:     }
        !          1099: 
        !          1100:     CardServices(ReleaseConfiguration, link->handle);
        !          1101:     CardServices(ReleaseIO, link->handle, &link->io);
        !          1102:     CardServices(ReleaseIRQ, link->handle, &link->irq);
        !          1103:     if (link->win) {
        !          1104:        iounmap(smc->base);
        !          1105:        CardServices(ReleaseWindow, link->win);
        !          1106:     }
        !          1107: 
        !          1108:     link->state &= ~DEV_CONFIG;
        !          1109: 
        !          1110: } /* smc91c92_release */
        !          1111: 
        !          1112: /*======================================================================
        !          1113: 
        !          1114:     The card status event handler.  Mostly, this schedules other
        !          1115:     stuff to run after an event is received.  A CARD_REMOVAL event
        !          1116:     also sets some flags to discourage the net drivers from trying
        !          1117:     to talk to the card any more.
        !          1118: 
        !          1119: ======================================================================*/
        !          1120: 
        !          1121: static int smc91c92_event(event_t event, int priority,
        !          1122:                          event_callback_args_t *args)
        !          1123: {
        !          1124:     dev_link_t *link = args->client_data;
        !          1125:     struct smc_private *smc = link->priv;
        !          1126:     struct net_device *dev = &smc->dev;
        !          1127:     int i;
        !          1128: 
        !          1129:     DEBUG(1, "smc91c92_event(0x%06x)\n", event);
        !          1130: 
        !          1131:     switch (event) {
        !          1132:     case CS_EVENT_CARD_REMOVAL:
        !          1133:        link->state &= ~DEV_PRESENT;
        !          1134:        if (link->state & DEV_CONFIG) {
        !          1135:            netif_device_detach(dev);
        !          1136:            mod_timer(&link->release, jiffies + HZ/20);
        !          1137:        }
        !          1138:        break;
        !          1139:     case CS_EVENT_CARD_INSERTION:
        !          1140:        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        !          1141:        smc91c92_config(link);
        !          1142:        break;
        !          1143:     case CS_EVENT_PM_SUSPEND:
        !          1144:        link->state |= DEV_SUSPEND;
        !          1145:        /* Fall through... */
        !          1146:     case CS_EVENT_RESET_PHYSICAL:
        !          1147:        if (link->state & DEV_CONFIG) {
        !          1148:            if (link->open)
        !          1149:                netif_device_detach(dev);
        !          1150:            CardServices(ReleaseConfiguration, link->handle);
        !          1151:        }
        !          1152:        break;
        !          1153:     case CS_EVENT_PM_RESUME:
        !          1154:        link->state &= ~DEV_SUSPEND;
        !          1155:        /* Fall through... */
        !          1156:     case CS_EVENT_CARD_RESET:
        !          1157:        if (link->state & DEV_CONFIG) {
        !          1158:            if ((smc->manfid == MANFID_MEGAHERTZ) &&
        !          1159:                (smc->cardid == PRODID_MEGAHERTZ_EM3288))
        !          1160:                mhz_3288_power(link);
        !          1161:            CardServices(RequestConfiguration, link->handle, &link->conf);
        !          1162:            if (smc->manfid == MANFID_MOTOROLA)
        !          1163:                mot_config(link);
        !          1164:            if ((smc->manfid == MANFID_OSITECH) &&
        !          1165:                (smc->cardid != PRODID_OSITECH_SEVEN)) {
        !          1166:                /* Power up the card and enable interrupts */
        !          1167:                set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
        !          1168:                set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
        !          1169:            }
        !          1170:            if (((smc->manfid == MANFID_OSITECH) &&
        !          1171:                (smc->cardid == PRODID_OSITECH_SEVEN)) ||
        !          1172:                ((smc->manfid == MANFID_PSION) &&
        !          1173:                (smc->cardid == PRODID_PSION_NET100))) {
        !          1174:                /* Download the Seven of Diamonds firmware */
        !          1175:                for (i = 0; i < sizeof(__Xilinx7OD); i++) {
        !          1176:                    outb(__Xilinx7OD[i], link->io.BasePort1+2);
        !          1177:                    udelay(50);
        !          1178:                }
        !          1179:            }
        !          1180:            if (link->open) {
        !          1181:                smc_reset(dev);
        !          1182:                netif_device_attach(dev);
        !          1183:            }
        !          1184:        }
        !          1185:        break;
        !          1186:     }
        !          1187:     return 0;
        !          1188: } /* smc91c92_event */
        !          1189: 
        !          1190: /*======================================================================
        !          1191: 
        !          1192:     MII interface support for SMC91cXX based cards
        !          1193: ======================================================================*/
        !          1194: 
        !          1195: #define MDIO_SHIFT_CLK         0x04
        !          1196: #define MDIO_DATA_OUT          0x01
        !          1197: #define MDIO_DIR_WRITE         0x08
        !          1198: #define MDIO_DATA_WRITE0       (MDIO_DIR_WRITE)
        !          1199: #define MDIO_DATA_WRITE1       (MDIO_DIR_WRITE | MDIO_DATA_OUT)
        !          1200: #define MDIO_DATA_READ         0x02
        !          1201: 
        !          1202: static void mdio_sync(ioaddr_t addr)
        !          1203: {
        !          1204:     int bits;
        !          1205:     for (bits = 0; bits < 32; bits++) {
        !          1206:        outb(MDIO_DATA_WRITE1, addr);
        !          1207:        outb(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr);
        !          1208:     }
        !          1209: }
        !          1210: 
        !          1211: static int mdio_read(struct net_device *dev, int phy_id, int loc)
        !          1212: {
        !          1213:     ioaddr_t addr = dev->base_addr + MGMT;
        !          1214:     u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
        !          1215:     int i, retval = 0;
        !          1216: 
        !          1217:     mdio_sync(addr);
        !          1218:     for (i = 13; i >= 0; i--) {
        !          1219:        int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
        !          1220:        outb(dat, addr);
        !          1221:        outb(dat | MDIO_SHIFT_CLK, addr);
        !          1222:     }
        !          1223:     for (i = 19; i > 0; i--) {
        !          1224:        outb(0, addr);
        !          1225:        retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0);
        !          1226:        outb(MDIO_SHIFT_CLK, addr);
        !          1227:     }
        !          1228:     return (retval>>1) & 0xffff;
        !          1229: }
        !          1230: 
        !          1231: static void mdio_write(struct net_device *dev, int phy_id, int loc, int value)
        !          1232: {
        !          1233:     ioaddr_t addr = dev->base_addr + MGMT;
        !          1234:     u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
        !          1235:     int i;
        !          1236: 
        !          1237:     mdio_sync(addr);
        !          1238:     for (i = 31; i >= 0; i--) {
        !          1239:        int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
        !          1240:        outb(dat, addr);
        !          1241:        outb(dat | MDIO_SHIFT_CLK, addr);
        !          1242:     }
        !          1243:     for (i = 1; i >= 0; i--) {
        !          1244:        outb(0, addr);
        !          1245:        outb(MDIO_SHIFT_CLK, addr);
        !          1246:     }
        !          1247: }
        !          1248: 
        !          1249: /*======================================================================
        !          1250: 
        !          1251:     The driver core code, most of which should be common with a
        !          1252:     non-PCMCIA implementation.
        !          1253: 
        !          1254: ======================================================================*/
        !          1255: 
        !          1256: #ifdef PCMCIA_DEBUG
        !          1257: static void smc_dump(struct net_device *dev)
        !          1258: {
        !          1259:     ioaddr_t ioaddr = dev->base_addr;
        !          1260:     u_short i, w, save;
        !          1261:     save = inw(ioaddr + BANK_SELECT);
        !          1262:     for (w = 0; w < 4; w++) {
        !          1263:        SMC_SELECT_BANK(w);
        !          1264:        printk(KERN_DEBUG "bank %d: ", w);
        !          1265:        for (i = 0; i < 14; i += 2)
        !          1266:            printk(" %04x", inw(ioaddr + i));
        !          1267:        printk("\n");
        !          1268:     }
        !          1269:     outw(save, ioaddr + BANK_SELECT);
        !          1270: }
        !          1271: #endif
        !          1272: 
        !          1273: static int smc_open(struct net_device *dev)
        !          1274: {
        !          1275:     struct smc_private *smc = dev->priv;
        !          1276:     dev_link_t *link = &smc->link;
        !          1277: 
        !          1278: #ifdef PCMCIA_DEBUG
        !          1279:     DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
        !          1280:          dev->name, dev, inw(dev->base_addr + BANK_SELECT));
        !          1281:     if (pc_debug > 1) smc_dump(dev);
        !          1282: #endif
        !          1283: 
        !          1284:     /* Check that the PCMCIA card is still here. */
        !          1285:     if (!DEV_OK(link))
        !          1286:        return -ENODEV;
        !          1287:     /* Physical device present signature. */
        !          1288:     if (check_sig(link) < 0) {
        !          1289:        printk("smc91c92_cs: Yikes!  Bad chip signature!\n");
        !          1290:        return -ENODEV;
        !          1291:     }
        !          1292:     link->open++;
        !          1293:     MOD_INC_USE_COUNT;
        !          1294: 
        !          1295:     netif_start_queue(dev);
        !          1296:     netif_mark_up(dev);
        !          1297:     smc->saved_skb = 0;
        !          1298:     smc->packets_waiting = 0;
        !          1299: 
        !          1300:     smc_reset(dev);
        !          1301:     smc->media.function = &media_check;
        !          1302:     smc->media.data = (u_long)smc;
        !          1303:     smc->media.expires = jiffies + HZ;
        !          1304:     add_timer(&smc->media);
        !          1305: 
        !          1306:     return 0;
        !          1307: } /* smc_open */
        !          1308: 
        !          1309: /*====================================================================*/
        !          1310: 
        !          1311: static int smc_close(struct net_device *dev)
        !          1312: {
        !          1313:     struct smc_private *smc = dev->priv;
        !          1314:     dev_link_t *link = &smc->link;
        !          1315:     ioaddr_t ioaddr = dev->base_addr;
        !          1316: 
        !          1317:     DEBUG(0, "%s: smc_close(), status %4.4x.\n",
        !          1318:          dev->name, inw(ioaddr + BANK_SELECT));
        !          1319: 
        !          1320:     netif_stop_queue(dev);
        !          1321:     netif_mark_down(dev);
        !          1322: 
        !          1323:     /* Shut off all interrupts, and turn off the Tx and Rx sections.
        !          1324:        Don't bother to check for chip present. */
        !          1325:     SMC_SELECT_BANK(2);        /* Nominally paranoia, but do no assume... */
        !          1326:     outw(0, ioaddr + INTERRUPT);
        !          1327:     SMC_SELECT_BANK(0);
        !          1328:     mask_bits(0xff00, ioaddr + RCR);
        !          1329:     mask_bits(0xff00, ioaddr + TCR);
        !          1330: 
        !          1331:     /* Put the chip into power-down mode. */
        !          1332:     SMC_SELECT_BANK(1);
        !          1333:     outw(CTL_POWERDOWN, ioaddr + CONTROL );
        !          1334: 
        !          1335:     link->open--;
        !          1336:     del_timer(&smc->media);
        !          1337:     if (link->state & DEV_STALE_CONFIG)
        !          1338:        mod_timer(&link->release, jiffies + HZ/20);
        !          1339: 
        !          1340:     MOD_DEC_USE_COUNT;
        !          1341: 
        !          1342:     return 0;
        !          1343: } /* smc_close */
        !          1344: 
        !          1345: static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        !          1346: {
        !          1347:     struct smc_private *smc = dev->priv;
        !          1348:     u16 *data = (u16 *)&rq->ifr_data;
        !          1349:     ushort saved_bank;
        !          1350:     ioaddr_t ioaddr = dev->base_addr;
        !          1351: 
        !          1352:     if (!(smc->cfg & CFG_MII_SELECT))
        !          1353:        return -EOPNOTSUPP;
        !          1354: 
        !          1355:     saved_bank = inw(ioaddr + BANK_SELECT);
        !          1356:     SMC_SELECT_BANK(3);
        !          1357: 
        !          1358:     switch (cmd) {
        !          1359:     case SIOCDEVPRIVATE:
        !          1360:        data[0] = smc->phy_id;
        !          1361:     case SIOCDEVPRIVATE+1:
        !          1362:        data[3] = mdio_read(dev, data[0], data[1] & 0x1f);
        !          1363:        SMC_SELECT_BANK(saved_bank);
        !          1364:        return 0;
        !          1365:     case SIOCDEVPRIVATE+2:
        !          1366:        if (!capable(CAP_NET_ADMIN)) {
        !          1367:            SMC_SELECT_BANK(saved_bank);
        !          1368:            return -EPERM;
        !          1369:        }
        !          1370:        mdio_write(dev, data[0], data[1] & 0x1f, data[2]);
        !          1371:        SMC_SELECT_BANK(saved_bank);
        !          1372:        return 0;
        !          1373:     }
        !          1374:     SMC_SELECT_BANK(saved_bank);
        !          1375:     return -EOPNOTSUPP;
        !          1376: }
        !          1377: /*======================================================================
        !          1378: 
        !          1379:    Transfer a packet to the hardware and trigger the packet send.
        !          1380:    This may be called at either from either the Tx queue code
        !          1381:    or the interrupt handler.
        !          1382: 
        !          1383: ======================================================================*/
        !          1384: 
        !          1385: static void smc_hardware_send_packet(struct net_device * dev)
        !          1386: {
        !          1387:     struct smc_private *smc = dev->priv;
        !          1388:     struct sk_buff *skb = smc->saved_skb;
        !          1389:     ioaddr_t ioaddr = dev->base_addr;
        !          1390:     u_char packet_no;
        !          1391: 
        !          1392:     if (!skb) {
        !          1393:        printk(KERN_ERR "%s: In XMIT with no packet to send.\n", dev->name);
        !          1394:        return;
        !          1395:     }
        !          1396: 
        !          1397:     /* There should be a packet slot waiting. */
        !          1398:     packet_no = inw(ioaddr + PNR_ARR) >> 8;
        !          1399:     if (packet_no & 0x80) {
        !          1400:        /* If not, there is a hardware problem!  Likely an ejected card. */
        !          1401:        printk(KERN_WARNING "%s: 91c92 hardware Tx buffer allocation"
        !          1402:               " failed, status %#2.2x.\n", dev->name, packet_no);
        !          1403:        dev_kfree_skb_irq(skb);
        !          1404:        smc->saved_skb = NULL;
        !          1405:        netif_start_queue(dev);
        !          1406:        return;
        !          1407:     }
        !          1408: 
        !          1409:     add_tx_bytes(&smc->stats, skb->len);
        !          1410:     /* The card should use the just-allocated buffer. */
        !          1411:     outw(packet_no, ioaddr + PNR_ARR);
        !          1412:     /* point to the beginning of the packet */
        !          1413:     outw(PTR_AUTOINC , ioaddr + POINTER);
        !          1414: 
        !          1415:     /* Send the packet length (+6 for status, length and ctl byte)
        !          1416:        and the status word (set to zeros). */
        !          1417:     {
        !          1418:        u_char *buf = skb->data;
        !          1419:        u_int length = skb->len; /* The chip will pad to ethernet min. */
        !          1420: 
        !          1421:        DEBUG(2, "%s: Trying to xmit packet of length %d.\n",
        !          1422:              dev->name, length);
        !          1423:        
        !          1424:        /* send the packet length: +6 for status word, length, and ctl */
        !          1425:        outw(0, ioaddr + DATA_1);
        !          1426:        outw(length + 6, ioaddr + DATA_1);
        !          1427:        outsw(ioaddr + DATA_1, buf, length >> 1);
        !          1428:        
        !          1429:        /* The odd last byte, if there is one, goes in the control word. */
        !          1430:        outw((length & 1) ? 0x2000 | buf[length-1] : 0, ioaddr + DATA_1);
        !          1431:     }
        !          1432: 
        !          1433:     /* Enable the Tx interrupts, both Tx (TxErr) and TxEmpty. */
        !          1434:     outw(((IM_TX_INT|IM_TX_EMPTY_INT)<<8) |
        !          1435:         (inw(ioaddr + INTERRUPT) & 0xff00),
        !          1436:         ioaddr + INTERRUPT);
        !          1437: 
        !          1438:     /* The chip does the rest of the work. */
        !          1439:     outw(MC_ENQUEUE , ioaddr + MMU_CMD);
        !          1440: 
        !          1441:     smc->saved_skb = NULL;
        !          1442:     dev_kfree_skb_irq(skb);
        !          1443:     dev->trans_start = jiffies;
        !          1444:     netif_start_queue(dev);
        !          1445:     return;
        !          1446: }
        !          1447: 
        !          1448: /*====================================================================*/
        !          1449: 
        !          1450: static void smc_tx_timeout(struct net_device *dev)
        !          1451: {
        !          1452:     struct smc_private *smc = dev->priv;
        !          1453:     ioaddr_t ioaddr = dev->base_addr;
        !          1454: 
        !          1455:     printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, "
        !          1456:           "Tx_status %2.2x status %4.4x.\n",
        !          1457:           dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2));
        !          1458:     smc->stats.tx_errors++;
        !          1459:     smc_reset(dev);
        !          1460:     dev->trans_start = jiffies;
        !          1461:     smc->saved_skb = NULL;
        !          1462:     netif_wake_queue(dev);
        !          1463: }
        !          1464: 
        !          1465: static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
        !          1466: {
        !          1467:     struct smc_private *smc = dev->priv;
        !          1468:     ioaddr_t ioaddr = dev->base_addr;
        !          1469:     u_short num_pages;
        !          1470:     short time_out, ir;
        !          1471: 
        !          1472:     tx_timeout_check(dev, smc_tx_timeout);
        !          1473:     skb_tx_check(dev, skb);
        !          1474: 
        !          1475:     DEBUG(2, "%s: smc_start_xmit(length = %ld) called,"
        !          1476:          " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
        !          1477: 
        !          1478:     if (smc->saved_skb) {
        !          1479:        /* THIS SHOULD NEVER HAPPEN. */
        !          1480:        smc->stats.tx_aborted_errors++;
        !          1481:        printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n",
        !          1482:               dev->name);
        !          1483:        return 1;
        !          1484:     }
        !          1485:     smc->saved_skb = skb;
        !          1486: 
        !          1487:     num_pages = skb->len >> 8;
        !          1488: 
        !          1489:     if (num_pages > 7) {
        !          1490:        printk(KERN_ERR "%s: Far too big packet error.\n", dev->name);
        !          1491:        DEV_KFREE_SKB (skb);
        !          1492:        smc->saved_skb = NULL;
        !          1493:        smc->stats.tx_dropped++;
        !          1494:        return 0;               /* Do not re-queue this packet. */
        !          1495:     }
        !          1496:     /* A packet is now waiting. */
        !          1497:     smc->packets_waiting++;
        !          1498: 
        !          1499:     SMC_SELECT_BANK(2);        /* Paranoia, we should always be in window 2 */
        !          1500: 
        !          1501:     /* need MC_RESET to keep the memory consistent. errata? */
        !          1502:     if (smc->rx_ovrn) {
        !          1503:        outw(MC_RESET, ioaddr + MMU_CMD);
        !          1504:        smc->rx_ovrn = 0;
        !          1505:     }
        !          1506: 
        !          1507:     /* Allocate the memory; send the packet now if we win. */
        !          1508:     outw(MC_ALLOC | num_pages, ioaddr + MMU_CMD);
        !          1509:     for (time_out = MEMORY_WAIT_TIME; time_out >= 0; time_out--) {
        !          1510:        ir = inw(ioaddr+INTERRUPT);
        !          1511:        if (ir & IM_ALLOC_INT) {
        !          1512:            /* Acknowledge the interrupt, send the packet. */
        !          1513:            outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT);
        !          1514:            smc_hardware_send_packet(dev);      /* Send the packet now.. */
        !          1515:            return 0;
        !          1516:        }
        !          1517:     }
        !          1518: 
        !          1519:     /* Otherwise defer until the Tx-space-allocated interrupt. */
        !          1520:     DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
        !          1521:     outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
        !          1522: 
        !          1523:     return 0;
        !          1524: }
        !          1525: 
        !          1526: /*======================================================================
        !          1527: 
        !          1528:     Handle a Tx anomolous event.  Entered while in Window 2.
        !          1529: 
        !          1530: ======================================================================*/
        !          1531: 
        !          1532: static void smc_tx_err(struct net_device * dev)
        !          1533: {
        !          1534:     struct smc_private *smc = (struct smc_private *)dev->priv;
        !          1535:     ioaddr_t ioaddr = dev->base_addr;
        !          1536:     int saved_packet = inw(ioaddr + PNR_ARR) & 0xff;
        !          1537:     int packet_no = inw(ioaddr + FIFO_PORTS) & 0x7f;
        !          1538:     int tx_status;
        !          1539: 
        !          1540:     /* select this as the packet to read from */
        !          1541:     outw(packet_no, ioaddr + PNR_ARR);
        !          1542: 
        !          1543:     /* read the first word from this packet */
        !          1544:     outw(PTR_AUTOINC | PTR_READ | 0, ioaddr + POINTER);
        !          1545: 
        !          1546:     tx_status = inw(ioaddr + DATA_1);
        !          1547: 
        !          1548:     smc->stats.tx_errors++;
        !          1549:     if (tx_status & TS_LOSTCAR) smc->stats.tx_carrier_errors++;
        !          1550:     if (tx_status & TS_LATCOL)  smc->stats.tx_window_errors++;
        !          1551:     if (tx_status & TS_16COL) {
        !          1552:        smc->stats.tx_aborted_errors++;
        !          1553:        smc->tx_err++;
        !          1554:     }
        !          1555: 
        !          1556:     if (tx_status & TS_SUCCESS) {
        !          1557:        printk(KERN_NOTICE "%s: Successful packet caused error "
        !          1558:               "interrupt?\n", dev->name);
        !          1559:     }
        !          1560:     /* re-enable transmit */
        !          1561:     SMC_SELECT_BANK(0);
        !          1562:     outw(inw(ioaddr + TCR) | TCR_ENABLE | smc->duplex, ioaddr + TCR);
        !          1563:     SMC_SELECT_BANK(2);
        !          1564: 
        !          1565:     outw(MC_FREEPKT, ioaddr + MMU_CMD);        /* Free the packet memory. */
        !          1566: 
        !          1567:     /* one less packet waiting for me */
        !          1568:     smc->packets_waiting--;
        !          1569: 
        !          1570:     outw(saved_packet, ioaddr + PNR_ARR);
        !          1571:     return;
        !          1572: }
        !          1573: 
        !          1574: /*====================================================================*/
        !          1575: 
        !          1576: static void smc_eph_irq(struct net_device *dev)
        !          1577: {
        !          1578:     struct smc_private *smc = dev->priv;
        !          1579:     ioaddr_t ioaddr = dev->base_addr;
        !          1580:     u_short card_stats, ephs;
        !          1581: 
        !          1582:     SMC_SELECT_BANK(0);
        !          1583:     ephs = inw(ioaddr + EPH);
        !          1584:     DEBUG(2, "%s: Ethernet protocol handler interrupt, status"
        !          1585:          " %4.4x.\n", dev->name, ephs);
        !          1586:     /* Could be a counter roll-over warning: update stats. */
        !          1587:     card_stats = inw(ioaddr + COUNTER);
        !          1588:     /* single collisions */
        !          1589:     smc->stats.collisions += card_stats & 0xF;
        !          1590:     card_stats >>= 4;
        !          1591:     /* multiple collisions */
        !          1592:     smc->stats.collisions += card_stats & 0xF;
        !          1593: #if 0          /* These are for when linux supports these statistics */
        !          1594:     card_stats >>= 4;                  /* deferred */
        !          1595:     card_stats >>= 4;                  /* excess deferred */
        !          1596: #endif
        !          1597:     /* If we had a transmit error we must re-enable the transmitter. */
        !          1598:     outw(inw(ioaddr + TCR) | TCR_ENABLE | smc->duplex, ioaddr + TCR);
        !          1599: 
        !          1600:     /* Clear a link error interrupt. */
        !          1601:     SMC_SELECT_BANK(1);
        !          1602:     outw(CTL_AUTO_RELEASE | 0x0000, ioaddr + CONTROL);
        !          1603:     outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE,
        !          1604:         ioaddr + CONTROL);
        !          1605:     SMC_SELECT_BANK(2);
        !          1606: }
        !          1607: 
        !          1608: /*====================================================================*/
        !          1609: 
        !          1610: static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        !          1611: {
        !          1612:     struct smc_private *smc = dev_id;
        !          1613:     struct net_device *dev = &smc->dev;
        !          1614:     ioaddr_t ioaddr;
        !          1615:     u_short saved_bank, saved_pointer, mask, status;
        !          1616:     char bogus_cnt = INTR_WORK;                /* Work we are willing to do. */
        !          1617: 
        !          1618:     if (!netif_device_present(dev))
        !          1619:        return;
        !          1620:     ioaddr = dev->base_addr;
        !          1621: 
        !          1622:     DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
        !          1623:          irq, ioaddr);
        !          1624: 
        !          1625:     smc->watchdog = 0;
        !          1626:     saved_bank = inw(ioaddr + BANK_SELECT);
        !          1627:     if ((saved_bank & 0xff00) != 0x3300) {
        !          1628:        /* The device does not exist -- the card could be off-line, or
        !          1629:           maybe it has been ejected. */
        !          1630:        DEBUG(1, "%s: SMC91c92 interrupt %d for non-existent"
        !          1631:              "/ejected device.\n", dev->name, irq);
        !          1632:        goto irq_done;
        !          1633:     }
        !          1634: 
        !          1635:     SMC_SELECT_BANK(2);
        !          1636:     saved_pointer = inw(ioaddr + POINTER);
        !          1637:     mask = inw(ioaddr + INTERRUPT) >> 8;
        !          1638:     /* clear all interrupts */
        !          1639:     outw(0, ioaddr + INTERRUPT);
        !          1640: 
        !          1641:     do { /* read the status flag, and mask it */
        !          1642:        status = inw(ioaddr + INTERRUPT) & 0xff;
        !          1643:        DEBUG(3, "%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
        !          1644:              status, mask);
        !          1645:        if ((status & mask) == 0)
        !          1646:            break;
        !          1647:        
        !          1648:        if (status & IM_RCV_INT) {
        !          1649:            /* Got a packet(s). */
        !          1650:            smc_rx(dev);
        !          1651:        }
        !          1652:        if (status & IM_TX_INT) {
        !          1653:            smc_tx_err(dev);
        !          1654:            outw(IM_TX_INT, ioaddr + INTERRUPT);
        !          1655:        }
        !          1656:        status &= mask;
        !          1657:        if (status & IM_TX_EMPTY_INT) {
        !          1658:            outw(IM_TX_EMPTY_INT, ioaddr + INTERRUPT);
        !          1659:            mask &= ~IM_TX_EMPTY_INT;
        !          1660:            smc->stats.tx_packets += smc->packets_waiting;
        !          1661:            smc->packets_waiting = 0;
        !          1662:        }
        !          1663:        if (status & IM_ALLOC_INT) {
        !          1664:            /* Clear this interrupt so it doesn't happen again */
        !          1665:            mask &= ~IM_ALLOC_INT;
        !          1666:        
        !          1667:            smc_hardware_send_packet(dev);
        !          1668:        
        !          1669:            /* enable xmit interrupts based on this */
        !          1670:            mask |= (IM_TX_EMPTY_INT | IM_TX_INT);
        !          1671:        
        !          1672:            /* and let the card send more packets to me */
        !          1673:            netif_wake_queue(dev);
        !          1674:        }
        !          1675:        if (status & IM_RX_OVRN_INT) {
        !          1676:            smc->stats.rx_errors++;
        !          1677:            smc->stats.rx_fifo_errors++;
        !          1678:            if (smc->duplex)
        !          1679:                smc->rx_ovrn = 1; /* need MC_RESET outside smc_interrupt */
        !          1680:            outw(IM_RX_OVRN_INT, ioaddr + INTERRUPT);
        !          1681:        }
        !          1682:        if (status & IM_EPH_INT)
        !          1683:            smc_eph_irq(dev);
        !          1684:     } while (--bogus_cnt);
        !          1685: 
        !          1686:     DEBUG(3, "  Restoring saved registers mask %2.2x bank %4.4x"
        !          1687:          " pointer %4.4x.\n", mask, saved_bank, saved_pointer);
        !          1688: 
        !          1689:     /* restore state register */
        !          1690:     outw((mask<<8), ioaddr + INTERRUPT);
        !          1691:     outw(saved_pointer, ioaddr + POINTER);
        !          1692:     SMC_SELECT_BANK(saved_bank);
        !          1693: 
        !          1694:     DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
        !          1695: 
        !          1696: irq_done:
        !          1697: 
        !          1698:     if ((smc->manfid == MANFID_OSITECH) &&
        !          1699:        (smc->cardid != PRODID_OSITECH_SEVEN)) {
        !          1700:        /* Retrigger interrupt if needed */
        !          1701:        mask_bits(0x00ff, ioaddr-0x10+OSITECH_RESET_ISR);
        !          1702:        set_bits(0x0300, ioaddr-0x10+OSITECH_RESET_ISR);
        !          1703:     }
        !          1704:     if (smc->manfid == MANFID_MOTOROLA) {
        !          1705:        u_char cor;
        !          1706:        cor = readb(smc->base + MOT_UART + CISREG_COR);
        !          1707:        writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_UART + CISREG_COR);
        !          1708:        writeb(cor, smc->base + MOT_UART + CISREG_COR);
        !          1709:        cor = readb(smc->base + MOT_LAN + CISREG_COR);
        !          1710:        writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_LAN + CISREG_COR);
        !          1711:        writeb(cor, smc->base + MOT_LAN + CISREG_COR);
        !          1712:     }
        !          1713: #ifdef DOES_NOT_WORK
        !          1714:     if (smc->base != NULL) { /* Megahertz MFC's */
        !          1715:        readb(smc->base+MEGAHERTZ_ISR);
        !          1716:        readb(smc->base+MEGAHERTZ_ISR);
        !          1717:     }
        !          1718: #endif
        !          1719: }
        !          1720: 
        !          1721: /*====================================================================*/
        !          1722: 
        !          1723: static void smc_rx(struct net_device *dev)
        !          1724: {
        !          1725:     struct smc_private *smc = (struct smc_private *)dev->priv;
        !          1726:     ioaddr_t ioaddr = dev->base_addr;
        !          1727:     int rx_status;
        !          1728:     int packet_length; /* Caution: not frame length, rather words
        !          1729:                           to transfer from the chip. */
        !          1730: 
        !          1731:     /* Assertion: we are in Window 2. */
        !          1732: 
        !          1733:     if (inw(ioaddr + FIFO_PORTS) & FP_RXEMPTY) {
        !          1734:        printk(KERN_ERR "%s: smc_rx() with nothing on Rx FIFO.\n",
        !          1735:               dev->name);
        !          1736:        return;
        !          1737:     }
        !          1738: 
        !          1739:     /*  Reset the read pointer, and read the status and packet length. */
        !          1740:     outw(PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr + POINTER);
        !          1741:     rx_status = inw(ioaddr + DATA_1);
        !          1742:     packet_length = inw(ioaddr + DATA_1) & 0x07ff;
        !          1743: 
        !          1744:     DEBUG(2, "%s: Receive status %4.4x length %d.\n",
        !          1745:          dev->name, rx_status, packet_length);
        !          1746: 
        !          1747:     if (!(rx_status & RS_ERRORS)) {            
        !          1748:        /* do stuff to make a new packet */
        !          1749:        struct sk_buff *skb;
        !          1750:        
        !          1751:        /* Note: packet_length adds 5 or 6 extra bytes here! */
        !          1752:        skb = dev_alloc_skb(packet_length+2);
        !          1753:        
        !          1754:        if (skb == NULL) {
        !          1755:            DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
        !          1756:            smc->stats.rx_dropped++;
        !          1757:            outw(MC_RELEASE, ioaddr + MMU_CMD);
        !          1758:            return;
        !          1759:        }
        !          1760:        
        !          1761:        packet_length -= (rx_status & RS_ODDFRAME ? 5 : 6);
        !          1762:        skb_reserve(skb, 2);
        !          1763:        insw(ioaddr+DATA_1, skb_put(skb, packet_length),
        !          1764:             (packet_length+1)>>1);
        !          1765:        skb->protocol = eth_type_trans(skb, dev);
        !          1766:        
        !          1767:        skb->dev = dev;
        !          1768:        netif_rx(skb);
        !          1769:        dev->last_rx = jiffies;
        !          1770:        smc->stats.rx_packets++;
        !          1771:        add_rx_bytes(&smc->stats, packet_length);
        !          1772:        if (rx_status & RS_MULTICAST)
        !          1773:            smc->stats.multicast++;
        !          1774:     } else {
        !          1775:        /* error ... */
        !          1776:        smc->stats.rx_errors++;
        !          1777:        
        !          1778:        if (rx_status & RS_ALGNERR)  smc->stats.rx_frame_errors++;
        !          1779:        if (rx_status & (RS_TOOSHORT | RS_TOOLONG))
        !          1780:            smc->stats.rx_length_errors++;
        !          1781:        if (rx_status & RS_BADCRC)      smc->stats.rx_crc_errors++;
        !          1782:     }
        !          1783:     /* Let the MMU free the memory of this packet. */
        !          1784:     outw(MC_RELEASE, ioaddr + MMU_CMD);
        !          1785: 
        !          1786:     return;
        !          1787: }
        !          1788: 
        !          1789: /*====================================================================*/
        !          1790: 
        !          1791: static struct net_device_stats *smc_get_stats(struct net_device *dev)
        !          1792: {
        !          1793:     struct smc_private *smc = (struct smc_private *)dev->priv;
        !          1794:     /* Nothing to update - the 91c92 is a pretty primative chip. */
        !          1795:     return &smc->stats;
        !          1796: }
        !          1797: 
        !          1798: /*======================================================================
        !          1799: 
        !          1800:     Calculate values for the hardware multicast filter hash table.
        !          1801: 
        !          1802: ======================================================================*/
        !          1803: 
        !          1804: static void fill_multicast_tbl(int count, struct dev_mc_list *addrs,
        !          1805:                               u_char *multicast_table)
        !          1806: {
        !          1807:     struct dev_mc_list *mc_addr;
        !          1808: 
        !          1809:     for (mc_addr = addrs;  mc_addr && --count > 0;  mc_addr = mc_addr->next) {
        !          1810:        u_int position = ether_crc(6, mc_addr->dmi_addr);
        !          1811: #ifndef final_version          /* Verify multicast address. */
        !          1812:        if ((mc_addr->dmi_addr[0] & 1) == 0)
        !          1813:            continue;
        !          1814: #endif
        !          1815:        multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
        !          1816:     }
        !          1817: }
        !          1818: 
        !          1819: /*======================================================================
        !          1820: 
        !          1821:     Set the receive mode.
        !          1822: 
        !          1823:     This routine is used by both the protocol level to notify us of
        !          1824:     promiscuous/multicast mode changes, and by the open/reset code to
        !          1825:     initialize the Rx registers.  We always set the multicast list and
        !          1826:     leave the receiver running.
        !          1827: 
        !          1828: ======================================================================*/
        !          1829: 
        !          1830: static void set_rx_mode(struct net_device *dev)
        !          1831: {
        !          1832:     ioaddr_t ioaddr = dev->base_addr;
        !          1833:     u_int multicast_table[ 2 ] = { 0, };
        !          1834:     unsigned long flags;
        !          1835:     u_short rx_cfg_setting;
        !          1836: 
        !          1837:     if (dev->flags & IFF_PROMISC) {
        !          1838:        printk(KERN_NOTICE "%s: setting Rx mode to promiscuous.\n", dev->name);
        !          1839:        rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
        !          1840:     } else if (dev->flags & IFF_ALLMULTI)
        !          1841:        rx_cfg_setting = RxStripCRC | RxEnable | RxAllMulti;
        !          1842:     else {
        !          1843:        if (dev->mc_count)  {
        !          1844:            fill_multicast_tbl(dev->mc_count, dev->mc_list,
        !          1845:                               (u_char *)multicast_table);
        !          1846:        }
        !          1847:        rx_cfg_setting = RxStripCRC | RxEnable;
        !          1848:     }
        !          1849: 
        !          1850:     /* Load MC table and Rx setting into the chip without interrupts. */
        !          1851:     save_flags(flags);
        !          1852:     cli();
        !          1853:     SMC_SELECT_BANK(3);
        !          1854:     outl(multicast_table[0], ioaddr + MULTICAST0);
        !          1855:     outl(multicast_table[1], ioaddr + MULTICAST4);
        !          1856:     SMC_SELECT_BANK(0);
        !          1857:     outw(rx_cfg_setting, ioaddr + RCR);
        !          1858:     SMC_SELECT_BANK(2);
        !          1859:     restore_flags(flags);
        !          1860: 
        !          1861:     return;
        !          1862: }
        !          1863: 
        !          1864: /*======================================================================
        !          1865: 
        !          1866:     Senses when a card's config changes. Here, it's coax or TP.
        !          1867: 
        !          1868: ======================================================================*/
        !          1869: 
        !          1870: static int s9k_config(struct net_device *dev, struct ifmap *map)
        !          1871: {
        !          1872:     struct smc_private *smc = dev->priv;
        !          1873:     if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
        !          1874:        if (smc->cfg & CFG_MII_SELECT)
        !          1875:            return -EOPNOTSUPP;
        !          1876:        else if (map->port > 2)
        !          1877:            return -EINVAL;
        !          1878:        dev->if_port = map->port;
        !          1879:        printk(KERN_INFO "%s: switched to %s port\n",
        !          1880:               dev->name, if_names[dev->if_port]);
        !          1881:        smc_reset(dev);
        !          1882:     }
        !          1883:     return 0;
        !          1884: }
        !          1885: 
        !          1886: /*======================================================================
        !          1887: 
        !          1888:     Reset the chip, reloading every register that might be corrupted.
        !          1889: 
        !          1890: ======================================================================*/
        !          1891: 
        !          1892: /*
        !          1893:   Set transceiver type, perhaps to something other than what the user
        !          1894:   specified in dev->if_port.
        !          1895: */
        !          1896: static void smc_set_xcvr(struct net_device *dev, int if_port)
        !          1897: {
        !          1898:     struct smc_private *smc = (struct smc_private *)dev->priv;
        !          1899:     ioaddr_t ioaddr = dev->base_addr;
        !          1900:     u_short saved_bank;
        !          1901: 
        !          1902:     saved_bank = inw(ioaddr + BANK_SELECT);
        !          1903:     SMC_SELECT_BANK(1);
        !          1904:     if (if_port == 2) {
        !          1905:        outw(smc->cfg | CFG_AUI_SELECT, ioaddr + CONFIG);
        !          1906:        if ((smc->manfid == MANFID_OSITECH) &&
        !          1907:            (smc->cardid != PRODID_OSITECH_SEVEN))
        !          1908:            set_bits(OSI_AUI_PWR, ioaddr - 0x10 + OSITECH_AUI_PWR);
        !          1909:        smc->media_status = ((dev->if_port == 0) ? 0x0001 : 0x0002);
        !          1910:     } else {
        !          1911:        outw(smc->cfg, ioaddr + CONFIG);
        !          1912:        if ((smc->manfid == MANFID_OSITECH) &&
        !          1913:            (smc->cardid != PRODID_OSITECH_SEVEN))
        !          1914:            mask_bits(~OSI_AUI_PWR, ioaddr - 0x10 + OSITECH_AUI_PWR);
        !          1915:        smc->media_status = ((dev->if_port == 0) ? 0x0012 : 0x4001);
        !          1916:     }
        !          1917:     SMC_SELECT_BANK(saved_bank);
        !          1918: }
        !          1919: 
        !          1920: static void smc_reset(struct net_device *dev)
        !          1921: {
        !          1922:     ioaddr_t ioaddr = dev->base_addr;
        !          1923:     struct smc_private *smc = dev->priv;
        !          1924:     int i;
        !          1925: 
        !          1926:     DEBUG(0, "%s: smc91c92 reset called.\n", dev->name);
        !          1927: 
        !          1928:     /* The first interaction must be a write to bring the chip out
        !          1929:        of sleep mode. */
        !          1930:     SMC_SELECT_BANK(0);
        !          1931:     /* Reset the chip. */
        !          1932:     outw(RCR_SOFTRESET, ioaddr + RCR);
        !          1933:     udelay(10);
        !          1934: 
        !          1935:     /* Clear the transmit and receive configuration registers. */
        !          1936:     outw(RCR_CLEAR, ioaddr + RCR);
        !          1937:     outw(TCR_CLEAR, ioaddr + TCR);
        !          1938: 
        !          1939:     /* Set the Window 1 control, configuration and station addr registers.
        !          1940:        No point in writing the I/O base register ;-> */
        !          1941:     SMC_SELECT_BANK(1);
        !          1942:     /* Automatically release succesfully transmitted packets,
        !          1943:        Accept link errors, counter and Tx error interrupts. */
        !          1944:     outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE,
        !          1945:         ioaddr + CONTROL);
        !          1946:     smc_set_xcvr(dev, dev->if_port);
        !          1947:     if ((smc->manfid == MANFID_OSITECH) &&
        !          1948:        (smc->cardid != PRODID_OSITECH_SEVEN))
        !          1949:        outw((dev->if_port == 2 ? OSI_AUI_PWR : 0) |
        !          1950:             (inw(ioaddr-0x10+OSITECH_AUI_PWR) & 0xff00),
        !          1951:             ioaddr - 0x10 + OSITECH_AUI_PWR);
        !          1952: 
        !          1953:     /* Fill in the physical address.  The databook is wrong about the order! */
        !          1954:     for (i = 0; i < 6; i += 2)
        !          1955:        outw((dev->dev_addr[i+1]<<8)+dev->dev_addr[i],
        !          1956:             ioaddr + ADDR0 + i);
        !          1957: 
        !          1958:     /* Reset the MMU */
        !          1959:     SMC_SELECT_BANK(2);
        !          1960:     outw(MC_RESET, ioaddr + MMU_CMD);
        !          1961:     outw(0, ioaddr + INTERRUPT);
        !          1962: 
        !          1963:     /* Re-enable the chip. */
        !          1964:     SMC_SELECT_BANK(0);
        !          1965:     outw(((smc->cfg & CFG_MII_SELECT) ? 0 : TCR_MONCSN) |
        !          1966:         TCR_ENABLE | TCR_PAD_EN | smc->duplex, ioaddr + TCR);
        !          1967:     set_rx_mode(dev);
        !          1968: 
        !          1969:     if (smc->cfg & CFG_MII_SELECT) {
        !          1970:        SMC_SELECT_BANK(3);
        !          1971: 
        !          1972:        /* Reset MII */
        !          1973:        mdio_write(dev, smc->phy_id, 0, 0x8000);
        !          1974: 
        !          1975:        /* Advertise 100F, 100H, 10F, 10H */
        !          1976:        mdio_write(dev, smc->phy_id, 4, 0x01e1);
        !          1977: 
        !          1978:        /* Restart MII autonegotiation */
        !          1979:        mdio_write(dev, smc->phy_id, 0, 0x0000);
        !          1980:        mdio_write(dev, smc->phy_id, 0, 0x1200);
        !          1981:     }
        !          1982: 
        !          1983:     /* Enable interrupts. */
        !          1984:     SMC_SELECT_BANK(2);
        !          1985:     outw((IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT) << 8,
        !          1986:         ioaddr + INTERRUPT);
        !          1987: }
        !          1988: 
        !          1989: /*======================================================================
        !          1990: 
        !          1991:     Media selection timer routine
        !          1992: 
        !          1993: ======================================================================*/
        !          1994: 
        !          1995: static void media_check(u_long arg)
        !          1996: {
        !          1997:     struct smc_private *smc = (struct smc_private *)(arg);
        !          1998:     struct net_device *dev = &smc->dev;
        !          1999:     ioaddr_t ioaddr = dev->base_addr;
        !          2000:     u_short i, media, saved_bank;
        !          2001:     u_short link;
        !          2002: 
        !          2003:     saved_bank = inw(ioaddr + BANK_SELECT);
        !          2004: 
        !          2005:     if (!netif_device_present(dev))
        !          2006:        goto reschedule;
        !          2007: 
        !          2008:     SMC_SELECT_BANK(2);
        !          2009: 
        !          2010:     /* need MC_RESET to keep the memory consistent. errata? */
        !          2011:     if (smc->rx_ovrn) {
        !          2012:        outw(MC_RESET, ioaddr + MMU_CMD);
        !          2013:        smc->rx_ovrn = 0;
        !          2014:     }
        !          2015:     i = inw(ioaddr + INTERRUPT);
        !          2016:     SMC_SELECT_BANK(0);
        !          2017:     media = inw(ioaddr + EPH) & EPH_LINK_OK;
        !          2018:     SMC_SELECT_BANK(1);
        !          2019:     media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1;
        !          2020: 
        !          2021:     /* Check for pending interrupt with watchdog flag set: with
        !          2022:        this, we can limp along even if the interrupt is blocked */
        !          2023:     if (smc->watchdog++ && ((i>>8) & i)) {
        !          2024:        if (!smc->fast_poll)
        !          2025:            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
        !          2026:        smc_interrupt(dev->irq, smc, NULL);
        !          2027:        smc->fast_poll = HZ;
        !          2028:     }
        !          2029:     if (smc->fast_poll) {
        !          2030:        smc->fast_poll--;
        !          2031:        smc->media.expires = jiffies + 1;
        !          2032:        add_timer(&smc->media);
        !          2033:        SMC_SELECT_BANK(saved_bank);
        !          2034:        return;
        !          2035:     }
        !          2036: 
        !          2037:     if (smc->cfg & CFG_MII_SELECT) {
        !          2038:        if (smc->phy_id < 0)
        !          2039:            goto reschedule;
        !          2040: 
        !          2041:        SMC_SELECT_BANK(3);
        !          2042:        link = mdio_read(dev, smc->phy_id, 1);
        !          2043:        if (!link || (link == 0xffff)) {
        !          2044:            printk(KERN_INFO "%s: MII is missing!\n", dev->name);
        !          2045:            smc->phy_id = -1;
        !          2046:            goto reschedule;
        !          2047:        }
        !          2048: 
        !          2049:        link &= 0x0004;
        !          2050:        if (link != smc->link_status) {
        !          2051:            u_short p = mdio_read(dev, smc->phy_id, 5);
        !          2052:            printk(KERN_INFO "%s: %s link beat\n", dev->name,
        !          2053:                (link) ? "found" : "lost");
        !          2054:            smc->duplex = (((p & 0x0100) || ((p & 0x1c0) == 0x40))
        !          2055:                           ? TCR_FDUPLX : 0);
        !          2056:            if (link) {
        !          2057:                printk(KERN_INFO "%s: autonegotiation complete: "
        !          2058:                       "%sbaseT-%cD selected\n", dev->name,
        !          2059:                       ((p & 0x0180) ? "100" : "10"),
        !          2060:                       (smc->duplex ? 'F' : 'H'));
        !          2061:            }
        !          2062:            SMC_SELECT_BANK(0);
        !          2063:            outw(inw(ioaddr + TCR) | smc->duplex, ioaddr + TCR);
        !          2064:            smc->link_status = link;
        !          2065:        }
        !          2066:        goto reschedule;
        !          2067:     }
        !          2068: 
        !          2069:     /* Ignore collisions unless we've had no rx's recently */
        !          2070:     if (jiffies - dev->last_rx > HZ) {
        !          2071:        if (smc->tx_err || (smc->media_status & EPH_16COL))
        !          2072:            media |= EPH_16COL;
        !          2073:     }
        !          2074:     smc->tx_err = 0;
        !          2075: 
        !          2076:     if (media != smc->media_status) {
        !          2077:        if ((media & smc->media_status & 1) &&
        !          2078:            ((smc->media_status ^ media) & EPH_LINK_OK))
        !          2079:            printk(KERN_INFO "%s: %s link beat\n", dev->name,
        !          2080:                   (smc->media_status & EPH_LINK_OK ? "lost" : "found"));
        !          2081:        else if ((media & smc->media_status & 2) &&
        !          2082:                 ((smc->media_status ^ media) & EPH_16COL))
        !          2083:            printk(KERN_INFO "%s: coax cable %s\n", dev->name,
        !          2084:                   (media & EPH_16COL ? "problem" : "ok"));
        !          2085:        if (dev->if_port == 0) {
        !          2086:            if (media & 1) {
        !          2087:                if (media & EPH_LINK_OK)
        !          2088:                    printk(KERN_INFO "%s: flipped to 10baseT\n",
        !          2089:                           dev->name);
        !          2090:                else
        !          2091:                    smc_set_xcvr(dev, 2);
        !          2092:            } else {
        !          2093:                if (media & EPH_16COL)
        !          2094:                    smc_set_xcvr(dev, 1);
        !          2095:                else
        !          2096:                    printk(KERN_INFO "%s: flipped to 10base2\n",
        !          2097:                           dev->name);
        !          2098:            }
        !          2099:        }
        !          2100:        smc->media_status = media;
        !          2101:     }
        !          2102: 
        !          2103: reschedule:
        !          2104:     smc->media.expires = jiffies + HZ;
        !          2105:     add_timer(&smc->media);
        !          2106:     SMC_SELECT_BANK(saved_bank);
        !          2107: }
        !          2108: 
        !          2109: 
        !          2110: /*====================================================================*/
        !          2111: 
        !          2112: static int __init init_smc91c92_cs(void)
        !          2113: {
        !          2114:     servinfo_t serv;
        !          2115:     DEBUG(0, "%s\n", version);
        !          2116:     CardServices(GetCardServicesInfo, &serv);
        !          2117:     if (serv.Revision != CS_RELEASE_CODE) {
        !          2118:        printk(KERN_ERR
        !          2119:               "smc91c92_cs: Card Services release does not match!\n");
        !          2120:        return -EINVAL;
        !          2121:     }
        !          2122:     register_pccard_driver(&dev_info, &smc91c92_attach, &smc91c92_detach);
        !          2123:     return 0;
        !          2124: }
        !          2125: 
        !          2126: static void __exit exit_smc91c92_cs(void)
        !          2127: {
        !          2128:     DEBUG(0, "smc91c92_cs: unloading\n");
        !          2129:     unregister_pccard_driver(&dev_info);
        !          2130:     while (dev_list != NULL)
        !          2131:        smc91c92_detach(dev_list);
        !          2132: }
        !          2133: 
        !          2134: module_init(init_smc91c92_cs);
        !          2135: module_exit(exit_smc91c92_cs);

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.