aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fmv18x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fmv18x.c')
-rw-r--r--drivers/net/fmv18x.c689
1 files changed, 0 insertions, 689 deletions
diff --git a/drivers/net/fmv18x.c b/drivers/net/fmv18x.c
deleted file mode 100644
index 04c748523471..000000000000
--- a/drivers/net/fmv18x.c
+++ /dev/null
@@ -1,689 +0,0 @@
1/* fmv18x.c: A network device driver for the Fujitsu FMV-181/182/183/184.
2
3 Original: at1700.c (1993-94 by Donald Becker).
4 Copyright 1993 United States Government as represented by the
5 Director, National Security Agency.
6 The author may be reached as becker@scyld.com, or C/O
7 Scyld Computing Corporation
8 410 Severn Ave., Suite 210
9 Annapolis MD 21403
10
11 Modified by Yutaka TAMIYA (tamy@flab.fujitsu.co.jp)
12 Copyright 1994 Fujitsu Laboratories Ltd.
13 Special thanks to:
14 Masayoshi UTAKA (utaka@ace.yk.fujitsu.co.jp)
15 for testing this driver.
16 H. NEGISHI (agy, negishi@sun45.psd.cs.fujitsu.co.jp)
17 for suggestion of some program modification.
18 Masahiro SEKIGUCHI <seki@sysrap.cs.fujitsu.co.jp>
19 for suggestion of some program modification.
20 Kazutoshi MORIOKA (morioka@aurora.oaks.cs.fujitsu.co.jp)
21 for testing this driver.
22
23 This software may be used and distributed according to the terms
24 of the GNU General Public License, incorporated herein by reference.
25
26 This is a device driver for the Fujitsu FMV-181/182/183/184, which
27 is a straight-forward Fujitsu MB86965 implementation.
28
29 Sources:
30 at1700.c
31 The Fujitsu MB86965 datasheet.
32 The Fujitsu FMV-181/182 user's guide
33*/
34
35static const char version[] =
36 "fmv18x.c:v2.2.0 09/24/98 Yutaka TAMIYA (tamy@flab.fujitsu.co.jp)\n";
37
38#include <linux/module.h>
39#include <linux/kernel.h>
40#include <linux/types.h>
41#include <linux/fcntl.h>
42#include <linux/interrupt.h>
43#include <linux/ioport.h>
44#include <linux/in.h>
45#include <linux/slab.h>
46#include <linux/string.h>
47#include <linux/init.h>
48#include <linux/errno.h>
49#include <linux/spinlock.h>
50#include <linux/netdevice.h>
51#include <linux/etherdevice.h>
52#include <linux/skbuff.h>
53#include <linux/delay.h>
54#include <linux/bitops.h>
55
56#include <asm/system.h>
57#include <asm/io.h>
58#include <asm/dma.h>
59
60#define DRV_NAME "fmv18x"
61
62static unsigned fmv18x_probe_list[] __initdata = {
63 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
64};
65
66/* use 0 for production, 1 for verification, >2 for debug */
67#ifndef NET_DEBUG
68#define NET_DEBUG 1
69#endif
70static unsigned int net_debug = NET_DEBUG;
71
72typedef unsigned char uchar;
73
74/* Information that need to be kept for each board. */
75struct net_local {
76 struct net_device_stats stats;
77 long open_time; /* Useless example local info. */
78 uint tx_started:1; /* Number of packet on the Tx queue. */
79 uint tx_queue_ready:1; /* Tx queue is ready to be sent. */
80 uint rx_started:1; /* Packets are Rxing. */
81 uchar tx_queue; /* Number of packet on the Tx queue. */
82 ushort tx_queue_len; /* Current length of the Tx queue. */
83 spinlock_t lock;
84};
85
86
87/* Offsets from the base address. */
88#define STATUS 0
89#define TX_STATUS 0
90#define RX_STATUS 1
91#define TX_INTR 2 /* Bit-mapped interrupt enable registers. */
92#define RX_INTR 3
93#define TX_MODE 4
94#define RX_MODE 5
95#define CONFIG_0 6 /* Misc. configuration settings. */
96#define CONFIG_1 7
97/* Run-time register bank 2 definitions. */
98#define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
99#define TX_START 10
100#define COL16CNTL 11 /* Controll Reg for 16 collisions */
101#define MODE13 13
102/* Fujitsu FMV-18x Card Configuration */
103#define FJ_STATUS0 0x10
104#define FJ_STATUS1 0x11
105#define FJ_CONFIG0 0x12
106#define FJ_CONFIG1 0x13
107#define FJ_MACADDR 0x14 /* 0x14 - 0x19 */
108#define FJ_BUFCNTL 0x1A
109#define FJ_BUFDATA 0x1C
110#define FMV18X_IO_EXTENT 32
111
112/* Index to functions, as function prototypes. */
113
114static int fmv18x_probe1(struct net_device *dev, short ioaddr);
115static int net_open(struct net_device *dev);
116static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
117static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
118static void net_rx(struct net_device *dev);
119static void net_timeout(struct net_device *dev);
120static int net_close(struct net_device *dev);
121static struct net_device_stats *net_get_stats(struct net_device *dev);
122static void set_multicast_list(struct net_device *dev);
123
124
125/* Check for a network adaptor of this type, and return '0' iff one exists.
126 If dev->base_addr == 0, probe all likely locations.
127 If dev->base_addr == 1, always return failure.
128 If dev->base_addr == 2, allocate space for the device and return success
129 (detachable devices only).
130 */
131
132static int io = 0x220;
133static int irq;
134
135struct net_device * __init fmv18x_probe(int unit)
136{
137 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
138 unsigned *port;
139 int err = 0;
140
141 if (!dev)
142 return ERR_PTR(-ENODEV);
143
144 if (unit >= 0) {
145 sprintf(dev->name, "eth%d", unit);
146 netdev_boot_setup_check(dev);
147 io = dev->base_addr;
148 irq = dev->irq;
149 }
150
151 SET_MODULE_OWNER(dev);
152
153 if (io > 0x1ff) { /* Check a single specified location. */
154 err = fmv18x_probe1(dev, io);
155 } else if (io != 0) { /* Don't probe at all. */
156 err = -ENXIO;
157 } else {
158 for (port = fmv18x_probe_list; *port; port++)
159 if (fmv18x_probe1(dev, *port) == 0)
160 break;
161 if (!*port)
162 err = -ENODEV;
163 }
164 if (err)
165 goto out;
166 err = register_netdev(dev);
167 if (err)
168 goto out1;
169 return dev;
170out1:
171 free_irq(dev->irq, dev);
172 release_region(dev->base_addr, FMV18X_IO_EXTENT);
173out:
174 free_netdev(dev);
175 return ERR_PTR(err);
176}
177
178/* The Fujitsu datasheet suggests that the NIC be probed for by checking its
179 "signature", the default bit pattern after a reset. This *doesn't* work --
180 there is no way to reset the bus interface without a complete power-cycle!
181
182 It turns out that ATI came to the same conclusion I did: the only thing
183 that can be done is checking a few bits and then diving right into MAC
184 address check. */
185
186static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
187{
188 char irqmap[4] = {3, 7, 10, 15};
189 char irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
190 unsigned int i, retval;
191 struct net_local *lp;
192
193 /* Resetting the chip doesn't reset the ISA interface, so don't bother.
194 That means we have to be careful with the register values we probe for.
195 */
196
197 if (!request_region(ioaddr, FMV18X_IO_EXTENT, DRV_NAME))
198 return -EBUSY;
199
200 dev->irq = irq;
201 dev->base_addr = ioaddr;
202
203 /* Check I/O address configuration and Fujitsu vendor code */
204 if (inb(ioaddr+FJ_MACADDR ) != 0x00
205 || inb(ioaddr+FJ_MACADDR+1) != 0x00
206 || inb(ioaddr+FJ_MACADDR+2) != 0x0e) {
207 retval = -ENODEV;
208 goto out;
209 }
210
211 /* Check PnP mode for FMV-183/184/183A/184A. */
212 /* This PnP routine is very poor. IO and IRQ should be known. */
213 if (inb(ioaddr + FJ_STATUS1) & 0x20) {
214 for (i = 0; i < 8; i++) {
215 if (dev->irq == irqmap_pnp[i])
216 break;
217 }
218 if (i == 8) {
219 retval = -ENODEV;
220 goto out;
221 }
222 } else {
223 if (fmv18x_probe_list[inb(ioaddr + FJ_CONFIG0) & 0x07] != ioaddr)
224 return -ENODEV;
225 dev->irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
226 }
227
228 /* Snarf the interrupt vector now. */
229 retval = request_irq(dev->irq, &net_interrupt, 0, DRV_NAME, dev);
230 if (retval) {
231 printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on"
232 "IRQ %d.\n", ioaddr, dev->irq);
233 goto out;
234 }
235
236 printk("%s: FMV-18x found at %#3x, IRQ %d, address ", dev->name,
237 ioaddr, dev->irq);
238
239 for(i = 0; i < 6; i++) {
240 unsigned char val = inb(ioaddr + FJ_MACADDR + i);
241 printk("%02x", val);
242 dev->dev_addr[i] = val;
243 }
244
245 /* "FJ_STATUS0" 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
246 rather than 150 ohm shielded twisted pair compensation.
247 0x0000 == auto-sense the interface
248 0x0800 == use TP interface
249 0x1800 == use coax interface
250 */
251 {
252 const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2/5"};
253 ushort setup_value = inb(ioaddr + FJ_STATUS0);
254
255 switch( setup_value & 0x07 ){
256 case 0x01 /* 10base5 */:
257 case 0x02 /* 10base2 */: dev->if_port = 0x18; break;
258 case 0x04 /* 10baseT */: dev->if_port = 0x08; break;
259 default /* auto-sense*/: dev->if_port = 0x00; break;
260 }
261 printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
262 }
263
264 /* Initialize LAN Controller and LAN Card */
265 outb(0xda, ioaddr + CONFIG_0); /* Initialize LAN Controller */
266 outb(0x00, ioaddr + CONFIG_1); /* Stand by mode */
267 outb(0x00, ioaddr + FJ_CONFIG1); /* Disable IRQ of LAN Card */
268 outb(0x00, ioaddr + FJ_BUFCNTL); /* Reset ? I'm not sure (TAMIYA) */
269
270 /* wait for a while */
271 udelay(200);
272
273 /* Set the station address in bank zero. */
274 outb(0x00, ioaddr + CONFIG_1);
275 for (i = 0; i < 6; i++)
276 outb(dev->dev_addr[i], ioaddr + 8 + i);
277
278 /* Switch to bank 1 and set the multicast table to accept none. */
279 outb(0x04, ioaddr + CONFIG_1);
280 for (i = 0; i < 8; i++)
281 outb(0x00, ioaddr + 8 + i);
282
283 /* Switch to bank 2 and lock our I/O address. */
284 outb(0x08, ioaddr + CONFIG_1);
285 outb(dev->if_port, ioaddr + MODE13);
286 outb(0x00, ioaddr + COL16CNTL);
287
288 if (net_debug)
289 printk(version);
290
291 /* Initialize the device structure. */
292 dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
293 if (!dev->priv) {
294 retval = -ENOMEM;
295 goto out_irq;
296 }
297 memset(dev->priv, 0, sizeof(struct net_local));
298 lp = dev->priv;
299 spin_lock_init(&lp->lock);
300
301 dev->open = net_open;
302 dev->stop = net_close;
303 dev->hard_start_xmit = net_send_packet;
304 dev->tx_timeout = net_timeout;
305 dev->watchdog_timeo = HZ/10;
306 dev->get_stats = net_get_stats;
307 dev->set_multicast_list = set_multicast_list;
308 return 0;
309
310out_irq:
311 free_irq(dev->irq, dev);
312out:
313 release_region(ioaddr, FMV18X_IO_EXTENT);
314 return retval;
315}
316
317
318static int net_open(struct net_device *dev)
319{
320 struct net_local *lp = dev->priv;
321 int ioaddr = dev->base_addr;
322
323 /* Set the configuration register 0 to 32K 100ns. byte-wide memory,
324 16 bit bus access, and two 4K Tx, enable the Rx and Tx. */
325 outb(0x5a, ioaddr + CONFIG_0);
326
327 /* Powerup and switch to register bank 2 for the run-time registers. */
328 outb(0xe8, ioaddr + CONFIG_1);
329
330 lp->tx_started = 0;
331 lp->tx_queue_ready = 1;
332 lp->rx_started = 0;
333 lp->tx_queue = 0;
334 lp->tx_queue_len = 0;
335
336 /* Clear Tx and Rx Status */
337 outb(0xff, ioaddr + TX_STATUS);
338 outb(0xff, ioaddr + RX_STATUS);
339 lp->open_time = jiffies;
340
341 netif_start_queue(dev);
342
343 /* Enable the IRQ of the LAN Card */
344 outb(0x80, ioaddr + FJ_CONFIG1);
345
346 /* Enable both Tx and Rx interrupts */
347 outw(0x8182, ioaddr+TX_INTR);
348
349 return 0;
350}
351
352static void net_timeout(struct net_device *dev)
353{
354 struct net_local *lp = dev->priv;
355 int ioaddr = dev->base_addr;
356 unsigned long flags;
357
358
359 printk(KERN_WARNING "%s: transmit timed out with status %04x, %s?\n", dev->name,
360 htons(inw(ioaddr + TX_STATUS)),
361 inb(ioaddr + TX_STATUS) & 0x80
362 ? "IRQ conflict" : "network cable problem");
363 printk(KERN_WARNING "%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
364 dev->name, htons(inw(ioaddr + 0)),
365 htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),
366 htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
367 htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
368 htons(inw(ioaddr +14)));
369 printk(KERN_WARNING "eth card: %04x %04x\n",
370 htons(inw(ioaddr+FJ_STATUS0)),
371 htons(inw(ioaddr+FJ_CONFIG0)));
372 lp->stats.tx_errors++;
373 /* ToDo: We should try to restart the adaptor... */
374 spin_lock_irqsave(&lp->lock, flags);
375
376 /* Initialize LAN Controller and LAN Card */
377 outb(0xda, ioaddr + CONFIG_0); /* Initialize LAN Controller */
378 outb(0x00, ioaddr + CONFIG_1); /* Stand by mode */
379 outb(0x00, ioaddr + FJ_CONFIG1); /* Disable IRQ of LAN Card */
380 outb(0x00, ioaddr + FJ_BUFCNTL); /* Reset ? I'm not sure */
381 net_open(dev);
382 spin_unlock_irqrestore(&lp->lock, flags);
383
384 netif_wake_queue(dev);
385}
386
387static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
388{
389 struct net_local *lp = dev->priv;
390 int ioaddr = dev->base_addr;
391 short length = skb->len;
392 unsigned char *buf;
393 unsigned long flags;
394
395 /* Block a transmit from overlapping. */
396
397 if (length > ETH_FRAME_LEN) {
398 if (net_debug)
399 printk("%s: Attempting to send a large packet (%d bytes).\n",
400 dev->name, length);
401 return 1;
402 }
403
404 if (length < ETH_ZLEN) {
405 skb = skb_padto(skb, ETH_ZLEN);
406 if (skb == NULL)
407 return 0;
408 length = ETH_ZLEN;
409 }
410 buf = skb->data;
411
412 if (net_debug > 4)
413 printk("%s: Transmitting a packet of length %lu.\n", dev->name,
414 (unsigned long)skb->len);
415 /* We may not start transmitting unless we finish transferring
416 a packet into the Tx queue. During executing the following
417 codes we possibly catch a Tx interrupt. Thus we flag off
418 tx_queue_ready, so that we prevent the interrupt routine
419 (net_interrupt) to start transmitting. */
420 spin_lock_irqsave(&lp->lock, flags);
421 lp->tx_queue_ready = 0;
422 {
423 outw(length, ioaddr + DATAPORT);
424 outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
425 lp->tx_queue++;
426 lp->tx_queue_len += length + 2;
427 }
428 lp->tx_queue_ready = 1;
429 spin_unlock_irqrestore(&lp->lock, flags);
430
431 if (lp->tx_started == 0) {
432 /* If the Tx is idle, always trigger a transmit. */
433 outb(0x80 | lp->tx_queue, ioaddr + TX_START);
434 lp->tx_queue = 0;
435 lp->tx_queue_len = 0;
436 dev->trans_start = jiffies;
437 lp->tx_started = 1;
438 } else if (lp->tx_queue_len >= 4096 - 1502) /* No room for a packet */
439 netif_stop_queue(dev);
440
441 dev_kfree_skb(skb);
442 return 0;
443}
444
445/* The typical workload of the driver:
446 Handle the network interface interrupts. */
447static irqreturn_t
448net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
449{
450 struct net_device *dev = dev_id;
451 struct net_local *lp;
452 int ioaddr, status;
453
454 ioaddr = dev->base_addr;
455 lp = dev->priv;
456 status = inw(ioaddr + TX_STATUS);
457 outw(status, ioaddr + TX_STATUS);
458
459 if (net_debug > 4)
460 printk("%s: Interrupt with status %04x.\n", dev->name, status);
461 if (lp->rx_started == 0 &&
462 (status & 0xff00 || (inb(ioaddr + RX_MODE) & 0x40) == 0)) {
463 /* Got a packet(s).
464 We cannot execute net_rx more than once at the same time for
465 the same device. During executing net_rx, we possibly catch a
466 Tx interrupt. Thus we flag on rx_started, so that we prevent
467 the interrupt routine (net_interrupt) to dive into net_rx
468 again. */
469 lp->rx_started = 1;
470 outb(0x00, ioaddr + RX_INTR); /* Disable RX intr. */
471 net_rx(dev);
472 outb(0x81, ioaddr + RX_INTR); /* Enable RX intr. */
473 lp->rx_started = 0;
474 }
475 if (status & 0x00ff) {
476 if (status & 0x02) {
477 /* More than 16 collisions occurred */
478 if (net_debug > 4)
479 printk("%s: 16 Collision occur during Txing.\n", dev->name);
480 /* Cancel sending a packet. */
481 outb(0x03, ioaddr + COL16CNTL);
482 lp->stats.collisions++;
483 }
484 if (status & 0x82) {
485 spin_lock(&lp->lock);
486 lp->stats.tx_packets++;
487 if (lp->tx_queue && lp->tx_queue_ready) {
488 outb(0x80 | lp->tx_queue, ioaddr + TX_START);
489 lp->tx_queue = 0;
490 lp->tx_queue_len = 0;
491 dev->trans_start = jiffies;
492 netif_wake_queue(dev); /* Inform upper layers. */
493 } else {
494 lp->tx_started = 0;
495 netif_wake_queue(dev); /* Inform upper layers. */
496 }
497 spin_unlock(&lp->lock);
498 }
499 }
500 return IRQ_RETVAL(status);
501}
502
503/* We have a good packet(s), get it/them out of the buffers. */
504static void net_rx(struct net_device *dev)
505{
506 struct net_local *lp = dev->priv;
507 int ioaddr = dev->base_addr;
508 int boguscount = 5;
509
510 while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
511 /* Clear PKT_RDY bit: by agy 19940922 */
512 /* outb(0x80, ioaddr + RX_STATUS); */
513 ushort status = inw(ioaddr + DATAPORT);
514
515 if (net_debug > 4)
516 printk("%s: Rxing packet mode %02x status %04x.\n",
517 dev->name, inb(ioaddr + RX_MODE), status);
518#ifndef final_version
519 if (status == 0) {
520 outb(0x05, ioaddr + 14);
521 break;
522 }
523#endif
524
525 if ((status & 0xF0) != 0x20) { /* There was an error. */
526 lp->stats.rx_errors++;
527 if (status & 0x08) lp->stats.rx_length_errors++;
528 if (status & 0x04) lp->stats.rx_frame_errors++;
529 if (status & 0x02) lp->stats.rx_crc_errors++;
530 if (status & 0x01) lp->stats.rx_over_errors++;
531 } else {
532 ushort pkt_len = inw(ioaddr + DATAPORT);
533 /* Malloc up new buffer. */
534 struct sk_buff *skb;
535
536 if (pkt_len > 1550) {
537 printk("%s: The FMV-18x claimed a very large packet, size %d.\n",
538 dev->name, pkt_len);
539 outb(0x05, ioaddr + 14);
540 lp->stats.rx_errors++;
541 break;
542 }
543 skb = dev_alloc_skb(pkt_len+3);
544 if (skb == NULL) {
545 printk("%s: Memory squeeze, dropping packet (len %d).\n",
546 dev->name, pkt_len);
547 outb(0x05, ioaddr + 14);
548 lp->stats.rx_dropped++;
549 break;
550 }
551 skb->dev = dev;
552 skb_reserve(skb,2);
553
554 insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
555
556 if (net_debug > 5) {
557 int i;
558 printk("%s: Rxed packet of length %d: ", dev->name, pkt_len);
559 for (i = 0; i < 14; i++)
560 printk(" %02x", skb->data[i]);
561 printk(".\n");
562 }
563
564 skb->protocol=eth_type_trans(skb, dev);
565 netif_rx(skb);
566 dev->last_rx = jiffies;
567 lp->stats.rx_packets++;
568 lp->stats.rx_bytes += pkt_len;
569 }
570 if (--boguscount <= 0)
571 break;
572 }
573
574 /* If any worth-while packets have been received, dev_rint()
575 has done a mark_bh(NET_BH) for us and will work on them
576 when we get to the bottom-half routine. */
577 {
578 int i;
579 for (i = 0; i < 20; i++) {
580 if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
581 break;
582 (void)inw(ioaddr + DATAPORT); /* dummy status read */
583 outb(0x05, ioaddr + 14);
584 }
585
586 if (net_debug > 5 && i > 0)
587 printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
588 dev->name, inb(ioaddr + RX_MODE), i);
589 }
590
591 return;
592}
593
594/* The inverse routine to net_open(). */
595static int net_close(struct net_device *dev)
596{
597 int ioaddr = dev->base_addr;
598
599 ((struct net_local *)dev->priv)->open_time = 0;
600
601 netif_stop_queue(dev);
602
603 /* Set configuration register 0 to disable Tx and Rx. */
604 outb(0xda, ioaddr + CONFIG_0);
605
606 /* Update the statistics -- ToDo. */
607
608 /* Power-down the chip. Green, green, green! */
609 outb(0x00, ioaddr + CONFIG_1);
610
611 /* Set the ethernet adaptor disable IRQ */
612 outb(0x00, ioaddr + FJ_CONFIG1);
613
614 return 0;
615}
616
617/* Get the current statistics. This may be called with the card open or
618 closed. */
619static struct net_device_stats *net_get_stats(struct net_device *dev)
620{
621 struct net_local *lp = dev->priv;
622 return &lp->stats;
623}
624
625/* Set or clear the multicast filter for this adaptor.
626 num_addrs == -1 Promiscuous mode, receive all packets
627 num_addrs == 0 Normal mode, clear multicast list
628 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
629 best-effort filtering.
630 */
631
632static void set_multicast_list(struct net_device *dev)
633{
634 short ioaddr = dev->base_addr;
635 if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI))
636 {
637 /*
638 * We must make the kernel realise we had to move
639 * into promisc mode or we start all out war on
640 * the cable. - AC
641 */
642 dev->flags|=IFF_PROMISC;
643
644 outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
645 }
646 else
647 outb(2, ioaddr + RX_MODE); /* Disable promiscuous, use normal mode */
648}
649
650#ifdef MODULE
651static struct net_device *dev_fmv18x;
652
653MODULE_PARM(io, "i");
654MODULE_PARM(irq, "i");
655MODULE_PARM(net_debug, "i");
656MODULE_PARM_DESC(io, "FMV-18X I/O address");
657MODULE_PARM_DESC(irq, "FMV-18X IRQ number");
658MODULE_PARM_DESC(net_debug, "FMV-18X debug level (0-1,5-6)");
659MODULE_LICENSE("GPL");
660
661int init_module(void)
662{
663 if (io == 0)
664 printk("fmv18x: You should not use auto-probing with insmod!\n");
665 dev_fmv18x = fmv18x_probe(-1);
666 if (IS_ERR(dev_fmv18x))
667 return PTR_ERR(dev_fmv18x);
668 return 0;
669}
670
671void
672cleanup_module(void)
673{
674 unregister_netdev(dev_fmv18x);
675 free_irq(dev_fmv18x->irq, dev_fmv18x);
676 release_region(dev_fmv18x->base_addr, FMV18X_IO_EXTENT);
677 free_netdev(dev_fmv18x);
678}
679#endif /* MODULE */
680
681/*
682 * Local variables:
683 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c fmv18x.c"
684 * version-control: t
685 * kept-new-versions: 5
686 * tab-width: 4
687 * c-indent-level: 4
688 * End:
689 */