blob: 98c4a69760456cf5f80f4027fd12e00a230b3e96 [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
114#define DRV_NAME "nmclan_cs"
115#define DRV_VERSION "0.16"
116
117
118/* ----------------------------------------------------------------------------
119Conditional Compilation Options
120---------------------------------------------------------------------------- */
121
122#define MULTI_TX 0
123#define RESET_ON_TIMEOUT 1
124#define TX_INTERRUPTABLE 1
125#define RESET_XILINX 0
126
127/* ----------------------------------------------------------------------------
128Include Files
129---------------------------------------------------------------------------- */
130
131#include <linux/module.h>
132#include <linux/kernel.h>
133#include <linux/init.h>
134#include <linux/ptrace.h>
135#include <linux/slab.h>
136#include <linux/string.h>
137#include <linux/timer.h>
138#include <linux/interrupt.h>
139#include <linux/in.h>
140#include <linux/delay.h>
141#include <linux/ethtool.h>
142#include <linux/netdevice.h>
143#include <linux/etherdevice.h>
144#include <linux/skbuff.h>
145#include <linux/if_arp.h>
146#include <linux/ioport.h>
147#include <linux/bitops.h>
148
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149#include <pcmcia/cs.h>
150#include <pcmcia/cisreg.h>
151#include <pcmcia/cistpl.h>
152#include <pcmcia/ds.h>
153
154#include <asm/uaccess.h>
155#include <asm/io.h>
156#include <asm/system.h>
157
158/* ----------------------------------------------------------------------------
159Defines
160---------------------------------------------------------------------------- */
161
162#define ETHER_ADDR_LEN ETH_ALEN
163 /* 6 bytes in an Ethernet Address */
164#define MACE_LADRF_LEN 8
165 /* 8 bytes in Logical Address Filter */
166
167/* Loop Control Defines */
168#define MACE_MAX_IR_ITERATIONS 10
169#define MACE_MAX_RX_ITERATIONS 12
170 /*
171 TBD: Dean brought this up, and I assumed the hardware would
172 handle it:
173
174 If MACE_MAX_RX_ITERATIONS is > 1, rx_framecnt may still be
175 non-zero when the isr exits. We may not get another interrupt
176 to process the remaining packets for some time.
177 */
178
179/*
180The Am2150 has a Xilinx XC3042 field programmable gate array (FPGA)
181which manages the interface between the MACE and the PCMCIA bus. It
182also includes buffer management for the 32K x 8 SRAM to control up to
183four transmit and 12 receive frames at a time.
184*/
185#define AM2150_MAX_TX_FRAMES 4
186#define AM2150_MAX_RX_FRAMES 12
187
188/* Am2150 Ethernet Card I/O Mapping */
189#define AM2150_RCV 0x00
190#define AM2150_XMT 0x04
191#define AM2150_XMT_SKIP 0x09
192#define AM2150_RCV_NEXT 0x0A
193#define AM2150_RCV_FRAME_COUNT 0x0B
194#define AM2150_MACE_BANK 0x0C
195#define AM2150_MACE_BASE 0x10
196
197/* MACE Registers */
198#define MACE_RCVFIFO 0
199#define MACE_XMTFIFO 1
200#define MACE_XMTFC 2
201#define MACE_XMTFS 3
202#define MACE_XMTRC 4
203#define MACE_RCVFC 5
204#define MACE_RCVFS 6
205#define MACE_FIFOFC 7
206#define MACE_IR 8
207#define MACE_IMR 9
208#define MACE_PR 10
209#define MACE_BIUCC 11
210#define MACE_FIFOCC 12
211#define MACE_MACCC 13
212#define MACE_PLSCC 14
213#define MACE_PHYCC 15
214#define MACE_CHIPIDL 16
215#define MACE_CHIPIDH 17
216#define MACE_IAC 18
217/* Reserved */
218#define MACE_LADRF 20
219#define MACE_PADR 21
220/* Reserved */
221/* Reserved */
222#define MACE_MPC 24
223/* Reserved */
224#define MACE_RNTPC 26
225#define MACE_RCVCC 27
226/* Reserved */
227#define MACE_UTR 29
228#define MACE_RTR1 30
229#define MACE_RTR2 31
230
231/* MACE Bit Masks */
232#define MACE_XMTRC_EXDEF 0x80
233#define MACE_XMTRC_XMTRC 0x0F
234
235#define MACE_XMTFS_XMTSV 0x80
236#define MACE_XMTFS_UFLO 0x40
237#define MACE_XMTFS_LCOL 0x20
238#define MACE_XMTFS_MORE 0x10
239#define MACE_XMTFS_ONE 0x08
240#define MACE_XMTFS_DEFER 0x04
241#define MACE_XMTFS_LCAR 0x02
242#define MACE_XMTFS_RTRY 0x01
243
244#define MACE_RCVFS_RCVSTS 0xF000
245#define MACE_RCVFS_OFLO 0x8000
246#define MACE_RCVFS_CLSN 0x4000
247#define MACE_RCVFS_FRAM 0x2000
248#define MACE_RCVFS_FCS 0x1000
249
250#define MACE_FIFOFC_RCVFC 0xF0
251#define MACE_FIFOFC_XMTFC 0x0F
252
253#define MACE_IR_JAB 0x80
254#define MACE_IR_BABL 0x40
255#define MACE_IR_CERR 0x20
256#define MACE_IR_RCVCCO 0x10
257#define MACE_IR_RNTPCO 0x08
258#define MACE_IR_MPCO 0x04
259#define MACE_IR_RCVINT 0x02
260#define MACE_IR_XMTINT 0x01
261
262#define MACE_MACCC_PROM 0x80
263#define MACE_MACCC_DXMT2PD 0x40
264#define MACE_MACCC_EMBA 0x20
265#define MACE_MACCC_RESERVED 0x10
266#define MACE_MACCC_DRCVPA 0x08
267#define MACE_MACCC_DRCVBC 0x04
268#define MACE_MACCC_ENXMT 0x02
269#define MACE_MACCC_ENRCV 0x01
270
271#define MACE_PHYCC_LNKFL 0x80
272#define MACE_PHYCC_DLNKTST 0x40
273#define MACE_PHYCC_REVPOL 0x20
274#define MACE_PHYCC_DAPC 0x10
275#define MACE_PHYCC_LRT 0x08
276#define MACE_PHYCC_ASEL 0x04
277#define MACE_PHYCC_RWAKE 0x02
278#define MACE_PHYCC_AWAKE 0x01
279
280#define MACE_IAC_ADDRCHG 0x80
281#define MACE_IAC_PHYADDR 0x04
282#define MACE_IAC_LOGADDR 0x02
283
284#define MACE_UTR_RTRE 0x80
285#define MACE_UTR_RTRD 0x40
286#define MACE_UTR_RPA 0x20
287#define MACE_UTR_FCOLL 0x10
288#define MACE_UTR_RCVFCSE 0x08
289#define MACE_UTR_LOOP_INCL_MENDEC 0x06
290#define MACE_UTR_LOOP_NO_MENDEC 0x04
291#define MACE_UTR_LOOP_EXTERNAL 0x02
292#define MACE_UTR_LOOP_NONE 0x00
293#define MACE_UTR_RESERVED 0x01
294
295/* Switch MACE register bank (only 0 and 1 are valid) */
296#define MACEBANK(win_num) outb((win_num), ioaddr + AM2150_MACE_BANK)
297
298#define MACE_IMR_DEFAULT \
299 (0xFF - \
300 ( \
301 MACE_IR_CERR | \
302 MACE_IR_RCVCCO | \
303 MACE_IR_RNTPCO | \
304 MACE_IR_MPCO | \
305 MACE_IR_RCVINT | \
306 MACE_IR_XMTINT \
307 ) \
308 )
309#undef MACE_IMR_DEFAULT
310#define MACE_IMR_DEFAULT 0x00 /* New statistics handling: grab everything */
311
312#define TX_TIMEOUT ((400*HZ)/1000)
313
314/* ----------------------------------------------------------------------------
315Type Definitions
316---------------------------------------------------------------------------- */
317
318typedef struct _mace_statistics {
319 /* MACE_XMTFS */
320 int xmtsv;
321 int uflo;
322 int lcol;
323 int more;
324 int one;
325 int defer;
326 int lcar;
327 int rtry;
328
329 /* MACE_XMTRC */
330 int exdef;
331 int xmtrc;
332
333 /* RFS1--Receive Status (RCVSTS) */
334 int oflo;
335 int clsn;
336 int fram;
337 int fcs;
338
339 /* RFS2--Runt Packet Count (RNTPC) */
340 int rfs_rntpc;
341
342 /* RFS3--Receive Collision Count (RCVCC) */
343 int rfs_rcvcc;
344
345 /* MACE_IR */
346 int jab;
347 int babl;
348 int cerr;
349 int rcvcco;
350 int rntpco;
351 int mpco;
352
353 /* MACE_MPC */
354 int mpc;
355
356 /* MACE_RNTPC */
357 int rntpc;
358
359 /* MACE_RCVCC */
360 int rcvcc;
361} mace_statistics;
362
363typedef struct _mace_private {
Dominik Brodowskifd238232006-03-05 10:45:09 +0100364 struct pcmcia_device *p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 struct net_device_stats linux_stats; /* Linux statistics counters */
366 mace_statistics mace_stats; /* MACE chip statistics counters */
367
368 /* restore_multicast_list() state variables */
369 int multicast_ladrf[MACE_LADRF_LEN]; /* Logical address filter */
370 int multicast_num_addrs;
371
372 char tx_free_frames; /* Number of free transmit frame buffers */
373 char tx_irq_disabled; /* MACE TX interrupt disabled */
374
375 spinlock_t bank_lock; /* Must be held if you step off bank 0 */
376} mace_private;
377
378/* ----------------------------------------------------------------------------
379Private Global Variables
380---------------------------------------------------------------------------- */
381
Arjan van de Venf71e1302006-03-03 21:33:57 -0500382static const char *if_names[]={
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 "Auto", "10baseT", "BNC",
384};
385
386/* ----------------------------------------------------------------------------
387Parameters
388 These are the parameters that can be set during loading with
389 'insmod'.
390---------------------------------------------------------------------------- */
391
392MODULE_DESCRIPTION("New Media PCMCIA ethernet driver");
393MODULE_LICENSE("GPL");
394
395#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
396
397/* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
398INT_MODULE_PARM(if_port, 0);
399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
401/* ----------------------------------------------------------------------------
402Function Prototypes
403---------------------------------------------------------------------------- */
404
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200405static int nmclan_config(struct pcmcia_device *link);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200406static void nmclan_release(struct pcmcia_device *link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
408static void nmclan_reset(struct net_device *dev);
409static int mace_config(struct net_device *dev, struct ifmap *map);
410static int mace_open(struct net_device *dev);
411static int mace_close(struct net_device *dev);
Stephen Hemmingerdbf02fa2009-08-31 19:50:49 +0000412static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
413 struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414static void mace_tx_timeout(struct net_device *dev);
David Howells7d12e782006-10-05 14:55:46 +0100415static irqreturn_t mace_interrupt(int irq, void *dev_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416static struct net_device_stats *mace_get_stats(struct net_device *dev);
417static int mace_rx(struct net_device *dev, unsigned char RxCnt);
418static void restore_multicast_list(struct net_device *dev);
419static void set_multicast_list(struct net_device *dev);
Jeff Garzik7282d492006-09-13 14:30:00 -0400420static const struct ethtool_ops netdev_ethtool_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421
422
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100423static void nmclan_detach(struct pcmcia_device *p_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
Stephen Hemminger28b18012009-03-20 19:36:05 +0000425static const struct net_device_ops mace_netdev_ops = {
426 .ndo_open = mace_open,
427 .ndo_stop = mace_close,
428 .ndo_start_xmit = mace_start_xmit,
429 .ndo_tx_timeout = mace_tx_timeout,
430 .ndo_set_config = mace_config,
431 .ndo_get_stats = mace_get_stats,
432 .ndo_set_multicast_list = set_multicast_list,
433 .ndo_change_mtu = eth_change_mtu,
434 .ndo_set_mac_address = eth_mac_addr,
435 .ndo_validate_addr = eth_validate_addr,
436};
437
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438/* ----------------------------------------------------------------------------
439nmclan_attach
440 Creates an "instance" of the driver, allocating local data
441 structures for one device. The device is registered with Card
442 Services.
443---------------------------------------------------------------------------- */
444
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200445static int nmclan_probe(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446{
447 mace_private *lp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 struct net_device *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200450 dev_dbg(&link->dev, "nmclan_attach()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451
452 /* Create new ethernet device */
453 dev = alloc_etherdev(sizeof(mace_private));
454 if (!dev)
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100455 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456 lp = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200457 lp->p_dev = link;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 link->priv = dev;
459
460 spin_lock_init(&lp->bank_lock);
Dominik Brodowski90abdc32010-07-24 17:23:51 +0200461 link->resource[0]->end = 32;
462 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 link->conf.Attributes = CONF_ENABLE_IRQ;
Dominik Brodowski7feabb62010-07-29 18:35:47 +0200464 link->config_index = 1;
465 link->config_regs = PRESENT_OPTION;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466
467 lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
468
Stephen Hemminger28b18012009-03-20 19:36:05 +0000469 dev->netdev_ops = &mace_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 dev->watchdog_timeo = TX_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200473 return nmclan_config(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474} /* nmclan_attach */
475
476/* ----------------------------------------------------------------------------
477nmclan_detach
478 This deletes a driver "instance". The device is de-registered
479 with Card Services. If it has been released, all local data
480 structures are freed. Otherwise, the structures will be freed
481 when the device is released.
482---------------------------------------------------------------------------- */
483
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200484static void nmclan_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485{
486 struct net_device *dev = link->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200488 dev_dbg(&link->dev, "nmclan_detach\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489
Dominik Brodowskic7c2fa02010-03-20 19:39:26 +0100490 unregister_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100492 nmclan_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 free_netdev(dev);
495} /* nmclan_detach */
496
497/* ----------------------------------------------------------------------------
498mace_read
499 Reads a MACE register. This is bank independent; however, the
500 caller must ensure that this call is not interruptable. We are
501 assuming that during normal operation, the MACE is always in
502 bank 0.
503---------------------------------------------------------------------------- */
Olof Johansson906da802008-02-04 22:27:35 -0800504static int mace_read(mace_private *lp, unsigned int ioaddr, int reg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505{
506 int data = 0xFF;
507 unsigned long flags;
508
509 switch (reg >> 4) {
510 case 0: /* register 0-15 */
511 data = inb(ioaddr + AM2150_MACE_BASE + reg);
512 break;
513 case 1: /* register 16-31 */
514 spin_lock_irqsave(&lp->bank_lock, flags);
515 MACEBANK(1);
516 data = inb(ioaddr + AM2150_MACE_BASE + (reg & 0x0F));
517 MACEBANK(0);
518 spin_unlock_irqrestore(&lp->bank_lock, flags);
519 break;
520 }
521 return (data & 0xFF);
522} /* mace_read */
523
524/* ----------------------------------------------------------------------------
525mace_write
526 Writes to a MACE register. This is bank independent; however,
527 the caller must ensure that this call is not interruptable. We
528 are assuming that during normal operation, the MACE is always in
529 bank 0.
530---------------------------------------------------------------------------- */
Olof Johansson906da802008-02-04 22:27:35 -0800531static void mace_write(mace_private *lp, unsigned int ioaddr, int reg,
532 int data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533{
534 unsigned long flags;
535
536 switch (reg >> 4) {
537 case 0: /* register 0-15 */
538 outb(data & 0xFF, ioaddr + AM2150_MACE_BASE + reg);
539 break;
540 case 1: /* register 16-31 */
541 spin_lock_irqsave(&lp->bank_lock, flags);
542 MACEBANK(1);
543 outb(data & 0xFF, ioaddr + AM2150_MACE_BASE + (reg & 0x0F));
544 MACEBANK(0);
545 spin_unlock_irqrestore(&lp->bank_lock, flags);
546 break;
547 }
548} /* mace_write */
549
550/* ----------------------------------------------------------------------------
551mace_init
552 Resets the MACE chip.
553---------------------------------------------------------------------------- */
Olof Johansson906da802008-02-04 22:27:35 -0800554static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555{
556 int i;
557 int ct = 0;
558
559 /* MACE Software reset */
560 mace_write(lp, ioaddr, MACE_BIUCC, 1);
561 while (mace_read(lp, ioaddr, MACE_BIUCC) & 0x01) {
562 /* Wait for reset bit to be cleared automatically after <= 200ns */;
563 if(++ct > 500)
564 {
565 printk(KERN_ERR "mace: reset failed, card removed ?\n");
566 return -1;
567 }
568 udelay(1);
569 }
570 mace_write(lp, ioaddr, MACE_BIUCC, 0);
571
572 /* The Am2150 requires that the MACE FIFOs operate in burst mode. */
573 mace_write(lp, ioaddr, MACE_FIFOCC, 0x0F);
574
575 mace_write(lp,ioaddr, MACE_RCVFC, 0); /* Disable Auto Strip Receive */
576 mace_write(lp, ioaddr, MACE_IMR, 0xFF); /* Disable all interrupts until _open */
577
578 /*
579 * Bit 2-1 PORTSEL[1-0] Port Select.
580 * 00 AUI/10Base-2
581 * 01 10Base-T
582 * 10 DAI Port (reserved in Am2150)
583 * 11 GPSI
584 * For this card, only the first two are valid.
585 * So, PLSCC should be set to
586 * 0x00 for 10Base-2
587 * 0x02 for 10Base-T
588 * Or just set ASEL in PHYCC below!
589 */
590 switch (if_port) {
591 case 1:
592 mace_write(lp, ioaddr, MACE_PLSCC, 0x02);
593 break;
594 case 2:
595 mace_write(lp, ioaddr, MACE_PLSCC, 0x00);
596 break;
597 default:
598 mace_write(lp, ioaddr, MACE_PHYCC, /* ASEL */ 4);
599 /* ASEL Auto Select. When set, the PORTSEL[1-0] bits are overridden,
600 and the MACE device will automatically select the operating media
601 interface port. */
602 break;
603 }
604
605 mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_PHYADDR);
606 /* Poll ADDRCHG bit */
607 ct = 0;
608 while (mace_read(lp, ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG)
609 {
610 if(++ ct > 500)
611 {
612 printk(KERN_ERR "mace: ADDRCHG timeout, card removed ?\n");
613 return -1;
614 }
615 }
616 /* Set PADR register */
617 for (i = 0; i < ETHER_ADDR_LEN; i++)
618 mace_write(lp, ioaddr, MACE_PADR, enet_addr[i]);
619
620 /* MAC Configuration Control Register should be written last */
621 /* Let set_multicast_list set this. */
622 /* mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV); */
623 mace_write(lp, ioaddr, MACE_MACCC, 0x00);
624 return 0;
625} /* mace_init */
626
627/* ----------------------------------------------------------------------------
628nmclan_config
629 This routine is scheduled to run after a CARD_INSERTION event
630 is received, to configure the PCMCIA socket, and to make the
631 ethernet device available to the system.
632---------------------------------------------------------------------------- */
633
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200634static int nmclan_config(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 struct net_device *dev = link->priv;
637 mace_private *lp = netdev_priv(dev);
Dominik Brodowskidddfbd82009-10-18 23:54:24 +0200638 u8 *buf;
639 size_t len;
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200640 int i, ret;
Olof Johansson906da802008-02-04 22:27:35 -0800641 unsigned int ioaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200643 dev_dbg(&link->dev, "nmclan_config\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644
Dominik Brodowski90abdc32010-07-24 17:23:51 +0200645 link->io_lines = 5;
646 ret = pcmcia_request_io(link);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200647 if (ret)
648 goto failed;
Dominik Brodowskieb141202010-03-07 12:21:16 +0100649 ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200650 if (ret)
651 goto failed;
652 ret = pcmcia_request_configuration(link, &link->conf);
653 if (ret)
654 goto failed;
655
Dominik Brodowskieb141202010-03-07 12:21:16 +0100656 dev->irq = link->irq;
Dominik Brodowski9a017a92010-07-24 15:58:54 +0200657 dev->base_addr = link->resource[0]->start;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658
659 ioaddr = dev->base_addr;
660
661 /* Read the ethernet address from the CIS. */
Dominik Brodowskidddfbd82009-10-18 23:54:24 +0200662 len = pcmcia_get_tuple(link, 0x80, &buf);
663 if (!buf || len < ETHER_ADDR_LEN) {
664 kfree(buf);
665 goto failed;
666 }
667 memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
668 kfree(buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669
670 /* Verify configuration by reading the MACE ID. */
671 {
672 char sig[2];
673
674 sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
675 sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
676 if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200677 dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 sig[0], sig[1]);
679 } else {
680 printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
681 " be 0x40 0x?9\n", sig[0], sig[1]);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200682 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 }
684 }
685
686 if(mace_init(lp, ioaddr, dev->dev_addr) == -1)
687 goto failed;
688
689 /* The if_port symbol can be set when the module is loaded */
690 if (if_port <= 2)
691 dev->if_port = if_port;
692 else
693 printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
694
Dominik Brodowskidd2e5a12009-11-03 10:27:34 +0100695 SET_NETDEV_DEV(dev, &link->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696
697 i = register_netdev(dev);
698 if (i != 0) {
699 printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 goto failed;
701 }
702
Joe Perches0795af52007-10-03 17:59:30 -0700703 printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port,"
Johannes Berge1749612008-10-27 15:59:26 -0700704 " hw_addr %pM\n",
Joe Perches0795af52007-10-03 17:59:30 -0700705 dev->name, dev->base_addr, dev->irq, if_names[dev->if_port],
Johannes Berge1749612008-10-27 15:59:26 -0700706 dev->dev_addr);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200707 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709failed:
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200710 nmclan_release(link);
711 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712} /* nmclan_config */
713
714/* ----------------------------------------------------------------------------
715nmclan_release
716 After a card is removed, nmclan_release() will unregister the
717 net device, and release the PCMCIA configuration. If the device
718 is still open, this will be postponed until it is closed.
719---------------------------------------------------------------------------- */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200720static void nmclan_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721{
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200722 dev_dbg(&link->dev, "nmclan_release\n");
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200723 pcmcia_disable_device(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724}
725
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200726static int nmclan_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100727{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100728 struct net_device *dev = link->priv;
729
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100730 if (link->open)
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100731 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100732
733 return 0;
734}
735
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200736static int nmclan_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100737{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100738 struct net_device *dev = link->priv;
739
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100740 if (link->open) {
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100741 nmclan_reset(dev);
742 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100743 }
744
745 return 0;
746}
747
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748
749/* ----------------------------------------------------------------------------
750nmclan_reset
751 Reset and restore all of the Xilinx and MACE registers.
752---------------------------------------------------------------------------- */
753static void nmclan_reset(struct net_device *dev)
754{
755 mace_private *lp = netdev_priv(dev);
756
757#if RESET_XILINX
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200758 struct pcmcia_device *link = &lp->link;
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200759 u8 OrigCorValue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760
761 /* Save original COR value */
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200762 pcmcia_read_config_byte(link, CISREG_COR, &OrigCorValue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763
764 /* Reset Xilinx */
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200765 dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%x, resetting...\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 OrigCorValue);
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200767 pcmcia_write_config_byte(link, CISREG_COR, COR_SOFT_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 /* Need to wait for 20 ms for PCMCIA to finish reset. */
769
770 /* Restore original COR configuration index */
Dominik Brodowski1d5cc192010-07-24 12:23:21 +0200771 pcmcia_write_config_byte(link, CISREG_COR,
772 (COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 /* Xilinx is now completely reset along with the MACE chip. */
774 lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
775
776#endif /* #if RESET_XILINX */
777
778 /* Xilinx is now completely reset along with the MACE chip. */
779 lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
780
781 /* Reinitialize the MACE chip for operation. */
782 mace_init(lp, dev->base_addr, dev->dev_addr);
783 mace_write(lp, dev->base_addr, MACE_IMR, MACE_IMR_DEFAULT);
784
785 /* Restore the multicast list and enable TX and RX. */
786 restore_multicast_list(dev);
787} /* nmclan_reset */
788
789/* ----------------------------------------------------------------------------
790mace_config
791 [Someone tell me what this is supposed to do? Is if_port a defined
792 standard? If so, there should be defines to indicate 1=10Base-T,
793 2=10Base-2, etc. including limited automatic detection.]
794---------------------------------------------------------------------------- */
795static int mace_config(struct net_device *dev, struct ifmap *map)
796{
797 if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
798 if (map->port <= 2) {
799 dev->if_port = map->port;
800 printk(KERN_INFO "%s: switched to %s port\n", dev->name,
801 if_names[dev->if_port]);
802 } 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
880 printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
881#if RESET_ON_TIMEOUT
882 printk("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 */
885 printk("NOT resetting card\n");
886#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) {
967 printk(
968 (lp->tx_irq_disabled?
969 KERN_NOTICE "%s: Interrupt with tx_irq_disabled "
970 "[isr=%02X, imr=%02X]\n":
971 KERN_NOTICE "%s: Re-entering the interrupt handler "
972 "[isr=%02X, imr=%02X]\n"),
973 dev->name,
974 inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
975 inb(ioaddr + AM2150_MACE_BASE + MACE_IMR)
976 );
977 /* WARNING: MACE_IR has been read! */
978 return IRQ_NONE;
979 }
980
981 if (!netif_device_present(dev)) {
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200982 pr_debug("%s: interrupt from dead card\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 return IRQ_NONE;
984 }
985
986 do {
987 /* WARNING: MACE_IR is a READ/CLEAR port! */
988 status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
989
Dominik Brodowskidd0fab52009-10-24 15:51:05 +0200990 pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991
992 if (status & MACE_IR_RCVINT) {
993 mace_rx(dev, MACE_MAX_RX_ITERATIONS);
994 }
995
996 if (status & MACE_IR_XMTINT) {
997 unsigned char fifofc;
998 unsigned char xmtrc;
999 unsigned char xmtfs;
1000
1001 fifofc = inb(ioaddr + AM2150_MACE_BASE + MACE_FIFOFC);
1002 if ((fifofc & MACE_FIFOFC_XMTFC)==0) {
1003 lp->linux_stats.tx_errors++;
1004 outb(0xFF, ioaddr + AM2150_XMT_SKIP);
1005 }
1006
1007 /* Transmit Retry Count (XMTRC, reg 4) */
1008 xmtrc = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTRC);
1009 if (xmtrc & MACE_XMTRC_EXDEF) lp->mace_stats.exdef++;
1010 lp->mace_stats.xmtrc += (xmtrc & MACE_XMTRC_XMTRC);
1011
1012 if (
1013 (xmtfs = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTFS)) &
1014 MACE_XMTFS_XMTSV /* Transmit Status Valid */
1015 ) {
1016 lp->mace_stats.xmtsv++;
1017
1018 if (xmtfs & ~MACE_XMTFS_XMTSV) {
1019 if (xmtfs & MACE_XMTFS_UFLO) {
1020 /* Underflow. Indicates that the Transmit FIFO emptied before
1021 the end of frame was reached. */
1022 lp->mace_stats.uflo++;
1023 }
1024 if (xmtfs & MACE_XMTFS_LCOL) {
1025 /* Late Collision */
1026 lp->mace_stats.lcol++;
1027 }
1028 if (xmtfs & MACE_XMTFS_MORE) {
1029 /* MORE than one retry was needed */
1030 lp->mace_stats.more++;
1031 }
1032 if (xmtfs & MACE_XMTFS_ONE) {
1033 /* Exactly ONE retry occurred */
1034 lp->mace_stats.one++;
1035 }
1036 if (xmtfs & MACE_XMTFS_DEFER) {
1037 /* Transmission was defered */
1038 lp->mace_stats.defer++;
1039 }
1040 if (xmtfs & MACE_XMTFS_LCAR) {
1041 /* Loss of carrier */
1042 lp->mace_stats.lcar++;
1043 }
1044 if (xmtfs & MACE_XMTFS_RTRY) {
1045 /* Retry error: transmit aborted after 16 attempts */
1046 lp->mace_stats.rtry++;
1047 }
1048 } /* if (xmtfs & ~MACE_XMTFS_XMTSV) */
1049
1050 } /* if (xmtfs & MACE_XMTFS_XMTSV) */
1051
1052 lp->linux_stats.tx_packets++;
1053 lp->tx_free_frames++;
1054 netif_wake_queue(dev);
1055 } /* if (status & MACE_IR_XMTINT) */
1056
1057 if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) {
1058 if (status & MACE_IR_JAB) {
1059 /* Jabber Error. Excessive transmit duration (20-150ms). */
1060 lp->mace_stats.jab++;
1061 }
1062 if (status & MACE_IR_BABL) {
1063 /* Babble Error. >1518 bytes transmitted. */
1064 lp->mace_stats.babl++;
1065 }
1066 if (status & MACE_IR_CERR) {
1067 /* Collision Error. CERR indicates the absence of the
1068 Signal Quality Error Test message after a packet
1069 transmission. */
1070 lp->mace_stats.cerr++;
1071 }
1072 if (status & MACE_IR_RCVCCO) {
1073 /* Receive Collision Count Overflow; */
1074 lp->mace_stats.rcvcco++;
1075 }
1076 if (status & MACE_IR_RNTPCO) {
1077 /* Runt Packet Count Overflow */
1078 lp->mace_stats.rntpco++;
1079 }
1080 if (status & MACE_IR_MPCO) {
1081 /* Missed Packet Count Overflow */
1082 lp->mace_stats.mpco++;
1083 }
1084 } /* if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) */
1085
1086 } while ((status & ~MACE_IMR_DEFAULT) && (--IntrCnt));
1087
1088 return IRQ_HANDLED;
1089} /* mace_interrupt */
1090
1091/* ----------------------------------------------------------------------------
1092mace_rx
1093 Receives packets.
1094---------------------------------------------------------------------------- */
1095static int mace_rx(struct net_device *dev, unsigned char RxCnt)
1096{
1097 mace_private *lp = netdev_priv(dev);
Olof Johansson906da802008-02-04 22:27:35 -08001098 unsigned int ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 unsigned char rx_framecnt;
1100 unsigned short rx_status;
1101
1102 while (
1103 ((rx_framecnt = inb(ioaddr + AM2150_RCV_FRAME_COUNT)) > 0) &&
1104 (rx_framecnt <= 12) && /* rx_framecnt==0xFF if card is extracted. */
1105 (RxCnt--)
1106 ) {
1107 rx_status = inw(ioaddr + AM2150_RCV);
1108
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001109 pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 " 0x%X.\n", dev->name, rx_framecnt, rx_status);
1111
1112 if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
1113 lp->linux_stats.rx_errors++;
1114 if (rx_status & MACE_RCVFS_OFLO) {
1115 lp->mace_stats.oflo++;
1116 }
1117 if (rx_status & MACE_RCVFS_CLSN) {
1118 lp->mace_stats.clsn++;
1119 }
1120 if (rx_status & MACE_RCVFS_FRAM) {
1121 lp->mace_stats.fram++;
1122 }
1123 if (rx_status & MACE_RCVFS_FCS) {
1124 lp->mace_stats.fcs++;
1125 }
1126 } else {
1127 short pkt_len = (rx_status & ~MACE_RCVFS_RCVSTS) - 4;
1128 /* Auto Strip is off, always subtract 4 */
1129 struct sk_buff *skb;
1130
1131 lp->mace_stats.rfs_rntpc += inb(ioaddr + AM2150_RCV);
1132 /* runt packet count */
1133 lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
1134 /* rcv collision count */
1135
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001136 pr_debug(" receiving packet size 0x%X rx_status"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 " 0x%X.\n", pkt_len, rx_status);
1138
1139 skb = dev_alloc_skb(pkt_len+2);
1140
1141 if (skb != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 skb_reserve(skb, 2);
1143 insw(ioaddr + AM2150_RCV, skb_put(skb, pkt_len), pkt_len>>1);
1144 if (pkt_len & 1)
Arnaldo Carvalho de Melo27a884d2007-04-19 20:29:13 -07001145 *(skb_tail_pointer(skb) - 1) = inb(ioaddr + AM2150_RCV);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 skb->protocol = eth_type_trans(skb, dev);
1147
1148 netif_rx(skb); /* Send the packet to the upper (protocol) layers. */
1149
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 lp->linux_stats.rx_packets++;
Florin Malita6f258912006-06-04 02:51:26 -07001151 lp->linux_stats.rx_bytes += pkt_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
1153 continue;
1154 } else {
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001155 pr_debug("%s: couldn't allocate a sk_buff of size"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 " %d.\n", dev->name, pkt_len);
1157 lp->linux_stats.rx_dropped++;
1158 }
1159 }
1160 outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
1161 } /* while */
1162
1163 return 0;
1164} /* mace_rx */
1165
1166/* ----------------------------------------------------------------------------
1167pr_linux_stats
1168---------------------------------------------------------------------------- */
1169static void pr_linux_stats(struct net_device_stats *pstats)
1170{
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001171 pr_debug("pr_linux_stats\n");
1172 pr_debug(" rx_packets=%-7ld tx_packets=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 (long)pstats->rx_packets, (long)pstats->tx_packets);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001174 pr_debug(" rx_errors=%-7ld tx_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 (long)pstats->rx_errors, (long)pstats->tx_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001176 pr_debug(" rx_dropped=%-7ld tx_dropped=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 (long)pstats->rx_dropped, (long)pstats->tx_dropped);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001178 pr_debug(" multicast=%-7ld collisions=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 (long)pstats->multicast, (long)pstats->collisions);
1180
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001181 pr_debug(" rx_length_errors=%-7ld rx_over_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 (long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001183 pr_debug(" rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184 (long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001185 pr_debug(" rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 (long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
1187
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001188 pr_debug(" tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 (long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001190 pr_debug(" tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 (long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001192 pr_debug(" tx_window_errors=%ld\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 (long)pstats->tx_window_errors);
1194} /* pr_linux_stats */
1195
1196/* ----------------------------------------------------------------------------
1197pr_mace_stats
1198---------------------------------------------------------------------------- */
1199static void pr_mace_stats(mace_statistics *pstats)
1200{
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001201 pr_debug("pr_mace_stats\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001203 pr_debug(" xmtsv=%-7d uflo=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 pstats->xmtsv, pstats->uflo);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001205 pr_debug(" lcol=%-7d more=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 pstats->lcol, pstats->more);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001207 pr_debug(" one=%-7d defer=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 pstats->one, pstats->defer);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001209 pr_debug(" lcar=%-7d rtry=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 pstats->lcar, pstats->rtry);
1211
1212 /* MACE_XMTRC */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001213 pr_debug(" exdef=%-7d xmtrc=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 pstats->exdef, pstats->xmtrc);
1215
1216 /* RFS1--Receive Status (RCVSTS) */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001217 pr_debug(" oflo=%-7d clsn=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 pstats->oflo, pstats->clsn);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001219 pr_debug(" fram=%-7d fcs=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 pstats->fram, pstats->fcs);
1221
1222 /* RFS2--Runt Packet Count (RNTPC) */
1223 /* RFS3--Receive Collision Count (RCVCC) */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001224 pr_debug(" rfs_rntpc=%-7d rfs_rcvcc=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 pstats->rfs_rntpc, pstats->rfs_rcvcc);
1226
1227 /* MACE_IR */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001228 pr_debug(" jab=%-7d babl=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 pstats->jab, pstats->babl);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001230 pr_debug(" cerr=%-7d rcvcco=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 pstats->cerr, pstats->rcvcco);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001232 pr_debug(" rntpco=%-7d mpco=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 pstats->rntpco, pstats->mpco);
1234
1235 /* MACE_MPC */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001236 pr_debug(" mpc=%d\n", pstats->mpc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237
1238 /* MACE_RNTPC */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001239 pr_debug(" rntpc=%d\n", pstats->rntpc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240
1241 /* MACE_RCVCC */
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001242 pr_debug(" rcvcc=%d\n", pstats->rcvcc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
1244} /* pr_mace_stats */
1245
1246/* ----------------------------------------------------------------------------
1247update_stats
1248 Update statistics. We change to register window 1, so this
1249 should be run single-threaded if the device is active. This is
1250 expected to be a rare operation, and it's simpler for the rest
1251 of the driver to assume that window 0 is always valid rather
1252 than use a special window-state variable.
1253
1254 oflo & uflo should _never_ occur since it would mean the Xilinx
1255 was not able to transfer data between the MACE FIFO and the
1256 card's SRAM fast enough. If this happens, something is
1257 seriously wrong with the hardware.
1258---------------------------------------------------------------------------- */
Olof Johansson906da802008-02-04 22:27:35 -08001259static void update_stats(unsigned int ioaddr, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260{
1261 mace_private *lp = netdev_priv(dev);
1262
1263 lp->mace_stats.rcvcc += mace_read(lp, ioaddr, MACE_RCVCC);
1264 lp->mace_stats.rntpc += mace_read(lp, ioaddr, MACE_RNTPC);
1265 lp->mace_stats.mpc += mace_read(lp, ioaddr, MACE_MPC);
1266 /* At this point, mace_stats is fully updated for this call.
1267 We may now update the linux_stats. */
1268
1269 /* The MACE has no equivalent for linux_stats field which are commented
1270 out. */
1271
1272 /* lp->linux_stats.multicast; */
1273 lp->linux_stats.collisions =
1274 lp->mace_stats.rcvcco * 256 + lp->mace_stats.rcvcc;
1275 /* Collision: The MACE may retry sending a packet 15 times
1276 before giving up. The retry count is in XMTRC.
1277 Does each retry constitute a collision?
1278 If so, why doesn't the RCVCC record these collisions? */
1279
1280 /* detailed rx_errors: */
1281 lp->linux_stats.rx_length_errors =
1282 lp->mace_stats.rntpco * 256 + lp->mace_stats.rntpc;
1283 /* lp->linux_stats.rx_over_errors */
1284 lp->linux_stats.rx_crc_errors = lp->mace_stats.fcs;
1285 lp->linux_stats.rx_frame_errors = lp->mace_stats.fram;
1286 lp->linux_stats.rx_fifo_errors = lp->mace_stats.oflo;
1287 lp->linux_stats.rx_missed_errors =
1288 lp->mace_stats.mpco * 256 + lp->mace_stats.mpc;
1289
1290 /* detailed tx_errors */
1291 lp->linux_stats.tx_aborted_errors = lp->mace_stats.rtry;
1292 lp->linux_stats.tx_carrier_errors = lp->mace_stats.lcar;
1293 /* LCAR usually results from bad cabling. */
1294 lp->linux_stats.tx_fifo_errors = lp->mace_stats.uflo;
1295 lp->linux_stats.tx_heartbeat_errors = lp->mace_stats.cerr;
1296 /* lp->linux_stats.tx_window_errors; */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297} /* update_stats */
1298
1299/* ----------------------------------------------------------------------------
1300mace_get_stats
1301 Gathers ethernet statistics from the MACE chip.
1302---------------------------------------------------------------------------- */
1303static struct net_device_stats *mace_get_stats(struct net_device *dev)
1304{
1305 mace_private *lp = netdev_priv(dev);
1306
1307 update_stats(dev->base_addr, dev);
1308
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001309 pr_debug("%s: updating the statistics.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310 pr_linux_stats(&lp->linux_stats);
1311 pr_mace_stats(&lp->mace_stats);
1312
1313 return &lp->linux_stats;
1314} /* net_device_stats */
1315
1316/* ----------------------------------------------------------------------------
1317updateCRC
1318 Modified from Am79C90 data sheet.
1319---------------------------------------------------------------------------- */
1320
1321#ifdef BROKEN_MULTICAST
1322
1323static void updateCRC(int *CRC, int bit)
1324{
1325 int poly[]={
1326 1,1,1,0, 1,1,0,1,
1327 1,0,1,1, 1,0,0,0,
1328 1,0,0,0, 0,0,1,1,
1329 0,0,1,0, 0,0,0,0
1330 }; /* CRC polynomial. poly[n] = coefficient of the x**n term of the
1331 CRC generator polynomial. */
1332
1333 int j;
1334
1335 /* shift CRC and control bit (CRC[32]) */
1336 for (j = 32; j > 0; j--)
1337 CRC[j] = CRC[j-1];
1338 CRC[0] = 0;
1339
1340 /* If bit XOR(control bit) = 1, set CRC = CRC XOR polynomial. */
1341 if (bit ^ CRC[32])
1342 for (j = 0; j < 32; j++)
1343 CRC[j] ^= poly[j];
1344} /* updateCRC */
1345
1346/* ----------------------------------------------------------------------------
1347BuildLAF
1348 Build logical address filter.
1349 Modified from Am79C90 data sheet.
1350
1351Input
1352 ladrf: logical address filter (contents initialized to 0)
1353 adr: ethernet address
1354---------------------------------------------------------------------------- */
1355static void BuildLAF(int *ladrf, int *adr)
1356{
1357 int CRC[33]={1}; /* CRC register, 1 word/bit + extra control bit */
1358
1359 int i, byte; /* temporary array indices */
1360 int hashcode; /* the output object */
1361
1362 CRC[32]=0;
1363
1364 for (byte = 0; byte < 6; byte++)
1365 for (i = 0; i < 8; i++)
1366 updateCRC(CRC, (adr[byte] >> i) & 1);
1367
1368 hashcode = 0;
1369 for (i = 0; i < 6; i++)
1370 hashcode = (hashcode << 1) + CRC[i];
1371
1372 byte = hashcode >> 3;
1373 ladrf[byte] |= (1 << (hashcode & 7));
1374
1375#ifdef PCMCIA_DEBUG
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001376 if (0)
Joe Perchesad361c92009-07-06 13:05:40 -07001377 printk(KERN_DEBUG " adr =%pM\n", adr);
1378 printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
1379 for (i = 0; i < 8; i++)
1380 printk(KERN_CONT " %02X", ladrf[i]);
1381 printk(KERN_CONT "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382#endif
1383} /* BuildLAF */
1384
1385/* ----------------------------------------------------------------------------
1386restore_multicast_list
1387 Restores the multicast filter for MACE chip to the last
1388 set_multicast_list() call.
1389
1390Input
1391 multicast_num_addrs
1392 multicast_ladrf[]
1393---------------------------------------------------------------------------- */
1394static void restore_multicast_list(struct net_device *dev)
1395{
1396 mace_private *lp = netdev_priv(dev);
1397 int num_addrs = lp->multicast_num_addrs;
1398 int *ladrf = lp->multicast_ladrf;
Olof Johansson906da802008-02-04 22:27:35 -08001399 unsigned int ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 int i;
1401
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001402 pr_debug("%s: restoring Rx mode to %d addresses.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 dev->name, num_addrs);
1404
1405 if (num_addrs > 0) {
1406
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001407 pr_debug("Attempt to restore multicast list detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
1409 mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
1410 /* Poll ADDRCHG bit */
1411 while (mace_read(lp, ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG)
1412 ;
1413 /* Set LADRF register */
1414 for (i = 0; i < MACE_LADRF_LEN; i++)
1415 mace_write(lp, ioaddr, MACE_LADRF, ladrf[i]);
1416
1417 mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_RCVFCSE | MACE_UTR_LOOP_EXTERNAL);
1418 mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
1419
1420 } else if (num_addrs < 0) {
1421
1422 /* Promiscuous mode: receive all packets */
1423 mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
1424 mace_write(lp, ioaddr, MACE_MACCC,
1425 MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV
1426 );
1427
1428 } else {
1429
1430 /* Normal mode */
1431 mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
1432 mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
1433
1434 }
1435} /* restore_multicast_list */
1436
1437/* ----------------------------------------------------------------------------
1438set_multicast_list
1439 Set or clear the multicast filter for this adaptor.
1440
1441Input
1442 num_addrs == -1 Promiscuous mode, receive all packets
1443 num_addrs == 0 Normal mode, clear multicast list
1444 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
1445 best-effort filtering.
1446Output
1447 multicast_num_addrs
1448 multicast_ladrf[]
1449---------------------------------------------------------------------------- */
1450
1451static void set_multicast_list(struct net_device *dev)
1452{
1453 mace_private *lp = netdev_priv(dev);
1454 int adr[ETHER_ADDR_LEN] = {0}; /* Ethernet address */
Jiri Pirko22bedad32010-04-01 21:22:57 +00001455 struct netdev_hw_addr *ha;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456
1457#ifdef PCMCIA_DEBUG
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001458 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 static int old;
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001460 if (netdev_mc_count(dev) != old) {
1461 old = netdev_mc_count(dev);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001462 pr_debug("%s: setting Rx mode to %d addresses.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 dev->name, old);
1464 }
1465 }
1466#endif
1467
1468 /* Set multicast_num_addrs. */
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001469 lp->multicast_num_addrs = netdev_mc_count(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470
1471 /* Set multicast_ladrf. */
1472 if (num_addrs > 0) {
1473 /* Calculate multicast logical address filter */
1474 memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN);
Jiri Pirko22bedad32010-04-01 21:22:57 +00001475 netdev_for_each_mc_addr(ha, dev) {
1476 memcpy(adr, ha->addr, ETHER_ADDR_LEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 BuildLAF(lp->multicast_ladrf, adr);
1478 }
1479 }
1480
1481 restore_multicast_list(dev);
1482
1483} /* set_multicast_list */
1484
1485#endif /* BROKEN_MULTICAST */
1486
1487static void restore_multicast_list(struct net_device *dev)
1488{
Olof Johansson906da802008-02-04 22:27:35 -08001489 unsigned int ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 mace_private *lp = netdev_priv(dev);
1491
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001492 pr_debug("%s: restoring Rx mode to %d addresses.\n", dev->name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 lp->multicast_num_addrs);
1494
1495 if (dev->flags & IFF_PROMISC) {
1496 /* Promiscuous mode: receive all packets */
1497 mace_write(lp,ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
1498 mace_write(lp, ioaddr, MACE_MACCC,
1499 MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV
1500 );
1501 } else {
1502 /* Normal mode */
1503 mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);
1504 mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);
1505 }
1506} /* restore_multicast_list */
1507
1508static void set_multicast_list(struct net_device *dev)
1509{
1510 mace_private *lp = netdev_priv(dev);
1511
1512#ifdef PCMCIA_DEBUG
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001513 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 static int old;
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001515 if (netdev_mc_count(dev) != old) {
1516 old = netdev_mc_count(dev);
Dominik Brodowskidd0fab52009-10-24 15:51:05 +02001517 pr_debug("%s: setting Rx mode to %d addresses.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 dev->name, old);
1519 }
1520 }
1521#endif
1522
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001523 lp->multicast_num_addrs = netdev_mc_count(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 restore_multicast_list(dev);
1525
1526} /* set_multicast_list */
1527
Dominik Brodowskia58e26c2005-06-27 16:28:23 -07001528static struct pcmcia_device_id nmclan_ids[] = {
1529 PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Ethernet", 0x085a850b, 0x00b2e941),
Komurod277ad02005-07-28 01:07:24 -07001530 PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet+", 0xebf1d60, 0xad673aaf),
Dominik Brodowskia58e26c2005-06-27 16:28:23 -07001531 PCMCIA_DEVICE_NULL,
1532};
1533MODULE_DEVICE_TABLE(pcmcia, nmclan_ids);
1534
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535static struct pcmcia_driver nmclan_cs_driver = {
1536 .owner = THIS_MODULE,
1537 .drv = {
1538 .name = "nmclan_cs",
1539 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +02001540 .probe = nmclan_probe,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001541 .remove = nmclan_detach,
Dominik Brodowskia58e26c2005-06-27 16:28:23 -07001542 .id_table = nmclan_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01001543 .suspend = nmclan_suspend,
1544 .resume = nmclan_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545};
1546
1547static int __init init_nmclan_cs(void)
1548{
1549 return pcmcia_register_driver(&nmclan_cs_driver);
1550}
1551
1552static void __exit exit_nmclan_cs(void)
1553{
1554 pcmcia_unregister_driver(&nmclan_cs_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555}
1556
1557module_init(init_nmclan_cs);
1558module_exit(exit_nmclan_cs);