blob: 34bf963b1296e6413e2555b2a48868714e2429f3 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*======================================================================
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#include <pcmcia/cs_types.h>
53#include <pcmcia/cs.h>
54#include <pcmcia/cistpl.h>
55#include <pcmcia/ciscode.h>
56#include <pcmcia/ds.h>
57
58#include <asm/uaccess.h>
59#include <asm/io.h>
60#include <asm/system.h>
61
62/*====================================================================*/
63
64/* Module parameters */
65
66MODULE_DESCRIPTION("fmvj18x and compatible PCMCIA ethernet driver");
67MODULE_LICENSE("GPL");
68
69#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
70
71/* SRAM configuration */
72/* 0:4KB*2 TX buffer else:8KB*2 TX buffer */
73INT_MODULE_PARM(sram_config, 0);
74
75#ifdef PCMCIA_DEBUG
76INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
77#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
78static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
79#else
80#define DEBUG(n, args...)
81#endif
82
83/*====================================================================*/
84/*
85 PCMCIA event handlers
86 */
87static void fmvj18x_config(dev_link_t *link);
88static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
89static int fmvj18x_setup_mfc(dev_link_t *link);
90static void fmvj18x_release(dev_link_t *link);
Dominik Brodowskicc3b4862005-11-14 21:23:14 +010091static void fmvj18x_detach(struct pcmcia_device *p_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93/*
94 LAN controller(MBH86960A) specific routines
95 */
96static int fjn_config(struct net_device *dev, struct ifmap *map);
97static int fjn_open(struct net_device *dev);
98static int fjn_close(struct net_device *dev);
99static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev);
100static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs);
101static void fjn_rx(struct net_device *dev);
102static void fjn_reset(struct net_device *dev);
103static struct net_device_stats *fjn_get_stats(struct net_device *dev);
104static void set_rx_mode(struct net_device *dev);
105static void fjn_tx_timeout(struct net_device *dev);
106static struct ethtool_ops netdev_ethtool_ops;
107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108/*
109 card type
110 */
111typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN,
112 XXX10304
113} cardtype_t;
114
115/*
116 driver specific data structure
117*/
118typedef struct local_info_t {
119 dev_link_t link;
120 dev_node_t node;
121 struct net_device_stats stats;
122 long open_time;
123 uint tx_started:1;
124 uint tx_queue;
125 u_short tx_queue_len;
126 cardtype_t cardtype;
127 u_short sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128} local_info_t;
129
Komuroab808822005-12-01 02:37:17 -0500130#define MC_FILTERBREAK 64
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
132/*====================================================================*/
133/*
134 ioport offset from the base address
135 */
136#define TX_STATUS 0 /* transmit status register */
137#define RX_STATUS 1 /* receive status register */
138#define TX_INTR 2 /* transmit interrupt mask register */
139#define RX_INTR 3 /* receive interrupt mask register */
140#define TX_MODE 4 /* transmit mode register */
141#define RX_MODE 5 /* receive mode register */
142#define CONFIG_0 6 /* configuration register 0 */
143#define CONFIG_1 7 /* configuration register 1 */
144
145#define NODE_ID 8 /* node ID register (bank 0) */
146#define MAR_ADR 8 /* multicast address registers (bank 1) */
147
148#define DATAPORT 8 /* buffer mem port registers (bank 2) */
149#define TX_START 10 /* transmit start register */
150#define COL_CTRL 11 /* 16 collision control register */
151#define BMPR12 12 /* reserved */
152#define BMPR13 13 /* reserved */
153#define RX_SKIP 14 /* skip received packet register */
154
155#define LAN_CTRL 16 /* LAN card control register */
156
157#define MAC_ID 0x1a /* hardware address */
158#define UNGERMANN_MAC_ID 0x18 /* UNGERMANN-BASS hardware address */
159
160/*
161 control bits
162 */
163#define ENA_TMT_OK 0x80
164#define ENA_TMT_REC 0x20
165#define ENA_COL 0x04
166#define ENA_16_COL 0x02
167#define ENA_TBUS_ERR 0x01
168
169#define ENA_PKT_RDY 0x80
170#define ENA_BUS_ERR 0x40
171#define ENA_LEN_ERR 0x08
172#define ENA_ALG_ERR 0x04
173#define ENA_CRC_ERR 0x02
174#define ENA_OVR_FLO 0x01
175
176/* flags */
177#define F_TMT_RDY 0x80 /* can accept new packet */
178#define F_NET_BSY 0x40 /* carrier is detected */
179#define F_TMT_OK 0x20 /* send packet successfully */
180#define F_SRT_PKT 0x10 /* short packet error */
181#define F_COL_ERR 0x04 /* collision error */
182#define F_16_COL 0x02 /* 16 collision error */
183#define F_TBUS_ERR 0x01 /* bus read error */
184
185#define F_PKT_RDY 0x80 /* packet(s) in buffer */
186#define F_BUS_ERR 0x40 /* bus read error */
187#define F_LEN_ERR 0x08 /* short packet */
188#define F_ALG_ERR 0x04 /* frame error */
189#define F_CRC_ERR 0x02 /* CRC error */
190#define F_OVR_FLO 0x01 /* overflow error */
191
192#define F_BUF_EMP 0x40 /* receive buffer is empty */
193
194#define F_SKP_PKT 0x05 /* drop packet in buffer */
195
196/* default bitmaps */
197#define D_TX_INTR ( ENA_TMT_OK )
198#define D_RX_INTR ( ENA_PKT_RDY | ENA_LEN_ERR \
199 | ENA_ALG_ERR | ENA_CRC_ERR | ENA_OVR_FLO )
200#define TX_STAT_M ( F_TMT_RDY )
201#define RX_STAT_M ( F_PKT_RDY | F_LEN_ERR \
202 | F_ALG_ERR | F_CRC_ERR | F_OVR_FLO )
203
204/* commands */
205#define D_TX_MODE 0x06 /* no tests, detect carrier */
206#define ID_MATCHED 0x02 /* (RX_MODE) */
207#define RECV_ALL 0x03 /* (RX_MODE) */
208#define CONFIG0_DFL 0x5a /* 16bit bus, 4K x 2 Tx queues */
209#define CONFIG0_DFL_1 0x5e /* 16bit bus, 8K x 2 Tx queues */
210#define CONFIG0_RST 0xda /* Data Link Controller off (CONFIG_0) */
211#define CONFIG0_RST_1 0xde /* Data Link Controller off (CONFIG_0) */
212#define BANK_0 0xa0 /* bank 0 (CONFIG_1) */
213#define BANK_1 0xa4 /* bank 1 (CONFIG_1) */
214#define BANK_2 0xa8 /* bank 2 (CONFIG_1) */
215#define CHIP_OFF 0x80 /* contrl chip power off (CONFIG_1) */
216#define DO_TX 0x80 /* do transmit packet */
217#define SEND_PKT 0x81 /* send a packet */
218#define AUTO_MODE 0x07 /* Auto skip packet on 16 col detected */
219#define MANU_MODE 0x03 /* Stop and skip packet on 16 col */
220#define TDK_AUTO_MODE 0x47 /* Auto skip packet on 16 col detected */
221#define TDK_MANU_MODE 0x43 /* Stop and skip packet on 16 col */
222#define INTR_OFF 0x0d /* LAN controller ignores interrupts */
223#define INTR_ON 0x1d /* LAN controller will catch interrupts */
224
225#define TX_TIMEOUT ((400*HZ)/1000)
226
227#define BANK_0U 0x20 /* bank 0 (CONFIG_1) */
228#define BANK_1U 0x24 /* bank 1 (CONFIG_1) */
229#define BANK_2U 0x28 /* bank 2 (CONFIG_1) */
230
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100231static int fmvj18x_attach(struct pcmcia_device *p_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232{
233 local_info_t *lp;
234 dev_link_t *link;
235 struct net_device *dev;
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100236
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 DEBUG(0, "fmvj18x_attach()\n");
238
239 /* Make up a FMVJ18x specific data structure */
240 dev = alloc_etherdev(sizeof(local_info_t));
241 if (!dev)
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100242 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 lp = netdev_priv(dev);
244 link = &lp->link;
245 link->priv = dev;
246
247 /* The io structure describes IO port mapping */
248 link->io.NumPorts1 = 32;
249 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
250 link->io.IOAddrLines = 5;
251
252 /* Interrupt setup */
253 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
254 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
255 link->irq.Handler = &fjn_interrupt;
256 link->irq.Instance = dev;
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100257
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 /* General socket configuration */
259 link->conf.Attributes = CONF_ENABLE_IRQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 link->conf.IntType = INT_MEMORY_AND_IO;
261
262 /* The FMVJ18x specific entries in the device structure. */
263 SET_MODULE_OWNER(dev);
264 dev->hard_start_xmit = &fjn_start_xmit;
265 dev->set_config = &fjn_config;
266 dev->get_stats = &fjn_get_stats;
267 dev->set_multicast_list = &set_rx_mode;
268 dev->open = &fjn_open;
269 dev->stop = &fjn_close;
270#ifdef HAVE_TX_TIMEOUT
271 dev->tx_timeout = fjn_tx_timeout;
272 dev->watchdog_timeo = TX_TIMEOUT;
273#endif
274 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100276 link->handle = p_dev;
277 p_dev->instance = link;
278
279 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
280 fmvj18x_config(link);
281
282 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283} /* fmvj18x_attach */
284
285/*====================================================================*/
286
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100287static void fmvj18x_detach(struct pcmcia_device *p_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288{
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100289 dev_link_t *link = dev_to_instance(p_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 struct net_device *dev = link->priv;
Dominik Brodowskib4635812005-11-14 21:25:35 +0100291
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293
294 if (link->dev)
295 unregister_netdev(dev);
296
297 if (link->state & DEV_CONFIG)
298 fmvj18x_release(link);
299
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 free_netdev(dev);
301} /* fmvj18x_detach */
302
303/*====================================================================*/
304
305#define CS_CHECK(fn, ret) \
306do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
307
308static int mfc_try_io_port(dev_link_t *link)
309{
310 int i, ret;
Arjan van de Venf71e1302006-03-03 21:33:57 -0500311 static const kio_addr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
313 for (i = 0; i < 5; i++) {
314 link->io.BasePort2 = serial_base[i];
315 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
316 if (link->io.BasePort2 == 0) {
317 link->io.NumPorts2 = 0;
318 printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
319 }
320 ret = pcmcia_request_io(link->handle, &link->io);
321 if (ret == CS_SUCCESS) return ret;
322 }
323 return ret;
324}
325
326static int ungermann_try_io_port(dev_link_t *link)
327{
328 int ret;
329 kio_addr_t ioaddr;
330 /*
331 Ungermann-Bass Access/CARD accepts 0x300,0x320,0x340,0x360
332 0x380,0x3c0 only for ioport.
333 */
334 for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) {
335 link->io.BasePort1 = ioaddr;
336 ret = pcmcia_request_io(link->handle, &link->io);
337 if (ret == CS_SUCCESS) {
338 /* calculate ConfigIndex value */
339 link->conf.ConfigIndex =
340 ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22;
341 return ret;
342 }
343 }
344 return ret; /* RequestIO failed */
345}
346
347static void fmvj18x_config(dev_link_t *link)
348{
349 client_handle_t handle = link->handle;
350 struct net_device *dev = link->priv;
351 local_info_t *lp = netdev_priv(dev);
352 tuple_t tuple;
353 cisparse_t parse;
354 u_short buf[32];
355 int i, last_fn, last_ret, ret;
356 kio_addr_t ioaddr;
357 cardtype_t cardtype;
358 char *card_name = "unknown";
359 u_char *node_id;
360
361 DEBUG(0, "fmvj18x_config(0x%p)\n", link);
362
363 /*
364 This reads the card's CONFIG tuple to find its configuration
365 registers.
366 */
367 tuple.DesiredTuple = CISTPL_CONFIG;
368 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
369 tuple.TupleData = (u_char *)buf;
370 tuple.TupleDataMax = 64;
371 tuple.TupleOffset = 0;
372 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
373 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
374
375 /* Configure card */
376 link->state |= DEV_CONFIG;
377
378 link->conf.ConfigBase = parse.config.base;
379 link->conf.Present = parse.config.rmask[0];
380
381 tuple.DesiredTuple = CISTPL_FUNCE;
382 tuple.TupleOffset = 0;
383 if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) {
384 /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
385 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
386 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
387 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
388 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
389 link->conf.ConfigIndex = parse.cftable_entry.index;
390 tuple.DesiredTuple = CISTPL_MANFID;
391 if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS)
392 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
393 else
394 buf[0] = 0xffff;
395 switch (le16_to_cpu(buf[0])) {
396 case MANFID_TDK:
397 cardtype = TDK;
Dominik Brodowski70294b42006-01-15 12:43:16 +0100398 if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410
Jun Komurof4d75102005-06-27 16:28:44 -0700399 || le16_to_cpu(buf[1]) == PRODID_TDK_NP9610
400 || le16_to_cpu(buf[1]) == PRODID_TDK_MN3200) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 /* MultiFunction Card */
402 link->conf.ConfigBase = 0x800;
403 link->conf.ConfigIndex = 0x47;
404 link->io.NumPorts2 = 8;
405 }
406 break;
407 case MANFID_CONTEC:
408 cardtype = CONTEC;
409 break;
410 case MANFID_FUJITSU:
411 if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10302)
412 /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302),
413 but these are MBH10304 based card. */
414 cardtype = MBH10304;
415 else if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304)
416 cardtype = MBH10304;
417 else
418 cardtype = LA501;
419 break;
420 default:
421 cardtype = MBH10304;
422 }
423 } else {
424 /* old type card */
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_FUJITSU:
432 if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) {
433 cardtype = XXX10304; /* MBH10304 with buggy CIS */
434 link->conf.ConfigIndex = 0x20;
435 } else {
436 cardtype = MBH10302; /* NextCom NC5310, etc. */
437 link->conf.ConfigIndex = 1;
438 }
439 break;
440 case MANFID_UNGERMANN:
441 cardtype = UNGERMANN;
442 break;
443 default:
444 cardtype = MBH10302;
445 link->conf.ConfigIndex = 1;
446 }
447 }
448
449 if (link->io.NumPorts2 != 0) {
450 link->irq.Attributes =
451 IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
452 ret = mfc_try_io_port(link);
453 if (ret != CS_SUCCESS) goto cs_failed;
454 } else if (cardtype == UNGERMANN) {
455 ret = ungermann_try_io_port(link);
456 if (ret != CS_SUCCESS) goto cs_failed;
457 } else {
458 CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
459 }
460 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
461 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
462 dev->irq = link->irq.AssignedIRQ;
463 dev->base_addr = link->io.BasePort1;
464
465 if (link->io.BasePort2 != 0)
466 fmvj18x_setup_mfc(link);
467
468 ioaddr = dev->base_addr;
469
470 /* Reset controller */
471 if (sram_config == 0)
472 outb(CONFIG0_RST, ioaddr + CONFIG_0);
473 else
474 outb(CONFIG0_RST_1, ioaddr + CONFIG_0);
475
476 /* Power On chip and select bank 0 */
477 if (cardtype == MBH10302)
478 outb(BANK_0, ioaddr + CONFIG_1);
479 else
480 outb(BANK_0U, ioaddr + CONFIG_1);
481
482 /* Set hardware address */
483 switch (cardtype) {
484 case MBH10304:
485 case TDK:
486 case LA501:
487 case CONTEC:
488 tuple.DesiredTuple = CISTPL_FUNCE;
489 tuple.TupleOffset = 0;
490 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
491 tuple.TupleOffset = 0;
492 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
493 if (cardtype == MBH10304) {
494 /* MBH10304's CIS_FUNCE is corrupted */
495 node_id = &(tuple.TupleData[5]);
496 card_name = "FMV-J182";
497 } else {
498 while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
499 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
500 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
501 }
502 node_id = &(tuple.TupleData[2]);
503 if( cardtype == TDK ) {
504 card_name = "TDK LAK-CD021";
505 } else if( cardtype == LA501 ) {
506 card_name = "LA501";
507 } else {
508 card_name = "C-NET(PC)C";
509 }
510 }
511 /* Read MACID from CIS */
512 for (i = 0; i < 6; i++)
513 dev->dev_addr[i] = node_id[i];
514 break;
515 case UNGERMANN:
516 /* Read MACID from register */
517 for (i = 0; i < 6; i++)
518 dev->dev_addr[i] = inb(ioaddr + UNGERMANN_MAC_ID + i);
519 card_name = "Access/CARD";
520 break;
521 case XXX10304:
522 /* Read MACID from Buggy CIS */
523 if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
524 printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
525 goto failed;
526 }
527 for (i = 0 ; i < 6; i++) {
528 dev->dev_addr[i] = tuple.TupleData[i];
529 }
530 card_name = "FMV-J182";
531 break;
532 case MBH10302:
533 default:
534 /* Read MACID from register */
535 for (i = 0; i < 6; i++)
536 dev->dev_addr[i] = inb(ioaddr + MAC_ID + i);
537 card_name = "FMV-J181";
538 break;
539 }
540
541 lp->cardtype = cardtype;
542 link->dev = &lp->node;
543 link->state &= ~DEV_CONFIG_PENDING;
544 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
545
546 if (register_netdev(dev) != 0) {
547 printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
548 link->dev = NULL;
549 goto failed;
550 }
551
552 strcpy(lp->node.dev_name, dev->name);
553
554 /* print current configuration */
555 printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, hw_addr ",
556 dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2",
557 dev->base_addr, dev->irq);
558 for (i = 0; i < 6; i++)
559 printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
560
561 return;
562
563cs_failed:
564 /* All Card Services errors end up here */
565 cs_error(link->handle, last_fn, last_ret);
566failed:
567 fmvj18x_release(link);
568 link->state &= ~DEV_CONFIG_PENDING;
569
570} /* fmvj18x_config */
571/*====================================================================*/
572
573static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id)
574{
575 win_req_t req;
576 memreq_t mem;
577 u_char __iomem *base;
578 int i, j;
579
580 /* Allocate a small memory window */
581 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
582 req.Base = 0; req.Size = 0;
583 req.AccessSpeed = 0;
584 i = pcmcia_request_window(&link->handle, &req, &link->win);
585 if (i != CS_SUCCESS) {
586 cs_error(link->handle, RequestWindow, i);
587 return -1;
588 }
589
590 base = ioremap(req.Base, req.Size);
591 mem.Page = 0;
592 mem.CardOffset = 0;
593 pcmcia_map_mem_page(link->win, &mem);
594
595 /*
596 * MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
597 * 22 0d xx xx xx 04 06 yy yy yy yy yy yy ff
598 * 'xx' is garbage.
599 * 'yy' is MAC address.
600 */
601 for (i = 0; i < 0x200; i++) {
602 if (readb(base+i*2) == 0x22) {
603 if (readb(base+(i-1)*2) == 0xff
604 && readb(base+(i+5)*2) == 0x04
605 && readb(base+(i+6)*2) == 0x06
606 && readb(base+(i+13)*2) == 0xff)
607 break;
608 }
609 }
610
611 if (i != 0x200) {
612 for (j = 0 ; j < 6; j++,i++) {
613 node_id[j] = readb(base+(i+7)*2);
614 }
615 }
616
617 iounmap(base);
618 j = pcmcia_release_window(link->win);
619 if (j != CS_SUCCESS)
620 cs_error(link->handle, ReleaseWindow, j);
621 return (i != 0x200) ? 0 : -1;
622
623} /* fmvj18x_get_hwinfo */
624/*====================================================================*/
625
626static int fmvj18x_setup_mfc(dev_link_t *link)
627{
628 win_req_t req;
629 memreq_t mem;
630 u_char __iomem *base;
631 int i, j;
632 struct net_device *dev = link->priv;
633 kio_addr_t ioaddr;
634
635 /* Allocate a small memory window */
636 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
637 req.Base = 0; req.Size = 0;
638 req.AccessSpeed = 0;
639 i = pcmcia_request_window(&link->handle, &req, &link->win);
640 if (i != CS_SUCCESS) {
641 cs_error(link->handle, RequestWindow, i);
642 return -1;
643 }
644
645 base = ioremap(req.Base, req.Size);
646 mem.Page = 0;
647 mem.CardOffset = 0;
648 pcmcia_map_mem_page(link->win, &mem);
649
650 ioaddr = dev->base_addr;
651 writeb(0x47, base+0x800); /* Config Option Register of LAN */
652 writeb(0x0, base+0x802); /* Config and Status Register */
653
654 writeb(ioaddr & 0xff, base+0x80a); /* I/O Base(Low) of LAN */
655 writeb((ioaddr >> 8) & 0xff, base+0x80c); /* I/O Base(High) of LAN */
656
657 writeb(0x45, base+0x820); /* Config Option Register of Modem */
658 writeb(0x8, base+0x822); /* Config and Status Register */
659
660 iounmap(base);
661 j = pcmcia_release_window(link->win);
662 if (j != CS_SUCCESS)
663 cs_error(link->handle, ReleaseWindow, j);
664 return 0;
665
666}
667/*====================================================================*/
668
669static void fmvj18x_release(dev_link_t *link)
670{
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100671 DEBUG(0, "fmvj18x_release(0x%p)\n", link);
672 pcmcia_disable_device(link->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673}
674
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100675static int fmvj18x_suspend(struct pcmcia_device *p_dev)
676{
677 dev_link_t *link = dev_to_instance(p_dev);
678 struct net_device *dev = link->priv;
679
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100680 if ((link->state & DEV_CONFIG) && (link->open))
681 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100682
683 return 0;
684}
685
686static int fmvj18x_resume(struct pcmcia_device *p_dev)
687{
688 dev_link_t *link = dev_to_instance(p_dev);
689 struct net_device *dev = link->priv;
690
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100691 if ((link->state & DEV_CONFIG) && (link->open)) {
692 fjn_reset(dev);
693 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100694 }
695
696 return 0;
697}
698
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699/*====================================================================*/
700
Dominik Brodowskicda4de82005-06-27 16:28:22 -0700701static struct pcmcia_device_id fmvj18x_ids[] = {
702 PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004),
703 PCMCIA_DEVICE_PROD_ID12("EAGLE Technology", "NE200 ETHERNET LAN MBH10302 04", 0x528c88c4, 0x74f91e59),
704 PCMCIA_DEVICE_PROD_ID12("Eiger Labs,Inc", "EPX-10BT PC Card Ethernet 10BT", 0x53af556e, 0x877f9922),
705 PCMCIA_DEVICE_PROD_ID12("Eiger labs,Inc.", "EPX-10BT PC Card Ethernet 10BT", 0xf47e6c66, 0x877f9922),
706 PCMCIA_DEVICE_PROD_ID12("FUJITSU", "LAN Card(FMV-J182)", 0x6ee5a3d8, 0x5baf31db),
707 PCMCIA_DEVICE_PROD_ID12("FUJITSU", "MBH10308", 0x6ee5a3d8, 0x3f04875e),
708 PCMCIA_DEVICE_PROD_ID12("FUJITSU TOWA", "LA501", 0xb8451188, 0x12939ba2),
709 PCMCIA_DEVICE_PROD_ID12("HITACHI", "HT-4840-11", 0xf4f43949, 0x773910f4),
710 PCMCIA_DEVICE_PROD_ID12("NextComK.K.", "NC5310B Ver1.0 ", 0x8cef4d3a, 0x075fc7b6),
711 PCMCIA_DEVICE_PROD_ID12("NextComK.K.", "NC5310 Ver1.0 ", 0x8cef4d3a, 0xbccf43e6),
712 PCMCIA_DEVICE_PROD_ID12("RATOC System Inc.", "10BASE_T CARD R280", 0x85c10e17, 0xd9413666),
713 PCMCIA_DEVICE_PROD_ID12("TDK", "LAC-CD02x", 0x1eae9475, 0x8fa0ee70),
714 PCMCIA_DEVICE_PROD_ID12("TDK", "LAC-CF010", 0x1eae9475, 0x7683bc9a),
715 PCMCIA_DEVICE_PROD_ID1("CONTEC Co.,Ltd.", 0x58d8fee2),
716 PCMCIA_DEVICE_PROD_ID1("PCMCIA LAN MBH10304 ES", 0x2599f454),
717 PCMCIA_DEVICE_PROD_ID1("PCMCIA MBH10302", 0x8f4005da),
718 PCMCIA_DEVICE_PROD_ID1("UBKK,V2.0", 0x90888080),
719 PCMCIA_PFC_DEVICE_PROD_ID12(0, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
Jun Komurof4d75102005-06-27 16:28:44 -0700720 PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0d0a),
721 PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a),
Dominik Brodowskicda4de82005-06-27 16:28:22 -0700722 PCMCIA_DEVICE_NULL,
723};
724MODULE_DEVICE_TABLE(pcmcia, fmvj18x_ids);
725
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726static struct pcmcia_driver fmvj18x_cs_driver = {
727 .owner = THIS_MODULE,
728 .drv = {
729 .name = "fmvj18x_cs",
730 },
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100731 .probe = fmvj18x_attach,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100732 .remove = fmvj18x_detach,
Dominik Brodowskicda4de82005-06-27 16:28:22 -0700733 .id_table = fmvj18x_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100734 .suspend = fmvj18x_suspend,
735 .resume = fmvj18x_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736};
737
738static int __init init_fmvj18x_cs(void)
739{
740 return pcmcia_register_driver(&fmvj18x_cs_driver);
741}
742
743static void __exit exit_fmvj18x_cs(void)
744{
745 pcmcia_unregister_driver(&fmvj18x_cs_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746}
747
748module_init(init_fmvj18x_cs);
749module_exit(exit_fmvj18x_cs);
750
751/*====================================================================*/
752
753static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
754{
755 struct net_device *dev = dev_id;
756 local_info_t *lp = netdev_priv(dev);
757 kio_addr_t ioaddr;
758 unsigned short tx_stat, rx_stat;
759
760 if (lp == NULL) {
761 printk(KERN_NOTICE "fjn_interrupt(): irq %d for "
762 "unknown device.\n", irq);
763 return IRQ_NONE;
764 }
765 ioaddr = dev->base_addr;
766
767 /* avoid multiple interrupts */
768 outw(0x0000, ioaddr + TX_INTR);
769
770 /* wait for a while */
771 udelay(1);
772
773 /* get status */
774 tx_stat = inb(ioaddr + TX_STATUS);
775 rx_stat = inb(ioaddr + RX_STATUS);
776
777 /* clear status */
778 outb(tx_stat, ioaddr + TX_STATUS);
779 outb(rx_stat, ioaddr + RX_STATUS);
780
781 DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
782 DEBUG(4, " tx_status %02x.\n", tx_stat);
783
784 if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
785 /* there is packet(s) in rx buffer */
786 fjn_rx(dev);
787 }
788 if (tx_stat & F_TMT_RDY) {
789 lp->stats.tx_packets += lp->sent ;
790 lp->sent = 0 ;
791 if (lp->tx_queue) {
792 outb(DO_TX | lp->tx_queue, ioaddr + TX_START);
793 lp->sent = lp->tx_queue ;
794 lp->tx_queue = 0;
795 lp->tx_queue_len = 0;
796 dev->trans_start = jiffies;
797 } else {
798 lp->tx_started = 0;
799 }
800 netif_wake_queue(dev);
801 }
802 DEBUG(4, "%s: exiting interrupt,\n", dev->name);
803 DEBUG(4, " tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
804
805 outb(D_TX_INTR, ioaddr + TX_INTR);
806 outb(D_RX_INTR, ioaddr + RX_INTR);
807 return IRQ_HANDLED;
808
809} /* fjn_interrupt */
810
811/*====================================================================*/
812
813static void fjn_tx_timeout(struct net_device *dev)
814{
815 struct local_info_t *lp = netdev_priv(dev);
816 kio_addr_t ioaddr = dev->base_addr;
817
818 printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n",
819 dev->name, htons(inw(ioaddr + TX_STATUS)),
820 inb(ioaddr + TX_STATUS) & F_TMT_RDY
821 ? "IRQ conflict" : "network cable problem");
822 printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x "
823 "%04x %04x %04x %04x %04x.\n",
824 dev->name, htons(inw(ioaddr + 0)),
825 htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),
826 htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
827 htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
828 htons(inw(ioaddr +14)));
829 lp->stats.tx_errors++;
830 /* ToDo: We should try to restart the adaptor... */
831 local_irq_disable();
832 fjn_reset(dev);
833
834 lp->tx_started = 0;
835 lp->tx_queue = 0;
836 lp->tx_queue_len = 0;
837 lp->sent = 0;
838 lp->open_time = jiffies;
839 local_irq_enable();
840 netif_wake_queue(dev);
841}
842
843static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
844{
845 struct local_info_t *lp = netdev_priv(dev);
846 kio_addr_t ioaddr = dev->base_addr;
847 short length = skb->len;
848
849 if (length < ETH_ZLEN)
850 {
851 skb = skb_padto(skb, ETH_ZLEN);
852 if (skb == NULL)
853 return 0;
854 length = ETH_ZLEN;
855 }
856
857 netif_stop_queue(dev);
858
859 {
860 unsigned char *buf = skb->data;
861
862 if (length > ETH_FRAME_LEN) {
863 printk(KERN_NOTICE "%s: Attempting to send a large packet"
864 " (%d bytes).\n", dev->name, length);
865 return 1;
866 }
867
868 DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
869 dev->name, (unsigned long)skb->len);
870 lp->stats.tx_bytes += skb->len;
871
872 /* Disable both interrupts. */
873 outw(0x0000, ioaddr + TX_INTR);
874
875 /* wait for a while */
876 udelay(1);
877
878 outw(length, ioaddr + DATAPORT);
879 outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
880
881 lp->tx_queue++;
882 lp->tx_queue_len += ((length+3) & ~1);
883
884 if (lp->tx_started == 0) {
885 /* If the Tx is idle, always trigger a transmit. */
886 outb(DO_TX | lp->tx_queue, ioaddr + TX_START);
887 lp->sent = lp->tx_queue ;
888 lp->tx_queue = 0;
889 lp->tx_queue_len = 0;
890 dev->trans_start = jiffies;
891 lp->tx_started = 1;
892 netif_start_queue(dev);
893 } else {
894 if( sram_config == 0 ) {
895 if (lp->tx_queue_len < (4096 - (ETH_FRAME_LEN +2)) )
896 /* Yes, there is room for one more packet. */
897 netif_start_queue(dev);
898 } else {
899 if (lp->tx_queue_len < (8192 - (ETH_FRAME_LEN +2)) &&
900 lp->tx_queue < 127 )
901 /* Yes, there is room for one more packet. */
902 netif_start_queue(dev);
903 }
904 }
905
906 /* Re-enable interrupts */
907 outb(D_TX_INTR, ioaddr + TX_INTR);
908 outb(D_RX_INTR, ioaddr + RX_INTR);
909 }
910 dev_kfree_skb (skb);
911
912 return 0;
913} /* fjn_start_xmit */
914
915/*====================================================================*/
916
917static void fjn_reset(struct net_device *dev)
918{
919 struct local_info_t *lp = netdev_priv(dev);
920 kio_addr_t ioaddr = dev->base_addr;
921 int i;
922
923 DEBUG(4, "fjn_reset(%s) called.\n",dev->name);
924
925 /* Reset controller */
926 if( sram_config == 0 )
927 outb(CONFIG0_RST, ioaddr + CONFIG_0);
928 else
929 outb(CONFIG0_RST_1, ioaddr + CONFIG_0);
930
931 /* Power On chip and select bank 0 */
932 if (lp->cardtype == MBH10302)
933 outb(BANK_0, ioaddr + CONFIG_1);
934 else
935 outb(BANK_0U, ioaddr + CONFIG_1);
936
937 /* Set Tx modes */
938 outb(D_TX_MODE, ioaddr + TX_MODE);
939 /* set Rx modes */
940 outb(ID_MATCHED, ioaddr + RX_MODE);
941
942 /* Set hardware address */
943 for (i = 0; i < 6; i++)
944 outb(dev->dev_addr[i], ioaddr + NODE_ID + i);
945
Komuroab808822005-12-01 02:37:17 -0500946 /* (re)initialize the multicast table */
947 set_rx_mode(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948
949 /* Switch to bank 2 (runtime mode) */
950 if (lp->cardtype == MBH10302)
951 outb(BANK_2, ioaddr + CONFIG_1);
952 else
953 outb(BANK_2U, ioaddr + CONFIG_1);
954
955 /* set 16col ctrl bits */
956 if( lp->cardtype == TDK || lp->cardtype == CONTEC)
957 outb(TDK_AUTO_MODE, ioaddr + COL_CTRL);
958 else
959 outb(AUTO_MODE, ioaddr + COL_CTRL);
960
961 /* clear Reserved Regs */
962 outb(0x00, ioaddr + BMPR12);
963 outb(0x00, ioaddr + BMPR13);
964
965 /* reset Skip packet reg. */
966 outb(0x01, ioaddr + RX_SKIP);
967
968 /* Enable Tx and Rx */
969 if( sram_config == 0 )
970 outb(CONFIG0_DFL, ioaddr + CONFIG_0);
971 else
972 outb(CONFIG0_DFL_1, ioaddr + CONFIG_0);
973
974 /* Init receive pointer ? */
975 inw(ioaddr + DATAPORT);
976 inw(ioaddr + DATAPORT);
977
978 /* Clear all status */
979 outb(0xff, ioaddr + TX_STATUS);
980 outb(0xff, ioaddr + RX_STATUS);
981
982 if (lp->cardtype == MBH10302)
983 outb(INTR_OFF, ioaddr + LAN_CTRL);
984
985 /* Turn on Rx interrupts */
986 outb(D_TX_INTR, ioaddr + TX_INTR);
987 outb(D_RX_INTR, ioaddr + RX_INTR);
988
989 /* Turn on interrupts from LAN card controller */
990 if (lp->cardtype == MBH10302)
991 outb(INTR_ON, ioaddr + LAN_CTRL);
992} /* fjn_reset */
993
994/*====================================================================*/
995
996static void fjn_rx(struct net_device *dev)
997{
998 struct local_info_t *lp = netdev_priv(dev);
999 kio_addr_t ioaddr = dev->base_addr;
1000 int boguscount = 10; /* 5 -> 10: by agy 19940922 */
1001
1002 DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",
1003 dev->name, inb(ioaddr + RX_STATUS));
1004
1005 while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
1006 u_short status = inw(ioaddr + DATAPORT);
1007
1008 DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n",
1009 dev->name, inb(ioaddr + RX_MODE), status);
1010#ifndef final_version
1011 if (status == 0) {
1012 outb(F_SKP_PKT, ioaddr + RX_SKIP);
1013 break;
1014 }
1015#endif
1016 if ((status & 0xF0) != 0x20) { /* There was an error. */
1017 lp->stats.rx_errors++;
1018 if (status & F_LEN_ERR) lp->stats.rx_length_errors++;
1019 if (status & F_ALG_ERR) lp->stats.rx_frame_errors++;
1020 if (status & F_CRC_ERR) lp->stats.rx_crc_errors++;
1021 if (status & F_OVR_FLO) lp->stats.rx_over_errors++;
1022 } else {
1023 u_short pkt_len = inw(ioaddr + DATAPORT);
1024 /* Malloc up new buffer. */
1025 struct sk_buff *skb;
1026
1027 if (pkt_len > 1550) {
1028 printk(KERN_NOTICE "%s: The FMV-18x claimed a very "
1029 "large packet, size %d.\n", dev->name, pkt_len);
1030 outb(F_SKP_PKT, ioaddr + RX_SKIP);
1031 lp->stats.rx_errors++;
1032 break;
1033 }
1034 skb = dev_alloc_skb(pkt_len+2);
1035 if (skb == NULL) {
1036 printk(KERN_NOTICE "%s: Memory squeeze, dropping "
1037 "packet (len %d).\n", dev->name, pkt_len);
1038 outb(F_SKP_PKT, ioaddr + RX_SKIP);
1039 lp->stats.rx_dropped++;
1040 break;
1041 }
1042 skb->dev = dev;
1043
1044 skb_reserve(skb, 2);
1045 insw(ioaddr + DATAPORT, skb_put(skb, pkt_len),
1046 (pkt_len + 1) >> 1);
1047 skb->protocol = eth_type_trans(skb, dev);
1048
1049#ifdef PCMCIA_DEBUG
1050 if (pc_debug > 5) {
1051 int i;
1052 printk(KERN_DEBUG "%s: Rxed packet of length %d: ",
1053 dev->name, pkt_len);
1054 for (i = 0; i < 14; i++)
1055 printk(" %02x", skb->data[i]);
1056 printk(".\n");
1057 }
1058#endif
1059
1060 netif_rx(skb);
1061 dev->last_rx = jiffies;
1062 lp->stats.rx_packets++;
1063 lp->stats.rx_bytes += pkt_len;
1064 }
1065 if (--boguscount <= 0)
1066 break;
1067 }
1068
1069 /* If any worth-while packets have been received, dev_rint()
1070 has done a netif_wake_queue() for us and will work on them
1071 when we get to the bottom-half routine. */
1072/*
1073 if (lp->cardtype != TDK) {
1074 int i;
1075 for (i = 0; i < 20; i++) {
1076 if ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == F_BUF_EMP)
1077 break;
1078 (void)inw(ioaddr + DATAPORT); /+ dummy status read +/
1079 outb(F_SKP_PKT, ioaddr + RX_SKIP);
1080 }
1081
1082 if (i > 0)
1083 DEBUG(5, "%s: Exint Rx packet with mode %02x after "
1084 "%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);
1085 }
1086*/
1087
1088 return;
1089} /* fjn_rx */
1090
1091/*====================================================================*/
1092
1093static void netdev_get_drvinfo(struct net_device *dev,
1094 struct ethtool_drvinfo *info)
1095{
1096 strcpy(info->driver, DRV_NAME);
1097 strcpy(info->version, DRV_VERSION);
1098 sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
1099}
1100
1101#ifdef PCMCIA_DEBUG
1102static u32 netdev_get_msglevel(struct net_device *dev)
1103{
1104 return pc_debug;
1105}
1106
1107static void netdev_set_msglevel(struct net_device *dev, u32 level)
1108{
1109 pc_debug = level;
1110}
1111#endif /* PCMCIA_DEBUG */
1112
1113static struct ethtool_ops netdev_ethtool_ops = {
1114 .get_drvinfo = netdev_get_drvinfo,
1115#ifdef PCMCIA_DEBUG
1116 .get_msglevel = netdev_get_msglevel,
1117 .set_msglevel = netdev_set_msglevel,
1118#endif /* PCMCIA_DEBUG */
1119};
1120
1121static int fjn_config(struct net_device *dev, struct ifmap *map){
1122 return 0;
1123}
1124
1125static int fjn_open(struct net_device *dev)
1126{
1127 struct local_info_t *lp = netdev_priv(dev);
1128 dev_link_t *link = &lp->link;
1129
1130 DEBUG(4, "fjn_open('%s').\n", dev->name);
1131
1132 if (!DEV_OK(link))
1133 return -ENODEV;
1134
1135 link->open++;
1136
1137 fjn_reset(dev);
1138
1139 lp->tx_started = 0;
1140 lp->tx_queue = 0;
1141 lp->tx_queue_len = 0;
1142 lp->open_time = jiffies;
1143 netif_start_queue(dev);
1144
1145 return 0;
1146} /* fjn_open */
1147
1148/*====================================================================*/
1149
1150static int fjn_close(struct net_device *dev)
1151{
1152 struct local_info_t *lp = netdev_priv(dev);
1153 dev_link_t *link = &lp->link;
1154 kio_addr_t ioaddr = dev->base_addr;
1155
1156 DEBUG(4, "fjn_close('%s').\n", dev->name);
1157
1158 lp->open_time = 0;
1159 netif_stop_queue(dev);
1160
1161 /* Set configuration register 0 to disable Tx and Rx. */
1162 if( sram_config == 0 )
1163 outb(CONFIG0_RST ,ioaddr + CONFIG_0);
1164 else
1165 outb(CONFIG0_RST_1 ,ioaddr + CONFIG_0);
1166
1167 /* Update the statistics -- ToDo. */
1168
1169 /* Power-down the chip. Green, green, green! */
1170 outb(CHIP_OFF ,ioaddr + CONFIG_1);
1171
1172 /* Set the ethernet adaptor disable IRQ */
1173 if (lp->cardtype == MBH10302)
1174 outb(INTR_OFF, ioaddr + LAN_CTRL);
1175
1176 link->open--;
1177
1178 return 0;
1179} /* fjn_close */
1180
1181/*====================================================================*/
1182
1183static struct net_device_stats *fjn_get_stats(struct net_device *dev)
1184{
1185 local_info_t *lp = netdev_priv(dev);
1186 return &lp->stats;
1187} /* fjn_get_stats */
1188
1189/*====================================================================*/
1190
1191/*
1192 Set the multicast/promiscuous mode for this adaptor.
1193*/
1194
1195static void set_rx_mode(struct net_device *dev)
1196{
1197 kio_addr_t ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 u_char mc_filter[8]; /* Multicast hash filter */
1199 u_long flags;
1200 int i;
1201
Komuroab808822005-12-01 02:37:17 -05001202 int saved_bank;
Komurod9a8a0a2005-08-06 12:01:43 +09001203 int saved_config_0 = inb(ioaddr + CONFIG_0);
1204
1205 local_irq_save(flags);
1206
1207 /* 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
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 if (dev->flags & IFF_PROMISC) {
1214 /* Unconditionally log net taps. */
1215 printk("%s: Promiscuous mode enabled.\n", dev->name);
1216 memset(mc_filter, 0xff, sizeof(mc_filter));
1217 outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
1218 } else if (dev->mc_count > MC_FILTERBREAK
1219 || (dev->flags & IFF_ALLMULTI)) {
1220 /* Too many to filter perfectly -- accept all multicasts. */
1221 memset(mc_filter, 0xff, sizeof(mc_filter));
1222 outb(2, ioaddr + RX_MODE); /* Use normal mode. */
1223 } else if (dev->mc_count == 0) {
1224 memset(mc_filter, 0x00, sizeof(mc_filter));
1225 outb(1, ioaddr + RX_MODE); /* Ignore almost all multicasts. */
1226 } else {
1227 struct dev_mc_list *mclist;
1228 int i;
1229
1230 memset(mc_filter, 0, sizeof(mc_filter));
1231 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
1232 i++, mclist = mclist->next) {
1233 unsigned int bit =
Komurod9a8a0a2005-08-06 12:01:43 +09001234 ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26;
1235 mc_filter[bit >> 3] |= (1 << (bit & 7));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 }
Komurod9a8a0a2005-08-06 12:01:43 +09001237 outb(2, ioaddr + RX_MODE); /* Use normal mode. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 }
1239
Komuroab808822005-12-01 02:37:17 -05001240 /* Switch to bank 1 and set the multicast table. */
1241 saved_bank = inb(ioaddr + CONFIG_1);
1242 outb(0xe4, ioaddr + CONFIG_1);
1243
1244 for (i = 0; i < 8; i++)
1245 outb(mc_filter[i], ioaddr + MAR_ADR + i);
1246 outb(saved_bank, ioaddr + CONFIG_1);
Komurod9a8a0a2005-08-06 12:01:43 +09001247
1248 outb(saved_config_0, ioaddr + CONFIG_0);
1249
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250 local_irq_restore(flags);
1251}