1644570b8SJeff Kirsher /* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */ 2644570b8SJeff Kirsher /* 3644570b8SJeff Kirsher Written 1992-94 by Donald Becker. 4644570b8SJeff Kirsher 5644570b8SJeff Kirsher Copyright 1993 United States Government as represented by the 6644570b8SJeff Kirsher Director, National Security Agency. 7644570b8SJeff Kirsher 8644570b8SJeff Kirsher This software may be used and distributed according to the terms 9644570b8SJeff Kirsher of the GNU General Public License, incorporated herein by reference. 10644570b8SJeff Kirsher 11644570b8SJeff Kirsher The author may be reached as becker@scyld.com, or C/O 12644570b8SJeff Kirsher Scyld Computing Corporation, 410 Severn Ave., Suite 210, Annapolis MD 21403 13644570b8SJeff Kirsher 14644570b8SJeff Kirsher This driver should work with many programmed-I/O 8390-based ethernet 15644570b8SJeff Kirsher boards. Currently it supports the NE1000, NE2000, many clones, 16644570b8SJeff Kirsher and some Cabletron products. 17644570b8SJeff Kirsher 18644570b8SJeff Kirsher Changelog: 19644570b8SJeff Kirsher 20644570b8SJeff Kirsher Paul Gortmaker : use ENISR_RDC to monitor Tx PIO uploads, made 21644570b8SJeff Kirsher sanity checks and bad clone support optional. 22644570b8SJeff Kirsher Paul Gortmaker : new reset code, reset card after probe at boot. 23644570b8SJeff Kirsher Paul Gortmaker : multiple card support for module users. 24644570b8SJeff Kirsher Paul Gortmaker : Support for PCI ne2k clones, similar to lance.c 25644570b8SJeff Kirsher Paul Gortmaker : Allow users with bad cards to avoid full probe. 26644570b8SJeff Kirsher Paul Gortmaker : PCI probe changes, more PCI cards supported. 27644570b8SJeff Kirsher rjohnson@analogic.com : Changed init order so an interrupt will only 28644570b8SJeff Kirsher occur after memory is allocated for dev->priv. Deallocated memory 29644570b8SJeff Kirsher last in cleanup_modue() 30644570b8SJeff Kirsher Richard Guenther : Added support for ISAPnP cards 31644570b8SJeff Kirsher Paul Gortmaker : Discontinued PCI support - use ne2k-pci.c instead. 32644570b8SJeff Kirsher Hayato Fujiwara : Add m32r support. 33644570b8SJeff Kirsher 34644570b8SJeff Kirsher */ 35644570b8SJeff Kirsher 36644570b8SJeff Kirsher /* Routines for the NatSemi-based designs (NE[12]000). */ 37644570b8SJeff Kirsher 38644570b8SJeff Kirsher static const char version1[] = 39644570b8SJeff Kirsher "ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)\n"; 40644570b8SJeff Kirsher static const char version2[] = 41644570b8SJeff Kirsher "Last modified Nov 1, 2000 by Paul Gortmaker\n"; 42644570b8SJeff Kirsher 43644570b8SJeff Kirsher 44644570b8SJeff Kirsher #include <linux/module.h> 45644570b8SJeff Kirsher #include <linux/kernel.h> 46644570b8SJeff Kirsher #include <linux/errno.h> 47644570b8SJeff Kirsher #include <linux/isapnp.h> 48644570b8SJeff Kirsher #include <linux/init.h> 49644570b8SJeff Kirsher #include <linux/interrupt.h> 50644570b8SJeff Kirsher #include <linux/delay.h> 51644570b8SJeff Kirsher #include <linux/netdevice.h> 52644570b8SJeff Kirsher #include <linux/etherdevice.h> 53644570b8SJeff Kirsher #include <linux/jiffies.h> 54644570b8SJeff Kirsher #include <linux/platform_device.h> 55644570b8SJeff Kirsher 56644570b8SJeff Kirsher #include <asm/io.h> 57644570b8SJeff Kirsher 58644570b8SJeff Kirsher #include "8390.h" 59644570b8SJeff Kirsher 60644570b8SJeff Kirsher #define DRV_NAME "ne" 61644570b8SJeff Kirsher 62644570b8SJeff Kirsher /* Some defines that people can play with if so inclined. */ 63644570b8SJeff Kirsher 64644570b8SJeff Kirsher /* Do we support clones that don't adhere to 14,15 of the SAprom ? */ 65644570b8SJeff Kirsher #define SUPPORT_NE_BAD_CLONES 66644570b8SJeff Kirsher /* 0xbad = bad sig or no reset ack */ 67644570b8SJeff Kirsher #define BAD 0xbad 68644570b8SJeff Kirsher 69644570b8SJeff Kirsher #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ 70644570b8SJeff Kirsher static struct platform_device *pdev_ne[MAX_NE_CARDS]; 71644570b8SJeff Kirsher static int io[MAX_NE_CARDS]; 72644570b8SJeff Kirsher static int irq[MAX_NE_CARDS]; 73644570b8SJeff Kirsher static int bad[MAX_NE_CARDS]; 74644570b8SJeff Kirsher 75644570b8SJeff Kirsher #ifdef MODULE 76644570b8SJeff Kirsher module_param_array(io, int, NULL, 0); 77644570b8SJeff Kirsher module_param_array(irq, int, NULL, 0); 78644570b8SJeff Kirsher module_param_array(bad, int, NULL, 0); 79644570b8SJeff Kirsher MODULE_PARM_DESC(io, "I/O base address(es),required"); 80644570b8SJeff Kirsher MODULE_PARM_DESC(irq, "IRQ number(s)"); 81644570b8SJeff Kirsher MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures"); 82644570b8SJeff Kirsher MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver"); 83644570b8SJeff Kirsher MODULE_LICENSE("GPL"); 84644570b8SJeff Kirsher #endif /* MODULE */ 85644570b8SJeff Kirsher 86644570b8SJeff Kirsher /* Do we perform extra sanity checks on stuff ? */ 87644570b8SJeff Kirsher /* #define NE_SANITY_CHECK */ 88644570b8SJeff Kirsher 89644570b8SJeff Kirsher /* Do we implement the read before write bugfix ? */ 90644570b8SJeff Kirsher /* #define NE_RW_BUGFIX */ 91644570b8SJeff Kirsher 92644570b8SJeff Kirsher /* Do we have a non std. amount of memory? (in units of 256 byte pages) */ 93644570b8SJeff Kirsher /* #define PACKETBUF_MEMSIZE 0x40 */ 94644570b8SJeff Kirsher 95644570b8SJeff Kirsher /* This is set up so that no ISA autoprobe takes place. We can't guarantee 96644570b8SJeff Kirsher that the ne2k probe is the last 8390 based probe to take place (as it 97644570b8SJeff Kirsher is at boot) and so the probe will get confused by any other 8390 cards. 98644570b8SJeff Kirsher ISA device autoprobes on a running machine are not recommended anyway. */ 99644570b8SJeff Kirsher #if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R)) 100644570b8SJeff Kirsher /* Do we need a portlist for the ISA auto-probe ? */ 101644570b8SJeff Kirsher #define NEEDS_PORTLIST 102644570b8SJeff Kirsher #endif 103644570b8SJeff Kirsher 104644570b8SJeff Kirsher /* A zero-terminated list of I/O addresses to be probed at boot. */ 105644570b8SJeff Kirsher #ifdef NEEDS_PORTLIST 106644570b8SJeff Kirsher static unsigned int netcard_portlist[] __initdata = { 107644570b8SJeff Kirsher 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0 108644570b8SJeff Kirsher }; 109644570b8SJeff Kirsher #endif 110644570b8SJeff Kirsher 111644570b8SJeff Kirsher static struct isapnp_device_id isapnp_clone_list[] __initdata = { 112644570b8SJeff Kirsher { ISAPNP_CARD_ID('A','X','E',0x2011), 113644570b8SJeff Kirsher ISAPNP_VENDOR('A','X','E'), ISAPNP_FUNCTION(0x2011), 114644570b8SJeff Kirsher (long) "NetGear EA201" }, 115644570b8SJeff Kirsher { ISAPNP_ANY_ID, ISAPNP_ANY_ID, 116644570b8SJeff Kirsher ISAPNP_VENDOR('E','D','I'), ISAPNP_FUNCTION(0x0216), 117644570b8SJeff Kirsher (long) "NN NE2000" }, 118644570b8SJeff Kirsher { ISAPNP_ANY_ID, ISAPNP_ANY_ID, 119644570b8SJeff Kirsher ISAPNP_VENDOR('P','N','P'), ISAPNP_FUNCTION(0x80d6), 120644570b8SJeff Kirsher (long) "Generic PNP" }, 121644570b8SJeff Kirsher { } /* terminate list */ 122644570b8SJeff Kirsher }; 123644570b8SJeff Kirsher 124644570b8SJeff Kirsher MODULE_DEVICE_TABLE(isapnp, isapnp_clone_list); 125644570b8SJeff Kirsher 126644570b8SJeff Kirsher #ifdef SUPPORT_NE_BAD_CLONES 127644570b8SJeff Kirsher /* A list of bad clones that we none-the-less recognize. */ 128644570b8SJeff Kirsher static struct { const char *name8, *name16; unsigned char SAprefix[4];} 129644570b8SJeff Kirsher bad_clone_list[] __initdata = { 130644570b8SJeff Kirsher {"DE100", "DE200", {0x00, 0xDE, 0x01,}}, 131644570b8SJeff Kirsher {"DE120", "DE220", {0x00, 0x80, 0xc8,}}, 132644570b8SJeff Kirsher {"DFI1000", "DFI2000", {'D', 'F', 'I',}}, /* Original, eh? */ 133644570b8SJeff Kirsher {"EtherNext UTP8", "EtherNext UTP16", {0x00, 0x00, 0x79}}, 134644570b8SJeff Kirsher {"NE1000","NE2000-invalid", {0x00, 0x00, 0xd8}}, /* Ancient real NE1000. */ 135644570b8SJeff Kirsher {"NN1000", "NN2000", {0x08, 0x03, 0x08}}, /* Outlaw no-name clone. */ 136644570b8SJeff Kirsher {"4-DIM8","4-DIM16", {0x00,0x00,0x4d,}}, /* Outlaw 4-Dimension cards. */ 137644570b8SJeff Kirsher {"Con-Intl_8", "Con-Intl_16", {0x00, 0x00, 0x24}}, /* Connect Int'nl */ 138644570b8SJeff Kirsher {"ET-100","ET-200", {0x00, 0x45, 0x54}}, /* YANG and YA clone */ 139644570b8SJeff Kirsher {"COMPEX","COMPEX16",{0x00,0x80,0x48}}, /* Broken ISA Compex cards */ 140644570b8SJeff Kirsher {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ 141644570b8SJeff Kirsher {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ 142644570b8SJeff Kirsher {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ 143644570b8SJeff Kirsher #ifdef CONFIG_MACH_TX49XX 144644570b8SJeff Kirsher {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ 145644570b8SJeff Kirsher #endif 146644570b8SJeff Kirsher {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ 147644570b8SJeff Kirsher {NULL,} 148644570b8SJeff Kirsher }; 149644570b8SJeff Kirsher #endif 150644570b8SJeff Kirsher 151644570b8SJeff Kirsher /* ---- No user-serviceable parts below ---- */ 152644570b8SJeff Kirsher 153644570b8SJeff Kirsher #define NE_BASE (dev->base_addr) 154644570b8SJeff Kirsher #define NE_CMD 0x00 155644570b8SJeff Kirsher #define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ 156644570b8SJeff Kirsher #define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ 157644570b8SJeff Kirsher #define NE_IO_EXTENT 0x20 158644570b8SJeff Kirsher 159644570b8SJeff Kirsher #define NE1SM_START_PG 0x20 /* First page of TX buffer */ 160644570b8SJeff Kirsher #define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ 161644570b8SJeff Kirsher #define NESM_START_PG 0x40 /* First page of TX buffer */ 162644570b8SJeff Kirsher #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ 163644570b8SJeff Kirsher 164644570b8SJeff Kirsher #if defined(CONFIG_PLAT_MAPPI) 165644570b8SJeff Kirsher # define DCR_VAL 0x4b 166644570b8SJeff Kirsher #elif defined(CONFIG_PLAT_OAKS32R) || \ 167644570b8SJeff Kirsher defined(CONFIG_MACH_TX49XX) 168644570b8SJeff Kirsher # define DCR_VAL 0x48 /* 8-bit mode */ 169644570b8SJeff Kirsher #else 170644570b8SJeff Kirsher # define DCR_VAL 0x49 171644570b8SJeff Kirsher #endif 172644570b8SJeff Kirsher 173644570b8SJeff Kirsher static int ne_probe1(struct net_device *dev, unsigned long ioaddr); 174644570b8SJeff Kirsher static int ne_probe_isapnp(struct net_device *dev); 175644570b8SJeff Kirsher 176644570b8SJeff Kirsher static void ne_reset_8390(struct net_device *dev); 177644570b8SJeff Kirsher static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, 178644570b8SJeff Kirsher int ring_page); 179644570b8SJeff Kirsher static void ne_block_input(struct net_device *dev, int count, 180644570b8SJeff Kirsher struct sk_buff *skb, int ring_offset); 181644570b8SJeff Kirsher static void ne_block_output(struct net_device *dev, const int count, 182644570b8SJeff Kirsher const unsigned char *buf, const int start_page); 183644570b8SJeff Kirsher 184644570b8SJeff Kirsher 185644570b8SJeff Kirsher /* Probe for various non-shared-memory ethercards. 186644570b8SJeff Kirsher 187644570b8SJeff Kirsher NEx000-clone boards have a Station Address PROM (SAPROM) in the packet 188644570b8SJeff Kirsher buffer memory space. NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of 189644570b8SJeff Kirsher the SAPROM, while other supposed NE2000 clones must be detected by their 190644570b8SJeff Kirsher SA prefix. 191644570b8SJeff Kirsher 192644570b8SJeff Kirsher Reading the SAPROM from a word-wide card with the 8390 set in byte-wide 193644570b8SJeff Kirsher mode results in doubled values, which can be detected and compensated for. 194644570b8SJeff Kirsher 195644570b8SJeff Kirsher The probe is also responsible for initializing the card and filling 196644570b8SJeff Kirsher in the 'dev' and 'ei_status' structures. 197644570b8SJeff Kirsher 198644570b8SJeff Kirsher We use the minimum memory size for some ethercard product lines, iff we can't 199644570b8SJeff Kirsher distinguish models. You can increase the packet buffer size by setting 200644570b8SJeff Kirsher PACKETBUF_MEMSIZE. Reported Cabletron packet buffer locations are: 201644570b8SJeff Kirsher E1010 starts at 0x100 and ends at 0x2000. 202644570b8SJeff Kirsher E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory") 203644570b8SJeff Kirsher E2010 starts at 0x100 and ends at 0x4000. 204644570b8SJeff Kirsher E2010-x starts at 0x100 and ends at 0xffff. */ 205644570b8SJeff Kirsher 206644570b8SJeff Kirsher static int __init do_ne_probe(struct net_device *dev) 207644570b8SJeff Kirsher { 208644570b8SJeff Kirsher unsigned long base_addr = dev->base_addr; 209644570b8SJeff Kirsher #ifdef NEEDS_PORTLIST 210644570b8SJeff Kirsher int orig_irq = dev->irq; 211644570b8SJeff Kirsher #endif 212644570b8SJeff Kirsher 213644570b8SJeff Kirsher /* First check any supplied i/o locations. User knows best. <cough> */ 214644570b8SJeff Kirsher if (base_addr > 0x1ff) { /* Check a single specified location. */ 215644570b8SJeff Kirsher int ret = ne_probe1(dev, base_addr); 216644570b8SJeff Kirsher if (ret) 217644570b8SJeff Kirsher printk(KERN_WARNING "ne.c: No NE*000 card found at " 218644570b8SJeff Kirsher "i/o = %#lx\n", base_addr); 219644570b8SJeff Kirsher return ret; 220644570b8SJeff Kirsher } 221644570b8SJeff Kirsher else if (base_addr != 0) /* Don't probe at all. */ 222644570b8SJeff Kirsher return -ENXIO; 223644570b8SJeff Kirsher 224644570b8SJeff Kirsher /* Then look for any installed ISAPnP clones */ 225644570b8SJeff Kirsher if (isapnp_present() && (ne_probe_isapnp(dev) == 0)) 226644570b8SJeff Kirsher return 0; 227644570b8SJeff Kirsher 228644570b8SJeff Kirsher #ifdef NEEDS_PORTLIST 229644570b8SJeff Kirsher /* Last resort. The semi-risky ISA auto-probe. */ 230644570b8SJeff Kirsher for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) { 231644570b8SJeff Kirsher int ioaddr = netcard_portlist[base_addr]; 232644570b8SJeff Kirsher dev->irq = orig_irq; 233644570b8SJeff Kirsher if (ne_probe1(dev, ioaddr) == 0) 234644570b8SJeff Kirsher return 0; 235644570b8SJeff Kirsher } 236644570b8SJeff Kirsher #endif 237644570b8SJeff Kirsher 238644570b8SJeff Kirsher return -ENODEV; 239644570b8SJeff Kirsher } 240644570b8SJeff Kirsher 241644570b8SJeff Kirsher static int __init ne_probe_isapnp(struct net_device *dev) 242644570b8SJeff Kirsher { 243644570b8SJeff Kirsher int i; 244644570b8SJeff Kirsher 245644570b8SJeff Kirsher for (i = 0; isapnp_clone_list[i].vendor != 0; i++) { 246644570b8SJeff Kirsher struct pnp_dev *idev = NULL; 247644570b8SJeff Kirsher 248644570b8SJeff Kirsher while ((idev = pnp_find_dev(NULL, 249644570b8SJeff Kirsher isapnp_clone_list[i].vendor, 250644570b8SJeff Kirsher isapnp_clone_list[i].function, 251644570b8SJeff Kirsher idev))) { 252644570b8SJeff Kirsher /* Avoid already found cards from previous calls */ 253644570b8SJeff Kirsher if (pnp_device_attach(idev) < 0) 254644570b8SJeff Kirsher continue; 255644570b8SJeff Kirsher if (pnp_activate_dev(idev) < 0) { 256644570b8SJeff Kirsher pnp_device_detach(idev); 257644570b8SJeff Kirsher continue; 258644570b8SJeff Kirsher } 259644570b8SJeff Kirsher /* if no io and irq, search for next */ 260644570b8SJeff Kirsher if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) { 261644570b8SJeff Kirsher pnp_device_detach(idev); 262644570b8SJeff Kirsher continue; 263644570b8SJeff Kirsher } 264644570b8SJeff Kirsher /* found it */ 265644570b8SJeff Kirsher dev->base_addr = pnp_port_start(idev, 0); 266644570b8SJeff Kirsher dev->irq = pnp_irq(idev, 0); 267644570b8SJeff Kirsher printk(KERN_INFO "ne.c: ISAPnP reports %s at i/o %#lx, irq %d.\n", 268644570b8SJeff Kirsher (char *) isapnp_clone_list[i].driver_data, 269644570b8SJeff Kirsher dev->base_addr, dev->irq); 270644570b8SJeff Kirsher if (ne_probe1(dev, dev->base_addr) != 0) { /* Shouldn't happen. */ 271644570b8SJeff Kirsher printk(KERN_ERR "ne.c: Probe of ISAPnP card at %#lx failed.\n", dev->base_addr); 272644570b8SJeff Kirsher pnp_device_detach(idev); 273644570b8SJeff Kirsher return -ENXIO; 274644570b8SJeff Kirsher } 275644570b8SJeff Kirsher ei_status.priv = (unsigned long)idev; 276644570b8SJeff Kirsher break; 277644570b8SJeff Kirsher } 278644570b8SJeff Kirsher if (!idev) 279644570b8SJeff Kirsher continue; 280644570b8SJeff Kirsher return 0; 281644570b8SJeff Kirsher } 282644570b8SJeff Kirsher 283644570b8SJeff Kirsher return -ENODEV; 284644570b8SJeff Kirsher } 285644570b8SJeff Kirsher 286644570b8SJeff Kirsher static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) 287644570b8SJeff Kirsher { 288644570b8SJeff Kirsher int i; 289644570b8SJeff Kirsher unsigned char SA_prom[32]; 290644570b8SJeff Kirsher int wordlength = 2; 291644570b8SJeff Kirsher const char *name = NULL; 292644570b8SJeff Kirsher int start_page, stop_page; 293644570b8SJeff Kirsher int neX000, ctron, copam, bad_card; 294644570b8SJeff Kirsher int reg0, ret; 295644570b8SJeff Kirsher static unsigned version_printed; 296644570b8SJeff Kirsher 297644570b8SJeff Kirsher if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) 298644570b8SJeff Kirsher return -EBUSY; 299644570b8SJeff Kirsher 300644570b8SJeff Kirsher reg0 = inb_p(ioaddr); 301644570b8SJeff Kirsher if (reg0 == 0xFF) { 302644570b8SJeff Kirsher ret = -ENODEV; 303644570b8SJeff Kirsher goto err_out; 304644570b8SJeff Kirsher } 305644570b8SJeff Kirsher 306644570b8SJeff Kirsher /* Do a preliminary verification that we have a 8390. */ 307644570b8SJeff Kirsher { 308644570b8SJeff Kirsher int regd; 309644570b8SJeff Kirsher outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); 310644570b8SJeff Kirsher regd = inb_p(ioaddr + 0x0d); 311644570b8SJeff Kirsher outb_p(0xff, ioaddr + 0x0d); 312644570b8SJeff Kirsher outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); 313644570b8SJeff Kirsher inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ 314644570b8SJeff Kirsher if (inb_p(ioaddr + EN0_COUNTER0) != 0) { 315644570b8SJeff Kirsher outb_p(reg0, ioaddr); 316644570b8SJeff Kirsher outb_p(regd, ioaddr + 0x0d); /* Restore the old values. */ 317644570b8SJeff Kirsher ret = -ENODEV; 318644570b8SJeff Kirsher goto err_out; 319644570b8SJeff Kirsher } 320644570b8SJeff Kirsher } 321644570b8SJeff Kirsher 322644570b8SJeff Kirsher if (ei_debug && version_printed++ == 0) 323644570b8SJeff Kirsher printk(KERN_INFO "%s%s", version1, version2); 324644570b8SJeff Kirsher 325644570b8SJeff Kirsher printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr); 326644570b8SJeff Kirsher 327644570b8SJeff Kirsher /* A user with a poor card that fails to ack the reset, or that 328644570b8SJeff Kirsher does not have a valid 0x57,0x57 signature can still use this 329644570b8SJeff Kirsher without having to recompile. Specifying an i/o address along 330644570b8SJeff Kirsher with an otherwise unused dev->mem_end value of "0xBAD" will 331644570b8SJeff Kirsher cause the driver to skip these parts of the probe. */ 332644570b8SJeff Kirsher 333644570b8SJeff Kirsher bad_card = ((dev->base_addr != 0) && (dev->mem_end == BAD)); 334644570b8SJeff Kirsher 335644570b8SJeff Kirsher /* Reset card. Who knows what dain-bramaged state it was left in. */ 336644570b8SJeff Kirsher 337644570b8SJeff Kirsher { 338644570b8SJeff Kirsher unsigned long reset_start_time = jiffies; 339644570b8SJeff Kirsher 340644570b8SJeff Kirsher /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ 341644570b8SJeff Kirsher outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); 342644570b8SJeff Kirsher 343644570b8SJeff Kirsher while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0) 344644570b8SJeff Kirsher if (time_after(jiffies, reset_start_time + 2*HZ/100)) { 345644570b8SJeff Kirsher if (bad_card) { 346644570b8SJeff Kirsher printk(" (warning: no reset ack)"); 347644570b8SJeff Kirsher break; 348644570b8SJeff Kirsher } else { 349644570b8SJeff Kirsher printk(" not found (no reset ack).\n"); 350644570b8SJeff Kirsher ret = -ENODEV; 351644570b8SJeff Kirsher goto err_out; 352644570b8SJeff Kirsher } 353644570b8SJeff Kirsher } 354644570b8SJeff Kirsher 355644570b8SJeff Kirsher outb_p(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ 356644570b8SJeff Kirsher } 357644570b8SJeff Kirsher 358644570b8SJeff Kirsher /* Read the 16 bytes of station address PROM. 359644570b8SJeff Kirsher We must first initialize registers, similar to NS8390p_init(eifdev, 0). 360644570b8SJeff Kirsher We can't reliably read the SAPROM address without this. 361644570b8SJeff Kirsher (I learned the hard way!). */ 362644570b8SJeff Kirsher { 363644570b8SJeff Kirsher struct {unsigned char value, offset; } program_seq[] = 364644570b8SJeff Kirsher { 365644570b8SJeff Kirsher {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ 366644570b8SJeff Kirsher {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ 367644570b8SJeff Kirsher {0x00, EN0_RCNTLO}, /* Clear the count regs. */ 368644570b8SJeff Kirsher {0x00, EN0_RCNTHI}, 369644570b8SJeff Kirsher {0x00, EN0_IMR}, /* Mask completion irq. */ 370644570b8SJeff Kirsher {0xFF, EN0_ISR}, 371644570b8SJeff Kirsher {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ 372644570b8SJeff Kirsher {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ 373644570b8SJeff Kirsher {32, EN0_RCNTLO}, 374644570b8SJeff Kirsher {0x00, EN0_RCNTHI}, 375644570b8SJeff Kirsher {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ 376644570b8SJeff Kirsher {0x00, EN0_RSARHI}, 377644570b8SJeff Kirsher {E8390_RREAD+E8390_START, E8390_CMD}, 378644570b8SJeff Kirsher }; 379644570b8SJeff Kirsher 380644570b8SJeff Kirsher for (i = 0; i < ARRAY_SIZE(program_seq); i++) 381644570b8SJeff Kirsher outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); 382644570b8SJeff Kirsher 383644570b8SJeff Kirsher } 384644570b8SJeff Kirsher for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) { 385644570b8SJeff Kirsher SA_prom[i] = inb(ioaddr + NE_DATAPORT); 386644570b8SJeff Kirsher SA_prom[i+1] = inb(ioaddr + NE_DATAPORT); 387644570b8SJeff Kirsher if (SA_prom[i] != SA_prom[i+1]) 388644570b8SJeff Kirsher wordlength = 1; 389644570b8SJeff Kirsher } 390644570b8SJeff Kirsher 391644570b8SJeff Kirsher if (wordlength == 2) 392644570b8SJeff Kirsher { 393644570b8SJeff Kirsher for (i = 0; i < 16; i++) 394644570b8SJeff Kirsher SA_prom[i] = SA_prom[i+i]; 395644570b8SJeff Kirsher /* We must set the 8390 for word mode. */ 396644570b8SJeff Kirsher outb_p(DCR_VAL, ioaddr + EN0_DCFG); 397644570b8SJeff Kirsher start_page = NESM_START_PG; 398644570b8SJeff Kirsher 399644570b8SJeff Kirsher /* 400644570b8SJeff Kirsher * Realtek RTL8019AS datasheet says that the PSTOP register 401644570b8SJeff Kirsher * shouldn't exceed 0x60 in 8-bit mode. 402644570b8SJeff Kirsher * This chip can be identified by reading the signature from 403644570b8SJeff Kirsher * the remote byte count registers (otherwise write-only)... 404644570b8SJeff Kirsher */ 405644570b8SJeff Kirsher if ((DCR_VAL & 0x01) == 0 && /* 8-bit mode */ 406644570b8SJeff Kirsher inb(ioaddr + EN0_RCNTLO) == 0x50 && 407644570b8SJeff Kirsher inb(ioaddr + EN0_RCNTHI) == 0x70) 408644570b8SJeff Kirsher stop_page = 0x60; 409644570b8SJeff Kirsher else 410644570b8SJeff Kirsher stop_page = NESM_STOP_PG; 411644570b8SJeff Kirsher } else { 412644570b8SJeff Kirsher start_page = NE1SM_START_PG; 413644570b8SJeff Kirsher stop_page = NE1SM_STOP_PG; 414644570b8SJeff Kirsher } 415644570b8SJeff Kirsher 416644570b8SJeff Kirsher #if defined(CONFIG_PLAT_MAPPI) || defined(CONFIG_PLAT_OAKS32R) 417644570b8SJeff Kirsher neX000 = ((SA_prom[14] == 0x57 && SA_prom[15] == 0x57) 418644570b8SJeff Kirsher || (SA_prom[14] == 0x42 && SA_prom[15] == 0x42)); 419644570b8SJeff Kirsher #else 420644570b8SJeff Kirsher neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); 421644570b8SJeff Kirsher #endif 422644570b8SJeff Kirsher ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d); 423644570b8SJeff Kirsher copam = (SA_prom[14] == 0x49 && SA_prom[15] == 0x00); 424644570b8SJeff Kirsher 425644570b8SJeff Kirsher /* Set up the rest of the parameters. */ 426644570b8SJeff Kirsher if (neX000 || bad_card || copam) { 427644570b8SJeff Kirsher name = (wordlength == 2) ? "NE2000" : "NE1000"; 428644570b8SJeff Kirsher } 429644570b8SJeff Kirsher else if (ctron) 430644570b8SJeff Kirsher { 431644570b8SJeff Kirsher name = (wordlength == 2) ? "Ctron-8" : "Ctron-16"; 432644570b8SJeff Kirsher start_page = 0x01; 433644570b8SJeff Kirsher stop_page = (wordlength == 2) ? 0x40 : 0x20; 434644570b8SJeff Kirsher } 435644570b8SJeff Kirsher else 436644570b8SJeff Kirsher { 437644570b8SJeff Kirsher #ifdef SUPPORT_NE_BAD_CLONES 438644570b8SJeff Kirsher /* Ack! Well, there might be a *bad* NE*000 clone there. 439644570b8SJeff Kirsher Check for total bogus addresses. */ 440644570b8SJeff Kirsher for (i = 0; bad_clone_list[i].name8; i++) 441644570b8SJeff Kirsher { 442644570b8SJeff Kirsher if (SA_prom[0] == bad_clone_list[i].SAprefix[0] && 443644570b8SJeff Kirsher SA_prom[1] == bad_clone_list[i].SAprefix[1] && 444644570b8SJeff Kirsher SA_prom[2] == bad_clone_list[i].SAprefix[2]) 445644570b8SJeff Kirsher { 446644570b8SJeff Kirsher if (wordlength == 2) 447644570b8SJeff Kirsher { 448644570b8SJeff Kirsher name = bad_clone_list[i].name16; 449644570b8SJeff Kirsher } else { 450644570b8SJeff Kirsher name = bad_clone_list[i].name8; 451644570b8SJeff Kirsher } 452644570b8SJeff Kirsher break; 453644570b8SJeff Kirsher } 454644570b8SJeff Kirsher } 455644570b8SJeff Kirsher if (bad_clone_list[i].name8 == NULL) 456644570b8SJeff Kirsher { 457644570b8SJeff Kirsher printk(" not found (invalid signature %2.2x %2.2x).\n", 458644570b8SJeff Kirsher SA_prom[14], SA_prom[15]); 459644570b8SJeff Kirsher ret = -ENXIO; 460644570b8SJeff Kirsher goto err_out; 461644570b8SJeff Kirsher } 462644570b8SJeff Kirsher #else 463644570b8SJeff Kirsher printk(" not found.\n"); 464644570b8SJeff Kirsher ret = -ENXIO; 465644570b8SJeff Kirsher goto err_out; 466644570b8SJeff Kirsher #endif 467644570b8SJeff Kirsher } 468644570b8SJeff Kirsher 469644570b8SJeff Kirsher if (dev->irq < 2) 470644570b8SJeff Kirsher { 471644570b8SJeff Kirsher unsigned long cookie = probe_irq_on(); 472644570b8SJeff Kirsher outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */ 473644570b8SJeff Kirsher outb_p(0x00, ioaddr + EN0_RCNTLO); 474644570b8SJeff Kirsher outb_p(0x00, ioaddr + EN0_RCNTHI); 475644570b8SJeff Kirsher outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */ 476644570b8SJeff Kirsher mdelay(10); /* wait 10ms for interrupt to propagate */ 477644570b8SJeff Kirsher outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */ 478644570b8SJeff Kirsher dev->irq = probe_irq_off(cookie); 479644570b8SJeff Kirsher if (ei_debug > 2) 480644570b8SJeff Kirsher printk(" autoirq is %d\n", dev->irq); 481644570b8SJeff Kirsher } else if (dev->irq == 2) 482644570b8SJeff Kirsher /* Fixup for users that don't know that IRQ 2 is really IRQ 9, 483644570b8SJeff Kirsher or don't know which one to set. */ 484644570b8SJeff Kirsher dev->irq = 9; 485644570b8SJeff Kirsher 486644570b8SJeff Kirsher if (! dev->irq) { 487644570b8SJeff Kirsher printk(" failed to detect IRQ line.\n"); 488644570b8SJeff Kirsher ret = -EAGAIN; 489644570b8SJeff Kirsher goto err_out; 490644570b8SJeff Kirsher } 491644570b8SJeff Kirsher 492644570b8SJeff Kirsher /* Snarf the interrupt now. There's no point in waiting since we cannot 493644570b8SJeff Kirsher share and the board will usually be enabled. */ 494644570b8SJeff Kirsher ret = request_irq(dev->irq, eip_interrupt, 0, name, dev); 495644570b8SJeff Kirsher if (ret) { 496644570b8SJeff Kirsher printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret); 497644570b8SJeff Kirsher goto err_out; 498644570b8SJeff Kirsher } 499644570b8SJeff Kirsher 500644570b8SJeff Kirsher dev->base_addr = ioaddr; 501644570b8SJeff Kirsher 502644570b8SJeff Kirsher #ifdef CONFIG_PLAT_MAPPI 503644570b8SJeff Kirsher outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, 504644570b8SJeff Kirsher ioaddr + E8390_CMD); /* 0x61 */ 505104bf3fbSJoe Perches for (i = 0; i < ETH_ALEN; i++) { 506644570b8SJeff Kirsher dev->dev_addr[i] = SA_prom[i] 507644570b8SJeff Kirsher = inb_p(ioaddr + EN1_PHYS_SHIFT(i)); 508644570b8SJeff Kirsher } 509644570b8SJeff Kirsher #else 510104bf3fbSJoe Perches for (i = 0; i < ETH_ALEN; i++) { 511644570b8SJeff Kirsher dev->dev_addr[i] = SA_prom[i]; 512644570b8SJeff Kirsher } 513644570b8SJeff Kirsher #endif 514644570b8SJeff Kirsher 515644570b8SJeff Kirsher printk("%pM\n", dev->dev_addr); 516644570b8SJeff Kirsher 517644570b8SJeff Kirsher ei_status.name = name; 518644570b8SJeff Kirsher ei_status.tx_start_page = start_page; 519644570b8SJeff Kirsher ei_status.stop_page = stop_page; 520644570b8SJeff Kirsher 521644570b8SJeff Kirsher /* Use 16-bit mode only if this wasn't overridden by DCR_VAL */ 522644570b8SJeff Kirsher ei_status.word16 = (wordlength == 2 && (DCR_VAL & 0x01)); 523644570b8SJeff Kirsher 524644570b8SJeff Kirsher ei_status.rx_start_page = start_page + TX_PAGES; 525644570b8SJeff Kirsher #ifdef PACKETBUF_MEMSIZE 526644570b8SJeff Kirsher /* Allow the packet buffer size to be overridden by know-it-alls. */ 527644570b8SJeff Kirsher ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; 528644570b8SJeff Kirsher #endif 529644570b8SJeff Kirsher 530644570b8SJeff Kirsher ei_status.reset_8390 = &ne_reset_8390; 531644570b8SJeff Kirsher ei_status.block_input = &ne_block_input; 532644570b8SJeff Kirsher ei_status.block_output = &ne_block_output; 533644570b8SJeff Kirsher ei_status.get_8390_hdr = &ne_get_8390_hdr; 534644570b8SJeff Kirsher ei_status.priv = 0; 535644570b8SJeff Kirsher 536644570b8SJeff Kirsher dev->netdev_ops = &eip_netdev_ops; 537644570b8SJeff Kirsher NS8390p_init(dev, 0); 538644570b8SJeff Kirsher 539644570b8SJeff Kirsher ret = register_netdev(dev); 540644570b8SJeff Kirsher if (ret) 541644570b8SJeff Kirsher goto out_irq; 542644570b8SJeff Kirsher printk(KERN_INFO "%s: %s found at %#lx, using IRQ %d.\n", 543644570b8SJeff Kirsher dev->name, name, ioaddr, dev->irq); 544644570b8SJeff Kirsher return 0; 545644570b8SJeff Kirsher 546644570b8SJeff Kirsher out_irq: 547644570b8SJeff Kirsher free_irq(dev->irq, dev); 548644570b8SJeff Kirsher err_out: 549644570b8SJeff Kirsher release_region(ioaddr, NE_IO_EXTENT); 550644570b8SJeff Kirsher return ret; 551644570b8SJeff Kirsher } 552644570b8SJeff Kirsher 553644570b8SJeff Kirsher /* Hard reset the card. This used to pause for the same period that a 554644570b8SJeff Kirsher 8390 reset command required, but that shouldn't be necessary. */ 555644570b8SJeff Kirsher 556644570b8SJeff Kirsher static void ne_reset_8390(struct net_device *dev) 557644570b8SJeff Kirsher { 558644570b8SJeff Kirsher unsigned long reset_start_time = jiffies; 559644570b8SJeff Kirsher 560644570b8SJeff Kirsher if (ei_debug > 1) 561644570b8SJeff Kirsher printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies); 562644570b8SJeff Kirsher 563644570b8SJeff Kirsher /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ 564644570b8SJeff Kirsher outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); 565644570b8SJeff Kirsher 566644570b8SJeff Kirsher ei_status.txing = 0; 567644570b8SJeff Kirsher ei_status.dmaing = 0; 568644570b8SJeff Kirsher 569644570b8SJeff Kirsher /* This check _should_not_ be necessary, omit eventually. */ 570644570b8SJeff Kirsher while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) 571644570b8SJeff Kirsher if (time_after(jiffies, reset_start_time + 2*HZ/100)) { 572644570b8SJeff Kirsher printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); 573644570b8SJeff Kirsher break; 574644570b8SJeff Kirsher } 575644570b8SJeff Kirsher outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ 576644570b8SJeff Kirsher } 577644570b8SJeff Kirsher 578644570b8SJeff Kirsher /* Grab the 8390 specific header. Similar to the block_input routine, but 579644570b8SJeff Kirsher we don't need to be concerned with ring wrap as the header will be at 580644570b8SJeff Kirsher the start of a page, so we optimize accordingly. */ 581644570b8SJeff Kirsher 582644570b8SJeff Kirsher static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) 583644570b8SJeff Kirsher { 584644570b8SJeff Kirsher int nic_base = dev->base_addr; 585644570b8SJeff Kirsher 586644570b8SJeff Kirsher /* This *shouldn't* happen. If it does, it's the last thing you'll see */ 587644570b8SJeff Kirsher 588644570b8SJeff Kirsher if (ei_status.dmaing) 589644570b8SJeff Kirsher { 590644570b8SJeff Kirsher printk(KERN_EMERG "%s: DMAing conflict in ne_get_8390_hdr " 591644570b8SJeff Kirsher "[DMAstat:%d][irqlock:%d].\n", 592644570b8SJeff Kirsher dev->name, ei_status.dmaing, ei_status.irqlock); 593644570b8SJeff Kirsher return; 594644570b8SJeff Kirsher } 595644570b8SJeff Kirsher 596644570b8SJeff Kirsher ei_status.dmaing |= 0x01; 597644570b8SJeff Kirsher outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); 598644570b8SJeff Kirsher outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); 599644570b8SJeff Kirsher outb_p(0, nic_base + EN0_RCNTHI); 600644570b8SJeff Kirsher outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ 601644570b8SJeff Kirsher outb_p(ring_page, nic_base + EN0_RSARHI); 602644570b8SJeff Kirsher outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); 603644570b8SJeff Kirsher 604644570b8SJeff Kirsher if (ei_status.word16) 605644570b8SJeff Kirsher insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); 606644570b8SJeff Kirsher else 607644570b8SJeff Kirsher insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)); 608644570b8SJeff Kirsher 609644570b8SJeff Kirsher outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ 610644570b8SJeff Kirsher ei_status.dmaing &= ~0x01; 611644570b8SJeff Kirsher 612644570b8SJeff Kirsher le16_to_cpus(&hdr->count); 613644570b8SJeff Kirsher } 614644570b8SJeff Kirsher 615644570b8SJeff Kirsher /* Block input and output, similar to the Crynwr packet driver. If you 616644570b8SJeff Kirsher are porting to a new ethercard, look at the packet driver source for hints. 617644570b8SJeff Kirsher The NEx000 doesn't share the on-board packet memory -- you have to put 618644570b8SJeff Kirsher the packet out through the "remote DMA" dataport using outb. */ 619644570b8SJeff Kirsher 620644570b8SJeff Kirsher static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) 621644570b8SJeff Kirsher { 622644570b8SJeff Kirsher #ifdef NE_SANITY_CHECK 623644570b8SJeff Kirsher int xfer_count = count; 624644570b8SJeff Kirsher #endif 625644570b8SJeff Kirsher int nic_base = dev->base_addr; 626644570b8SJeff Kirsher char *buf = skb->data; 627644570b8SJeff Kirsher 628644570b8SJeff Kirsher /* This *shouldn't* happen. If it does, it's the last thing you'll see */ 629644570b8SJeff Kirsher if (ei_status.dmaing) 630644570b8SJeff Kirsher { 631644570b8SJeff Kirsher printk(KERN_EMERG "%s: DMAing conflict in ne_block_input " 632644570b8SJeff Kirsher "[DMAstat:%d][irqlock:%d].\n", 633644570b8SJeff Kirsher dev->name, ei_status.dmaing, ei_status.irqlock); 634644570b8SJeff Kirsher return; 635644570b8SJeff Kirsher } 636644570b8SJeff Kirsher ei_status.dmaing |= 0x01; 637644570b8SJeff Kirsher outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); 638644570b8SJeff Kirsher outb_p(count & 0xff, nic_base + EN0_RCNTLO); 639644570b8SJeff Kirsher outb_p(count >> 8, nic_base + EN0_RCNTHI); 640644570b8SJeff Kirsher outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); 641644570b8SJeff Kirsher outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); 642644570b8SJeff Kirsher outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); 643644570b8SJeff Kirsher if (ei_status.word16) 644644570b8SJeff Kirsher { 645644570b8SJeff Kirsher insw(NE_BASE + NE_DATAPORT,buf,count>>1); 646644570b8SJeff Kirsher if (count & 0x01) 647644570b8SJeff Kirsher { 648644570b8SJeff Kirsher buf[count-1] = inb(NE_BASE + NE_DATAPORT); 649644570b8SJeff Kirsher #ifdef NE_SANITY_CHECK 650644570b8SJeff Kirsher xfer_count++; 651644570b8SJeff Kirsher #endif 652644570b8SJeff Kirsher } 653644570b8SJeff Kirsher } else { 654644570b8SJeff Kirsher insb(NE_BASE + NE_DATAPORT, buf, count); 655644570b8SJeff Kirsher } 656644570b8SJeff Kirsher 657644570b8SJeff Kirsher #ifdef NE_SANITY_CHECK 658644570b8SJeff Kirsher /* This was for the ALPHA version only, but enough people have 659644570b8SJeff Kirsher been encountering problems so it is still here. If you see 660644570b8SJeff Kirsher this message you either 1) have a slightly incompatible clone 661644570b8SJeff Kirsher or 2) have noise/speed problems with your bus. */ 662644570b8SJeff Kirsher 663644570b8SJeff Kirsher if (ei_debug > 1) 664644570b8SJeff Kirsher { 665644570b8SJeff Kirsher /* DMA termination address check... */ 666644570b8SJeff Kirsher int addr, tries = 20; 667644570b8SJeff Kirsher do { 668644570b8SJeff Kirsher /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here 669644570b8SJeff Kirsher -- it's broken for Rx on some cards! */ 670644570b8SJeff Kirsher int high = inb_p(nic_base + EN0_RSARHI); 671644570b8SJeff Kirsher int low = inb_p(nic_base + EN0_RSARLO); 672644570b8SJeff Kirsher addr = (high << 8) + low; 673644570b8SJeff Kirsher if (((ring_offset + xfer_count) & 0xff) == low) 674644570b8SJeff Kirsher break; 675644570b8SJeff Kirsher } while (--tries > 0); 676644570b8SJeff Kirsher if (tries <= 0) 677644570b8SJeff Kirsher printk(KERN_WARNING "%s: RX transfer address mismatch," 678644570b8SJeff Kirsher "%#4.4x (expected) vs. %#4.4x (actual).\n", 679644570b8SJeff Kirsher dev->name, ring_offset + xfer_count, addr); 680644570b8SJeff Kirsher } 681644570b8SJeff Kirsher #endif 682644570b8SJeff Kirsher outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ 683644570b8SJeff Kirsher ei_status.dmaing &= ~0x01; 684644570b8SJeff Kirsher } 685644570b8SJeff Kirsher 686644570b8SJeff Kirsher static void ne_block_output(struct net_device *dev, int count, 687644570b8SJeff Kirsher const unsigned char *buf, const int start_page) 688644570b8SJeff Kirsher { 689644570b8SJeff Kirsher int nic_base = NE_BASE; 690644570b8SJeff Kirsher unsigned long dma_start; 691644570b8SJeff Kirsher #ifdef NE_SANITY_CHECK 692644570b8SJeff Kirsher int retries = 0; 693644570b8SJeff Kirsher #endif 694644570b8SJeff Kirsher 695644570b8SJeff Kirsher /* Round the count up for word writes. Do we need to do this? 696644570b8SJeff Kirsher What effect will an odd byte count have on the 8390? 697644570b8SJeff Kirsher I should check someday. */ 698644570b8SJeff Kirsher 699644570b8SJeff Kirsher if (ei_status.word16 && (count & 0x01)) 700644570b8SJeff Kirsher count++; 701644570b8SJeff Kirsher 702644570b8SJeff Kirsher /* This *shouldn't* happen. If it does, it's the last thing you'll see */ 703644570b8SJeff Kirsher if (ei_status.dmaing) 704644570b8SJeff Kirsher { 705644570b8SJeff Kirsher printk(KERN_EMERG "%s: DMAing conflict in ne_block_output." 706644570b8SJeff Kirsher "[DMAstat:%d][irqlock:%d]\n", 707644570b8SJeff Kirsher dev->name, ei_status.dmaing, ei_status.irqlock); 708644570b8SJeff Kirsher return; 709644570b8SJeff Kirsher } 710644570b8SJeff Kirsher ei_status.dmaing |= 0x01; 711644570b8SJeff Kirsher /* We should already be in page 0, but to be safe... */ 712644570b8SJeff Kirsher outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); 713644570b8SJeff Kirsher 714644570b8SJeff Kirsher #ifdef NE_SANITY_CHECK 715644570b8SJeff Kirsher retry: 716644570b8SJeff Kirsher #endif 717644570b8SJeff Kirsher 718644570b8SJeff Kirsher #ifdef NE8390_RW_BUGFIX 719644570b8SJeff Kirsher /* Handle the read-before-write bug the same way as the 720644570b8SJeff Kirsher Crynwr packet driver -- the NatSemi method doesn't work. 721644570b8SJeff Kirsher Actually this doesn't always work either, but if you have 722644570b8SJeff Kirsher problems with your NEx000 this is better than nothing! */ 723644570b8SJeff Kirsher 724644570b8SJeff Kirsher outb_p(0x42, nic_base + EN0_RCNTLO); 725644570b8SJeff Kirsher outb_p(0x00, nic_base + EN0_RCNTHI); 726644570b8SJeff Kirsher outb_p(0x42, nic_base + EN0_RSARLO); 727644570b8SJeff Kirsher outb_p(0x00, nic_base + EN0_RSARHI); 728644570b8SJeff Kirsher outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); 729644570b8SJeff Kirsher /* Make certain that the dummy read has occurred. */ 730644570b8SJeff Kirsher udelay(6); 731644570b8SJeff Kirsher #endif 732644570b8SJeff Kirsher 733644570b8SJeff Kirsher outb_p(ENISR_RDC, nic_base + EN0_ISR); 734644570b8SJeff Kirsher 735644570b8SJeff Kirsher /* Now the normal output. */ 736644570b8SJeff Kirsher outb_p(count & 0xff, nic_base + EN0_RCNTLO); 737644570b8SJeff Kirsher outb_p(count >> 8, nic_base + EN0_RCNTHI); 738644570b8SJeff Kirsher outb_p(0x00, nic_base + EN0_RSARLO); 739644570b8SJeff Kirsher outb_p(start_page, nic_base + EN0_RSARHI); 740644570b8SJeff Kirsher 741644570b8SJeff Kirsher outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD); 742644570b8SJeff Kirsher if (ei_status.word16) { 743644570b8SJeff Kirsher outsw(NE_BASE + NE_DATAPORT, buf, count>>1); 744644570b8SJeff Kirsher } else { 745644570b8SJeff Kirsher outsb(NE_BASE + NE_DATAPORT, buf, count); 746644570b8SJeff Kirsher } 747644570b8SJeff Kirsher 748644570b8SJeff Kirsher dma_start = jiffies; 749644570b8SJeff Kirsher 750644570b8SJeff Kirsher #ifdef NE_SANITY_CHECK 751644570b8SJeff Kirsher /* This was for the ALPHA version only, but enough people have 752644570b8SJeff Kirsher been encountering problems so it is still here. */ 753644570b8SJeff Kirsher 754644570b8SJeff Kirsher if (ei_debug > 1) 755644570b8SJeff Kirsher { 756644570b8SJeff Kirsher /* DMA termination address check... */ 757644570b8SJeff Kirsher int addr, tries = 20; 758644570b8SJeff Kirsher do { 759644570b8SJeff Kirsher int high = inb_p(nic_base + EN0_RSARHI); 760644570b8SJeff Kirsher int low = inb_p(nic_base + EN0_RSARLO); 761644570b8SJeff Kirsher addr = (high << 8) + low; 762644570b8SJeff Kirsher if ((start_page << 8) + count == addr) 763644570b8SJeff Kirsher break; 764644570b8SJeff Kirsher } while (--tries > 0); 765644570b8SJeff Kirsher 766644570b8SJeff Kirsher if (tries <= 0) 767644570b8SJeff Kirsher { 768644570b8SJeff Kirsher printk(KERN_WARNING "%s: Tx packet transfer address mismatch," 769644570b8SJeff Kirsher "%#4.4x (expected) vs. %#4.4x (actual).\n", 770644570b8SJeff Kirsher dev->name, (start_page << 8) + count, addr); 771644570b8SJeff Kirsher if (retries++ == 0) 772644570b8SJeff Kirsher goto retry; 773644570b8SJeff Kirsher } 774644570b8SJeff Kirsher } 775644570b8SJeff Kirsher #endif 776644570b8SJeff Kirsher 777644570b8SJeff Kirsher while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) 778644570b8SJeff Kirsher if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ 779644570b8SJeff Kirsher printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); 780644570b8SJeff Kirsher ne_reset_8390(dev); 781644570b8SJeff Kirsher NS8390p_init(dev, 1); 782644570b8SJeff Kirsher break; 783644570b8SJeff Kirsher } 784644570b8SJeff Kirsher 785644570b8SJeff Kirsher outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ 786644570b8SJeff Kirsher ei_status.dmaing &= ~0x01; 787644570b8SJeff Kirsher } 788644570b8SJeff Kirsher 789644570b8SJeff Kirsher static int __init ne_drv_probe(struct platform_device *pdev) 790644570b8SJeff Kirsher { 791644570b8SJeff Kirsher struct net_device *dev; 792644570b8SJeff Kirsher int err, this_dev = pdev->id; 793644570b8SJeff Kirsher struct resource *res; 794644570b8SJeff Kirsher 795644570b8SJeff Kirsher dev = alloc_eip_netdev(); 796644570b8SJeff Kirsher if (!dev) 797644570b8SJeff Kirsher return -ENOMEM; 798644570b8SJeff Kirsher 799644570b8SJeff Kirsher /* ne.c doesn't populate resources in platform_device, but 800644570b8SJeff Kirsher * rbtx4927_ne_init and rbtx4938_ne_init do register devices 801644570b8SJeff Kirsher * with resources. 802644570b8SJeff Kirsher */ 803644570b8SJeff Kirsher res = platform_get_resource(pdev, IORESOURCE_IO, 0); 804644570b8SJeff Kirsher if (res) { 805644570b8SJeff Kirsher dev->base_addr = res->start; 806644570b8SJeff Kirsher dev->irq = platform_get_irq(pdev, 0); 807644570b8SJeff Kirsher } else { 808644570b8SJeff Kirsher if (this_dev < 0 || this_dev >= MAX_NE_CARDS) { 809644570b8SJeff Kirsher free_netdev(dev); 810644570b8SJeff Kirsher return -EINVAL; 811644570b8SJeff Kirsher } 812644570b8SJeff Kirsher dev->base_addr = io[this_dev]; 813644570b8SJeff Kirsher dev->irq = irq[this_dev]; 814644570b8SJeff Kirsher dev->mem_end = bad[this_dev]; 815644570b8SJeff Kirsher } 816da9da01dSAlan Cox SET_NETDEV_DEV(dev, &pdev->dev); 817644570b8SJeff Kirsher err = do_ne_probe(dev); 818644570b8SJeff Kirsher if (err) { 819644570b8SJeff Kirsher free_netdev(dev); 820644570b8SJeff Kirsher return err; 821644570b8SJeff Kirsher } 822644570b8SJeff Kirsher platform_set_drvdata(pdev, dev); 823644570b8SJeff Kirsher 824644570b8SJeff Kirsher /* Update with any values found by probing, don't update if 825644570b8SJeff Kirsher * resources were specified. 826644570b8SJeff Kirsher */ 827644570b8SJeff Kirsher if (!res) { 828644570b8SJeff Kirsher io[this_dev] = dev->base_addr; 829644570b8SJeff Kirsher irq[this_dev] = dev->irq; 830644570b8SJeff Kirsher } 831644570b8SJeff Kirsher return 0; 832644570b8SJeff Kirsher } 833644570b8SJeff Kirsher 834644570b8SJeff Kirsher static int ne_drv_remove(struct platform_device *pdev) 835644570b8SJeff Kirsher { 836644570b8SJeff Kirsher struct net_device *dev = platform_get_drvdata(pdev); 837644570b8SJeff Kirsher 838644570b8SJeff Kirsher if (dev) { 839644570b8SJeff Kirsher struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; 840644570b8SJeff Kirsher netif_device_detach(dev); 841644570b8SJeff Kirsher unregister_netdev(dev); 842644570b8SJeff Kirsher if (idev) 843644570b8SJeff Kirsher pnp_device_detach(idev); 844644570b8SJeff Kirsher /* Careful ne_drv_remove can be called twice, once from 845644570b8SJeff Kirsher * the platform_driver.remove and again when the 846644570b8SJeff Kirsher * platform_device is being removed. 847644570b8SJeff Kirsher */ 848644570b8SJeff Kirsher ei_status.priv = 0; 849644570b8SJeff Kirsher free_irq(dev->irq, dev); 850644570b8SJeff Kirsher release_region(dev->base_addr, NE_IO_EXTENT); 851644570b8SJeff Kirsher free_netdev(dev); 852644570b8SJeff Kirsher platform_set_drvdata(pdev, NULL); 853644570b8SJeff Kirsher } 854644570b8SJeff Kirsher return 0; 855644570b8SJeff Kirsher } 856644570b8SJeff Kirsher 857644570b8SJeff Kirsher /* Remove unused devices or all if true. */ 858644570b8SJeff Kirsher static void ne_loop_rm_unreg(int all) 859644570b8SJeff Kirsher { 860644570b8SJeff Kirsher int this_dev; 861644570b8SJeff Kirsher struct platform_device *pdev; 862644570b8SJeff Kirsher for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { 863644570b8SJeff Kirsher pdev = pdev_ne[this_dev]; 864644570b8SJeff Kirsher /* No network device == unused */ 865644570b8SJeff Kirsher if (pdev && (!platform_get_drvdata(pdev) || all)) { 866644570b8SJeff Kirsher ne_drv_remove(pdev); 867644570b8SJeff Kirsher platform_device_unregister(pdev); 868644570b8SJeff Kirsher pdev_ne[this_dev] = NULL; 869644570b8SJeff Kirsher } 870644570b8SJeff Kirsher } 871644570b8SJeff Kirsher } 872644570b8SJeff Kirsher 873644570b8SJeff Kirsher #ifdef CONFIG_PM 874644570b8SJeff Kirsher static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state) 875644570b8SJeff Kirsher { 876644570b8SJeff Kirsher struct net_device *dev = platform_get_drvdata(pdev); 877644570b8SJeff Kirsher 878644570b8SJeff Kirsher if (netif_running(dev)) { 879644570b8SJeff Kirsher struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; 880644570b8SJeff Kirsher netif_device_detach(dev); 881644570b8SJeff Kirsher if (idev) 882644570b8SJeff Kirsher pnp_stop_dev(idev); 883644570b8SJeff Kirsher } 884644570b8SJeff Kirsher return 0; 885644570b8SJeff Kirsher } 886644570b8SJeff Kirsher 887644570b8SJeff Kirsher static int ne_drv_resume(struct platform_device *pdev) 888644570b8SJeff Kirsher { 889644570b8SJeff Kirsher struct net_device *dev = platform_get_drvdata(pdev); 890644570b8SJeff Kirsher 891644570b8SJeff Kirsher if (netif_running(dev)) { 892644570b8SJeff Kirsher struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; 893644570b8SJeff Kirsher if (idev) 894644570b8SJeff Kirsher pnp_start_dev(idev); 895644570b8SJeff Kirsher ne_reset_8390(dev); 896644570b8SJeff Kirsher NS8390p_init(dev, 1); 897644570b8SJeff Kirsher netif_device_attach(dev); 898644570b8SJeff Kirsher } 899644570b8SJeff Kirsher return 0; 900644570b8SJeff Kirsher } 901644570b8SJeff Kirsher #else 902644570b8SJeff Kirsher #define ne_drv_suspend NULL 903644570b8SJeff Kirsher #define ne_drv_resume NULL 904644570b8SJeff Kirsher #endif 905644570b8SJeff Kirsher 906644570b8SJeff Kirsher static struct platform_driver ne_driver = { 907644570b8SJeff Kirsher .remove = ne_drv_remove, 908644570b8SJeff Kirsher .suspend = ne_drv_suspend, 909644570b8SJeff Kirsher .resume = ne_drv_resume, 910644570b8SJeff Kirsher .driver = { 911644570b8SJeff Kirsher .name = DRV_NAME, 912644570b8SJeff Kirsher .owner = THIS_MODULE, 913644570b8SJeff Kirsher }, 914644570b8SJeff Kirsher }; 915644570b8SJeff Kirsher 916644570b8SJeff Kirsher static void __init ne_add_devices(void) 917644570b8SJeff Kirsher { 918644570b8SJeff Kirsher int this_dev; 919644570b8SJeff Kirsher struct platform_device *pdev; 920644570b8SJeff Kirsher 921644570b8SJeff Kirsher for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { 922644570b8SJeff Kirsher if (pdev_ne[this_dev]) 923644570b8SJeff Kirsher continue; 924644570b8SJeff Kirsher pdev = platform_device_register_simple( 925644570b8SJeff Kirsher DRV_NAME, this_dev, NULL, 0); 926644570b8SJeff Kirsher if (IS_ERR(pdev)) 927644570b8SJeff Kirsher continue; 928644570b8SJeff Kirsher pdev_ne[this_dev] = pdev; 929644570b8SJeff Kirsher } 930644570b8SJeff Kirsher } 931644570b8SJeff Kirsher 932644570b8SJeff Kirsher #ifdef MODULE 933644570b8SJeff Kirsher int __init init_module(void) 934644570b8SJeff Kirsher { 935644570b8SJeff Kirsher int retval; 936644570b8SJeff Kirsher ne_add_devices(); 937644570b8SJeff Kirsher retval = platform_driver_probe(&ne_driver, ne_drv_probe); 938644570b8SJeff Kirsher if (retval) { 939644570b8SJeff Kirsher if (io[0] == 0) 940644570b8SJeff Kirsher printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\"" 941644570b8SJeff Kirsher " value(s) for ISA cards.\n"); 942644570b8SJeff Kirsher ne_loop_rm_unreg(1); 943644570b8SJeff Kirsher return retval; 944644570b8SJeff Kirsher } 945644570b8SJeff Kirsher 946644570b8SJeff Kirsher /* Unregister unused platform_devices. */ 947644570b8SJeff Kirsher ne_loop_rm_unreg(0); 948644570b8SJeff Kirsher return retval; 949644570b8SJeff Kirsher } 950644570b8SJeff Kirsher #else /* MODULE */ 951644570b8SJeff Kirsher static int __init ne_init(void) 952644570b8SJeff Kirsher { 953644570b8SJeff Kirsher int retval = platform_driver_probe(&ne_driver, ne_drv_probe); 954644570b8SJeff Kirsher 955644570b8SJeff Kirsher /* Unregister unused platform_devices. */ 956644570b8SJeff Kirsher ne_loop_rm_unreg(0); 957644570b8SJeff Kirsher return retval; 958644570b8SJeff Kirsher } 959644570b8SJeff Kirsher module_init(ne_init); 960644570b8SJeff Kirsher 961644570b8SJeff Kirsher struct net_device * __init ne_probe(int unit) 962644570b8SJeff Kirsher { 963644570b8SJeff Kirsher int this_dev; 964644570b8SJeff Kirsher struct net_device *dev; 965644570b8SJeff Kirsher 966644570b8SJeff Kirsher /* Find an empty slot, that is no net_device and zero io port. */ 967644570b8SJeff Kirsher this_dev = 0; 968644570b8SJeff Kirsher while ((pdev_ne[this_dev] && platform_get_drvdata(pdev_ne[this_dev])) || 969644570b8SJeff Kirsher io[this_dev]) { 970644570b8SJeff Kirsher if (++this_dev == MAX_NE_CARDS) 971644570b8SJeff Kirsher return ERR_PTR(-ENOMEM); 972644570b8SJeff Kirsher } 973644570b8SJeff Kirsher 974644570b8SJeff Kirsher /* Get irq, io from kernel command line */ 975644570b8SJeff Kirsher dev = alloc_eip_netdev(); 976644570b8SJeff Kirsher if (!dev) 977644570b8SJeff Kirsher return ERR_PTR(-ENOMEM); 978644570b8SJeff Kirsher 979644570b8SJeff Kirsher sprintf(dev->name, "eth%d", unit); 980644570b8SJeff Kirsher netdev_boot_setup_check(dev); 981644570b8SJeff Kirsher 982644570b8SJeff Kirsher io[this_dev] = dev->base_addr; 983644570b8SJeff Kirsher irq[this_dev] = dev->irq; 984644570b8SJeff Kirsher bad[this_dev] = dev->mem_end; 985644570b8SJeff Kirsher 986644570b8SJeff Kirsher free_netdev(dev); 987644570b8SJeff Kirsher 988644570b8SJeff Kirsher ne_add_devices(); 989644570b8SJeff Kirsher 990644570b8SJeff Kirsher /* return the first device found */ 991644570b8SJeff Kirsher for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { 992644570b8SJeff Kirsher if (pdev_ne[this_dev]) { 993644570b8SJeff Kirsher dev = platform_get_drvdata(pdev_ne[this_dev]); 994644570b8SJeff Kirsher if (dev) 995644570b8SJeff Kirsher return dev; 996644570b8SJeff Kirsher } 997644570b8SJeff Kirsher } 998644570b8SJeff Kirsher 999644570b8SJeff Kirsher return ERR_PTR(-ENODEV); 1000644570b8SJeff Kirsher } 1001644570b8SJeff Kirsher #endif /* MODULE */ 1002644570b8SJeff Kirsher 1003644570b8SJeff Kirsher static void __exit ne_exit(void) 1004644570b8SJeff Kirsher { 1005644570b8SJeff Kirsher platform_driver_unregister(&ne_driver); 1006644570b8SJeff Kirsher ne_loop_rm_unreg(1); 1007644570b8SJeff Kirsher } 1008644570b8SJeff Kirsher module_exit(ne_exit); 1009