aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/fmvj18x_cs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/pcmcia/fmvj18x_cs.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/net/pcmcia/fmvj18x_cs.c')
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c1286
1 files changed, 1286 insertions, 0 deletions
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
new file mode 100644
index 000000000000..0424865e8094
--- /dev/null
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -0,0 +1,1286 @@
1/*======================================================================
2 fmvj18x_cs.c 2.8 2002/03/23
3
4 A fmvj18x (and its compatibles) PCMCIA client driver
5
6 Contributed by Shingo Fujimoto, shingo@flab.fujitsu.co.jp
7
8 TDK LAK-CD021 and CONTEC C-NET(PC)C support added by
9 Nobuhiro Katayama, kata-n@po.iijnet.or.jp
10
11 The PCMCIA client code is based on code written by David Hinds.
12 Network code is based on the "FMV-18x driver" by Yutaka TAMIYA
13 but is actually largely Donald Becker's AT1700 driver, which
14 carries the following attribution:
15
16 Written 1993-94 by Donald Becker.
17
18 Copyright 1993 United States Government as represented by the
19 Director, National Security Agency.
20
21 This software may be used and distributed according to the terms
22 of the GNU General Public License, incorporated herein by reference.
23
24 The author may be reached as becker@scyld.com, or C/O
25 Scyld Computing Corporation
26 410 Severn Ave., Suite 210
27 Annapolis MD 21403
28
29======================================================================*/
30
31#define DRV_NAME "fmvj18x_cs"
32#define DRV_VERSION "2.8"
33
34#include <linux/module.h>
35#include <linux/kernel.h>
36#include <linux/init.h>
37#include <linux/ptrace.h>
38#include <linux/slab.h>
39#include <linux/string.h>
40#include <linux/timer.h>
41#include <linux/interrupt.h>
42#include <linux/in.h>
43#include <linux/delay.h>
44#include <linux/ethtool.h>
45#include <linux/netdevice.h>
46#include <linux/etherdevice.h>
47#include <linux/skbuff.h>
48#include <linux/if_arp.h>
49#include <linux/ioport.h>
50#include <linux/crc32.h>
51
52#include <pcmcia/version.h>
53#include <pcmcia/cs_types.h>
54#include <pcmcia/cs.h>
55#include <pcmcia/cistpl.h>
56#include <pcmcia/ciscode.h>
57#include <pcmcia/ds.h>
58
59#include <asm/uaccess.h>
60#include <asm/io.h>
61#include <asm/system.h>
62
63/*====================================================================*/
64
65/* Module parameters */
66
67MODULE_DESCRIPTION("fmvj18x and compatible PCMCIA ethernet driver");
68MODULE_LICENSE("GPL");
69
70#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
71
72/* SRAM configuration */
73/* 0:4KB*2 TX buffer else:8KB*2 TX buffer */
74INT_MODULE_PARM(sram_config, 0);
75
76#ifdef PCMCIA_DEBUG
77INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
78#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
79static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
80#else
81#define DEBUG(n, args...)
82#endif
83
84/*====================================================================*/
85/*
86 PCMCIA event handlers
87 */
88static void fmvj18x_config(dev_link_t *link);
89static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
90static int fmvj18x_setup_mfc(dev_link_t *link);
91static void fmvj18x_release(dev_link_t *link);
92static int fmvj18x_event(event_t event, int priority,
93 event_callback_args_t *args);
94static dev_link_t *fmvj18x_attach(void);
95static void fmvj18x_detach(dev_link_t *);
96
97/*
98 LAN controller(MBH86960A) specific routines
99 */
100static int fjn_config(struct net_device *dev, struct ifmap *map);
101static int fjn_open(struct net_device *dev);
102static int fjn_close(struct net_device *dev);
103static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev);
104static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs);
105static void fjn_rx(struct net_device *dev);
106static void fjn_reset(struct net_device *dev);
107static struct net_device_stats *fjn_get_stats(struct net_device *dev);
108static void set_rx_mode(struct net_device *dev);
109static void fjn_tx_timeout(struct net_device *dev);
110static struct ethtool_ops netdev_ethtool_ops;
111
112static dev_info_t dev_info = "fmvj18x_cs";
113static dev_link_t *dev_list;
114
115/*
116 card type
117 */
118typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN,
119 XXX10304
120} cardtype_t;
121
122/*
123 driver specific data structure
124*/
125typedef struct local_info_t {
126 dev_link_t link;
127 dev_node_t node;
128 struct net_device_stats stats;
129 long open_time;
130 uint tx_started:1;
131 uint tx_queue;
132 u_short tx_queue_len;
133 cardtype_t cardtype;
134 u_short sent;
135 u_char mc_filter[8];
136} local_info_t;
137
138#define MC_FILTERBREAK 64
139
140/*====================================================================*/
141/*
142 ioport offset from the base address
143 */
144#define TX_STATUS 0 /* transmit status register */
145#define RX_STATUS 1 /* receive status register */
146#define TX_INTR 2 /* transmit interrupt mask register */
147#define RX_INTR 3 /* receive interrupt mask register */
148#define TX_MODE 4 /* transmit mode register */
149#define RX_MODE 5 /* receive mode register */
150#define CONFIG_0 6 /* configuration register 0 */
151#define CONFIG_1 7 /* configuration register 1 */
152
153#define NODE_ID 8 /* node ID register (bank 0) */
154#define MAR_ADR 8 /* multicast address registers (bank 1) */
155
156#define DATAPORT 8 /* buffer mem port registers (bank 2) */
157#define TX_START 10 /* transmit start register */
158#define COL_CTRL 11 /* 16 collision control register */
159#define BMPR12 12 /* reserved */
160#define BMPR13 13 /* reserved */
161#define RX_SKIP 14 /* skip received packet register */
162
163#define LAN_CTRL 16 /* LAN card control register */
164
165#define MAC_ID 0x1a /* hardware address */
166#define UNGERMANN_MAC_ID 0x18 /* UNGERMANN-BASS hardware address */
167
168/*
169 control bits
170 */
171#define ENA_TMT_OK 0x80
172#define ENA_TMT_REC 0x20
173#define ENA_COL 0x04
174#define ENA_16_COL 0x02
175#define ENA_TBUS_ERR 0x01
176
177#define ENA_PKT_RDY 0x80
178#define ENA_BUS_ERR 0x40
179#define ENA_LEN_ERR 0x08
180#define ENA_ALG_ERR 0x04
181#define ENA_CRC_ERR 0x02
182#define ENA_OVR_FLO 0x01
183
184/* flags */
185#define F_TMT_RDY 0x80 /* can accept new packet */
186#define F_NET_BSY 0x40 /* carrier is detected */
187#define F_TMT_OK 0x20 /* send packet successfully */
188#define F_SRT_PKT 0x10 /* short packet error */
189#define F_COL_ERR 0x04 /* collision error */
190#define F_16_COL 0x02 /* 16 collision error */
191#define F_TBUS_ERR 0x01 /* bus read error */
192
193#define F_PKT_RDY 0x80 /* packet(s) in buffer */
194#define F_BUS_ERR 0x40 /* bus read error */
195#define F_LEN_ERR 0x08 /* short packet */
196#define F_ALG_ERR 0x04 /* frame error */
197#define F_CRC_ERR 0x02 /* CRC error */
198#define F_OVR_FLO 0x01 /* overflow error */
199
200#define F_BUF_EMP 0x40 /* receive buffer is empty */
201
202#define F_SKP_PKT 0x05 /* drop packet in buffer */
203
204/* default bitmaps */
205#define D_TX_INTR ( ENA_TMT_OK )
206#define D_RX_INTR ( ENA_PKT_RDY | ENA_LEN_ERR \
207 | ENA_ALG_ERR | ENA_CRC_ERR | ENA_OVR_FLO )
208#define TX_STAT_M ( F_TMT_RDY )
209#define RX_STAT_M ( F_PKT_RDY | F_LEN_ERR \
210 | F_ALG_ERR | F_CRC_ERR | F_OVR_FLO )
211
212/* commands */
213#define D_TX_MODE 0x06 /* no tests, detect carrier */
214#define ID_MATCHED 0x02 /* (RX_MODE) */
215#define RECV_ALL 0x03 /* (RX_MODE) */
216#define CONFIG0_DFL 0x5a /* 16bit bus, 4K x 2 Tx queues */
217#define CONFIG0_DFL_1 0x5e /* 16bit bus, 8K x 2 Tx queues */
218#define CONFIG0_RST 0xda /* Data Link Controller off (CONFIG_0) */
219#define CONFIG0_RST_1 0xde /* Data Link Controller off (CONFIG_0) */
220#define BANK_0 0xa0 /* bank 0 (CONFIG_1) */
221#define BANK_1 0xa4 /* bank 1 (CONFIG_1) */
222#define BANK_2 0xa8 /* bank 2 (CONFIG_1) */
223#define CHIP_OFF 0x80 /* contrl chip power off (CONFIG_1) */
224#define DO_TX 0x80 /* do transmit packet */
225#define SEND_PKT 0x81 /* send a packet */
226#define AUTO_MODE 0x07 /* Auto skip packet on 16 col detected */
227#define MANU_MODE 0x03 /* Stop and skip packet on 16 col */
228#define TDK_AUTO_MODE 0x47 /* Auto skip packet on 16 col detected */
229#define TDK_MANU_MODE 0x43 /* Stop and skip packet on 16 col */
230#define INTR_OFF 0x0d /* LAN controller ignores interrupts */
231#define INTR_ON 0x1d /* LAN controller will catch interrupts */
232
233#define TX_TIMEOUT ((400*HZ)/1000)
234
235#define BANK_0U 0x20 /* bank 0 (CONFIG_1) */
236#define BANK_1U 0x24 /* bank 1 (CONFIG_1) */
237#define BANK_2U 0x28 /* bank 2 (CONFIG_1) */
238
239static dev_link_t *fmvj18x_attach(void)
240{
241 local_info_t *lp;
242 dev_link_t *link;
243 struct net_device *dev;
244 client_reg_t client_reg;
245 int ret;
246
247 DEBUG(0, "fmvj18x_attach()\n");
248
249 /* Make up a FMVJ18x specific data structure */
250 dev = alloc_etherdev(sizeof(local_info_t));
251 if (!dev)
252 return NULL;
253 lp = netdev_priv(dev);
254 link = &lp->link;
255 link->priv = dev;
256
257 /* The io structure describes IO port mapping */
258 link->io.NumPorts1 = 32;
259 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
260 link->io.IOAddrLines = 5;
261
262 /* Interrupt setup */
263 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
264 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
265 link->irq.Handler = &fjn_interrupt;
266 link->irq.Instance = dev;
267
268 /* General socket configuration */
269 link->conf.Attributes = CONF_ENABLE_IRQ;
270 link->conf.Vcc = 50;
271 link->conf.IntType = INT_MEMORY_AND_IO;
272
273 /* The FMVJ18x specific entries in the device structure. */
274 SET_MODULE_OWNER(dev);
275 dev->hard_start_xmit = &fjn_start_xmit;
276 dev->set_config = &fjn_config;
277 dev->get_stats = &fjn_get_stats;
278 dev->set_multicast_list = &set_rx_mode;
279 dev->open = &fjn_open;
280 dev->stop = &fjn_close;
281#ifdef HAVE_TX_TIMEOUT
282 dev->tx_timeout = fjn_tx_timeout;
283 dev->watchdog_timeo = TX_TIMEOUT;
284#endif
285 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
286
287 /* Register with Card Services */
288 link->next = dev_list;
289 dev_list = link;
290 client_reg.dev_info = &dev_info;
291 client_reg.EventMask =
292 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
293 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
294 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
295 client_reg.event_handler = &fmvj18x_event;
296 client_reg.Version = 0x0210;
297 client_reg.event_callback_args.client_data = link;
298 ret = pcmcia_register_client(&link->handle, &client_reg);
299 if (ret != 0) {
300 cs_error(link->handle, RegisterClient, ret);
301 fmvj18x_detach(link);
302 return NULL;
303 }
304
305 return link;
306} /* fmvj18x_attach */
307
308/*====================================================================*/
309
310static void fmvj18x_detach(dev_link_t *link)
311{
312 struct net_device *dev = link->priv;
313 dev_link_t **linkp;
314
315 DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
316
317 /* Locate device structure */
318 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
319 if (*linkp == link) break;
320 if (*linkp == NULL)
321 return;
322
323 if (link->dev)
324 unregister_netdev(dev);
325
326 if (link->state & DEV_CONFIG)
327 fmvj18x_release(link);
328
329 /* Break the link with Card Services */
330 if (link->handle)
331 pcmcia_deregister_client(link->handle);
332
333 /* Unlink device structure, free pieces */
334 *linkp = link->next;
335 free_netdev(dev);
336} /* fmvj18x_detach */
337
338/*====================================================================*/
339
340#define CS_CHECK(fn, ret) \
341do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
342
343static int mfc_try_io_port(dev_link_t *link)
344{
345 int i, ret;
346 static kio_addr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
347
348 for (i = 0; i < 5; i++) {
349 link->io.BasePort2 = serial_base[i];
350 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
351 if (link->io.BasePort2 == 0) {
352 link->io.NumPorts2 = 0;
353 printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
354 }
355 ret = pcmcia_request_io(link->handle, &link->io);
356 if (ret == CS_SUCCESS) return ret;
357 }
358 return ret;
359}
360
361static int ungermann_try_io_port(dev_link_t *link)
362{
363 int ret;
364 kio_addr_t ioaddr;
365 /*
366 Ungermann-Bass Access/CARD accepts 0x300,0x320,0x340,0x360
367 0x380,0x3c0 only for ioport.
368 */
369 for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) {
370 link->io.BasePort1 = ioaddr;
371 ret = pcmcia_request_io(link->handle, &link->io);
372 if (ret == CS_SUCCESS) {
373 /* calculate ConfigIndex value */
374 link->conf.ConfigIndex =
375 ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22;
376 return ret;
377 }
378 }
379 return ret; /* RequestIO failed */
380}
381
382static void fmvj18x_config(dev_link_t *link)
383{
384 client_handle_t handle = link->handle;
385 struct net_device *dev = link->priv;
386 local_info_t *lp = netdev_priv(dev);
387 tuple_t tuple;
388 cisparse_t parse;
389 u_short buf[32];
390 int i, last_fn, last_ret, ret;
391 kio_addr_t ioaddr;
392 cardtype_t cardtype;
393 char *card_name = "unknown";
394 u_char *node_id;
395
396 DEBUG(0, "fmvj18x_config(0x%p)\n", link);
397
398 /*
399 This reads the card's CONFIG tuple to find its configuration
400 registers.
401 */
402 tuple.DesiredTuple = CISTPL_CONFIG;
403 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
404 tuple.TupleData = (u_char *)buf;
405 tuple.TupleDataMax = 64;
406 tuple.TupleOffset = 0;
407 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
408 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
409
410 /* Configure card */
411 link->state |= DEV_CONFIG;
412
413 link->conf.ConfigBase = parse.config.base;
414 link->conf.Present = parse.config.rmask[0];
415
416 tuple.DesiredTuple = CISTPL_FUNCE;
417 tuple.TupleOffset = 0;
418 if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) {
419 /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
420 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
421 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
422 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
423 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
424 link->conf.ConfigIndex = parse.cftable_entry.index;
425 tuple.DesiredTuple = CISTPL_MANFID;
426 if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS)
427 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
428 else
429 buf[0] = 0xffff;
430 switch (le16_to_cpu(buf[0])) {
431 case MANFID_TDK:
432 cardtype = TDK;
433 if (le16_to_cpu(buf[1]) == PRODID_TDK_CF010) {
434 cs_status_t status;
435 pcmcia_get_status(handle, &status);
436 if (status.CardState & CS_EVENT_3VCARD)
437 link->conf.Vcc = 33; /* inserted in 3.3V slot */
438 } else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410) {
439 /* MultiFunction Card */
440 link->conf.ConfigBase = 0x800;
441 link->conf.ConfigIndex = 0x47;
442 link->io.NumPorts2 = 8;
443 }
444 break;
445 case MANFID_CONTEC:
446 cardtype = CONTEC;
447 break;
448 case MANFID_FUJITSU:
449 if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10302)
450 /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302),
451 but these are MBH10304 based card. */
452 cardtype = MBH10304;
453 else if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304)
454 cardtype = MBH10304;
455 else
456 cardtype = LA501;
457 break;
458 default:
459 cardtype = MBH10304;
460 }
461 } else {
462 /* old type card */
463 tuple.DesiredTuple = CISTPL_MANFID;
464 if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS)
465 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
466 else
467 buf[0] = 0xffff;
468 switch (le16_to_cpu(buf[0])) {
469 case MANFID_FUJITSU:
470 if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) {
471 cardtype = XXX10304; /* MBH10304 with buggy CIS */
472 link->conf.ConfigIndex = 0x20;
473 } else {
474 cardtype = MBH10302; /* NextCom NC5310, etc. */
475 link->conf.ConfigIndex = 1;
476 }
477 break;
478 case MANFID_UNGERMANN:
479 cardtype = UNGERMANN;
480 break;
481 default:
482 cardtype = MBH10302;
483 link->conf.ConfigIndex = 1;
484 }
485 }
486
487 if (link->io.NumPorts2 != 0) {
488 link->irq.Attributes =
489 IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
490 ret = mfc_try_io_port(link);
491 if (ret != CS_SUCCESS) goto cs_failed;
492 } else if (cardtype == UNGERMANN) {
493 ret = ungermann_try_io_port(link);
494 if (ret != CS_SUCCESS) goto cs_failed;
495 } else {
496 CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
497 }
498 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
499 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
500 dev->irq = link->irq.AssignedIRQ;
501 dev->base_addr = link->io.BasePort1;
502
503 if (link->io.BasePort2 != 0)
504 fmvj18x_setup_mfc(link);
505
506 ioaddr = dev->base_addr;
507
508 /* Reset controller */
509 if (sram_config == 0)
510 outb(CONFIG0_RST, ioaddr + CONFIG_0);
511 else
512 outb(CONFIG0_RST_1, ioaddr + CONFIG_0);
513
514 /* Power On chip and select bank 0 */
515 if (cardtype == MBH10302)
516 outb(BANK_0, ioaddr + CONFIG_1);
517 else
518 outb(BANK_0U, ioaddr + CONFIG_1);
519
520 /* Set hardware address */
521 switch (cardtype) {
522 case MBH10304:
523 case TDK:
524 case LA501:
525 case CONTEC:
526 tuple.DesiredTuple = CISTPL_FUNCE;
527 tuple.TupleOffset = 0;
528 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
529 tuple.TupleOffset = 0;
530 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
531 if (cardtype == MBH10304) {
532 /* MBH10304's CIS_FUNCE is corrupted */
533 node_id = &(tuple.TupleData[5]);
534 card_name = "FMV-J182";
535 } else {
536 while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
537 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
538 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
539 }
540 node_id = &(tuple.TupleData[2]);
541 if( cardtype == TDK ) {
542 card_name = "TDK LAK-CD021";
543 } else if( cardtype == LA501 ) {
544 card_name = "LA501";
545 } else {
546 card_name = "C-NET(PC)C";
547 }
548 }
549 /* Read MACID from CIS */
550 for (i = 0; i < 6; i++)
551 dev->dev_addr[i] = node_id[i];
552 break;
553 case UNGERMANN:
554 /* Read MACID from register */
555 for (i = 0; i < 6; i++)
556 dev->dev_addr[i] = inb(ioaddr + UNGERMANN_MAC_ID + i);
557 card_name = "Access/CARD";
558 break;
559 case XXX10304:
560 /* Read MACID from Buggy CIS */
561 if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
562 printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
563 goto failed;
564 }
565 for (i = 0 ; i < 6; i++) {
566 dev->dev_addr[i] = tuple.TupleData[i];
567 }
568 card_name = "FMV-J182";
569 break;
570 case MBH10302:
571 default:
572 /* Read MACID from register */
573 for (i = 0; i < 6; i++)
574 dev->dev_addr[i] = inb(ioaddr + MAC_ID + i);
575 card_name = "FMV-J181";
576 break;
577 }
578
579 lp->cardtype = cardtype;
580 link->dev = &lp->node;
581 link->state &= ~DEV_CONFIG_PENDING;
582 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
583
584 if (register_netdev(dev) != 0) {
585 printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
586 link->dev = NULL;
587 goto failed;
588 }
589
590 strcpy(lp->node.dev_name, dev->name);
591
592 /* print current configuration */
593 printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, hw_addr ",
594 dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2",
595 dev->base_addr, dev->irq);
596 for (i = 0; i < 6; i++)
597 printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
598
599 return;
600
601cs_failed:
602 /* All Card Services errors end up here */
603 cs_error(link->handle, last_fn, last_ret);
604failed:
605 fmvj18x_release(link);
606 link->state &= ~DEV_CONFIG_PENDING;
607
608} /* fmvj18x_config */
609/*====================================================================*/
610
611static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id)
612{
613 win_req_t req;
614 memreq_t mem;
615 u_char __iomem *base;
616 int i, j;
617
618 /* Allocate a small memory window */
619 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
620 req.Base = 0; req.Size = 0;
621 req.AccessSpeed = 0;
622 i = pcmcia_request_window(&link->handle, &req, &link->win);
623 if (i != CS_SUCCESS) {
624 cs_error(link->handle, RequestWindow, i);
625 return -1;
626 }
627
628 base = ioremap(req.Base, req.Size);
629 mem.Page = 0;
630 mem.CardOffset = 0;
631 pcmcia_map_mem_page(link->win, &mem);
632
633 /*
634 * MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
635 * 22 0d xx xx xx 04 06 yy yy yy yy yy yy ff
636 * 'xx' is garbage.
637 * 'yy' is MAC address.
638 */
639 for (i = 0; i < 0x200; i++) {
640 if (readb(base+i*2) == 0x22) {
641 if (readb(base+(i-1)*2) == 0xff
642 && readb(base+(i+5)*2) == 0x04
643 && readb(base+(i+6)*2) == 0x06
644 && readb(base+(i+13)*2) == 0xff)
645 break;
646 }
647 }
648
649 if (i != 0x200) {
650 for (j = 0 ; j < 6; j++,i++) {
651 node_id[j] = readb(base+(i+7)*2);
652 }
653 }
654
655 iounmap(base);
656 j = pcmcia_release_window(link->win);
657 if (j != CS_SUCCESS)
658 cs_error(link->handle, ReleaseWindow, j);
659 return (i != 0x200) ? 0 : -1;
660
661} /* fmvj18x_get_hwinfo */
662/*====================================================================*/
663
664static int fmvj18x_setup_mfc(dev_link_t *link)
665{
666 win_req_t req;
667 memreq_t mem;
668 u_char __iomem *base;
669 int i, j;
670 struct net_device *dev = link->priv;
671 kio_addr_t ioaddr;
672
673 /* Allocate a small memory window */
674 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
675 req.Base = 0; req.Size = 0;
676 req.AccessSpeed = 0;
677 i = pcmcia_request_window(&link->handle, &req, &link->win);
678 if (i != CS_SUCCESS) {
679 cs_error(link->handle, RequestWindow, i);
680 return -1;
681 }
682
683 base = ioremap(req.Base, req.Size);
684 mem.Page = 0;
685 mem.CardOffset = 0;
686 pcmcia_map_mem_page(link->win, &mem);
687
688 ioaddr = dev->base_addr;
689 writeb(0x47, base+0x800); /* Config Option Register of LAN */
690 writeb(0x0, base+0x802); /* Config and Status Register */
691
692 writeb(ioaddr & 0xff, base+0x80a); /* I/O Base(Low) of LAN */
693 writeb((ioaddr >> 8) & 0xff, base+0x80c); /* I/O Base(High) of LAN */
694
695 writeb(0x45, base+0x820); /* Config Option Register of Modem */
696 writeb(0x8, base+0x822); /* Config and Status Register */
697
698 iounmap(base);
699 j = pcmcia_release_window(link->win);
700 if (j != CS_SUCCESS)
701 cs_error(link->handle, ReleaseWindow, j);
702 return 0;
703
704}
705/*====================================================================*/
706
707static void fmvj18x_release(dev_link_t *link)
708{
709
710 DEBUG(0, "fmvj18x_release(0x%p)\n", link);
711
712 /* Don't bother checking to see if these succeed or not */
713 pcmcia_release_window(link->win);
714 pcmcia_release_configuration(link->handle);
715 pcmcia_release_io(link->handle, &link->io);
716 pcmcia_release_irq(link->handle, &link->irq);
717
718 link->state &= ~DEV_CONFIG;
719}
720
721/*====================================================================*/
722
723static int fmvj18x_event(event_t event, int priority,
724 event_callback_args_t *args)
725{
726 dev_link_t *link = args->client_data;
727 struct net_device *dev = link->priv;
728
729 DEBUG(1, "fmvj18x_event(0x%06x)\n", event);
730
731 switch (event) {
732 case CS_EVENT_CARD_REMOVAL:
733 link->state &= ~DEV_PRESENT;
734 if (link->state & DEV_CONFIG)
735 netif_device_detach(dev);
736 break;
737 case CS_EVENT_CARD_INSERTION:
738 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
739 fmvj18x_config(link);
740 break;
741 case CS_EVENT_PM_SUSPEND:
742 link->state |= DEV_SUSPEND;
743 /* Fall through... */
744 case CS_EVENT_RESET_PHYSICAL:
745 if (link->state & DEV_CONFIG) {
746 if (link->open)
747 netif_device_detach(dev);
748 pcmcia_release_configuration(link->handle);
749 }
750 break;
751 case CS_EVENT_PM_RESUME:
752 link->state &= ~DEV_SUSPEND;
753 /* Fall through... */
754 case CS_EVENT_CARD_RESET:
755 if (link->state & DEV_CONFIG) {
756 pcmcia_request_configuration(link->handle, &link->conf);
757 if (link->open) {
758 fjn_reset(dev);
759 netif_device_attach(dev);
760 }
761 }
762 break;
763 }
764 return 0;
765} /* fmvj18x_event */
766
767static struct pcmcia_driver fmvj18x_cs_driver = {
768 .owner = THIS_MODULE,
769 .drv = {
770 .name = "fmvj18x_cs",
771 },
772 .attach = fmvj18x_attach,
773 .detach = fmvj18x_detach,
774};
775
776static int __init init_fmvj18x_cs(void)
777{
778 return pcmcia_register_driver(&fmvj18x_cs_driver);
779}
780
781static void __exit exit_fmvj18x_cs(void)
782{
783 pcmcia_unregister_driver(&fmvj18x_cs_driver);
784 BUG_ON(dev_list != NULL);
785}
786
787module_init(init_fmvj18x_cs);
788module_exit(exit_fmvj18x_cs);
789
790/*====================================================================*/
791
792static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
793{
794 struct net_device *dev = dev_id;
795 local_info_t *lp = netdev_priv(dev);
796 kio_addr_t ioaddr;
797 unsigned short tx_stat, rx_stat;
798
799 if (lp == NULL) {
800 printk(KERN_NOTICE "fjn_interrupt(): irq %d for "
801 "unknown device.\n", irq);
802 return IRQ_NONE;
803 }
804 ioaddr = dev->base_addr;
805
806 /* avoid multiple interrupts */
807 outw(0x0000, ioaddr + TX_INTR);
808
809 /* wait for a while */
810 udelay(1);
811
812 /* get status */
813 tx_stat = inb(ioaddr + TX_STATUS);
814 rx_stat = inb(ioaddr + RX_STATUS);
815
816 /* clear status */
817 outb(tx_stat, ioaddr + TX_STATUS);
818 outb(rx_stat, ioaddr + RX_STATUS);
819
820 DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
821 DEBUG(4, " tx_status %02x.\n", tx_stat);
822
823 if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
824 /* there is packet(s) in rx buffer */
825 fjn_rx(dev);
826 }
827 if (tx_stat & F_TMT_RDY) {
828 lp->stats.tx_packets += lp->sent ;
829 lp->sent = 0 ;
830 if (lp->tx_queue) {
831 outb(DO_TX | lp->tx_queue, ioaddr + TX_START);
832 lp->sent = lp->tx_queue ;
833 lp->tx_queue = 0;
834 lp->tx_queue_len = 0;
835 dev->trans_start = jiffies;
836 } else {
837 lp->tx_started = 0;
838 }
839 netif_wake_queue(dev);
840 }
841 DEBUG(4, "%s: exiting interrupt,\n", dev->name);
842 DEBUG(4, " tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
843
844 outb(D_TX_INTR, ioaddr + TX_INTR);
845 outb(D_RX_INTR, ioaddr + RX_INTR);
846 return IRQ_HANDLED;
847
848} /* fjn_interrupt */
849
850/*====================================================================*/
851
852static void fjn_tx_timeout(struct net_device *dev)
853{
854 struct local_info_t *lp = netdev_priv(dev);
855 kio_addr_t ioaddr = dev->base_addr;
856
857 printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n",
858 dev->name, htons(inw(ioaddr + TX_STATUS)),
859 inb(ioaddr + TX_STATUS) & F_TMT_RDY
860 ? "IRQ conflict" : "network cable problem");
861 printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x "
862 "%04x %04x %04x %04x %04x.\n",
863 dev->name, htons(inw(ioaddr + 0)),
864 htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),
865 htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
866 htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
867 htons(inw(ioaddr +14)));
868 lp->stats.tx_errors++;
869 /* ToDo: We should try to restart the adaptor... */
870 local_irq_disable();
871 fjn_reset(dev);
872
873 lp->tx_started = 0;
874 lp->tx_queue = 0;
875 lp->tx_queue_len = 0;
876 lp->sent = 0;
877 lp->open_time = jiffies;
878 local_irq_enable();
879 netif_wake_queue(dev);
880}
881
882static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
883{
884 struct local_info_t *lp = netdev_priv(dev);
885 kio_addr_t ioaddr = dev->base_addr;
886 short length = skb->len;
887
888 if (length < ETH_ZLEN)
889 {
890 skb = skb_padto(skb, ETH_ZLEN);
891 if (skb == NULL)
892 return 0;
893 length = ETH_ZLEN;
894 }
895
896 netif_stop_queue(dev);
897
898 {
899 unsigned char *buf = skb->data;
900
901 if (length > ETH_FRAME_LEN) {
902 printk(KERN_NOTICE "%s: Attempting to send a large packet"
903 " (%d bytes).\n", dev->name, length);
904 return 1;
905 }
906
907 DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
908 dev->name, (unsigned long)skb->len);
909 lp->stats.tx_bytes += skb->len;
910
911 /* Disable both interrupts. */
912 outw(0x0000, ioaddr + TX_INTR);
913
914 /* wait for a while */
915 udelay(1);
916
917 outw(length, ioaddr + DATAPORT);
918 outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
919
920 lp->tx_queue++;
921 lp->tx_queue_len += ((length+3) & ~1);
922
923 if (lp->tx_started == 0) {
924 /* If the Tx is idle, always trigger a transmit. */
925 outb(DO_TX | lp->tx_queue, ioaddr + TX_START);
926 lp->sent = lp->tx_queue ;
927 lp->tx_queue = 0;
928 lp->tx_queue_len = 0;
929 dev->trans_start = jiffies;
930 lp->tx_started = 1;
931 netif_start_queue(dev);
932 } else {
933 if( sram_config == 0 ) {
934 if (lp->tx_queue_len < (4096 - (ETH_FRAME_LEN +2)) )
935 /* Yes, there is room for one more packet. */
936 netif_start_queue(dev);
937 } else {
938 if (lp->tx_queue_len < (8192 - (ETH_FRAME_LEN +2)) &&
939 lp->tx_queue < 127 )
940 /* Yes, there is room for one more packet. */
941 netif_start_queue(dev);
942 }
943 }
944
945 /* Re-enable interrupts */
946 outb(D_TX_INTR, ioaddr + TX_INTR);
947 outb(D_RX_INTR, ioaddr + RX_INTR);
948 }
949 dev_kfree_skb (skb);
950
951 return 0;
952} /* fjn_start_xmit */
953
954/*====================================================================*/
955
956static void fjn_reset(struct net_device *dev)
957{
958 struct local_info_t *lp = netdev_priv(dev);
959 kio_addr_t ioaddr = dev->base_addr;
960 int i;
961
962 DEBUG(4, "fjn_reset(%s) called.\n",dev->name);
963
964 /* Reset controller */
965 if( sram_config == 0 )
966 outb(CONFIG0_RST, ioaddr + CONFIG_0);
967 else
968 outb(CONFIG0_RST_1, ioaddr + CONFIG_0);
969
970 /* Power On chip and select bank 0 */
971 if (lp->cardtype == MBH10302)
972 outb(BANK_0, ioaddr + CONFIG_1);
973 else
974 outb(BANK_0U, ioaddr + CONFIG_1);
975
976 /* Set Tx modes */
977 outb(D_TX_MODE, ioaddr + TX_MODE);
978 /* set Rx modes */
979 outb(ID_MATCHED, ioaddr + RX_MODE);
980
981 /* Set hardware address */
982 for (i = 0; i < 6; i++)
983 outb(dev->dev_addr[i], ioaddr + NODE_ID + i);
984
985 /* Switch to bank 1 */
986 if (lp->cardtype == MBH10302)
987 outb(BANK_1, ioaddr + CONFIG_1);
988 else
989 outb(BANK_1U, ioaddr + CONFIG_1);
990
991 /* set the multicast table to accept none. */
992 for (i = 0; i < 6; i++)
993 outb(0x00, ioaddr + MAR_ADR + i);
994
995 /* Switch to bank 2 (runtime mode) */
996 if (lp->cardtype == MBH10302)
997 outb(BANK_2, ioaddr + CONFIG_1);
998 else
999 outb(BANK_2U, ioaddr + CONFIG_1);
1000
1001 /* set 16col ctrl bits */
1002 if( lp->cardtype == TDK || lp->cardtype == CONTEC)
1003 outb(TDK_AUTO_MODE, ioaddr + COL_CTRL);
1004 else
1005 outb(AUTO_MODE, ioaddr + COL_CTRL);
1006
1007 /* clear Reserved Regs */
1008 outb(0x00, ioaddr + BMPR12);
1009 outb(0x00, ioaddr + BMPR13);
1010
1011 /* reset Skip packet reg. */
1012 outb(0x01, ioaddr + RX_SKIP);
1013
1014 /* Enable Tx and Rx */
1015 if( sram_config == 0 )
1016 outb(CONFIG0_DFL, ioaddr + CONFIG_0);
1017 else
1018 outb(CONFIG0_DFL_1, ioaddr + CONFIG_0);
1019
1020 /* Init receive pointer ? */
1021 inw(ioaddr + DATAPORT);
1022 inw(ioaddr + DATAPORT);
1023
1024 /* Clear all status */
1025 outb(0xff, ioaddr + TX_STATUS);
1026 outb(0xff, ioaddr + RX_STATUS);
1027
1028 if (lp->cardtype == MBH10302)
1029 outb(INTR_OFF, ioaddr + LAN_CTRL);
1030
1031 /* Turn on Rx interrupts */
1032 outb(D_TX_INTR, ioaddr + TX_INTR);
1033 outb(D_RX_INTR, ioaddr + RX_INTR);
1034
1035 /* Turn on interrupts from LAN card controller */
1036 if (lp->cardtype == MBH10302)
1037 outb(INTR_ON, ioaddr + LAN_CTRL);
1038} /* fjn_reset */
1039
1040/*====================================================================*/
1041
1042static void fjn_rx(struct net_device *dev)
1043{
1044 struct local_info_t *lp = netdev_priv(dev);
1045 kio_addr_t ioaddr = dev->base_addr;
1046 int boguscount = 10; /* 5 -> 10: by agy 19940922 */
1047
1048 DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",
1049 dev->name, inb(ioaddr + RX_STATUS));
1050
1051 while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
1052 u_short status = inw(ioaddr + DATAPORT);
1053
1054 DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n",
1055 dev->name, inb(ioaddr + RX_MODE), status);
1056#ifndef final_version
1057 if (status == 0) {
1058 outb(F_SKP_PKT, ioaddr + RX_SKIP);
1059 break;
1060 }
1061#endif
1062 if ((status & 0xF0) != 0x20) { /* There was an error. */
1063 lp->stats.rx_errors++;
1064 if (status & F_LEN_ERR) lp->stats.rx_length_errors++;
1065 if (status & F_ALG_ERR) lp->stats.rx_frame_errors++;
1066 if (status & F_CRC_ERR) lp->stats.rx_crc_errors++;
1067 if (status & F_OVR_FLO) lp->stats.rx_over_errors++;
1068 } else {
1069 u_short pkt_len = inw(ioaddr + DATAPORT);
1070 /* Malloc up new buffer. */
1071 struct sk_buff *skb;
1072
1073 if (pkt_len > 1550) {
1074 printk(KERN_NOTICE "%s: The FMV-18x claimed a very "
1075 "large packet, size %d.\n", dev->name, pkt_len);
1076 outb(F_SKP_PKT, ioaddr + RX_SKIP);
1077 lp->stats.rx_errors++;
1078 break;
1079 }
1080 skb = dev_alloc_skb(pkt_len+2);
1081 if (skb == NULL) {
1082 printk(KERN_NOTICE "%s: Memory squeeze, dropping "
1083 "packet (len %d).\n", dev->name, pkt_len);
1084 outb(F_SKP_PKT, ioaddr + RX_SKIP);
1085 lp->stats.rx_dropped++;
1086 break;
1087 }
1088 skb->dev = dev;
1089
1090 skb_reserve(skb, 2);
1091 insw(ioaddr + DATAPORT, skb_put(skb, pkt_len),
1092 (pkt_len + 1) >> 1);
1093 skb->protocol = eth_type_trans(skb, dev);
1094
1095#ifdef PCMCIA_DEBUG
1096 if (pc_debug > 5) {
1097 int i;
1098 printk(KERN_DEBUG "%s: Rxed packet of length %d: ",
1099 dev->name, pkt_len);
1100 for (i = 0; i < 14; i++)
1101 printk(" %02x", skb->data[i]);
1102 printk(".\n");
1103 }
1104#endif
1105
1106 netif_rx(skb);
1107 dev->last_rx = jiffies;
1108 lp->stats.rx_packets++;
1109 lp->stats.rx_bytes += pkt_len;
1110 }
1111 if (--boguscount <= 0)
1112 break;
1113 }
1114
1115 /* If any worth-while packets have been received, dev_rint()
1116 has done a netif_wake_queue() for us and will work on them
1117 when we get to the bottom-half routine. */
1118/*
1119 if (lp->cardtype != TDK) {
1120 int i;
1121 for (i = 0; i < 20; i++) {
1122 if ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == F_BUF_EMP)
1123 break;
1124 (void)inw(ioaddr + DATAPORT); /+ dummy status read +/
1125 outb(F_SKP_PKT, ioaddr + RX_SKIP);
1126 }
1127
1128 if (i > 0)
1129 DEBUG(5, "%s: Exint Rx packet with mode %02x after "
1130 "%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);
1131 }
1132*/
1133
1134 return;
1135} /* fjn_rx */
1136
1137/*====================================================================*/
1138
1139static void netdev_get_drvinfo(struct net_device *dev,
1140 struct ethtool_drvinfo *info)
1141{
1142 strcpy(info->driver, DRV_NAME);
1143 strcpy(info->version, DRV_VERSION);
1144 sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
1145}
1146
1147#ifdef PCMCIA_DEBUG
1148static u32 netdev_get_msglevel(struct net_device *dev)
1149{
1150 return pc_debug;
1151}
1152
1153static void netdev_set_msglevel(struct net_device *dev, u32 level)
1154{
1155 pc_debug = level;
1156}
1157#endif /* PCMCIA_DEBUG */
1158
1159static struct ethtool_ops netdev_ethtool_ops = {
1160 .get_drvinfo = netdev_get_drvinfo,
1161#ifdef PCMCIA_DEBUG
1162 .get_msglevel = netdev_get_msglevel,
1163 .set_msglevel = netdev_set_msglevel,
1164#endif /* PCMCIA_DEBUG */
1165};
1166
1167static int fjn_config(struct net_device *dev, struct ifmap *map){
1168 return 0;
1169}
1170
1171static int fjn_open(struct net_device *dev)
1172{
1173 struct local_info_t *lp = netdev_priv(dev);
1174 dev_link_t *link = &lp->link;
1175
1176 DEBUG(4, "fjn_open('%s').\n", dev->name);
1177
1178 if (!DEV_OK(link))
1179 return -ENODEV;
1180
1181 link->open++;
1182
1183 fjn_reset(dev);
1184
1185 lp->tx_started = 0;
1186 lp->tx_queue = 0;
1187 lp->tx_queue_len = 0;
1188 lp->open_time = jiffies;
1189 netif_start_queue(dev);
1190
1191 return 0;
1192} /* fjn_open */
1193
1194/*====================================================================*/
1195
1196static int fjn_close(struct net_device *dev)
1197{
1198 struct local_info_t *lp = netdev_priv(dev);
1199 dev_link_t *link = &lp->link;
1200 kio_addr_t ioaddr = dev->base_addr;
1201
1202 DEBUG(4, "fjn_close('%s').\n", dev->name);
1203
1204 lp->open_time = 0;
1205 netif_stop_queue(dev);
1206
1207 /* Set configuration register 0 to disable Tx and Rx. */
1208 if( sram_config == 0 )
1209 outb(CONFIG0_RST ,ioaddr + CONFIG_0);
1210 else
1211 outb(CONFIG0_RST_1 ,ioaddr + CONFIG_0);
1212
1213 /* Update the statistics -- ToDo. */
1214
1215 /* Power-down the chip. Green, green, green! */
1216 outb(CHIP_OFF ,ioaddr + CONFIG_1);
1217
1218 /* Set the ethernet adaptor disable IRQ */
1219 if (lp->cardtype == MBH10302)
1220 outb(INTR_OFF, ioaddr + LAN_CTRL);
1221
1222 link->open--;
1223
1224 return 0;
1225} /* fjn_close */
1226
1227/*====================================================================*/
1228
1229static struct net_device_stats *fjn_get_stats(struct net_device *dev)
1230{
1231 local_info_t *lp = netdev_priv(dev);
1232 return &lp->stats;
1233} /* fjn_get_stats */
1234
1235/*====================================================================*/
1236
1237/*
1238 Set the multicast/promiscuous mode for this adaptor.
1239*/
1240
1241static void set_rx_mode(struct net_device *dev)
1242{
1243 kio_addr_t ioaddr = dev->base_addr;
1244 struct local_info_t *lp = netdev_priv(dev);
1245 u_char mc_filter[8]; /* Multicast hash filter */
1246 u_long flags;
1247 int i;
1248
1249 if (dev->flags & IFF_PROMISC) {
1250 /* Unconditionally log net taps. */
1251 printk("%s: Promiscuous mode enabled.\n", dev->name);
1252 memset(mc_filter, 0xff, sizeof(mc_filter));
1253 outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
1254 } else if (dev->mc_count > MC_FILTERBREAK
1255 || (dev->flags & IFF_ALLMULTI)) {
1256 /* Too many to filter perfectly -- accept all multicasts. */
1257 memset(mc_filter, 0xff, sizeof(mc_filter));
1258 outb(2, ioaddr + RX_MODE); /* Use normal mode. */
1259 } else if (dev->mc_count == 0) {
1260 memset(mc_filter, 0x00, sizeof(mc_filter));
1261 outb(1, ioaddr + RX_MODE); /* Ignore almost all multicasts. */
1262 } else {
1263 struct dev_mc_list *mclist;
1264 int i;
1265
1266 memset(mc_filter, 0, sizeof(mc_filter));
1267 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
1268 i++, mclist = mclist->next) {
1269 unsigned int bit =
1270 ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;
1271 mc_filter[bit >> 3] |= (1 << bit);
1272 }
1273 }
1274
1275 local_irq_save(flags);
1276 if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
1277 int saved_bank = inb(ioaddr + CONFIG_1);
1278 /* Switch to bank 1 and set the multicast table. */
1279 outb(0xe4, ioaddr + CONFIG_1);
1280 for (i = 0; i < 8; i++)
1281 outb(mc_filter[i], ioaddr + 8 + i);
1282 memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
1283 outb(saved_bank, ioaddr + CONFIG_1);
1284 }
1285 local_irq_restore(flags);
1286}