Annotation of Gnu-Mach/linux/src/drivers/net/ne2k-pci.c, revision 1.1.1.2

1.1       root        1: /* ne2k-pci.c: A NE2000 clone on PCI bus driver for Linux. */
                      2: /*
                      3:        A Linux device driver for PCI NE2000 clones.
                      4: 
1.1.1.2 ! root        5:        Authors and other copyright holders:
        !             6:        1992-2002 by Donald Becker, NE2000 core and various modifications.
1.1       root        7:        1995-1998 by Paul Gortmaker, core modifications and PCI support.
                      8:        Copyright 1993 assigned to the United States Government as represented
                      9:        by the Director, National Security Agency.
                     10: 
1.1.1.2 ! root       11:        This software may be used and distributed according to the terms of
        !            12:        the GNU General Public License (GPL), incorporated herein by reference.
        !            13:        Drivers based on or derived from this code fall under the GPL and must
        !            14:        retain the authorship, copyright and license notice.  This file is not
        !            15:        a complete program and may only be used when the entire operating
        !            16:        system is licensed under the GPL.
        !            17: 
        !            18:        The author may be reached as [email protected], or C/O
        !            19:        Scyld Computing Corporation
        !            20:        410 Severn Ave., Suite 210
        !            21:        Annapolis MD 21403
1.1       root       22: 
                     23:        Issues remaining:
1.1.1.2 ! root       24:        People are making PCI ne2000 clones! Oh the horror, the horror...
        !            25:        Limited full-duplex support.
1.1       root       26: */
                     27: 
1.1.1.2 ! root       28: /* These identify the driver base version and may not be removed. */
        !            29: static const char version1[] =
        !            30: "ne2k-pci.c:v1.05 6/13/2002 D. Becker/P. Gortmaker\n";
        !            31: static const char version2[] =
        !            32: "  http://www.scyld.com/network/ne2k-pci.html\n";
        !            33: 
        !            34: /* The user-configurable values.
        !            35:    These may be modified when a driver module is loaded.*/
        !            36: 
        !            37: static int debug = 1;                  /* 1 normal messages, 0 quiet .. 7 verbose. */
        !            38: 
        !            39: #define MAX_UNITS 8                            /* More are supported, limit only on options */
        !            40: /* Used to pass the full-duplex flag, etc. */
        !            41: static int full_duplex[MAX_UNITS] = {0, };
        !            42: static int options[MAX_UNITS] = {0, };
1.1       root       43: 
1.1.1.2 ! root       44: /* Force a non std. amount of memory.  Units are 256 byte pages. */
        !            45: /* #define PACKETBUF_MEMSIZE   0x40 */
        !            46: 
        !            47: #ifndef __KERNEL__
        !            48: #define __KERNEL__
        !            49: #endif
        !            50: #if !defined(__OPTIMIZE__)
        !            51: #warning  You must compile this file with the correct options!
        !            52: #warning  See the last lines of the source file.
        !            53: #error You must compile this driver with "-O".
        !            54: #endif
        !            55: 
        !            56: #include <linux/config.h>
        !            57: #if defined(CONFIG_SMP) && ! defined(__SMP__)
        !            58: #define __SMP__
        !            59: #endif
        !            60: #if defined(MODULE) && defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
        !            61: #define MODVERSIONS
1.1       root       62: #endif
1.1.1.2 ! root       63: 
        !            64: #include <linux/version.h>
1.1       root       65: #include <linux/module.h>
1.1.1.2 ! root       66: #if LINUX_VERSION_CODE < 0x20300  &&  defined(MODVERSIONS)
        !            67: #include <linux/modversions.h>
        !            68: #endif
        !            69: 
1.1       root       70: #include <linux/kernel.h>
                     71: #include <linux/errno.h>
                     72: #include <linux/pci.h>
1.1.1.2 ! root       73: #if LINUX_VERSION_CODE < 0x20200
        !            74: #define lock_8390_module()
        !            75: #define unlock_8390_module()
        !            76: #else
        !            77: #include <linux/init.h>
        !            78: #endif
        !            79: 
1.1       root       80: #include <asm/system.h>
                     81: #include <asm/io.h>
                     82: #include <asm/irq.h>
                     83: 
                     84: #include <linux/netdevice.h>
                     85: #include <linux/etherdevice.h>
                     86: #include "8390.h"
                     87: 
1.1.1.2 ! root       88: #ifdef INLINE_PCISCAN
        !            89: #include "k_compat.h"
        !            90: #else
        !            91: #include "pci-scan.h"
        !            92: #include "kern_compat.h"
        !            93: #endif
        !            94: 
        !            95: MODULE_AUTHOR("Donald Becker / Paul Gortmaker");
        !            96: MODULE_DESCRIPTION("PCI NE2000 clone driver");
        !            97: MODULE_PARM(debug, "i");
        !            98: MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
        !            99: MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
1.1       root      100: 
                    101: /* Some defines that people can play with if so inclined. */
                    102: 
                    103: /* Do #define LOAD_8390_BY_KERNELD to automatically load 8390 support. */
                    104: #ifdef LOAD_8390_BY_KERNELD
                    105: #include <linux/kerneld.h>
                    106: #endif
                    107: 
1.1.1.2 ! root      108: static void *ne2k_pci_probe1(struct pci_dev *pdev, void *dev,
        !           109:                                                         long ioaddr, int irq, int chip_idx, int fnd_cnt);
        !           110: /* Flags.  We rename an existing ei_status field to store flags! */
        !           111: /* Thus only the low 8 bits are usable for non-init-time flags. */
        !           112: #define ne2k_flags reg0
        !           113: enum {
        !           114:        ONLY_16BIT_IO=8, ONLY_32BIT_IO=4,       /* Chip can do only 16/32-bit xfers. */
        !           115:        FORCE_FDX=0x20,                                         /* User override. */
        !           116:        REALTEK_FDX=0x40, HOLTEK_FDX=0x80,
        !           117:        STOP_PG_0x60=0x100,
        !           118: };
        !           119: #define NE_IO_EXTENT   0x20
        !           120: #ifndef USE_MEMORY_OPS
        !           121: #define PCI_IOTYPE (PCI_USES_IO  | PCI_ADDR0)
        !           122: #else
        !           123: #warning When using PCI memory mode the 8390 core must be compiled for memory
        !           124: #warning operations as well.
        !           125: #warning Not all PCI NE2000 clones support memory mode access. 
        !           126: #define PCI_IOTYPE (PCI_USES_MEM | PCI_ADDR1)
        !           127: #endif
        !           128: 
        !           129: static struct pci_id_info pci_id_tbl[] = {
        !           130:        {"RealTek RTL-8029",{ 0x802910ec, 0xffffffff}, PCI_IOTYPE, NE_IO_EXTENT,
        !           131:         REALTEK_FDX },
        !           132:        {"Winbond 89C940",  { 0x09401050, 0xffffffff}, PCI_IOTYPE, NE_IO_EXTENT, 0},
        !           133:        {"Winbond w89c940",     { 0x5a5a1050, 0xffffffff}, PCI_IOTYPE, NE_IO_EXTENT, 0},
        !           134:        {"KTI ET32P2",      { 0x30008e2e, 0xffffffff}, PCI_IOTYPE, NE_IO_EXTENT, 0},
        !           135:        {"NetVin NV5000SC", { 0x50004a14, 0xffffffff}, PCI_IOTYPE, NE_IO_EXTENT, 0},
        !           136:        {"Via 86C926",          { 0x09261106, 0xffffffff},
        !           137:         PCI_IOTYPE, NE_IO_EXTENT, ONLY_16BIT_IO},
        !           138:        {"SureCom NE34",        { 0x0e3410bd, 0xffffffff}, PCI_IOTYPE, NE_IO_EXTENT, 0},
        !           139:        {"Holtek HT80232",      { 0x005812c3, 0xffffffff},
        !           140:         PCI_IOTYPE, NE_IO_EXTENT, ONLY_16BIT_IO | HOLTEK_FDX},
        !           141:        {"Holtek HT80229",      { 0x559812c3, 0xffffffff},
        !           142:         PCI_IOTYPE, NE_IO_EXTENT, ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60},
        !           143:        {"Compex RL2000",
        !           144:         { 0x140111f6, 0xffffffff}, PCI_IOTYPE, NE_IO_EXTENT, 0},
        !           145:        /* A mutant board: Winbond chip with a RTL format EEPROM. */
        !           146:        {"Winbond w89c940 (misprogrammed type 0x1980)", { 0x19808c4a, 0xffffffff},
        !           147:         PCI_IOTYPE, NE_IO_EXTENT, 0},
        !           148:        {0,},                                           /* 0 terminated list. */
        !           149: };
1.1       root      150: 
1.1.1.2 ! root      151: struct drv_id_info ne2k_pci_drv_id = {
        !           152:        "ne2k-pci", 0, PCI_CLASS_NETWORK_ETHERNET<<8, pci_id_tbl, ne2k_pci_probe1,
1.1       root      153: };
                    154: 
                    155: /* ---- No user-serviceable parts below ---- */
                    156: 
                    157: #define NE_BASE         (dev->base_addr)
                    158: #define NE_CMD         0x00
                    159: #define NE_DATAPORT    0x10    /* NatSemi-defined port window offset. */
                    160: #define NE_RESET       0x1f    /* Issue a read to reset, a write to clear. */
                    161: 
                    162: #define NESM_START_PG  0x40    /* First page of TX buffer */
                    163: #define NESM_STOP_PG   0x80    /* Last page +1 of RX ring */
                    164: 
1.1.1.2 ! root      165: int ne2k_pci_probe(struct net_device *dev);
1.1       root      166: 
1.1.1.2 ! root      167: static int ne2k_pci_open(struct net_device *dev);
        !           168: static int ne2k_pci_close(struct net_device *dev);
1.1       root      169: 
1.1.1.2 ! root      170: static void ne2k_pci_reset_8390(struct net_device *dev);
        !           171: static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
1.1       root      172:                          int ring_page);
1.1.1.2 ! root      173: static void ne2k_pci_block_input(struct net_device *dev, int count,
1.1       root      174:                          struct sk_buff *skb, int ring_offset);
1.1.1.2 ! root      175: static void ne2k_pci_block_output(struct net_device *dev, const int count,
1.1       root      176:                const unsigned char *buf, const int start_page);
                    177: 
                    178: 
                    179: 
1.1.1.2 ! root      180: /* There is no room in the standard 8390 structure for extra info we need,
        !           181:    so we build a meta/outer-wrapper structure.. */
1.1       root      182: struct ne2k_pci_card {
                    183:        struct ne2k_pci_card *next;
1.1.1.2 ! root      184:        struct net_device *dev;
        !           185:        struct pci_dev *pci_dev;
1.1       root      186: };
                    187: /* A list of all installed devices, for removing the driver module. */
                    188: static struct ne2k_pci_card *ne2k_card_list = NULL;
                    189: 
                    190: #ifdef LOAD_8390_BY_KERNELD
1.1.1.2 ! root      191: static int (*Lethdev_init)(struct net_device *dev);
        !           192: static void (*LNS8390_init)(struct net_device *dev, int startp);
        !           193: static int (*Lei_open)(struct net_device *dev);
        !           194: static int (*Lei_close)(struct net_device *dev);
1.1       root      195: static void (*Lei_interrupt)(int irq, void *dev_id, struct pt_regs *regs);
                    196: #else
                    197: #define Lethdev_init ethdev_init
                    198: #define LNS8390_init NS8390_init
                    199: #define Lei_open ei_open
                    200: #define Lei_close ei_close
                    201: #define Lei_interrupt ei_interrupt
                    202: #endif
                    203: 
                    204: #ifdef MODULE
1.1.1.2 ! root      205: int init_module(void)
1.1       root      206: {
1.1.1.2 ! root      207:        int found_cnt;
1.1       root      208: 
1.1.1.2 ! root      209:        if (debug)                                      /* Emit version even if no cards detected. */
        !           210:                printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
        !           211:        found_cnt = pci_drv_register(&ne2k_pci_drv_id, NULL);
        !           212:        if (found_cnt < 0) {
        !           213:                printk(KERN_NOTICE "ne2k-pci.c: No useable cards found, driver NOT installed.\n");
        !           214:                return -ENODEV;
        !           215:        }
        !           216:        lock_8390_module();
        !           217:        return 0;
1.1       root      218: }
                    219: 
1.1.1.2 ! root      220: void cleanup_module(void)
1.1       root      221: {
1.1.1.2 ! root      222:        struct net_device *dev;
1.1       root      223:        struct ne2k_pci_card *this_card;
                    224: 
1.1.1.2 ! root      225:        pci_drv_unregister(&ne2k_pci_drv_id);
        !           226: 
1.1       root      227:        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
                    228:        while (ne2k_card_list) {
                    229:                dev = ne2k_card_list->dev;
                    230:                unregister_netdev(dev);
                    231:                release_region(dev->base_addr, NE_IO_EXTENT);
                    232:                kfree(dev);
                    233:                this_card = ne2k_card_list;
                    234:                ne2k_card_list = ne2k_card_list->next;
                    235:                kfree(this_card);
                    236:        }
                    237: 
                    238: #ifdef LOAD_8390_BY_KERNELD
                    239:        release_module("8390", 0);
1.1.1.2 ! root      240: #else
        !           241:        unlock_8390_module();
1.1       root      242: #endif
                    243: }
                    244: 
1.1.1.2 ! root      245: #else
1.1       root      246: 
1.1.1.2 ! root      247: int ne2k_pci_probe(struct net_device *dev)
1.1       root      248: {
1.1.1.2 ! root      249:        int found_cnt = pci_drv_register(&ne2k_pci_drv_id, NULL);
        !           250:        if (found_cnt >= 0  &&  debug)
        !           251:                printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
        !           252:        return found_cnt;
1.1       root      253: }
1.1.1.2 ! root      254: #endif  /* MODULE */
1.1       root      255: 
1.1.1.2 ! root      256: static void *ne2k_pci_probe1(struct pci_dev *pdev, void *init_dev,
        !           257:                                                         long ioaddr, int irq, int chip_idx, int fnd_cnt)
1.1       root      258: {
1.1.1.2 ! root      259:        struct net_device *dev;
1.1       root      260:        int i;
                    261:        unsigned char SA_prom[32];
                    262:        int start_page, stop_page;
                    263:        int reg0 = inb(ioaddr);
1.1.1.2 ! root      264:        int flags = pci_id_tbl[chip_idx].drv_flags;
        !           265:        struct ne2k_pci_card *ne2k_card;
1.1       root      266: 
                    267:        if (reg0 == 0xFF)
                    268:                return 0;
                    269: 
                    270:        /* Do a preliminary verification that we have a 8390. */
                    271:        {
                    272:                int regd;
                    273:                outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
                    274:                regd = inb(ioaddr + 0x0d);
                    275:                outb(0xff, ioaddr + 0x0d);
                    276:                outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
                    277:                inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
                    278:                if (inb(ioaddr + EN0_COUNTER0) != 0) {
                    279:                        outb(reg0, ioaddr);
                    280:                        outb(regd, ioaddr + 0x0d);      /* Restore the old values. */
                    281:                        return 0;
                    282:                }
                    283:        }
                    284: 
1.1.1.2 ! root      285:        dev = init_etherdev(init_dev, 0);
        !           286: 
        !           287:        if (dev == NULL)
        !           288:                return 0;
        !           289:        ne2k_card = kmalloc(sizeof(struct ne2k_pci_card), GFP_KERNEL);
        !           290:        if (ne2k_card == NULL)
        !           291:                return 0;
        !           292: 
        !           293:        ne2k_card->next = ne2k_card_list;
        !           294:        ne2k_card_list = ne2k_card;
        !           295:        ne2k_card->dev = dev;
        !           296:        ne2k_card->pci_dev = pdev;
1.1       root      297: 
                    298:        /* Reset card. Who knows what dain-bramaged state it was left in. */
                    299:        {
                    300:                unsigned long reset_start_time = jiffies;
                    301: 
                    302:                outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
                    303: 
                    304:                /* This looks like a horrible timing loop, but it should never take
                    305:                   more than a few cycles.
                    306:                */
                    307:                while ((inb(ioaddr + EN0_ISR) & ENISR_RESET) == 0)
                    308:                        /* Limit wait: '2' avoids jiffy roll-over. */
                    309:                        if (jiffies - reset_start_time > 2) {
                    310:                                printk("ne2k-pci: Card failure (no reset ack).\n");
                    311:                                return 0;
                    312:                        }
                    313:                
                    314:                outb(0xff, ioaddr + EN0_ISR);           /* Ack all intr. */
                    315:        }
                    316: 
                    317: #if defined(LOAD_8390_BY_KERNELD)
                    318:        /* We are now certain the 8390 module is required. */
                    319:        if (request_module("8390")) {
                    320:                printk("ne2k-pci: Failed to load the 8390 core module.\n");
                    321:                return 0;
                    322:        }
                    323:        if ((Lethdev_init = (void*)get_module_symbol(0, "ethdev_init")) == 0 ||
                    324:                (LNS8390_init = (void*)get_module_symbol(0, "NS8390_init")) == 0 ||
                    325:                (Lei_open = (void*)get_module_symbol(0, "ei_open")) == 0 ||
                    326:                (Lei_close = (void*)get_module_symbol(0, "ei_close")) == 0 ||
                    327:                (Lei_interrupt = (void*)get_module_symbol(0, "ei_interrupt")) == 0 ) {
                    328:                printk("ne2k-pci: Failed to resolve an 8390 symbol.\n");
                    329:                release_module("8390", 0);
                    330:                return 0;
                    331:        }
                    332: #endif
                    333: 
                    334:        /* Read the 16 bytes of station address PROM.
                    335:           We must first initialize registers, similar to NS8390_init(eifdev, 0).
                    336:           We can't reliably read the SAPROM address without this.
                    337:           (I learned the hard way!). */
                    338:        {
                    339:                struct {unsigned char value, offset; } program_seq[] = {
                    340:                        {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
                    341:                        {0x49,  EN0_DCFG},      /* Set word-wide access. */
                    342:                        {0x00,  EN0_RCNTLO},    /* Clear the count regs. */
                    343:                        {0x00,  EN0_RCNTHI},
                    344:                        {0x00,  EN0_IMR},       /* Mask completion irq. */
                    345:                        {0xFF,  EN0_ISR},
                    346:                        {E8390_RXOFF, EN0_RXCR},        /* 0x20  Set to monitor */
                    347:                        {E8390_TXOFF, EN0_TXCR},        /* 0x02  and loopback mode. */
                    348:                        {32,    EN0_RCNTLO},
                    349:                        {0x00,  EN0_RCNTHI},
                    350:                        {0x00,  EN0_RSARLO},    /* DMA starting at 0x0000. */
                    351:                        {0x00,  EN0_RSARHI},
                    352:                        {E8390_RREAD+E8390_START, E8390_CMD},
                    353:                };
                    354:                for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
                    355:                        outb(program_seq[i].value, ioaddr + program_seq[i].offset);
                    356: 
                    357:        }
                    358: 
1.1.1.2 ! root      359:        /* Note: all PCI cards have at least 16 bit access, so we don't have
        !           360:           to check for 8 bit cards.  Most cards permit 32 bit access. */
1.1       root      361: 
1.1.1.2 ! root      362:        if (flags & ONLY_32BIT_IO) {
        !           363:                for (i = 0; i < 8; i++)
        !           364:                        ((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT));
        !           365:        } else
        !           366:                for(i = 0; i < 32 /*sizeof(SA_prom)*/; i++)
        !           367:                        SA_prom[i] = inb(ioaddr + NE_DATAPORT);
1.1       root      368: 
                    369:        /* We always set the 8390 registers for word mode. */
                    370:        outb(0x49, ioaddr + EN0_DCFG);
                    371:        start_page = NESM_START_PG;
                    372: 
1.1.1.2 ! root      373:        stop_page = flags & STOP_PG_0x60 ? 0x60 : NESM_STOP_PG;
1.1       root      374: 
1.1.1.2 ! root      375:        /* Set up the rest of the parameters. */
1.1       root      376:        dev->irq = irq;
                    377:        dev->base_addr = ioaddr;
                    378: 
                    379:        /* Allocate dev->priv and fill in 8390 specific dev fields. */
                    380:        if (Lethdev_init(dev)) {
                    381:                printk ("%s: unable to get memory for dev->priv.\n", dev->name);
                    382:                return 0;
                    383:        }
                    384: 
                    385:        request_region(ioaddr, NE_IO_EXTENT, dev->name);
                    386: 
1.1.1.2 ! root      387:        printk("%s: %s found at %#lx, IRQ %d, ",
        !           388:                   dev->name, pci_id_tbl[chip_idx].name, ioaddr, dev->irq);
1.1       root      389:        for(i = 0; i < 6; i++) {
                    390:                printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":");
                    391:                dev->dev_addr[i] = SA_prom[i];
                    392:        }
                    393: 
1.1.1.2 ! root      394:        ei_status.name = pci_id_tbl[chip_idx].name;
1.1       root      395:        ei_status.tx_start_page = start_page;
                    396:        ei_status.stop_page = stop_page;
                    397:        ei_status.word16 = 1;
1.1.1.2 ! root      398:        ei_status.ne2k_flags = flags;
        !           399:        if (fnd_cnt < MAX_UNITS) {
        !           400:                if (full_duplex[fnd_cnt] > 0  ||  (options[fnd_cnt] & FORCE_FDX)) {
        !           401:                        printk("%s:  Full duplex set by user option.\n", dev->name);
        !           402:                        ei_status.ne2k_flags |= FORCE_FDX;
        !           403:                }
        !           404:        }
1.1       root      405: 
                    406:        ei_status.rx_start_page = start_page + TX_PAGES;
                    407: #ifdef PACKETBUF_MEMSIZE
                    408:        /* Allow the packet buffer size to be overridden by know-it-alls. */
                    409:        ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
                    410: #endif
                    411: 
1.1.1.2 ! root      412:        ei_status.reset_8390 = &ne2k_pci_reset_8390;
        !           413:        ei_status.block_input = &ne2k_pci_block_input;
        !           414:        ei_status.block_output = &ne2k_pci_block_output;
        !           415:        ei_status.get_8390_hdr = &ne2k_pci_get_8390_hdr;
        !           416:        dev->open = &ne2k_pci_open;
        !           417:        dev->stop = &ne2k_pci_close;
1.1       root      418:        LNS8390_init(dev, 0);
                    419:        return dev;
                    420: }
                    421: 
1.1.1.2 ! root      422: static int ne2k_pci_open(struct net_device *dev)
1.1       root      423: {
1.1.1.2 ! root      424:        MOD_INC_USE_COUNT;
        !           425:        if (request_irq(dev->irq, Lei_interrupt, SA_SHIRQ, dev->name, dev)) {
        !           426:                MOD_DEC_USE_COUNT;
1.1       root      427:                return -EAGAIN;
1.1.1.2 ! root      428:        }
        !           429:        /* Set full duplex for the chips that we know about. */
        !           430:        if (ei_status.ne2k_flags & FORCE_FDX) {
        !           431:                long ioaddr = dev->base_addr;
        !           432:                if (ei_status.ne2k_flags & REALTEK_FDX) {
        !           433:                        outb(0xC0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 3 */
        !           434:                        outb(inb(ioaddr + 0x20) | 0x80, ioaddr + 0x20);
        !           435:                } else if (ei_status.ne2k_flags & HOLTEK_FDX)
        !           436:                        outb(inb(ioaddr + 0x20) | 0x80, ioaddr + 0x20);
        !           437:        }
1.1       root      438:        Lei_open(dev);
                    439:        return 0;
                    440: }
                    441: 
1.1.1.2 ! root      442: static int ne2k_pci_close(struct net_device *dev)
1.1       root      443: {
                    444:        Lei_close(dev);
                    445:        free_irq(dev->irq, dev);
                    446:        MOD_DEC_USE_COUNT;
                    447:        return 0;
                    448: }
                    449: 
                    450: /* Hard reset the card.  This used to pause for the same period that a
                    451:    8390 reset command required, but that shouldn't be necessary. */
1.1.1.2 ! root      452: static void ne2k_pci_reset_8390(struct net_device *dev)
1.1       root      453: {
                    454:        unsigned long reset_start_time = jiffies;
                    455: 
                    456:        if (debug > 1) printk("%s: Resetting the 8390 t=%ld...",
                    457:                                                  dev->name, jiffies);
                    458: 
                    459:        outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
                    460: 
                    461:        ei_status.txing = 0;
                    462:        ei_status.dmaing = 0;
                    463: 
                    464:        /* This check _should_not_ be necessary, omit eventually. */
                    465:        while ((inb(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
                    466:                if (jiffies - reset_start_time > 2) {
1.1.1.2 ! root      467:                        printk("%s: ne2k_pci_reset_8390() did not complete.\n", dev->name);
1.1       root      468:                        break;
                    469:                }
                    470:        outb(ENISR_RESET, NE_BASE + EN0_ISR);   /* Ack intr. */
                    471: }
                    472: 
                    473: /* Grab the 8390 specific header. Similar to the block_input routine, but
                    474:    we don't need to be concerned with ring wrap as the header will be at
                    475:    the start of a page, so we optimize accordingly. */
                    476: 
1.1.1.2 ! root      477: static void ne2k_pci_get_8390_hdr(struct net_device *dev,
        !           478:                                                                  struct e8390_pkt_hdr *hdr, int ring_page)
1.1       root      479: {
                    480: 
1.1.1.2 ! root      481:        long nic_base = dev->base_addr;
1.1       root      482: 
                    483:        /* This *shouldn't* happen. If it does, it's the last thing you'll see */
                    484:        if (ei_status.dmaing) {
1.1.1.2 ! root      485:                printk("%s: DMAing conflict in ne2k_pci_get_8390_hdr "
1.1       root      486:                           "[DMAstat:%d][irqlock:%d][intr:%d].\n",
                    487:                           dev->name, ei_status.dmaing, ei_status.irqlock,
1.1.1.2 ! root      488:                           (int)dev->interrupt);
1.1       root      489:                return;
                    490:        }
                    491: 
                    492:        ei_status.dmaing |= 0x01;
                    493:        outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
                    494:        outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
                    495:        outb(0, nic_base + EN0_RCNTHI);
                    496:        outb(0, nic_base + EN0_RSARLO);         /* On page boundary */
                    497:        outb(ring_page, nic_base + EN0_RSARHI);
                    498:        outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
                    499: 
1.1.1.2 ! root      500:        if (ei_status.ne2k_flags & ONLY_16BIT_IO) {
        !           501:                insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
        !           502:        } else {
        !           503:                *(u32*)hdr = le32_to_cpu(inl(NE_BASE + NE_DATAPORT));
        !           504:                le16_to_cpus(&hdr->count);
        !           505:        }
1.1       root      506: 
                    507:        outb(ENISR_RDC, nic_base + EN0_ISR);    /* Ack intr. */
                    508:        ei_status.dmaing &= ~0x01;
                    509: }
                    510: 
                    511: /* Block input and output, similar to the Crynwr packet driver.  If you
                    512:    are porting to a new ethercard, look at the packet driver source for hints.
                    513:    The NEx000 doesn't share the on-board packet memory -- you have to put
                    514:    the packet out through the "remote DMA" dataport using outb. */
                    515: 
1.1.1.2 ! root      516: static void ne2k_pci_block_input(struct net_device *dev, int count,
        !           517:                                                                 struct sk_buff *skb, int ring_offset)
1.1       root      518: {
1.1.1.2 ! root      519:        long nic_base = dev->base_addr;
1.1       root      520:        char *buf = skb->data;
                    521: 
                    522:        /* This *shouldn't* happen. If it does, it's the last thing you'll see */
                    523:        if (ei_status.dmaing) {
1.1.1.2 ! root      524:                printk("%s: DMAing conflict in ne2k_pci_block_input "
1.1       root      525:                           "[DMAstat:%d][irqlock:%d][intr:%d].\n",
                    526:                           dev->name, ei_status.dmaing, ei_status.irqlock,
1.1.1.2 ! root      527:                           (int)dev->interrupt);
1.1       root      528:                return;
                    529:        }
                    530:        ei_status.dmaing |= 0x01;
1.1.1.2 ! root      531:        if (ei_status.ne2k_flags & ONLY_32BIT_IO)
        !           532:                count = (count + 3) & 0xFFFC;
1.1       root      533:        outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
                    534:        outb(count & 0xff, nic_base + EN0_RCNTLO);
                    535:        outb(count >> 8, nic_base + EN0_RCNTHI);
                    536:        outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
                    537:        outb(ring_offset >> 8, nic_base + EN0_RSARHI);
                    538:        outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
                    539: 
1.1.1.2 ! root      540:        if (ei_status.ne2k_flags & ONLY_16BIT_IO) {
        !           541:                insw(NE_BASE + NE_DATAPORT,buf,count>>1);
        !           542:                if (count & 0x01) {
        !           543:                        buf[count-1] = inb(NE_BASE + NE_DATAPORT);
        !           544:                }
        !           545:        } else {
        !           546:                insl(NE_BASE + NE_DATAPORT, buf, count>>2);
        !           547:                if (count & 3) {
        !           548:                        buf += count & ~3;
        !           549:                        if (count & 2) {
        !           550:                                *((u16 *) buf) = le16_to_cpu(inw(NE_BASE + NE_DATAPORT));
        !           551:                                buf = (void *) buf + sizeof (u16);
        !           552:                        }
        !           553:                        if (count & 1)
        !           554:                                *buf = inb(NE_BASE + NE_DATAPORT);
        !           555:                }
1.1       root      556:        }
                    557: 
                    558:        outb(ENISR_RDC, nic_base + EN0_ISR);    /* Ack intr. */
                    559:        ei_status.dmaing &= ~0x01;
                    560: }
                    561: 
                    562: static void
1.1.1.2 ! root      563: ne2k_pci_block_output(struct net_device *dev, int count,
1.1       root      564:                const unsigned char *buf, const int start_page)
                    565: {
                    566:        int nic_base = NE_BASE;
                    567:        unsigned long dma_start;
                    568: 
                    569:        /* On little-endian it's always safe to round the count up for
                    570:           word writes. */
1.1.1.2 ! root      571:        if (ei_status.ne2k_flags & ONLY_32BIT_IO)
        !           572:                count = (count + 3) & 0xFFFC;
        !           573:        else
        !           574:                if (count & 0x01)
        !           575:                        count++;
1.1       root      576: 
                    577:        /* This *shouldn't* happen. If it does, it's the last thing you'll see */
                    578:        if (ei_status.dmaing) {
1.1.1.2 ! root      579:                printk("%s: DMAing conflict in ne2k_pci_block_output."
1.1       root      580:                           "[DMAstat:%d][irqlock:%d][intr:%d]\n",
                    581:                           dev->name, ei_status.dmaing, ei_status.irqlock,
1.1.1.2 ! root      582:                           (int)dev->interrupt);
1.1       root      583:                return;
                    584:        }
                    585:        ei_status.dmaing |= 0x01;
                    586:        /* We should already be in page 0, but to be safe... */
                    587:        outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
                    588: 
                    589: #ifdef NE8390_RW_BUGFIX
                    590:        /* Handle the read-before-write bug the same way as the
                    591:           Crynwr packet driver -- the NatSemi method doesn't work.
                    592:           Actually this doesn't always work either, but if you have
                    593:           problems with your NEx000 this is better than nothing! */
                    594:        outb(0x42, nic_base + EN0_RCNTLO);
                    595:        outb(0x00, nic_base + EN0_RCNTHI);
                    596:        outb(0x42, nic_base + EN0_RSARLO);
                    597:        outb(0x00, nic_base + EN0_RSARHI);
                    598:        outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
                    599: #endif
                    600:        outb(ENISR_RDC, nic_base + EN0_ISR);
                    601: 
                    602:    /* Now the normal output. */
                    603:        outb(count & 0xff, nic_base + EN0_RCNTLO);
                    604:        outb(count >> 8,   nic_base + EN0_RCNTHI);
                    605:        outb(0x00, nic_base + EN0_RSARLO);
                    606:        outb(start_page, nic_base + EN0_RSARHI);
                    607:        outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
1.1.1.2 ! root      608:        if (ei_status.ne2k_flags & ONLY_16BIT_IO) {
        !           609:                outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
        !           610:        } else {
        !           611:                outsl(NE_BASE + NE_DATAPORT, buf, count>>2);
        !           612:                if (count & 3) {
        !           613:                        buf += count & ~3;
        !           614:                        if (count & 2) {
        !           615:                                outw(cpu_to_le16(*((u16 *) buf)), NE_BASE + NE_DATAPORT);
        !           616:                                buf = (void *) buf + sizeof (u16);
        !           617:                        }
        !           618:                }
1.1       root      619:        }
                    620: 
                    621:        dma_start = jiffies;
                    622: 
                    623:        while ((inb(nic_base + EN0_ISR) & ENISR_RDC) == 0)
                    624:                if (jiffies - dma_start > 2) {                  /* Avoid clock roll-over. */
                    625:                        printk("%s: timeout waiting for Tx RDC.\n", dev->name);
1.1.1.2 ! root      626:                        ne2k_pci_reset_8390(dev);
1.1       root      627:                        LNS8390_init(dev,1);
                    628:                        break;
                    629:                }
                    630: 
                    631:        outb(ENISR_RDC, nic_base + EN0_ISR);    /* Ack intr. */
                    632:        ei_status.dmaing &= ~0x01;
                    633:        return;
                    634: }
                    635: 
                    636: 
                    637: /*
                    638:  * Local variables:
1.1.1.2 ! root      639:  *  compile-command: "gcc -DMODULE -Wall -Wstrict-prototypes -O6 -c ne2k-pci.c  -I/usr/src/linux/drivers/net/"
        !           640:  *  alt-compile-command: "gcc -DMODULE -O6 -c ne2k-pci.c"
1.1       root      641:  *  c-indent-level: 4
                    642:  *  c-basic-offset: 4
                    643:  *  tab-width: 4
                    644:  *  version-control: t
                    645:  *  kept-new-versions: 5
                    646:  * End:
                    647:  */

unix.superglobalmegacorp.com

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