~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/net/fmv18x.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.