blob: 89cf63bb8c913a4af6ed1065e7aeaff1d7257276 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* ----------------------------------------------------------------------------
2Linux PCMCIA ethernet adapter driver for the New Media Ethernet LAN.
3 nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao
4
5 The Ethernet LAN uses the Advanced Micro Devices (AMD) Am79C940 Media
6 Access Controller for Ethernet (MACE). It is essentially the Am2150
7 PCMCIA Ethernet card contained in the Am2150 Demo Kit.
8
9Written by Roger C. Pao <rpao@paonet.org>
10 Copyright 1995 Roger C. Pao
11 Linux 2.5 cleanups Copyright Red Hat 2003
12
13 This software may be used and distributed according to the terms of
14 the GNU General Public License.
15
16Ported to Linux 1.3.* network driver environment by
17 Matti Aarnio <mea@utu.fi>
18
19References
20
21 Am2150 Technical Reference Manual, Revision 1.0, August 17, 1993
22 Am79C940 (MACE) Data Sheet, 1994
23 Am79C90 (C-LANCE) Data Sheet, 1994
24 Linux PCMCIA Programmer's Guide v1.17
25 /usr/src/linux/net/inet/dev.c, Linux kernel 1.2.8
26
27 Eric Mears, New Media Corporation
28 Tom Pollard, New Media Corporation
29 Dean Siasoyco, New Media Corporation
30 Ken Lesniak, Silicon Graphics, Inc. <lesniak@boston.sgi.com>
31 Donald Becker <becker@scyld.com>
32 David Hinds <dahinds@users.sourceforge.net>
33
34 The Linux client driver is based on the 3c589_cs.c client driver by
35 David Hinds.
36
37 The Linux network driver outline is based on the 3c589_cs.c driver,
38 the 8390.c driver, and the example skeleton.c kernel code, which are
39 by Donald Becker.
40
41 The Am2150 network driver hardware interface code is based on the
42 OS/9000 driver for the New Media Ethernet LAN by Eric Mears.
43
44 Special thanks for testing and help in debugging this driver goes
45 to Ken Lesniak.
46
47-------------------------------------------------------------------------------
48Driver Notes and Issues
49-------------------------------------------------------------------------------
50
511. Developed on a Dell 320SLi
52 PCMCIA Card Services 2.6.2
53 Linux dell 1.2.10 #1 Thu Jun 29 20:23:41 PDT 1995 i386
54
552. rc.pcmcia may require loading pcmcia_core with io_speed=300:
56 'insmod pcmcia_core.o io_speed=300'.
57 This will avoid problems with fast systems which causes rx_framecnt
58 to return random values.
59
603. If hot extraction does not work for you, use 'ifconfig eth0 down'
61 before extraction.
62
634. There is a bad slow-down problem in this driver.
64
655. Future: Multicast processing. In the meantime, do _not_ compile your
66 kernel with multicast ip enabled.
67
68-------------------------------------------------------------------------------
69History
70-------------------------------------------------------------------------------
71Log: nmclan_cs.c,v
Alan Cox113aa832008-10-13 19:01:08 -070072 * 2.5.75-ac1 2003/07/11 Alan Cox <alan@lxorguk.ukuu.org.uk>
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 * Fixed hang on card eject as we probe it
74 * Cleaned up to use new style locking.
75 *
76 * Revision 0.16 1995/07/01 06:42:17 rpao
77 * Bug fix: nmclan_reset() called CardServices incorrectly.
78 *
79 * Revision 0.15 1995/05/24 08:09:47 rpao
80 * Re-implement MULTI_TX dev->tbusy handling.
81 *
82 * Revision 0.14 1995/05/23 03:19:30 rpao
83 * Added, in nmclan_config(), "tuple.Attributes = 0;".
84 * Modified MACE ID check to ignore chip revision level.
85 * Avoid tx_free_frames race condition between _start_xmit and _interrupt.
86 *
87 * Revision 0.13 1995/05/18 05:56:34 rpao
88 * Statistics changes.
89 * Bug fix: nmclan_reset did not enable TX and RX: call restore_multicast_list.
90 * Bug fix: mace_interrupt checks ~MACE_IMR_DEFAULT. Fixes driver lockup.
91 *
92 * Revision 0.12 1995/05/14 00:12:23 rpao
93 * Statistics overhaul.
94 *
95
9695/05/13 rpao V0.10a
97 Bug fix: MACE statistics counters used wrong I/O ports.
98 Bug fix: mace_interrupt() needed to allow statistics to be
99 processed without RX or TX interrupts pending.
10095/05/11 rpao V0.10
101 Multiple transmit request processing.
102 Modified statistics to use MACE counters where possible.
10395/05/10 rpao V0.09 Bug fix: Must use IO_DATA_PATH_WIDTH_AUTO.
104 *Released
10595/05/10 rpao V0.08
106 Bug fix: Make all non-exported functions private by using
107 static keyword.
108 Bug fix: Test IntrCnt _before_ reading MACE_IR.
10995/05/10 rpao V0.07 Statistics.
11095/05/09 rpao V0.06 Fix rx_framecnt problem by addition of PCIC wait states.
111
112---------------------------------------------------------------------------- */
113
Joe Perches636b8112010-08-12 12:22:51 +0000114#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
115
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116#define DRV_NAME "nmclan_cs"
117#define DRV_VERSION "0.16"
118
119
120/* ----------------------------------------------------------------------------
121Conditional Compilation Options
122---------------------------------------------------------------------------- */
123
124#define MULTI_TX 0
125#define RESET_ON_TIMEOUT 1
126#define TX_INTERRUPTABLE 1
127#define RESET_XILINX 0
128
129/* ----------------------------------------------------------------------------
130Include Files
131---------------------------------------------------------------------------- */
132
133#include <linux/module.h>
134#include <linux/kernel.h>
135#include <linux/init.h>
136#include <linux/ptrace.h>
137#include <linux/slab.h>
138#include <linux/string.h>
139#include <linux/timer.h>
140#include <linux/interrupt.h>
141#include <linux/in.h>
142#include <linux/delay.h>
143#include <linux/ethtool.h>
144#include <linux/netdevice.h>
145#include <linux/etherdevice.h>
146#include <linux/skbuff.h>
147#include <linux/if_arp.h>
148#include <linux/ioport.h>
149#include <linux/bitops.h>
150
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151#include <pcmcia/cs.h>
152#include <pcmcia/cisreg.h>
153#include <pcmcia/cistpl.h>
154#include <pcmcia/ds.h>
155
156#include <asm/uaccess.h>
157#include <asm/io.h>
158#include <asm/system.h>
159
160/* ----------------------------------------------------------------------------
161Defines
162---------------------------------------------------------------------------- */
163
164#define ETHER_ADDR_LEN ETH_ALEN
165 /* 6 bytes in an Ethernet Address */
166#define MACE_LADRF_LEN 8
167 /* 8 bytes in Logical Address Filter */
168
169/* Loop Control Defines */
170#define MACE_MAX_IR_ITERATIONS 10
171#define MACE_MAX_RX_ITERATIONS 12
172 /*
173 TBD: Dean brought this up, and I assumed the hardware would
174 handle it:
175
176 If MACE_MAX_RX_ITERATIONS is > 1, rx_framecnt may still be
177 non-zero when the isr exits. We may not get another interrupt
178 to process the remaining packets for some time.
179 */
180
181/*
182The Am2150 has a Xilinx XC3042 field programmable gate array (FPGA)
183which manages the interface between the MACE and the PCMCIA bus. It
184also includes buffer management for the 32K x 8 SRAM to control up to
185four transmit and 12 receive frames at a time.
186*/
187#define AM2150_MAX_TX_FRAMES 4
188#define AM2150_MAX_RX_FRAMES 12
189
190/* Am2150 Ethernet Card I/O Mapping */
191#define AM2150_RCV 0x00
192#define AM2150_XMT 0x04
193#define AM2150_XMT_SKIP 0x09
194#define AM2150_RCV_NEXT 0x0A
195#define AM2150_RCV_FRAME_COUNT 0x0B
196#define AM2150_MACE_BANK 0x0C
197#define AM2150_MACE_BASE 0x10
198
199/* MACE Registers */
200#define MACE_RCVFIFO 0
201#define MACE_XMTFIFO 1
202#define MACE_XMTFC 2
203#define MACE_XMTFS 3
204#define MACE_XMTRC 4
205#define MACE_RCVFC 5
206#define MACE_RCVFS 6
207#define MACE_FIFOFC 7
208#define MACE_IR 8
209#define MACE_IMR 9
210#define MACE_PR 10
211#define MACE_BIUCC 11
212#define MACE_FIFOCC 12
213#define MACE_MACCC 13
214#define MACE_PLSCC 14
215#define MACE_PHYCC 15
216#define MACE_CHIPIDL 16
217#define MACE_CHIPIDH 17
218#define MACE_IAC 18
219/* Reserved */
220#define MACE_LADRF 20
221#define MACE_PADR 21
222/* Reserved */
223/* Reserved */
224#define MACE_MPC 24
225/* Reserved */
226#define MACE_RNTPC 26
227#define MACE_RCVCC 27
228/* Reserved */
229#define MACE_UTR 29
230#define MACE_RTR1 30
231#define MACE_RTR2 31
232
233/* MACE Bit Masks */
234#define MACE_XMTRC_EXDEF 0x80
235#define MACE_XMTRC_XMTRC 0x0F
236
237#define MACE_XMTFS_XMTSV 0x80
238#define MACE_XMTFS_UFLO 0x40
239#define MACE_XMTFS_LCOL 0x20
240#define MACE_XMTFS_MORE 0x10
241#define MACE_XMTFS_ONE 0x08
242#define MACE_XMTFS_DEFER 0x04
243#define MACE_XMTFS_LCAR 0x02
244#define MACE_XMTFS_RTRY 0x01
245
246#define MACE_RCVFS_RCVSTS 0xF000
247#define MACE_RCVFS_OFLO 0x8000
248#define MACE_RCVFS_CLSN 0x4000
249#define MACE_RCVFS_FRAM 0x2000
250#define MACE_RCVFS_FCS 0x1000
251
252#define MACE_FIFOFC_RCVFC 0xF0
253#define MACE_FIFOFC_XMTFC 0x0F
254
255#define MACE_IR_JAB 0x80
256#define MACE_IR_BABL 0x40
257#define MACE_IR_CERR 0x20
258#define MACE_IR_RCVCCO 0x10
259#define MACE_IR_RNTPCO 0x08
260#define MACE_IR_MPCO 0x04
261#define MACE_IR_RCVINT 0x02
262#define MACE_IR_XMTINT 0x01
263
264#define MACE_MACCC_PROM 0x80
265#define MACE_MACCC_DXMT2PD 0x40
266#define MACE_MACCC_EMBA 0x20
267#define MACE_MACCC_RESERVED 0x10
268#define MACE_MACCC_DRCVPA 0x08
269#define MACE_MACCC_DRCVBC 0x04
270#define MACE_MACCC_ENXMT 0x02
271#define MACE_MACCC_ENRCV 0x01
272
273#define MACE_PHYCC_LNKFL 0x80
274#define MACE_PHYCC_DLNKTST 0x40
275#define MACE_PHYCC_REVPOL 0x20
276#define MACE_PHYCC_DAPC 0x10
277#define MACE_PHYCC_LRT 0x08
278#define MACE_PHYCC_ASEL 0x04
279#define MACE_PHYCC_RWAKE 0x02
280#define MACE_PHYCC_AWAKE 0x01
281
282#define MACE_IAC_ADDRCHG 0x80
283#define MACE_IAC_PHYADDR 0x04
284#define MACE_IAC_LOGADDR 0x02
285
286#define MACE_UTR_RTRE 0x80
287#define MACE_UTR_RTRD 0x40
288#define MACE_UTR_RPA 0x20
289#define MACE_UTR_FCOLL 0x10
290#define MACE_UTR_RCVFCSE 0x08
291#define MACE_UTR_LOOP_INCL_MENDEC 0x06
292#define MACE_UTR_LOOP_NO_MENDEC 0x04
293#define MACE_UTR_LOOP_EXTERNAL 0x02
294#define MACE_UTR_LOOP_NONE 0x00
295#define MACE_UTR_RESERVED 0x01
296
297/* Switch MACE register bank (only 0 and 1 are valid) */
298#define MACEBANK(win_num) outb((win_num), ioaddr + AM2150_MACE_BANK)
299
300#define MACE_IMR_DEFAULT \
301 (0xFF - \
302 ( \
303 MACE_IR_CERR | \
304 MACE_IR_RCVCCO | \
305 MACE_IR_RNTPCO | \
306 MACE_IR_MPCO | \
307 MACE_IR_RCVINT | \
308 MACE_IR_XMTINT \
309 ) \
310 )
311#undef MACE_IMR_DEFAULT
312#define MACE_IMR_DEFAULT 0x00 /* New statistics handling: grab everything */
313
314#define TX_TIMEOUT ((400*HZ)/1000)
315
316/* ----------------------------------------------------------------------------
317Type Definitions
318---------------------------------------------------------------------------- */
319
320typedef struct _mace_statistics {
321 /* MACE_XMTFS */
322 int xmtsv;
323 int uflo;
324 int lcol;
325 int more;
326 int one;
327 int defer;
328 int lcar;
329 int rtry;
330
331 /* MACE_XMTRC */
332 int exdef;
333 int xmtrc;
334
335 /* RFS1--Receive Status (RCVSTS) */
336 int oflo;
337 int clsn;
338 int fram;
339 int fcs;
340
341 /* RFS2--Runt Packet Count (RNTPC) */
342 int rfs_rntpc;
343
344 /* RFS3--Receive Collision Count (RCVCC) */
345 int rfs_rcvcc;
346
347 /* MACE_IR */
348 int jab;
349 int babl;
350 int cerr;
351 int rcvcco;
352 int rntpco;
353 int mpco;
354
355 /* MACE_MPC */
356 int mpc;
357
358 /* MACE_RNTPC */
359 int rntpc;
360
361 /* MACE_RCVCC */
362 int rcvcc;
363} mace_statistics;
364
365typedef struct _mace_private {
Dominik Brodowskifd238232006-03-05 10:45:09 +0100366 struct pcmcia_device *p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 struct net_device_stats linux_stats; /* Linux statistics counters */
368 mace_statistics mace_stats; /* MACE chip statistics counters */
369
370 /* restore_multicast_list() state variables */
371 int multicast_ladrf[MACE_LADRF_LEN]; /* Logical address filter */
372 int multicast_num_addrs;
373
374 char tx_free_frames; /* Number of free transmit frame buffers */
375 char tx_irq_disabled; /* MACE TX interrupt disabled */
376
377 spinlock_t bank_lock; /* Must be held if you step off bank 0 */
378} mace_private;
379
380/* ----------------------------------------------------------------------------
381Private Global Variables
382---------------------------------------------------------------------------- */
383
Arjan van de Venf71e1302006-03-03 21:33:57 -0500384static const char *if_names[]={
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 "Auto", "10baseT", "BNC",
386};
387
388/* ----------------------------------------------------------------------------
389Parameters
390 These are the parameters that can be set during loading with
391 'insmod'.
392---------------------------------------------------------------------------- */
393
394MODULE_DESCRIPTION("New Media PCMCIA ethernet driver");
395MODULE_LICENSE("GPL");
396
397#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
398
399/* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
400INT_MODULE_PARM(if_port, 0);
401
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
403/* ----------------------------------------------------------------------------
404Function Prototypes
405---------------------------------------------------------------------------- */
406
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200407static int nmclan_config(struct pcmcia_device *link);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200408static void nmclan_release(struct pcmcia_device *link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
410static void nmclan_reset(struct net_device *dev);
411static int mace_config(struct net_device *dev, struct ifmap *map);
412static int mace_open(struct net_device *dev);
413static int mace_close(struct net_device *dev);
Stephen Hemmingerdbf02fa2009-08-31 19:50:49 +0000414static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
415 struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416static void mace_tx_timeout(struct net_device *dev);
David Howells7d12e782006-10-05 14:55:46 +0100417static irqreturn_t mace_interrupt(int irq, void *dev_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418static struct net_device_stats *mace_get_stats(struct net_device *dev);
419static int mace_rx(struct net_device *dev, unsigned char RxCnt);
420static void restore_multicast_list(struct net_device *dev);
421static void set_multicast_list(struct net_device *dev);
Jeff Garzik7282d492006-09-13 14:30:00 -0400422static const struct ethtool_ops netdev_ethtool_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
424
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100425static void nmclan_detach(struct pcmcia_device *p_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
Stephen Hemminger28b18012009-03-20 19:36:05 +0000427static const struct net_device_ops mace_netdev_ops = {
428 .ndo_open = mace_open,
429 .ndo_stop = mace_close,
430 .ndo_start_xmit = mace_start_xmit,
431 .ndo_tx_timeout = mace_tx_timeout,
432 .ndo_set_config = mace_config,
433 .ndo_get_stats = mace_get_stats,
434 .ndo_set_multicast_list = set_multicast_list,
435 .ndo_change_mtu = eth_change_mtu,
436 .ndo_set_mac_address = eth_mac_addr,
437 .ndo_validate_addr = eth_validate_addr,
438};
439
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440/* ----------------------------------------------------------------------------
441nmclan_attach
442 Creates an "instance" of the driver, allocating local data
443 structures for one device. The device is registered with Card
444 Services.
445---------------------------------------------------------------------------- */
446
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200447static int nmclan_probe(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448{
449 mace_private *lp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 struct net_device *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200452 dev_dbg(&link->dev, "nmclan_attach()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453
454 /* Create new ethernet device */
455 dev = alloc_etherdev(sizeof(mace_private));
456 if (!dev)
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100457 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 lp = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200459 lp->p_dev = link;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 link->priv = dev;
461
462 spin_lock_init(&lp->bank_lock);
Dominik Brodowski90abdc32010-07-24 17:23:51 +0200463 link->resource[0]->end = 32;
464 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 link->conf.Attributes = CONF_ENABLE_IRQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 link->conf.IntType = INT_MEMORY_AND_IO;
467 link->conf.ConfigIndex = 1;
468 link->conf.Present = PRESENT_OPTION;
469
470 lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
471
Stephen Hemminger28b18012009-03-20 19:36:05 +0000472 dev->netdev_ops = &mace_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 dev->watchdog_timeo = TX_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200476 return nmclan_config(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477} /* nmclan_attach */
478
479/* ----------------------------------------------------------------------------
480nmclan_detach
481 This deletes a driver "instance". The device is de-registered
482 with Card Services. If it has been released, all local data
483 structures are freed. Otherwise, the structures will be freed
484 when the device is released.
485---------------------------------------------------------------------------- */
486
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200487static void nmclan_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488{
489 struct net_device *dev = link->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200491 dev_dbg(&link->dev, "nmclan_detach\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492
Dominik Brodowskic7c2fa02010-03-20 19:39:26 +0100493 unregister_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100495 nmclan_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 free_netdev(dev);
498} /* nmclan_detach */
499
500/* ----------------------------------------------------------------------------
501mace_read
502 Reads a MACE register. This is bank independent; however, the
503 caller must ensure that this call is not interruptable. We are
504 assuming that during normal operation, the MACE is always in
505 bank 0.
506---------------------------------------------------------------------------- */
Olof Johansson906da802008-02-04 22:27:35 -0800507static int mace_read(mace_private *lp, unsigned int ioaddr, int reg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508{
509 int data = 0xFF;
510 unsigned long flags;
511
512 switch (reg >> 4) {
513 case 0: /* register 0-15 */
514 data = inb(ioaddr + AM2150_MACE_BASE + reg);
515 break;
516 case 1: /* register 16-31 */
517 spin_lock_irqsave(&lp->bank_lock, flags);
518 MACEBANK(1);
519 data = inb(ioaddr + AM2150_MACE_BASE + (reg & 0x0F));
520 MACEBANK(0);
521 spin_unlock_irqrestore(&lp->bank_lock, flags);
522 break;
523 }
524 return (data & 0xFF);
525} /* mace_read */
526
527/* ----------------------------------------------------------------------------
528mace_write
529 Writes to a MACE register. This is bank independent; however,
530 the caller must ensure that this call is not interruptable. We
531 are assuming that during normal operation, the MACE is always in
532 bank 0.
533---------------------------------------------------------------------------- */
Olof Johansson906da802008-02-04 22:27:35 -0800534static void mace_write(mace_private *lp, unsigned int ioaddr, int reg,
535 int data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536{
537 unsigned long flags;
538
539 switch (reg >> 4) {
540 case 0: /* register 0-15 */
541 outb(data & 0xFF, ioaddr + AM2150_MACE_BASE + reg);
542 break;
543 case 1: /* register 16-31 */
544 spin_lock_irqsave(&lp->bank_lock, flags);
545 MACEBANK(1);
546 outb(data & 0xFF, ioaddr + AM2150_MACE_BASE + (reg & 0x0F));
547 MACEBANK(0);
548 spin_unlock_irqrestore(&lp->bank_lock, flags);
549 break;
550 }
551} /* mace_write */
552
553/* ----------------------------------------------------------------------------
554mace_init
555 Resets the MACE chip.
556---------------------------------------------------------------------------- */
Olof Johansson906da802008-02-04 22:27:35 -0800557static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558{
559 int i;
560 int ct = 0;
561
562 /* MACE Software reset */
563 mace_write(lp, ioaddr, MACE_BIUCC, 1);
564 while (mace_read(lp, ioaddr, MACE_BIUCC) & 0x01) {
565 /* Wait for reset bit to be cleared automatically after <= 200ns */;
566 if(++ct > 500)
567 {
Joe Perches636b8112010-08-12 12:22:51 +0000568 pr_err("reset failed, card removed?\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 return -1;
570 }
571 udelay(1);
572 }
573 mace_write(lp, ioaddr, MACE_BIUCC, 0);
574
575 /* The Am2150 requires that the MACE FIFOs operate in burst mode. */
576 mace_write(lp, ioaddr, MACE_FIFOCC, 0x0F);
577
578 mace_write(lp,ioaddr, MACE_RCVFC, 0); /* Disable Auto Strip Receive */
579 mace_write(lp, ioaddr, MACE_IMR, 0xFF); /* Disable all interrupts until _open */
580
581 /*
582 * Bit 2-1 PORTSEL[1-0] Port Select.
583 * 00 AUI/10Base-2
584 * 01 10Base-T
585 * 10 DAI Port (reserved in Am2150)
586 * 11 GPSI
587 * For this card, only the first two are valid.
588 * So, PLSCC should be set to
589 * 0x00 for 10Base-2
590 * 0x02 for 10Base-T
591 * Or just set ASEL in PHYCC below!
592 */
593 switch (if_port) {
594 case 1:
595 mace_write(lp, ioaddr, MACE_PLSCC, 0x02);
596 break;
597 case 2:
598 mace_write(lp, ioaddr, MACE_PLSCC, 0x00);
599 break;
600 default:
601 mace_write(lp, ioaddr, MACE_PHYCC, /* ASEL */ 4);
602 /* ASEL Auto Select. When set, the PORTSEL[1-0] bits are overridden,
603 and the MACE device will automatically select the operating media
604 interface port. */
605 break;
606 }
607
608 mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_PHYADDR);
609 /* Poll ADDRCHG bit */
610 ct = 0;
611 while (mace_read(lp, ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG)
612 {
613 if(++ ct > 500)
614 {
Joe Perches636b8112010-08-12 12:22:51 +0000615 pr_err("ADDRCHG timeout, card removed?\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 return -1;
617 }
618 }
619 /* Set PADR register */
620 for (i = 0; i < ETHER_ADDR_LEN; i++)
621 mace_write(lp, ioaddr, MACE_PADR, enet_addr[i]);
622
623 /* MAC Configuration Control Register should be written last */
624 /* Let set_multicast_list set this. */
625 /* mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV); */
626 mace_write(lp, ioaddr, MACE_MACCC, 0x00);
627 return 0;
628} /* mace_init */
629
630/* ----------------------------------------------------------------------------
631nmclan_config
632 This routine is scheduled to run after a CARD_INSERTION event
633 is received, to configure the PCMCIA socket, and to make the
634 ethernet device available to the system.
635---------------------------------------------------------------------------- */
636
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200637static int nmclan_config(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 struct net_device *dev = link->priv;
640 mace_private *lp = netdev_priv(dev);
Dominik Brodowskidddfbd82009-10-18 23:54:24 +0200641 u8 *buf;
642 size_t len;
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200643 int i, ret;
Olof Johansson906da802008-02-04 22:27:35 -0800644 unsigned int ioaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200646 dev_dbg(&link->dev, "nmclan_config\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
Dominik Brodowski90abdc32010-07-24 17:23:51 +0200648 link->io_lines = 5;
649 ret = pcmcia_request_io(link);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200650 if (ret)
651 goto failed;
Dominik Brodowskieb141202010-03-07 12:21:16 +0100652 ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200653 if (ret)
654 goto failed;
655 ret = pcmcia_request_configuration(link, &link->conf);
656 if (ret)
657 goto failed;
658
Dominik Brodowskieb141202010-03-07 12:21:16 +0100659 dev->irq = link->irq;
Dominik Brodowski9a017a92010-07-24 15:58:54 +0200660 dev->base_addr = link->resource[0]->start;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661
662 ioaddr = dev->base_addr;
663
664 /* Read the ethernet address from the CIS. */
Dominik Brodowskidddfbd82009-10-18 23:54:24 +0200665 len = pcmcia_get_tuple(link, 0x80, &buf);
666 if (!buf || len < ETHER_ADDR_LEN) {
667 kfree(buf);
668 goto failed;
669 }
670 memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
671 kfree(buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672
673 /* Verify configuration by reading the MACE ID. */
674 {
675 char sig[2];
676
677 sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
678 sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
679 if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200680 dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 sig[0], sig[1]);
682 } else {
Joe Perches636b8112010-08-12 12:22:51 +0000683 pr_notice("mace id not found: %x %x should be 0x40 0x?9\n",
684 sig[0], sig[1]);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200685 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 }
687 }
688
689 if(mace_init(lp, ioaddr, dev->dev_addr) == -1)
690 goto failed;
691
692 /* The if_port symbol can be set when the module is loaded */
693 if (if_port <= 2)
694 dev->if_port = if_port;
695 else
Joe Perches636b8112010-08-12 12:22:51 +0000696 pr_notice("invalid if_port requested\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697
Dominik Brodowskidd2e5a12009-11-03 10:27:34 +0100698 SET_NETDEV_DEV(dev, &link->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699
700 i = register_netdev(dev);
701 if (i != 0) {
Joe Perches636b8112010-08-12 12:22:51 +0000702 pr_notice("register_netdev() failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 goto failed;
704 }
705
Joe Perches636b8112010-08-12 12:22:51 +0000706 netdev_info(dev, "nmclan: port %#3lx, irq %d, %s port, hw_addr %pM\n",
707 dev->base_addr, dev->irq, if_names[dev->if_port], dev->dev_addr);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200708 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710failed:
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200711 nmclan_release(link);
712 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713} /* nmclan_config */
714
715/* ----------------------------------------------------------------------------
716nmclan_release
717 After a card is removed, nmclan_release() will unregister the
718 net device, and release the PCMCIA configuration. If the device
719 is still open, this will be postponed until it is closed.
720---------------------------------------------------------------------------- */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200721static void nmclan_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722{
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200723 dev_dbg(&link->dev, "nmclan_release\n");
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200724 pcmcia_disable_device(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725}
726
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200727static int nmclan_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100728{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100729 struct net_device *dev = link->priv;
730
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100731 if (link->open)
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100732 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100733
734 return 0;
735}
736
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200737static int nmclan_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100738{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100739 struct net_device *dev = link->priv;
740
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100741 if (link->open) {
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100742 nmclan_reset(dev);
743 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100744 }
745
746 return 0;
747}
748
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749
750/* ----------------------------------------------------------------------------
751nmclan_reset
752 Reset and restore all of the Xilinx and MACE registers.
753---------------------------------------------------------------------------- */
754static void nmclan_reset(struct net_device *dev)
755{
756 mace_private *lp = netdev_priv(dev);
757
758#if RESET_XILINX
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200759 struct pcmcia_device *link = &lp->link;
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200760 u8 OrigCorValue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761
762 /* Save original COR value */
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200763 pcmcia_read_config_byte(link, CISREG_COR, &OrigCorValue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764
765 /* Reset Xilinx */
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200766 dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%x, resetting...\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 OrigCorValue);
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200768 pcmcia_write_config_byte(link, CISREG_COR, COR_SOFT_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 /* Need to wait for 20 ms for PCMCIA to finish reset. */
770
771 /* Restore original COR configuration index */
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200772 pcmcia_write_config_byte(link, CISREG_COR,
773 (COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 /* Xilinx is now completely reset along with the MACE chip. */
775 lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
776
777#endif /* #if RESET_XILINX */
778
779 /* Xilinx is now completely reset along with the MACE chip. */
780 lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
781
782 /* Reinitialize the MACE chip for operation. */
783 mace_init(lp, dev->base_addr, dev->dev_addr);
784 mace_write(lp, dev->base_addr, MACE_IMR, MACE_IMR_DEFAULT);
785
786 /* Restore the multicast list and enable TX and RX. */
787 restore_multicast_list(dev);
788} /* nmclan_reset */
789
790/* ----------------------------------------------------------------------------
791mace_config
792 [Someone tell me what this is supposed to do? Is if_port a defined
793 standard? If so, there should be defines to indicate 1=10Base-T,
794 2=10Base-2, etc. including limited automatic detection.]
795---------------------------------------------------------------------------- */
796static int mace_config(struct net_device *dev, struct ifmap *map)
797{
798 if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
799 if (map->port <= 2) {
800 dev->if_port = map->port;
Joe Perches636b8112010-08-12 12:22:51 +0000801 netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 } else
803 return -EINVAL;
804 }
805 return 0;
806} /* mace_config */
807
808/* ----------------------------------------------------------------------------
809mace_open
810 Open device driver.
811---------------------------------------------------------------------------- */
812static int mace_open(struct net_device *dev)
813{
Olof Johansson906da802008-02-04 22:27:35 -0800814 unsigned int ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 mace_private *lp = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200816 struct pcmcia_device *link = lp->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
Dominik Brodowski9940ec32006-03-05 11:04:33 +0100818 if (!pcmcia_dev_present(link))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 return -ENODEV;
820
821 link->open++;
822
823 MACEBANK(0);
824
825 netif_start_queue(dev);
826 nmclan_reset(dev);
827
828 return 0; /* Always succeed */
829} /* mace_open */
830
831/* ----------------------------------------------------------------------------
832mace_close
833 Closes device driver.
834---------------------------------------------------------------------------- */
835static int mace_close(struct net_device *dev)
836{
Olof Johansson906da802008-02-04 22:27:35 -0800837 unsigned int ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838 mace_private *lp = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200839 struct pcmcia_device *link = lp->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200841 dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
843 /* Mask off all interrupts from the MACE chip. */
844 outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
845
846 link->open--;
847 netif_stop_queue(dev);
848
849 return 0;
850} /* mace_close */
851
852static void netdev_get_drvinfo(struct net_device *dev,
853 struct ethtool_drvinfo *info)
854{
855 strcpy(info->driver, DRV_NAME);
856 strcpy(info->version, DRV_VERSION);
857 sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
858}
859
Jeff Garzik7282d492006-09-13 14:30:00 -0400860static const struct ethtool_ops netdev_ethtool_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 .get_drvinfo = netdev_get_drvinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862};
863
864/* ----------------------------------------------------------------------------
865mace_start_xmit
866 This routine begins the packet transmit function. When completed,
867 it will generate a transmit interrupt.
868
869 According to /usr/src/linux/net/inet/dev.c, if _start_xmit
870 returns 0, the "packet is now solely the responsibility of the
871 driver." If _start_xmit returns non-zero, the "transmission
872 failed, put skb back into a list."
873---------------------------------------------------------------------------- */
874
875static void mace_tx_timeout(struct net_device *dev)
876{
877 mace_private *lp = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200878 struct pcmcia_device *link = lp->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
Joe Perches636b8112010-08-12 12:22:51 +0000880 netdev_notice(dev, "transmit timed out -- ");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881#if RESET_ON_TIMEOUT
Joe Perches636b8112010-08-12 12:22:51 +0000882 pr_cont("resetting card\n");
Dominik Brodowski994917f2008-08-31 15:20:26 +0200883 pcmcia_reset_card(link->socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884#else /* #if RESET_ON_TIMEOUT */
Joe Perches636b8112010-08-12 12:22:51 +0000885 pr_cont("NOT resetting card\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886#endif /* #if RESET_ON_TIMEOUT */
Eric Dumazet1ae5dc32010-05-10 05:01:31 -0700887 dev->trans_start = jiffies; /* prevent tx timeout */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 netif_wake_queue(dev);
889}
890
Stephen Hemmingerdbf02fa2009-08-31 19:50:49 +0000891static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
892 struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893{
894 mace_private *lp = netdev_priv(dev);
Olof Johansson906da802008-02-04 22:27:35 -0800895 unsigned int ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896
897 netif_stop_queue(dev);
898
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200899 pr_debug("%s: mace_start_xmit(length = %ld) called.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 dev->name, (long)skb->len);
901
902#if (!TX_INTERRUPTABLE)
903 /* Disable MACE TX interrupts. */
904 outb(MACE_IMR_DEFAULT | MACE_IR_XMTINT,
905 ioaddr + AM2150_MACE_BASE + MACE_IMR);
906 lp->tx_irq_disabled=1;
907#endif /* #if (!TX_INTERRUPTABLE) */
908
909 {
910 /* This block must not be interrupted by another transmit request!
911 mace_tx_timeout will take care of timer-based retransmissions from
912 the upper layers. The interrupt handler is guaranteed never to
913 service a transmit interrupt while we are in here.
914 */
915
916 lp->linux_stats.tx_bytes += skb->len;
917 lp->tx_free_frames--;
918
919 /* WARNING: Write the _exact_ number of bytes written in the header! */
920 /* Put out the word header [must be an outw()] . . . */
921 outw(skb->len, ioaddr + AM2150_XMT);
922 /* . . . and the packet [may be any combination of outw() and outb()] */
923 outsw(ioaddr + AM2150_XMT, skb->data, skb->len >> 1);
924 if (skb->len & 1) {
925 /* Odd byte transfer */
926 outb(skb->data[skb->len-1], ioaddr + AM2150_XMT);
927 }
928
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929#if MULTI_TX
930 if (lp->tx_free_frames > 0)
931 netif_start_queue(dev);
932#endif /* #if MULTI_TX */
933 }
934
935#if (!TX_INTERRUPTABLE)
936 /* Re-enable MACE TX interrupts. */
937 lp->tx_irq_disabled=0;
938 outb(MACE_IMR_DEFAULT, ioaddr + AM2150_MACE_BASE + MACE_IMR);
939#endif /* #if (!TX_INTERRUPTABLE) */
940
941 dev_kfree_skb(skb);
942
Patrick McHardy6ed10652009-06-23 06:03:08 +0000943 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944} /* mace_start_xmit */
945
946/* ----------------------------------------------------------------------------
947mace_interrupt
948 The interrupt handler.
949---------------------------------------------------------------------------- */
David Howells7d12e782006-10-05 14:55:46 +0100950static irqreturn_t mace_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951{
952 struct net_device *dev = (struct net_device *) dev_id;
953 mace_private *lp = netdev_priv(dev);
Olof Johansson906da802008-02-04 22:27:35 -0800954 unsigned int ioaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 int status;
956 int IntrCnt = MACE_MAX_IR_ITERATIONS;
957
958 if (dev == NULL) {
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200959 pr_debug("mace_interrupt(): irq 0x%X for unknown device.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 irq);
961 return IRQ_NONE;
962 }
963
Micah Gruberc196d802007-07-24 10:44:56 +0800964 ioaddr = dev->base_addr;
965
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 if (lp->tx_irq_disabled) {
Joe Perches636b8112010-08-12 12:22:51 +0000967 const char *msg;
968 if (lp->tx_irq_disabled)
969 msg = "Interrupt with tx_irq_disabled";
970 else
971 msg = "Re-entering the interrupt handler";
972 netdev_notice(dev, "%s [isr=%02X, imr=%02X]\n",
973 msg,
974 inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
975 inb(ioaddr + AM2150_MACE_BASE + MACE_IMR));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976 /* WARNING: MACE_IR has been read! */
977 return IRQ_NONE;
978 }
979
980 if (!netif_device_present(dev)) {
Joe Perches636b8112010-08-12 12:22:51 +0000981 netdev_dbg(dev, "interrupt from dead card\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 return IRQ_NONE;
983 }
984
985 do {
986 /* WARNING: MACE_IR is a READ/CLEAR port! */
987 status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
988
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200989 pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
991 if (status & MACE_IR_RCVINT) {
992 mace_rx(dev, MACE_MAX_RX_ITERATIONS);
993 }
994
995 if (status & MACE_IR_XMTINT) {
996 unsigned char fifofc;
997 unsigned char xmtrc;
998 unsigned char xmtfs;
999
1000 fifofc = inb(ioaddr + AM2150_MACE_BASE + MACE_FIFOFC);
1001 if ((fifofc & MACE_FIFOFC_XMTFC)==0) {
1002 lp->linux_stats.tx_errors++;
1003 outb(0xFF, ioaddr + AM2150_XMT_SKIP);
1004 }
1005
1006 /* Transmit Retry Count (XMTRC, reg 4) */
1007 xmtrc = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTRC);
1008 if (xmtrc & MACE_XMTRC_EXDEF) lp->mace_stats.exdef++;
1009 lp->mace_stats.xmtrc += (xmtrc & MACE_XMTRC_XMTRC);
1010
1011 if (
1012 (xmtfs = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTFS)) &
1013 MACE_XMTFS_XMTSV /* Transmit Status Valid */
1014 ) {
1015 lp->mace_stats.xmtsv++;
1016
1017 if (xmtfs & ~MACE_XMTFS_XMTSV) {
1018 if (xmtfs & MACE_XMTFS_UFLO) {
1019 /* Underflow. Indicates that the Transmit FIFO emptied before
1020 the end of frame was reached. */
1021 lp->mace_stats.uflo++;
1022 }
1023 if (xmtfs & MACE_XMTFS_LCOL) {
1024 /* Late Collision */
1025 lp->mace_stats.lcol++;
1026 }
1027 if (xmtfs & MACE_XMTFS_MORE) {
1028 /* MORE than one retry was needed */
1029 lp->mace_stats.more++;
1030 }
1031 if (xmtfs & MACE_XMTFS_ONE) {
1032 /* Exactly ONE retry occurred */
1033 lp->mace_stats.one++;
1034 }
1035 if (xmtfs & MACE_XMTFS_DEFER) {
1036 /* Transmission was defered */
1037 lp->mace_stats.defer++;
1038 }
1039 if (xmtfs & MACE_XMTFS_LCAR) {
1040 /* Loss of carrier */
1041 lp->mace_stats.lcar++;
1042 }
1043 if (xmtfs & MACE_XMTFS_RTRY) {
1044 /* Retry error: transmit aborted after 16 attempts */
1045 lp->mace_stats.rtry++;
1046 }
1047 } /* if (xmtfs & ~MACE_XMTFS_XMTSV) */
1048
1049 } /* if (xmtfs & MACE_XMTFS_XMTSV) */
1050
1051 lp->linux_stats.tx_packets++;
1052 lp->tx_free_frames++;
1053 netif_wake_queue(dev);
1054 } /* if (status & MACE_IR_XMTINT) */
1055
1056 if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) {
1057 if (status & MACE_IR_JAB) {
1058 /* Jabber Error. Excessive transmit duration (20-150ms). */
1059 lp->mace_stats.jab++;
1060 }
1061 if (status & MACE_IR_BABL) {
1062 /* Babble Error. >1518 bytes transmitted. */
1063 lp->mace_stats.babl++;
1064 }
1065 if (status & MACE_IR_CERR) {
1066 /* Collision Error. CERR indicates the absence of the
1067 Signal Quality Error Test message after a packet
1068 transmission. */
1069 lp->mace_stats.cerr++;
1070 }
1071 if (status & MACE_IR_RCVCCO) {
1072 /* Receive Collision Count Overflow; */
1073 lp->mace_stats.rcvcco++;
1074 }
1075 if (status & MACE_IR_RNTPCO) {
1076 /* Runt Packet Count Overflow */
1077 lp->mace_stats.rntpco++;
1078 }
1079 if (status & MACE_IR_MPCO) {
1080 /* Missed Packet Count Overflow */
1081 lp->mace_stats.mpco++;
1082 }
1083 } /* if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) */
1084
1085 } while ((status & ~MACE_IMR_DEFAULT) && (--IntrCnt));
1086
1087 return IRQ_HANDLED;
1088} /* mace_interrupt */
1089
1090/* ----------------------------------------------------------------------------
1091mace_rx
1092 Receives packets.
1093---------------------------------------------------------------------------- */
1094static int mace_rx(struct net_device *dev, unsigned char RxCnt)
1095{
1096 mace_private *lp = netdev_priv(dev);
Olof Johansson906da802008-02-04 22:27:35 -08001097 unsigned int ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 unsigned char rx_framecnt;
1099 unsigned short rx_status;
1100
1101 while (
1102 ((rx_framecnt = inb(ioaddr + AM2150_RCV_FRAME_COUNT)) > 0) &&
1103 (rx_framecnt <= 12) && /* rx_framecnt==0xFF if card is extracted. */
1104 (RxCnt--)
1105 ) {
1106 rx_status = inw(ioaddr + AM2150_RCV);
1107
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001108 pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 " 0x%X.\n", dev->name, rx_framecnt, rx_status);
1110
1111 if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
1112 lp->linux_stats.rx_errors++;
1113 if (rx_status & MACE_RCVFS_OFLO) {
1114 lp->mace_stats.oflo++;
1115 }
1116 if (rx_status & MACE_RCVFS_CLSN) {
1117 lp->mace_stats.clsn++;
1118 }
1119 if (rx_status & MACE_RCVFS_FRAM) {
1120 lp->mace_stats.fram++;
1121 }
1122 if (rx_status & MACE_RCVFS_FCS) {
1123 lp->mace_stats.fcs++;
1124 }
1125 } else {
1126 short pkt_len = (rx_status & ~MACE_RCVFS_RCVSTS) - 4;
1127 /* Auto Strip is off, always subtract 4 */
1128 struct sk_buff *skb;
1129
1130 lp->mace_stats.rfs_rntpc += inb(ioaddr + AM2150_RCV);
1131 /* runt packet count */
1132 lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
1133 /* rcv collision count */
1134
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001135 pr_debug(" receiving packet size 0x%X rx_status"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 " 0x%X.\n", pkt_len, rx_status);
1137
1138 skb = dev_alloc_skb(pkt_len+2);
1139
1140 if (skb != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 skb_reserve(skb, 2);
1142 insw(ioaddr + AM2150_RCV, skb_put(skb, pkt_len), pkt_len>>1);
1143 if (pkt_len & 1)
Arnaldo Carvalho de Melo27a884d2007-04-19 20:29:13 -07001144 *(skb_tail_pointer(skb) - 1) = inb(ioaddr + AM2150_RCV);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 skb->protocol = eth_type_trans(skb, dev);
1146
1147 netif_rx(skb); /* Send the packet to the upper (protocol) layers. */
1148
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 lp->linux_stats.rx_packets++;
Florin Malita6f258912006-06-04 02:51:26 -07001150 lp->linux_stats.rx_bytes += pkt_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
1152 continue;
1153 } else {
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001154 pr_debug("%s: couldn't allocate a sk_buff of size"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 " %d.\n", dev->name, pkt_len);
1156 lp->linux_stats.rx_dropped++;
1157 }
1158 }
1159 outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
1160 } /* while */
1161
1162 return 0;
1163} /* mace_rx */
1164
1165/* ----------------------------------------------------------------------------
1166pr_linux_stats
1167---------------------------------------------------------------------------- */
1168static void pr_linux_stats(struct net_device_stats *pstats)
1169{
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001170 pr_debug("pr_linux_stats\n");
1171 pr_debug(" rx_packets=%-7ld tx_packets=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172 (long)pstats->rx_packets, (long)pstats->tx_packets);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001173 pr_debug(" rx_errors=%-7ld tx_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174 (long)pstats->rx_errors, (long)pstats->tx_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001175 pr_debug(" rx_dropped=%-7ld tx_dropped=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 (long)pstats->rx_dropped, (long)pstats->tx_dropped);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001177 pr_debug(" multicast=%-7ld collisions=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 (long)pstats->multicast, (long)pstats->collisions);
1179
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001180 pr_debug(" rx_length_errors=%-7ld rx_over_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 (long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001182 pr_debug(" rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 (long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001184 pr_debug(" rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185 (long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
1186
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001187 pr_debug(" tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188 (long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001189 pr_debug(" tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 (long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001191 pr_debug(" tx_window_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 (long)pstats->tx_window_errors);
1193} /* pr_linux_stats */
1194
1195/* ----------------------------------------------------------------------------
1196pr_mace_stats
1197---------------------------------------------------------------------------- */
1198static void pr_mace_stats(mace_statistics *pstats)
1199{
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001200 pr_debug("pr_mace_stats\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001202 pr_debug(" xmtsv=%-7d uflo=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 pstats->xmtsv, pstats->uflo);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001204 pr_debug(" lcol=%-7d more=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 pstats->lcol, pstats->more);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001206 pr_debug(" one=%-7d defer=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 pstats->one, pstats->defer);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001208 pr_debug(" lcar=%-7d rtry=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 pstats->lcar, pstats->rtry);
1210
1211 /* MACE_XMTRC */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001212 pr_debug(" exdef=%-7d xmtrc=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 pstats->exdef, pstats->xmtrc);
1214
1215 /* RFS1--Receive Status (RCVSTS) */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001216 pr_debug(" oflo=%-7d clsn=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 pstats->oflo, pstats->clsn);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001218 pr_debug(" fram=%-7d fcs=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 pstats->fram, pstats->fcs);
1220
1221 /* RFS2--Runt Packet Count (RNTPC) */
1222 /* RFS3--Receive Collision Count (RCVCC) */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001223 pr_debug(" rfs_rntpc=%-7d rfs_rcvcc=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 pstats->rfs_rntpc, pstats->rfs_rcvcc);
1225
1226 /* MACE_IR */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001227 pr_debug(" jab=%-7d babl=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 pstats->jab, pstats->babl);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001229 pr_debug(" cerr=%-7d rcvcco=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 pstats->cerr, pstats->rcvcco);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001231 pr_debug(" rntpco=%-7d mpco=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 pstats->rntpco, pstats->mpco);
1233
1234 /* MACE_MPC */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001235 pr_debug(" mpc=%d\n", pstats->mpc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236
1237 /* MACE_RNTPC */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001238 pr_debug(" rntpc=%d\n", pstats->rntpc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
1240 /* MACE_RCVCC */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001241 pr_debug(" rcvcc=%d\n", pstats->rcvcc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
1243} /* pr_mace_stats */
1244
1245/* ----------------------------------------------------------------------------
1246update_stats
1247 Update statistics. We change to register window 1, so this
1248 should be run single-threaded if the device is active. This is
1249 expected to be a rare operation, and it's simpler for the rest
1250 of the driver to assume that window 0 is always valid rather
1251 than use a special window-state variable.
1252
1253 oflo & uflo should _never_ occur since it would mean the Xilinx
1254 was not able to transfer data between the MACE FIFO and the
1255 card's SRAM fast enough. If this happens, something is
1256 seriously wrong with the hardware.
1257---------------------------------------------------------------------------- */
Olof Johansson906da802008-02-04 22:27:35 -08001258static void update_stats(unsigned int ioaddr, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259{
1260 mace_private *lp = netdev_priv(dev);
1261
1262 lp->mace_stats.rcvcc += mace_read(lp, ioaddr, MACE_RCVCC);
1263 lp->mace_stats.rntpc += mace_read(lp, ioaddr, MACE_RNTPC);
1264 lp->mace_stats.mpc += mace_read(lp, ioaddr, MACE_MPC);
1265 /* At this point, mace_stats is fully updated for this call.
1266 We may now update the linux_stats. */
1267
1268 /* The MACE has no equivalent for linux_stats field which are commented
1269 out. */
1270
1271 /* lp->linux_stats.multicast; */
1272 lp->linux_stats.collisions =
1273 lp->mace_stats.rcvcco * 256 + lp->mace_stats.rcvcc;
1274 /* Collision: The MACE may retry sending a packet 15 times
1275 before giving up. The retry count is in XMTRC.
1276 Does each retry constitute a collision?
1277 If so, why doesn't the RCVCC record these collisions? */
1278
1279 /* detailed rx_errors: */
1280 lp->linux_stats.rx_length_errors =
1281 lp->mace_stats.rntpco * 256 + lp->mace_stats.rntpc;
1282 /* lp->linux_stats.rx_over_errors */
1283 lp->linux_stats.rx_crc_errors = lp->mace_stats.fcs;
1284 lp->linux_stats.rx_frame_errors = lp->mace_stats.fram;
1285 lp->linux_stats.rx_fifo_errors = lp->mace_stats.oflo;
1286 lp->linux_stats.rx_missed_errors =
1287 lp->mace_stats.mpco * 256 + lp->mace_stats.mpc;
1288
1289 /* detailed tx_errors */
1290 lp->linux_stats.tx_aborted_errors = lp->mace_stats.rtry;
1291 lp->linux_stats.tx_carrier_errors = lp->mace_stats.lcar;
1292 /* LCAR usually results from bad cabling. */
1293 lp->linux_stats.tx_fifo_errors = lp->mace_stats.uflo;
1294 lp->linux_stats.tx_heartbeat_errors = lp->mace_stats.cerr;
1295 /* lp->linux_stats.tx_window_errors; */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296} /* update_stats */
1297
1298/* ----------------------------------------------------------------------------
1299mace_get_stats
1300 Gathers ethernet statistics from the MACE chip.
1301---------------------------------------------------------------------------- */
1302static struct net_device_stats *mace_get_stats(struct net_device *dev)
1303{
1304 mace_private *lp = netdev_priv(dev);
1305
1306 update_stats(dev->base_addr, dev);
1307
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001308 pr_debug("%s: updating the statistics.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309 pr_linux_stats(&lp->linux_stats);
1310 pr_mace_stats(&lp->mace_stats);
1311
1312 return &lp->linux_stats;
1313} /* net_device_stats */
1314
1315/* ----------------------------------------------------------------------------
1316updateCRC
1317 Modified from Am79C90 data sheet.
1318---------------------------------------------------------------------------- */
1319
1320#ifdef BROKEN_MULTICAST
1321
1322static void updateCRC(int *CRC, int bit)
1323{
1324 int poly[]={
1325 1,1,1,0, 1,1,0,1,
1326 1,0,1,1, 1,0,0,0,
1327 1,0,0,0, 0,0,1,1,
1328 0,0,1,0, 0,0,0,0
1329 }; /* CRC polynomial. poly[n] = coefficient of the x**n term of the
1330 CRC generator polynomial. */
1331
1332 int j;
1333
1334 /* shift CRC and control bit (CRC[32]) */
1335 for (j = 32; j > 0; j--)
1336 CRC[j] = CRC[j-1];
1337 CRC[0] = 0;
1338
1339 /* If bit XOR(control bit) = 1, set CRC = CRC XOR polynomial. */
1340 if (bit ^ CRC[32])
1341 for (j = 0; j < 32; j++)
1342 CRC[j] ^= poly[j];
1343} /* updateCRC */
1344
1345/* ----------------------------------------------------------------------------
1346BuildLAF
1347 Build logical address filter.
1348 Modified from Am79C90 data sheet.
1349
1350Input
1351 ladrf: logical address filter (contents initialized to 0)
1352 adr: ethernet address
1353---------------------------------------------------------------------------- */
1354static void BuildLAF(int *ladrf, int *adr)
1355{
1356 int CRC[33]={1}; /* CRC register, 1 word/bit + extra control bit */
1357
1358 int i, byte; /* temporary array indices */
1359 int hashcode; /* the output object */
1360
1361 CRC[32]=0;
1362
1363 for (byte = 0; byte < 6; byte++)
1364 for (i = 0; i < 8; i++)
1365 updateCRC(CRC, (adr[byte] >> i) & 1);
1366
1367 hashcode = 0;
1368 for (i = 0; i < 6; i++)
1369 hashcode = (hashcode << 1) + CRC[i];
1370
1371 byte = hashcode >> 3;
1372 ladrf[byte] |= (1 << (hashcode & 7));
1373
1374#ifdef PCMCIA_DEBUG
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001375 if (0)
Joe Perchesad361c92009-07-06 13:05:40 -07001376 printk(KERN_DEBUG " adr =%pM\n", adr);
1377 printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
1378 for (i = 0; i < 8; i++)
Joe Perches636b8112010-08-12 12:22:51 +00001379 pr_cont(" %02X", ladrf[i]);
1380 pr_cont("\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381#endif
1382} /* BuildLAF */
1383
1384/* ----------------------------------------------------------------------------
1385restore_multicast_list
1386 Restores the multicast filter for MACE chip to the last
1387 set_multicast_list() call.
1388
1389Input
1390 multicast_num_addrs
1391 multicast_ladrf[]
1392---------------------------------------------------------------------------- */
1393static void restore_multicast_list(struct net_device *dev)
1394{
1395 mace_private *lp = netdev_priv(dev);
1396 int num_addrs = lp->multicast_num_addrs;
1397 int *ladrf = lp->multicast_ladrf;
Olof Johansson906da802008-02-04 22:27:35 -08001398 unsigned int ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 int i;
1400
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001401 pr_debug("%s: restoring Rx mode to %d addresses.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 dev->name, num_addrs);
1403
1404 if (num_addrs > 0) {
1405
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001406 pr_debug("Attempt to restore multicast list detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
1408 mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
1409 /* Poll ADDRCHG bit */
1410 while (mace_read(lp, ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG)
1411 ;
1412 /* Set LADRF register */
1413 for (i = 0; i < MACE_LADRF_LEN; i++)
1414 mace_write(lp, ioaddr, MACE_LADRF, ladrf[i]);
1415
1416 mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_RCVFCSE | MACE_UTR_LOOP_EXTERNAL);
1417 mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
1418
1419 } else if (num_addrs < 0) {
1420
1421 /* Promiscuous mode: receive all packets */
1422 mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
1423 mace_write(lp, ioaddr, MACE_MACCC,
1424 MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV
1425 );
1426
1427 } else {
1428
1429 /* Normal mode */
1430 mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
1431 mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
1432
1433 }
1434} /* restore_multicast_list */
1435
1436/* ----------------------------------------------------------------------------
1437set_multicast_list
1438 Set or clear the multicast filter for this adaptor.
1439
1440Input
1441 num_addrs == -1 Promiscuous mode, receive all packets
1442 num_addrs == 0 Normal mode, clear multicast list
1443 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
1444 best-effort filtering.
1445Output
1446 multicast_num_addrs
1447 multicast_ladrf[]
1448---------------------------------------------------------------------------- */
1449
1450static void set_multicast_list(struct net_device *dev)
1451{
1452 mace_private *lp = netdev_priv(dev);
1453 int adr[ETHER_ADDR_LEN] = {0}; /* Ethernet address */
Jiri Pirko22bedad2010-04-01 21:22:57 +00001454 struct netdev_hw_addr *ha;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
1456#ifdef PCMCIA_DEBUG
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001457 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458 static int old;
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001459 if (netdev_mc_count(dev) != old) {
1460 old = netdev_mc_count(dev);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001461 pr_debug("%s: setting Rx mode to %d addresses.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 dev->name, old);
1463 }
1464 }
1465#endif
1466
1467 /* Set multicast_num_addrs. */
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001468 lp->multicast_num_addrs = netdev_mc_count(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469
1470 /* Set multicast_ladrf. */
1471 if (num_addrs > 0) {
1472 /* Calculate multicast logical address filter */
1473 memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN);
Jiri Pirko22bedad2010-04-01 21:22:57 +00001474 netdev_for_each_mc_addr(ha, dev) {
1475 memcpy(adr, ha->addr, ETHER_ADDR_LEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 BuildLAF(lp->multicast_ladrf, adr);
1477 }
1478 }
1479
1480 restore_multicast_list(dev);
1481
1482} /* set_multicast_list */
1483
1484#endif /* BROKEN_MULTICAST */
1485
1486static void restore_multicast_list(struct net_device *dev)
1487{
Olof Johansson906da802008-02-04 22:27:35 -08001488 unsigned int ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 mace_private *lp = netdev_priv(dev);
1490
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001491 pr_debug("%s: restoring Rx mode to %d addresses.\n", dev->name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 lp->multicast_num_addrs);
1493
1494 if (dev->flags & IFF_PROMISC) {
1495 /* Promiscuous mode: receive all packets */
1496 mace_write(lp,ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
1497 mace_write(lp, ioaddr, MACE_MACCC,
1498 MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV
1499 );
1500 } else {
1501 /* Normal mode */
1502 mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
1503 mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
1504 }
1505} /* restore_multicast_list */
1506
1507static void set_multicast_list(struct net_device *dev)
1508{
1509 mace_private *lp = netdev_priv(dev);
1510
1511#ifdef PCMCIA_DEBUG
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001512 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 static int old;
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001514 if (netdev_mc_count(dev) != old) {
1515 old = netdev_mc_count(dev);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001516 pr_debug("%s: setting Rx mode to %d addresses.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 dev->name, old);
1518 }
1519 }
1520#endif
1521
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001522 lp->multicast_num_addrs = netdev_mc_count(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 restore_multicast_list(dev);
1524
1525} /* set_multicast_list */
1526
Dominik Brodowskia58e26c2005-06-27 16:28:23 -07001527static struct pcmcia_device_id nmclan_ids[] = {
1528 PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Ethernet", 0x085a850b, 0x00b2e941),
Komurod277ad02005-07-28 01:07:24 -07001529 PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet+", 0xebf1d60, 0xad673aaf),
Dominik Brodowskia58e26c2005-06-27 16:28:23 -07001530 PCMCIA_DEVICE_NULL,
1531};
1532MODULE_DEVICE_TABLE(pcmcia, nmclan_ids);
1533
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534static struct pcmcia_driver nmclan_cs_driver = {
1535 .owner = THIS_MODULE,
1536 .drv = {
1537 .name = "nmclan_cs",
1538 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +02001539 .probe = nmclan_probe,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001540 .remove = nmclan_detach,
Dominik Brodowskia58e26c2005-06-27 16:28:23 -07001541 .id_table = nmclan_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01001542 .suspend = nmclan_suspend,
1543 .resume = nmclan_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544};
1545
1546static int __init init_nmclan_cs(void)
1547{
1548 return pcmcia_register_driver(&nmclan_cs_driver);
1549}
1550
1551static void __exit exit_nmclan_cs(void)
1552{
1553 pcmcia_unregister_driver(&nmclan_cs_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554}
1555
1556module_init(init_nmclan_cs);
1557module_exit(exit_nmclan_cs);