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

1.1     ! root        1: /* ----------------------------------------------------------------------------
        !             2: Linux PCMCIA ethernet adapter driver for the New Media Ethernet LAN.
        !             3:   nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao
        !             4: 
        !             5:   The Ethernet LAN uses the Advanced Micro Devices (AMD) Am79C940 Media
        !             6:   Access Controller for Ethernet (MACE).  It is essentially the Am2150
        !             7:   PCMCIA Ethernet card contained in the Am2150 Demo Kit.
        !             8: 
        !             9: Written by Roger C. Pao <[email protected]>
        !            10:   Copyright 1995 Roger C. Pao
        !            11: 
        !            12:   This software may be used and distributed according to the terms of
        !            13:   the GNU General Public License.
        !            14: 
        !            15: Ported to Linux 1.3.* network driver environment by
        !            16:   Matti Aarnio <[email protected]>
        !            17: 
        !            18: References
        !            19: 
        !            20:   Am2150 Technical Reference Manual, Revision 1.0, August 17, 1993
        !            21:   Am79C940 (MACE) Data Sheet, 1994
        !            22:   Am79C90 (C-LANCE) Data Sheet, 1994
        !            23:   Linux PCMCIA Programmer's Guide v1.17
        !            24:   /usr/src/linux/net/inet/dev.c, Linux kernel 1.2.8
        !            25: 
        !            26:   Eric Mears, New Media Corporation
        !            27:   Tom Pollard, New Media Corporation
        !            28:   Dean Siasoyco, New Media Corporation
        !            29:   Ken Lesniak, Silicon Graphics, Inc. <[email protected]>
        !            30:   Donald Becker <[email protected]>
        !            31:   David Hinds <[email protected]>
        !            32: 
        !            33:   The Linux client driver is based on the 3c589_cs.c client driver by
        !            34:   David Hinds.
        !            35: 
        !            36:   The Linux network driver outline is based on the 3c589_cs.c driver,
        !            37:   the 8390.c driver, and the example skeleton.c kernel code, which are
        !            38:   by Donald Becker.
        !            39: 
        !            40:   The Am2150 network driver hardware interface code is based on the
        !            41:   OS/9000 driver for the New Media Ethernet LAN by Eric Mears.
        !            42: 
        !            43:   Special thanks for testing and help in debugging this driver goes
        !            44:   to Ken Lesniak.
        !            45: 
        !            46: -------------------------------------------------------------------------------
        !            47: Driver Notes and Issues
        !            48: -------------------------------------------------------------------------------
        !            49: 
        !            50: 1. Developed on a Dell 320SLi
        !            51:    PCMCIA Card Services 2.6.2
        !            52:    Linux dell 1.2.10 #1 Thu Jun 29 20:23:41 PDT 1995 i386
        !            53: 
        !            54: 2. rc.pcmcia may require loading pcmcia_core with io_speed=300:
        !            55:    'insmod pcmcia_core.o io_speed=300'.
        !            56:    This will avoid problems with fast systems which causes rx_framecnt
        !            57:    to return random values.
        !            58: 
        !            59: 3. If hot extraction does not work for you, use 'ifconfig eth0 down'
        !            60:    before extraction.
        !            61: 
        !            62: 4. There is a bad slow-down problem in this driver.
        !            63: 
        !            64: 5. Future: Multicast processing.  In the meantime, do _not_ compile your
        !            65:    kernel with multicast ip enabled.
        !            66: 
        !            67: -------------------------------------------------------------------------------
        !            68: History
        !            69: -------------------------------------------------------------------------------
        !            70: Log: nmclan_cs.c,v
        !            71:  * Revision 0.16  1995/07/01  06:42:17  rpao
        !            72:  * Bug fix: nmclan_reset() called CardServices incorrectly.
        !            73:  *
        !            74:  * Revision 0.15  1995/05/24  08:09:47  rpao
        !            75:  * Re-implement MULTI_TX dev->tbusy handling.
        !            76:  *
        !            77:  * Revision 0.14  1995/05/23  03:19:30  rpao
        !            78:  * Added, in nmclan_config(), "tuple.Attributes = 0;".
        !            79:  * Modified MACE ID check to ignore chip revision level.
        !            80:  * Avoid tx_free_frames race condition between _start_xmit and _interrupt.
        !            81:  *
        !            82:  * Revision 0.13  1995/05/18  05:56:34  rpao
        !            83:  * Statistics changes.
        !            84:  * Bug fix: nmclan_reset did not enable TX and RX: call restore_multicast_list.
        !            85:  * Bug fix: mace_interrupt checks ~MACE_IMR_DEFAULT.  Fixes driver lockup.
        !            86:  *
        !            87:  * Revision 0.12  1995/05/14  00:12:23  rpao
        !            88:  * Statistics overhaul.
        !            89:  *
        !            90: 
        !            91: 95/05/13 rpao  V0.10a
        !            92:                Bug fix: MACE statistics counters used wrong I/O ports.
        !            93:                Bug fix: mace_interrupt() needed to allow statistics to be
        !            94:                processed without RX or TX interrupts pending.
        !            95: 95/05/11 rpao  V0.10
        !            96:                Multiple transmit request processing.
        !            97:                Modified statistics to use MACE counters where possible.
        !            98: 95/05/10 rpao  V0.09 Bug fix: Must use IO_DATA_PATH_WIDTH_AUTO.
        !            99:                *Released
        !           100: 95/05/10 rpao  V0.08
        !           101:                Bug fix: Make all non-exported functions private by using
        !           102:                static keyword.
        !           103:                Bug fix: Test IntrCnt _before_ reading MACE_IR.
        !           104: 95/05/10 rpao  V0.07 Statistics.
        !           105: 95/05/09 rpao  V0.06 Fix rx_framecnt problem by addition of PCIC wait states.
        !           106: 
        !           107: ---------------------------------------------------------------------------- */
        !           108: 
        !           109: /* ----------------------------------------------------------------------------
        !           110: Conditional Compilation Options
        !           111: ---------------------------------------------------------------------------- */
        !           112: 
        !           113: #define MULTI_TX                       0
        !           114: #define RESET_ON_TIMEOUT               1
        !           115: #define TX_INTERRUPTABLE               1
        !           116: #define RESET_XILINX                   0
        !           117: 
        !           118: /* ----------------------------------------------------------------------------
        !           119: Include Files
        !           120: ---------------------------------------------------------------------------- */
        !           121: 
        !           122: #include <linux/module.h>
        !           123: #include <linux/kernel.h>
        !           124: #include <linux/init.h>
        !           125: #include <linux/sched.h>
        !           126: #include <linux/ptrace.h>
        !           127: #include <linux/slab.h>
        !           128: #include <linux/string.h>
        !           129: #include <linux/timer.h>
        !           130: #include <linux/interrupt.h>
        !           131: #include <linux/in.h>
        !           132: #include <linux/delay.h>
        !           133: #include <asm/io.h>
        !           134: #include <asm/system.h>
        !           135: #include <asm/bitops.h>
        !           136: 
        !           137: #include <linux/netdevice.h>
        !           138: #include <linux/etherdevice.h>
        !           139: #include <linux/skbuff.h>
        !           140: #include <linux/if_arp.h>
        !           141: #include <linux/ioport.h>
        !           142: 
        !           143: #include <pcmcia/version.h>
        !           144: #include <pcmcia/cs_types.h>
        !           145: #include <pcmcia/cs.h>
        !           146: #include <pcmcia/cisreg.h>
        !           147: #include <pcmcia/cistpl.h>
        !           148: #include <pcmcia/ds.h>
        !           149: 
        !           150: /* ----------------------------------------------------------------------------
        !           151: Defines
        !           152: ---------------------------------------------------------------------------- */
        !           153: 
        !           154: #define ETHER_ADDR_LEN                 ETH_ALEN
        !           155:                                        /* 6 bytes in an Ethernet Address */
        !           156: #define MACE_LADRF_LEN                 8
        !           157:                                        /* 8 bytes in Logical Address Filter */
        !           158: 
        !           159: /* Loop Control Defines */
        !           160: #define MACE_MAX_IR_ITERATIONS         10
        !           161: #define MACE_MAX_RX_ITERATIONS         12
        !           162:        /*
        !           163:        TBD: Dean brought this up, and I assumed the hardware would
        !           164:        handle it:
        !           165: 
        !           166:        If MACE_MAX_RX_ITERATIONS is > 1, rx_framecnt may still be
        !           167:        non-zero when the isr exits.  We may not get another interrupt
        !           168:        to process the remaining packets for some time.
        !           169:        */
        !           170: 
        !           171: /*
        !           172: The Am2150 has a Xilinx XC3042 field programmable gate array (FPGA)
        !           173: which manages the interface between the MACE and the PCMCIA bus.  It
        !           174: also includes buffer management for the 32K x 8 SRAM to control up to
        !           175: four transmit and 12 receive frames at a time.
        !           176: */
        !           177: #define AM2150_MAX_TX_FRAMES           4
        !           178: #define AM2150_MAX_RX_FRAMES           12
        !           179: 
        !           180: /* Am2150 Ethernet Card I/O Mapping */
        !           181: #define AM2150_RCV                     0x00
        !           182: #define AM2150_XMT                     0x04
        !           183: #define AM2150_XMT_SKIP                        0x09
        !           184: #define AM2150_RCV_NEXT                        0x0A
        !           185: #define AM2150_RCV_FRAME_COUNT         0x0B
        !           186: #define AM2150_MACE_BANK               0x0C
        !           187: #define AM2150_MACE_BASE               0x10
        !           188: 
        !           189: /* MACE Registers */
        !           190: #define MACE_RCVFIFO                   0
        !           191: #define MACE_XMTFIFO                   1
        !           192: #define MACE_XMTFC                     2
        !           193: #define MACE_XMTFS                     3
        !           194: #define MACE_XMTRC                     4
        !           195: #define MACE_RCVFC                     5
        !           196: #define MACE_RCVFS                     6
        !           197: #define MACE_FIFOFC                    7
        !           198: #define MACE_IR                                8
        !           199: #define MACE_IMR                       9
        !           200: #define MACE_PR                                10
        !           201: #define MACE_BIUCC                     11
        !           202: #define MACE_FIFOCC                    12
        !           203: #define MACE_MACCC                     13
        !           204: #define MACE_PLSCC                     14
        !           205: #define MACE_PHYCC                     15
        !           206: #define MACE_CHIPIDL                   16
        !           207: #define MACE_CHIPIDH                   17
        !           208: #define MACE_IAC                       18
        !           209: /* Reserved */
        !           210: #define MACE_LADRF                     20
        !           211: #define MACE_PADR                      21
        !           212: /* Reserved */
        !           213: /* Reserved */
        !           214: #define MACE_MPC                       24
        !           215: /* Reserved */
        !           216: #define MACE_RNTPC                     26
        !           217: #define MACE_RCVCC                     27
        !           218: /* Reserved */
        !           219: #define MACE_UTR                       29
        !           220: #define MACE_RTR1                      30
        !           221: #define MACE_RTR2                      31
        !           222: 
        !           223: /* MACE Bit Masks */
        !           224: #define MACE_XMTRC_EXDEF               0x80
        !           225: #define MACE_XMTRC_XMTRC               0x0F
        !           226: 
        !           227: #define MACE_XMTFS_XMTSV               0x80
        !           228: #define MACE_XMTFS_UFLO                        0x40
        !           229: #define MACE_XMTFS_LCOL                        0x20
        !           230: #define MACE_XMTFS_MORE                        0x10
        !           231: #define MACE_XMTFS_ONE                 0x08
        !           232: #define MACE_XMTFS_DEFER               0x04
        !           233: #define MACE_XMTFS_LCAR                        0x02
        !           234: #define MACE_XMTFS_RTRY                        0x01
        !           235: 
        !           236: #define MACE_RCVFS_RCVSTS              0xF000
        !           237: #define MACE_RCVFS_OFLO                        0x8000
        !           238: #define MACE_RCVFS_CLSN                        0x4000
        !           239: #define MACE_RCVFS_FRAM                        0x2000
        !           240: #define MACE_RCVFS_FCS                 0x1000
        !           241: 
        !           242: #define MACE_FIFOFC_RCVFC              0xF0
        !           243: #define MACE_FIFOFC_XMTFC              0x0F
        !           244: 
        !           245: #define MACE_IR_JAB                    0x80
        !           246: #define MACE_IR_BABL                   0x40
        !           247: #define MACE_IR_CERR                   0x20
        !           248: #define MACE_IR_RCVCCO                 0x10
        !           249: #define MACE_IR_RNTPCO                 0x08
        !           250: #define MACE_IR_MPCO                   0x04
        !           251: #define MACE_IR_RCVINT                 0x02
        !           252: #define MACE_IR_XMTINT                 0x01
        !           253: 
        !           254: #define MACE_MACCC_PROM                        0x80
        !           255: #define MACE_MACCC_DXMT2PD             0x40
        !           256: #define MACE_MACCC_EMBA                        0x20
        !           257: #define MACE_MACCC_RESERVED            0x10
        !           258: #define MACE_MACCC_DRCVPA              0x08
        !           259: #define MACE_MACCC_DRCVBC              0x04
        !           260: #define MACE_MACCC_ENXMT               0x02
        !           261: #define MACE_MACCC_ENRCV               0x01
        !           262: 
        !           263: #define MACE_PHYCC_LNKFL               0x80
        !           264: #define MACE_PHYCC_DLNKTST             0x40
        !           265: #define MACE_PHYCC_REVPOL              0x20
        !           266: #define MACE_PHYCC_DAPC                        0x10
        !           267: #define MACE_PHYCC_LRT                 0x08
        !           268: #define MACE_PHYCC_ASEL                        0x04
        !           269: #define MACE_PHYCC_RWAKE               0x02
        !           270: #define MACE_PHYCC_AWAKE               0x01
        !           271: 
        !           272: #define MACE_IAC_ADDRCHG               0x80
        !           273: #define MACE_IAC_PHYADDR               0x04
        !           274: #define MACE_IAC_LOGADDR               0x02
        !           275: 
        !           276: #define MACE_UTR_RTRE                  0x80
        !           277: #define MACE_UTR_RTRD                  0x40
        !           278: #define MACE_UTR_RPA                   0x20
        !           279: #define MACE_UTR_FCOLL                 0x10
        !           280: #define MACE_UTR_RCVFCSE               0x08
        !           281: #define MACE_UTR_LOOP_INCL_MENDEC      0x06
        !           282: #define MACE_UTR_LOOP_NO_MENDEC                0x04
        !           283: #define MACE_UTR_LOOP_EXTERNAL         0x02
        !           284: #define MACE_UTR_LOOP_NONE             0x00
        !           285: #define MACE_UTR_RESERVED              0x01
        !           286: 
        !           287: /* Switch MACE register bank (only 0 and 1 are valid) */
        !           288: #define MACEBANK(win_num) outb((win_num), ioaddr + AM2150_MACE_BANK)
        !           289: 
        !           290: #define MACE_IMR_DEFAULT \
        !           291:   (0xFF - \
        !           292:     ( \
        !           293:       MACE_IR_CERR | \
        !           294:       MACE_IR_RCVCCO | \
        !           295:       MACE_IR_RNTPCO | \
        !           296:       MACE_IR_MPCO | \
        !           297:       MACE_IR_RCVINT | \
        !           298:       MACE_IR_XMTINT \
        !           299:     ) \
        !           300:   )
        !           301: #undef MACE_IMR_DEFAULT
        !           302: #define MACE_IMR_DEFAULT 0x00 /* New statistics handling: grab everything */
        !           303: 
        !           304: #define TX_TIMEOUT             ((400*HZ)/1000)
        !           305: 
        !           306: /* ----------------------------------------------------------------------------
        !           307: Type Definitions
        !           308: ---------------------------------------------------------------------------- */
        !           309: 
        !           310: typedef struct _mace_statistics {
        !           311:     /* MACE_XMTFS */
        !           312:     int xmtsv;
        !           313:     int uflo;
        !           314:     int lcol;
        !           315:     int more;
        !           316:     int one;
        !           317:     int defer;
        !           318:     int lcar;
        !           319:     int rtry;
        !           320: 
        !           321:     /* MACE_XMTRC */
        !           322:     int exdef;
        !           323:     int xmtrc;
        !           324: 
        !           325:     /* RFS1--Receive Status (RCVSTS) */
        !           326:     int oflo;
        !           327:     int clsn;
        !           328:     int fram;
        !           329:     int fcs;
        !           330: 
        !           331:     /* RFS2--Runt Packet Count (RNTPC) */
        !           332:     int rfs_rntpc;
        !           333: 
        !           334:     /* RFS3--Receive Collision Count (RCVCC) */
        !           335:     int rfs_rcvcc;
        !           336: 
        !           337:     /* MACE_IR */
        !           338:     int jab;
        !           339:     int babl;
        !           340:     int cerr;
        !           341:     int rcvcco;
        !           342:     int rntpco;
        !           343:     int mpco;
        !           344: 
        !           345:     /* MACE_MPC */
        !           346:     int mpc;
        !           347: 
        !           348:     /* MACE_RNTPC */
        !           349:     int rntpc;
        !           350: 
        !           351:     /* MACE_RCVCC */
        !           352:     int rcvcc;
        !           353: } mace_statistics;
        !           354: 
        !           355: typedef struct _mace_private {
        !           356:     dev_link_t link;
        !           357:     struct net_device dev;
        !           358:     dev_node_t node;
        !           359:     struct net_device_stats linux_stats; /* Linux statistics counters */
        !           360:     mace_statistics mace_stats; /* MACE chip statistics counters */
        !           361: 
        !           362:     /* restore_multicast_list() state variables */
        !           363:     int multicast_ladrf[MACE_LADRF_LEN]; /* Logical address filter */
        !           364:     int multicast_num_addrs;
        !           365: 
        !           366:     char tx_free_frames; /* Number of free transmit frame buffers */
        !           367:     char tx_irq_disabled; /* MACE TX interrupt disabled */
        !           368: } mace_private;
        !           369: 
        !           370: /* ----------------------------------------------------------------------------
        !           371: Private Global Variables
        !           372: ---------------------------------------------------------------------------- */
        !           373: 
        !           374: #ifdef PCMCIA_DEBUG
        !           375: static char rcsid[] =
        !           376: "nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao";
        !           377: static char *version =
        !           378: "nmclan_cs 0.16 (Roger C. Pao)";
        !           379: #endif
        !           380: 
        !           381: static dev_info_t dev_info="nmclan_cs";
        !           382: static dev_link_t *dev_list=NULL;
        !           383: 
        !           384: static char *if_names[]={
        !           385:     "Auto", "10baseT", "BNC",
        !           386: };
        !           387: 
        !           388: /* ----------------------------------------------------------------------------
        !           389: Parameters
        !           390:        These are the parameters that can be set during loading with
        !           391:        'insmod'.
        !           392: ---------------------------------------------------------------------------- */
        !           393: 
        !           394: MODULE_DESCRIPTION("New Media PCMCIA ethernet driver");
        !           395: MODULE_LICENSE("GPL");
        !           396: 
        !           397: #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
        !           398: 
        !           399: static int irq_list[4] = { -1 };
        !           400: MODULE_PARM(irq_list, "1-4i");
        !           401: 
        !           402: /* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
        !           403: INT_MODULE_PARM(if_port, 0);
        !           404: /* Bit map of interrupts to choose from */
        !           405: INT_MODULE_PARM(irq_mask, 0xdeb8);
        !           406: 
        !           407: #ifdef PCMCIA_DEBUG
        !           408: INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
        !           409: #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
        !           410: #else
        !           411: #define DEBUG(n, args...)
        !           412: #endif
        !           413: 
        !           414: /* ----------------------------------------------------------------------------
        !           415: Function Prototypes
        !           416: ---------------------------------------------------------------------------- */
        !           417: 
        !           418: static void nmclan_config(dev_link_t *link);
        !           419: static void nmclan_release(u_long arg);
        !           420: static int nmclan_event(event_t event, int priority,
        !           421:                        event_callback_args_t *args);
        !           422: 
        !           423: static void nmclan_reset(struct net_device *dev);
        !           424: static int mace_config(struct net_device *dev, struct ifmap *map);
        !           425: static int mace_open(struct net_device *dev);
        !           426: static int mace_close(struct net_device *dev);
        !           427: static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev);
        !           428: static void mace_tx_timeout(struct net_device *dev);
        !           429: static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
        !           430: static struct net_device_stats *mace_get_stats(struct net_device *dev);
        !           431: static int mace_rx(struct net_device *dev, unsigned char RxCnt);
        !           432: static void restore_multicast_list(struct net_device *dev);
        !           433: 
        !           434: static void set_multicast_list(struct net_device *dev);
        !           435: 
        !           436: static dev_link_t *nmclan_attach(void);
        !           437: static void nmclan_detach(dev_link_t *);
        !           438: 
        !           439: /* ----------------------------------------------------------------------------
        !           440: flush_stale_links
        !           441:        Clean up stale device structures
        !           442: ---------------------------------------------------------------------------- */
        !           443: 
        !           444: static void flush_stale_links(void)
        !           445: {
        !           446:     dev_link_t *link, *next;
        !           447:     for (link = dev_list; link; link = next) {
        !           448:        next = link->next;
        !           449:        if (link->state & DEV_STALE_LINK)
        !           450:            nmclan_detach(link);
        !           451:     }
        !           452: }
        !           453: 
        !           454: /* ----------------------------------------------------------------------------
        !           455: cs_error
        !           456:        Report a Card Services related error.
        !           457: ---------------------------------------------------------------------------- */
        !           458: 
        !           459: static void cs_error(client_handle_t handle, int func, int ret)
        !           460: {
        !           461:     error_info_t err = { func, ret };
        !           462:     CardServices(ReportError, handle, &err);
        !           463: }
        !           464: 
        !           465: /* ----------------------------------------------------------------------------
        !           466: nmclan_attach
        !           467:        Creates an "instance" of the driver, allocating local data
        !           468:        structures for one device.  The device is registered with Card
        !           469:        Services.
        !           470: ---------------------------------------------------------------------------- */
        !           471: 
        !           472: static dev_link_t *nmclan_attach(void)
        !           473: {
        !           474:     mace_private *lp;
        !           475:     dev_link_t *link;
        !           476:     struct net_device *dev;
        !           477:     client_reg_t client_reg;
        !           478:     int i, ret;
        !           479: 
        !           480:     DEBUG(0, "nmclan_attach()\n");
        !           481:     DEBUG(1, "%s\n", rcsid);
        !           482:     flush_stale_links();
        !           483: 
        !           484:     /* Create new ethernet device */
        !           485:     lp = kmalloc(sizeof(*lp), GFP_KERNEL);
        !           486:     if (!lp) return NULL;
        !           487:     memset(lp, 0, sizeof(*lp));
        !           488:     link = &lp->link; dev = &lp->dev;
        !           489:     link->priv = dev->priv = link->irq.Instance = lp;
        !           490: 
        !           491:     init_timer(&link->release);
        !           492:     link->release.function = &nmclan_release;
        !           493:     link->release.data = (u_long)link;
        !           494:     link->io.NumPorts1 = 32;
        !           495:     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        !           496:     link->io.IOAddrLines = 5;
        !           497:     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
        !           498:     link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
        !           499:     if (irq_list[0] == -1)
        !           500:        link->irq.IRQInfo2 = irq_mask;
        !           501:     else
        !           502:        for (i = 0; i < 4; i++)
        !           503:            link->irq.IRQInfo2 |= 1 << irq_list[i];
        !           504:     link->irq.Handler = &mace_interrupt;
        !           505:     link->conf.Attributes = CONF_ENABLE_IRQ;
        !           506:     link->conf.Vcc = 50;
        !           507:     link->conf.IntType = INT_MEMORY_AND_IO;
        !           508:     link->conf.ConfigIndex = 1;
        !           509:     link->conf.Present = PRESENT_OPTION;
        !           510: 
        !           511:     lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
        !           512: 
        !           513:     dev->hard_start_xmit = &mace_start_xmit;
        !           514:     dev->set_config = &mace_config;
        !           515:     dev->get_stats = &mace_get_stats;
        !           516:     dev->set_multicast_list = &set_multicast_list;
        !           517:     ether_setup(dev);
        !           518:     init_dev_name(dev, lp->node);
        !           519:     dev->open = &mace_open;
        !           520:     dev->stop = &mace_close;
        !           521: #ifdef HAVE_TX_TIMEOUT
        !           522:     dev->tx_timeout = mace_tx_timeout;
        !           523:     dev->watchdog_timeo = TX_TIMEOUT;
        !           524: #endif
        !           525: 
        !           526:     /* Register with Card Services */
        !           527:     link->next = dev_list;
        !           528:     dev_list = link;
        !           529:     client_reg.dev_info = &dev_info;
        !           530:     client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
        !           531:     client_reg.EventMask =
        !           532:        CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
        !           533:        CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
        !           534:        CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
        !           535:     client_reg.event_handler = &nmclan_event;
        !           536:     client_reg.Version = 0x0210;
        !           537:     client_reg.event_callback_args.client_data = link;
        !           538:     ret = CardServices(RegisterClient, &link->handle, &client_reg);
        !           539:     if (ret != 0) {
        !           540:        cs_error(link->handle, RegisterClient, ret);
        !           541:        nmclan_detach(link);
        !           542:        return NULL;
        !           543:     }
        !           544: 
        !           545:     return link;
        !           546: } /* nmclan_attach */
        !           547: 
        !           548: /* ----------------------------------------------------------------------------
        !           549: nmclan_detach
        !           550:        This deletes a driver "instance".  The device is de-registered
        !           551:        with Card Services.  If it has been released, all local data
        !           552:        structures are freed.  Otherwise, the structures will be freed
        !           553:        when the device is released.
        !           554: ---------------------------------------------------------------------------- */
        !           555: 
        !           556: static void nmclan_detach(dev_link_t *link)
        !           557: {
        !           558:     mace_private *lp = link->priv;
        !           559:     dev_link_t **linkp;
        !           560: 
        !           561:     DEBUG(0, "nmclan_detach(0x%p)\n", link);
        !           562: 
        !           563:     /* Locate device structure */
        !           564:     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
        !           565:        if (*linkp == link) break;
        !           566:     if (*linkp == NULL)
        !           567:        return;
        !           568: 
        !           569:     del_timer(&link->release);
        !           570:     if (link->state & DEV_CONFIG) {
        !           571:        nmclan_release((u_long)link);
        !           572:        if (link->state & DEV_STALE_CONFIG) {
        !           573:            link->state |= DEV_STALE_LINK;
        !           574:            return;
        !           575:        }
        !           576:     }
        !           577: 
        !           578:     if (link->handle)
        !           579:        CardServices(DeregisterClient, link->handle);
        !           580: 
        !           581:     /* Unlink device structure, free bits */
        !           582:     *linkp = link->next;
        !           583:     if (link->dev)
        !           584:        unregister_netdev(&lp->dev);
        !           585:     kfree(lp);
        !           586: 
        !           587: } /* nmclan_detach */
        !           588: 
        !           589: /* ----------------------------------------------------------------------------
        !           590: mace_read
        !           591:        Reads a MACE register.  This is bank independent; however, the
        !           592:        caller must ensure that this call is not interruptable.  We are
        !           593:        assuming that during normal operation, the MACE is always in
        !           594:        bank 0.
        !           595: ---------------------------------------------------------------------------- */
        !           596: static int mace_read(ioaddr_t ioaddr, int reg)
        !           597: {
        !           598:   int data = 0xFF;
        !           599:   unsigned long flags;
        !           600: 
        !           601:   switch (reg >> 4) {
        !           602:     case 0: /* register 0-15 */
        !           603:       data = inb(ioaddr + AM2150_MACE_BASE + reg);
        !           604:       break;
        !           605:     case 1: /* register 16-31 */
        !           606:       save_flags(flags);
        !           607:       cli();
        !           608:       MACEBANK(1);
        !           609:       data = inb(ioaddr + AM2150_MACE_BASE + (reg & 0x0F));
        !           610:       MACEBANK(0);
        !           611:       restore_flags(flags);
        !           612:       break;
        !           613:   }
        !           614:   return (data & 0xFF);
        !           615: } /* mace_read */
        !           616: 
        !           617: /* ----------------------------------------------------------------------------
        !           618: mace_write
        !           619:        Writes to a MACE register.  This is bank independent; however,
        !           620:        the caller must ensure that this call is not interruptable.  We
        !           621:        are assuming that during normal operation, the MACE is always in
        !           622:        bank 0.
        !           623: ---------------------------------------------------------------------------- */
        !           624: static void mace_write(ioaddr_t ioaddr, int reg, int data)
        !           625: {
        !           626:   unsigned long flags;
        !           627: 
        !           628:   switch (reg >> 4) {
        !           629:     case 0: /* register 0-15 */
        !           630:       outb(data & 0xFF, ioaddr + AM2150_MACE_BASE + reg);
        !           631:       break;
        !           632:     case 1: /* register 16-31 */
        !           633:       save_flags(flags);
        !           634:       cli();
        !           635:       MACEBANK(1);
        !           636:       outb(data & 0xFF, ioaddr + AM2150_MACE_BASE + (reg & 0x0F));
        !           637:       MACEBANK(0);
        !           638:       restore_flags(flags);
        !           639:       break;
        !           640:   }
        !           641: } /* mace_write */
        !           642: 
        !           643: /* ----------------------------------------------------------------------------
        !           644: mace_init
        !           645:        Resets the MACE chip.
        !           646: ---------------------------------------------------------------------------- */
        !           647: static void mace_init(ioaddr_t ioaddr, char *enet_addr)
        !           648: {
        !           649:   int i;
        !           650: 
        !           651:   /* MACE Software reset */
        !           652:   mace_write(ioaddr, MACE_BIUCC, 1);
        !           653:   while (mace_read(ioaddr, MACE_BIUCC) & 0x01) {
        !           654:     /* Wait for reset bit to be cleared automatically after <= 200ns */;
        !           655:   }
        !           656:   mace_write(ioaddr, MACE_BIUCC, 0);
        !           657: 
        !           658:   /* The Am2150 requires that the MACE FIFOs operate in burst mode. */
        !           659:   mace_write(ioaddr, MACE_FIFOCC, 0x0F);
        !           660: 
        !           661:   mace_write(ioaddr, MACE_RCVFC, 0); /* Disable Auto Strip Receive */
        !           662:   mace_write(ioaddr, MACE_IMR, 0xFF); /* Disable all interrupts until _open */
        !           663: 
        !           664:   /*
        !           665:    * Bit 2-1 PORTSEL[1-0] Port Select.
        !           666:    * 00 AUI/10Base-2
        !           667:    * 01 10Base-T
        !           668:    * 10 DAI Port (reserved in Am2150)
        !           669:    * 11 GPSI
        !           670:    * For this card, only the first two are valid.
        !           671:    * So, PLSCC should be set to
        !           672:    * 0x00 for 10Base-2
        !           673:    * 0x02 for 10Base-T
        !           674:    * Or just set ASEL in PHYCC below!
        !           675:    */
        !           676:   switch (if_port) {
        !           677:     case 1:
        !           678:       mace_write(ioaddr, MACE_PLSCC, 0x02);
        !           679:       break;
        !           680:     case 2:
        !           681:       mace_write(ioaddr, MACE_PLSCC, 0x00);
        !           682:       break;
        !           683:     default:
        !           684:       mace_write(ioaddr, MACE_PHYCC, /* ASEL */ 4);
        !           685:       /* ASEL Auto Select.  When set, the PORTSEL[1-0] bits are overridden,
        !           686:         and the MACE device will automatically select the operating media
        !           687:         interface port. */
        !           688:       break;
        !           689:   }
        !           690: 
        !           691:   mace_write(ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_PHYADDR);
        !           692:   /* Poll ADDRCHG bit */
        !           693:   while (mace_read(ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG)
        !           694:     ;
        !           695:   /* Set PADR register */
        !           696:   for (i = 0; i < ETHER_ADDR_LEN; i++)
        !           697:     mace_write(ioaddr, MACE_PADR, enet_addr[i]);
        !           698: 
        !           699:   /* MAC Configuration Control Register should be written last */
        !           700:   /* Let set_multicast_list set this. */
        !           701:   /* mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV); */
        !           702:   mace_write(ioaddr, MACE_MACCC, 0x00);
        !           703: } /* mace_init */
        !           704: 
        !           705: /* ----------------------------------------------------------------------------
        !           706: nmclan_config
        !           707:        This routine is scheduled to run after a CARD_INSERTION event
        !           708:        is received, to configure the PCMCIA socket, and to make the
        !           709:        ethernet device available to the system.
        !           710: ---------------------------------------------------------------------------- */
        !           711: 
        !           712: #define CS_CHECK(fn, args...) \
        !           713: while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
        !           714: 
        !           715: static void nmclan_config(dev_link_t *link)
        !           716: {
        !           717:   client_handle_t handle = link->handle;
        !           718:   mace_private *lp = link->priv;
        !           719:   struct net_device *dev = &lp->dev;
        !           720:   tuple_t tuple;
        !           721:   cisparse_t parse;
        !           722:   u_char buf[64];
        !           723:   int i, last_ret, last_fn;
        !           724:   ioaddr_t ioaddr;
        !           725: 
        !           726:   DEBUG(0, "nmclan_config(0x%p)\n", link);
        !           727: 
        !           728:   tuple.Attributes = 0;
        !           729:   tuple.TupleData = buf;
        !           730:   tuple.TupleDataMax = 64;
        !           731:   tuple.TupleOffset = 0;
        !           732:   tuple.DesiredTuple = CISTPL_CONFIG;
        !           733:   CS_CHECK(GetFirstTuple, handle, &tuple);
        !           734:   CS_CHECK(GetTupleData, handle, &tuple);
        !           735:   CS_CHECK(ParseTuple, handle, &tuple, &parse);
        !           736:   link->conf.ConfigBase = parse.config.base;
        !           737: 
        !           738:   /* Configure card */
        !           739:   link->state |= DEV_CONFIG;
        !           740: 
        !           741:   CS_CHECK(RequestIO, handle, &link->io);
        !           742:   CS_CHECK(RequestIRQ, handle, &link->irq);
        !           743:   CS_CHECK(RequestConfiguration, handle, &link->conf);
        !           744:   dev->irq = link->irq.AssignedIRQ;
        !           745:   dev->base_addr = link->io.BasePort1;
        !           746:   i = register_netdev(dev);
        !           747:   if (i != 0) {
        !           748:     printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
        !           749:     goto failed;
        !           750:   }
        !           751: 
        !           752:   ioaddr = dev->base_addr;
        !           753: 
        !           754:   /* Read the ethernet address from the CIS. */
        !           755:   tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */;
        !           756:   tuple.TupleData = buf;
        !           757:   tuple.TupleDataMax = 64;
        !           758:   tuple.TupleOffset = 0;
        !           759:   CS_CHECK(GetFirstTuple, handle, &tuple);
        !           760:   CS_CHECK(GetTupleData, handle, &tuple);
        !           761:   memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
        !           762: 
        !           763:   /* Verify configuration by reading the MACE ID. */
        !           764:   {
        !           765:     char sig[2];
        !           766: 
        !           767:     sig[0] = mace_read(ioaddr, MACE_CHIPIDL);
        !           768:     sig[1] = mace_read(ioaddr, MACE_CHIPIDH);
        !           769:     if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
        !           770:       DEBUG(0, "nmclan_cs configured: mace id=%x %x\n",
        !           771:            sig[0], sig[1]);
        !           772:     } else {
        !           773:       printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
        !           774:             " be 0x40 0x?9\n", sig[0], sig[1]);
        !           775:       link->state &= ~DEV_CONFIG_PENDING;
        !           776:       return;
        !           777:     }
        !           778:   }
        !           779: 
        !           780:   mace_init(ioaddr, dev->dev_addr);
        !           781: 
        !           782:   /* The if_port symbol can be set when the module is loaded */
        !           783:   if (if_port <= 2)
        !           784:     dev->if_port = if_port;
        !           785:   else
        !           786:     printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
        !           787: 
        !           788: #if 0
        !           789:   /* Determine which port we are using if auto is selected */
        !           790:   if (if_port==0) {
        !           791:     mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
        !           792:     DEBUG(2, "%s: mace_phycc 0x%X.\n", dev->name,
        !           793:          mace_read(ioaddr, MACE_PHYCC));
        !           794:     if (mace_read(ioaddr, MACE_PHYCC) & MACE_PHYCC_LNKFL)
        !           795:       /* 10base-T receiver is in link fail, MACE is using AUI port. */
        !           796:       dev->if_port = 2;
        !           797:     else
        !           798:       dev->if_port = 1;
        !           799:     mace_write(ioaddr, MACE_MACCC, 0x00);
        !           800:   }
        !           801:   /* Unfortunately, this doesn't seem to work.  LNKFL is always set.
        !           802:      LNKFL is supposed to be opposite the green LED on the edge of the card.
        !           803:      It doesn't work if it is checked and printed in _open() either.
        !           804:      It does work if check in _start_xmit(), but that's not a good place
        !           805:      to printk. */
        !           806: #endif
        !           807: 
        !           808:   copy_dev_name(lp->node, dev);
        !           809:   link->dev = &lp->node;
        !           810:   link->state &= ~DEV_CONFIG_PENDING;
        !           811: 
        !           812:   printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port, hw_addr ",
        !           813:         dev->name, dev->base_addr, dev->irq, if_names[dev->if_port]);
        !           814:   for (i = 0; i < 6; i++)
        !           815:       printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
        !           816:   return;
        !           817: 
        !           818: cs_failed:
        !           819:     cs_error(link->handle, last_fn, last_ret);
        !           820: failed:
        !           821:     nmclan_release((u_long)link);
        !           822:     link->state &= ~DEV_CONFIG_PENDING;
        !           823:     return;
        !           824: 
        !           825: } /* nmclan_config */
        !           826: 
        !           827: /* ----------------------------------------------------------------------------
        !           828: nmclan_release
        !           829:        After a card is removed, nmclan_release() will unregister the
        !           830:        net device, and release the PCMCIA configuration.  If the device
        !           831:        is still open, this will be postponed until it is closed.
        !           832: ---------------------------------------------------------------------------- */
        !           833: static void nmclan_release(u_long arg)
        !           834: {
        !           835:   dev_link_t *link = (dev_link_t *)arg;
        !           836: 
        !           837:   DEBUG(0, "nmclan_release(0x%p)\n", link);
        !           838: 
        !           839:   if (link->open) {
        !           840:     DEBUG(1, "nmclan_cs: release postponed, '%s' "
        !           841:          "still open\n", link->dev->dev_name);
        !           842:     link->state |= DEV_STALE_CONFIG;
        !           843:     return;
        !           844:   }
        !           845: 
        !           846:   CardServices(ReleaseConfiguration, link->handle);
        !           847:   CardServices(ReleaseIO, link->handle, &link->io);
        !           848:   CardServices(ReleaseIRQ, link->handle, &link->irq);
        !           849: 
        !           850:   link->state &= ~DEV_CONFIG;
        !           851: 
        !           852: } /* nmclan_release */
        !           853: 
        !           854: /* ----------------------------------------------------------------------------
        !           855: nmclan_event
        !           856:        The card status event handler.  Mostly, this schedules other
        !           857:        stuff to run after an event is received.  A CARD_REMOVAL event
        !           858:        also sets some flags to discourage the net drivers from trying
        !           859:        to talk to the card any more.
        !           860: ---------------------------------------------------------------------------- */
        !           861: static int nmclan_event(event_t event, int priority,
        !           862:                       event_callback_args_t *args)
        !           863: {
        !           864:   dev_link_t *link = args->client_data;
        !           865:   mace_private *lp = link->priv;
        !           866:   struct net_device *dev = &lp->dev;
        !           867: 
        !           868:   DEBUG(1, "nmclan_event(0x%06x)\n", event);
        !           869: 
        !           870:   switch (event) {
        !           871:     case CS_EVENT_CARD_REMOVAL:
        !           872:       link->state &= ~DEV_PRESENT;
        !           873:       if (link->state & DEV_CONFIG) {
        !           874:        netif_device_detach(dev);
        !           875:        mod_timer(&link->release, jiffies + HZ/20);
        !           876:       }
        !           877:       break;
        !           878:     case CS_EVENT_CARD_INSERTION:
        !           879:       link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        !           880:       nmclan_config(link);
        !           881:       break;
        !           882:     case CS_EVENT_PM_SUSPEND:
        !           883:       link->state |= DEV_SUSPEND;
        !           884:       /* Fall through... */
        !           885:     case CS_EVENT_RESET_PHYSICAL:
        !           886:       if (link->state & DEV_CONFIG) {
        !           887:        if (link->open)
        !           888:          netif_device_detach(dev);
        !           889:        CardServices(ReleaseConfiguration, link->handle);
        !           890:       }
        !           891:       break;
        !           892:     case CS_EVENT_PM_RESUME:
        !           893:       link->state &= ~DEV_SUSPEND;
        !           894:       /* Fall through... */
        !           895:     case CS_EVENT_CARD_RESET:
        !           896:       if (link->state & DEV_CONFIG) {
        !           897:        CardServices(RequestConfiguration, link->handle, &link->conf);
        !           898:        if (link->open) {
        !           899:          nmclan_reset(dev);
        !           900:          netif_device_attach(dev);
        !           901:        }
        !           902:       }
        !           903:       break;
        !           904:     case CS_EVENT_RESET_REQUEST:
        !           905:       return 1;
        !           906:       break;
        !           907:   }
        !           908:   return 0;
        !           909: } /* nmclan_event */
        !           910: 
        !           911: /* ----------------------------------------------------------------------------
        !           912: nmclan_reset
        !           913:        Reset and restore all of the Xilinx and MACE registers.
        !           914: ---------------------------------------------------------------------------- */
        !           915: static void nmclan_reset(struct net_device *dev)
        !           916: {
        !           917:   mace_private *lp = dev->priv;
        !           918: 
        !           919: #if RESET_XILINX
        !           920:   dev_link_t *link = &lp->link;
        !           921:   conf_reg_t reg;
        !           922:   u_long OrigCorValue; 
        !           923: 
        !           924:   /* Save original COR value */
        !           925:   reg.Function = 0;
        !           926:   reg.Action = CS_READ;
        !           927:   reg.Offset = CISREG_COR;
        !           928:   reg.Value = 0;
        !           929:   CardServices(AccessConfigurationRegister, link->handle, &reg);
        !           930:   OrigCorValue = reg.Value;
        !           931: 
        !           932:   /* Reset Xilinx */
        !           933:   reg.Action = CS_WRITE;
        !           934:   reg.Offset = CISREG_COR;
        !           935:   DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
        !           936:        OrigCorValue);
        !           937:   reg.Value = COR_SOFT_RESET;
        !           938:   CardServices(AccessConfigurationRegister, link->handle, &reg);
        !           939:   /* Need to wait for 20 ms for PCMCIA to finish reset. */
        !           940: 
        !           941:   /* Restore original COR configuration index */
        !           942:   reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK);
        !           943:   CardServices(AccessConfigurationRegister, link->handle, &reg);
        !           944:   /* Xilinx is now completely reset along with the MACE chip. */
        !           945:   lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
        !           946: 
        !           947: #endif /* #if RESET_XILINX */
        !           948: 
        !           949:   /* Xilinx is now completely reset along with the MACE chip. */
        !           950:   lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
        !           951: 
        !           952:   /* Reinitialize the MACE chip for operation. */
        !           953:   mace_init(dev->base_addr, dev->dev_addr);
        !           954:   mace_write(dev->base_addr, MACE_IMR, MACE_IMR_DEFAULT);
        !           955: 
        !           956:   /* Restore the multicast list and enable TX and RX. */
        !           957:   restore_multicast_list(dev);
        !           958: } /* nmclan_reset */
        !           959: 
        !           960: /* ----------------------------------------------------------------------------
        !           961: mace_config
        !           962:        [Someone tell me what this is supposed to do?  Is if_port a defined
        !           963:        standard?  If so, there should be defines to indicate 1=10Base-T,
        !           964:        2=10Base-2, etc. including limited automatic detection.]
        !           965: ---------------------------------------------------------------------------- */
        !           966: static int mace_config(struct net_device *dev, struct ifmap *map)
        !           967: {
        !           968:   if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
        !           969:     if (map->port <= 2) {
        !           970:       dev->if_port = map->port;
        !           971:       printk(KERN_INFO "%s: switched to %s port\n", dev->name,
        !           972:             if_names[dev->if_port]);
        !           973:     } else
        !           974:       return -EINVAL;
        !           975:   }
        !           976:   return 0;
        !           977: } /* mace_config */
        !           978: 
        !           979: /* ----------------------------------------------------------------------------
        !           980: mace_open
        !           981:        Open device driver.
        !           982: ---------------------------------------------------------------------------- */
        !           983: static int mace_open(struct net_device *dev)
        !           984: {
        !           985:   ioaddr_t ioaddr = dev->base_addr;
        !           986:   mace_private *lp = dev->priv;
        !           987:   dev_link_t *link = &lp->link;
        !           988: 
        !           989:   if (!DEV_OK(link))
        !           990:     return -ENODEV;
        !           991: 
        !           992:   link->open++;
        !           993:   MOD_INC_USE_COUNT;
        !           994: 
        !           995:   MACEBANK(0);
        !           996: 
        !           997:   netif_start_queue(dev);
        !           998:   netif_mark_up(dev);
        !           999:   nmclan_reset(dev);
        !          1000: 
        !          1001:   return 0; /* Always succeed */
        !          1002: } /* mace_open */
        !          1003: 
        !          1004: /* ----------------------------------------------------------------------------
        !          1005: mace_close
        !          1006:        Closes device driver.
        !          1007: ---------------------------------------------------------------------------- */
        !          1008: static int mace_close(struct net_device *dev)
        !          1009: {
        !          1010:   ioaddr_t ioaddr = dev->base_addr;
        !          1011:   mace_private *lp = dev->priv;
        !          1012:   dev_link_t *link = &lp->link;
        !          1013: 
        !          1014:   DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
        !          1015: 
        !          1016:   /* Mask off all interrupts from the MACE chip. */
        !          1017:   outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
        !          1018: 
        !          1019:   link->open--;
        !          1020:   netif_stop_queue(dev);
        !          1021:   netif_mark_down(dev);
        !          1022:   if (link->state & DEV_STALE_CONFIG)
        !          1023:     mod_timer(&link->release, jiffies + HZ/20);
        !          1024: 
        !          1025:   MOD_DEC_USE_COUNT;
        !          1026: 
        !          1027:   return 0;
        !          1028: } /* mace_close */
        !          1029: 
        !          1030: /* ----------------------------------------------------------------------------
        !          1031: mace_start_xmit
        !          1032:        This routine begins the packet transmit function.  When completed,
        !          1033:        it will generate a transmit interrupt.
        !          1034: 
        !          1035:        According to /usr/src/linux/net/inet/dev.c, if _start_xmit
        !          1036:        returns 0, the "packet is now solely the responsibility of the
        !          1037:        driver."  If _start_xmit returns non-zero, the "transmission
        !          1038:        failed, put skb back into a list."
        !          1039: ---------------------------------------------------------------------------- */
        !          1040: 
        !          1041: static void mace_tx_timeout(struct net_device *dev)
        !          1042: {
        !          1043:   mace_private *lp = (mace_private *)dev->priv;
        !          1044:   dev_link_t *link = &lp->link;
        !          1045: 
        !          1046:   printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
        !          1047: #if RESET_ON_TIMEOUT
        !          1048:   printk("resetting card\n");
        !          1049:   CardServices(ResetCard, link->handle);
        !          1050: #else /* #if RESET_ON_TIMEOUT */
        !          1051:   printk("NOT resetting card\n");
        !          1052: #endif /* #if RESET_ON_TIMEOUT */
        !          1053:   dev->trans_start = jiffies;
        !          1054:   netif_wake_queue(dev);
        !          1055: }
        !          1056: 
        !          1057: static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev)
        !          1058: {
        !          1059:   mace_private *lp = (mace_private *)dev->priv;
        !          1060:   ioaddr_t ioaddr = dev->base_addr;
        !          1061: 
        !          1062:   tx_timeout_check(dev, mace_tx_timeout);
        !          1063:   skb_tx_check(dev, skb);
        !          1064: 
        !          1065:   DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n",
        !          1066:        dev->name, (long)skb->len);
        !          1067: 
        !          1068: #if (!TX_INTERRUPTABLE)
        !          1069:   /* Disable MACE TX interrupts. */
        !          1070:   outb(MACE_IMR_DEFAULT | MACE_IR_XMTINT,
        !          1071:     ioaddr + AM2150_MACE_BASE + MACE_IMR);
        !          1072:   lp->tx_irq_disabled=1;
        !          1073: #endif /* #if (!TX_INTERRUPTABLE) */
        !          1074: 
        !          1075:   {
        !          1076:     /* This block must not be interrupted by another transmit request!
        !          1077:        mace_tx_timeout will take care of timer-based retransmissions from
        !          1078:        the upper layers.  The interrupt handler is guaranteed never to
        !          1079:        service a transmit interrupt while we are in here.
        !          1080:     */
        !          1081: 
        !          1082:     add_tx_bytes(&lp->linux_stats, skb->len);
        !          1083:     lp->tx_free_frames--;
        !          1084: 
        !          1085:     /* WARNING: Write the _exact_ number of bytes written in the header! */
        !          1086:     /* Put out the word header [must be an outw()] . . . */
        !          1087:     outw(skb->len, ioaddr + AM2150_XMT);
        !          1088:     /* . . . and the packet [may be any combination of outw() and outb()] */
        !          1089:     outsw(ioaddr + AM2150_XMT, skb->data, skb->len >> 1);
        !          1090:     if (skb->len & 1) {
        !          1091:       /* Odd byte transfer */
        !          1092:       outb(skb->data[skb->len-1], ioaddr + AM2150_XMT);
        !          1093:     }
        !          1094: 
        !          1095:     dev->trans_start = jiffies;
        !          1096: 
        !          1097: #if MULTI_TX
        !          1098:     if (lp->tx_free_frames > 0)
        !          1099:       netif_start_queue(dev);
        !          1100: #endif /* #if MULTI_TX */
        !          1101:   }
        !          1102: 
        !          1103: #if (!TX_INTERRUPTABLE)
        !          1104:   /* Re-enable MACE TX interrupts. */
        !          1105:   lp->tx_irq_disabled=0;
        !          1106:   outb(MACE_IMR_DEFAULT, ioaddr + AM2150_MACE_BASE + MACE_IMR);
        !          1107: #endif /* #if (!TX_INTERRUPTABLE) */
        !          1108: 
        !          1109:   DEV_KFREE_SKB(skb);
        !          1110: 
        !          1111:   return 0;
        !          1112: } /* mace_start_xmit */
        !          1113: 
        !          1114: /* ----------------------------------------------------------------------------
        !          1115: mace_interrupt
        !          1116:        The interrupt handler.
        !          1117: ---------------------------------------------------------------------------- */
        !          1118: static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        !          1119: {
        !          1120:   mace_private *lp = (mace_private *)dev_id;
        !          1121:   struct net_device *dev = &lp->dev;
        !          1122:   ioaddr_t ioaddr = dev->base_addr;
        !          1123:   int status;
        !          1124:   int IntrCnt = MACE_MAX_IR_ITERATIONS;
        !          1125: 
        !          1126:   if (dev == NULL) {
        !          1127:     DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n",
        !          1128:          irq);
        !          1129:     return;
        !          1130:   }
        !          1131: 
        !          1132:   if (lp->tx_irq_disabled) {
        !          1133:     printk(
        !          1134:       (lp->tx_irq_disabled?
        !          1135:        KERN_NOTICE "%s: Interrupt with tx_irq_disabled "
        !          1136:        "[isr=%02X, imr=%02X]\n": 
        !          1137:        KERN_NOTICE "%s: Re-entering the interrupt handler "
        !          1138:        "[isr=%02X, imr=%02X]\n"),
        !          1139:       dev->name,
        !          1140:       inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
        !          1141:       inb(ioaddr + AM2150_MACE_BASE + MACE_IMR)
        !          1142:     );
        !          1143:     /* WARNING: MACE_IR has been read! */
        !          1144:     return;
        !          1145:   }
        !          1146: 
        !          1147:   if (!netif_device_present(dev)) {
        !          1148:     DEBUG(2, "%s: interrupt from dead card\n", dev->name);
        !          1149:     goto exception;
        !          1150:   }
        !          1151: 
        !          1152:   do {
        !          1153:     /* WARNING: MACE_IR is a READ/CLEAR port! */
        !          1154:     status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
        !          1155: 
        !          1156:     DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
        !          1157: 
        !          1158:     if (status & MACE_IR_RCVINT) {
        !          1159:       mace_rx(dev, MACE_MAX_RX_ITERATIONS);
        !          1160:     }
        !          1161: 
        !          1162:     if (status & MACE_IR_XMTINT) {
        !          1163:       unsigned char fifofc;
        !          1164:       unsigned char xmtrc;
        !          1165:       unsigned char xmtfs;
        !          1166: 
        !          1167:       fifofc = inb(ioaddr + AM2150_MACE_BASE + MACE_FIFOFC);
        !          1168:       if ((fifofc & MACE_FIFOFC_XMTFC)==0) {
        !          1169:        lp->linux_stats.tx_errors++;
        !          1170:        outb(0xFF, ioaddr + AM2150_XMT_SKIP);
        !          1171:       }
        !          1172: 
        !          1173:       /* Transmit Retry Count (XMTRC, reg 4) */
        !          1174:       xmtrc = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTRC);
        !          1175:       if (xmtrc & MACE_XMTRC_EXDEF) lp->mace_stats.exdef++;
        !          1176:       lp->mace_stats.xmtrc += (xmtrc & MACE_XMTRC_XMTRC);
        !          1177: 
        !          1178:       if (
        !          1179:         (xmtfs = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTFS)) &
        !          1180:         MACE_XMTFS_XMTSV /* Transmit Status Valid */
        !          1181:       ) {
        !          1182:        lp->mace_stats.xmtsv++;
        !          1183: 
        !          1184:        if (xmtfs & ~MACE_XMTFS_XMTSV) {
        !          1185:          if (xmtfs & MACE_XMTFS_UFLO) {
        !          1186:            /* Underflow.  Indicates that the Transmit FIFO emptied before
        !          1187:               the end of frame was reached. */
        !          1188:            lp->mace_stats.uflo++;
        !          1189:          }
        !          1190:          if (xmtfs & MACE_XMTFS_LCOL) {
        !          1191:            /* Late Collision */
        !          1192:            lp->mace_stats.lcol++;
        !          1193:          }
        !          1194:          if (xmtfs & MACE_XMTFS_MORE) {
        !          1195:            /* MORE than one retry was needed */
        !          1196:            lp->mace_stats.more++;
        !          1197:          }
        !          1198:          if (xmtfs & MACE_XMTFS_ONE) {
        !          1199:            /* Exactly ONE retry occurred */
        !          1200:            lp->mace_stats.one++;
        !          1201:          }
        !          1202:          if (xmtfs & MACE_XMTFS_DEFER) {
        !          1203:            /* Transmission was defered */
        !          1204:            lp->mace_stats.defer++;
        !          1205:          }
        !          1206:          if (xmtfs & MACE_XMTFS_LCAR) {
        !          1207:            /* Loss of carrier */
        !          1208:            lp->mace_stats.lcar++;
        !          1209:          }
        !          1210:          if (xmtfs & MACE_XMTFS_RTRY) {
        !          1211:            /* Retry error: transmit aborted after 16 attempts */
        !          1212:            lp->mace_stats.rtry++;
        !          1213:          }
        !          1214:         } /* if (xmtfs & ~MACE_XMTFS_XMTSV) */
        !          1215: 
        !          1216:       } /* if (xmtfs & MACE_XMTFS_XMTSV) */
        !          1217: 
        !          1218:       lp->linux_stats.tx_packets++;
        !          1219:       lp->tx_free_frames++;
        !          1220:       netif_wake_queue(dev);
        !          1221:     } /* if (status & MACE_IR_XMTINT) */
        !          1222: 
        !          1223:     if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) {
        !          1224:       if (status & MACE_IR_JAB) {
        !          1225:         /* Jabber Error.  Excessive transmit duration (20-150ms). */
        !          1226:         lp->mace_stats.jab++;
        !          1227:       }
        !          1228:       if (status & MACE_IR_BABL) {
        !          1229:         /* Babble Error.  >1518 bytes transmitted. */
        !          1230:         lp->mace_stats.babl++;
        !          1231:       }
        !          1232:       if (status & MACE_IR_CERR) {
        !          1233:        /* Collision Error.  CERR indicates the absence of the
        !          1234:           Signal Quality Error Test message after a packet
        !          1235:           transmission. */
        !          1236:         lp->mace_stats.cerr++;
        !          1237:       }
        !          1238:       if (status & MACE_IR_RCVCCO) {
        !          1239:         /* Receive Collision Count Overflow; */
        !          1240:         lp->mace_stats.rcvcco++;
        !          1241:       }
        !          1242:       if (status & MACE_IR_RNTPCO) {
        !          1243:         /* Runt Packet Count Overflow */
        !          1244:         lp->mace_stats.rntpco++;
        !          1245:       }
        !          1246:       if (status & MACE_IR_MPCO) {
        !          1247:         /* Missed Packet Count Overflow */
        !          1248:         lp->mace_stats.mpco++;
        !          1249:       }
        !          1250:     } /* if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) */
        !          1251: 
        !          1252:   } while ((status & ~MACE_IMR_DEFAULT) && (--IntrCnt));
        !          1253: 
        !          1254: exception:
        !          1255:   return;
        !          1256: } /* mace_interrupt */
        !          1257: 
        !          1258: /* ----------------------------------------------------------------------------
        !          1259: mace_rx
        !          1260:        Receives packets.
        !          1261: ---------------------------------------------------------------------------- */
        !          1262: static int mace_rx(struct net_device *dev, unsigned char RxCnt)
        !          1263: {
        !          1264:   mace_private *lp = (mace_private *)dev->priv;
        !          1265:   ioaddr_t ioaddr = dev->base_addr;
        !          1266:   unsigned char rx_framecnt;
        !          1267:   unsigned short rx_status;
        !          1268: 
        !          1269:   while (
        !          1270:     ((rx_framecnt = inb(ioaddr + AM2150_RCV_FRAME_COUNT)) > 0) &&
        !          1271:     (rx_framecnt <= 12) && /* rx_framecnt==0xFF if card is extracted. */
        !          1272:     (RxCnt--)
        !          1273:   ) {
        !          1274:     rx_status = inw(ioaddr + AM2150_RCV);
        !          1275: 
        !          1276:     DEBUG(3, "%s: in mace_rx(), framecnt 0x%X, rx_status"
        !          1277:          " 0x%X.\n", dev->name, rx_framecnt, rx_status);
        !          1278: 
        !          1279:     if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
        !          1280:       lp->linux_stats.rx_errors++;
        !          1281:       if (rx_status & MACE_RCVFS_OFLO) {
        !          1282:         lp->mace_stats.oflo++;
        !          1283:       }
        !          1284:       if (rx_status & MACE_RCVFS_CLSN) {
        !          1285:         lp->mace_stats.clsn++;
        !          1286:       }
        !          1287:       if (rx_status & MACE_RCVFS_FRAM) {
        !          1288:        lp->mace_stats.fram++;
        !          1289:       }
        !          1290:       if (rx_status & MACE_RCVFS_FCS) {
        !          1291:         lp->mace_stats.fcs++;
        !          1292:       }
        !          1293:     } else {
        !          1294:       short pkt_len = (rx_status & ~MACE_RCVFS_RCVSTS) - 4;
        !          1295:         /* Auto Strip is off, always subtract 4 */
        !          1296:       struct sk_buff *skb;
        !          1297: 
        !          1298:       lp->mace_stats.rfs_rntpc += inb(ioaddr + AM2150_RCV);
        !          1299:         /* runt packet count */
        !          1300:       lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
        !          1301:         /* rcv collision count */
        !          1302: 
        !          1303:       DEBUG(3, "    receiving packet size 0x%X rx_status"
        !          1304:            " 0x%X.\n", pkt_len, rx_status);
        !          1305: 
        !          1306:       skb = dev_alloc_skb(pkt_len+2);
        !          1307: 
        !          1308:       if (skb != NULL) {
        !          1309:        skb->dev = dev;
        !          1310: 
        !          1311:        skb_reserve(skb, 2);
        !          1312:        insw(ioaddr + AM2150_RCV, skb_put(skb, pkt_len), pkt_len>>1);
        !          1313:        if (pkt_len & 1)
        !          1314:            *(skb->tail-1) = inb(ioaddr + AM2150_RCV);
        !          1315:        skb->protocol = eth_type_trans(skb, dev);
        !          1316:        
        !          1317:        netif_rx(skb); /* Send the packet to the upper (protocol) layers. */
        !          1318: 
        !          1319:        dev->last_rx = jiffies;
        !          1320:        lp->linux_stats.rx_packets++;
        !          1321:        add_rx_bytes(&lp->linux_stats, skb->len);
        !          1322:        outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
        !          1323:        continue;
        !          1324:       } else {
        !          1325:        DEBUG(1, "%s: couldn't allocate a sk_buff of size"
        !          1326:              " %d.\n", dev->name, pkt_len);
        !          1327:        lp->linux_stats.rx_dropped++;
        !          1328:       }
        !          1329:     }
        !          1330:     outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
        !          1331:   } /* while */
        !          1332: 
        !          1333:   return 0;
        !          1334: } /* mace_rx */
        !          1335: 
        !          1336: /* ----------------------------------------------------------------------------
        !          1337: pr_linux_stats
        !          1338: ---------------------------------------------------------------------------- */
        !          1339: static void pr_linux_stats(struct net_device_stats *pstats)
        !          1340: {
        !          1341:   DEBUG(2, "pr_linux_stats\n");
        !          1342:   DEBUG(2, " rx_packets=%-7ld        tx_packets=%ld\n",
        !          1343:        (long)pstats->rx_packets, (long)pstats->tx_packets);
        !          1344:   DEBUG(2, " rx_errors=%-7ld         tx_errors=%ld\n",
        !          1345:        (long)pstats->rx_errors, (long)pstats->tx_errors);
        !          1346:   DEBUG(2, " rx_dropped=%-7ld        tx_dropped=%ld\n",
        !          1347:        (long)pstats->rx_dropped, (long)pstats->tx_dropped);
        !          1348:   DEBUG(2, " multicast=%-7ld         collisions=%ld\n",
        !          1349:        (long)pstats->multicast, (long)pstats->collisions);
        !          1350: 
        !          1351:   DEBUG(2, " rx_length_errors=%-7ld  rx_over_errors=%ld\n",
        !          1352:        (long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
        !          1353:   DEBUG(2, " rx_crc_errors=%-7ld     rx_frame_errors=%ld\n",
        !          1354:        (long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
        !          1355:   DEBUG(2, " rx_fifo_errors=%-7ld    rx_missed_errors=%ld\n",
        !          1356:        (long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
        !          1357: 
        !          1358:   DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
        !          1359:        (long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
        !          1360:   DEBUG(2, " tx_fifo_errors=%-7ld    tx_heartbeat_errors=%ld\n",
        !          1361:        (long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
        !          1362:   DEBUG(2, " tx_window_errors=%ld\n",
        !          1363:        (long)pstats->tx_window_errors);
        !          1364: } /* pr_linux_stats */
        !          1365: 
        !          1366: /* ----------------------------------------------------------------------------
        !          1367: pr_mace_stats
        !          1368: ---------------------------------------------------------------------------- */
        !          1369: static void pr_mace_stats(mace_statistics *pstats)
        !          1370: {
        !          1371:   DEBUG(2, "pr_mace_stats\n");
        !          1372: 
        !          1373:   DEBUG(2, " xmtsv=%-7d             uflo=%d\n",
        !          1374:        pstats->xmtsv, pstats->uflo);
        !          1375:   DEBUG(2, " lcol=%-7d              more=%d\n",
        !          1376:        pstats->lcol, pstats->more);
        !          1377:   DEBUG(2, " one=%-7d               defer=%d\n",
        !          1378:        pstats->one, pstats->defer);
        !          1379:   DEBUG(2, " lcar=%-7d              rtry=%d\n",
        !          1380:        pstats->lcar, pstats->rtry);
        !          1381: 
        !          1382:   /* MACE_XMTRC */
        !          1383:   DEBUG(2, " exdef=%-7d             xmtrc=%d\n",
        !          1384:        pstats->exdef, pstats->xmtrc);
        !          1385: 
        !          1386:   /* RFS1--Receive Status (RCVSTS) */
        !          1387:   DEBUG(2, " oflo=%-7d              clsn=%d\n",
        !          1388:        pstats->oflo, pstats->clsn);
        !          1389:   DEBUG(2, " fram=%-7d              fcs=%d\n",
        !          1390:        pstats->fram, pstats->fcs);
        !          1391: 
        !          1392:   /* RFS2--Runt Packet Count (RNTPC) */
        !          1393:   /* RFS3--Receive Collision Count (RCVCC) */
        !          1394:   DEBUG(2, " rfs_rntpc=%-7d         rfs_rcvcc=%d\n",
        !          1395:        pstats->rfs_rntpc, pstats->rfs_rcvcc);
        !          1396: 
        !          1397:   /* MACE_IR */
        !          1398:   DEBUG(2, " jab=%-7d               babl=%d\n",
        !          1399:        pstats->jab, pstats->babl);
        !          1400:   DEBUG(2, " cerr=%-7d              rcvcco=%d\n",
        !          1401:        pstats->cerr, pstats->rcvcco);
        !          1402:   DEBUG(2, " rntpco=%-7d            mpco=%d\n",
        !          1403:        pstats->rntpco, pstats->mpco);
        !          1404: 
        !          1405:   /* MACE_MPC */
        !          1406:   DEBUG(2, " mpc=%d\n", pstats->mpc);
        !          1407: 
        !          1408:   /* MACE_RNTPC */
        !          1409:   DEBUG(2, " rntpc=%d\n", pstats->rntpc);
        !          1410: 
        !          1411:   /* MACE_RCVCC */
        !          1412:   DEBUG(2, " rcvcc=%d\n", pstats->rcvcc);
        !          1413: 
        !          1414: } /* pr_mace_stats */
        !          1415: 
        !          1416: /* ----------------------------------------------------------------------------
        !          1417: update_stats
        !          1418:        Update statistics.  We change to register window 1, so this
        !          1419:        should be run single-threaded if the device is active. This is
        !          1420:        expected to be a rare operation, and it's simpler for the rest
        !          1421:        of the driver to assume that window 0 is always valid rather
        !          1422:        than use a special window-state variable.
        !          1423: 
        !          1424:        oflo & uflo should _never_ occur since it would mean the Xilinx
        !          1425:        was not able to transfer data between the MACE FIFO and the
        !          1426:        card's SRAM fast enough.  If this happens, something is
        !          1427:        seriously wrong with the hardware.
        !          1428: ---------------------------------------------------------------------------- */
        !          1429: static void update_stats(ioaddr_t ioaddr, struct net_device *dev)
        !          1430: {
        !          1431:   mace_private *lp = (mace_private *)dev->priv;
        !          1432: 
        !          1433:   lp->mace_stats.rcvcc += mace_read(ioaddr, MACE_RCVCC);
        !          1434:   lp->mace_stats.rntpc += mace_read(ioaddr, MACE_RNTPC);
        !          1435:   lp->mace_stats.mpc += mace_read(ioaddr, MACE_MPC);
        !          1436:   /* At this point, mace_stats is fully updated for this call.
        !          1437:      We may now update the linux_stats. */
        !          1438: 
        !          1439:   /* The MACE has no equivalent for linux_stats field which are commented
        !          1440:      out. */
        !          1441: 
        !          1442: #if 0
        !          1443:   /* These must be tracked in the main body of the driver. */
        !          1444:   lp->linux_stats.rx_packets;
        !          1445:   lp->linux_stats.tx_packets;
        !          1446:   lp->linux_stats.rx_errors;
        !          1447:   lp->linux_stats.tx_errors;
        !          1448:   lp->linux_stats.rx_dropped;
        !          1449:   lp->linux_stats.tx_dropped;
        !          1450: #endif
        !          1451:   /* lp->linux_stats.multicast; */
        !          1452:   lp->linux_stats.collisions = 
        !          1453:     lp->mace_stats.rcvcco * 256 + lp->mace_stats.rcvcc;
        !          1454:     /* Collision: The MACE may retry sending a packet 15 times
        !          1455:        before giving up.  The retry count is in XMTRC.
        !          1456:        Does each retry constitute a collision?
        !          1457:        If so, why doesn't the RCVCC record these collisions? */
        !          1458: 
        !          1459:   /* detailed rx_errors: */
        !          1460:   lp->linux_stats.rx_length_errors = 
        !          1461:     lp->mace_stats.rntpco * 256 + lp->mace_stats.rntpc;
        !          1462:   /* lp->linux_stats.rx_over_errors */
        !          1463:   lp->linux_stats.rx_crc_errors = lp->mace_stats.fcs;
        !          1464:   lp->linux_stats.rx_frame_errors = lp->mace_stats.fram;
        !          1465:   lp->linux_stats.rx_fifo_errors = lp->mace_stats.oflo;
        !          1466:   lp->linux_stats.rx_missed_errors = 
        !          1467:     lp->mace_stats.mpco * 256 + lp->mace_stats.mpc;
        !          1468: 
        !          1469:   /* detailed tx_errors */
        !          1470:   lp->linux_stats.tx_aborted_errors = lp->mace_stats.rtry;
        !          1471:   lp->linux_stats.tx_carrier_errors = lp->mace_stats.lcar;
        !          1472:     /* LCAR usually results from bad cabling. */
        !          1473:   lp->linux_stats.tx_fifo_errors = lp->mace_stats.uflo;
        !          1474:   lp->linux_stats.tx_heartbeat_errors = lp->mace_stats.cerr;
        !          1475:   /* lp->linux_stats.tx_window_errors; */
        !          1476: 
        !          1477:   return;
        !          1478: } /* update_stats */
        !          1479: 
        !          1480: /* ----------------------------------------------------------------------------
        !          1481: mace_get_stats
        !          1482:        Gathers ethernet statistics from the MACE chip.
        !          1483: ---------------------------------------------------------------------------- */
        !          1484: static struct net_device_stats *mace_get_stats(struct net_device *dev)
        !          1485: {
        !          1486:   mace_private *lp = (mace_private *)dev->priv;
        !          1487: 
        !          1488:   update_stats(dev->base_addr, dev);
        !          1489: 
        !          1490:   DEBUG(1, "%s: updating the statistics.\n", dev->name);
        !          1491:   pr_linux_stats(&lp->linux_stats);
        !          1492:   pr_mace_stats(&lp->mace_stats);
        !          1493: 
        !          1494:   return &lp->linux_stats;
        !          1495: } /* net_device_stats */
        !          1496: 
        !          1497: /* ----------------------------------------------------------------------------
        !          1498: updateCRC
        !          1499:        Modified from Am79C90 data sheet.
        !          1500: ---------------------------------------------------------------------------- */
        !          1501: 
        !          1502: #if BROKEN_MULTICAST
        !          1503: 
        !          1504: static void updateCRC(int *CRC, int bit)
        !          1505: {
        !          1506:   int poly[]={
        !          1507:     1,1,1,0, 1,1,0,1,
        !          1508:     1,0,1,1, 1,0,0,0,
        !          1509:     1,0,0,0, 0,0,1,1,
        !          1510:     0,0,1,0, 0,0,0,0
        !          1511:   }; /* CRC polynomial.  poly[n] = coefficient of the x**n term of the
        !          1512:        CRC generator polynomial. */
        !          1513: 
        !          1514:   int j;
        !          1515: 
        !          1516:   /* shift CRC and control bit (CRC[32]) */
        !          1517:   for (j = 32; j > 0; j--)
        !          1518:     CRC[j] = CRC[j-1];
        !          1519:   CRC[0] = 0;
        !          1520: 
        !          1521:   /* If bit XOR(control bit) = 1, set CRC = CRC XOR polynomial. */
        !          1522:   if (bit ^ CRC[32])
        !          1523:     for (j = 0; j < 32; j++)
        !          1524:       CRC[j] ^= poly[j];
        !          1525: } /* updateCRC */
        !          1526: 
        !          1527: /* ----------------------------------------------------------------------------
        !          1528: BuildLAF
        !          1529:        Build logical address filter.
        !          1530:        Modified from Am79C90 data sheet.
        !          1531: 
        !          1532: Input
        !          1533:        ladrf: logical address filter (contents initialized to 0)
        !          1534:        adr: ethernet address
        !          1535: ---------------------------------------------------------------------------- */
        !          1536: static void BuildLAF(int *ladrf, int *adr)
        !          1537: {
        !          1538:   int CRC[33]={1}; /* CRC register, 1 word/bit + extra control bit */
        !          1539: 
        !          1540:   int i, byte; /* temporary array indices */
        !          1541:   int hashcode; /* the output object */
        !          1542: 
        !          1543:   CRC[32]=0;
        !          1544: 
        !          1545:   for (byte = 0; byte < 6; byte++)
        !          1546:     for (i = 0; i < 8; i++)
        !          1547:       updateCRC(CRC, (adr[byte] >> i) & 1);
        !          1548: 
        !          1549:   hashcode = 0;
        !          1550:   for (i = 0; i < 6; i++)
        !          1551:     hashcode = (hashcode << 1) + CRC[i];
        !          1552: 
        !          1553:   byte = hashcode >> 3;
        !          1554:   ladrf[byte] |= (1 << (hashcode & 7));
        !          1555: 
        !          1556: #ifdef PCMCIA_DEBUG
        !          1557:   if (pc_debug > 2) {
        !          1558:     printk(KERN_DEBUG "    adr =");
        !          1559:     for (i = 0; i < 6; i++)
        !          1560:       printk(" %02X", adr[i]);
        !          1561:     printk("\n" KERN_DEBUG "    hashcode = %d(decimal), ladrf[0:63]"
        !          1562:           " =", hashcode);
        !          1563:     for (i = 0; i < 8; i++)
        !          1564:       printk(" %02X", ladrf[i]);
        !          1565:     printk("\n");
        !          1566:   }
        !          1567: #endif
        !          1568: } /* BuildLAF */
        !          1569: 
        !          1570: /* ----------------------------------------------------------------------------
        !          1571: restore_multicast_list
        !          1572:        Restores the multicast filter for MACE chip to the last
        !          1573:        set_multicast_list() call.
        !          1574: 
        !          1575: Input
        !          1576:        multicast_num_addrs
        !          1577:        multicast_ladrf[]
        !          1578: ---------------------------------------------------------------------------- */
        !          1579: static void restore_multicast_list(struct net_device *dev)
        !          1580: {
        !          1581:   mace_private *lp = (mace_private *)dev->priv;
        !          1582:   int num_addrs = lp->multicast_num_addrs;
        !          1583:   int *ladrf = lp->multicast_ladrf;
        !          1584:   ioaddr_t ioaddr = dev->base_addr;
        !          1585:   int i;
        !          1586: 
        !          1587:   DEBUG(2, "%s: restoring Rx mode to %d addresses.\n",
        !          1588:        dev->name, num_addrs);
        !          1589: 
        !          1590:   if (num_addrs > 0) {
        !          1591: 
        !          1592:     DEBUG(1, "Attempt to restore multicast list detected.\n");
        !          1593: 
        !          1594:     mace_write(ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
        !          1595:     /* Poll ADDRCHG bit */
        !          1596:     while (mace_read(ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG)
        !          1597:       ;
        !          1598:     /* Set LADRF register */
        !          1599:     for (i = 0; i < MACE_LADRF_LEN; i++)
        !          1600:       mace_write(ioaddr, MACE_LADRF, ladrf[i]);
        !          1601: 
        !          1602:     mace_write(ioaddr, MACE_UTR, MACE_UTR_RCVFCSE | MACE_UTR_LOOP_EXTERNAL);
        !          1603:     mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
        !          1604: 
        !          1605:   } else if (num_addrs < 0) {
        !          1606: 
        !          1607:     /* Promiscuous mode: receive all packets */
        !          1608:     mace_write(ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
        !          1609:     mace_write(ioaddr, MACE_MACCC,
        !          1610:       MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV
        !          1611:     );
        !          1612: 
        !          1613:   } else {
        !          1614: 
        !          1615:     /* Normal mode */
        !          1616:     mace_write(ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
        !          1617:     mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
        !          1618: 
        !          1619:   }
        !          1620: } /* restore_multicast_list */
        !          1621: 
        !          1622: /* ----------------------------------------------------------------------------
        !          1623: set_multicast_list
        !          1624:        Set or clear the multicast filter for this adaptor.
        !          1625: 
        !          1626: Input
        !          1627:        num_addrs == -1 Promiscuous mode, receive all packets
        !          1628:        num_addrs == 0  Normal mode, clear multicast list
        !          1629:        num_addrs > 0   Multicast mode, receive normal and MC packets, and do
        !          1630:                        best-effort filtering.
        !          1631: Output
        !          1632:        multicast_num_addrs
        !          1633:        multicast_ladrf[]
        !          1634: ---------------------------------------------------------------------------- */
        !          1635: 
        !          1636: static void set_multicast_list(struct net_device *dev)
        !          1637: {
        !          1638:   mace_private *lp = (mace_private *)dev->priv;
        !          1639:   int adr[ETHER_ADDR_LEN] = {0}; /* Ethernet address */
        !          1640:   int i;
        !          1641:   struct dev_mc_list *dmi = dev->mc_list;
        !          1642: 
        !          1643: #ifdef PCMCIA_DEBUG
        !          1644:   if (pc_debug > 1) {
        !          1645:     static int old = 0;
        !          1646:     if (dev->mc_count != old) {
        !          1647:       old = dev->mc_count;
        !          1648:       DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
        !          1649:            dev->name, old);
        !          1650:     }
        !          1651:   }
        !          1652: #endif
        !          1653: 
        !          1654:   /* Set multicast_num_addrs. */
        !          1655:   lp->multicast_num_addrs = dev->mc_count;
        !          1656: 
        !          1657:   /* Set multicast_ladrf. */
        !          1658:   if (num_addrs > 0) {
        !          1659:     /* Calculate multicast logical address filter */
        !          1660:     memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN);
        !          1661:     for (i = 0; i < dev->mc_count; i++) {
        !          1662:       memcpy(adr, dmi->dmi_addr, ETHER_ADDR_LEN);
        !          1663:       dmi = dmi->next;
        !          1664:       BuildLAF(lp->multicast_ladrf, adr);
        !          1665:     }
        !          1666:   }
        !          1667: 
        !          1668:   restore_multicast_list(dev);
        !          1669: 
        !          1670: } /* set_multicast_list */
        !          1671: 
        !          1672: #endif /* BROKEN_MULTICAST */
        !          1673: 
        !          1674: static void restore_multicast_list(struct net_device *dev)
        !          1675: {
        !          1676:   ioaddr_t ioaddr = dev->base_addr;
        !          1677: 
        !          1678:   DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name,
        !          1679:        ((mace_private *)(dev->priv))->multicast_num_addrs);
        !          1680: 
        !          1681:   if (dev->flags & IFF_PROMISC) {
        !          1682:     /* Promiscuous mode: receive all packets */
        !          1683:     mace_write(ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
        !          1684:     mace_write(ioaddr, MACE_MACCC,
        !          1685:       MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV
        !          1686:     );
        !          1687:   } else {
        !          1688:     /* Normal mode */
        !          1689:     mace_write(ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
        !          1690:     mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
        !          1691:   }
        !          1692: } /* restore_multicast_list */
        !          1693: 
        !          1694: static void set_multicast_list(struct net_device *dev)
        !          1695: {
        !          1696:   mace_private *lp = (mace_private *)dev->priv;
        !          1697: 
        !          1698: #ifdef PCMCIA_DEBUG
        !          1699:   if (pc_debug > 1) {
        !          1700:     static int old = 0;
        !          1701:     if (dev->mc_count != old) {
        !          1702:       old = dev->mc_count;
        !          1703:       DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
        !          1704:            dev->name, old);
        !          1705:     }
        !          1706:   }
        !          1707: #endif
        !          1708: 
        !          1709:   lp->multicast_num_addrs = dev->mc_count;
        !          1710:   restore_multicast_list(dev);
        !          1711: 
        !          1712: } /* set_multicast_list */
        !          1713: 
        !          1714: /* ----------------------------------------------------------------------------
        !          1715: init_nmclan_cs
        !          1716: ---------------------------------------------------------------------------- */
        !          1717: 
        !          1718: static int __init init_nmclan_cs(void)
        !          1719: {
        !          1720:   servinfo_t serv;
        !          1721:   DEBUG(0, "%s\n", version);
        !          1722:   CardServices(GetCardServicesInfo, &serv);
        !          1723:   if (serv.Revision != CS_RELEASE_CODE) {
        !          1724:     printk(KERN_NOTICE "nmclan_cs: Card Services release does not match!\n");
        !          1725:     return -EINVAL;
        !          1726:   }
        !          1727:   register_pccard_driver(&dev_info, &nmclan_attach, &nmclan_detach);
        !          1728:   return 0;
        !          1729: }
        !          1730: 
        !          1731: /* ----------------------------------------------------------------------------
        !          1732: exit_nmclan_cs
        !          1733: ---------------------------------------------------------------------------- */
        !          1734: 
        !          1735: static void __exit exit_nmclan_cs(void)
        !          1736: {
        !          1737:     DEBUG(0, "nmclan_cs: unloading\n");
        !          1738:     unregister_pccard_driver(&dev_info);
        !          1739:     while (dev_list != NULL)
        !          1740:        nmclan_detach(dev_list);
        !          1741: }
        !          1742: 
        !          1743: module_init(init_nmclan_cs);
        !          1744: module_exit(exit_nmclan_cs);

unix.superglobalmegacorp.com

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