blob: f4e293bd04dcbd39b2550d26052b0da188c11173 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* 3c574.c: A PCMCIA ethernet driver for the 3com 3c574 "RoadRunner".
2
3 Written 1993-1998 by
4 Donald Becker, becker@scyld.com, (driver core) and
5 David Hinds, dahinds@users.sourceforge.net (from his PC card code).
6 Locking fixes (C) Copyright 2003 Red Hat Inc
7
8 This software may be used and distributed according to the terms of
9 the GNU General Public License, incorporated herein by reference.
10
11 This driver derives from Donald Becker's 3c509 core, which has the
12 following copyright:
13 Copyright 1993 United States Government as represented by the
14 Director, National Security Agency.
15
16
17*/
18
19/*
20 Theory of Operation
21
22I. Board Compatibility
23
24This device driver is designed for the 3Com 3c574 PC card Fast Ethernet
25Adapter.
26
27II. Board-specific settings
28
29None -- PC cards are autoconfigured.
30
31III. Driver operation
32
33The 3c574 uses a Boomerang-style interface, without the bus-master capability.
34See the Boomerang driver and documentation for most details.
35
36IV. Notes and chip documentation.
37
38Two added registers are used to enhance PIO performance, RunnerRdCtrl and
39RunnerWrCtrl. These are 11 bit down-counters that are preloaded with the
40count of word (16 bits) reads or writes the driver is about to do to the Rx
41or Tx FIFO. The chip is then able to hide the internal-PCI-bus to PC-card
42translation latency by buffering the I/O operations with an 8 word FIFO.
43Note: No other chip accesses are permitted when this buffer is used.
44
45A second enhancement is that both attribute and common memory space
460x0800-0x0fff can translated to the PIO FIFO. Thus memory operations (faster
47with *some* PCcard bridges) may be used instead of I/O operations.
48This is enabled by setting the 0x10 bit in the PCMCIA LAN COR.
49
50Some slow PC card bridges work better if they never see a WAIT signal.
51This is configured by setting the 0x20 bit in the PCMCIA LAN COR.
52Only do this after testing that it is reliable and improves performance.
53
54The upper five bits of RunnerRdCtrl are used to window into PCcard
55configuration space registers. Window 0 is the regular Boomerang/Odie
56register set, 1-5 are various PC card control registers, and 16-31 are
57the (reversed!) CIS table.
58
59A final note: writing the InternalConfig register in window 3 with an
60invalid ramWidth is Very Bad.
61
62V. References
63
64http://www.scyld.com/expert/NWay.html
65http://www.national.com/pf/DP/DP83840.html
66
67Thanks to Terry Murphy of 3Com for providing development information for
68earlier 3Com products.
69
70*/
71
72#include <linux/module.h>
73#include <linux/kernel.h>
74#include <linux/init.h>
75#include <linux/slab.h>
76#include <linux/string.h>
77#include <linux/timer.h>
78#include <linux/interrupt.h>
79#include <linux/in.h>
80#include <linux/delay.h>
81#include <linux/netdevice.h>
82#include <linux/etherdevice.h>
83#include <linux/skbuff.h>
84#include <linux/if_arp.h>
85#include <linux/ioport.h>
86#include <linux/ethtool.h>
87#include <linux/bitops.h>
88
Linus Torvalds1da177e2005-04-16 15:20:36 -070089#include <pcmcia/cs_types.h>
90#include <pcmcia/cs.h>
91#include <pcmcia/cistpl.h>
92#include <pcmcia/cisreg.h>
93#include <pcmcia/ciscode.h>
94#include <pcmcia/ds.h>
95#include <pcmcia/mem_op.h>
96
97#include <asm/uaccess.h>
98#include <asm/io.h>
99#include <asm/system.h>
100
101/*====================================================================*/
102
103/* Module parameters */
104
105MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
106MODULE_DESCRIPTION("3Com 3c574 series PCMCIA ethernet driver");
107MODULE_LICENSE("GPL");
108
109#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
110
111/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
112INT_MODULE_PARM(max_interrupt_work, 32);
113
114/* Force full duplex modes? */
115INT_MODULE_PARM(full_duplex, 0);
116
117/* Autodetect link polarity reversal? */
118INT_MODULE_PARM(auto_polarity, 1);
119
120#ifdef PCMCIA_DEBUG
121INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
122#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
123static char *version =
124"3c574_cs.c 1.65ac1 2003/04/07 Donald Becker/David Hinds, becker@scyld.com.\n";
125#else
126#define DEBUG(n, args...)
127#endif
128
129/*====================================================================*/
130
131/* Time in jiffies before concluding the transmitter is hung. */
132#define TX_TIMEOUT ((800*HZ)/1000)
133
134/* To minimize the size of the driver source and make the driver more
135 readable not all constants are symbolically defined.
136 You'll need the manual if you want to understand driver details anyway. */
137/* Offsets from base I/O address. */
138#define EL3_DATA 0x00
139#define EL3_CMD 0x0e
140#define EL3_STATUS 0x0e
141
142#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
143
144/* The top five bits written to EL3_CMD are a command, the lower
145 11 bits are the parameter, if applicable. */
146enum el3_cmds {
147 TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
148 RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
149 TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
150 FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
151 SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
152 SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
153 StatsDisable = 22<<11, StopCoax = 23<<11,
154};
155
156enum elxl_status {
157 IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
158 TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
159 IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000 };
160
161/* The SetRxFilter command accepts the following classes: */
162enum RxFilter {
163 RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8
164};
165
166enum Window0 {
167 Wn0EepromCmd = 10, Wn0EepromData = 12, /* EEPROM command/address, data. */
168 IntrStatus=0x0E, /* Valid in all windows. */
169};
170/* These assumes the larger EEPROM. */
171enum Win0_EEPROM_cmds {
172 EEPROM_Read = 0x200, EEPROM_WRITE = 0x100, EEPROM_ERASE = 0x300,
173 EEPROM_EWENB = 0x30, /* Enable erasing/writing for 10 msec. */
174 EEPROM_EWDIS = 0x00, /* Disable EWENB before 10 msec timeout. */
175};
176
177/* Register window 1 offsets, the window used in normal operation.
178 On the "Odie" this window is always mapped at offsets 0x10-0x1f.
179 Except for TxFree, which is overlapped by RunnerWrCtrl. */
180enum Window1 {
181 TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14,
182 RxStatus = 0x18, Timer=0x1A, TxStatus = 0x1B,
183 TxFree = 0x0C, /* Remaining free bytes in Tx buffer. */
184 RunnerRdCtrl = 0x16, RunnerWrCtrl = 0x1c,
185};
186
187enum Window3 { /* Window 3: MAC/config bits. */
188 Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8,
189};
190union wn3_config {
191 int i;
192 struct w3_config_fields {
193 unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
194 int pad8:8;
195 unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1;
196 int pad24:7;
197 } u;
198};
199
200enum Window4 { /* Window 4: Xcvr/media bits. */
201 Wn4_FIFODiag = 4, Wn4_NetDiag = 6, Wn4_PhysicalMgmt=8, Wn4_Media = 10,
202};
203
204#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */
205
206struct el3_private {
Dominik Brodowskifd238232006-03-05 10:45:09 +0100207 struct pcmcia_device *p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 dev_node_t node;
209 struct net_device_stats stats;
210 u16 advertising, partner; /* NWay media advertisement */
211 unsigned char phys; /* MII device address */
212 unsigned int autoselect:1, default_media:3; /* Read from the EEPROM/Wn3_Config. */
213 /* for transceiver monitoring */
214 struct timer_list media;
215 unsigned short media_status;
216 unsigned short fast_poll;
217 unsigned long last_irq;
218 spinlock_t window_lock; /* Guards the Window selection */
219};
220
221/* Set iff a MII transceiver on any interface requires mdio preamble.
222 This only set with the original DP83840 on older 3c905 boards, so the extra
223 code size of a per-interface flag is not worthwhile. */
224static char mii_preamble_required = 0;
225
226/* Index of functions. */
227
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200228static void tc574_config(struct pcmcia_device *link);
229static void tc574_release(struct pcmcia_device *link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230
231static void mdio_sync(kio_addr_t ioaddr, int bits);
232static int mdio_read(kio_addr_t ioaddr, int phy_id, int location);
233static void mdio_write(kio_addr_t ioaddr, int phy_id, int location, int value);
234static unsigned short read_eeprom(kio_addr_t ioaddr, int index);
235static void tc574_wait_for_completion(struct net_device *dev, int cmd);
236
237static void tc574_reset(struct net_device *dev);
238static void media_check(unsigned long arg);
239static int el3_open(struct net_device *dev);
240static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
241static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
242static void update_stats(struct net_device *dev);
243static struct net_device_stats *el3_get_stats(struct net_device *dev);
244static int el3_rx(struct net_device *dev, int worklimit);
245static int el3_close(struct net_device *dev);
246static void el3_tx_timeout(struct net_device *dev);
247static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
248static struct ethtool_ops netdev_ethtool_ops;
249static void set_rx_mode(struct net_device *dev);
250
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100251static void tc574_detach(struct pcmcia_device *p_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253/*
254 tc574_attach() creates an "instance" of the driver, allocating
255 local data structures for one device. The device is registered
256 with Card Services.
257*/
258
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200259static int tc574_attach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260{
261 struct el3_private *lp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 struct net_device *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263
264 DEBUG(0, "3c574_attach()\n");
265
266 /* Create the PC card device object. */
267 dev = alloc_etherdev(sizeof(struct el3_private));
268 if (!dev)
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100269 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 link->priv = dev;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200272 lp->p_dev = link;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273
274 spin_lock_init(&lp->window_lock);
275 link->io.NumPorts1 = 32;
276 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
277 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
278 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
279 link->irq.Handler = &el3_interrupt;
280 link->irq.Instance = dev;
281 link->conf.Attributes = CONF_ENABLE_IRQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 link->conf.IntType = INT_MEMORY_AND_IO;
283 link->conf.ConfigIndex = 1;
284 link->conf.Present = PRESENT_OPTION;
285
286 /* The EL3-specific entries in the device structure. */
287 dev->hard_start_xmit = &el3_start_xmit;
288 dev->get_stats = &el3_get_stats;
289 dev->do_ioctl = &el3_ioctl;
290 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
291 dev->set_multicast_list = &set_rx_mode;
292 dev->open = &el3_open;
293 dev->stop = &el3_close;
294#ifdef HAVE_TX_TIMEOUT
295 dev->tx_timeout = el3_tx_timeout;
296 dev->watchdog_timeo = TX_TIMEOUT;
297#endif
298
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100299 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
300 tc574_config(link);
301
302 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303} /* tc574_attach */
304
305/*
306
307 This deletes a driver "instance". The device is de-registered
308 with Card Services. If it has been released, all local data
309 structures are freed. Otherwise, the structures will be freed
310 when the device is released.
311
312*/
313
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200314static void tc574_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315{
316 struct net_device *dev = link->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317
318 DEBUG(0, "3c574_detach(0x%p)\n", link);
319
Dominik Brodowskifd238232006-03-05 10:45:09 +0100320 if (link->dev_node)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 unregister_netdev(dev);
322
323 if (link->state & DEV_CONFIG)
324 tc574_release(link);
325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 free_netdev(dev);
327} /* tc574_detach */
328
329/*
330 tc574_config() is scheduled to run after a CARD_INSERTION event
331 is received, to configure the PCMCIA socket, and to make the
332 ethernet device available to the system.
333*/
334
335#define CS_CHECK(fn, ret) \
336 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
337
Arjan van de Venf71e1302006-03-03 21:33:57 -0500338static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200340static void tc574_config(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 struct net_device *dev = link->priv;
343 struct el3_private *lp = netdev_priv(dev);
344 tuple_t tuple;
345 cisparse_t parse;
346 unsigned short buf[32];
347 int last_fn, last_ret, i, j;
348 kio_addr_t ioaddr;
349 u16 *phys_addr;
350 char *cardname;
351 union wn3_config config;
352
353 phys_addr = (u16 *)dev->dev_addr;
354
355 DEBUG(0, "3c574_config(0x%p)\n", link);
356
357 tuple.Attributes = 0;
358 tuple.DesiredTuple = CISTPL_CONFIG;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200359 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 tuple.TupleData = (cisdata_t *)buf;
361 tuple.TupleDataMax = 64;
362 tuple.TupleOffset = 0;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200363 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
364 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 link->conf.ConfigBase = parse.config.base;
366 link->conf.Present = parse.config.rmask[0];
367
368 /* Configure card */
369 link->state |= DEV_CONFIG;
370
371 link->io.IOAddrLines = 16;
372 for (i = j = 0; j < 0x400; j += 0x20) {
373 link->io.BasePort1 = j ^ 0x300;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200374 i = pcmcia_request_io(link, &link->io);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 if (i == CS_SUCCESS) break;
376 }
377 if (i != CS_SUCCESS) {
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200378 cs_error(link, RequestIO, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 goto failed;
380 }
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200381 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
382 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
384 dev->irq = link->irq.AssignedIRQ;
385 dev->base_addr = link->io.BasePort1;
386
387 ioaddr = dev->base_addr;
388
389 /* The 3c574 normally uses an EEPROM for configuration info, including
390 the hardware address. The future products may include a modem chip
391 and put the address in the CIS. */
392 tuple.DesiredTuple = 0x88;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200393 if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
394 pcmcia_get_tuple_data(link, &tuple);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 for (i = 0; i < 3; i++)
396 phys_addr[i] = htons(buf[i]);
397 } else {
398 EL3WINDOW(0);
399 for (i = 0; i < 3; i++)
400 phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
401 if (phys_addr[0] == 0x6060) {
402 printk(KERN_NOTICE "3c574_cs: IO port conflict at 0x%03lx"
403 "-0x%03lx\n", dev->base_addr, dev->base_addr+15);
404 goto failed;
405 }
406 }
407 tuple.DesiredTuple = CISTPL_VERS_1;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200408 if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS &&
409 pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS &&
410 pcmcia_parse_tuple(link, &tuple, &parse) == CS_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 cardname = parse.version_1.str + parse.version_1.ofs[1];
412 } else
413 cardname = "3Com 3c574";
414
415 {
416 u_char mcr;
417 outw(2<<11, ioaddr + RunnerRdCtrl);
418 mcr = inb(ioaddr + 2);
419 outw(0<<11, ioaddr + RunnerRdCtrl);
420 printk(KERN_INFO " ASIC rev %d,", mcr>>3);
421 EL3WINDOW(3);
422 config.i = inl(ioaddr + Wn3_Config);
423 lp->default_media = config.u.xcvr;
424 lp->autoselect = config.u.autoselect;
425 }
426
427 init_timer(&lp->media);
428
429 {
430 int phy;
431
432 /* Roadrunner only: Turn on the MII transceiver */
433 outw(0x8040, ioaddr + Wn3_Options);
434 mdelay(1);
435 outw(0xc040, ioaddr + Wn3_Options);
436 tc574_wait_for_completion(dev, TxReset);
437 tc574_wait_for_completion(dev, RxReset);
438 mdelay(1);
439 outw(0x8040, ioaddr + Wn3_Options);
440
441 EL3WINDOW(4);
442 for (phy = 1; phy <= 32; phy++) {
443 int mii_status;
444 mdio_sync(ioaddr, 32);
445 mii_status = mdio_read(ioaddr, phy & 0x1f, 1);
446 if (mii_status != 0xffff) {
447 lp->phys = phy & 0x1f;
448 DEBUG(0, " MII transceiver at index %d, status %x.\n",
449 phy, mii_status);
450 if ((mii_status & 0x0040) == 0)
451 mii_preamble_required = 1;
452 break;
453 }
454 }
455 if (phy > 32) {
456 printk(KERN_NOTICE " No MII transceivers found!\n");
457 goto failed;
458 }
459 i = mdio_read(ioaddr, lp->phys, 16) | 0x40;
460 mdio_write(ioaddr, lp->phys, 16, i);
461 lp->advertising = mdio_read(ioaddr, lp->phys, 4);
462 if (full_duplex) {
463 /* Only advertise the FD media types. */
464 lp->advertising &= ~0x02a0;
465 mdio_write(ioaddr, lp->phys, 4, lp->advertising);
466 }
467 }
468
469 link->state &= ~DEV_CONFIG_PENDING;
Dominik Brodowskifd238232006-03-05 10:45:09 +0100470 link->dev_node = &lp->node;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200471 SET_NETDEV_DEV(dev, &handle_to_dev(link));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472
473 if (register_netdev(dev) != 0) {
474 printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
Dominik Brodowskifd238232006-03-05 10:45:09 +0100475 link->dev_node = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 goto failed;
477 }
478
479 strcpy(lp->node.dev_name, dev->name);
480
481 printk(KERN_INFO "%s: %s at io %#3lx, irq %d, hw_addr ",
482 dev->name, cardname, dev->base_addr, dev->irq);
483 for (i = 0; i < 6; i++)
484 printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : ".\n"));
485 printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n",
486 8 << config.u.ram_size, ram_split[config.u.ram_split],
487 config.u.autoselect ? "autoselect " : "");
488
489 return;
490
491cs_failed:
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200492 cs_error(link, last_fn, last_ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493failed:
494 tc574_release(link);
495 return;
496
497} /* tc574_config */
498
499/*
500 After a card is removed, tc574_release() will unregister the net
501 device, and release the PCMCIA configuration. If the device is
502 still open, this will be postponed until it is closed.
503*/
504
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200505static void tc574_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506{
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200507 pcmcia_disable_device(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508}
509
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200510static int tc574_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100511{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100512 struct net_device *dev = link->priv;
513
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100514 if ((link->state & DEV_CONFIG) && (link->open))
515 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100516
517 return 0;
518}
519
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200520static int tc574_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100521{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100522 struct net_device *dev = link->priv;
523
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100524 if ((link->state & DEV_CONFIG) && (link->open)) {
525 tc574_reset(dev);
526 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100527 }
528
529 return 0;
530}
531
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532static void dump_status(struct net_device *dev)
533{
534 kio_addr_t ioaddr = dev->base_addr;
535 EL3WINDOW(1);
536 printk(KERN_INFO " irq status %04x, rx status %04x, tx status "
537 "%02x, tx free %04x\n", inw(ioaddr+EL3_STATUS),
538 inw(ioaddr+RxStatus), inb(ioaddr+TxStatus),
539 inw(ioaddr+TxFree));
540 EL3WINDOW(4);
541 printk(KERN_INFO " diagnostics: fifo %04x net %04x ethernet %04x"
542 " media %04x\n", inw(ioaddr+0x04), inw(ioaddr+0x06),
543 inw(ioaddr+0x08), inw(ioaddr+0x0a));
544 EL3WINDOW(1);
545}
546
547/*
548 Use this for commands that may take time to finish
549*/
550static void tc574_wait_for_completion(struct net_device *dev, int cmd)
551{
552 int i = 1500;
553 outw(cmd, dev->base_addr + EL3_CMD);
554 while (--i > 0)
555 if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break;
556 if (i == 0)
557 printk(KERN_NOTICE "%s: command 0x%04x did not complete!\n", dev->name, cmd);
558}
559
560/* Read a word from the EEPROM using the regular EEPROM access register.
561 Assume that we are in register window zero.
562 */
563static unsigned short read_eeprom(kio_addr_t ioaddr, int index)
564{
565 int timer;
566 outw(EEPROM_Read + index, ioaddr + Wn0EepromCmd);
567 /* Pause for at least 162 usec for the read to take place. */
568 for (timer = 1620; timer >= 0; timer--) {
569 if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
570 break;
571 }
572 return inw(ioaddr + Wn0EepromData);
573}
574
575/* MII transceiver control section.
576 Read and write the MII registers using software-generated serial
577 MDIO protocol. See the MII specifications or DP83840A data sheet
578 for details.
579 The maxium data clock rate is 2.5 Mhz. The timing is easily met by the
580 slow PC card interface. */
581
582#define MDIO_SHIFT_CLK 0x01
583#define MDIO_DIR_WRITE 0x04
584#define MDIO_DATA_WRITE0 (0x00 | MDIO_DIR_WRITE)
585#define MDIO_DATA_WRITE1 (0x02 | MDIO_DIR_WRITE)
586#define MDIO_DATA_READ 0x02
587#define MDIO_ENB_IN 0x00
588
589/* Generate the preamble required for initial synchronization and
590 a few older transceivers. */
591static void mdio_sync(kio_addr_t ioaddr, int bits)
592{
593 kio_addr_t mdio_addr = ioaddr + Wn4_PhysicalMgmt;
594
595 /* Establish sync by sending at least 32 logic ones. */
596 while (-- bits >= 0) {
597 outw(MDIO_DATA_WRITE1, mdio_addr);
598 outw(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
599 }
600}
601
602static int mdio_read(kio_addr_t ioaddr, int phy_id, int location)
603{
604 int i;
605 int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
606 unsigned int retval = 0;
607 kio_addr_t mdio_addr = ioaddr + Wn4_PhysicalMgmt;
608
609 if (mii_preamble_required)
610 mdio_sync(ioaddr, 32);
611
612 /* Shift the read command bits out. */
613 for (i = 14; i >= 0; i--) {
614 int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
615 outw(dataval, mdio_addr);
616 outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
617 }
618 /* Read the two transition, 16 data, and wire-idle bits. */
619 for (i = 19; i > 0; i--) {
620 outw(MDIO_ENB_IN, mdio_addr);
621 retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
622 outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
623 }
624 return (retval>>1) & 0xffff;
625}
626
627static void mdio_write(kio_addr_t ioaddr, int phy_id, int location, int value)
628{
629 int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
630 kio_addr_t mdio_addr = ioaddr + Wn4_PhysicalMgmt;
631 int i;
632
633 if (mii_preamble_required)
634 mdio_sync(ioaddr, 32);
635
636 /* Shift the command bits out. */
637 for (i = 31; i >= 0; i--) {
638 int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
639 outw(dataval, mdio_addr);
640 outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
641 }
642 /* Leave the interface idle. */
643 for (i = 1; i >= 0; i--) {
644 outw(MDIO_ENB_IN, mdio_addr);
645 outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
646 }
647
648 return;
649}
650
651/* Reset and restore all of the 3c574 registers. */
652static void tc574_reset(struct net_device *dev)
653{
654 struct el3_private *lp = netdev_priv(dev);
655 int i;
656 kio_addr_t ioaddr = dev->base_addr;
657 unsigned long flags;
658
659 tc574_wait_for_completion(dev, TotalReset|0x10);
660
661 spin_lock_irqsave(&lp->window_lock, flags);
662 /* Clear any transactions in progress. */
663 outw(0, ioaddr + RunnerWrCtrl);
664 outw(0, ioaddr + RunnerRdCtrl);
665
666 /* Set the station address and mask. */
667 EL3WINDOW(2);
668 for (i = 0; i < 6; i++)
669 outb(dev->dev_addr[i], ioaddr + i);
670 for (; i < 12; i+=2)
671 outw(0, ioaddr + i);
672
673 /* Reset config options */
674 EL3WINDOW(3);
675 outb((dev->mtu > 1500 ? 0x40 : 0), ioaddr + Wn3_MAC_Ctrl);
676 outl((lp->autoselect ? 0x01000000 : 0) | 0x0062001b,
677 ioaddr + Wn3_Config);
678 /* Roadrunner only: Turn on the MII transceiver. */
679 outw(0x8040, ioaddr + Wn3_Options);
680 mdelay(1);
681 outw(0xc040, ioaddr + Wn3_Options);
682 EL3WINDOW(1);
683 spin_unlock_irqrestore(&lp->window_lock, flags);
684
685 tc574_wait_for_completion(dev, TxReset);
686 tc574_wait_for_completion(dev, RxReset);
687 mdelay(1);
688 spin_lock_irqsave(&lp->window_lock, flags);
689 EL3WINDOW(3);
690 outw(0x8040, ioaddr + Wn3_Options);
691
692 /* Switch to the stats window, and clear all stats by reading. */
693 outw(StatsDisable, ioaddr + EL3_CMD);
694 EL3WINDOW(6);
695 for (i = 0; i < 10; i++)
696 inb(ioaddr + i);
697 inw(ioaddr + 10);
698 inw(ioaddr + 12);
699 EL3WINDOW(4);
700 inb(ioaddr + 12);
701 inb(ioaddr + 13);
702
703 /* .. enable any extra statistics bits.. */
704 outw(0x0040, ioaddr + Wn4_NetDiag);
705
706 EL3WINDOW(1);
707 spin_unlock_irqrestore(&lp->window_lock, flags);
708
709 /* .. re-sync MII and re-fill what NWay is advertising. */
710 mdio_sync(ioaddr, 32);
711 mdio_write(ioaddr, lp->phys, 4, lp->advertising);
712 if (!auto_polarity) {
713 /* works for TDK 78Q2120 series MII's */
714 int i = mdio_read(ioaddr, lp->phys, 16) | 0x20;
715 mdio_write(ioaddr, lp->phys, 16, i);
716 }
717
718 spin_lock_irqsave(&lp->window_lock, flags);
719 /* Switch to register set 1 for normal use, just for TxFree. */
720 set_rx_mode(dev);
721 spin_unlock_irqrestore(&lp->window_lock, flags);
722 outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
723 outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
724 outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
725 /* Allow status bits to be seen. */
726 outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
727 /* Ack all pending events, and set active indicator mask. */
728 outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
729 ioaddr + EL3_CMD);
730 outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull
731 | AdapterFailure | RxEarly, ioaddr + EL3_CMD);
732}
733
734static int el3_open(struct net_device *dev)
735{
736 struct el3_private *lp = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200737 struct pcmcia_device *link = lp->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738
739 if (!DEV_OK(link))
740 return -ENODEV;
741
742 link->open++;
743 netif_start_queue(dev);
744
745 tc574_reset(dev);
746 lp->media.function = &media_check;
747 lp->media.data = (unsigned long) dev;
748 lp->media.expires = jiffies + HZ;
749 add_timer(&lp->media);
750
751 DEBUG(2, "%s: opened, status %4.4x.\n",
752 dev->name, inw(dev->base_addr + EL3_STATUS));
753
754 return 0;
755}
756
757static void el3_tx_timeout(struct net_device *dev)
758{
759 struct el3_private *lp = netdev_priv(dev);
760 kio_addr_t ioaddr = dev->base_addr;
761
762 printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name);
763 dump_status(dev);
764 lp->stats.tx_errors++;
765 dev->trans_start = jiffies;
766 /* Issue TX_RESET and TX_START commands. */
767 tc574_wait_for_completion(dev, TxReset);
768 outw(TxEnable, ioaddr + EL3_CMD);
769 netif_wake_queue(dev);
770}
771
772static void pop_tx_status(struct net_device *dev)
773{
774 struct el3_private *lp = netdev_priv(dev);
775 kio_addr_t ioaddr = dev->base_addr;
776 int i;
777
778 /* Clear the Tx status stack. */
779 for (i = 32; i > 0; i--) {
780 u_char tx_status = inb(ioaddr + TxStatus);
781 if (!(tx_status & 0x84))
782 break;
783 /* reset transmitter on jabber error or underrun */
784 if (tx_status & 0x30)
785 tc574_wait_for_completion(dev, TxReset);
786 if (tx_status & 0x38) {
787 DEBUG(1, "%s: transmit error: status 0x%02x\n",
788 dev->name, tx_status);
789 outw(TxEnable, ioaddr + EL3_CMD);
790 lp->stats.tx_aborted_errors++;
791 }
792 outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
793 }
794}
795
796static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
797{
798 kio_addr_t ioaddr = dev->base_addr;
799 struct el3_private *lp = netdev_priv(dev);
800 unsigned long flags;
801
802 DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
803 "status %4.4x.\n", dev->name, (long)skb->len,
804 inw(ioaddr + EL3_STATUS));
805
806 spin_lock_irqsave(&lp->window_lock, flags);
807 outw(skb->len, ioaddr + TX_FIFO);
808 outw(0, ioaddr + TX_FIFO);
809 outsl(ioaddr + TX_FIFO, skb->data, (skb->len+3)>>2);
810
811 dev->trans_start = jiffies;
812
813 /* TxFree appears only in Window 1, not offset 0x1c. */
814 if (inw(ioaddr + TxFree) <= 1536) {
815 netif_stop_queue(dev);
816 /* Interrupt us when the FIFO has room for max-sized packet.
817 The threshold is in units of dwords. */
818 outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
819 }
820
821 pop_tx_status(dev);
822 spin_unlock_irqrestore(&lp->window_lock, flags);
823 dev_kfree_skb(skb);
824 return 0;
825}
826
827/* The EL3 interrupt handler. */
828static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
829{
830 struct net_device *dev = (struct net_device *) dev_id;
831 struct el3_private *lp = netdev_priv(dev);
832 kio_addr_t ioaddr;
833 unsigned status;
834 int work_budget = max_interrupt_work;
835 int handled = 0;
836
837 if (!netif_device_present(dev))
838 return IRQ_NONE;
839 ioaddr = dev->base_addr;
840
841 DEBUG(3, "%s: interrupt, status %4.4x.\n",
842 dev->name, inw(ioaddr + EL3_STATUS));
843
844 spin_lock(&lp->window_lock);
845
846 while ((status = inw(ioaddr + EL3_STATUS)) &
847 (IntLatch | RxComplete | RxEarly | StatsFull)) {
848 if (!netif_device_present(dev) ||
849 ((status & 0xe000) != 0x2000)) {
850 DEBUG(1, "%s: Interrupt from dead card\n", dev->name);
851 break;
852 }
853
854 handled = 1;
855
856 if (status & RxComplete)
857 work_budget = el3_rx(dev, work_budget);
858
859 if (status & TxAvailable) {
860 DEBUG(3, " TX room bit was handled.\n");
861 /* There's room in the FIFO for a full-sized packet. */
862 outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
863 netif_wake_queue(dev);
864 }
865
866 if (status & TxComplete)
867 pop_tx_status(dev);
868
869 if (status & (AdapterFailure | RxEarly | StatsFull)) {
870 /* Handle all uncommon interrupts. */
871 if (status & StatsFull)
872 update_stats(dev);
873 if (status & RxEarly) {
874 work_budget = el3_rx(dev, work_budget);
875 outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
876 }
877 if (status & AdapterFailure) {
878 u16 fifo_diag;
879 EL3WINDOW(4);
880 fifo_diag = inw(ioaddr + Wn4_FIFODiag);
881 EL3WINDOW(1);
882 printk(KERN_NOTICE "%s: adapter failure, FIFO diagnostic"
883 " register %04x.\n", dev->name, fifo_diag);
884 if (fifo_diag & 0x0400) {
885 /* Tx overrun */
886 tc574_wait_for_completion(dev, TxReset);
887 outw(TxEnable, ioaddr + EL3_CMD);
888 }
889 if (fifo_diag & 0x2000) {
890 /* Rx underrun */
891 tc574_wait_for_completion(dev, RxReset);
892 set_rx_mode(dev);
893 outw(RxEnable, ioaddr + EL3_CMD);
894 }
895 outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);
896 }
897 }
898
899 if (--work_budget < 0) {
900 DEBUG(0, "%s: Too much work in interrupt, "
901 "status %4.4x.\n", dev->name, status);
902 /* Clear all interrupts */
903 outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
904 break;
905 }
906 /* Acknowledge the IRQ. */
907 outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
908 }
909
910 DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
911 dev->name, inw(ioaddr + EL3_STATUS));
912
913 spin_unlock(&lp->window_lock);
914 return IRQ_RETVAL(handled);
915}
916
917/*
918 This timer serves two purposes: to check for missed interrupts
919 (and as a last resort, poll the NIC for events), and to monitor
920 the MII, reporting changes in cable status.
921*/
922static void media_check(unsigned long arg)
923{
924 struct net_device *dev = (struct net_device *) arg;
925 struct el3_private *lp = netdev_priv(dev);
926 kio_addr_t ioaddr = dev->base_addr;
927 unsigned long flags;
928 unsigned short /* cable, */ media, partner;
929
930 if (!netif_device_present(dev))
931 goto reschedule;
932
933 /* Check for pending interrupt with expired latency timer: with
934 this, we can limp along even if the interrupt is blocked */
935 if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) {
936 if (!lp->fast_poll)
937 printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
938 el3_interrupt(dev->irq, lp, NULL);
939 lp->fast_poll = HZ;
940 }
941 if (lp->fast_poll) {
942 lp->fast_poll--;
943 lp->media.expires = jiffies + 2*HZ/100;
944 add_timer(&lp->media);
945 return;
946 }
947
948 spin_lock_irqsave(&lp->window_lock, flags);
949 EL3WINDOW(4);
950 media = mdio_read(ioaddr, lp->phys, 1);
951 partner = mdio_read(ioaddr, lp->phys, 5);
952 EL3WINDOW(1);
953
954 if (media != lp->media_status) {
955 if ((media ^ lp->media_status) & 0x0004)
956 printk(KERN_INFO "%s: %s link beat\n", dev->name,
957 (lp->media_status & 0x0004) ? "lost" : "found");
958 if ((media ^ lp->media_status) & 0x0020) {
959 lp->partner = 0;
960 if (lp->media_status & 0x0020) {
961 printk(KERN_INFO "%s: autonegotiation restarted\n",
962 dev->name);
963 } else if (partner) {
964 partner &= lp->advertising;
965 lp->partner = partner;
966 printk(KERN_INFO "%s: autonegotiation complete: "
967 "%sbaseT-%cD selected\n", dev->name,
968 ((partner & 0x0180) ? "100" : "10"),
969 ((partner & 0x0140) ? 'F' : 'H'));
970 } else {
971 printk(KERN_INFO "%s: link partner did not autonegotiate\n",
972 dev->name);
973 }
974
975 EL3WINDOW(3);
976 outb((partner & 0x0140 ? 0x20 : 0) |
977 (dev->mtu > 1500 ? 0x40 : 0), ioaddr + Wn3_MAC_Ctrl);
978 EL3WINDOW(1);
979
980 }
981 if (media & 0x0010)
982 printk(KERN_INFO "%s: remote fault detected\n",
983 dev->name);
984 if (media & 0x0002)
985 printk(KERN_INFO "%s: jabber detected\n", dev->name);
986 lp->media_status = media;
987 }
988 spin_unlock_irqrestore(&lp->window_lock, flags);
989
990reschedule:
991 lp->media.expires = jiffies + HZ;
992 add_timer(&lp->media);
993}
994
995static struct net_device_stats *el3_get_stats(struct net_device *dev)
996{
997 struct el3_private *lp = netdev_priv(dev);
998
999 if (netif_device_present(dev)) {
1000 unsigned long flags;
1001 spin_lock_irqsave(&lp->window_lock, flags);
1002 update_stats(dev);
1003 spin_unlock_irqrestore(&lp->window_lock, flags);
1004 }
1005 return &lp->stats;
1006}
1007
1008/* Update statistics.
1009 Suprisingly this need not be run single-threaded, but it effectively is.
1010 The counters clear when read, so the adds must merely be atomic.
1011 */
1012static void update_stats(struct net_device *dev)
1013{
1014 struct el3_private *lp = netdev_priv(dev);
1015 kio_addr_t ioaddr = dev->base_addr;
1016 u8 rx, tx, up;
1017
1018 DEBUG(2, "%s: updating the statistics.\n", dev->name);
1019
1020 if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */
1021 return;
1022
1023 /* Unlike the 3c509 we need not turn off stats updates while reading. */
1024 /* Switch to the stats window, and read everything. */
1025 EL3WINDOW(6);
1026 lp->stats.tx_carrier_errors += inb(ioaddr + 0);
1027 lp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
1028 /* Multiple collisions. */ inb(ioaddr + 2);
1029 lp->stats.collisions += inb(ioaddr + 3);
1030 lp->stats.tx_window_errors += inb(ioaddr + 4);
1031 lp->stats.rx_fifo_errors += inb(ioaddr + 5);
1032 lp->stats.tx_packets += inb(ioaddr + 6);
1033 up = inb(ioaddr + 9);
1034 lp->stats.tx_packets += (up&0x30) << 4;
1035 /* Rx packets */ inb(ioaddr + 7);
1036 /* Tx deferrals */ inb(ioaddr + 8);
1037 rx = inw(ioaddr + 10);
1038 tx = inw(ioaddr + 12);
1039
1040 EL3WINDOW(4);
1041 /* BadSSD */ inb(ioaddr + 12);
1042 up = inb(ioaddr + 13);
1043
1044 lp->stats.tx_bytes += tx + ((up & 0xf0) << 12);
1045
1046 EL3WINDOW(1);
1047}
1048
1049static int el3_rx(struct net_device *dev, int worklimit)
1050{
1051 struct el3_private *lp = netdev_priv(dev);
1052 kio_addr_t ioaddr = dev->base_addr;
1053 short rx_status;
1054
1055 DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
1056 dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
1057 while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) &&
1058 (--worklimit >= 0)) {
1059 if (rx_status & 0x4000) { /* Error, update stats. */
1060 short error = rx_status & 0x3800;
1061 lp->stats.rx_errors++;
1062 switch (error) {
1063 case 0x0000: lp->stats.rx_over_errors++; break;
1064 case 0x0800: lp->stats.rx_length_errors++; break;
1065 case 0x1000: lp->stats.rx_frame_errors++; break;
1066 case 0x1800: lp->stats.rx_length_errors++; break;
1067 case 0x2000: lp->stats.rx_frame_errors++; break;
1068 case 0x2800: lp->stats.rx_crc_errors++; break;
1069 }
1070 } else {
1071 short pkt_len = rx_status & 0x7ff;
1072 struct sk_buff *skb;
1073
1074 skb = dev_alloc_skb(pkt_len+5);
1075
1076 DEBUG(3, " Receiving packet size %d status %4.4x.\n",
1077 pkt_len, rx_status);
1078 if (skb != NULL) {
1079 skb->dev = dev;
1080 skb_reserve(skb, 2);
1081 insl(ioaddr+RX_FIFO, skb_put(skb, pkt_len),
1082 ((pkt_len+3)>>2));
1083 skb->protocol = eth_type_trans(skb, dev);
1084 netif_rx(skb);
1085 dev->last_rx = jiffies;
1086 lp->stats.rx_packets++;
1087 lp->stats.rx_bytes += pkt_len;
1088 } else {
1089 DEBUG(1, "%s: couldn't allocate a sk_buff of"
1090 " size %d.\n", dev->name, pkt_len);
1091 lp->stats.rx_dropped++;
1092 }
1093 }
1094 tc574_wait_for_completion(dev, RxDiscard);
1095 }
1096
1097 return worklimit;
1098}
1099
1100static void netdev_get_drvinfo(struct net_device *dev,
1101 struct ethtool_drvinfo *info)
1102{
1103 strcpy(info->driver, "3c574_cs");
1104}
1105
1106static struct ethtool_ops netdev_ethtool_ops = {
1107 .get_drvinfo = netdev_get_drvinfo,
1108};
1109
1110/* Provide ioctl() calls to examine the MII xcvr state. */
1111static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1112{
1113 struct el3_private *lp = netdev_priv(dev);
1114 kio_addr_t ioaddr = dev->base_addr;
1115 u16 *data = (u16 *)&rq->ifr_ifru;
1116 int phy = lp->phys & 0x1f;
1117
1118 DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
1119 dev->name, rq->ifr_ifrn.ifrn_name, cmd,
1120 data[0], data[1], data[2], data[3]);
1121
1122 switch(cmd) {
1123 case SIOCGMIIPHY: /* Get the address of the PHY in use. */
1124 data[0] = phy;
1125 case SIOCGMIIREG: /* Read the specified MII register. */
1126 {
1127 int saved_window;
1128 unsigned long flags;
1129
1130 spin_lock_irqsave(&lp->window_lock, flags);
1131 saved_window = inw(ioaddr + EL3_CMD) >> 13;
1132 EL3WINDOW(4);
1133 data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
1134 EL3WINDOW(saved_window);
1135 spin_unlock_irqrestore(&lp->window_lock, flags);
1136 return 0;
1137 }
1138 case SIOCSMIIREG: /* Write the specified MII register */
1139 {
1140 int saved_window;
1141 unsigned long flags;
1142
1143 if (!capable(CAP_NET_ADMIN))
1144 return -EPERM;
1145 spin_lock_irqsave(&lp->window_lock, flags);
1146 saved_window = inw(ioaddr + EL3_CMD) >> 13;
1147 EL3WINDOW(4);
1148 mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
1149 EL3WINDOW(saved_window);
1150 spin_unlock_irqrestore(&lp->window_lock, flags);
1151 return 0;
1152 }
1153 default:
1154 return -EOPNOTSUPP;
1155 }
1156}
1157
1158/* The Odie chip has a 64 bin multicast filter, but the bit layout is not
1159 documented. Until it is we revert to receiving all multicast frames when
1160 any multicast reception is desired.
1161 Note: My other drivers emit a log message whenever promiscuous mode is
1162 entered to help detect password sniffers. This is less desirable on
1163 typical PC card machines, so we omit the message.
1164 */
1165
1166static void set_rx_mode(struct net_device *dev)
1167{
1168 kio_addr_t ioaddr = dev->base_addr;
1169
1170 if (dev->flags & IFF_PROMISC)
1171 outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
1172 ioaddr + EL3_CMD);
1173 else if (dev->mc_count || (dev->flags & IFF_ALLMULTI))
1174 outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
1175 else
1176 outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
1177}
1178
1179static int el3_close(struct net_device *dev)
1180{
1181 kio_addr_t ioaddr = dev->base_addr;
1182 struct el3_private *lp = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001183 struct pcmcia_device *link = lp->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184
1185 DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
1186
1187 if (DEV_OK(link)) {
1188 unsigned long flags;
1189
1190 /* Turn off statistics ASAP. We update lp->stats below. */
1191 outw(StatsDisable, ioaddr + EL3_CMD);
1192
1193 /* Disable the receiver and transmitter. */
1194 outw(RxDisable, ioaddr + EL3_CMD);
1195 outw(TxDisable, ioaddr + EL3_CMD);
1196
1197 /* Note: Switching to window 0 may disable the IRQ. */
1198 EL3WINDOW(0);
1199 spin_lock_irqsave(&lp->window_lock, flags);
1200 update_stats(dev);
1201 spin_unlock_irqrestore(&lp->window_lock, flags);
Daniel Ritzb9a6eaf2005-04-10 20:27:45 +02001202
1203 /* force interrupts off */
1204 outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 }
1206
1207 link->open--;
1208 netif_stop_queue(dev);
1209 del_timer_sync(&lp->media);
1210
1211 return 0;
1212}
1213
Dominik Brodowski270b6e92005-06-27 16:28:18 -07001214static struct pcmcia_device_id tc574_ids[] = {
1215 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0574),
1216 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "3CCFEM556.cis"),
1217 PCMCIA_DEVICE_NULL,
1218};
1219MODULE_DEVICE_TABLE(pcmcia, tc574_ids);
1220
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221static struct pcmcia_driver tc574_driver = {
1222 .owner = THIS_MODULE,
1223 .drv = {
1224 .name = "3c574_cs",
1225 },
Dominik Brodowskif8cfa612005-11-14 21:25:51 +01001226 .probe = tc574_attach,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001227 .remove = tc574_detach,
Dominik Brodowski270b6e92005-06-27 16:28:18 -07001228 .id_table = tc574_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01001229 .suspend = tc574_suspend,
1230 .resume = tc574_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231};
1232
1233static int __init init_tc574(void)
1234{
1235 return pcmcia_register_driver(&tc574_driver);
1236}
1237
1238static void __exit exit_tc574(void)
1239{
1240 pcmcia_unregister_driver(&tc574_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241}
1242
1243module_init(init_tc574);
1244module_exit(exit_tc574);