1644570b8SJeff Kirsher /* ne2k-pci.c: A NE2000 clone on PCI bus driver for Linux. */ 2644570b8SJeff Kirsher /* 3644570b8SJeff Kirsher A Linux device driver for PCI NE2000 clones. 4644570b8SJeff Kirsher 5644570b8SJeff Kirsher Authors and other copyright holders: 6644570b8SJeff Kirsher 1992-2000 by Donald Becker, NE2000 core and various modifications. 7644570b8SJeff Kirsher 1995-1998 by Paul Gortmaker, core modifications and PCI support. 8644570b8SJeff Kirsher Copyright 1993 assigned to the United States Government as represented 9644570b8SJeff Kirsher by the Director, National Security Agency. 10644570b8SJeff Kirsher 11644570b8SJeff Kirsher This software may be used and distributed according to the terms of 12644570b8SJeff Kirsher the GNU General Public License (GPL), incorporated herein by reference. 13644570b8SJeff Kirsher Drivers based on or derived from this code fall under the GPL and must 14644570b8SJeff Kirsher retain the authorship, copyright and license notice. This file is not 15644570b8SJeff Kirsher a complete program and may only be used when the entire operating 16644570b8SJeff Kirsher system is licensed under the GPL. 17644570b8SJeff Kirsher 18644570b8SJeff Kirsher The author may be reached as becker@scyld.com, or C/O 19644570b8SJeff Kirsher Scyld Computing Corporation 20644570b8SJeff Kirsher 410 Severn Ave., Suite 210 21644570b8SJeff Kirsher Annapolis MD 21403 22644570b8SJeff Kirsher 23644570b8SJeff Kirsher Issues remaining: 24644570b8SJeff Kirsher People are making PCI ne2000 clones! Oh the horror, the horror... 25644570b8SJeff Kirsher Limited full-duplex support. 26644570b8SJeff Kirsher */ 27644570b8SJeff Kirsher 28644570b8SJeff Kirsher #define DRV_NAME "ne2k-pci" 29644570b8SJeff Kirsher #define DRV_VERSION "1.03" 30644570b8SJeff Kirsher #define DRV_RELDATE "9/22/2003" 31644570b8SJeff Kirsher 32644570b8SJeff Kirsher 33644570b8SJeff Kirsher /* The user-configurable values. 34644570b8SJeff Kirsher These may be modified when a driver module is loaded.*/ 35644570b8SJeff Kirsher 36644570b8SJeff Kirsher #define MAX_UNITS 8 /* More are supported, limit only on options */ 37644570b8SJeff Kirsher /* Used to pass the full-duplex flag, etc. */ 38644570b8SJeff Kirsher static int full_duplex[MAX_UNITS]; 39644570b8SJeff Kirsher static int options[MAX_UNITS]; 40644570b8SJeff Kirsher 41644570b8SJeff Kirsher /* Force a non std. amount of memory. Units are 256 byte pages. */ 42644570b8SJeff Kirsher /* #define PACKETBUF_MEMSIZE 0x40 */ 43644570b8SJeff Kirsher 44644570b8SJeff Kirsher 45644570b8SJeff Kirsher #include <linux/module.h> 46644570b8SJeff Kirsher #include <linux/kernel.h> 47644570b8SJeff Kirsher #include <linux/errno.h> 48644570b8SJeff Kirsher #include <linux/pci.h> 49644570b8SJeff Kirsher #include <linux/init.h> 50644570b8SJeff Kirsher #include <linux/interrupt.h> 51644570b8SJeff Kirsher #include <linux/ethtool.h> 52644570b8SJeff Kirsher #include <linux/netdevice.h> 53644570b8SJeff Kirsher #include <linux/etherdevice.h> 54644570b8SJeff Kirsher 55644570b8SJeff Kirsher #include <asm/io.h> 56644570b8SJeff Kirsher #include <asm/irq.h> 577c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 58644570b8SJeff Kirsher 59644570b8SJeff Kirsher #include "8390.h" 60644570b8SJeff Kirsher 61c45f812fSMatthew Whitehead static u32 ne2k_msg_enable; 62c45f812fSMatthew Whitehead 63644570b8SJeff Kirsher /* These identify the driver base version and may not be removed. */ 644168ac0eSBill Pemberton static const char version[] = 65644570b8SJeff Kirsher KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE 66644570b8SJeff Kirsher " D. Becker/P. Gortmaker\n"; 67644570b8SJeff Kirsher 68644570b8SJeff Kirsher #if defined(__powerpc__) 69644570b8SJeff Kirsher #define inl_le(addr) le32_to_cpu(inl(addr)) 70644570b8SJeff Kirsher #define inw_le(addr) le16_to_cpu(inw(addr)) 71644570b8SJeff Kirsher #endif 72644570b8SJeff Kirsher 73644570b8SJeff Kirsher #define PFX DRV_NAME ": " 74644570b8SJeff Kirsher 75644570b8SJeff Kirsher MODULE_AUTHOR("Donald Becker / Paul Gortmaker"); 76644570b8SJeff Kirsher MODULE_DESCRIPTION("PCI NE2000 clone driver"); 77644570b8SJeff Kirsher MODULE_LICENSE("GPL"); 78644570b8SJeff Kirsher 79c45f812fSMatthew Whitehead module_param_named(msg_enable, ne2k_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH)); 80644570b8SJeff Kirsher module_param_array(options, int, NULL, 0); 81644570b8SJeff Kirsher module_param_array(full_duplex, int, NULL, 0); 82c45f812fSMatthew Whitehead MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)"); 83644570b8SJeff Kirsher MODULE_PARM_DESC(options, "Bit 5: full duplex"); 84644570b8SJeff Kirsher MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)"); 85644570b8SJeff Kirsher 86644570b8SJeff Kirsher /* Some defines that people can play with if so inclined. */ 87644570b8SJeff Kirsher 88644570b8SJeff Kirsher /* Use 32 bit data-movement operations instead of 16 bit. */ 89644570b8SJeff Kirsher #define USE_LONGIO 90644570b8SJeff Kirsher 91644570b8SJeff Kirsher /* Do we implement the read before write bugfix ? */ 92644570b8SJeff Kirsher /* #define NE_RW_BUGFIX */ 93644570b8SJeff Kirsher 94644570b8SJeff Kirsher /* Flags. We rename an existing ei_status field to store flags! */ 95644570b8SJeff Kirsher /* Thus only the low 8 bits are usable for non-init-time flags. */ 96644570b8SJeff Kirsher #define ne2k_flags reg0 97644570b8SJeff Kirsher enum { 98644570b8SJeff Kirsher ONLY_16BIT_IO=8, ONLY_32BIT_IO=4, /* Chip can do only 16/32-bit xfers. */ 99644570b8SJeff Kirsher FORCE_FDX=0x20, /* User override. */ 100644570b8SJeff Kirsher REALTEK_FDX=0x40, HOLTEK_FDX=0x80, 101644570b8SJeff Kirsher STOP_PG_0x60=0x100, 102644570b8SJeff Kirsher }; 103644570b8SJeff Kirsher 104644570b8SJeff Kirsher enum ne2k_pci_chipsets { 105644570b8SJeff Kirsher CH_RealTek_RTL_8029 = 0, 106644570b8SJeff Kirsher CH_Winbond_89C940, 107644570b8SJeff Kirsher CH_Compex_RL2000, 108644570b8SJeff Kirsher CH_KTI_ET32P2, 109644570b8SJeff Kirsher CH_NetVin_NV5000SC, 110644570b8SJeff Kirsher CH_Via_86C926, 111644570b8SJeff Kirsher CH_SureCom_NE34, 112644570b8SJeff Kirsher CH_Winbond_W89C940F, 113644570b8SJeff Kirsher CH_Holtek_HT80232, 114644570b8SJeff Kirsher CH_Holtek_HT80229, 115644570b8SJeff Kirsher CH_Winbond_89C940_8c4a, 116644570b8SJeff Kirsher }; 117644570b8SJeff Kirsher 118644570b8SJeff Kirsher 119644570b8SJeff Kirsher static struct { 120644570b8SJeff Kirsher char *name; 121644570b8SJeff Kirsher int flags; 1224168ac0eSBill Pemberton } pci_clone_list[] = { 123644570b8SJeff Kirsher {"RealTek RTL-8029", REALTEK_FDX}, 124644570b8SJeff Kirsher {"Winbond 89C940", 0}, 125644570b8SJeff Kirsher {"Compex RL2000", 0}, 126644570b8SJeff Kirsher {"KTI ET32P2", 0}, 127644570b8SJeff Kirsher {"NetVin NV5000SC", 0}, 128644570b8SJeff Kirsher {"Via 86C926", ONLY_16BIT_IO}, 129644570b8SJeff Kirsher {"SureCom NE34", 0}, 130644570b8SJeff Kirsher {"Winbond W89C940F", 0}, 131644570b8SJeff Kirsher {"Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX}, 132644570b8SJeff Kirsher {"Holtek HT80229", ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 }, 133644570b8SJeff Kirsher {"Winbond W89C940(misprogrammed)", 0}, 134644570b8SJeff Kirsher {NULL,} 135644570b8SJeff Kirsher }; 136644570b8SJeff Kirsher 137644570b8SJeff Kirsher 1389baa3c34SBenoit Taine static const struct pci_device_id ne2k_pci_tbl[] = { 139644570b8SJeff Kirsher { 0x10ec, 0x8029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RealTek_RTL_8029 }, 140644570b8SJeff Kirsher { 0x1050, 0x0940, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940 }, 141644570b8SJeff Kirsher { 0x11f6, 0x1401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Compex_RL2000 }, 142644570b8SJeff Kirsher { 0x8e2e, 0x3000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_KTI_ET32P2 }, 143644570b8SJeff Kirsher { 0x4a14, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_NetVin_NV5000SC }, 144644570b8SJeff Kirsher { 0x1106, 0x0926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Via_86C926 }, 145644570b8SJeff Kirsher { 0x10bd, 0x0e34, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_SureCom_NE34 }, 146644570b8SJeff Kirsher { 0x1050, 0x5a5a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_W89C940F }, 147644570b8SJeff Kirsher { 0x12c3, 0x0058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80232 }, 148644570b8SJeff Kirsher { 0x12c3, 0x5598, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80229 }, 149644570b8SJeff Kirsher { 0x8c4a, 0x1980, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940_8c4a }, 150644570b8SJeff Kirsher { 0, } 151644570b8SJeff Kirsher }; 152644570b8SJeff Kirsher MODULE_DEVICE_TABLE(pci, ne2k_pci_tbl); 153644570b8SJeff Kirsher 154644570b8SJeff Kirsher 155644570b8SJeff Kirsher /* ---- No user-serviceable parts below ---- */ 156644570b8SJeff Kirsher 157644570b8SJeff Kirsher #define NE_BASE (dev->base_addr) 158644570b8SJeff Kirsher #define NE_CMD 0x00 159644570b8SJeff Kirsher #define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ 160644570b8SJeff Kirsher #define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ 161644570b8SJeff Kirsher #define NE_IO_EXTENT 0x20 162644570b8SJeff Kirsher 163644570b8SJeff Kirsher #define NESM_START_PG 0x40 /* First page of TX buffer */ 164644570b8SJeff Kirsher #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ 165644570b8SJeff Kirsher 166644570b8SJeff Kirsher 167644570b8SJeff Kirsher static int ne2k_pci_open(struct net_device *dev); 168644570b8SJeff Kirsher static int ne2k_pci_close(struct net_device *dev); 169644570b8SJeff Kirsher 170644570b8SJeff Kirsher static void ne2k_pci_reset_8390(struct net_device *dev); 171644570b8SJeff Kirsher static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, 172644570b8SJeff Kirsher int ring_page); 173644570b8SJeff Kirsher static void ne2k_pci_block_input(struct net_device *dev, int count, 174644570b8SJeff Kirsher struct sk_buff *skb, int ring_offset); 175644570b8SJeff Kirsher static void ne2k_pci_block_output(struct net_device *dev, const int count, 176644570b8SJeff Kirsher const unsigned char *buf, const int start_page); 177644570b8SJeff Kirsher static const struct ethtool_ops ne2k_pci_ethtool_ops; 178644570b8SJeff Kirsher 179644570b8SJeff Kirsher 180644570b8SJeff Kirsher 181644570b8SJeff Kirsher /* There is no room in the standard 8390 structure for extra info we need, 182644570b8SJeff Kirsher so we build a meta/outer-wrapper structure.. */ 183644570b8SJeff Kirsher struct ne2k_pci_card { 184644570b8SJeff Kirsher struct net_device *dev; 185644570b8SJeff Kirsher struct pci_dev *pci_dev; 186644570b8SJeff Kirsher }; 187644570b8SJeff Kirsher 188644570b8SJeff Kirsher 189644570b8SJeff Kirsher 190644570b8SJeff Kirsher /* 191644570b8SJeff Kirsher NEx000-clone boards have a Station Address (SA) PROM (SAPROM) in the packet 192644570b8SJeff Kirsher buffer memory space. By-the-spec NE2000 clones have 0x57,0x57 in bytes 193644570b8SJeff Kirsher 0x0e,0x0f of the SAPROM, while other supposed NE2000 clones must be 194644570b8SJeff Kirsher detected by their SA prefix. 195644570b8SJeff Kirsher 196644570b8SJeff Kirsher Reading the SAPROM from a word-wide card with the 8390 set in byte-wide 197644570b8SJeff Kirsher mode results in doubled values, which can be detected and compensated for. 198644570b8SJeff Kirsher 199644570b8SJeff Kirsher The probe is also responsible for initializing the card and filling 200644570b8SJeff Kirsher in the 'dev' and 'ei_status' structures. 201644570b8SJeff Kirsher */ 202644570b8SJeff Kirsher 203644570b8SJeff Kirsher static const struct net_device_ops ne2k_netdev_ops = { 204644570b8SJeff Kirsher .ndo_open = ne2k_pci_open, 205644570b8SJeff Kirsher .ndo_stop = ne2k_pci_close, 206644570b8SJeff Kirsher .ndo_start_xmit = ei_start_xmit, 207644570b8SJeff Kirsher .ndo_tx_timeout = ei_tx_timeout, 208644570b8SJeff Kirsher .ndo_get_stats = ei_get_stats, 209afc4b13dSJiri Pirko .ndo_set_rx_mode = ei_set_multicast_list, 210644570b8SJeff Kirsher .ndo_validate_addr = eth_validate_addr, 211644570b8SJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 212644570b8SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 213644570b8SJeff Kirsher .ndo_poll_controller = ei_poll, 214644570b8SJeff Kirsher #endif 215644570b8SJeff Kirsher }; 216644570b8SJeff Kirsher 2174168ac0eSBill Pemberton static int ne2k_pci_init_one(struct pci_dev *pdev, 218644570b8SJeff Kirsher const struct pci_device_id *ent) 219644570b8SJeff Kirsher { 220644570b8SJeff Kirsher struct net_device *dev; 221644570b8SJeff Kirsher int i; 222644570b8SJeff Kirsher unsigned char SA_prom[32]; 223644570b8SJeff Kirsher int start_page, stop_page; 224644570b8SJeff Kirsher int irq, reg0, chip_idx = ent->driver_data; 225644570b8SJeff Kirsher static unsigned int fnd_cnt; 226644570b8SJeff Kirsher long ioaddr; 227644570b8SJeff Kirsher int flags = pci_clone_list[chip_idx].flags; 228c45f812fSMatthew Whitehead struct ei_device *ei_local; 229644570b8SJeff Kirsher 230644570b8SJeff Kirsher /* when built into the kernel, we only print version if device is found */ 231644570b8SJeff Kirsher #ifndef MODULE 232644570b8SJeff Kirsher static int printed_version; 233644570b8SJeff Kirsher if (!printed_version++) 234644570b8SJeff Kirsher printk(version); 235644570b8SJeff Kirsher #endif 236644570b8SJeff Kirsher 237644570b8SJeff Kirsher fnd_cnt++; 238644570b8SJeff Kirsher 239644570b8SJeff Kirsher i = pci_enable_device (pdev); 240644570b8SJeff Kirsher if (i) 241644570b8SJeff Kirsher return i; 242644570b8SJeff Kirsher 243644570b8SJeff Kirsher ioaddr = pci_resource_start (pdev, 0); 244644570b8SJeff Kirsher irq = pdev->irq; 245644570b8SJeff Kirsher 246644570b8SJeff Kirsher if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) { 247644570b8SJeff Kirsher dev_err(&pdev->dev, "no I/O resource at PCI BAR #0\n"); 248eb69c5bfSJia-Ju Bai goto err_out; 249644570b8SJeff Kirsher } 250644570b8SJeff Kirsher 251644570b8SJeff Kirsher if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) { 252644570b8SJeff Kirsher dev_err(&pdev->dev, "I/O resource 0x%x @ 0x%lx busy\n", 253644570b8SJeff Kirsher NE_IO_EXTENT, ioaddr); 254eb69c5bfSJia-Ju Bai goto err_out; 255644570b8SJeff Kirsher } 256644570b8SJeff Kirsher 257644570b8SJeff Kirsher reg0 = inb(ioaddr); 258644570b8SJeff Kirsher if (reg0 == 0xFF) 259644570b8SJeff Kirsher goto err_out_free_res; 260644570b8SJeff Kirsher 261644570b8SJeff Kirsher /* Do a preliminary verification that we have a 8390. */ 262644570b8SJeff Kirsher { 263644570b8SJeff Kirsher int regd; 264644570b8SJeff Kirsher outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); 265644570b8SJeff Kirsher regd = inb(ioaddr + 0x0d); 266644570b8SJeff Kirsher outb(0xff, ioaddr + 0x0d); 267644570b8SJeff Kirsher outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); 268644570b8SJeff Kirsher inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ 269644570b8SJeff Kirsher if (inb(ioaddr + EN0_COUNTER0) != 0) { 270644570b8SJeff Kirsher outb(reg0, ioaddr); 271644570b8SJeff Kirsher outb(regd, ioaddr + 0x0d); /* Restore the old values. */ 272644570b8SJeff Kirsher goto err_out_free_res; 273644570b8SJeff Kirsher } 274644570b8SJeff Kirsher } 275644570b8SJeff Kirsher 276644570b8SJeff Kirsher /* Allocate net_device, dev->priv; fill in 8390 specific dev fields. */ 277644570b8SJeff Kirsher dev = alloc_ei_netdev(); 278644570b8SJeff Kirsher if (!dev) { 279644570b8SJeff Kirsher dev_err(&pdev->dev, "cannot allocate ethernet device\n"); 280644570b8SJeff Kirsher goto err_out_free_res; 281644570b8SJeff Kirsher } 282644570b8SJeff Kirsher dev->netdev_ops = &ne2k_netdev_ops; 283c45f812fSMatthew Whitehead ei_local = netdev_priv(dev); 284c45f812fSMatthew Whitehead ei_local->msg_enable = ne2k_msg_enable; 285644570b8SJeff Kirsher 286644570b8SJeff Kirsher SET_NETDEV_DEV(dev, &pdev->dev); 287644570b8SJeff Kirsher 288644570b8SJeff Kirsher /* Reset card. Who knows what dain-bramaged state it was left in. */ 289644570b8SJeff Kirsher { 290644570b8SJeff Kirsher unsigned long reset_start_time = jiffies; 291644570b8SJeff Kirsher 292644570b8SJeff Kirsher outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); 293644570b8SJeff Kirsher 294644570b8SJeff Kirsher /* This looks like a horrible timing loop, but it should never take 295644570b8SJeff Kirsher more than a few cycles. 296644570b8SJeff Kirsher */ 297644570b8SJeff Kirsher while ((inb(ioaddr + EN0_ISR) & ENISR_RESET) == 0) 298644570b8SJeff Kirsher /* Limit wait: '2' avoids jiffy roll-over. */ 299644570b8SJeff Kirsher if (jiffies - reset_start_time > 2) { 300644570b8SJeff Kirsher dev_err(&pdev->dev, 301644570b8SJeff Kirsher "Card failure (no reset ack).\n"); 302644570b8SJeff Kirsher goto err_out_free_netdev; 303644570b8SJeff Kirsher } 304644570b8SJeff Kirsher 305644570b8SJeff Kirsher outb(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ 306644570b8SJeff Kirsher } 307644570b8SJeff Kirsher 308644570b8SJeff Kirsher /* Read the 16 bytes of station address PROM. 309644570b8SJeff Kirsher We must first initialize registers, similar to NS8390_init(eifdev, 0). 310644570b8SJeff Kirsher We can't reliably read the SAPROM address without this. 311644570b8SJeff Kirsher (I learned the hard way!). */ 312644570b8SJeff Kirsher { 313644570b8SJeff Kirsher struct {unsigned char value, offset; } program_seq[] = { 314644570b8SJeff Kirsher {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ 315644570b8SJeff Kirsher {0x49, EN0_DCFG}, /* Set word-wide access. */ 316644570b8SJeff Kirsher {0x00, EN0_RCNTLO}, /* Clear the count regs. */ 317644570b8SJeff Kirsher {0x00, EN0_RCNTHI}, 318644570b8SJeff Kirsher {0x00, EN0_IMR}, /* Mask completion irq. */ 319644570b8SJeff Kirsher {0xFF, EN0_ISR}, 320644570b8SJeff Kirsher {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ 321644570b8SJeff Kirsher {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ 322644570b8SJeff Kirsher {32, EN0_RCNTLO}, 323644570b8SJeff Kirsher {0x00, EN0_RCNTHI}, 324644570b8SJeff Kirsher {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ 325644570b8SJeff Kirsher {0x00, EN0_RSARHI}, 326644570b8SJeff Kirsher {E8390_RREAD+E8390_START, E8390_CMD}, 327644570b8SJeff Kirsher }; 328644570b8SJeff Kirsher for (i = 0; i < ARRAY_SIZE(program_seq); i++) 329644570b8SJeff Kirsher outb(program_seq[i].value, ioaddr + program_seq[i].offset); 330644570b8SJeff Kirsher 331644570b8SJeff Kirsher } 332644570b8SJeff Kirsher 333644570b8SJeff Kirsher /* Note: all PCI cards have at least 16 bit access, so we don't have 334644570b8SJeff Kirsher to check for 8 bit cards. Most cards permit 32 bit access. */ 335644570b8SJeff Kirsher if (flags & ONLY_32BIT_IO) { 336644570b8SJeff Kirsher for (i = 0; i < 4 ; i++) 337644570b8SJeff Kirsher ((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT)); 338644570b8SJeff Kirsher } else 339644570b8SJeff Kirsher for(i = 0; i < 32 /*sizeof(SA_prom)*/; i++) 340644570b8SJeff Kirsher SA_prom[i] = inb(ioaddr + NE_DATAPORT); 341644570b8SJeff Kirsher 342644570b8SJeff Kirsher /* We always set the 8390 registers for word mode. */ 343644570b8SJeff Kirsher outb(0x49, ioaddr + EN0_DCFG); 344644570b8SJeff Kirsher start_page = NESM_START_PG; 345644570b8SJeff Kirsher 346644570b8SJeff Kirsher stop_page = flags & STOP_PG_0x60 ? 0x60 : NESM_STOP_PG; 347644570b8SJeff Kirsher 348644570b8SJeff Kirsher /* Set up the rest of the parameters. */ 349644570b8SJeff Kirsher dev->irq = irq; 350644570b8SJeff Kirsher dev->base_addr = ioaddr; 351644570b8SJeff Kirsher pci_set_drvdata(pdev, dev); 352644570b8SJeff Kirsher 353644570b8SJeff Kirsher ei_status.name = pci_clone_list[chip_idx].name; 354644570b8SJeff Kirsher ei_status.tx_start_page = start_page; 355644570b8SJeff Kirsher ei_status.stop_page = stop_page; 356644570b8SJeff Kirsher ei_status.word16 = 1; 357644570b8SJeff Kirsher ei_status.ne2k_flags = flags; 358644570b8SJeff Kirsher if (fnd_cnt < MAX_UNITS) { 359644570b8SJeff Kirsher if (full_duplex[fnd_cnt] > 0 || (options[fnd_cnt] & FORCE_FDX)) 360644570b8SJeff Kirsher ei_status.ne2k_flags |= FORCE_FDX; 361644570b8SJeff Kirsher } 362644570b8SJeff Kirsher 363644570b8SJeff Kirsher ei_status.rx_start_page = start_page + TX_PAGES; 364644570b8SJeff Kirsher #ifdef PACKETBUF_MEMSIZE 365644570b8SJeff Kirsher /* Allow the packet buffer size to be overridden by know-it-alls. */ 366644570b8SJeff Kirsher ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; 367644570b8SJeff Kirsher #endif 368644570b8SJeff Kirsher 369644570b8SJeff Kirsher ei_status.reset_8390 = &ne2k_pci_reset_8390; 370644570b8SJeff Kirsher ei_status.block_input = &ne2k_pci_block_input; 371644570b8SJeff Kirsher ei_status.block_output = &ne2k_pci_block_output; 372644570b8SJeff Kirsher ei_status.get_8390_hdr = &ne2k_pci_get_8390_hdr; 373644570b8SJeff Kirsher ei_status.priv = (unsigned long) pdev; 374644570b8SJeff Kirsher 375644570b8SJeff Kirsher dev->ethtool_ops = &ne2k_pci_ethtool_ops; 376644570b8SJeff Kirsher NS8390_init(dev, 0); 377644570b8SJeff Kirsher 378644570b8SJeff Kirsher memcpy(dev->dev_addr, SA_prom, dev->addr_len); 379644570b8SJeff Kirsher 380644570b8SJeff Kirsher i = register_netdev(dev); 381644570b8SJeff Kirsher if (i) 382644570b8SJeff Kirsher goto err_out_free_netdev; 383644570b8SJeff Kirsher 384c45f812fSMatthew Whitehead netdev_info(dev, "%s found at %#lx, IRQ %d, %pM.\n", 385c45f812fSMatthew Whitehead pci_clone_list[chip_idx].name, ioaddr, dev->irq, 386644570b8SJeff Kirsher dev->dev_addr); 387644570b8SJeff Kirsher 388644570b8SJeff Kirsher return 0; 389644570b8SJeff Kirsher 390644570b8SJeff Kirsher err_out_free_netdev: 391644570b8SJeff Kirsher free_netdev (dev); 392644570b8SJeff Kirsher err_out_free_res: 393644570b8SJeff Kirsher release_region (ioaddr, NE_IO_EXTENT); 394eb69c5bfSJia-Ju Bai err_out: 395eb69c5bfSJia-Ju Bai pci_disable_device(pdev); 396644570b8SJeff Kirsher return -ENODEV; 397644570b8SJeff Kirsher } 398644570b8SJeff Kirsher 399644570b8SJeff Kirsher /* 400644570b8SJeff Kirsher * Magic incantation sequence for full duplex on the supported cards. 401644570b8SJeff Kirsher */ 402644570b8SJeff Kirsher static inline int set_realtek_fdx(struct net_device *dev) 403644570b8SJeff Kirsher { 404644570b8SJeff Kirsher long ioaddr = dev->base_addr; 405644570b8SJeff Kirsher 406644570b8SJeff Kirsher outb(0xC0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 3 */ 407644570b8SJeff Kirsher outb(0xC0, ioaddr + 0x01); /* Enable writes to CONFIG3 */ 408644570b8SJeff Kirsher outb(0x40, ioaddr + 0x06); /* Enable full duplex */ 409644570b8SJeff Kirsher outb(0x00, ioaddr + 0x01); /* Disable writes to CONFIG3 */ 410644570b8SJeff Kirsher outb(E8390_PAGE0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 0 */ 411644570b8SJeff Kirsher return 0; 412644570b8SJeff Kirsher } 413644570b8SJeff Kirsher 414644570b8SJeff Kirsher static inline int set_holtek_fdx(struct net_device *dev) 415644570b8SJeff Kirsher { 416644570b8SJeff Kirsher long ioaddr = dev->base_addr; 417644570b8SJeff Kirsher 418644570b8SJeff Kirsher outb(inb(ioaddr + 0x20) | 0x80, ioaddr + 0x20); 419644570b8SJeff Kirsher return 0; 420644570b8SJeff Kirsher } 421644570b8SJeff Kirsher 422644570b8SJeff Kirsher static int ne2k_pci_set_fdx(struct net_device *dev) 423644570b8SJeff Kirsher { 424644570b8SJeff Kirsher if (ei_status.ne2k_flags & REALTEK_FDX) 425644570b8SJeff Kirsher return set_realtek_fdx(dev); 426644570b8SJeff Kirsher else if (ei_status.ne2k_flags & HOLTEK_FDX) 427644570b8SJeff Kirsher return set_holtek_fdx(dev); 428644570b8SJeff Kirsher 429644570b8SJeff Kirsher return -EOPNOTSUPP; 430644570b8SJeff Kirsher } 431644570b8SJeff Kirsher 432644570b8SJeff Kirsher static int ne2k_pci_open(struct net_device *dev) 433644570b8SJeff Kirsher { 434644570b8SJeff Kirsher int ret = request_irq(dev->irq, ei_interrupt, IRQF_SHARED, dev->name, dev); 435644570b8SJeff Kirsher if (ret) 436644570b8SJeff Kirsher return ret; 437644570b8SJeff Kirsher 438644570b8SJeff Kirsher if (ei_status.ne2k_flags & FORCE_FDX) 439644570b8SJeff Kirsher ne2k_pci_set_fdx(dev); 440644570b8SJeff Kirsher 441644570b8SJeff Kirsher ei_open(dev); 442644570b8SJeff Kirsher return 0; 443644570b8SJeff Kirsher } 444644570b8SJeff Kirsher 445644570b8SJeff Kirsher static int ne2k_pci_close(struct net_device *dev) 446644570b8SJeff Kirsher { 447644570b8SJeff Kirsher ei_close(dev); 448644570b8SJeff Kirsher free_irq(dev->irq, dev); 449644570b8SJeff Kirsher return 0; 450644570b8SJeff Kirsher } 451644570b8SJeff Kirsher 452644570b8SJeff Kirsher /* Hard reset the card. This used to pause for the same period that a 453644570b8SJeff Kirsher 8390 reset command required, but that shouldn't be necessary. */ 454644570b8SJeff Kirsher static void ne2k_pci_reset_8390(struct net_device *dev) 455644570b8SJeff Kirsher { 456644570b8SJeff Kirsher unsigned long reset_start_time = jiffies; 457c45f812fSMatthew Whitehead struct ei_device *ei_local = netdev_priv(dev); 458644570b8SJeff Kirsher 459c45f812fSMatthew Whitehead netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", 460c45f812fSMatthew Whitehead jiffies); 461644570b8SJeff Kirsher 462644570b8SJeff Kirsher outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); 463644570b8SJeff Kirsher 464644570b8SJeff Kirsher ei_status.txing = 0; 465644570b8SJeff Kirsher ei_status.dmaing = 0; 466644570b8SJeff Kirsher 467644570b8SJeff Kirsher /* This check _should_not_ be necessary, omit eventually. */ 468644570b8SJeff Kirsher while ((inb(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) 469644570b8SJeff Kirsher if (jiffies - reset_start_time > 2) { 470c45f812fSMatthew Whitehead netdev_err(dev, "ne2k_pci_reset_8390() did not complete.\n"); 471644570b8SJeff Kirsher break; 472644570b8SJeff Kirsher } 473644570b8SJeff Kirsher outb(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ 474644570b8SJeff Kirsher } 475644570b8SJeff Kirsher 476644570b8SJeff Kirsher /* Grab the 8390 specific header. Similar to the block_input routine, but 477644570b8SJeff Kirsher we don't need to be concerned with ring wrap as the header will be at 478644570b8SJeff Kirsher the start of a page, so we optimize accordingly. */ 479644570b8SJeff Kirsher 480644570b8SJeff Kirsher static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) 481644570b8SJeff Kirsher { 482644570b8SJeff Kirsher 483644570b8SJeff Kirsher long nic_base = dev->base_addr; 484644570b8SJeff Kirsher 485644570b8SJeff Kirsher /* This *shouldn't* happen. If it does, it's the last thing you'll see */ 486644570b8SJeff Kirsher if (ei_status.dmaing) { 487c45f812fSMatthew Whitehead netdev_err(dev, "DMAing conflict in ne2k_pci_get_8390_hdr " 488644570b8SJeff Kirsher "[DMAstat:%d][irqlock:%d].\n", 489c45f812fSMatthew Whitehead ei_status.dmaing, ei_status.irqlock); 490644570b8SJeff Kirsher return; 491644570b8SJeff Kirsher } 492644570b8SJeff Kirsher 493644570b8SJeff Kirsher ei_status.dmaing |= 0x01; 494644570b8SJeff Kirsher outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); 495644570b8SJeff Kirsher outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); 496644570b8SJeff Kirsher outb(0, nic_base + EN0_RCNTHI); 497644570b8SJeff Kirsher outb(0, nic_base + EN0_RSARLO); /* On page boundary */ 498644570b8SJeff Kirsher outb(ring_page, nic_base + EN0_RSARHI); 499644570b8SJeff Kirsher outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); 500644570b8SJeff Kirsher 501644570b8SJeff Kirsher if (ei_status.ne2k_flags & ONLY_16BIT_IO) { 502644570b8SJeff Kirsher insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); 503644570b8SJeff Kirsher } else { 504644570b8SJeff Kirsher *(u32*)hdr = le32_to_cpu(inl(NE_BASE + NE_DATAPORT)); 505644570b8SJeff Kirsher le16_to_cpus(&hdr->count); 506644570b8SJeff Kirsher } 507644570b8SJeff Kirsher 508644570b8SJeff Kirsher outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ 509644570b8SJeff Kirsher ei_status.dmaing &= ~0x01; 510644570b8SJeff Kirsher } 511644570b8SJeff Kirsher 512644570b8SJeff Kirsher /* Block input and output, similar to the Crynwr packet driver. If you 513644570b8SJeff Kirsher are porting to a new ethercard, look at the packet driver source for hints. 514644570b8SJeff Kirsher The NEx000 doesn't share the on-board packet memory -- you have to put 515644570b8SJeff Kirsher the packet out through the "remote DMA" dataport using outb. */ 516644570b8SJeff Kirsher 517644570b8SJeff Kirsher static void ne2k_pci_block_input(struct net_device *dev, int count, 518644570b8SJeff Kirsher struct sk_buff *skb, int ring_offset) 519644570b8SJeff Kirsher { 520644570b8SJeff Kirsher long nic_base = dev->base_addr; 521644570b8SJeff Kirsher char *buf = skb->data; 522644570b8SJeff Kirsher 523644570b8SJeff Kirsher /* This *shouldn't* happen. If it does, it's the last thing you'll see */ 524644570b8SJeff Kirsher if (ei_status.dmaing) { 525c45f812fSMatthew Whitehead netdev_err(dev, "DMAing conflict in ne2k_pci_block_input " 526644570b8SJeff Kirsher "[DMAstat:%d][irqlock:%d].\n", 527c45f812fSMatthew Whitehead ei_status.dmaing, ei_status.irqlock); 528644570b8SJeff Kirsher return; 529644570b8SJeff Kirsher } 530644570b8SJeff Kirsher ei_status.dmaing |= 0x01; 531644570b8SJeff Kirsher if (ei_status.ne2k_flags & ONLY_32BIT_IO) 532644570b8SJeff Kirsher count = (count + 3) & 0xFFFC; 533644570b8SJeff Kirsher outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); 534644570b8SJeff Kirsher outb(count & 0xff, nic_base + EN0_RCNTLO); 535644570b8SJeff Kirsher outb(count >> 8, nic_base + EN0_RCNTHI); 536644570b8SJeff Kirsher outb(ring_offset & 0xff, nic_base + EN0_RSARLO); 537644570b8SJeff Kirsher outb(ring_offset >> 8, nic_base + EN0_RSARHI); 538644570b8SJeff Kirsher outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); 539644570b8SJeff Kirsher 540644570b8SJeff Kirsher if (ei_status.ne2k_flags & ONLY_16BIT_IO) { 541644570b8SJeff Kirsher insw(NE_BASE + NE_DATAPORT,buf,count>>1); 542644570b8SJeff Kirsher if (count & 0x01) { 543644570b8SJeff Kirsher buf[count-1] = inb(NE_BASE + NE_DATAPORT); 544644570b8SJeff Kirsher } 545644570b8SJeff Kirsher } else { 546644570b8SJeff Kirsher insl(NE_BASE + NE_DATAPORT, buf, count>>2); 547644570b8SJeff Kirsher if (count & 3) { 548644570b8SJeff Kirsher buf += count & ~3; 549644570b8SJeff Kirsher if (count & 2) { 550644570b8SJeff Kirsher __le16 *b = (__le16 *)buf; 551644570b8SJeff Kirsher 552644570b8SJeff Kirsher *b++ = cpu_to_le16(inw(NE_BASE + NE_DATAPORT)); 553644570b8SJeff Kirsher buf = (char *)b; 554644570b8SJeff Kirsher } 555644570b8SJeff Kirsher if (count & 1) 556644570b8SJeff Kirsher *buf = inb(NE_BASE + NE_DATAPORT); 557644570b8SJeff Kirsher } 558644570b8SJeff Kirsher } 559644570b8SJeff Kirsher 560644570b8SJeff Kirsher outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ 561644570b8SJeff Kirsher ei_status.dmaing &= ~0x01; 562644570b8SJeff Kirsher } 563644570b8SJeff Kirsher 564644570b8SJeff Kirsher static void ne2k_pci_block_output(struct net_device *dev, int count, 565644570b8SJeff Kirsher const unsigned char *buf, const int start_page) 566644570b8SJeff Kirsher { 567644570b8SJeff Kirsher long nic_base = NE_BASE; 568644570b8SJeff Kirsher unsigned long dma_start; 569644570b8SJeff Kirsher 570644570b8SJeff Kirsher /* On little-endian it's always safe to round the count up for 571644570b8SJeff Kirsher word writes. */ 572644570b8SJeff Kirsher if (ei_status.ne2k_flags & ONLY_32BIT_IO) 573644570b8SJeff Kirsher count = (count + 3) & 0xFFFC; 574644570b8SJeff Kirsher else 575644570b8SJeff Kirsher if (count & 0x01) 576644570b8SJeff Kirsher count++; 577644570b8SJeff Kirsher 578644570b8SJeff Kirsher /* This *shouldn't* happen. If it does, it's the last thing you'll see */ 579644570b8SJeff Kirsher if (ei_status.dmaing) { 580c45f812fSMatthew Whitehead netdev_err(dev, "DMAing conflict in ne2k_pci_block_output." 581644570b8SJeff Kirsher "[DMAstat:%d][irqlock:%d]\n", 582c45f812fSMatthew Whitehead ei_status.dmaing, ei_status.irqlock); 583644570b8SJeff Kirsher return; 584644570b8SJeff Kirsher } 585644570b8SJeff Kirsher ei_status.dmaing |= 0x01; 586644570b8SJeff Kirsher /* We should already be in page 0, but to be safe... */ 587644570b8SJeff Kirsher outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); 588644570b8SJeff Kirsher 589644570b8SJeff Kirsher #ifdef NE8390_RW_BUGFIX 590644570b8SJeff Kirsher /* Handle the read-before-write bug the same way as the 591644570b8SJeff Kirsher Crynwr packet driver -- the NatSemi method doesn't work. 592644570b8SJeff Kirsher Actually this doesn't always work either, but if you have 593644570b8SJeff Kirsher problems with your NEx000 this is better than nothing! */ 594644570b8SJeff Kirsher outb(0x42, nic_base + EN0_RCNTLO); 595644570b8SJeff Kirsher outb(0x00, nic_base + EN0_RCNTHI); 596644570b8SJeff Kirsher outb(0x42, nic_base + EN0_RSARLO); 597644570b8SJeff Kirsher outb(0x00, nic_base + EN0_RSARHI); 598644570b8SJeff Kirsher outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); 599644570b8SJeff Kirsher #endif 600644570b8SJeff Kirsher outb(ENISR_RDC, nic_base + EN0_ISR); 601644570b8SJeff Kirsher 602644570b8SJeff Kirsher /* Now the normal output. */ 603644570b8SJeff Kirsher outb(count & 0xff, nic_base + EN0_RCNTLO); 604644570b8SJeff Kirsher outb(count >> 8, nic_base + EN0_RCNTHI); 605644570b8SJeff Kirsher outb(0x00, nic_base + EN0_RSARLO); 606644570b8SJeff Kirsher outb(start_page, nic_base + EN0_RSARHI); 607644570b8SJeff Kirsher outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); 608644570b8SJeff Kirsher if (ei_status.ne2k_flags & ONLY_16BIT_IO) { 609644570b8SJeff Kirsher outsw(NE_BASE + NE_DATAPORT, buf, count>>1); 610644570b8SJeff Kirsher } else { 611644570b8SJeff Kirsher outsl(NE_BASE + NE_DATAPORT, buf, count>>2); 612644570b8SJeff Kirsher if (count & 3) { 613644570b8SJeff Kirsher buf += count & ~3; 614644570b8SJeff Kirsher if (count & 2) { 615644570b8SJeff Kirsher __le16 *b = (__le16 *)buf; 616644570b8SJeff Kirsher 617644570b8SJeff Kirsher outw(le16_to_cpu(*b++), NE_BASE + NE_DATAPORT); 618644570b8SJeff Kirsher buf = (char *)b; 619644570b8SJeff Kirsher } 620644570b8SJeff Kirsher } 621644570b8SJeff Kirsher } 622644570b8SJeff Kirsher 623644570b8SJeff Kirsher dma_start = jiffies; 624644570b8SJeff Kirsher 625644570b8SJeff Kirsher while ((inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) 626644570b8SJeff Kirsher if (jiffies - dma_start > 2) { /* Avoid clock roll-over. */ 627c45f812fSMatthew Whitehead netdev_warn(dev, "timeout waiting for Tx RDC.\n"); 628644570b8SJeff Kirsher ne2k_pci_reset_8390(dev); 629644570b8SJeff Kirsher NS8390_init(dev,1); 630644570b8SJeff Kirsher break; 631644570b8SJeff Kirsher } 632644570b8SJeff Kirsher 633644570b8SJeff Kirsher outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ 634644570b8SJeff Kirsher ei_status.dmaing &= ~0x01; 635644570b8SJeff Kirsher } 636644570b8SJeff Kirsher 637644570b8SJeff Kirsher static void ne2k_pci_get_drvinfo(struct net_device *dev, 638644570b8SJeff Kirsher struct ethtool_drvinfo *info) 639644570b8SJeff Kirsher { 640644570b8SJeff Kirsher struct ei_device *ei = netdev_priv(dev); 641644570b8SJeff Kirsher struct pci_dev *pci_dev = (struct pci_dev *) ei->priv; 642644570b8SJeff Kirsher 64368aad78cSRick Jones strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); 64468aad78cSRick Jones strlcpy(info->version, DRV_VERSION, sizeof(info->version)); 64568aad78cSRick Jones strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); 646644570b8SJeff Kirsher } 647644570b8SJeff Kirsher 648c45f812fSMatthew Whitehead static u32 ne2k_pci_get_msglevel(struct net_device *dev) 649c45f812fSMatthew Whitehead { 650c45f812fSMatthew Whitehead struct ei_device *ei_local = netdev_priv(dev); 651c45f812fSMatthew Whitehead 652c45f812fSMatthew Whitehead return ei_local->msg_enable; 653c45f812fSMatthew Whitehead } 654c45f812fSMatthew Whitehead 655c45f812fSMatthew Whitehead static void ne2k_pci_set_msglevel(struct net_device *dev, u32 v) 656c45f812fSMatthew Whitehead { 657c45f812fSMatthew Whitehead struct ei_device *ei_local = netdev_priv(dev); 658c45f812fSMatthew Whitehead 659c45f812fSMatthew Whitehead ei_local->msg_enable = v; 660c45f812fSMatthew Whitehead } 661c45f812fSMatthew Whitehead 662644570b8SJeff Kirsher static const struct ethtool_ops ne2k_pci_ethtool_ops = { 663644570b8SJeff Kirsher .get_drvinfo = ne2k_pci_get_drvinfo, 664c45f812fSMatthew Whitehead .get_msglevel = ne2k_pci_get_msglevel, 665c45f812fSMatthew Whitehead .set_msglevel = ne2k_pci_set_msglevel, 666644570b8SJeff Kirsher }; 667644570b8SJeff Kirsher 6684168ac0eSBill Pemberton static void ne2k_pci_remove_one(struct pci_dev *pdev) 669644570b8SJeff Kirsher { 670644570b8SJeff Kirsher struct net_device *dev = pci_get_drvdata(pdev); 671644570b8SJeff Kirsher 672644570b8SJeff Kirsher BUG_ON(!dev); 673644570b8SJeff Kirsher unregister_netdev(dev); 674644570b8SJeff Kirsher release_region(dev->base_addr, NE_IO_EXTENT); 675644570b8SJeff Kirsher free_netdev(dev); 676644570b8SJeff Kirsher pci_disable_device(pdev); 677644570b8SJeff Kirsher } 678644570b8SJeff Kirsher 679644570b8SJeff Kirsher #ifdef CONFIG_PM 680644570b8SJeff Kirsher static int ne2k_pci_suspend (struct pci_dev *pdev, pm_message_t state) 681644570b8SJeff Kirsher { 682644570b8SJeff Kirsher struct net_device *dev = pci_get_drvdata (pdev); 683644570b8SJeff Kirsher 684644570b8SJeff Kirsher netif_device_detach(dev); 685644570b8SJeff Kirsher pci_save_state(pdev); 686644570b8SJeff Kirsher pci_disable_device(pdev); 687644570b8SJeff Kirsher pci_set_power_state(pdev, pci_choose_state(pdev, state)); 688644570b8SJeff Kirsher 689644570b8SJeff Kirsher return 0; 690644570b8SJeff Kirsher } 691644570b8SJeff Kirsher 692644570b8SJeff Kirsher static int ne2k_pci_resume (struct pci_dev *pdev) 693644570b8SJeff Kirsher { 694644570b8SJeff Kirsher struct net_device *dev = pci_get_drvdata (pdev); 695644570b8SJeff Kirsher int rc; 696644570b8SJeff Kirsher 6971ca01512SYijing Wang pci_set_power_state(pdev, PCI_D0); 698644570b8SJeff Kirsher pci_restore_state(pdev); 699644570b8SJeff Kirsher 700644570b8SJeff Kirsher rc = pci_enable_device(pdev); 701644570b8SJeff Kirsher if (rc) 702644570b8SJeff Kirsher return rc; 703644570b8SJeff Kirsher 704644570b8SJeff Kirsher NS8390_init(dev, 1); 705644570b8SJeff Kirsher netif_device_attach(dev); 706644570b8SJeff Kirsher 707644570b8SJeff Kirsher return 0; 708644570b8SJeff Kirsher } 709644570b8SJeff Kirsher 710644570b8SJeff Kirsher #endif /* CONFIG_PM */ 711644570b8SJeff Kirsher 712644570b8SJeff Kirsher 713644570b8SJeff Kirsher static struct pci_driver ne2k_driver = { 714644570b8SJeff Kirsher .name = DRV_NAME, 715644570b8SJeff Kirsher .probe = ne2k_pci_init_one, 7164168ac0eSBill Pemberton .remove = ne2k_pci_remove_one, 717644570b8SJeff Kirsher .id_table = ne2k_pci_tbl, 718644570b8SJeff Kirsher #ifdef CONFIG_PM 719644570b8SJeff Kirsher .suspend = ne2k_pci_suspend, 720644570b8SJeff Kirsher .resume = ne2k_pci_resume, 721644570b8SJeff Kirsher #endif /* CONFIG_PM */ 722644570b8SJeff Kirsher 723644570b8SJeff Kirsher }; 724644570b8SJeff Kirsher 725644570b8SJeff Kirsher 726644570b8SJeff Kirsher static int __init ne2k_pci_init(void) 727644570b8SJeff Kirsher { 728644570b8SJeff Kirsher /* when a module, this is printed whether or not devices are found in probe */ 729644570b8SJeff Kirsher #ifdef MODULE 730644570b8SJeff Kirsher printk(version); 731644570b8SJeff Kirsher #endif 732644570b8SJeff Kirsher return pci_register_driver(&ne2k_driver); 733644570b8SJeff Kirsher } 734644570b8SJeff Kirsher 735644570b8SJeff Kirsher 736644570b8SJeff Kirsher static void __exit ne2k_pci_cleanup(void) 737644570b8SJeff Kirsher { 738644570b8SJeff Kirsher pci_unregister_driver (&ne2k_driver); 739644570b8SJeff Kirsher } 740644570b8SJeff Kirsher 741644570b8SJeff Kirsher module_init(ne2k_pci_init); 742644570b8SJeff Kirsher module_exit(ne2k_pci_cleanup); 743