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