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