Annotation of Gnu-Mach/linux/src/drivers/net/yellowfin.c, revision 1.1.1.3

1.1       root        1: /* yellowfin.c: A Packet Engines G-NIC ethernet driver for linux. */
                      2: /*
1.1.1.3 ! root        3:        Written 1997-2003 by Donald Becker.
1.1       root        4: 
1.1.1.3 ! root        5:        This software may be used and distributed according to the terms of
        !             6:        the GNU General Public License (GPL), incorporated herein by reference.
        !             7:        Drivers based on or derived from this code fall under the GPL and must
        !             8:        retain the authorship, copyright and license notice.  This file is not
        !             9:        a complete program and may only be used when the entire operating
        !            10:        system is licensed under the GPL.
1.1       root       11: 
                     12:        This driver is for the Packet Engines G-NIC PCI Gigabit Ethernet adapter.
                     13:        It also supports the Symbios Logic version of the same chip core.
                     14: 
1.1.1.3 ! root       15:        The author may be reached as [email protected], or C/O
        !            16:        Scyld Computing Corporation
        !            17:        914 Bay Ridge Road, Suite 220
        !            18:        Annapolis MD 21403
        !            19: 
        !            20:        Support information and updates available at
        !            21:                http://www.scyld.com/network/yellowfin.html
        !            22:        The information and support mailing lists are based at
        !            23:                http://www.scyld.com/mailman/listinfo/
1.1       root       24: */
                     25: 
1.1.1.3 ! root       26: /* These identify the driver base version and may not be removed. */
        !            27: static const char version1[] =
        !            28: "yellowfin.c:v1.10 7/22/2003  Written by Donald Becker <[email protected]>\n";
        !            29: static const char version2[] =
        !            30: "  http://www.scyld.com/network/yellowfin.html\n";
        !            31: 
        !            32: /* The user-configurable values.
        !            33:    These may be modified when a driver module is loaded.*/
1.1       root       34: 
1.1.1.3 ! root       35: /* Message enable level: 0..31 = no..all messages.  See NETIF_MSG docs. */
        !            36: static int debug = 2;
1.1       root       37: 
1.1.1.3 ! root       38: /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
1.1       root       39: static int max_interrupt_work = 20;
1.1.1.3 ! root       40: 
        !            41: /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
        !            42:    Typical is a 64 element hash table based on the Ethernet CRC.  */
        !            43: static int multicast_filter_limit = 64;
        !            44: 
1.1       root       45: #ifdef YF_PROTOTYPE                    /* Support for prototype hardware errata. */
                     46: /* System-wide count of bogus-rx frames. */
                     47: static int bogus_rx = 0;
                     48: static int dma_ctrl = 0x004A0263;                      /* Constrained by errata */
                     49: static int fifo_cfg = 0x0020;                          /* Bypass external Tx FIFO. */
                     50: #elif YF_NEW                                   /* A future perfect board :->.  */
                     51: static int dma_ctrl = 0x00CAC277;                      /* Override when loading module! */
                     52: static int fifo_cfg = 0x0028;
                     53: #else
                     54: static int dma_ctrl = 0x004A0263;                      /* Constrained by errata */
                     55: static int fifo_cfg = 0x0020;                          /* Bypass external Tx FIFO. */
                     56: #endif
                     57: 
                     58: /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
                     59:    Setting to > 1518 effectively disables this feature. */
1.1.1.3 ! root       60: static int rx_copybreak = 0;
        !            61: 
        !            62: /* Used to pass the media type, etc.
        !            63:    No media types are currently defined.  These options exist only for
        !            64:    compatibility with other drivers.
        !            65: */
        !            66: #define MAX_UNITS 8            /* More are supported, limit only on options */
        !            67: static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
        !            68: static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
        !            69: 
        !            70: /* Do ugly workaround for GX server chipset errata. */
        !            71: static int gx_fix = 0;
        !            72: 
        !            73: /* Operational parameters that are set at compile time. */
1.1       root       74: 
                     75: /* Keep the ring sizes a power of two for efficiency.
                     76:    Making the Tx ring too large decreases the effectiveness of channel
1.1.1.3 ! root       77:    bonding and packet priority, confuses the system network buffer limits,
        !            78:    and wastes memory.
        !            79:    Too-large receive rings waste memory and confound network buffer limits.
        !            80: */
1.1       root       81: #define TX_RING_SIZE   16
1.1.1.3 ! root       82: #define TX_QUEUE_SIZE  12              /* Must be > 4 && <= TX_RING_SIZE */
        !            83: #define RX_RING_SIZE   64
1.1       root       84: 
                     85: /* Operational parameters that usually are not changed. */
                     86: /* Time in jiffies before concluding the transmitter is hung. */
1.1.1.3 ! root       87: #define TX_TIMEOUT  (6*HZ)
        !            88: 
        !            89: /* Allocation size of Rx buffers with normal sized Ethernet frames.
        !            90:    Do not change this value without good reason.  This is not a limit,
        !            91:    but a way to keep a consistent allocation size among drivers.
        !            92:  */
        !            93: #define PKT_BUF_SZ             1536
        !            94: 
        !            95: #ifndef __KERNEL__
        !            96: #define __KERNEL__
        !            97: #endif
        !            98: #if !defined(__OPTIMIZE__)
        !            99: #warning  You must compile this file with the correct options!
        !           100: #warning  See the last lines of the source file.
        !           101: #error You must compile this driver with "-O".
        !           102: #endif
1.1       root      103: 
                    104: #include <linux/config.h>
1.1.1.3 ! root      105: #if defined(CONFIG_SMP) && ! defined(__SMP__)
        !           106: #define __SMP__
1.1       root      107: #endif
1.1.1.3 ! root      108: #if defined(MODULE) && defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
        !           109: #define MODVERSIONS
        !           110: #endif
        !           111: 
1.1       root      112: #include <linux/version.h>
1.1.1.3 ! root      113: #if defined(MODVERSIONS)
        !           114: #include <linux/modversions.h>
1.1       root      115: #endif
1.1.1.3 ! root      116: #include <linux/module.h>
1.1       root      117: 
                    118: #include <linux/kernel.h>
                    119: #include <linux/string.h>
                    120: #include <linux/timer.h>
                    121: #include <linux/errno.h>
                    122: #include <linux/ioport.h>
1.1.1.3 ! root      123: #if LINUX_VERSION_CODE >= 0x20400
        !           124: #include <linux/slab.h>
        !           125: #else
1.1       root      126: #include <linux/malloc.h>
1.1.1.3 ! root      127: #endif
1.1       root      128: #include <linux/interrupt.h>
                    129: #include <linux/pci.h>
                    130: #include <linux/netdevice.h>
                    131: #include <linux/etherdevice.h>
                    132: #include <linux/skbuff.h>
1.1.1.3 ! root      133: #include <asm/processor.h>             /* Processor type for cache alignment. */
        !           134: #include <asm/unaligned.h>
        !           135: #include <asm/bitops.h>
        !           136: #include <asm/io.h>
1.1       root      137: 
1.1.1.3 ! root      138: #ifdef INLINE_PCISCAN
        !           139: #include "k_compat.h"
1.1       root      140: #else
1.1.1.3 ! root      141: #include "pci-scan.h"
        !           142: #include "kern_compat.h"
1.1       root      143: #endif
                    144: 
1.1.1.3 ! root      145: /* Condensed operations for readability. */
        !           146: #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
        !           147: #define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
1.1       root      148: 
1.1.1.3 ! root      149: #if (LINUX_VERSION_CODE >= 0x20100)  &&  defined(MODULE)
        !           150: char kernel_version[] = UTS_RELEASE;
1.1       root      151: #endif
                    152: 
1.1.1.3 ! root      153: MODULE_AUTHOR("Donald Becker <[email protected]>");
        !           154: MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
        !           155: MODULE_LICENSE("GPL");
        !           156: MODULE_PARM(debug, "i");
        !           157: MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
        !           158: MODULE_PARM(rx_copybreak, "i");
        !           159: MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
        !           160: MODULE_PARM(multicast_filter_limit, "i");
        !           161: MODULE_PARM(max_interrupt_work, "i");
        !           162: MODULE_PARM(gx_fix, "i");
        !           163: MODULE_PARM_DESC(debug, "Driver message level enable (0-31)");
        !           164: MODULE_PARM_DESC(options, "Force transceiver type or fixed speed+duplex");
        !           165: MODULE_PARM_DESC(rx_copybreak,
        !           166:                                 "Breakpoint in bytes for copy-only-tiny-frames");
        !           167: MODULE_PARM_DESC(full_duplex,
        !           168:                                 "Non-zero to force full duplex, non-negotiated link "
        !           169:                                 "(deprecated).");
        !           170: MODULE_PARM_DESC(max_interrupt_work,
        !           171:                                 "Driver maximum events handled per interrupt");
        !           172: MODULE_PARM_DESC(multicast_filter_limit,
        !           173:                                 "Multicast addresses before switching to Rx-all-multicast");
        !           174: MODULE_PARM_DESC(gx_fix, "Set to work around old GX chipset errata");
1.1       root      175: 
                    176: /*
                    177:                                Theory of Operation
                    178: 
                    179: I. Board Compatibility
                    180: 
                    181: This device driver is designed for the Packet Engines "Yellowfin" Gigabit
                    182: Ethernet adapter.  The only PCA currently supported is the G-NIC 64-bit
                    183: PCI card.
                    184: 
                    185: II. Board-specific settings
                    186: 
                    187: PCI bus devices are configured by the system at boot time, so no jumpers
                    188: need to be set on the board.  The system BIOS preferably should assign the
                    189: PCI INTA signal to an otherwise unused system IRQ line.
                    190: Note: Kernel versions earlier than 1.3.73 do not support shared PCI
                    191: interrupt lines.
                    192: 
                    193: III. Driver operation
                    194: 
                    195: IIIa. Ring buffers
                    196: 
                    197: The Yellowfin uses the Descriptor Based DMA Architecture specified by Apple.
                    198: This is a descriptor list scheme similar to that used by the EEPro100 and
                    199: Tulip.  This driver uses two statically allocated fixed-size descriptor lists
                    200: formed into rings by a branch from the final descriptor to the beginning of
                    201: the list.  The ring sizes are set at compile time by RX/TX_RING_SIZE.
                    202: 
                    203: The driver allocates full frame size skbuffs for the Rx ring buffers at
                    204: open() time and passes the skb->data field to the Yellowfin as receive data
                    205: buffers.  When an incoming frame is less than RX_COPYBREAK bytes long,
                    206: a fresh skbuff is allocated and the frame is copied to the new skbuff.
                    207: When the incoming frame is larger, the skbuff is passed directly up the
                    208: protocol stack and replaced by a newly allocated skbuff.
                    209: 
                    210: The RX_COPYBREAK value is chosen to trade-off the memory wasted by
                    211: using a full-sized skbuff for small frames vs. the copying costs of larger
                    212: frames.  For small frames the copying cost is negligible (esp. considering
                    213: that we are pre-loading the cache with immediately useful header
                    214: information).  For large frames the copying cost is non-trivial, and the
                    215: larger copy might flush the cache of useful data.
                    216: 
                    217: IIIC. Synchronization
                    218: 
                    219: The driver runs as two independent, single-threaded flows of control.  One
                    220: is the send-packet routine, which enforces single-threaded use by the
                    221: dev->tbusy flag.  The other thread is the interrupt handler, which is single
                    222: threaded by the hardware and other software.
                    223: 
                    224: The send packet thread has partial control over the Tx ring and 'dev->tbusy'
                    225: flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
                    226: queue slot is empty, it clears the tbusy flag when finished otherwise it sets
                    227: the 'yp->tx_full' flag.
                    228: 
                    229: The interrupt handler has exclusive control over the Rx ring and records stats
                    230: from the Tx ring.  After reaping the stats, it marks the Tx queue entry as
                    231: empty by incrementing the dirty_tx mark. Iff the 'yp->tx_full' flag is set, it
                    232: clears both the tx_full and tbusy flags.
                    233: 
                    234: IV. Notes
                    235: 
                    236: Thanks to Kim Stearns of Packet Engines for providing a pair of G-NIC boards.
1.1.1.3 ! root      237: Thanks to Bruce Faust of Digitalscape for providing both their SYM53C885 board
        !           238: and an AlphaStation to verifty the Alpha port!
1.1       root      239: 
                    240: IVb. References
                    241: 
                    242: Yellowfin Engineering Design Specification, 4/23/97 Preliminary/Confidential
1.1.1.3 ! root      243: Symbios SYM53C885 PCI-SCSI/Fast Ethernet Multifunction Controller Preliminary
        !           244:    Data Manual v3.0
        !           245: http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
1.1       root      246: http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
                    247: 
                    248: IVc. Errata
                    249: 
1.1.1.3 ! root      250: See Packet Engines confidential appendix (prototype chips only).
1.1       root      251: */
1.1.1.3 ! root      252: 
1.1       root      253: 
                    254: 
1.1.1.3 ! root      255: static void *yellowfin_probe1(struct pci_dev *pdev, void *init_dev,
        !           256:                                                          long ioaddr, int irq, int chip_idx, int fnd_cnt);
        !           257: enum capability_flags {
        !           258:        HasMII=1, FullTxStatus=2, IsGigabit=4, HasMulticastBug=8, FullRxStatus=16,
        !           259:        HasMACAddrBug=32,                       /* Only on early revs.  */
        !           260: };
        !           261: /* The PCI I/O space extent. */
        !           262: #define YELLOWFIN_SIZE 0x100
        !           263: #ifdef USE_IO_OPS
        !           264: #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO  | PCI_ADDR0)
        !           265: #else
        !           266: #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
1.1       root      267: #endif
                    268: 
1.1.1.3 ! root      269: static struct pci_id_info pci_id_tbl[] = {
        !           270:        {"Yellowfin G-NIC Gigabit Ethernet", { 0x07021000, 0xffffffff},
        !           271:         PCI_IOTYPE, YELLOWFIN_SIZE,
        !           272:         FullTxStatus | IsGigabit | HasMulticastBug | HasMACAddrBug},
        !           273:        {"Symbios SYM83C885", { 0x07011000, 0xffffffff},
        !           274:         PCI_IOTYPE, YELLOWFIN_SIZE, HasMII },
        !           275:        {0,},
        !           276: };
1.1       root      277: 
1.1.1.3 ! root      278: struct drv_id_info yellowfin_drv_id = {
        !           279:        "yellowfin", PCI_HOTSWAP, PCI_CLASS_NETWORK_ETHERNET<<8, pci_id_tbl,
        !           280:        yellowfin_probe1, };
1.1       root      281: 
                    282: /* Offsets to the Yellowfin registers.  Various sizes and alignments. */
                    283: enum yellowfin_offsets {
                    284:        TxCtrl=0x00, TxStatus=0x04, TxPtr=0x0C,
                    285:        TxIntrSel=0x10, TxBranchSel=0x14, TxWaitSel=0x18,
                    286:        RxCtrl=0x40, RxStatus=0x44, RxPtr=0x4C,
                    287:        RxIntrSel=0x50, RxBranchSel=0x54, RxWaitSel=0x58,
                    288:        EventStatus=0x80, IntrEnb=0x82, IntrClear=0x84, IntrStatus=0x86,
1.1.1.3 ! root      289:        ChipRev=0x8C, DMACtrl=0x90, TxThreshold=0x94,
        !           290:        Cnfg=0xA0, FrameGap0=0xA2, FrameGap1=0xA4,
        !           291:        MII_Cmd=0xA6, MII_Addr=0xA8, MII_Wr_Data=0xAA, MII_Rd_Data=0xAC,
        !           292:        MII_Status=0xAE,
        !           293:        RxDepth=0xB8, FlowCtrl=0xBC,
1.1       root      294:        AddrMode=0xD0, StnAddr=0xD2, HashTbl=0xD8, FIFOcfg=0xF8,
1.1.1.3 ! root      295:        EEStatus=0xF0, EECtrl=0xF1, EEAddr=0xF2, EERead=0xF3, EEWrite=0xF4,
        !           296:        EEFeature=0xF5,
1.1       root      297: };
                    298: 
1.1.1.3 ! root      299: /* The Yellowfin Rx and Tx buffer descriptors.
        !           300:    Elements are written as 32 bit for endian portability. */
1.1       root      301: struct yellowfin_desc {
1.1.1.3 ! root      302:        u32 dbdma_cmd;
1.1       root      303:        u32 addr;
                    304:        u32 branch_addr;
1.1.1.3 ! root      305:        u32 result_status;
1.1       root      306: };
                    307: 
                    308: struct tx_status_words {
1.1.1.3 ! root      309: #if defined(__powerpc__)
        !           310:        u16 tx_errs;
        !           311:        u16 tx_cnt;
        !           312:        u16 paused;
        !           313:        u16 total_tx_cnt;
        !           314: #else  /* Little endian chips. */
1.1       root      315:        u16 tx_cnt;
                    316:        u16 tx_errs;
                    317:        u16 total_tx_cnt;
                    318:        u16 paused;
1.1.1.3 ! root      319: #endif
1.1       root      320: };
                    321: 
                    322: /* Bits in yellowfin_desc.cmd */
                    323: enum desc_cmd_bits {
1.1.1.3 ! root      324:        CMD_TX_PKT=0x10000000, CMD_RX_BUF=0x20000000, CMD_TXSTATUS=0x30000000,
        !           325:        CMD_NOP=0x60000000, CMD_STOP=0x70000000,
        !           326:        BRANCH_ALWAYS=0x0C0000, INTR_ALWAYS=0x300000, WAIT_ALWAYS=0x030000,
        !           327:        BRANCH_IFTRUE=0x040000,
1.1       root      328: };
                    329: 
                    330: /* Bits in yellowfin_desc.status */
                    331: enum desc_status_bits { RX_EOP=0x0040, };
                    332: 
                    333: /* Bits in the interrupt status/mask registers. */
                    334: enum intr_status_bits {
                    335:        IntrRxDone=0x01, IntrRxInvalid=0x02, IntrRxPCIFault=0x04,IntrRxPCIErr=0x08,
                    336:        IntrTxDone=0x10, IntrTxInvalid=0x20, IntrTxPCIFault=0x40,IntrTxPCIErr=0x80,
                    337:        IntrEarlyRx=0x100, IntrWakeup=0x200, };
                    338: 
1.1.1.3 ! root      339: #define PRIV_ALIGN     31      /* Required alignment mask */
1.1       root      340: struct yellowfin_private {
1.1.1.3 ! root      341:        /* Descriptor rings first for alignment.
        !           342:           Tx requires a second descriptor for status. */
1.1       root      343:        struct yellowfin_desc rx_ring[RX_RING_SIZE];
                    344:        struct yellowfin_desc tx_ring[TX_RING_SIZE*2];
1.1.1.3 ! root      345:        struct net_device *next_module;
        !           346:        void *priv_addr;                                        /* Unaligned address for kfree */
1.1       root      347:        /* The addresses of receive-in-place skbuffs. */
                    348:        struct sk_buff* rx_skbuff[RX_RING_SIZE];
1.1.1.3 ! root      349:        /* The saved address of a sent-in-place packet/buffer, for later free(). */
        !           350:        struct sk_buff* tx_skbuff[TX_RING_SIZE];
        !           351:        struct tx_status_words tx_status[TX_RING_SIZE];
1.1       root      352:        struct timer_list timer;        /* Media selection timer. */
1.1.1.3 ! root      353:        struct net_device_stats stats;
        !           354:        /* Frequently used and paired value: keep adjacent for cache effect. */
        !           355:        int msg_level;
        !           356:        int chip_id, drv_flags;
        !           357:        struct pci_dev *pci_dev;
        !           358:        long in_interrupt;
        !           359:        int max_interrupt_work;
        !           360: 
        !           361:        struct yellowfin_desc *rx_head_desc;
        !           362:        unsigned int cur_rx, dirty_rx;          /* Producer/consumer ring indices */
        !           363:        unsigned int rx_buf_sz;                         /* Based on MTU+slack. */
        !           364:        int rx_copybreak;
        !           365: 
        !           366:        struct tx_status_words *tx_tail_desc;
        !           367:        unsigned int cur_tx, dirty_tx;
        !           368:        int tx_threshold;
1.1       root      369:        unsigned int tx_full:1;                         /* The Tx queue is full. */
                    370:        unsigned int full_duplex:1;                     /* Full-duplex operation requested. */
1.1.1.3 ! root      371:        unsigned int duplex_lock:1;
1.1       root      372:        unsigned int medialock:1;                       /* Do not sense media. */
1.1.1.3 ! root      373:        unsigned int default_port;                      /* Last dev->if_port value. */
        !           374:        /* MII transceiver section. */
        !           375:        int mii_cnt;                                            /* MII device addresses. */
        !           376:        u16 advertising;                                        /* NWay media advertisement */
        !           377:        unsigned char phys[2];                          /* MII device addresses. */
        !           378:        /* Rx multicast filter. */
        !           379:        u16 mc_filter[4];
        !           380:        int rx_mode;
        !           381:        int multicast_filter_limit;
1.1       root      382: };
                    383: 
1.1.1.3 ! root      384: static int read_eeprom(long ioaddr, int location);
        !           385: static int mdio_read(long ioaddr, int phy_id, int location);
        !           386: static void mdio_write(long ioaddr, int phy_id, int location, int value);
        !           387: #ifdef HAVE_PRIVATE_IOCTL
        !           388: static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
1.1       root      389: #endif
1.1.1.3 ! root      390: static int yellowfin_open(struct net_device *dev);
1.1       root      391: static void yellowfin_timer(unsigned long data);
1.1.1.3 ! root      392: static void yellowfin_tx_timeout(struct net_device *dev);
        !           393: static void yellowfin_init_ring(struct net_device *dev);
        !           394: static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev);
        !           395: static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
        !           396: static int yellowfin_rx(struct net_device *dev);
        !           397: static void yellowfin_error(struct net_device *dev, int intr_status);
        !           398: static int yellowfin_close(struct net_device *dev);
        !           399: static struct net_device_stats *yellowfin_get_stats(struct net_device *dev);
        !           400: static void set_rx_mode(struct net_device *dev);
1.1       root      401: 
                    402: 
                    403: 
1.1.1.3 ! root      404: /* A list of installed Yellowfin devices, for removing the driver module. */
        !           405: static struct net_device *root_yellowfin_dev = NULL;
1.1       root      406: 
1.1.1.3 ! root      407: #ifndef MODULE
        !           408: int yellowfin_probe(struct net_device *dev)
1.1       root      409: {
1.1.1.3 ! root      410:        if (pci_drv_register(&yellowfin_drv_id, dev) < 0)
        !           411:                return -ENODEV;
        !           412:        printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
        !           413:        return 0;
1.1       root      414: }
1.1.1.3 ! root      415: #endif
1.1       root      416: 
1.1.1.3 ! root      417: static void *yellowfin_probe1(struct pci_dev *pdev, void *init_dev,
        !           418:                                                          long ioaddr, int irq, int chip_idx, int find_cnt)
1.1       root      419: {
1.1.1.3 ! root      420:        struct net_device *dev;
        !           421:        struct yellowfin_private *np;
        !           422:        void *priv_mem;
        !           423:        int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
        !           424:        int drv_flags = pci_id_tbl[chip_idx].drv_flags;
        !           425: 
        !           426:        dev = init_etherdev(init_dev, 0);
        !           427:        if (!dev)
        !           428:                return NULL;
        !           429: 
        !           430:        printk(KERN_INFO "%s: %s type %8x at 0x%lx, ",
        !           431:                   dev->name, pci_id_tbl[chip_idx].name, (int)inl(ioaddr + ChipRev),
        !           432:                   ioaddr);
        !           433: 
        !           434:        if (drv_flags & IsGigabit)
        !           435:                for (i = 0; i < 6; i++)
        !           436:                        dev->dev_addr[i] = inb(ioaddr + StnAddr + i);
        !           437:        else {
        !           438:                int ee_offset = (read_eeprom(ioaddr, 6) == 0xff ? 0x100 : 0);
        !           439:                for (i = 0; i < 6; i++)
        !           440:                        dev->dev_addr[i] = read_eeprom(ioaddr, ee_offset + i);
        !           441:        }
1.1       root      442:        for (i = 0; i < 5; i++)
1.1.1.3 ! root      443:                        printk("%2.2x:", dev->dev_addr[i]);
        !           444:        printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
1.1       root      445: 
                    446:        /* Reset the chip. */
                    447:        outl(0x80000000, ioaddr + DMACtrl);
                    448: 
1.1.1.3 ! root      449:        /* Make certain elements e.g. descriptor lists are aligned. */
        !           450:        priv_mem = kmalloc(sizeof(*np) + PRIV_ALIGN, GFP_KERNEL);
        !           451:        /* Check for the very unlikely case of no memory. */
        !           452:        if (priv_mem == NULL)
        !           453:                return NULL;
1.1       root      454: 
                    455:        /* We do a request_region() only to register /proc/ioports info. */
1.1.1.3 ! root      456:        request_region(ioaddr, pci_id_tbl[chip_idx].io_size, dev->name);
1.1       root      457: 
                    458:        dev->base_addr = ioaddr;
                    459:        dev->irq = irq;
                    460: 
1.1.1.3 ! root      461:        dev->priv = np = (void *)(((long)priv_mem + PRIV_ALIGN) & ~PRIV_ALIGN);
        !           462:        memset(np, 0, sizeof(*np));
        !           463:        np->priv_addr = priv_mem;
1.1       root      464: 
1.1.1.3 ! root      465:        np->next_module = root_yellowfin_dev;
1.1       root      466:        root_yellowfin_dev = dev;
                    467: 
1.1.1.3 ! root      468:        np->pci_dev = pdev;
        !           469:        np->chip_id = chip_idx;
        !           470:        np->drv_flags = drv_flags;
        !           471:        np->msg_level = (1 << debug) - 1;
        !           472:        np->rx_copybreak = rx_copybreak;
        !           473:        np->max_interrupt_work = max_interrupt_work;
        !           474:        np->multicast_filter_limit = multicast_filter_limit;
1.1       root      475: 
1.1.1.3 ! root      476:        if (dev->mem_start)
        !           477:                option = dev->mem_start;
1.1       root      478: 
                    479:        /* The lower four bits are the media type. */
1.1.1.3 ! root      480:        if (option > 0) {
        !           481:                if (option & 0x220)
        !           482:                        np->full_duplex = 1;
        !           483:                np->default_port = option & 15;
        !           484:                if (np->default_port)
        !           485:                        np->medialock = 1;
1.1       root      486:        }
1.1.1.3 ! root      487:        if (find_cnt < MAX_UNITS  &&  full_duplex[find_cnt] > 0)
        !           488:                np->full_duplex = 1;
        !           489: 
        !           490:        if (np->full_duplex)
        !           491:                np->duplex_lock = 1;
1.1       root      492: 
                    493:        /* The Yellowfin-specific entries in the device structure. */
                    494:        dev->open = &yellowfin_open;
                    495:        dev->hard_start_xmit = &yellowfin_start_xmit;
                    496:        dev->stop = &yellowfin_close;
                    497:        dev->get_stats = &yellowfin_get_stats;
                    498:        dev->set_multicast_list = &set_rx_mode;
1.1.1.3 ! root      499:        dev->do_ioctl = &mii_ioctl;
1.1       root      500: 
1.1.1.3 ! root      501:        if (np->drv_flags & HasMII) {
        !           502:                int phy, phy_idx = 0;
        !           503:                for (phy = 0; phy < 32 && phy_idx < 4; phy++) {
        !           504:                        int mii_status = mdio_read(ioaddr, phy, 1);
        !           505:                        if (mii_status != 0xffff  &&  mii_status != 0x0000) {
        !           506:                                np->phys[phy_idx++] = phy;
        !           507:                                np->advertising = mdio_read(ioaddr, phy, 4);
        !           508:                                printk(KERN_INFO "%s: MII PHY found at address %d, status "
        !           509:                                           "0x%4.4x advertising %4.4x.\n",
        !           510:                                           dev->name, phy, mii_status, np->advertising);
        !           511:                        }
        !           512:                }
        !           513:                np->mii_cnt = phy_idx;
        !           514:        }
1.1       root      515: 
                    516:        return dev;
                    517: }
                    518: 
1.1.1.3 ! root      519: static int read_eeprom(long ioaddr, int location)
        !           520: {
        !           521:        int bogus_cnt = 10000;          /* Typical 33Mhz: 1050 ticks */
        !           522: 
        !           523:        outb(location, ioaddr + EEAddr);
        !           524:        outb(0x30 | ((location >> 8) & 7), ioaddr + EECtrl);
        !           525:        while ((inb(ioaddr + EEStatus) & 0x80)  &&  --bogus_cnt > 0)
        !           526:                ;
        !           527:        return inb(ioaddr + EERead);
        !           528: }
        !           529: 
        !           530: /* MII Managemen Data I/O accesses.
        !           531:    These routines assume the MDIO controller is idle, and do not exit until
        !           532:    the command is finished. */
        !           533: 
        !           534: static int mdio_read(long ioaddr, int phy_id, int location)
        !           535: {
        !           536:        int i;
        !           537: 
        !           538:        outw((phy_id<<8) + location, ioaddr + MII_Addr);
        !           539:        outw(1, ioaddr + MII_Cmd);
        !           540:        for (i = 10000; i >= 0; i--)
        !           541:                if ((inw(ioaddr + MII_Status) & 1) == 0)
        !           542:                        break;
        !           543:        return inw(ioaddr + MII_Rd_Data);
        !           544: }
        !           545: 
        !           546: static void mdio_write(long ioaddr, int phy_id, int location, int value)
        !           547: {
        !           548:        int i;
        !           549: 
        !           550:        outw((phy_id<<8) + location, ioaddr + MII_Addr);
        !           551:        outw(value, ioaddr + MII_Wr_Data);
        !           552: 
        !           553:        /* Wait for the command to finish. */
        !           554:        for (i = 10000; i >= 0; i--)
        !           555:                if ((inw(ioaddr + MII_Status) & 1) == 0)
        !           556:                        break;
        !           557:        return;
        !           558: }
        !           559: 
1.1       root      560: 
1.1.1.3 ! root      561: static int yellowfin_open(struct net_device *dev)
1.1       root      562: {
                    563:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
1.1.1.3 ! root      564:        long ioaddr = dev->base_addr;
        !           565:        int i;
1.1       root      566: 
                    567:        /* Reset the chip. */
                    568:        outl(0x80000000, ioaddr + DMACtrl);
                    569: 
1.1.1.3 ! root      570:        MOD_INC_USE_COUNT;
        !           571: 
        !           572:        if (request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ, dev->name,
        !           573:                                        dev)) {
        !           574:                MOD_DEC_USE_COUNT;
1.1       root      575:                return -EAGAIN;
                    576:        }
                    577: 
1.1.1.3 ! root      578:        if (yp->msg_level & NETIF_MSG_IFUP)
        !           579:                printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n",
        !           580:                           dev->name, dev->irq);
1.1       root      581: 
                    582:        yellowfin_init_ring(dev);
                    583: 
                    584:        outl(virt_to_bus(yp->rx_ring), ioaddr + RxPtr);
                    585:        outl(virt_to_bus(yp->tx_ring), ioaddr + TxPtr);
                    586: 
1.1.1.3 ! root      587:        for (i = 0; i < 6; i++)
        !           588:                outb(dev->dev_addr[i], ioaddr + StnAddr + i);
        !           589: 
1.1       root      590:        /* Set up various condition 'select' registers.
                    591:           There are no options here. */
                    592:        outl(0x00800080, ioaddr + TxIntrSel);   /* Interrupt on Tx abort */
                    593:        outl(0x00800080, ioaddr + TxBranchSel); /* Branch on Tx abort */
                    594:        outl(0x00400040, ioaddr + TxWaitSel);   /* Wait on Tx status */
                    595:        outl(0x00400040, ioaddr + RxIntrSel);   /* Interrupt on Rx done */
                    596:        outl(0x00400040, ioaddr + RxBranchSel); /* Branch on Rx error */
                    597:        outl(0x00400040, ioaddr + RxWaitSel);   /* Wait on Rx done */
                    598: 
                    599:        /* Initialize other registers: with so many this eventually this will
                    600:           converted to an offset/value list. */
                    601:        outl(dma_ctrl, ioaddr + DMACtrl);
                    602:        outw(fifo_cfg, ioaddr + FIFOcfg);
                    603:        /* Enable automatic generation of flow control frames, period 0xffff. */
                    604:        outl(0x0030FFFF, ioaddr + FlowCtrl);
                    605: 
1.1.1.3 ! root      606:        yp->tx_threshold = 32;
        !           607:        outl(yp->tx_threshold, ioaddr + TxThreshold);
        !           608: 
1.1       root      609:        if (dev->if_port == 0)
                    610:                dev->if_port = yp->default_port;
                    611: 
                    612:        yp->in_interrupt = 0;
                    613: 
                    614:        /* Setting the Rx mode will start the Rx process. */
1.1.1.3 ! root      615:        if (yp->drv_flags & IsGigabit) {
        !           616:                /* We are always in full-duplex mode with gigabit! */
        !           617:                yp->full_duplex = 1;
        !           618:                outw(0x01CF, ioaddr + Cnfg);
        !           619:        } else {
        !           620:                outw(0x0018, ioaddr + FrameGap0); /* 0060/4060 for non-MII 10baseT */
        !           621:                outw(0x1018, ioaddr + FrameGap1);
        !           622:                outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
        !           623:        }
        !           624:        yp->rx_mode = 0;
1.1       root      625:        set_rx_mode(dev);
1.1.1.3 ! root      626:        netif_start_tx_queue(dev);
1.1       root      627: 
                    628:        /* Enable interrupts by setting the interrupt mask. */
                    629:        outw(0x81ff, ioaddr + IntrEnb);                 /* See enum intr_status_bits */
                    630:        outw(0x0000, ioaddr + EventStatus);             /* Clear non-interrupting events */
                    631:        outl(0x80008000, ioaddr + RxCtrl);              /* Start Rx and Tx channels. */
                    632:        outl(0x80008000, ioaddr + TxCtrl);
                    633: 
1.1.1.3 ! root      634:        if (yp->msg_level & NETIF_MSG_IFUP)
        !           635:                printk(KERN_DEBUG "%s: Done yellowfin_open().\n",
1.1       root      636:                           dev->name);
1.1.1.3 ! root      637: 
1.1       root      638:        /* Set the timer to check for link beat. */
                    639:        init_timer(&yp->timer);
1.1.1.3 ! root      640:        yp->timer.expires = jiffies + 3*HZ;
1.1       root      641:        yp->timer.data = (unsigned long)dev;
                    642:        yp->timer.function = &yellowfin_timer;                          /* timer handler */
                    643:        add_timer(&yp->timer);
                    644: 
                    645:        return 0;
                    646: }
                    647: 
                    648: static void yellowfin_timer(unsigned long data)
                    649: {
1.1.1.3 ! root      650:        struct net_device *dev = (struct net_device *)data;
1.1       root      651:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
1.1.1.3 ! root      652:        long ioaddr = dev->base_addr;
        !           653:        int next_tick = 60*HZ;
        !           654: 
        !           655:        if (yp->msg_level & NETIF_MSG_TIMER)
        !           656:                printk(KERN_DEBUG "%s: Yellowfin timer tick, status %8.8x.\n",
        !           657:                           dev->name, inw(ioaddr + IntrStatus));
        !           658: 
        !           659:        if (jiffies - dev->trans_start > TX_TIMEOUT
        !           660:                && yp->cur_tx - yp->dirty_tx > 1
        !           661:                && netif_queue_paused(dev))
        !           662:                yellowfin_tx_timeout(dev);
1.1       root      663: 
1.1.1.3 ! root      664:        if (yp->mii_cnt) {
        !           665:                int mii_reg1 = mdio_read(ioaddr, yp->phys[0], 1);
        !           666:                int mii_reg5 = mdio_read(ioaddr, yp->phys[0], 5);
        !           667:                int negotiated = mii_reg5 & yp->advertising;
        !           668:                if (yp->msg_level & NETIF_MSG_TIMER)
        !           669:                        printk(KERN_DEBUG "%s: MII #%d status register is %4.4x, "
        !           670:                                   "link partner capability %4.4x.\n",
        !           671:                                   dev->name, yp->phys[0], mii_reg1, mii_reg5);
        !           672: 
        !           673:                if ( ! yp->duplex_lock &&
        !           674:                         ((negotiated & 0x0300) == 0x0100
        !           675:                          || (negotiated & 0x00C0) == 0x0040)) {
        !           676:                        yp->full_duplex = 1;
        !           677:                }
        !           678:                outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
        !           679: 
        !           680:                if (mii_reg1 & 0x0004)
        !           681:                        next_tick = 60*HZ;
        !           682:                else
        !           683:                        next_tick = 3*HZ;
1.1       root      684:        }
1.1.1.3 ! root      685: 
        !           686:        yp->timer.expires = jiffies + next_tick;
        !           687:        add_timer(&yp->timer);
1.1       root      688: }
                    689: 
1.1.1.3 ! root      690: static void yellowfin_tx_timeout(struct net_device *dev)
1.1       root      691: {
                    692:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
1.1.1.3 ! root      693:        long ioaddr = dev->base_addr;
1.1       root      694: 
1.1.1.3 ! root      695:        printk(KERN_WARNING "%s: Yellowfin transmit timed out at %d/%d Tx "
        !           696:                   "status %4.4x, Rx status %4.4x, resetting...\n",
        !           697:                   dev->name, yp->cur_tx, yp->dirty_tx,
        !           698:                   (int)inl(ioaddr + TxStatus), (int)inl(ioaddr + RxStatus));
1.1       root      699: 
1.1.1.3 ! root      700:        /* Note: these should be KERN_DEBUG. */
        !           701:        if (yp->msg_level & NETIF_MSG_TX_ERR) {
1.1       root      702:                int i;
1.1.1.3 ! root      703:                printk(KERN_DEBUG "  Rx ring %p: ", yp->rx_ring);
1.1       root      704:                for (i = 0; i < RX_RING_SIZE; i++)
1.1.1.3 ! root      705:                        printk(" %8.8x", yp->rx_ring[i].result_status);
        !           706:                printk("\n"KERN_DEBUG"  Tx ring %p: ", yp->tx_ring);
1.1       root      707:                for (i = 0; i < TX_RING_SIZE; i++)
1.1.1.3 ! root      708:                        printk(" %4.4x /%8.8x", yp->tx_status[i].tx_errs,
        !           709:                                   yp->tx_ring[i].result_status);
1.1       root      710:                printk("\n");
                    711:        }
                    712: 
1.1.1.3 ! root      713:        /* If the hardware is found to hang regularly, we will update the code
        !           714:           to reinitialize the chip here. */
        !           715:        dev->if_port = 0;
1.1       root      716: 
1.1.1.3 ! root      717:        /* Wake the potentially-idle transmit channel. */
        !           718:        outl(0x10001000, dev->base_addr + TxCtrl);
        !           719:        if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE)
        !           720:                netif_unpause_tx_queue(dev);
        !           721: 
        !           722:        dev->trans_start = jiffies;
        !           723:        yp->stats.tx_errors++;
        !           724:        return;
        !           725: }
1.1       root      726: 
                    727: /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
1.1.1.3 ! root      728: static void yellowfin_init_ring(struct net_device *dev)
1.1       root      729: {
                    730:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
                    731:        int i;
                    732: 
                    733:        yp->tx_full = 0;
                    734:        yp->cur_rx = yp->cur_tx = 0;
1.1.1.3 ! root      735:        yp->dirty_tx = 0;
1.1       root      736: 
1.1.1.3 ! root      737:        yp->rx_buf_sz = dev->mtu + 18 + 15;
        !           738:        /* Match other driver's allocation size when possible. */
        !           739:        if (yp->rx_buf_sz < PKT_BUF_SZ)
        !           740:                yp->rx_buf_sz = PKT_BUF_SZ;
        !           741:        yp->rx_head_desc = &yp->rx_ring[0];
1.1       root      742: 
1.1.1.3 ! root      743:        for (i = 0; i < RX_RING_SIZE; i++) {
        !           744:                yp->rx_ring[i].dbdma_cmd =
        !           745:                        cpu_to_le32(CMD_RX_BUF | INTR_ALWAYS | yp->rx_buf_sz);
        !           746:                yp->rx_ring[i].branch_addr = virt_to_le32desc(&yp->rx_ring[i+1]);
        !           747:        }
        !           748:        /* Mark the last entry as wrapping the ring. */
        !           749:        yp->rx_ring[i-1].branch_addr = virt_to_le32desc(&yp->rx_ring[0]);
1.1       root      750: 
1.1.1.3 ! root      751:        for (i = 0; i < RX_RING_SIZE; i++) {
        !           752:                struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz);
1.1       root      753:                yp->rx_skbuff[i] = skb;
                    754:                if (skb == NULL)
1.1.1.3 ! root      755:                        break;
1.1       root      756:                skb->dev = dev;                 /* Mark as being used by this device. */
1.1.1.3 ! root      757:                skb_reserve(skb, 2);    /* 16 byte align the IP header. */
        !           758:                yp->rx_ring[i].addr = virt_to_le32desc(skb->tail);
1.1       root      759:        }
1.1.1.3 ! root      760:        yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP);
        !           761:        yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
1.1       root      762: 
1.1.1.3 ! root      763: #define NO_TXSTATS
1.1       root      764: #ifdef NO_TXSTATS
                    765:        /* In this mode the Tx ring needs only a single descriptor. */
                    766:        for (i = 0; i < TX_RING_SIZE; i++) {
                    767:                yp->tx_skbuff[i] = 0;
1.1.1.3 ! root      768:                yp->tx_ring[i].dbdma_cmd = cpu_to_le32(CMD_STOP);
        !           769:                yp->tx_ring[i].branch_addr = virt_to_le32desc(&yp->tx_ring[i+1]);
1.1       root      770:        }
1.1.1.3 ! root      771:        /* Wrap ring */
        !           772:        yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS);
        !           773:        yp->tx_ring[i].branch_addr = virt_to_le32desc(&yp->tx_ring[0]);
1.1       root      774: #else
                    775:        /* Tx ring needs a pair of descriptors, the second for the status. */
                    776:        for (i = 0; i < TX_RING_SIZE*2; i++) {
                    777:                yp->tx_skbuff[i/2] = 0;
1.1.1.3 ! root      778:                /* Branch on Tx error. */
        !           779:                yp->tx_ring[i].dbdma_cmd = cpu_to_le32(CMD_STOP);
        !           780:                yp->tx_ring[i].branch_addr = virt_to_le32desc(&yp->tx_ring[i+1]);
1.1       root      781:                i++;
1.1.1.3 ! root      782:                if (yp->flags & FullTxStatus) {
        !           783:                        yp->tx_ring[i].dbdma_cmd =
        !           784:                                cpu_to_le32(CMD_TXSTATUS | sizeof(yp->tx_status[i]));
        !           785:                        yp->tx_ring[i].request_cnt = sizeof(yp->tx_status[i]);
        !           786:                        yp->tx_ring[i].addr = virt_to_le32desc(&yp->tx_status[i/2]);
        !           787:                } else {                                /* Symbios chips write only tx_errs word. */
        !           788:                        yp->tx_ring[i].dbdma_cmd =
        !           789:                                cpu_to_le32(CMD_TXSTATUS | INTR_ALWAYS | 2);
        !           790:                        yp->tx_ring[i].request_cnt = 2;
        !           791:                        yp->tx_ring[i].addr = virt_to_le32desc(&yp->tx_status[i/2].tx_errs);
        !           792:                }
        !           793:                yp->tx_ring[i].branch_addr = virt_to_le32desc(&yp->tx_ring[i+1]);
1.1       root      794:        }
                    795:        /* Wrap ring */
1.1.1.3 ! root      796:        yp->tx_ring[--i].dbdma_cmd |= cpu_to_le32(BRANCH_ALWAYS | INTR_ALWAYS);
        !           797:        yp->tx_ring[i].branch_addr = virt_to_le32desc(&yp->tx_ring[0]);
1.1       root      798: #endif
1.1.1.3 ! root      799:        yp->tx_tail_desc = &yp->tx_status[0];
        !           800:        return;
1.1       root      801: }
                    802: 
1.1.1.3 ! root      803: static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
1.1       root      804: {
                    805:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
                    806:        unsigned entry;
                    807: 
1.1.1.3 ! root      808: #if LINUX_VERSION_CODE < 0x20323
1.1       root      809:        /* Block a timer-based transmit from overlapping.  This could better be
                    810:           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
1.1.1.3 ! root      811:        if (netif_pause_tx_queue(dev) != 0) {
        !           812:                /* This watchdog code is redundant with the media monitor timer. */
        !           813:                if (jiffies - dev->trans_start > TX_TIMEOUT)
        !           814:                        yellowfin_tx_timeout(dev);
1.1       root      815:                return 1;
                    816:        }
1.1.1.3 ! root      817: #endif
1.1       root      818: 
1.1.1.3 ! root      819:        /* Note: Ordering is important here, set the field with the
        !           820:           "ownership" bit last, and only then increment cur_tx. */
1.1       root      821: 
                    822:        /* Calculate the next Tx descriptor entry. */
                    823:        entry = yp->cur_tx % TX_RING_SIZE;
                    824: 
                    825:        yp->tx_skbuff[entry] = skb;
                    826: 
1.1.1.3 ! root      827:        if (gx_fix) {           /* Note: only works for paddable protocols e.g. IP. */
        !           828:                int cacheline_end = (virt_to_bus(skb->data) + skb->len) % 32;
        !           829:                /* Fix GX chipset errata. */
        !           830:                if (cacheline_end > 24  || cacheline_end == 0)
        !           831:                        skb->len += 32 - cacheline_end + 1;
        !           832:        }
1.1       root      833: #ifdef NO_TXSTATS
1.1.1.3 ! root      834:        yp->tx_ring[entry].addr = virt_to_le32desc(skb->data);
        !           835:        yp->tx_ring[entry].result_status = 0;
1.1       root      836:        if (entry >= TX_RING_SIZE-1) {
1.1.1.3 ! root      837:                /* New stop command. */
        !           838:                yp->tx_ring[0].dbdma_cmd = cpu_to_le32(CMD_STOP);
        !           839:                yp->tx_ring[TX_RING_SIZE-1].dbdma_cmd =
        !           840:                        cpu_to_le32(CMD_TX_PKT|BRANCH_ALWAYS | skb->len);
1.1       root      841:        } else {
1.1.1.3 ! root      842:                yp->tx_ring[entry+1].dbdma_cmd = cpu_to_le32(CMD_STOP);
        !           843:                yp->tx_ring[entry].dbdma_cmd =
        !           844:                        cpu_to_le32(CMD_TX_PKT | BRANCH_IFTRUE | skb->len);
1.1       root      845:        }
                    846:        yp->cur_tx++;
                    847: #else
                    848:        yp->tx_ring[entry<<1].request_cnt = skb->len;
1.1.1.3 ! root      849:        yp->tx_ring[entry<<1].addr = virt_to_le32desc(skb->data);
1.1       root      850:        /* The input_last (status-write) command is constant, but we must rewrite
                    851:           the subsequent 'stop' command. */
                    852: 
                    853:        yp->cur_tx++;
                    854:        {
                    855:                unsigned next_entry = yp->cur_tx % TX_RING_SIZE;
1.1.1.3 ! root      856:                yp->tx_ring[next_entry<<1].dbdma_cmd = cpu_to_le32(CMD_STOP);
1.1       root      857:        }
                    858:        /* Final step -- overwrite the old 'stop' command. */
                    859: 
1.1.1.3 ! root      860:        yp->tx_ring[entry<<1].dbdma_cmd =
        !           861:                cpu_to_le32( ((entry % 6) == 0 ? CMD_TX_PKT|INTR_ALWAYS|BRANCH_IFTRUE :
        !           862:                                          CMD_TX_PKT | BRANCH_IFTRUE) | skb->len);
1.1       root      863: #endif
                    864: 
1.1.1.3 ! root      865:        /* Non-x86 Todo: explicitly flush cache lines here. */
1.1       root      866: 
                    867:        /* Wake the potentially-idle transmit channel. */
                    868:        outl(0x10001000, dev->base_addr + TxCtrl);
                    869: 
1.1.1.3 ! root      870:        if (yp->cur_tx - yp->dirty_tx >= TX_QUEUE_SIZE) {
        !           871:                netif_stop_tx_queue(dev);
1.1       root      872:                yp->tx_full = 1;
1.1.1.3 ! root      873:                if (yp->cur_tx - (volatile int)yp->dirty_tx < TX_QUEUE_SIZE) {
        !           874:                        netif_unpause_tx_queue(dev);
        !           875:                        yp->tx_full = 0;
        !           876:                } else
        !           877:                        netif_stop_tx_queue(dev);
        !           878:        } else
        !           879:                netif_unpause_tx_queue(dev);            /* Typical path */
1.1       root      880:        dev->trans_start = jiffies;
                    881: 
1.1.1.3 ! root      882:        if (yp->msg_level & NETIF_MSG_TX_QUEUED) {
        !           883:                printk(KERN_DEBUG "%s: Yellowfin transmit frame #%d queued in slot %d.\n",
1.1       root      884:                           dev->name, yp->cur_tx, entry);
                    885:        }
                    886:        return 0;
                    887: }
                    888: 
                    889: /* The interrupt handler does all of the Rx thread work and cleans up
                    890:    after the Tx thread. */
1.1.1.3 ! root      891: static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1.1       root      892: {
1.1.1.3 ! root      893:        struct net_device *dev = (struct net_device *)dev_instance;
        !           894:        struct yellowfin_private *yp;
        !           895:        long ioaddr;
        !           896:        int boguscnt = max_interrupt_work;
1.1       root      897: 
1.1.1.3 ! root      898: #ifndef final_version                  /* Can never occur. */
1.1       root      899:        if (dev == NULL) {
1.1.1.3 ! root      900:                printk (KERN_ERR "yellowfin_interrupt(): irq %d for unknown device.\n", irq);
1.1       root      901:                return;
                    902:        }
1.1.1.3 ! root      903: #endif
1.1       root      904: 
                    905:        ioaddr = dev->base_addr;
1.1.1.3 ! root      906:        yp = (struct yellowfin_private *)dev->priv;
        !           907:        if (test_and_set_bit(0, (void*)&yp->in_interrupt)) {
1.1       root      908:                printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
                    909:                return;
                    910:        }
                    911: 
                    912:        do {
                    913:                u16 intr_status = inw(ioaddr + IntrClear);
                    914: 
1.1.1.3 ! root      915:                if (yp->msg_level & NETIF_MSG_INTR)
        !           916:                        printk(KERN_DEBUG "%s: Yellowfin interrupt, status %4.4x.\n",
1.1       root      917:                                   dev->name, intr_status);
                    918: 
                    919:                if (intr_status == 0)
                    920:                        break;
                    921: 
1.1.1.3 ! root      922:                if (intr_status & (IntrRxDone | IntrEarlyRx)) {
1.1       root      923:                        yellowfin_rx(dev);
1.1.1.3 ! root      924:                        outl(0x10001000, ioaddr + RxCtrl);              /* Wake Rx engine. */
        !           925:                }
1.1       root      926: 
                    927: #ifdef NO_TXSTATS
1.1.1.3 ! root      928:                for (; yp->cur_tx - yp->dirty_tx > 0; yp->dirty_tx++) {
        !           929:                        int entry = yp->dirty_tx % TX_RING_SIZE;
        !           930:                        if (yp->tx_ring[entry].result_status == 0)
1.1       root      931:                                break;
1.1.1.3 ! root      932:                        yp->stats.tx_packets++;
        !           933: #if LINUX_VERSION_CODE > 0x20127
        !           934:                        yp->stats.tx_bytes += yp->tx_skbuff[entry]->len;
        !           935: #endif
1.1       root      936:                        /* Free the original skb. */
1.1.1.3 ! root      937:                        dev_free_skb_irq(yp->tx_skbuff[entry]);
        !           938:                        yp->tx_skbuff[entry] = 0;
1.1       root      939:                }
1.1.1.3 ! root      940:                if (yp->tx_full
        !           941:                        && yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE - 4) {
1.1       root      942:                        /* The ring is no longer full, clear tbusy. */
1.1.1.3 ! root      943:                        yp->tx_full = 0;
        !           944:                        netif_resume_tx_queue(dev);
1.1       root      945:                }
                    946: #else
                    947:                if (intr_status & IntrTxDone
1.1.1.3 ! root      948:                        || yp->tx_tail_desc->tx_errs) {
        !           949:                        unsigned dirty_tx = yp->dirty_tx;
1.1       root      950: 
1.1.1.3 ! root      951:                        for (dirty_tx = yp->dirty_tx; yp->cur_tx - dirty_tx > 0;
1.1       root      952:                                 dirty_tx++) {
                    953:                                /* Todo: optimize this. */
                    954:                                int entry = dirty_tx % TX_RING_SIZE;
1.1.1.3 ! root      955:                                u16 tx_errs = yp->tx_status[entry].tx_errs;
1.1       root      956: 
1.1.1.3 ! root      957: #ifndef final_version
        !           958:                                if (yp->msg_level & NETIF_MSG_INTR)
        !           959:                                        printk(KERN_DEBUG "%s: Tx queue %d check, Tx status "
        !           960:                                                   "%4.4x %4.4x %4.4x %4.4x.\n",
        !           961:                                                   dev->name, entry,
        !           962:                                                   yp->tx_status[entry].tx_cnt,
        !           963:                                                   yp->tx_status[entry].tx_errs,
        !           964:                                                   yp->tx_status[entry].total_tx_cnt,
        !           965:                                                   yp->tx_status[entry].paused);
        !           966: #endif
1.1       root      967:                                if (tx_errs == 0)
                    968:                                        break;                  /* It still hasn't been Txed */
1.1.1.3 ! root      969:                                if (tx_errs & 0xF810) {
1.1       root      970:                                        /* There was an major error, log it. */
                    971: #ifndef final_version
1.1.1.3 ! root      972:                                        if (yp->msg_level & NETIF_MSG_TX_ERR)
        !           973:                                                printk(KERN_DEBUG "%s: Transmit error, Tx status %4.4x.\n",
1.1       root      974:                                                           dev->name, tx_errs);
                    975: #endif
1.1.1.3 ! root      976:                                        yp->stats.tx_errors++;
        !           977:                                        if (tx_errs & 0xF800) yp->stats.tx_aborted_errors++;
        !           978:                                        if (tx_errs & 0x0800) yp->stats.tx_carrier_errors++;
        !           979:                                        if (tx_errs & 0x2000) yp->stats.tx_window_errors++;
        !           980:                                        if (tx_errs & 0x8000) yp->stats.tx_fifo_errors++;
1.1       root      981: #ifdef ETHER_STATS
1.1.1.3 ! root      982:                                        if (tx_errs & 0x1000) yp->stats.collisions16++;
1.1       root      983: #endif
                    984:                                } else {
1.1.1.3 ! root      985: #ifndef final_version
        !           986:                                        if (yp->msg_level & NETIF_MSG_TX_DONE)
        !           987:                                                printk(KERN_DEBUG "%s: Normal transmit, Tx status %4.4x.\n",
        !           988:                                                           dev->name, tx_errs);
        !           989: #endif
1.1       root      990: #ifdef ETHER_STATS
1.1.1.3 ! root      991:                                        if (tx_errs & 0x0400) yp->stats.tx_deferred++;
        !           992: #endif
        !           993: #if LINUX_VERSION_CODE > 0x20127
        !           994:                                        yp->stats.tx_bytes += yp->tx_skbuff[entry]->len;
1.1       root      995: #endif
1.1.1.3 ! root      996:                                        yp->stats.collisions += tx_errs & 15;
        !           997:                                        yp->stats.tx_packets++;
1.1       root      998:                                }
                    999:                                /* Free the original skb. */
1.1.1.3 ! root     1000:                                dev_free_skb_irq(yp->tx_skbuff[entry]);
        !          1001:                                yp->tx_skbuff[entry] = 0;
1.1       root     1002:                                /* Mark status as empty. */
1.1.1.3 ! root     1003:                                yp->tx_status[entry].tx_errs = 0;
1.1       root     1004:                        }
                   1005: 
                   1006: #ifndef final_version
1.1.1.3 ! root     1007:                        if (yp->cur_tx - dirty_tx > TX_RING_SIZE) {
        !          1008:                                printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
        !          1009:                                           dev->name, dirty_tx, yp->cur_tx, yp->tx_full);
1.1       root     1010:                                dirty_tx += TX_RING_SIZE;
                   1011:                        }
                   1012: #endif
                   1013: 
1.1.1.3 ! root     1014:                        if (yp->tx_full
        !          1015:                                && yp->cur_tx - dirty_tx < TX_QUEUE_SIZE - 2) {
1.1       root     1016:                                /* The ring is no longer full, clear tbusy. */
1.1.1.3 ! root     1017:                                yp->tx_full = 0;
        !          1018:                                netif_resume_tx_queue(dev);
1.1       root     1019:                        }
                   1020: 
1.1.1.3 ! root     1021:                        yp->dirty_tx = dirty_tx;
        !          1022:                        yp->tx_tail_desc = &yp->tx_status[dirty_tx % TX_RING_SIZE];
1.1       root     1023:                }
                   1024: #endif
                   1025: 
1.1.1.3 ! root     1026:                /* Log errors and other uncommon events. */
        !          1027:                if (intr_status & 0x2ee)        /* Abnormal error summary. */
        !          1028:                        yellowfin_error(dev, intr_status);
        !          1029: 
1.1       root     1030:                if (--boguscnt < 0) {
1.1.1.3 ! root     1031:                        printk(KERN_WARNING "%s: Too much work at interrupt, "
        !          1032:                                   "status=0x%4.4x.\n",
1.1       root     1033:                                   dev->name, intr_status);
                   1034:                        break;
                   1035:                }
                   1036:        } while (1);
                   1037: 
1.1.1.3 ! root     1038:        if (yp->msg_level & NETIF_MSG_INTR)
        !          1039:                printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
1.1       root     1040:                           dev->name, inw(ioaddr + IntrStatus));
                   1041: 
1.1.1.3 ! root     1042:        clear_bit(0, (void*)&yp->in_interrupt);
1.1       root     1043:        return;
                   1044: }
                   1045: 
                   1046: /* This routine is logically part of the interrupt handler, but separated
                   1047:    for clarity and better register allocation. */
1.1.1.3 ! root     1048: static int yellowfin_rx(struct net_device *dev)
1.1       root     1049: {
                   1050:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
1.1.1.3 ! root     1051:        int entry = yp->cur_rx % RX_RING_SIZE;
        !          1052:        int boguscnt = yp->dirty_rx + RX_RING_SIZE - yp->cur_rx;
1.1       root     1053: 
1.1.1.3 ! root     1054:        if (yp->msg_level & NETIF_MSG_RX_STATUS) {
        !          1055:                printk(KERN_DEBUG " In yellowfin_rx(), entry %d status %8.8x.\n",
        !          1056:                           entry, yp->rx_ring[entry].result_status);
        !          1057:                printk(KERN_DEBUG "   #%d desc. %8.8x %8.8x %8.8x.\n",
        !          1058:                           entry, yp->rx_ring[entry].dbdma_cmd, yp->rx_ring[entry].addr,
        !          1059:                           yp->rx_ring[entry].result_status);
1.1       root     1060:        }
                   1061: 
                   1062:        /* If EOP is set on the next entry, it's a new packet. Send it up. */
1.1.1.3 ! root     1063:        while (yp->rx_head_desc->result_status) {
        !          1064:                struct yellowfin_desc *desc = yp->rx_head_desc;
        !          1065:                u16 desc_status = le32_to_cpu(desc->result_status) >> 16;
        !          1066:                int data_size =
        !          1067:                        (le32_to_cpu(desc->dbdma_cmd) - le32_to_cpu(desc->result_status))
        !          1068:                        & 0xffff;
        !          1069:                u8 *buf_addr = le32desc_to_virt(desc->addr);
        !          1070:                s16 frame_status = get_unaligned((s16*)&(buf_addr[data_size - 2]));
        !          1071: 
        !          1072:                if (yp->msg_level & NETIF_MSG_RX_STATUS)
        !          1073:                        printk(KERN_DEBUG "  yellowfin_rx() status was %4.4x.\n",
        !          1074:                                   frame_status);
1.1       root     1075:                if (--boguscnt < 0)
                   1076:                        break;
                   1077:                if ( ! (desc_status & RX_EOP)) {
1.1.1.3 ! root     1078:                        printk(KERN_WARNING "%s: Oversized Ethernet frame spanned multiple buffers,"
1.1       root     1079:                                   " status %4.4x!\n", dev->name, desc_status);
1.1.1.3 ! root     1080:                        yp->stats.rx_length_errors++;
        !          1081:                } else if ((yp->drv_flags & IsGigabit)  &&  (frame_status & 0x0038)) {
1.1       root     1082:                        /* There was a error. */
1.1.1.3 ! root     1083:                        if (yp->msg_level & NETIF_MSG_RX_ERR)
        !          1084:                                printk(KERN_DEBUG "  yellowfin_rx() Rx error was %4.4x.\n",
        !          1085:                                           frame_status);
        !          1086:                        yp->stats.rx_errors++;
        !          1087:                        if (frame_status & 0x0060) yp->stats.rx_length_errors++;
        !          1088:                        if (frame_status & 0x0008) yp->stats.rx_frame_errors++;
        !          1089:                        if (frame_status & 0x0010) yp->stats.rx_crc_errors++;
        !          1090:                        if (frame_status < 0) yp->stats.rx_dropped++;
        !          1091:                } else if ( !(yp->drv_flags & IsGigabit)  &&
        !          1092:                                   ((buf_addr[data_size-1] & 0x85) || buf_addr[data_size-2] & 0xC0)) {
        !          1093:                        u8 status1 = buf_addr[data_size-2];
        !          1094:                        u8 status2 = buf_addr[data_size-1];
        !          1095:                        yp->stats.rx_errors++;
        !          1096:                        if (status1 & 0xC0) yp->stats.rx_length_errors++;
        !          1097:                        if (status2 & 0x03) yp->stats.rx_frame_errors++;
        !          1098:                        if (status2 & 0x04) yp->stats.rx_crc_errors++;
        !          1099:                        if (status2 & 0x80) yp->stats.rx_dropped++;
1.1       root     1100: #ifdef YF_PROTOTYPE                    /* Support for prototype hardware errata. */
1.1.1.3 ! root     1101:                } else if ((yp->flags & HasMACAddrBug)  &&
        !          1102:                                   memcmp(le32desc_to_virt(yp->rx_ring[entry].addr),
1.1       root     1103:                                                  dev->dev_addr, 6) != 0
1.1.1.3 ! root     1104:                                   && memcmp(le32desc_to_virt(yp->rx_ring[entry].addr),
1.1       root     1105:                                                         "\377\377\377\377\377\377", 6) != 0) {
1.1.1.3 ! root     1106:                        if (bogus_rx++ == 0)
        !          1107:                                printk(KERN_WARNING "%s: Bad frame to %2.2x:%2.2x:%2.2x:%2.2x:"
        !          1108:                                           "%2.2x:%2.2x.\n",
        !          1109:                                           dev->name, buf_addr[0], buf_addr[1], buf_addr[2],
        !          1110:                                           buf_addr[3], buf_addr[4], buf_addr[5]);
1.1       root     1111: #endif
                   1112:                } else {
                   1113:                        struct sk_buff *skb;
1.1.1.3 ! root     1114:                        int pkt_len = data_size -
        !          1115:                                (yp->chip_id ? 7 : 8 + buf_addr[data_size - 8]);
        !          1116:                        /* To verify: Yellowfin Length should omit the CRC! */
1.1       root     1117: 
1.1.1.3 ! root     1118: #ifndef final_version
        !          1119:                        if (yp->msg_level & NETIF_MSG_RX_STATUS)
        !          1120:                                printk(KERN_DEBUG "  yellowfin_rx() normal Rx pkt length %d"
        !          1121:                                           " of %d, bogus_cnt %d.\n",
        !          1122:                                           pkt_len, data_size, boguscnt);
        !          1123: #endif
        !          1124:                        /* Check if the packet is long enough to just pass up the skbuff
        !          1125:                           without copying to a properly sized skbuff. */
        !          1126:                        if (pkt_len > yp->rx_copybreak) {
        !          1127:                                char *temp = skb_put(skb = yp->rx_skbuff[entry], pkt_len);
        !          1128:                                yp->rx_skbuff[entry] = NULL;
        !          1129: #ifndef final_version                          /* Remove after testing. */
        !          1130:                                if (le32desc_to_virt(yp->rx_ring[entry].addr) != temp)
        !          1131:                                        printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
        !          1132:                                                   "do not match in yellowfin_rx: %p vs. %p / %p.\n",
        !          1133:                                                   dev->name,
        !          1134:                                                   le32desc_to_virt(yp->rx_ring[entry].addr),
1.1       root     1135:                                                   skb->head, temp);
1.1.1.3 ! root     1136: #endif
        !          1137:                        } else {
        !          1138:                                skb = dev_alloc_skb(pkt_len + 2);
        !          1139:                                if (skb == NULL)
        !          1140:                                        break;
        !          1141:                                skb->dev = dev;
        !          1142:                                skb_reserve(skb, 2);    /* 16 byte align the IP header */
        !          1143: #if HAS_IP_COPYSUM
        !          1144:                                eth_copy_and_sum(skb, yp->rx_skbuff[entry]->tail, pkt_len, 0);
        !          1145:                                skb_put(skb, pkt_len);
1.1       root     1146: #else
1.1.1.3 ! root     1147:                                memcpy(skb_put(skb, pkt_len), yp->rx_skbuff[entry]->tail,
        !          1148:                                           pkt_len);
1.1       root     1149: #endif
1.1.1.3 ! root     1150:                        }
        !          1151:                        skb->protocol = eth_type_trans(skb, dev);
1.1       root     1152:                        netif_rx(skb);
1.1.1.3 ! root     1153:                        dev->last_rx = jiffies;
        !          1154:                        yp->stats.rx_packets++;
        !          1155: #if LINUX_VERSION_CODE > 0x20127
        !          1156:                        yp->stats.rx_bytes += pkt_len;
        !          1157: #endif
1.1       root     1158:                }
1.1.1.3 ! root     1159:                entry = (++yp->cur_rx) % RX_RING_SIZE;
        !          1160:                yp->rx_head_desc = &yp->rx_ring[entry];
        !          1161:        }
1.1       root     1162: 
1.1.1.3 ! root     1163:        /* Refill the Rx ring buffers. */
        !          1164:        for (; yp->cur_rx - yp->dirty_rx > 0; yp->dirty_rx++) {
        !          1165:                entry = yp->dirty_rx % RX_RING_SIZE;
        !          1166:                if (yp->rx_skbuff[entry] == NULL) {
        !          1167:                        struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz);
        !          1168:                        yp->rx_skbuff[entry] = skb;
        !          1169:                        if (skb == NULL)
        !          1170:                                break;                          /* Better luck next round. */
        !          1171:                        skb->dev = dev;                 /* Mark as being used by this device. */
        !          1172:                        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
        !          1173:                        yp->rx_ring[entry].addr = virt_to_le32desc(skb->tail);
1.1       root     1174:                }
1.1.1.3 ! root     1175:                yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP);
        !          1176:                yp->rx_ring[entry].result_status = 0;   /* Clear complete bit. */
        !          1177:                if (entry != 0)
        !          1178:                        yp->rx_ring[entry - 1].dbdma_cmd =
        !          1179:                                cpu_to_le32(CMD_RX_BUF | INTR_ALWAYS | yp->rx_buf_sz);
        !          1180:                else
        !          1181:                        yp->rx_ring[RX_RING_SIZE - 1].dbdma_cmd =
        !          1182:                                cpu_to_le32(CMD_RX_BUF | INTR_ALWAYS | BRANCH_ALWAYS
        !          1183:                                                        | yp->rx_buf_sz);
1.1       root     1184:        }
                   1185: 
                   1186:        return 0;
                   1187: }
                   1188: 
1.1.1.3 ! root     1189: static void yellowfin_error(struct net_device *dev, int intr_status)
        !          1190: {
        !          1191:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
        !          1192: 
        !          1193:        printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
        !          1194:                   dev->name, intr_status);
        !          1195:        /* Hmmmmm, it's not clear what to do here. */
        !          1196:        if (intr_status & (IntrTxPCIErr | IntrTxPCIFault))
        !          1197:                yp->stats.tx_errors++;
        !          1198:        if (intr_status & (IntrRxPCIErr | IntrRxPCIFault))
        !          1199:                yp->stats.rx_errors++;
        !          1200: }
        !          1201: 
        !          1202: static int yellowfin_close(struct net_device *dev)
1.1       root     1203: {
1.1.1.3 ! root     1204:        long ioaddr = dev->base_addr;
1.1       root     1205:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
                   1206:        int i;
                   1207: 
1.1.1.3 ! root     1208:        netif_stop_tx_queue(dev);
1.1       root     1209: 
1.1.1.3 ! root     1210:        if (yp->msg_level & NETIF_MSG_IFDOWN) {
        !          1211:                printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %4.4x "
        !          1212:                           "Rx %4.4x Int %2.2x.\n",
1.1       root     1213:                           dev->name, inw(ioaddr + TxStatus),
1.1.1.3 ! root     1214:                           inw(ioaddr + RxStatus), inw(ioaddr + IntrStatus));
        !          1215:                printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
1.1       root     1216:                           dev->name, yp->cur_tx, yp->dirty_tx, yp->cur_rx, yp->dirty_rx);
                   1217:        }
                   1218: 
                   1219:        /* Disable interrupts by clearing the interrupt mask. */
                   1220:        outw(0x0000, ioaddr + IntrEnb);
                   1221: 
                   1222:        /* Stop the chip's Tx and Rx processes. */
                   1223:        outl(0x80000000, ioaddr + RxCtrl);
                   1224:        outl(0x80000000, ioaddr + TxCtrl);
                   1225: 
                   1226:        del_timer(&yp->timer);
                   1227: 
1.1.1.3 ! root     1228: #if defined(__i386__)
        !          1229:        if (yp->msg_level & NETIF_MSG_IFDOWN) {
        !          1230:                printk("\n"KERN_DEBUG"  Tx ring at %8.8x:\n",
        !          1231:                           (int)virt_to_bus(yp->tx_ring));
1.1       root     1232:                for (i = 0; i < TX_RING_SIZE*2; i++)
1.1.1.3 ! root     1233:                        printk(" %c #%d desc. %8.8x %8.8x %8.8x %8.8x.\n",
1.1       root     1234:                                   inl(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ',
1.1.1.3 ! root     1235:                                   i, yp->tx_ring[i].dbdma_cmd, yp->tx_ring[i].addr,
        !          1236:                                   yp->tx_ring[i].branch_addr, yp->tx_ring[i].result_status);
        !          1237:                printk(KERN_DEBUG "  Tx status %p:\n", yp->tx_status);
1.1       root     1238:                for (i = 0; i < TX_RING_SIZE; i++)
1.1.1.3 ! root     1239:                        printk(KERN_DEBUG "   #%d status %4.4x %4.4x %4.4x %4.4x.\n",
1.1       root     1240:                                   i, yp->tx_status[i].tx_cnt, yp->tx_status[i].tx_errs,
                   1241:                                   yp->tx_status[i].total_tx_cnt, yp->tx_status[i].paused);
                   1242: 
1.1.1.3 ! root     1243:                printk("\n"KERN_DEBUG "  Rx ring %8.8x:\n",
        !          1244:                           (int)virt_to_bus(yp->rx_ring));
1.1       root     1245:                for (i = 0; i < RX_RING_SIZE; i++) {
1.1.1.3 ! root     1246:                        printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x\n",
1.1       root     1247:                                   inl(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ',
1.1.1.3 ! root     1248:                                   i, yp->rx_ring[i].dbdma_cmd, yp->rx_ring[i].addr,
        !          1249:                                   yp->rx_ring[i].result_status);
        !          1250:                        if (yp->msg_level & NETIF_MSG_PKTDATA) {
        !          1251:                                if (get_unaligned((u8*)yp->rx_ring[i].addr) != 0x69) {
1.1       root     1252:                                        int j;
                   1253:                                        for (j = 0; j < 0x50; j++)
1.1.1.3 ! root     1254:                                                printk(" %4.4x",
        !          1255:                                                           get_unaligned(((u16*)yp->rx_ring[i].addr) + j));
1.1       root     1256:                                        printk("\n");
                   1257:                                }
                   1258:                        }
                   1259:                }
                   1260:        }
                   1261: #endif /* __i386__ debugging only */
                   1262: 
                   1263:        free_irq(dev->irq, dev);
                   1264: 
                   1265:        /* Free all the skbuffs in the Rx queue. */
                   1266:        for (i = 0; i < RX_RING_SIZE; i++) {
1.1.1.3 ! root     1267:                yp->rx_ring[i].dbdma_cmd = cpu_to_le32(CMD_STOP);
1.1       root     1268:                yp->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */
                   1269:                if (yp->rx_skbuff[i]) {
                   1270: #if LINUX_VERSION_CODE < 0x20100
                   1271:                        yp->rx_skbuff[i]->free = 1;
                   1272: #endif
1.1.1.3 ! root     1273:                        dev_free_skb(yp->rx_skbuff[i]);
1.1       root     1274:                }
                   1275:                yp->rx_skbuff[i] = 0;
                   1276:        }
                   1277:        for (i = 0; i < TX_RING_SIZE; i++) {
                   1278:                if (yp->tx_skbuff[i])
1.1.1.3 ! root     1279:                        dev_free_skb(yp->tx_skbuff[i]);
1.1       root     1280:                yp->tx_skbuff[i] = 0;
                   1281:        }
                   1282: 
                   1283: #ifdef YF_PROTOTYPE                    /* Support for prototype hardware errata. */
1.1.1.3 ! root     1284:        if (yp->msg_level & NETIF_MSG_IFDOWN) {
        !          1285:                printk(KERN_DEBUG "%s: Received %d frames that we should not have.\n",
1.1       root     1286:                           dev->name, bogus_rx);
                   1287:        }
                   1288: #endif
                   1289:        MOD_DEC_USE_COUNT;
                   1290: 
                   1291:        return 0;
                   1292: }
                   1293: 
1.1.1.3 ! root     1294: static struct net_device_stats *yellowfin_get_stats(struct net_device *dev)
1.1       root     1295: {
                   1296:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
                   1297:        return &yp->stats;
                   1298: }
                   1299: 
                   1300: /* Set or clear the multicast filter for this adaptor. */
                   1301: 
                   1302: /* The little-endian AUTODIN32 ethernet CRC calculation.
                   1303:    N.B. Do not use for bulk data, use a table-based routine instead.
                   1304:    This is common code and should be moved to net/core/crc.c */
                   1305: static unsigned const ethernet_polynomial_le = 0xedb88320U;
1.1.1.3 ! root     1306: 
1.1       root     1307: static inline unsigned ether_crc_le(int length, unsigned char *data)
                   1308: {
                   1309:        unsigned int crc = 0xffffffff;  /* Initial value. */
                   1310:        while(--length >= 0) {
                   1311:                unsigned char current_octet = *data++;
                   1312:                int bit;
                   1313:                for (bit = 8; --bit >= 0; current_octet >>= 1) {
                   1314:                        if ((crc ^ current_octet) & 1) {
                   1315:                                crc >>= 1;
                   1316:                                crc ^= ethernet_polynomial_le;
                   1317:                        } else
                   1318:                                crc >>= 1;
                   1319:                }
                   1320:        }
                   1321:        return crc;
                   1322: }
                   1323: 
                   1324: 
1.1.1.3 ! root     1325: static void set_rx_mode(struct net_device *dev)
1.1       root     1326: {
1.1.1.3 ! root     1327:        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
        !          1328:        u16 hash_table[4] = {0, 0, 0, 0};
        !          1329:        int mc_change = 0;
        !          1330:        int new_rx_mode, i;
1.1       root     1331: 
                   1332:        if (dev->flags & IFF_PROMISC) {                 /* Set promiscuous. */
                   1333:                /* Unconditionally log net taps. */
1.1.1.3 ! root     1334:                printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
        !          1335:                new_rx_mode = 0x000F;
        !          1336:        } else if (dev->mc_count > yp->multicast_filter_limit
        !          1337:                           ||  (dev->flags & IFF_ALLMULTI)) {
1.1       root     1338:                /* Too many to filter well, or accept all multicasts. */
1.1.1.3 ! root     1339:                new_rx_mode = 0x000B;
1.1       root     1340:        } else if (dev->mc_count > 0) { /* Must use the multicast hash table. */
                   1341:                struct dev_mc_list *mclist;
1.1.1.3 ! root     1342: 
1.1       root     1343:                for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
                   1344:                         i++, mclist = mclist->next) {
                   1345:                        /* Due to a bug in the early chip versions, multiple filter
                   1346:                           slots must be set for each address. */
1.1.1.3 ! root     1347:                        if (yp->drv_flags & HasMulticastBug) {
        !          1348:                                set_bit((ether_crc_le(3, mclist->dmi_addr) >> 3) & 0x3f,
        !          1349:                                                hash_table);
        !          1350:                                set_bit((ether_crc_le(4, mclist->dmi_addr) >> 3) & 0x3f,
        !          1351:                                                hash_table);
        !          1352:                                set_bit((ether_crc_le(5, mclist->dmi_addr) >> 3) & 0x3f,
        !          1353:                                                hash_table);
        !          1354:                        }
1.1       root     1355:                        set_bit((ether_crc_le(6, mclist->dmi_addr) >> 3) & 0x3f,
                   1356:                                        hash_table);
                   1357:                }
1.1.1.3 ! root     1358:                if (memcmp(hash_table, yp->mc_filter, sizeof hash_table) != 0)
        !          1359:                        mc_change = 1;
        !          1360:                new_rx_mode = 0x0003;
        !          1361:        } else {                                        /* Normal, unicast/broadcast-only mode. */
        !          1362:                new_rx_mode = 0x0001;
        !          1363:        }
        !          1364: 
        !          1365:        /* Stop the Rx process to change any value. */
        !          1366:        if (yp->rx_mode != new_rx_mode || mc_change) {
        !          1367:                long ioaddr = dev->base_addr;
        !          1368:                u16 cfg_value = inw(ioaddr + Cnfg);
        !          1369: 
        !          1370:                outw(cfg_value & ~0x1000, ioaddr + Cnfg);
        !          1371: 
        !          1372:                yp->rx_mode = new_rx_mode;
        !          1373:                outw(new_rx_mode, ioaddr + AddrMode);
        !          1374:                memcpy(yp->mc_filter, hash_table, sizeof hash_table);
1.1       root     1375:                /* Copy the hash table to the chip. */
                   1376:                for (i = 0; i < 4; i++)
                   1377:                        outw(hash_table[i], ioaddr + HashTbl + i*2);
1.1.1.3 ! root     1378: 
        !          1379:                /* Restart the Rx process. */
        !          1380:                outw(cfg_value | 0x1000, ioaddr + Cnfg);
1.1       root     1381:        }
                   1382: }
                   1383: 
1.1.1.3 ! root     1384: static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1.1       root     1385: {
1.1.1.3 ! root     1386:        struct yellowfin_private *np = (void *)dev->priv;
        !          1387:        long ioaddr = dev->base_addr;
        !          1388:        u16 *data = (u16 *)&rq->ifr_data;
        !          1389:        u32 *data32 = (void *)&rq->ifr_data;
        !          1390: 
        !          1391:        switch(cmd) {
        !          1392:        case 0x8947: case 0x89F0:
        !          1393:                /* SIOCGMIIPHY: Get the address of the PHY in use. */
        !          1394:                data[0] = np->phys[0] & 0x1f;
        !          1395:                /* Fall Through */
        !          1396:        case 0x8948: case 0x89F1:
        !          1397:                /* SIOCGMIIREG: Read the specified MII register. */
        !          1398:                data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
        !          1399:                return 0;
        !          1400:        case 0x8949: case 0x89F2:
        !          1401:                /* SIOCSMIIREG: Write the specified MII register */
        !          1402:                if (!capable(CAP_NET_ADMIN))
        !          1403:                        return -EPERM;
        !          1404:                if (data[0] == np->phys[0]) {
        !          1405:                        u16 value = data[2];
        !          1406:                        switch (data[1]) {
        !          1407:                        case 0:
        !          1408:                                /* Check for autonegotiation on or reset. */
        !          1409:                                np->medialock = (value & 0x9000) ? 0 : 1;
        !          1410:                                if (np->medialock)
        !          1411:                                        np->full_duplex = (value & 0x0100) ? 1 : 0;
        !          1412:                                break;
        !          1413:                        case 4: np->advertising = value; break;
        !          1414:                        }
        !          1415:                        /* Perhaps check_duplex(dev), depending on chip semantics. */
        !          1416:                }
        !          1417:                mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
        !          1418:                return 0;
        !          1419:        case SIOCGPARAMS:
        !          1420:                data32[0] = np->msg_level;
        !          1421:                data32[1] = np->multicast_filter_limit;
        !          1422:                data32[2] = np->max_interrupt_work;
        !          1423:                data32[3] = np->rx_copybreak;
        !          1424:                return 0;
        !          1425:        case SIOCSPARAMS:
        !          1426:                if (!capable(CAP_NET_ADMIN))
        !          1427:                        return -EPERM;
        !          1428:                np->msg_level = data32[0];
        !          1429:                np->multicast_filter_limit = data32[1];
        !          1430:                np->max_interrupt_work = data32[2];
        !          1431:                np->rx_copybreak = data32[3];
        !          1432:                return 0;
        !          1433:        default:
        !          1434:                return -EOPNOTSUPP;
        !          1435:        }
        !          1436: }
1.1       root     1437: 
1.1.1.3 ! root     1438: 
        !          1439: #ifdef MODULE
        !          1440: int init_module(void)
        !          1441: {
        !          1442:        /* Emit version even if no cards detected. */
        !          1443:        printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
        !          1444:        return pci_drv_register(&yellowfin_drv_id, NULL);
1.1       root     1445: }
                   1446: 
1.1.1.3 ! root     1447: void cleanup_module(void)
1.1       root     1448: {
1.1.1.3 ! root     1449:        struct net_device *next_dev;
        !          1450: 
        !          1451:        pci_drv_unregister(&yellowfin_drv_id);
1.1       root     1452: 
                   1453:        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
                   1454:        while (root_yellowfin_dev) {
1.1.1.3 ! root     1455:                struct yellowfin_private *np = (void *)(root_yellowfin_dev->priv);
1.1       root     1456:                unregister_netdev(root_yellowfin_dev);
1.1.1.3 ! root     1457: #ifdef USE_IO_OPS
        !          1458:                release_region(root_yellowfin_dev->base_addr,
        !          1459:                                           pci_id_tbl[np->chip_id].io_size);
        !          1460: #else
        !          1461:                iounmap((char *)root_yellowfin_dev->base_addr);
        !          1462: #endif
        !          1463:                next_dev = np->next_module;
        !          1464:                if (np->priv_addr)
        !          1465:                        kfree(np->priv_addr);
1.1       root     1466:                kfree(root_yellowfin_dev);
                   1467:                root_yellowfin_dev = next_dev;
                   1468:        }
                   1469: }
                   1470: 
                   1471: #endif  /* MODULE */
                   1472: 
                   1473: /*
                   1474:  * Local variables:
1.1.1.3 ! root     1475:  *  compile-command: "make KERNVER=`uname -r` yellowfin.o"
        !          1476:  *  compile-cmd: "gcc -DMODULE -Wall -Wstrict-prototypes -O6 -c yellowfin.c"
        !          1477:  *  simple-compile-command: "gcc -DMODULE -O6 -c yellowfin.c"
1.1       root     1478:  *  c-indent-level: 4
                   1479:  *  c-basic-offset: 4
                   1480:  *  tab-width: 4
                   1481:  * End:
                   1482:  */

unix.superglobalmegacorp.com

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