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