1ca7a8e85SJeff Kirsher /* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */ 2ca7a8e85SJeff Kirsher /* 3ca7a8e85SJeff Kirsher Written 1993-2000 by Donald Becker. 4ca7a8e85SJeff Kirsher 5ca7a8e85SJeff Kirsher Copyright 1994-2000 by Donald Becker. 6ca7a8e85SJeff Kirsher Copyright 1993 United States Government as represented by the 7ca7a8e85SJeff Kirsher Director, National Security Agency. This software may be used and 8ca7a8e85SJeff Kirsher distributed according to the terms of the GNU General Public License, 9ca7a8e85SJeff Kirsher incorporated herein by reference. 10ca7a8e85SJeff Kirsher 11ca7a8e85SJeff Kirsher This driver is for the 3Com EtherLinkIII series. 12ca7a8e85SJeff Kirsher 13ca7a8e85SJeff Kirsher The author may be reached as becker@scyld.com, or C/O 14ca7a8e85SJeff Kirsher Scyld Computing Corporation 15ca7a8e85SJeff Kirsher 410 Severn Ave., Suite 210 16ca7a8e85SJeff Kirsher Annapolis MD 21403 17ca7a8e85SJeff Kirsher 18ca7a8e85SJeff Kirsher Known limitations: 19ca7a8e85SJeff Kirsher Because of the way 3c509 ISA detection works it's difficult to predict 20ca7a8e85SJeff Kirsher a priori which of several ISA-mode cards will be detected first. 21ca7a8e85SJeff Kirsher 22ca7a8e85SJeff Kirsher This driver does not use predictive interrupt mode, resulting in higher 23ca7a8e85SJeff Kirsher packet latency but lower overhead. If interrupts are disabled for an 24ca7a8e85SJeff Kirsher unusually long time it could also result in missed packets, but in 25ca7a8e85SJeff Kirsher practice this rarely happens. 26ca7a8e85SJeff Kirsher 27ca7a8e85SJeff Kirsher 28ca7a8e85SJeff Kirsher FIXES: 29ca7a8e85SJeff Kirsher Alan Cox: Removed the 'Unexpected interrupt' bug. 30ca7a8e85SJeff Kirsher Michael Meskes: Upgraded to Donald Becker's version 1.07. 31ca7a8e85SJeff Kirsher Alan Cox: Increased the eeprom delay. Regardless of 32ca7a8e85SJeff Kirsher what the docs say some people definitely 33ca7a8e85SJeff Kirsher get problems with lower (but in card spec) 34ca7a8e85SJeff Kirsher delays 35ca7a8e85SJeff Kirsher v1.10 4/21/97 Fixed module code so that multiple cards may be detected, 36ca7a8e85SJeff Kirsher other cleanups. -djb 37ca7a8e85SJeff Kirsher Andrea Arcangeli: Upgraded to Donald Becker's version 1.12. 38ca7a8e85SJeff Kirsher Rick Payne: Fixed SMP race condition 39ca7a8e85SJeff Kirsher v1.13 9/8/97 Made 'max_interrupt_work' an insmod-settable variable -djb 40ca7a8e85SJeff Kirsher v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb 41ca7a8e85SJeff Kirsher v1.15 1/31/98 Faster recovery for Tx errors. -djb 42ca7a8e85SJeff Kirsher v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb 43ca7a8e85SJeff Kirsher v1.18 12Mar2001 Andrew Morton 44ca7a8e85SJeff Kirsher - Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz) 45ca7a8e85SJeff Kirsher - Reviewed against 1.18 from scyld.com 46ca7a8e85SJeff Kirsher v1.18a 17Nov2001 Jeff Garzik <jgarzik@pobox.com> 47ca7a8e85SJeff Kirsher - ethtool support 48ca7a8e85SJeff Kirsher v1.18b 1Mar2002 Zwane Mwaikambo <zwane@commfireservices.com> 49ca7a8e85SJeff Kirsher - Power Management support 50ca7a8e85SJeff Kirsher v1.18c 1Mar2002 David Ruggiero <jdr@farfalle.com> 51ca7a8e85SJeff Kirsher - Full duplex support 52ca7a8e85SJeff Kirsher v1.19 16Oct2002 Zwane Mwaikambo <zwane@linuxpower.ca> 53ca7a8e85SJeff Kirsher - Additional ethtool features 54ca7a8e85SJeff Kirsher v1.19a 28Oct2002 Davud Ruggiero <jdr@farfalle.com> 55ca7a8e85SJeff Kirsher - Increase *read_eeprom udelay to workaround oops with 2 cards. 56ca7a8e85SJeff Kirsher v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org> 57ca7a8e85SJeff Kirsher - Introduce driver model for EISA cards. 58ca7a8e85SJeff Kirsher v1.20 04Feb2008 Ondrej Zary <linux@rainbow-software.org> 59ca7a8e85SJeff Kirsher - convert to isa_driver and pnp_driver and some cleanups 60ca7a8e85SJeff Kirsher */ 61ca7a8e85SJeff Kirsher 62ca7a8e85SJeff Kirsher #define DRV_NAME "3c509" 63ca7a8e85SJeff Kirsher #define DRV_VERSION "1.20" 64ca7a8e85SJeff Kirsher #define DRV_RELDATE "04Feb2008" 65ca7a8e85SJeff Kirsher 66ca7a8e85SJeff Kirsher /* A few values that may be tweaked. */ 67ca7a8e85SJeff Kirsher 68ca7a8e85SJeff Kirsher /* Time in jiffies before concluding the transmitter is hung. */ 69ca7a8e85SJeff Kirsher #define TX_TIMEOUT (400*HZ/1000) 70ca7a8e85SJeff Kirsher 71ca7a8e85SJeff Kirsher #include <linux/module.h> 72ca7a8e85SJeff Kirsher #include <linux/isa.h> 73ca7a8e85SJeff Kirsher #include <linux/pnp.h> 74ca7a8e85SJeff Kirsher #include <linux/string.h> 75ca7a8e85SJeff Kirsher #include <linux/interrupt.h> 76ca7a8e85SJeff Kirsher #include <linux/errno.h> 77ca7a8e85SJeff Kirsher #include <linux/in.h> 78ca7a8e85SJeff Kirsher #include <linux/ioport.h> 79ca7a8e85SJeff Kirsher #include <linux/init.h> 80ca7a8e85SJeff Kirsher #include <linux/netdevice.h> 81ca7a8e85SJeff Kirsher #include <linux/etherdevice.h> 82ca7a8e85SJeff Kirsher #include <linux/pm.h> 83ca7a8e85SJeff Kirsher #include <linux/skbuff.h> 84ca7a8e85SJeff Kirsher #include <linux/delay.h> /* for udelay() */ 85ca7a8e85SJeff Kirsher #include <linux/spinlock.h> 86ca7a8e85SJeff Kirsher #include <linux/ethtool.h> 87ca7a8e85SJeff Kirsher #include <linux/device.h> 88ca7a8e85SJeff Kirsher #include <linux/eisa.h> 89ca7a8e85SJeff Kirsher #include <linux/bitops.h> 90ca7a8e85SJeff Kirsher 91ca7a8e85SJeff Kirsher #include <asm/uaccess.h> 92ca7a8e85SJeff Kirsher #include <asm/io.h> 93ca7a8e85SJeff Kirsher #include <asm/irq.h> 94ca7a8e85SJeff Kirsher 952791cf7aSBill Pemberton static char version[] = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n"; 96ca7a8e85SJeff Kirsher 97ca7a8e85SJeff Kirsher #ifdef EL3_DEBUG 98ca7a8e85SJeff Kirsher static int el3_debug = EL3_DEBUG; 99ca7a8e85SJeff Kirsher #else 100ca7a8e85SJeff Kirsher static int el3_debug = 2; 101ca7a8e85SJeff Kirsher #endif 102ca7a8e85SJeff Kirsher 103ca7a8e85SJeff Kirsher /* Used to do a global count of all the cards in the system. Must be 104a5e371f6SPaul Gortmaker * a global variable so that the eisa probe routines can increment 105ca7a8e85SJeff Kirsher * it */ 106ca7a8e85SJeff Kirsher static int el3_cards = 0; 107ca7a8e85SJeff Kirsher #define EL3_MAX_CARDS 8 108ca7a8e85SJeff Kirsher 109ca7a8e85SJeff Kirsher /* To minimize the size of the driver source I only define operating 110ca7a8e85SJeff Kirsher constants if they are used several times. You'll need the manual 111ca7a8e85SJeff Kirsher anyway if you want to understand driver details. */ 112ca7a8e85SJeff Kirsher /* Offsets from base I/O address. */ 113ca7a8e85SJeff Kirsher #define EL3_DATA 0x00 114ca7a8e85SJeff Kirsher #define EL3_CMD 0x0e 115ca7a8e85SJeff Kirsher #define EL3_STATUS 0x0e 116ca7a8e85SJeff Kirsher #define EEPROM_READ 0x80 117ca7a8e85SJeff Kirsher 118ca7a8e85SJeff Kirsher #define EL3_IO_EXTENT 16 119ca7a8e85SJeff Kirsher 120ca7a8e85SJeff Kirsher #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD) 121ca7a8e85SJeff Kirsher 122ca7a8e85SJeff Kirsher 123ca7a8e85SJeff Kirsher /* The top five bits written to EL3_CMD are a command, the lower 124ca7a8e85SJeff Kirsher 11 bits are the parameter, if applicable. */ 125ca7a8e85SJeff Kirsher enum c509cmd { 126ca7a8e85SJeff Kirsher TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11, 127ca7a8e85SJeff Kirsher RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11, 128ca7a8e85SJeff Kirsher TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11, 129ca7a8e85SJeff Kirsher FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11, 130ca7a8e85SJeff Kirsher SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11, 131ca7a8e85SJeff Kirsher SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11, 132ca7a8e85SJeff Kirsher StatsDisable = 22<<11, StopCoax = 23<<11, PowerUp = 27<<11, 133ca7a8e85SJeff Kirsher PowerDown = 28<<11, PowerAuto = 29<<11}; 134ca7a8e85SJeff Kirsher 135ca7a8e85SJeff Kirsher enum c509status { 136ca7a8e85SJeff Kirsher IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004, 137ca7a8e85SJeff Kirsher TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020, 138ca7a8e85SJeff Kirsher IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000, }; 139ca7a8e85SJeff Kirsher 140ca7a8e85SJeff Kirsher /* The SetRxFilter command accepts the following classes: */ 141ca7a8e85SJeff Kirsher enum RxFilter { 142ca7a8e85SJeff Kirsher RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 }; 143ca7a8e85SJeff Kirsher 144ca7a8e85SJeff Kirsher /* Register window 1 offsets, the window used in normal operation. */ 145ca7a8e85SJeff Kirsher #define TX_FIFO 0x00 146ca7a8e85SJeff Kirsher #define RX_FIFO 0x00 147ca7a8e85SJeff Kirsher #define RX_STATUS 0x08 148ca7a8e85SJeff Kirsher #define TX_STATUS 0x0B 149ca7a8e85SJeff Kirsher #define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */ 150ca7a8e85SJeff Kirsher 151ca7a8e85SJeff Kirsher #define WN0_CONF_CTRL 0x04 /* Window 0: Configuration control register */ 152ca7a8e85SJeff Kirsher #define WN0_ADDR_CONF 0x06 /* Window 0: Address configuration register */ 153ca7a8e85SJeff Kirsher #define WN0_IRQ 0x08 /* Window 0: Set IRQ line in bits 12-15. */ 154ca7a8e85SJeff Kirsher #define WN4_MEDIA 0x0A /* Window 4: Various transcvr/media bits. */ 155ca7a8e85SJeff Kirsher #define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ 156ca7a8e85SJeff Kirsher #define WN4_NETDIAG 0x06 /* Window 4: Net diagnostic */ 157ca7a8e85SJeff Kirsher #define FD_ENABLE 0x8000 /* Enable full-duplex ("external loopback") */ 158ca7a8e85SJeff Kirsher 159ca7a8e85SJeff Kirsher /* 160ca7a8e85SJeff Kirsher * Must be a power of two (we use a binary and in the 161ca7a8e85SJeff Kirsher * circular queue) 162ca7a8e85SJeff Kirsher */ 163ca7a8e85SJeff Kirsher #define SKB_QUEUE_SIZE 64 164ca7a8e85SJeff Kirsher 165a5e371f6SPaul Gortmaker enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_EISA }; 166ca7a8e85SJeff Kirsher 167ca7a8e85SJeff Kirsher struct el3_private { 168ca7a8e85SJeff Kirsher spinlock_t lock; 169ca7a8e85SJeff Kirsher /* skb send-queue */ 170ca7a8e85SJeff Kirsher int head, size; 171ca7a8e85SJeff Kirsher struct sk_buff *queue[SKB_QUEUE_SIZE]; 172ca7a8e85SJeff Kirsher enum el3_cardtype type; 173ca7a8e85SJeff Kirsher }; 174ca7a8e85SJeff Kirsher static int id_port; 175ca7a8e85SJeff Kirsher static int current_tag; 176ca7a8e85SJeff Kirsher static struct net_device *el3_devs[EL3_MAX_CARDS]; 177ca7a8e85SJeff Kirsher 178ca7a8e85SJeff Kirsher /* Parameters that may be passed into the module. */ 179ca7a8e85SJeff Kirsher static int debug = -1; 180ca7a8e85SJeff Kirsher static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1}; 181ca7a8e85SJeff Kirsher /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ 182ca7a8e85SJeff Kirsher static int max_interrupt_work = 10; 183ca7a8e85SJeff Kirsher #ifdef CONFIG_PNP 184ca7a8e85SJeff Kirsher static int nopnp; 185ca7a8e85SJeff Kirsher #endif 186ca7a8e85SJeff Kirsher 1872791cf7aSBill Pemberton static int el3_common_init(struct net_device *dev); 188ca7a8e85SJeff Kirsher static void el3_common_remove(struct net_device *dev); 189ca7a8e85SJeff Kirsher static ushort id_read_eeprom(int index); 190ca7a8e85SJeff Kirsher static ushort read_eeprom(int ioaddr, int index); 191ca7a8e85SJeff Kirsher static int el3_open(struct net_device *dev); 192ca7a8e85SJeff Kirsher static netdev_tx_t el3_start_xmit(struct sk_buff *skb, struct net_device *dev); 193ca7a8e85SJeff Kirsher static irqreturn_t el3_interrupt(int irq, void *dev_id); 194ca7a8e85SJeff Kirsher static void update_stats(struct net_device *dev); 195ca7a8e85SJeff Kirsher static struct net_device_stats *el3_get_stats(struct net_device *dev); 196ca7a8e85SJeff Kirsher static int el3_rx(struct net_device *dev); 197ca7a8e85SJeff Kirsher static int el3_close(struct net_device *dev); 198ca7a8e85SJeff Kirsher static void set_multicast_list(struct net_device *dev); 199ca7a8e85SJeff Kirsher static void el3_tx_timeout (struct net_device *dev); 200ca7a8e85SJeff Kirsher static void el3_down(struct net_device *dev); 201ca7a8e85SJeff Kirsher static void el3_up(struct net_device *dev); 202ca7a8e85SJeff Kirsher static const struct ethtool_ops ethtool_ops; 203ca7a8e85SJeff Kirsher #ifdef CONFIG_PM 204ca7a8e85SJeff Kirsher static int el3_suspend(struct device *, pm_message_t); 205ca7a8e85SJeff Kirsher static int el3_resume(struct device *); 206ca7a8e85SJeff Kirsher #else 207ca7a8e85SJeff Kirsher #define el3_suspend NULL 208ca7a8e85SJeff Kirsher #define el3_resume NULL 209ca7a8e85SJeff Kirsher #endif 210ca7a8e85SJeff Kirsher 211ca7a8e85SJeff Kirsher 212ca7a8e85SJeff Kirsher /* generic device remove for all device types */ 213ca7a8e85SJeff Kirsher static int el3_device_remove (struct device *device); 214ca7a8e85SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 215ca7a8e85SJeff Kirsher static void el3_poll_controller(struct net_device *dev); 216ca7a8e85SJeff Kirsher #endif 217ca7a8e85SJeff Kirsher 218ca7a8e85SJeff Kirsher /* Return 0 on success, 1 on error, 2 when found already detected PnP card */ 219ca7a8e85SJeff Kirsher static int el3_isa_id_sequence(__be16 *phys_addr) 220ca7a8e85SJeff Kirsher { 221ca7a8e85SJeff Kirsher short lrs_state = 0xff; 222ca7a8e85SJeff Kirsher int i; 223ca7a8e85SJeff Kirsher 224ca7a8e85SJeff Kirsher /* ISA boards are detected by sending the ID sequence to the 225ca7a8e85SJeff Kirsher ID_PORT. We find cards past the first by setting the 'current_tag' 226ca7a8e85SJeff Kirsher on cards as they are found. Cards with their tag set will not 227ca7a8e85SJeff Kirsher respond to subsequent ID sequences. */ 228ca7a8e85SJeff Kirsher 229ca7a8e85SJeff Kirsher outb(0x00, id_port); 230ca7a8e85SJeff Kirsher outb(0x00, id_port); 231ca7a8e85SJeff Kirsher for (i = 0; i < 255; i++) { 232ca7a8e85SJeff Kirsher outb(lrs_state, id_port); 233ca7a8e85SJeff Kirsher lrs_state <<= 1; 234ca7a8e85SJeff Kirsher lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state; 235ca7a8e85SJeff Kirsher } 236ca7a8e85SJeff Kirsher /* For the first probe, clear all board's tag registers. */ 237ca7a8e85SJeff Kirsher if (current_tag == 0) 238ca7a8e85SJeff Kirsher outb(0xd0, id_port); 239ca7a8e85SJeff Kirsher else /* Otherwise kill off already-found boards. */ 240ca7a8e85SJeff Kirsher outb(0xd8, id_port); 241ca7a8e85SJeff Kirsher if (id_read_eeprom(7) != 0x6d50) 242ca7a8e85SJeff Kirsher return 1; 243ca7a8e85SJeff Kirsher /* Read in EEPROM data, which does contention-select. 244ca7a8e85SJeff Kirsher Only the lowest address board will stay "on-line". 245ca7a8e85SJeff Kirsher 3Com got the byte order backwards. */ 246ca7a8e85SJeff Kirsher for (i = 0; i < 3; i++) 247ca7a8e85SJeff Kirsher phys_addr[i] = htons(id_read_eeprom(i)); 248ca7a8e85SJeff Kirsher #ifdef CONFIG_PNP 249ca7a8e85SJeff Kirsher if (!nopnp) { 250ca7a8e85SJeff Kirsher /* The ISA PnP 3c509 cards respond to the ID sequence too. 251ca7a8e85SJeff Kirsher This check is needed in order not to register them twice. */ 252ca7a8e85SJeff Kirsher for (i = 0; i < el3_cards; i++) { 253ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(el3_devs[i]); 254ca7a8e85SJeff Kirsher if (lp->type == EL3_PNP && 255ca7a8e85SJeff Kirsher !memcmp(phys_addr, el3_devs[i]->dev_addr, 256ca7a8e85SJeff Kirsher ETH_ALEN)) { 257ca7a8e85SJeff Kirsher if (el3_debug > 3) 258ca7a8e85SJeff Kirsher pr_debug("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n", 259ca7a8e85SJeff Kirsher phys_addr[0] & 0xff, phys_addr[0] >> 8, 260ca7a8e85SJeff Kirsher phys_addr[1] & 0xff, phys_addr[1] >> 8, 261ca7a8e85SJeff Kirsher phys_addr[2] & 0xff, phys_addr[2] >> 8); 262ca7a8e85SJeff Kirsher /* Set the adaptor tag so that the next card can be found. */ 263ca7a8e85SJeff Kirsher outb(0xd0 + ++current_tag, id_port); 264ca7a8e85SJeff Kirsher return 2; 265ca7a8e85SJeff Kirsher } 266ca7a8e85SJeff Kirsher } 267ca7a8e85SJeff Kirsher } 268ca7a8e85SJeff Kirsher #endif /* CONFIG_PNP */ 269ca7a8e85SJeff Kirsher return 0; 270ca7a8e85SJeff Kirsher 271ca7a8e85SJeff Kirsher } 272ca7a8e85SJeff Kirsher 2732791cf7aSBill Pemberton static void el3_dev_fill(struct net_device *dev, __be16 *phys_addr, 274ca7a8e85SJeff Kirsher int ioaddr, int irq, int if_port, 275ca7a8e85SJeff Kirsher enum el3_cardtype type) 276ca7a8e85SJeff Kirsher { 277ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(dev); 278ca7a8e85SJeff Kirsher 279ca7a8e85SJeff Kirsher memcpy(dev->dev_addr, phys_addr, ETH_ALEN); 280ca7a8e85SJeff Kirsher dev->base_addr = ioaddr; 281ca7a8e85SJeff Kirsher dev->irq = irq; 282ca7a8e85SJeff Kirsher dev->if_port = if_port; 283ca7a8e85SJeff Kirsher lp->type = type; 284ca7a8e85SJeff Kirsher } 285ca7a8e85SJeff Kirsher 2862791cf7aSBill Pemberton static int el3_isa_match(struct device *pdev, 287ca7a8e85SJeff Kirsher unsigned int ndev) 288ca7a8e85SJeff Kirsher { 289ca7a8e85SJeff Kirsher struct net_device *dev; 290ca7a8e85SJeff Kirsher int ioaddr, isa_irq, if_port, err; 291ca7a8e85SJeff Kirsher unsigned int iobase; 292ca7a8e85SJeff Kirsher __be16 phys_addr[3]; 293ca7a8e85SJeff Kirsher 294ca7a8e85SJeff Kirsher while ((err = el3_isa_id_sequence(phys_addr)) == 2) 295ca7a8e85SJeff Kirsher ; /* Skip to next card when PnP card found */ 296ca7a8e85SJeff Kirsher if (err == 1) 297ca7a8e85SJeff Kirsher return 0; 298ca7a8e85SJeff Kirsher 299ca7a8e85SJeff Kirsher iobase = id_read_eeprom(8); 300ca7a8e85SJeff Kirsher if_port = iobase >> 14; 301ca7a8e85SJeff Kirsher ioaddr = 0x200 + ((iobase & 0x1f) << 4); 302ca7a8e85SJeff Kirsher if (irq[el3_cards] > 1 && irq[el3_cards] < 16) 303ca7a8e85SJeff Kirsher isa_irq = irq[el3_cards]; 304ca7a8e85SJeff Kirsher else 305ca7a8e85SJeff Kirsher isa_irq = id_read_eeprom(9) >> 12; 306ca7a8e85SJeff Kirsher 307ca7a8e85SJeff Kirsher dev = alloc_etherdev(sizeof(struct el3_private)); 308ca7a8e85SJeff Kirsher if (!dev) 309ca7a8e85SJeff Kirsher return -ENOMEM; 310ca7a8e85SJeff Kirsher 311ca7a8e85SJeff Kirsher netdev_boot_setup_check(dev); 312ca7a8e85SJeff Kirsher 313ca7a8e85SJeff Kirsher if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) { 314ca7a8e85SJeff Kirsher free_netdev(dev); 315ca7a8e85SJeff Kirsher return 0; 316ca7a8e85SJeff Kirsher } 317ca7a8e85SJeff Kirsher 318ca7a8e85SJeff Kirsher /* Set the adaptor tag so that the next card can be found. */ 319ca7a8e85SJeff Kirsher outb(0xd0 + ++current_tag, id_port); 320ca7a8e85SJeff Kirsher 321ca7a8e85SJeff Kirsher /* Activate the adaptor at the EEPROM location. */ 322ca7a8e85SJeff Kirsher outb((ioaddr >> 4) | 0xe0, id_port); 323ca7a8e85SJeff Kirsher 324ca7a8e85SJeff Kirsher EL3WINDOW(0); 325ca7a8e85SJeff Kirsher if (inw(ioaddr) != 0x6d50) { 326ca7a8e85SJeff Kirsher free_netdev(dev); 327ca7a8e85SJeff Kirsher return 0; 328ca7a8e85SJeff Kirsher } 329ca7a8e85SJeff Kirsher 330ca7a8e85SJeff Kirsher /* Free the interrupt so that some other card can use it. */ 331ca7a8e85SJeff Kirsher outw(0x0f00, ioaddr + WN0_IRQ); 332ca7a8e85SJeff Kirsher 333ca7a8e85SJeff Kirsher el3_dev_fill(dev, phys_addr, ioaddr, isa_irq, if_port, EL3_ISA); 334ca7a8e85SJeff Kirsher dev_set_drvdata(pdev, dev); 335ca7a8e85SJeff Kirsher if (el3_common_init(dev)) { 336ca7a8e85SJeff Kirsher free_netdev(dev); 337ca7a8e85SJeff Kirsher return 0; 338ca7a8e85SJeff Kirsher } 339ca7a8e85SJeff Kirsher 340ca7a8e85SJeff Kirsher el3_devs[el3_cards++] = dev; 341ca7a8e85SJeff Kirsher return 1; 342ca7a8e85SJeff Kirsher } 343ca7a8e85SJeff Kirsher 3442791cf7aSBill Pemberton static int el3_isa_remove(struct device *pdev, 345ca7a8e85SJeff Kirsher unsigned int ndev) 346ca7a8e85SJeff Kirsher { 347ca7a8e85SJeff Kirsher el3_device_remove(pdev); 348ca7a8e85SJeff Kirsher dev_set_drvdata(pdev, NULL); 349ca7a8e85SJeff Kirsher return 0; 350ca7a8e85SJeff Kirsher } 351ca7a8e85SJeff Kirsher 352ca7a8e85SJeff Kirsher #ifdef CONFIG_PM 353ca7a8e85SJeff Kirsher static int el3_isa_suspend(struct device *dev, unsigned int n, 354ca7a8e85SJeff Kirsher pm_message_t state) 355ca7a8e85SJeff Kirsher { 356ca7a8e85SJeff Kirsher current_tag = 0; 357ca7a8e85SJeff Kirsher return el3_suspend(dev, state); 358ca7a8e85SJeff Kirsher } 359ca7a8e85SJeff Kirsher 360ca7a8e85SJeff Kirsher static int el3_isa_resume(struct device *dev, unsigned int n) 361ca7a8e85SJeff Kirsher { 362ca7a8e85SJeff Kirsher struct net_device *ndev = dev_get_drvdata(dev); 363ca7a8e85SJeff Kirsher int ioaddr = ndev->base_addr, err; 364ca7a8e85SJeff Kirsher __be16 phys_addr[3]; 365ca7a8e85SJeff Kirsher 366ca7a8e85SJeff Kirsher while ((err = el3_isa_id_sequence(phys_addr)) == 2) 367ca7a8e85SJeff Kirsher ; /* Skip to next card when PnP card found */ 368ca7a8e85SJeff Kirsher if (err == 1) 369ca7a8e85SJeff Kirsher return 0; 370ca7a8e85SJeff Kirsher /* Set the adaptor tag so that the next card can be found. */ 371ca7a8e85SJeff Kirsher outb(0xd0 + ++current_tag, id_port); 372ca7a8e85SJeff Kirsher /* Enable the card */ 373ca7a8e85SJeff Kirsher outb((ioaddr >> 4) | 0xe0, id_port); 374ca7a8e85SJeff Kirsher EL3WINDOW(0); 375ca7a8e85SJeff Kirsher if (inw(ioaddr) != 0x6d50) 376ca7a8e85SJeff Kirsher return 1; 377ca7a8e85SJeff Kirsher /* Free the interrupt so that some other card can use it. */ 378ca7a8e85SJeff Kirsher outw(0x0f00, ioaddr + WN0_IRQ); 379ca7a8e85SJeff Kirsher return el3_resume(dev); 380ca7a8e85SJeff Kirsher } 381ca7a8e85SJeff Kirsher #endif 382ca7a8e85SJeff Kirsher 383ca7a8e85SJeff Kirsher static struct isa_driver el3_isa_driver = { 384ca7a8e85SJeff Kirsher .match = el3_isa_match, 3852791cf7aSBill Pemberton .remove = el3_isa_remove, 386ca7a8e85SJeff Kirsher #ifdef CONFIG_PM 387ca7a8e85SJeff Kirsher .suspend = el3_isa_suspend, 388ca7a8e85SJeff Kirsher .resume = el3_isa_resume, 389ca7a8e85SJeff Kirsher #endif 390ca7a8e85SJeff Kirsher .driver = { 391ca7a8e85SJeff Kirsher .name = "3c509" 392ca7a8e85SJeff Kirsher }, 393ca7a8e85SJeff Kirsher }; 394ca7a8e85SJeff Kirsher static int isa_registered; 395ca7a8e85SJeff Kirsher 396ca7a8e85SJeff Kirsher #ifdef CONFIG_PNP 397ca7a8e85SJeff Kirsher static struct pnp_device_id el3_pnp_ids[] = { 398ca7a8e85SJeff Kirsher { .id = "TCM5090" }, /* 3Com Etherlink III (TP) */ 399ca7a8e85SJeff Kirsher { .id = "TCM5091" }, /* 3Com Etherlink III */ 400ca7a8e85SJeff Kirsher { .id = "TCM5094" }, /* 3Com Etherlink III (combo) */ 401ca7a8e85SJeff Kirsher { .id = "TCM5095" }, /* 3Com Etherlink III (TPO) */ 402ca7a8e85SJeff Kirsher { .id = "TCM5098" }, /* 3Com Etherlink III (TPC) */ 403ca7a8e85SJeff Kirsher { .id = "PNP80f7" }, /* 3Com Etherlink III compatible */ 404ca7a8e85SJeff Kirsher { .id = "PNP80f8" }, /* 3Com Etherlink III compatible */ 405ca7a8e85SJeff Kirsher { .id = "" } 406ca7a8e85SJeff Kirsher }; 407ca7a8e85SJeff Kirsher MODULE_DEVICE_TABLE(pnp, el3_pnp_ids); 408ca7a8e85SJeff Kirsher 4092791cf7aSBill Pemberton static int el3_pnp_probe(struct pnp_dev *pdev, 410ca7a8e85SJeff Kirsher const struct pnp_device_id *id) 411ca7a8e85SJeff Kirsher { 412ca7a8e85SJeff Kirsher short i; 413ca7a8e85SJeff Kirsher int ioaddr, irq, if_port; 414ca7a8e85SJeff Kirsher __be16 phys_addr[3]; 415ca7a8e85SJeff Kirsher struct net_device *dev = NULL; 416ca7a8e85SJeff Kirsher int err; 417ca7a8e85SJeff Kirsher 418ca7a8e85SJeff Kirsher ioaddr = pnp_port_start(pdev, 0); 419ca7a8e85SJeff Kirsher if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-pnp")) 420ca7a8e85SJeff Kirsher return -EBUSY; 421ca7a8e85SJeff Kirsher irq = pnp_irq(pdev, 0); 422ca7a8e85SJeff Kirsher EL3WINDOW(0); 423ca7a8e85SJeff Kirsher for (i = 0; i < 3; i++) 424ca7a8e85SJeff Kirsher phys_addr[i] = htons(read_eeprom(ioaddr, i)); 425ca7a8e85SJeff Kirsher if_port = read_eeprom(ioaddr, 8) >> 14; 426ca7a8e85SJeff Kirsher dev = alloc_etherdev(sizeof(struct el3_private)); 427ca7a8e85SJeff Kirsher if (!dev) { 428ca7a8e85SJeff Kirsher release_region(ioaddr, EL3_IO_EXTENT); 429ca7a8e85SJeff Kirsher return -ENOMEM; 430ca7a8e85SJeff Kirsher } 431ca7a8e85SJeff Kirsher SET_NETDEV_DEV(dev, &pdev->dev); 432ca7a8e85SJeff Kirsher netdev_boot_setup_check(dev); 433ca7a8e85SJeff Kirsher 434ca7a8e85SJeff Kirsher el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_PNP); 435ca7a8e85SJeff Kirsher pnp_set_drvdata(pdev, dev); 436ca7a8e85SJeff Kirsher err = el3_common_init(dev); 437ca7a8e85SJeff Kirsher 438ca7a8e85SJeff Kirsher if (err) { 439ca7a8e85SJeff Kirsher pnp_set_drvdata(pdev, NULL); 440ca7a8e85SJeff Kirsher free_netdev(dev); 441ca7a8e85SJeff Kirsher return err; 442ca7a8e85SJeff Kirsher } 443ca7a8e85SJeff Kirsher 444ca7a8e85SJeff Kirsher el3_devs[el3_cards++] = dev; 445ca7a8e85SJeff Kirsher return 0; 446ca7a8e85SJeff Kirsher } 447ca7a8e85SJeff Kirsher 4482791cf7aSBill Pemberton static void el3_pnp_remove(struct pnp_dev *pdev) 449ca7a8e85SJeff Kirsher { 450ca7a8e85SJeff Kirsher el3_common_remove(pnp_get_drvdata(pdev)); 451ca7a8e85SJeff Kirsher pnp_set_drvdata(pdev, NULL); 452ca7a8e85SJeff Kirsher } 453ca7a8e85SJeff Kirsher 454ca7a8e85SJeff Kirsher #ifdef CONFIG_PM 455ca7a8e85SJeff Kirsher static int el3_pnp_suspend(struct pnp_dev *pdev, pm_message_t state) 456ca7a8e85SJeff Kirsher { 457ca7a8e85SJeff Kirsher return el3_suspend(&pdev->dev, state); 458ca7a8e85SJeff Kirsher } 459ca7a8e85SJeff Kirsher 460ca7a8e85SJeff Kirsher static int el3_pnp_resume(struct pnp_dev *pdev) 461ca7a8e85SJeff Kirsher { 462ca7a8e85SJeff Kirsher return el3_resume(&pdev->dev); 463ca7a8e85SJeff Kirsher } 464ca7a8e85SJeff Kirsher #endif 465ca7a8e85SJeff Kirsher 466ca7a8e85SJeff Kirsher static struct pnp_driver el3_pnp_driver = { 467ca7a8e85SJeff Kirsher .name = "3c509", 468ca7a8e85SJeff Kirsher .id_table = el3_pnp_ids, 469ca7a8e85SJeff Kirsher .probe = el3_pnp_probe, 4702791cf7aSBill Pemberton .remove = el3_pnp_remove, 471ca7a8e85SJeff Kirsher #ifdef CONFIG_PM 472ca7a8e85SJeff Kirsher .suspend = el3_pnp_suspend, 473ca7a8e85SJeff Kirsher .resume = el3_pnp_resume, 474ca7a8e85SJeff Kirsher #endif 475ca7a8e85SJeff Kirsher }; 476ca7a8e85SJeff Kirsher static int pnp_registered; 477ca7a8e85SJeff Kirsher #endif /* CONFIG_PNP */ 478ca7a8e85SJeff Kirsher 479ca7a8e85SJeff Kirsher #ifdef CONFIG_EISA 480ca7a8e85SJeff Kirsher static struct eisa_device_id el3_eisa_ids[] = { 481ca7a8e85SJeff Kirsher { "TCM5090" }, 482ca7a8e85SJeff Kirsher { "TCM5091" }, 483ca7a8e85SJeff Kirsher { "TCM5092" }, 484ca7a8e85SJeff Kirsher { "TCM5093" }, 485ca7a8e85SJeff Kirsher { "TCM5094" }, 486ca7a8e85SJeff Kirsher { "TCM5095" }, 487ca7a8e85SJeff Kirsher { "TCM5098" }, 488ca7a8e85SJeff Kirsher { "" } 489ca7a8e85SJeff Kirsher }; 490ca7a8e85SJeff Kirsher MODULE_DEVICE_TABLE(eisa, el3_eisa_ids); 491ca7a8e85SJeff Kirsher 492ca7a8e85SJeff Kirsher static int el3_eisa_probe (struct device *device); 493ca7a8e85SJeff Kirsher 494ca7a8e85SJeff Kirsher static struct eisa_driver el3_eisa_driver = { 495ca7a8e85SJeff Kirsher .id_table = el3_eisa_ids, 496ca7a8e85SJeff Kirsher .driver = { 497ca7a8e85SJeff Kirsher .name = "3c579", 498ca7a8e85SJeff Kirsher .probe = el3_eisa_probe, 4992791cf7aSBill Pemberton .remove = el3_device_remove, 500ca7a8e85SJeff Kirsher .suspend = el3_suspend, 501ca7a8e85SJeff Kirsher .resume = el3_resume, 502ca7a8e85SJeff Kirsher } 503ca7a8e85SJeff Kirsher }; 504ca7a8e85SJeff Kirsher static int eisa_registered; 505ca7a8e85SJeff Kirsher #endif 506ca7a8e85SJeff Kirsher 507ca7a8e85SJeff Kirsher static const struct net_device_ops netdev_ops = { 508ca7a8e85SJeff Kirsher .ndo_open = el3_open, 509ca7a8e85SJeff Kirsher .ndo_stop = el3_close, 510ca7a8e85SJeff Kirsher .ndo_start_xmit = el3_start_xmit, 511ca7a8e85SJeff Kirsher .ndo_get_stats = el3_get_stats, 512afc4b13dSJiri Pirko .ndo_set_rx_mode = set_multicast_list, 513ca7a8e85SJeff Kirsher .ndo_tx_timeout = el3_tx_timeout, 514ca7a8e85SJeff Kirsher .ndo_change_mtu = eth_change_mtu, 515ca7a8e85SJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 516ca7a8e85SJeff Kirsher .ndo_validate_addr = eth_validate_addr, 517ca7a8e85SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 518ca7a8e85SJeff Kirsher .ndo_poll_controller = el3_poll_controller, 519ca7a8e85SJeff Kirsher #endif 520ca7a8e85SJeff Kirsher }; 521ca7a8e85SJeff Kirsher 5222791cf7aSBill Pemberton static int el3_common_init(struct net_device *dev) 523ca7a8e85SJeff Kirsher { 524ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(dev); 525ca7a8e85SJeff Kirsher int err; 526ca7a8e85SJeff Kirsher const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"}; 527ca7a8e85SJeff Kirsher 528ca7a8e85SJeff Kirsher spin_lock_init(&lp->lock); 529ca7a8e85SJeff Kirsher 530ca7a8e85SJeff Kirsher if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */ 531ca7a8e85SJeff Kirsher dev->if_port = (dev->mem_start & 0x0f); 532ca7a8e85SJeff Kirsher } else { /* xcvr codes 0/8 */ 533ca7a8e85SJeff Kirsher /* use eeprom value, but save user's full-duplex selection */ 534ca7a8e85SJeff Kirsher dev->if_port |= (dev->mem_start & 0x08); 535ca7a8e85SJeff Kirsher } 536ca7a8e85SJeff Kirsher 537ca7a8e85SJeff Kirsher /* The EL3-specific entries in the device structure. */ 538ca7a8e85SJeff Kirsher dev->netdev_ops = &netdev_ops; 539ca7a8e85SJeff Kirsher dev->watchdog_timeo = TX_TIMEOUT; 540ca7a8e85SJeff Kirsher SET_ETHTOOL_OPS(dev, ðtool_ops); 541ca7a8e85SJeff Kirsher 542ca7a8e85SJeff Kirsher err = register_netdev(dev); 543ca7a8e85SJeff Kirsher if (err) { 544ca7a8e85SJeff Kirsher pr_err("Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n", 545ca7a8e85SJeff Kirsher dev->base_addr, dev->irq); 546ca7a8e85SJeff Kirsher release_region(dev->base_addr, EL3_IO_EXTENT); 547ca7a8e85SJeff Kirsher return err; 548ca7a8e85SJeff Kirsher } 549ca7a8e85SJeff Kirsher 550ca7a8e85SJeff Kirsher pr_info("%s: 3c5x9 found at %#3.3lx, %s port, address %pM, IRQ %d.\n", 551ca7a8e85SJeff Kirsher dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)], 552ca7a8e85SJeff Kirsher dev->dev_addr, dev->irq); 553ca7a8e85SJeff Kirsher 554ca7a8e85SJeff Kirsher if (el3_debug > 0) 555ca7a8e85SJeff Kirsher pr_info("%s", version); 556ca7a8e85SJeff Kirsher return 0; 557ca7a8e85SJeff Kirsher 558ca7a8e85SJeff Kirsher } 559ca7a8e85SJeff Kirsher 560ca7a8e85SJeff Kirsher static void el3_common_remove (struct net_device *dev) 561ca7a8e85SJeff Kirsher { 562ca7a8e85SJeff Kirsher unregister_netdev (dev); 563ca7a8e85SJeff Kirsher release_region(dev->base_addr, EL3_IO_EXTENT); 564ca7a8e85SJeff Kirsher free_netdev (dev); 565ca7a8e85SJeff Kirsher } 566ca7a8e85SJeff Kirsher 567ca7a8e85SJeff Kirsher #ifdef CONFIG_EISA 568ca7a8e85SJeff Kirsher static int __init el3_eisa_probe (struct device *device) 569ca7a8e85SJeff Kirsher { 570ca7a8e85SJeff Kirsher short i; 571ca7a8e85SJeff Kirsher int ioaddr, irq, if_port; 572ca7a8e85SJeff Kirsher __be16 phys_addr[3]; 573ca7a8e85SJeff Kirsher struct net_device *dev = NULL; 574ca7a8e85SJeff Kirsher struct eisa_device *edev; 575ca7a8e85SJeff Kirsher int err; 576ca7a8e85SJeff Kirsher 577ca7a8e85SJeff Kirsher /* Yeepee, The driver framework is calling us ! */ 578ca7a8e85SJeff Kirsher edev = to_eisa_device (device); 579ca7a8e85SJeff Kirsher ioaddr = edev->base_addr; 580ca7a8e85SJeff Kirsher 581ca7a8e85SJeff Kirsher if (!request_region(ioaddr, EL3_IO_EXTENT, "3c579-eisa")) 582ca7a8e85SJeff Kirsher return -EBUSY; 583ca7a8e85SJeff Kirsher 584ca7a8e85SJeff Kirsher /* Change the register set to the configuration window 0. */ 585ca7a8e85SJeff Kirsher outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD); 586ca7a8e85SJeff Kirsher 587ca7a8e85SJeff Kirsher irq = inw(ioaddr + WN0_IRQ) >> 12; 588ca7a8e85SJeff Kirsher if_port = inw(ioaddr + 6)>>14; 589ca7a8e85SJeff Kirsher for (i = 0; i < 3; i++) 590ca7a8e85SJeff Kirsher phys_addr[i] = htons(read_eeprom(ioaddr, i)); 591ca7a8e85SJeff Kirsher 592ca7a8e85SJeff Kirsher /* Restore the "Product ID" to the EEPROM read register. */ 593ca7a8e85SJeff Kirsher read_eeprom(ioaddr, 3); 594ca7a8e85SJeff Kirsher 595ca7a8e85SJeff Kirsher dev = alloc_etherdev(sizeof (struct el3_private)); 596ca7a8e85SJeff Kirsher if (dev == NULL) { 597ca7a8e85SJeff Kirsher release_region(ioaddr, EL3_IO_EXTENT); 598ca7a8e85SJeff Kirsher return -ENOMEM; 599ca7a8e85SJeff Kirsher } 600ca7a8e85SJeff Kirsher 601ca7a8e85SJeff Kirsher netdev_boot_setup_check(dev); 602ca7a8e85SJeff Kirsher 603ca7a8e85SJeff Kirsher el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA); 604ca7a8e85SJeff Kirsher eisa_set_drvdata (edev, dev); 605ca7a8e85SJeff Kirsher err = el3_common_init(dev); 606ca7a8e85SJeff Kirsher 607ca7a8e85SJeff Kirsher if (err) { 608ca7a8e85SJeff Kirsher eisa_set_drvdata (edev, NULL); 609ca7a8e85SJeff Kirsher free_netdev(dev); 610ca7a8e85SJeff Kirsher return err; 611ca7a8e85SJeff Kirsher } 612ca7a8e85SJeff Kirsher 613ca7a8e85SJeff Kirsher el3_devs[el3_cards++] = dev; 614ca7a8e85SJeff Kirsher return 0; 615ca7a8e85SJeff Kirsher } 616ca7a8e85SJeff Kirsher #endif 617ca7a8e85SJeff Kirsher 618ca7a8e85SJeff Kirsher /* This remove works for all device types. 619ca7a8e85SJeff Kirsher * 620ca7a8e85SJeff Kirsher * The net dev must be stored in the driver data field */ 6212791cf7aSBill Pemberton static int el3_device_remove(struct device *device) 622ca7a8e85SJeff Kirsher { 623ca7a8e85SJeff Kirsher struct net_device *dev; 624ca7a8e85SJeff Kirsher 625ca7a8e85SJeff Kirsher dev = dev_get_drvdata(device); 626ca7a8e85SJeff Kirsher 627ca7a8e85SJeff Kirsher el3_common_remove (dev); 628ca7a8e85SJeff Kirsher return 0; 629ca7a8e85SJeff Kirsher } 630ca7a8e85SJeff Kirsher 631ca7a8e85SJeff Kirsher /* Read a word from the EEPROM using the regular EEPROM access register. 632ca7a8e85SJeff Kirsher Assume that we are in register window zero. 633ca7a8e85SJeff Kirsher */ 634ca7a8e85SJeff Kirsher static ushort read_eeprom(int ioaddr, int index) 635ca7a8e85SJeff Kirsher { 636ca7a8e85SJeff Kirsher outw(EEPROM_READ + index, ioaddr + 10); 637ca7a8e85SJeff Kirsher /* Pause for at least 162 us. for the read to take place. 638ca7a8e85SJeff Kirsher Some chips seem to require much longer */ 639ca7a8e85SJeff Kirsher mdelay(2); 640ca7a8e85SJeff Kirsher return inw(ioaddr + 12); 641ca7a8e85SJeff Kirsher } 642ca7a8e85SJeff Kirsher 643ca7a8e85SJeff Kirsher /* Read a word from the EEPROM when in the ISA ID probe state. */ 644ca7a8e85SJeff Kirsher static ushort id_read_eeprom(int index) 645ca7a8e85SJeff Kirsher { 646ca7a8e85SJeff Kirsher int bit, word = 0; 647ca7a8e85SJeff Kirsher 648ca7a8e85SJeff Kirsher /* Issue read command, and pause for at least 162 us. for it to complete. 649ca7a8e85SJeff Kirsher Assume extra-fast 16Mhz bus. */ 650ca7a8e85SJeff Kirsher outb(EEPROM_READ + index, id_port); 651ca7a8e85SJeff Kirsher 652ca7a8e85SJeff Kirsher /* Pause for at least 162 us. for the read to take place. */ 653ca7a8e85SJeff Kirsher /* Some chips seem to require much longer */ 654ca7a8e85SJeff Kirsher mdelay(4); 655ca7a8e85SJeff Kirsher 656ca7a8e85SJeff Kirsher for (bit = 15; bit >= 0; bit--) 657ca7a8e85SJeff Kirsher word = (word << 1) + (inb(id_port) & 0x01); 658ca7a8e85SJeff Kirsher 659ca7a8e85SJeff Kirsher if (el3_debug > 3) 660ca7a8e85SJeff Kirsher pr_debug(" 3c509 EEPROM word %d %#4.4x.\n", index, word); 661ca7a8e85SJeff Kirsher 662ca7a8e85SJeff Kirsher return word; 663ca7a8e85SJeff Kirsher } 664ca7a8e85SJeff Kirsher 665ca7a8e85SJeff Kirsher 666ca7a8e85SJeff Kirsher static int 667ca7a8e85SJeff Kirsher el3_open(struct net_device *dev) 668ca7a8e85SJeff Kirsher { 669ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 670ca7a8e85SJeff Kirsher int i; 671ca7a8e85SJeff Kirsher 672ca7a8e85SJeff Kirsher outw(TxReset, ioaddr + EL3_CMD); 673ca7a8e85SJeff Kirsher outw(RxReset, ioaddr + EL3_CMD); 674ca7a8e85SJeff Kirsher outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD); 675ca7a8e85SJeff Kirsher 676ca7a8e85SJeff Kirsher i = request_irq(dev->irq, el3_interrupt, 0, dev->name, dev); 677ca7a8e85SJeff Kirsher if (i) 678ca7a8e85SJeff Kirsher return i; 679ca7a8e85SJeff Kirsher 680ca7a8e85SJeff Kirsher EL3WINDOW(0); 681ca7a8e85SJeff Kirsher if (el3_debug > 3) 682ca7a8e85SJeff Kirsher pr_debug("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name, 683ca7a8e85SJeff Kirsher dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS)); 684ca7a8e85SJeff Kirsher 685ca7a8e85SJeff Kirsher el3_up(dev); 686ca7a8e85SJeff Kirsher 687ca7a8e85SJeff Kirsher if (el3_debug > 3) 688ca7a8e85SJeff Kirsher pr_debug("%s: Opened 3c509 IRQ %d status %4.4x.\n", 689ca7a8e85SJeff Kirsher dev->name, dev->irq, inw(ioaddr + EL3_STATUS)); 690ca7a8e85SJeff Kirsher 691ca7a8e85SJeff Kirsher return 0; 692ca7a8e85SJeff Kirsher } 693ca7a8e85SJeff Kirsher 694ca7a8e85SJeff Kirsher static void 695ca7a8e85SJeff Kirsher el3_tx_timeout (struct net_device *dev) 696ca7a8e85SJeff Kirsher { 697ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 698ca7a8e85SJeff Kirsher 699ca7a8e85SJeff Kirsher /* Transmitter timeout, serious problems. */ 700ca7a8e85SJeff Kirsher pr_warning("%s: transmit timed out, Tx_status %2.2x status %4.4x Tx FIFO room %d.\n", 701ca7a8e85SJeff Kirsher dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS), 702ca7a8e85SJeff Kirsher inw(ioaddr + TX_FREE)); 703ca7a8e85SJeff Kirsher dev->stats.tx_errors++; 704ca7a8e85SJeff Kirsher dev->trans_start = jiffies; /* prevent tx timeout */ 705ca7a8e85SJeff Kirsher /* Issue TX_RESET and TX_START commands. */ 706ca7a8e85SJeff Kirsher outw(TxReset, ioaddr + EL3_CMD); 707ca7a8e85SJeff Kirsher outw(TxEnable, ioaddr + EL3_CMD); 708ca7a8e85SJeff Kirsher netif_wake_queue(dev); 709ca7a8e85SJeff Kirsher } 710ca7a8e85SJeff Kirsher 711ca7a8e85SJeff Kirsher 712ca7a8e85SJeff Kirsher static netdev_tx_t 713ca7a8e85SJeff Kirsher el3_start_xmit(struct sk_buff *skb, struct net_device *dev) 714ca7a8e85SJeff Kirsher { 715ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(dev); 716ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 717ca7a8e85SJeff Kirsher unsigned long flags; 718ca7a8e85SJeff Kirsher 719ca7a8e85SJeff Kirsher netif_stop_queue (dev); 720ca7a8e85SJeff Kirsher 721ca7a8e85SJeff Kirsher dev->stats.tx_bytes += skb->len; 722ca7a8e85SJeff Kirsher 723ca7a8e85SJeff Kirsher if (el3_debug > 4) { 724ca7a8e85SJeff Kirsher pr_debug("%s: el3_start_xmit(length = %u) called, status %4.4x.\n", 725ca7a8e85SJeff Kirsher dev->name, skb->len, inw(ioaddr + EL3_STATUS)); 726ca7a8e85SJeff Kirsher } 727ca7a8e85SJeff Kirsher #if 0 728ca7a8e85SJeff Kirsher #ifndef final_version 729ca7a8e85SJeff Kirsher { /* Error-checking code, delete someday. */ 730ca7a8e85SJeff Kirsher ushort status = inw(ioaddr + EL3_STATUS); 731ca7a8e85SJeff Kirsher if (status & 0x0001 && /* IRQ line active, missed one. */ 732ca7a8e85SJeff Kirsher inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */ 733ca7a8e85SJeff Kirsher pr_debug("%s: Missed interrupt, status then %04x now %04x" 734ca7a8e85SJeff Kirsher " Tx %2.2x Rx %4.4x.\n", dev->name, status, 735ca7a8e85SJeff Kirsher inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS), 736ca7a8e85SJeff Kirsher inw(ioaddr + RX_STATUS)); 737ca7a8e85SJeff Kirsher /* Fake interrupt trigger by masking, acknowledge interrupts. */ 738ca7a8e85SJeff Kirsher outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD); 739ca7a8e85SJeff Kirsher outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, 740ca7a8e85SJeff Kirsher ioaddr + EL3_CMD); 741ca7a8e85SJeff Kirsher outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD); 742ca7a8e85SJeff Kirsher } 743ca7a8e85SJeff Kirsher } 744ca7a8e85SJeff Kirsher #endif 745ca7a8e85SJeff Kirsher #endif 746ca7a8e85SJeff Kirsher /* 747ca7a8e85SJeff Kirsher * We lock the driver against other processors. Note 748ca7a8e85SJeff Kirsher * we don't need to lock versus the IRQ as we suspended 749ca7a8e85SJeff Kirsher * that. This means that we lose the ability to take 750ca7a8e85SJeff Kirsher * an RX during a TX upload. That sucks a bit with SMP 751ca7a8e85SJeff Kirsher * on an original 3c509 (2K buffer) 752ca7a8e85SJeff Kirsher * 753ca7a8e85SJeff Kirsher * Using disable_irq stops us crapping on other 754ca7a8e85SJeff Kirsher * time sensitive devices. 755ca7a8e85SJeff Kirsher */ 756ca7a8e85SJeff Kirsher 757ca7a8e85SJeff Kirsher spin_lock_irqsave(&lp->lock, flags); 758ca7a8e85SJeff Kirsher 759ca7a8e85SJeff Kirsher /* Put out the doubleword header... */ 760ca7a8e85SJeff Kirsher outw(skb->len, ioaddr + TX_FIFO); 761ca7a8e85SJeff Kirsher outw(0x00, ioaddr + TX_FIFO); 762ca7a8e85SJeff Kirsher /* ... and the packet rounded to a doubleword. */ 763ca7a8e85SJeff Kirsher outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); 764ca7a8e85SJeff Kirsher 765ca7a8e85SJeff Kirsher if (inw(ioaddr + TX_FREE) > 1536) 766ca7a8e85SJeff Kirsher netif_start_queue(dev); 767ca7a8e85SJeff Kirsher else 768ca7a8e85SJeff Kirsher /* Interrupt us when the FIFO has room for max-sized packet. */ 769ca7a8e85SJeff Kirsher outw(SetTxThreshold + 1536, ioaddr + EL3_CMD); 770ca7a8e85SJeff Kirsher 771ca7a8e85SJeff Kirsher spin_unlock_irqrestore(&lp->lock, flags); 772ca7a8e85SJeff Kirsher 773ca7a8e85SJeff Kirsher dev_kfree_skb (skb); 774ca7a8e85SJeff Kirsher 775ca7a8e85SJeff Kirsher /* Clear the Tx status stack. */ 776ca7a8e85SJeff Kirsher { 777ca7a8e85SJeff Kirsher short tx_status; 778ca7a8e85SJeff Kirsher int i = 4; 779ca7a8e85SJeff Kirsher 780ca7a8e85SJeff Kirsher while (--i > 0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) { 781ca7a8e85SJeff Kirsher if (tx_status & 0x38) dev->stats.tx_aborted_errors++; 782ca7a8e85SJeff Kirsher if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD); 783ca7a8e85SJeff Kirsher if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD); 784ca7a8e85SJeff Kirsher outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */ 785ca7a8e85SJeff Kirsher } 786ca7a8e85SJeff Kirsher } 787ca7a8e85SJeff Kirsher return NETDEV_TX_OK; 788ca7a8e85SJeff Kirsher } 789ca7a8e85SJeff Kirsher 790ca7a8e85SJeff Kirsher /* The EL3 interrupt handler. */ 791ca7a8e85SJeff Kirsher static irqreturn_t 792ca7a8e85SJeff Kirsher el3_interrupt(int irq, void *dev_id) 793ca7a8e85SJeff Kirsher { 794ca7a8e85SJeff Kirsher struct net_device *dev = dev_id; 795ca7a8e85SJeff Kirsher struct el3_private *lp; 796ca7a8e85SJeff Kirsher int ioaddr, status; 797ca7a8e85SJeff Kirsher int i = max_interrupt_work; 798ca7a8e85SJeff Kirsher 799ca7a8e85SJeff Kirsher lp = netdev_priv(dev); 800ca7a8e85SJeff Kirsher spin_lock(&lp->lock); 801ca7a8e85SJeff Kirsher 802ca7a8e85SJeff Kirsher ioaddr = dev->base_addr; 803ca7a8e85SJeff Kirsher 804ca7a8e85SJeff Kirsher if (el3_debug > 4) { 805ca7a8e85SJeff Kirsher status = inw(ioaddr + EL3_STATUS); 806ca7a8e85SJeff Kirsher pr_debug("%s: interrupt, status %4.4x.\n", dev->name, status); 807ca7a8e85SJeff Kirsher } 808ca7a8e85SJeff Kirsher 809ca7a8e85SJeff Kirsher while ((status = inw(ioaddr + EL3_STATUS)) & 810ca7a8e85SJeff Kirsher (IntLatch | RxComplete | StatsFull)) { 811ca7a8e85SJeff Kirsher 812ca7a8e85SJeff Kirsher if (status & RxComplete) 813ca7a8e85SJeff Kirsher el3_rx(dev); 814ca7a8e85SJeff Kirsher 815ca7a8e85SJeff Kirsher if (status & TxAvailable) { 816ca7a8e85SJeff Kirsher if (el3_debug > 5) 817ca7a8e85SJeff Kirsher pr_debug(" TX room bit was handled.\n"); 818ca7a8e85SJeff Kirsher /* There's room in the FIFO for a full-sized packet. */ 819ca7a8e85SJeff Kirsher outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); 820ca7a8e85SJeff Kirsher netif_wake_queue (dev); 821ca7a8e85SJeff Kirsher } 822ca7a8e85SJeff Kirsher if (status & (AdapterFailure | RxEarly | StatsFull | TxComplete)) { 823ca7a8e85SJeff Kirsher /* Handle all uncommon interrupts. */ 824ca7a8e85SJeff Kirsher if (status & StatsFull) /* Empty statistics. */ 825ca7a8e85SJeff Kirsher update_stats(dev); 826ca7a8e85SJeff Kirsher if (status & RxEarly) { /* Rx early is unused. */ 827ca7a8e85SJeff Kirsher el3_rx(dev); 828ca7a8e85SJeff Kirsher outw(AckIntr | RxEarly, ioaddr + EL3_CMD); 829ca7a8e85SJeff Kirsher } 830ca7a8e85SJeff Kirsher if (status & TxComplete) { /* Really Tx error. */ 831ca7a8e85SJeff Kirsher short tx_status; 832ca7a8e85SJeff Kirsher int i = 4; 833ca7a8e85SJeff Kirsher 834ca7a8e85SJeff Kirsher while (--i>0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) { 835ca7a8e85SJeff Kirsher if (tx_status & 0x38) dev->stats.tx_aborted_errors++; 836ca7a8e85SJeff Kirsher if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD); 837ca7a8e85SJeff Kirsher if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD); 838ca7a8e85SJeff Kirsher outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */ 839ca7a8e85SJeff Kirsher } 840ca7a8e85SJeff Kirsher } 841ca7a8e85SJeff Kirsher if (status & AdapterFailure) { 842ca7a8e85SJeff Kirsher /* Adapter failure requires Rx reset and reinit. */ 843ca7a8e85SJeff Kirsher outw(RxReset, ioaddr + EL3_CMD); 844ca7a8e85SJeff Kirsher /* Set the Rx filter to the current state. */ 845ca7a8e85SJeff Kirsher outw(SetRxFilter | RxStation | RxBroadcast 846ca7a8e85SJeff Kirsher | (dev->flags & IFF_ALLMULTI ? RxMulticast : 0) 847ca7a8e85SJeff Kirsher | (dev->flags & IFF_PROMISC ? RxProm : 0), 848ca7a8e85SJeff Kirsher ioaddr + EL3_CMD); 849ca7a8e85SJeff Kirsher outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */ 850ca7a8e85SJeff Kirsher outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); 851ca7a8e85SJeff Kirsher } 852ca7a8e85SJeff Kirsher } 853ca7a8e85SJeff Kirsher 854ca7a8e85SJeff Kirsher if (--i < 0) { 855ca7a8e85SJeff Kirsher pr_err("%s: Infinite loop in interrupt, status %4.4x.\n", 856ca7a8e85SJeff Kirsher dev->name, status); 857ca7a8e85SJeff Kirsher /* Clear all interrupts. */ 858ca7a8e85SJeff Kirsher outw(AckIntr | 0xFF, ioaddr + EL3_CMD); 859ca7a8e85SJeff Kirsher break; 860ca7a8e85SJeff Kirsher } 861ca7a8e85SJeff Kirsher /* Acknowledge the IRQ. */ 862ca7a8e85SJeff Kirsher outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); /* Ack IRQ */ 863ca7a8e85SJeff Kirsher } 864ca7a8e85SJeff Kirsher 865ca7a8e85SJeff Kirsher if (el3_debug > 4) { 866ca7a8e85SJeff Kirsher pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name, 867ca7a8e85SJeff Kirsher inw(ioaddr + EL3_STATUS)); 868ca7a8e85SJeff Kirsher } 869ca7a8e85SJeff Kirsher spin_unlock(&lp->lock); 870ca7a8e85SJeff Kirsher return IRQ_HANDLED; 871ca7a8e85SJeff Kirsher } 872ca7a8e85SJeff Kirsher 873ca7a8e85SJeff Kirsher 874ca7a8e85SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 875ca7a8e85SJeff Kirsher /* 876ca7a8e85SJeff Kirsher * Polling receive - used by netconsole and other diagnostic tools 877ca7a8e85SJeff Kirsher * to allow network i/o with interrupts disabled. 878ca7a8e85SJeff Kirsher */ 879ca7a8e85SJeff Kirsher static void el3_poll_controller(struct net_device *dev) 880ca7a8e85SJeff Kirsher { 881ca7a8e85SJeff Kirsher disable_irq(dev->irq); 882ca7a8e85SJeff Kirsher el3_interrupt(dev->irq, dev); 883ca7a8e85SJeff Kirsher enable_irq(dev->irq); 884ca7a8e85SJeff Kirsher } 885ca7a8e85SJeff Kirsher #endif 886ca7a8e85SJeff Kirsher 887ca7a8e85SJeff Kirsher static struct net_device_stats * 888ca7a8e85SJeff Kirsher el3_get_stats(struct net_device *dev) 889ca7a8e85SJeff Kirsher { 890ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(dev); 891ca7a8e85SJeff Kirsher unsigned long flags; 892ca7a8e85SJeff Kirsher 893ca7a8e85SJeff Kirsher /* 894ca7a8e85SJeff Kirsher * This is fast enough not to bother with disable IRQ 895ca7a8e85SJeff Kirsher * stuff. 896ca7a8e85SJeff Kirsher */ 897ca7a8e85SJeff Kirsher 898ca7a8e85SJeff Kirsher spin_lock_irqsave(&lp->lock, flags); 899ca7a8e85SJeff Kirsher update_stats(dev); 900ca7a8e85SJeff Kirsher spin_unlock_irqrestore(&lp->lock, flags); 901ca7a8e85SJeff Kirsher return &dev->stats; 902ca7a8e85SJeff Kirsher } 903ca7a8e85SJeff Kirsher 904ca7a8e85SJeff Kirsher /* Update statistics. We change to register window 6, so this should be run 905ca7a8e85SJeff Kirsher single-threaded if the device is active. This is expected to be a rare 906ca7a8e85SJeff Kirsher operation, and it's simpler for the rest of the driver to assume that 907ca7a8e85SJeff Kirsher window 1 is always valid rather than use a special window-state variable. 908ca7a8e85SJeff Kirsher */ 909ca7a8e85SJeff Kirsher static void update_stats(struct net_device *dev) 910ca7a8e85SJeff Kirsher { 911ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 912ca7a8e85SJeff Kirsher 913ca7a8e85SJeff Kirsher if (el3_debug > 5) 914ca7a8e85SJeff Kirsher pr_debug(" Updating the statistics.\n"); 915ca7a8e85SJeff Kirsher /* Turn off statistics updates while reading. */ 916ca7a8e85SJeff Kirsher outw(StatsDisable, ioaddr + EL3_CMD); 917ca7a8e85SJeff Kirsher /* Switch to the stats window, and read everything. */ 918ca7a8e85SJeff Kirsher EL3WINDOW(6); 919ca7a8e85SJeff Kirsher dev->stats.tx_carrier_errors += inb(ioaddr + 0); 920ca7a8e85SJeff Kirsher dev->stats.tx_heartbeat_errors += inb(ioaddr + 1); 921ca7a8e85SJeff Kirsher /* Multiple collisions. */ inb(ioaddr + 2); 922ca7a8e85SJeff Kirsher dev->stats.collisions += inb(ioaddr + 3); 923ca7a8e85SJeff Kirsher dev->stats.tx_window_errors += inb(ioaddr + 4); 924ca7a8e85SJeff Kirsher dev->stats.rx_fifo_errors += inb(ioaddr + 5); 925ca7a8e85SJeff Kirsher dev->stats.tx_packets += inb(ioaddr + 6); 926ca7a8e85SJeff Kirsher /* Rx packets */ inb(ioaddr + 7); 927ca7a8e85SJeff Kirsher /* Tx deferrals */ inb(ioaddr + 8); 928ca7a8e85SJeff Kirsher inw(ioaddr + 10); /* Total Rx and Tx octets. */ 929ca7a8e85SJeff Kirsher inw(ioaddr + 12); 930ca7a8e85SJeff Kirsher 931ca7a8e85SJeff Kirsher /* Back to window 1, and turn statistics back on. */ 932ca7a8e85SJeff Kirsher EL3WINDOW(1); 933ca7a8e85SJeff Kirsher outw(StatsEnable, ioaddr + EL3_CMD); 934ca7a8e85SJeff Kirsher } 935ca7a8e85SJeff Kirsher 936ca7a8e85SJeff Kirsher static int 937ca7a8e85SJeff Kirsher el3_rx(struct net_device *dev) 938ca7a8e85SJeff Kirsher { 939ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 940ca7a8e85SJeff Kirsher short rx_status; 941ca7a8e85SJeff Kirsher 942ca7a8e85SJeff Kirsher if (el3_debug > 5) 943ca7a8e85SJeff Kirsher pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n", 944ca7a8e85SJeff Kirsher inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS)); 945ca7a8e85SJeff Kirsher while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) { 946ca7a8e85SJeff Kirsher if (rx_status & 0x4000) { /* Error, update stats. */ 947ca7a8e85SJeff Kirsher short error = rx_status & 0x3800; 948ca7a8e85SJeff Kirsher 949ca7a8e85SJeff Kirsher outw(RxDiscard, ioaddr + EL3_CMD); 950ca7a8e85SJeff Kirsher dev->stats.rx_errors++; 951ca7a8e85SJeff Kirsher switch (error) { 952ca7a8e85SJeff Kirsher case 0x0000: dev->stats.rx_over_errors++; break; 953ca7a8e85SJeff Kirsher case 0x0800: dev->stats.rx_length_errors++; break; 954ca7a8e85SJeff Kirsher case 0x1000: dev->stats.rx_frame_errors++; break; 955ca7a8e85SJeff Kirsher case 0x1800: dev->stats.rx_length_errors++; break; 956ca7a8e85SJeff Kirsher case 0x2000: dev->stats.rx_frame_errors++; break; 957ca7a8e85SJeff Kirsher case 0x2800: dev->stats.rx_crc_errors++; break; 958ca7a8e85SJeff Kirsher } 959ca7a8e85SJeff Kirsher } else { 960ca7a8e85SJeff Kirsher short pkt_len = rx_status & 0x7ff; 961ca7a8e85SJeff Kirsher struct sk_buff *skb; 962ca7a8e85SJeff Kirsher 9631d266430SPradeep A Dalvi skb = netdev_alloc_skb(dev, pkt_len + 5); 964ca7a8e85SJeff Kirsher if (el3_debug > 4) 965ca7a8e85SJeff Kirsher pr_debug("Receiving packet size %d status %4.4x.\n", 966ca7a8e85SJeff Kirsher pkt_len, rx_status); 967ca7a8e85SJeff Kirsher if (skb != NULL) { 968ca7a8e85SJeff Kirsher skb_reserve(skb, 2); /* Align IP on 16 byte */ 969ca7a8e85SJeff Kirsher 970ca7a8e85SJeff Kirsher /* 'skb->data' points to the start of sk_buff data area. */ 971ca7a8e85SJeff Kirsher insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len), 972ca7a8e85SJeff Kirsher (pkt_len + 3) >> 2); 973ca7a8e85SJeff Kirsher 974ca7a8e85SJeff Kirsher outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */ 975ca7a8e85SJeff Kirsher skb->protocol = eth_type_trans(skb,dev); 976ca7a8e85SJeff Kirsher netif_rx(skb); 977ca7a8e85SJeff Kirsher dev->stats.rx_bytes += pkt_len; 978ca7a8e85SJeff Kirsher dev->stats.rx_packets++; 979ca7a8e85SJeff Kirsher continue; 980ca7a8e85SJeff Kirsher } 981ca7a8e85SJeff Kirsher outw(RxDiscard, ioaddr + EL3_CMD); 982ca7a8e85SJeff Kirsher dev->stats.rx_dropped++; 983ca7a8e85SJeff Kirsher if (el3_debug) 984ca7a8e85SJeff Kirsher pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n", 985ca7a8e85SJeff Kirsher dev->name, pkt_len); 986ca7a8e85SJeff Kirsher } 987ca7a8e85SJeff Kirsher inw(ioaddr + EL3_STATUS); /* Delay. */ 988ca7a8e85SJeff Kirsher while (inw(ioaddr + EL3_STATUS) & 0x1000) 989ca7a8e85SJeff Kirsher pr_debug(" Waiting for 3c509 to discard packet, status %x.\n", 990ca7a8e85SJeff Kirsher inw(ioaddr + EL3_STATUS) ); 991ca7a8e85SJeff Kirsher } 992ca7a8e85SJeff Kirsher 993ca7a8e85SJeff Kirsher return 0; 994ca7a8e85SJeff Kirsher } 995ca7a8e85SJeff Kirsher 996ca7a8e85SJeff Kirsher /* 997ca7a8e85SJeff Kirsher * Set or clear the multicast filter for this adaptor. 998ca7a8e85SJeff Kirsher */ 999ca7a8e85SJeff Kirsher static void 1000ca7a8e85SJeff Kirsher set_multicast_list(struct net_device *dev) 1001ca7a8e85SJeff Kirsher { 1002ca7a8e85SJeff Kirsher unsigned long flags; 1003ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(dev); 1004ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 1005ca7a8e85SJeff Kirsher int mc_count = netdev_mc_count(dev); 1006ca7a8e85SJeff Kirsher 1007ca7a8e85SJeff Kirsher if (el3_debug > 1) { 1008ca7a8e85SJeff Kirsher static int old; 1009ca7a8e85SJeff Kirsher if (old != mc_count) { 1010ca7a8e85SJeff Kirsher old = mc_count; 1011ca7a8e85SJeff Kirsher pr_debug("%s: Setting Rx mode to %d addresses.\n", 1012ca7a8e85SJeff Kirsher dev->name, mc_count); 1013ca7a8e85SJeff Kirsher } 1014ca7a8e85SJeff Kirsher } 1015ca7a8e85SJeff Kirsher spin_lock_irqsave(&lp->lock, flags); 1016ca7a8e85SJeff Kirsher if (dev->flags&IFF_PROMISC) { 1017ca7a8e85SJeff Kirsher outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm, 1018ca7a8e85SJeff Kirsher ioaddr + EL3_CMD); 1019ca7a8e85SJeff Kirsher } 1020ca7a8e85SJeff Kirsher else if (mc_count || (dev->flags&IFF_ALLMULTI)) { 1021ca7a8e85SJeff Kirsher outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast, ioaddr + EL3_CMD); 1022ca7a8e85SJeff Kirsher } 1023ca7a8e85SJeff Kirsher else 1024ca7a8e85SJeff Kirsher outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); 1025ca7a8e85SJeff Kirsher spin_unlock_irqrestore(&lp->lock, flags); 1026ca7a8e85SJeff Kirsher } 1027ca7a8e85SJeff Kirsher 1028ca7a8e85SJeff Kirsher static int 1029ca7a8e85SJeff Kirsher el3_close(struct net_device *dev) 1030ca7a8e85SJeff Kirsher { 1031ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 1032ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(dev); 1033ca7a8e85SJeff Kirsher 1034ca7a8e85SJeff Kirsher if (el3_debug > 2) 1035ca7a8e85SJeff Kirsher pr_debug("%s: Shutting down ethercard.\n", dev->name); 1036ca7a8e85SJeff Kirsher 1037ca7a8e85SJeff Kirsher el3_down(dev); 1038ca7a8e85SJeff Kirsher 1039ca7a8e85SJeff Kirsher free_irq(dev->irq, dev); 1040ca7a8e85SJeff Kirsher /* Switching back to window 0 disables the IRQ. */ 1041ca7a8e85SJeff Kirsher EL3WINDOW(0); 1042ca7a8e85SJeff Kirsher if (lp->type != EL3_EISA) { 1043ca7a8e85SJeff Kirsher /* But we explicitly zero the IRQ line select anyway. Don't do 1044ca7a8e85SJeff Kirsher * it on EISA cards, it prevents the module from getting an 1045ca7a8e85SJeff Kirsher * IRQ after unload+reload... */ 1046ca7a8e85SJeff Kirsher outw(0x0f00, ioaddr + WN0_IRQ); 1047ca7a8e85SJeff Kirsher } 1048ca7a8e85SJeff Kirsher 1049ca7a8e85SJeff Kirsher return 0; 1050ca7a8e85SJeff Kirsher } 1051ca7a8e85SJeff Kirsher 1052ca7a8e85SJeff Kirsher static int 1053ca7a8e85SJeff Kirsher el3_link_ok(struct net_device *dev) 1054ca7a8e85SJeff Kirsher { 1055ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 1056ca7a8e85SJeff Kirsher u16 tmp; 1057ca7a8e85SJeff Kirsher 1058ca7a8e85SJeff Kirsher EL3WINDOW(4); 1059ca7a8e85SJeff Kirsher tmp = inw(ioaddr + WN4_MEDIA); 1060ca7a8e85SJeff Kirsher EL3WINDOW(1); 1061ca7a8e85SJeff Kirsher return tmp & (1<<11); 1062ca7a8e85SJeff Kirsher } 1063ca7a8e85SJeff Kirsher 1064ca7a8e85SJeff Kirsher static int 1065ca7a8e85SJeff Kirsher el3_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) 1066ca7a8e85SJeff Kirsher { 1067ca7a8e85SJeff Kirsher u16 tmp; 1068ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 1069ca7a8e85SJeff Kirsher 1070ca7a8e85SJeff Kirsher EL3WINDOW(0); 1071ca7a8e85SJeff Kirsher /* obtain current transceiver via WN4_MEDIA? */ 1072ca7a8e85SJeff Kirsher tmp = inw(ioaddr + WN0_ADDR_CONF); 1073ca7a8e85SJeff Kirsher ecmd->transceiver = XCVR_INTERNAL; 1074ca7a8e85SJeff Kirsher switch (tmp >> 14) { 1075ca7a8e85SJeff Kirsher case 0: 1076ca7a8e85SJeff Kirsher ecmd->port = PORT_TP; 1077ca7a8e85SJeff Kirsher break; 1078ca7a8e85SJeff Kirsher case 1: 1079ca7a8e85SJeff Kirsher ecmd->port = PORT_AUI; 1080ca7a8e85SJeff Kirsher ecmd->transceiver = XCVR_EXTERNAL; 1081ca7a8e85SJeff Kirsher break; 1082ca7a8e85SJeff Kirsher case 3: 1083ca7a8e85SJeff Kirsher ecmd->port = PORT_BNC; 1084ca7a8e85SJeff Kirsher default: 1085ca7a8e85SJeff Kirsher break; 1086ca7a8e85SJeff Kirsher } 1087ca7a8e85SJeff Kirsher 1088ca7a8e85SJeff Kirsher ecmd->duplex = DUPLEX_HALF; 1089ca7a8e85SJeff Kirsher ecmd->supported = 0; 1090ca7a8e85SJeff Kirsher tmp = inw(ioaddr + WN0_CONF_CTRL); 1091ca7a8e85SJeff Kirsher if (tmp & (1<<13)) 1092ca7a8e85SJeff Kirsher ecmd->supported |= SUPPORTED_AUI; 1093ca7a8e85SJeff Kirsher if (tmp & (1<<12)) 1094ca7a8e85SJeff Kirsher ecmd->supported |= SUPPORTED_BNC; 1095ca7a8e85SJeff Kirsher if (tmp & (1<<9)) { 1096ca7a8e85SJeff Kirsher ecmd->supported |= SUPPORTED_TP | SUPPORTED_10baseT_Half | 1097ca7a8e85SJeff Kirsher SUPPORTED_10baseT_Full; /* hmm... */ 1098ca7a8e85SJeff Kirsher EL3WINDOW(4); 1099ca7a8e85SJeff Kirsher tmp = inw(ioaddr + WN4_NETDIAG); 1100ca7a8e85SJeff Kirsher if (tmp & FD_ENABLE) 1101ca7a8e85SJeff Kirsher ecmd->duplex = DUPLEX_FULL; 1102ca7a8e85SJeff Kirsher } 1103ca7a8e85SJeff Kirsher 1104ca7a8e85SJeff Kirsher ethtool_cmd_speed_set(ecmd, SPEED_10); 1105ca7a8e85SJeff Kirsher EL3WINDOW(1); 1106ca7a8e85SJeff Kirsher return 0; 1107ca7a8e85SJeff Kirsher } 1108ca7a8e85SJeff Kirsher 1109ca7a8e85SJeff Kirsher static int 1110ca7a8e85SJeff Kirsher el3_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) 1111ca7a8e85SJeff Kirsher { 1112ca7a8e85SJeff Kirsher u16 tmp; 1113ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 1114ca7a8e85SJeff Kirsher 1115ca7a8e85SJeff Kirsher if (ecmd->speed != SPEED_10) 1116ca7a8e85SJeff Kirsher return -EINVAL; 1117ca7a8e85SJeff Kirsher if ((ecmd->duplex != DUPLEX_HALF) && (ecmd->duplex != DUPLEX_FULL)) 1118ca7a8e85SJeff Kirsher return -EINVAL; 1119ca7a8e85SJeff Kirsher if ((ecmd->transceiver != XCVR_INTERNAL) && (ecmd->transceiver != XCVR_EXTERNAL)) 1120ca7a8e85SJeff Kirsher return -EINVAL; 1121ca7a8e85SJeff Kirsher 1122ca7a8e85SJeff Kirsher /* change XCVR type */ 1123ca7a8e85SJeff Kirsher EL3WINDOW(0); 1124ca7a8e85SJeff Kirsher tmp = inw(ioaddr + WN0_ADDR_CONF); 1125ca7a8e85SJeff Kirsher switch (ecmd->port) { 1126ca7a8e85SJeff Kirsher case PORT_TP: 1127ca7a8e85SJeff Kirsher tmp &= ~(3<<14); 1128ca7a8e85SJeff Kirsher dev->if_port = 0; 1129ca7a8e85SJeff Kirsher break; 1130ca7a8e85SJeff Kirsher case PORT_AUI: 1131ca7a8e85SJeff Kirsher tmp |= (1<<14); 1132ca7a8e85SJeff Kirsher dev->if_port = 1; 1133ca7a8e85SJeff Kirsher break; 1134ca7a8e85SJeff Kirsher case PORT_BNC: 1135ca7a8e85SJeff Kirsher tmp |= (3<<14); 1136ca7a8e85SJeff Kirsher dev->if_port = 3; 1137ca7a8e85SJeff Kirsher break; 1138ca7a8e85SJeff Kirsher default: 1139ca7a8e85SJeff Kirsher return -EINVAL; 1140ca7a8e85SJeff Kirsher } 1141ca7a8e85SJeff Kirsher 1142ca7a8e85SJeff Kirsher outw(tmp, ioaddr + WN0_ADDR_CONF); 1143ca7a8e85SJeff Kirsher if (dev->if_port == 3) { 1144ca7a8e85SJeff Kirsher /* fire up the DC-DC convertor if BNC gets enabled */ 1145ca7a8e85SJeff Kirsher tmp = inw(ioaddr + WN0_ADDR_CONF); 1146ca7a8e85SJeff Kirsher if (tmp & (3 << 14)) { 1147ca7a8e85SJeff Kirsher outw(StartCoax, ioaddr + EL3_CMD); 1148ca7a8e85SJeff Kirsher udelay(800); 1149ca7a8e85SJeff Kirsher } else 1150ca7a8e85SJeff Kirsher return -EIO; 1151ca7a8e85SJeff Kirsher } 1152ca7a8e85SJeff Kirsher 1153ca7a8e85SJeff Kirsher EL3WINDOW(4); 1154ca7a8e85SJeff Kirsher tmp = inw(ioaddr + WN4_NETDIAG); 1155ca7a8e85SJeff Kirsher if (ecmd->duplex == DUPLEX_FULL) 1156ca7a8e85SJeff Kirsher tmp |= FD_ENABLE; 1157ca7a8e85SJeff Kirsher else 1158ca7a8e85SJeff Kirsher tmp &= ~FD_ENABLE; 1159ca7a8e85SJeff Kirsher outw(tmp, ioaddr + WN4_NETDIAG); 1160ca7a8e85SJeff Kirsher EL3WINDOW(1); 1161ca7a8e85SJeff Kirsher 1162ca7a8e85SJeff Kirsher return 0; 1163ca7a8e85SJeff Kirsher } 1164ca7a8e85SJeff Kirsher 1165ca7a8e85SJeff Kirsher static void el3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 1166ca7a8e85SJeff Kirsher { 1167ca7a8e85SJeff Kirsher strcpy(info->driver, DRV_NAME); 1168ca7a8e85SJeff Kirsher strcpy(info->version, DRV_VERSION); 1169ca7a8e85SJeff Kirsher } 1170ca7a8e85SJeff Kirsher 1171ca7a8e85SJeff Kirsher static int el3_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 1172ca7a8e85SJeff Kirsher { 1173ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(dev); 1174ca7a8e85SJeff Kirsher int ret; 1175ca7a8e85SJeff Kirsher 1176ca7a8e85SJeff Kirsher spin_lock_irq(&lp->lock); 1177ca7a8e85SJeff Kirsher ret = el3_netdev_get_ecmd(dev, ecmd); 1178ca7a8e85SJeff Kirsher spin_unlock_irq(&lp->lock); 1179ca7a8e85SJeff Kirsher return ret; 1180ca7a8e85SJeff Kirsher } 1181ca7a8e85SJeff Kirsher 1182ca7a8e85SJeff Kirsher static int el3_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 1183ca7a8e85SJeff Kirsher { 1184ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(dev); 1185ca7a8e85SJeff Kirsher int ret; 1186ca7a8e85SJeff Kirsher 1187ca7a8e85SJeff Kirsher spin_lock_irq(&lp->lock); 1188ca7a8e85SJeff Kirsher ret = el3_netdev_set_ecmd(dev, ecmd); 1189ca7a8e85SJeff Kirsher spin_unlock_irq(&lp->lock); 1190ca7a8e85SJeff Kirsher return ret; 1191ca7a8e85SJeff Kirsher } 1192ca7a8e85SJeff Kirsher 1193ca7a8e85SJeff Kirsher static u32 el3_get_link(struct net_device *dev) 1194ca7a8e85SJeff Kirsher { 1195ca7a8e85SJeff Kirsher struct el3_private *lp = netdev_priv(dev); 1196ca7a8e85SJeff Kirsher u32 ret; 1197ca7a8e85SJeff Kirsher 1198ca7a8e85SJeff Kirsher spin_lock_irq(&lp->lock); 1199ca7a8e85SJeff Kirsher ret = el3_link_ok(dev); 1200ca7a8e85SJeff Kirsher spin_unlock_irq(&lp->lock); 1201ca7a8e85SJeff Kirsher return ret; 1202ca7a8e85SJeff Kirsher } 1203ca7a8e85SJeff Kirsher 1204ca7a8e85SJeff Kirsher static u32 el3_get_msglevel(struct net_device *dev) 1205ca7a8e85SJeff Kirsher { 1206ca7a8e85SJeff Kirsher return el3_debug; 1207ca7a8e85SJeff Kirsher } 1208ca7a8e85SJeff Kirsher 1209ca7a8e85SJeff Kirsher static void el3_set_msglevel(struct net_device *dev, u32 v) 1210ca7a8e85SJeff Kirsher { 1211ca7a8e85SJeff Kirsher el3_debug = v; 1212ca7a8e85SJeff Kirsher } 1213ca7a8e85SJeff Kirsher 1214ca7a8e85SJeff Kirsher static const struct ethtool_ops ethtool_ops = { 1215ca7a8e85SJeff Kirsher .get_drvinfo = el3_get_drvinfo, 1216ca7a8e85SJeff Kirsher .get_settings = el3_get_settings, 1217ca7a8e85SJeff Kirsher .set_settings = el3_set_settings, 1218ca7a8e85SJeff Kirsher .get_link = el3_get_link, 1219ca7a8e85SJeff Kirsher .get_msglevel = el3_get_msglevel, 1220ca7a8e85SJeff Kirsher .set_msglevel = el3_set_msglevel, 1221ca7a8e85SJeff Kirsher }; 1222ca7a8e85SJeff Kirsher 1223ca7a8e85SJeff Kirsher static void 1224ca7a8e85SJeff Kirsher el3_down(struct net_device *dev) 1225ca7a8e85SJeff Kirsher { 1226ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 1227ca7a8e85SJeff Kirsher 1228ca7a8e85SJeff Kirsher netif_stop_queue(dev); 1229ca7a8e85SJeff Kirsher 1230ca7a8e85SJeff Kirsher /* Turn off statistics ASAP. We update lp->stats below. */ 1231ca7a8e85SJeff Kirsher outw(StatsDisable, ioaddr + EL3_CMD); 1232ca7a8e85SJeff Kirsher 1233ca7a8e85SJeff Kirsher /* Disable the receiver and transmitter. */ 1234ca7a8e85SJeff Kirsher outw(RxDisable, ioaddr + EL3_CMD); 1235ca7a8e85SJeff Kirsher outw(TxDisable, ioaddr + EL3_CMD); 1236ca7a8e85SJeff Kirsher 1237ca7a8e85SJeff Kirsher if (dev->if_port == 3) 1238ca7a8e85SJeff Kirsher /* Turn off thinnet power. Green! */ 1239ca7a8e85SJeff Kirsher outw(StopCoax, ioaddr + EL3_CMD); 1240ca7a8e85SJeff Kirsher else if (dev->if_port == 0) { 1241ca7a8e85SJeff Kirsher /* Disable link beat and jabber, if_port may change here next open(). */ 1242ca7a8e85SJeff Kirsher EL3WINDOW(4); 1243ca7a8e85SJeff Kirsher outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA); 1244ca7a8e85SJeff Kirsher } 1245ca7a8e85SJeff Kirsher 1246ca7a8e85SJeff Kirsher outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD); 1247ca7a8e85SJeff Kirsher 1248ca7a8e85SJeff Kirsher update_stats(dev); 1249ca7a8e85SJeff Kirsher } 1250ca7a8e85SJeff Kirsher 1251ca7a8e85SJeff Kirsher static void 1252ca7a8e85SJeff Kirsher el3_up(struct net_device *dev) 1253ca7a8e85SJeff Kirsher { 1254ca7a8e85SJeff Kirsher int i, sw_info, net_diag; 1255ca7a8e85SJeff Kirsher int ioaddr = dev->base_addr; 1256ca7a8e85SJeff Kirsher 1257ca7a8e85SJeff Kirsher /* Activating the board required and does no harm otherwise */ 1258ca7a8e85SJeff Kirsher outw(0x0001, ioaddr + 4); 1259ca7a8e85SJeff Kirsher 1260ca7a8e85SJeff Kirsher /* Set the IRQ line. */ 1261ca7a8e85SJeff Kirsher outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ); 1262ca7a8e85SJeff Kirsher 1263ca7a8e85SJeff Kirsher /* Set the station address in window 2 each time opened. */ 1264ca7a8e85SJeff Kirsher EL3WINDOW(2); 1265ca7a8e85SJeff Kirsher 1266ca7a8e85SJeff Kirsher for (i = 0; i < 6; i++) 1267ca7a8e85SJeff Kirsher outb(dev->dev_addr[i], ioaddr + i); 1268ca7a8e85SJeff Kirsher 1269ca7a8e85SJeff Kirsher if ((dev->if_port & 0x03) == 3) /* BNC interface */ 1270ca7a8e85SJeff Kirsher /* Start the thinnet transceiver. We should really wait 50ms...*/ 1271ca7a8e85SJeff Kirsher outw(StartCoax, ioaddr + EL3_CMD); 1272ca7a8e85SJeff Kirsher else if ((dev->if_port & 0x03) == 0) { /* 10baseT interface */ 1273ca7a8e85SJeff Kirsher /* Combine secondary sw_info word (the adapter level) and primary 1274ca7a8e85SJeff Kirsher sw_info word (duplex setting plus other useless bits) */ 1275ca7a8e85SJeff Kirsher EL3WINDOW(0); 1276ca7a8e85SJeff Kirsher sw_info = (read_eeprom(ioaddr, 0x14) & 0x400f) | 1277ca7a8e85SJeff Kirsher (read_eeprom(ioaddr, 0x0d) & 0xBff0); 1278ca7a8e85SJeff Kirsher 1279ca7a8e85SJeff Kirsher EL3WINDOW(4); 1280ca7a8e85SJeff Kirsher net_diag = inw(ioaddr + WN4_NETDIAG); 1281ca7a8e85SJeff Kirsher net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */ 1282ca7a8e85SJeff Kirsher pr_info("%s: ", dev->name); 1283ca7a8e85SJeff Kirsher switch (dev->if_port & 0x0c) { 1284ca7a8e85SJeff Kirsher case 12: 1285ca7a8e85SJeff Kirsher /* force full-duplex mode if 3c5x9b */ 1286ca7a8e85SJeff Kirsher if (sw_info & 0x000f) { 1287ca7a8e85SJeff Kirsher pr_cont("Forcing 3c5x9b full-duplex mode"); 1288ca7a8e85SJeff Kirsher break; 1289ca7a8e85SJeff Kirsher } 1290ca7a8e85SJeff Kirsher case 8: 1291ca7a8e85SJeff Kirsher /* set full-duplex mode based on eeprom config setting */ 1292ca7a8e85SJeff Kirsher if ((sw_info & 0x000f) && (sw_info & 0x8000)) { 1293ca7a8e85SJeff Kirsher pr_cont("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)"); 1294ca7a8e85SJeff Kirsher break; 1295ca7a8e85SJeff Kirsher } 1296ca7a8e85SJeff Kirsher default: 1297ca7a8e85SJeff Kirsher /* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */ 1298ca7a8e85SJeff Kirsher pr_cont("Setting 3c5x9/3c5x9B half-duplex mode"); 1299ca7a8e85SJeff Kirsher net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */ 1300ca7a8e85SJeff Kirsher } 1301ca7a8e85SJeff Kirsher 1302ca7a8e85SJeff Kirsher outw(net_diag, ioaddr + WN4_NETDIAG); 1303ca7a8e85SJeff Kirsher pr_cont(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info); 1304ca7a8e85SJeff Kirsher if (el3_debug > 3) 1305ca7a8e85SJeff Kirsher pr_debug("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag); 1306ca7a8e85SJeff Kirsher /* Enable link beat and jabber check. */ 1307ca7a8e85SJeff Kirsher outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA); 1308ca7a8e85SJeff Kirsher } 1309ca7a8e85SJeff Kirsher 1310ca7a8e85SJeff Kirsher /* Switch to the stats window, and clear all stats by reading. */ 1311ca7a8e85SJeff Kirsher outw(StatsDisable, ioaddr + EL3_CMD); 1312ca7a8e85SJeff Kirsher EL3WINDOW(6); 1313ca7a8e85SJeff Kirsher for (i = 0; i < 9; i++) 1314ca7a8e85SJeff Kirsher inb(ioaddr + i); 1315ca7a8e85SJeff Kirsher inw(ioaddr + 10); 1316ca7a8e85SJeff Kirsher inw(ioaddr + 12); 1317ca7a8e85SJeff Kirsher 1318ca7a8e85SJeff Kirsher /* Switch to register set 1 for normal use. */ 1319ca7a8e85SJeff Kirsher EL3WINDOW(1); 1320ca7a8e85SJeff Kirsher 1321ca7a8e85SJeff Kirsher /* Accept b-case and phys addr only. */ 1322ca7a8e85SJeff Kirsher outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); 1323ca7a8e85SJeff Kirsher outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ 1324ca7a8e85SJeff Kirsher 1325ca7a8e85SJeff Kirsher outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ 1326ca7a8e85SJeff Kirsher outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ 1327ca7a8e85SJeff Kirsher /* Allow status bits to be seen. */ 1328ca7a8e85SJeff Kirsher outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD); 1329ca7a8e85SJeff Kirsher /* Ack all pending events, and set active indicator mask. */ 1330ca7a8e85SJeff Kirsher outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, 1331ca7a8e85SJeff Kirsher ioaddr + EL3_CMD); 1332ca7a8e85SJeff Kirsher outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull, 1333ca7a8e85SJeff Kirsher ioaddr + EL3_CMD); 1334ca7a8e85SJeff Kirsher 1335ca7a8e85SJeff Kirsher netif_start_queue(dev); 1336ca7a8e85SJeff Kirsher } 1337ca7a8e85SJeff Kirsher 1338ca7a8e85SJeff Kirsher /* Power Management support functions */ 1339ca7a8e85SJeff Kirsher #ifdef CONFIG_PM 1340ca7a8e85SJeff Kirsher 1341ca7a8e85SJeff Kirsher static int 1342ca7a8e85SJeff Kirsher el3_suspend(struct device *pdev, pm_message_t state) 1343ca7a8e85SJeff Kirsher { 1344ca7a8e85SJeff Kirsher unsigned long flags; 1345ca7a8e85SJeff Kirsher struct net_device *dev; 1346ca7a8e85SJeff Kirsher struct el3_private *lp; 1347ca7a8e85SJeff Kirsher int ioaddr; 1348ca7a8e85SJeff Kirsher 1349ca7a8e85SJeff Kirsher dev = dev_get_drvdata(pdev); 1350ca7a8e85SJeff Kirsher lp = netdev_priv(dev); 1351ca7a8e85SJeff Kirsher ioaddr = dev->base_addr; 1352ca7a8e85SJeff Kirsher 1353ca7a8e85SJeff Kirsher spin_lock_irqsave(&lp->lock, flags); 1354ca7a8e85SJeff Kirsher 1355ca7a8e85SJeff Kirsher if (netif_running(dev)) 1356ca7a8e85SJeff Kirsher netif_device_detach(dev); 1357ca7a8e85SJeff Kirsher 1358ca7a8e85SJeff Kirsher el3_down(dev); 1359ca7a8e85SJeff Kirsher outw(PowerDown, ioaddr + EL3_CMD); 1360ca7a8e85SJeff Kirsher 1361ca7a8e85SJeff Kirsher spin_unlock_irqrestore(&lp->lock, flags); 1362ca7a8e85SJeff Kirsher return 0; 1363ca7a8e85SJeff Kirsher } 1364ca7a8e85SJeff Kirsher 1365ca7a8e85SJeff Kirsher static int 1366ca7a8e85SJeff Kirsher el3_resume(struct device *pdev) 1367ca7a8e85SJeff Kirsher { 1368ca7a8e85SJeff Kirsher unsigned long flags; 1369ca7a8e85SJeff Kirsher struct net_device *dev; 1370ca7a8e85SJeff Kirsher struct el3_private *lp; 1371ca7a8e85SJeff Kirsher int ioaddr; 1372ca7a8e85SJeff Kirsher 1373ca7a8e85SJeff Kirsher dev = dev_get_drvdata(pdev); 1374ca7a8e85SJeff Kirsher lp = netdev_priv(dev); 1375ca7a8e85SJeff Kirsher ioaddr = dev->base_addr; 1376ca7a8e85SJeff Kirsher 1377ca7a8e85SJeff Kirsher spin_lock_irqsave(&lp->lock, flags); 1378ca7a8e85SJeff Kirsher 1379ca7a8e85SJeff Kirsher outw(PowerUp, ioaddr + EL3_CMD); 1380ca7a8e85SJeff Kirsher EL3WINDOW(0); 1381ca7a8e85SJeff Kirsher el3_up(dev); 1382ca7a8e85SJeff Kirsher 1383ca7a8e85SJeff Kirsher if (netif_running(dev)) 1384ca7a8e85SJeff Kirsher netif_device_attach(dev); 1385ca7a8e85SJeff Kirsher 1386ca7a8e85SJeff Kirsher spin_unlock_irqrestore(&lp->lock, flags); 1387ca7a8e85SJeff Kirsher return 0; 1388ca7a8e85SJeff Kirsher } 1389ca7a8e85SJeff Kirsher 1390ca7a8e85SJeff Kirsher #endif /* CONFIG_PM */ 1391ca7a8e85SJeff Kirsher 1392ca7a8e85SJeff Kirsher module_param(debug,int, 0); 1393ca7a8e85SJeff Kirsher module_param_array(irq, int, NULL, 0); 1394ca7a8e85SJeff Kirsher module_param(max_interrupt_work, int, 0); 1395ca7a8e85SJeff Kirsher MODULE_PARM_DESC(debug, "debug level (0-6)"); 1396ca7a8e85SJeff Kirsher MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); 1397ca7a8e85SJeff Kirsher MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt"); 1398ca7a8e85SJeff Kirsher #ifdef CONFIG_PNP 1399ca7a8e85SJeff Kirsher module_param(nopnp, int, 0); 1400ca7a8e85SJeff Kirsher MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)"); 1401ca7a8e85SJeff Kirsher #endif /* CONFIG_PNP */ 1402ca7a8e85SJeff Kirsher MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B, 3c529, 3c579) ethernet driver"); 1403ca7a8e85SJeff Kirsher MODULE_LICENSE("GPL"); 1404ca7a8e85SJeff Kirsher 1405ca7a8e85SJeff Kirsher static int __init el3_init_module(void) 1406ca7a8e85SJeff Kirsher { 1407ca7a8e85SJeff Kirsher int ret = 0; 1408ca7a8e85SJeff Kirsher 1409ca7a8e85SJeff Kirsher if (debug >= 0) 1410ca7a8e85SJeff Kirsher el3_debug = debug; 1411ca7a8e85SJeff Kirsher 1412ca7a8e85SJeff Kirsher #ifdef CONFIG_PNP 1413ca7a8e85SJeff Kirsher if (!nopnp) { 1414ca7a8e85SJeff Kirsher ret = pnp_register_driver(&el3_pnp_driver); 1415ca7a8e85SJeff Kirsher if (!ret) 1416ca7a8e85SJeff Kirsher pnp_registered = 1; 1417ca7a8e85SJeff Kirsher } 1418ca7a8e85SJeff Kirsher #endif 1419ca7a8e85SJeff Kirsher /* Select an open I/O location at 0x1*0 to do ISA contention select. */ 1420ca7a8e85SJeff Kirsher /* Start with 0x110 to avoid some sound cards.*/ 1421ca7a8e85SJeff Kirsher for (id_port = 0x110 ; id_port < 0x200; id_port += 0x10) { 1422ca7a8e85SJeff Kirsher if (!request_region(id_port, 1, "3c509-control")) 1423ca7a8e85SJeff Kirsher continue; 1424ca7a8e85SJeff Kirsher outb(0x00, id_port); 1425ca7a8e85SJeff Kirsher outb(0xff, id_port); 1426ca7a8e85SJeff Kirsher if (inb(id_port) & 0x01) 1427ca7a8e85SJeff Kirsher break; 1428ca7a8e85SJeff Kirsher else 1429ca7a8e85SJeff Kirsher release_region(id_port, 1); 1430ca7a8e85SJeff Kirsher } 1431ca7a8e85SJeff Kirsher if (id_port >= 0x200) { 1432ca7a8e85SJeff Kirsher id_port = 0; 1433ca7a8e85SJeff Kirsher pr_err("No I/O port available for 3c509 activation.\n"); 1434ca7a8e85SJeff Kirsher } else { 1435ca7a8e85SJeff Kirsher ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS); 1436ca7a8e85SJeff Kirsher if (!ret) 1437ca7a8e85SJeff Kirsher isa_registered = 1; 1438ca7a8e85SJeff Kirsher } 1439ca7a8e85SJeff Kirsher #ifdef CONFIG_EISA 1440ca7a8e85SJeff Kirsher ret = eisa_driver_register(&el3_eisa_driver); 1441ca7a8e85SJeff Kirsher if (!ret) 1442ca7a8e85SJeff Kirsher eisa_registered = 1; 1443ca7a8e85SJeff Kirsher #endif 1444ca7a8e85SJeff Kirsher 1445ca7a8e85SJeff Kirsher #ifdef CONFIG_PNP 1446ca7a8e85SJeff Kirsher if (pnp_registered) 1447ca7a8e85SJeff Kirsher ret = 0; 1448ca7a8e85SJeff Kirsher #endif 1449ca7a8e85SJeff Kirsher if (isa_registered) 1450ca7a8e85SJeff Kirsher ret = 0; 1451ca7a8e85SJeff Kirsher #ifdef CONFIG_EISA 1452ca7a8e85SJeff Kirsher if (eisa_registered) 1453ca7a8e85SJeff Kirsher ret = 0; 1454ca7a8e85SJeff Kirsher #endif 1455ca7a8e85SJeff Kirsher return ret; 1456ca7a8e85SJeff Kirsher } 1457ca7a8e85SJeff Kirsher 1458ca7a8e85SJeff Kirsher static void __exit el3_cleanup_module(void) 1459ca7a8e85SJeff Kirsher { 1460ca7a8e85SJeff Kirsher #ifdef CONFIG_PNP 1461ca7a8e85SJeff Kirsher if (pnp_registered) 1462ca7a8e85SJeff Kirsher pnp_unregister_driver(&el3_pnp_driver); 1463ca7a8e85SJeff Kirsher #endif 1464ca7a8e85SJeff Kirsher if (isa_registered) 1465ca7a8e85SJeff Kirsher isa_unregister_driver(&el3_isa_driver); 1466ca7a8e85SJeff Kirsher if (id_port) 1467ca7a8e85SJeff Kirsher release_region(id_port, 1); 1468ca7a8e85SJeff Kirsher #ifdef CONFIG_EISA 1469ca7a8e85SJeff Kirsher if (eisa_registered) 1470ca7a8e85SJeff Kirsher eisa_driver_unregister(&el3_eisa_driver); 1471ca7a8e85SJeff Kirsher #endif 1472ca7a8e85SJeff Kirsher } 1473ca7a8e85SJeff Kirsher 1474ca7a8e85SJeff Kirsher module_init (el3_init_module); 1475ca7a8e85SJeff Kirsher module_exit (el3_cleanup_module); 1476