1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38#include <linux/config.h>
39#include <linux/module.h>
40
41#include <linux/kernel.h>
42#include <linux/sched.h>
43#include <linux/types.h>
44#include <linux/fcntl.h>
45#include <linux/interrupt.h>
46#include <linux/ioport.h>
47#include <linux/in.h>
48#include <linux/slab.h>
49#include <linux/string.h>
50#include <linux/init.h>
51#include <linux/crc32.h>
52#include <asm/system.h>
53#include <asm/bitops.h>
54#include <asm/io.h>
55#include <asm/dma.h>
56#include <linux/errno.h>
57
58#include <linux/netdevice.h>
59#include <linux/etherdevice.h>
60#include <linux/skbuff.h>
61
62#include <linux/mca.h>
63
64static char version[] __initdata =
65 "at1700.c:v1.15 4/7/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
66
67
68
69
70#define MC_FILTERBREAK 64
71
72
73
74static int fmv18x_probe_list[] __initdata = {
75 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
76};
77
78
79
80
81
82static int at1700_probe_list[] __initdata = {
83 0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
84};
85
86
87
88
89#ifdef CONFIG_MCA
90static int at1700_ioaddr_pattern[] __initdata = {
91 0x00, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07
92};
93
94static int at1700_mca_probe_list[] __initdata = {
95 0x400, 0x1400, 0x2400, 0x3400, 0x4400, 0x5400, 0x6400, 0x7400, 0
96};
97
98static int at1700_irq_pattern[] __initdata = {
99 0x00, 0x00, 0x00, 0x30, 0x70, 0xb0, 0x00, 0x00,
100 0x00, 0xf0, 0x34, 0x74, 0xb4, 0x00, 0x00, 0xf4, 0x00
101};
102#endif
103
104
105#ifndef NET_DEBUG
106#define NET_DEBUG 1
107#endif
108static unsigned int net_debug = NET_DEBUG;
109
110typedef unsigned char uchar;
111
112
113struct net_local {
114 struct net_device_stats stats;
115 spinlock_t lock;
116 unsigned char mc_filter[8];
117 uint jumpered:1;
118 uint tx_started:1;
119 uint tx_queue_ready:1;
120 uint rx_started:1;
121 uchar tx_queue;
122 char mca_slot;
123 ushort tx_queue_len;
124};
125
126
127
128#define STATUS 0
129#define TX_STATUS 0
130#define RX_STATUS 1
131#define TX_INTR 2
132#define RX_INTR 3
133#define TX_MODE 4
134#define RX_MODE 5
135#define CONFIG_0 6
136#define CONFIG_1 7
137
138#define DATAPORT 8
139#define TX_START 10
140#define COL16CNTL 11
141#define MODE13 13
142
143#define EEPROM_Ctrl 16
144#define EEPROM_Data 17
145#define CARDSTATUS 16
146#define CARDSTATUS1 17
147#define IOCONFIG 18
148#define IOCONFIG1 19
149#define SAPROM 20
150#define RESET 31
151#define AT1700_IO_EXTENT 32
152
153#define TX_TIMEOUT 10
154
155
156
157
158extern int at1700_probe(struct net_device *dev);
159
160static int at1700_probe1(struct net_device *dev, int ioaddr);
161static int read_eeprom(long ioaddr, int location);
162static int net_open(struct net_device *dev);
163static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
164static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
165static void net_rx(struct net_device *dev);
166static int net_close(struct net_device *dev);
167static struct net_device_stats *net_get_stats(struct net_device *dev);
168static void set_rx_mode(struct net_device *dev);
169static void net_tx_timeout (struct net_device *dev);
170
171
172#ifdef CONFIG_MCA
173struct at1720_mca_adapters_struct {
174 char* name;
175 int id;
176};
177
178
179static struct at1720_mca_adapters_struct at1720_mca_adapters[] __initdata = {
180 { "Allied Telesys AT1720AT", 0x6410 },
181 { "Allied Telesys AT1720BT", 0x6413 },
182 { "Allied Telesys AT1720T", 0x6416 },
183 { NULL, 0 },
184};
185#endif
186
187
188
189
190
191
192
193
194int __init at1700_probe(struct net_device *dev)
195{
196 int i;
197 int base_addr = dev->base_addr;
198
199 SET_MODULE_OWNER(dev);
200
201 if (base_addr > 0x1ff)
202 return at1700_probe1(dev, base_addr);
203 else if (base_addr != 0)
204 return -ENXIO;
205
206 for (i = 0; at1700_probe_list[i]; i++) {
207 int ioaddr = at1700_probe_list[i];
208 if (at1700_probe1(dev, ioaddr) == 0)
209 return 0;
210 }
211 return -ENODEV;
212}
213
214
215
216
217
218
219
220
221
222static int __init at1700_probe1(struct net_device *dev, int ioaddr)
223{
224 char fmv_irqmap[4] = {3, 7, 10, 15};
225 char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
226 char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
227 unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
228 int slot, ret = -ENODEV;
229 struct net_local *lp;
230
231 if (!request_region(ioaddr, AT1700_IO_EXTENT, dev->name))
232 return -EBUSY;
233
234
235
236
237#ifdef notdef
238 printk("at1700 probe at %#x, eeprom is %4.4x %4.4x %4.4x ctrl %4.4x.\n",
239 ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
240 read_eeprom(ioaddr, 6), inw(ioaddr + EEPROM_Ctrl));
241#endif
242
243#ifdef CONFIG_MCA
244
245
246
247
248
249
250
251
252
253 if (MCA_bus) {
254 int j;
255 int l_i;
256 u_char pos3, pos4;
257
258 for (j = 0; at1720_mca_adapters[j].name != NULL; j ++) {
259 slot = 0;
260 while (slot != MCA_NOTFOUND) {
261
262 slot = mca_find_unused_adapter( at1720_mca_adapters[j].id, slot );
263 if (slot == MCA_NOTFOUND) break;
264
265
266
267
268 pos3 = mca_read_stored_pos( slot, 3 );
269 pos4 = mca_read_stored_pos( slot, 4 );
270
271 for (l_i = 0; l_i < 0x09; l_i++)
272 if (( pos3 & 0x07) == at1700_ioaddr_pattern[l_i])
273 break;
274 ioaddr = at1700_mca_probe_list[l_i];
275
276 for (irq = 0; irq < 0x10; irq++)
277 if (((((pos4>>4) & 0x0f) | (pos3 & 0xf0)) & 0xff) == at1700_irq_pattern[irq])
278 break;
279
280
281 if (dev &&
282 ((dev->irq && dev->irq != irq) ||
283 (dev->base_addr && dev->base_addr != ioaddr))) {
284 slot++;
285 continue;
286 }
287
288 if (dev)
289 dev->irq = irq;
290
291
292 mca_set_adapter_name( slot, at1720_mca_adapters[j].name );
293 mca_mark_as_used(slot);
294
295 goto found;
296 }
297 }
298
299 }
300#endif
301 slot = -1;
302
303
304 if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr
305 && read_eeprom(ioaddr, 4) == 0x0000
306 && (read_eeprom(ioaddr, 5) & 0xff00) == 0xF400)
307 is_at1700 = 1;
308 else if (inb(ioaddr + SAPROM ) == 0x00
309 && inb(ioaddr + SAPROM + 1) == 0x00
310 && inb(ioaddr + SAPROM + 2) == 0x0e)
311 is_fmv18x = 1;
312 else {
313 goto err_out;
314 }
315
316#ifdef CONFIG_MCA
317found:
318#endif
319
320
321 outb(0, ioaddr + RESET);
322
323 if (is_at1700)
324 irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
325 | (read_eeprom(ioaddr, 0)>>14)];
326 else {
327
328
329 if (inb(ioaddr + CARDSTATUS1) & 0x20) {
330 irq = dev->irq;
331 for (i = 0; i < 8; i++) {
332 if (irq == fmv_irqmap_pnp[i])
333 break;
334 }
335 if (i == 8) {
336 goto err_out;
337 }
338 } else {
339 if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr)
340 goto err_out;
341 irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
342 }
343 }
344
345 printk("%s: %s found at %#3x, IRQ %d, address ", dev->name,
346 is_at1700 ? "AT1700" : "FMV-18X", ioaddr, irq);
347
348 dev->base_addr = ioaddr;
349 dev->irq = irq;
350
351 if (is_at1700) {
352 for(i = 0; i < 3; i++) {
353 unsigned short eeprom_val = read_eeprom(ioaddr, 4+i);
354 printk("%04x", eeprom_val);
355 ((unsigned short *)dev->dev_addr)[i] = ntohs(eeprom_val);
356 }
357 } else {
358 for(i = 0; i < 6; i++) {
359 unsigned char val = inb(ioaddr + SAPROM + i);
360 printk("%02x", val);
361 dev->dev_addr[i] = val;
362 }
363 }
364
365
366
367
368
369
370
371 {
372 const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2"};
373 if (is_at1700) {
374 ushort setup_value = read_eeprom(ioaddr, 12);
375 dev->if_port = setup_value >> 8;
376 } else {
377 ushort setup_value = inb(ioaddr + CARDSTATUS);
378 switch (setup_value & 0x07) {
379 case 0x01:
380 case 0x02:
381 dev->if_port = 0x18; break;
382 case 0x04:
383 dev->if_port = 0x08; break;
384 default:
385 dev->if_port = 0x00; break;
386 }
387 }
388 printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
389 }
390
391
392
393 outb(0xda, ioaddr + CONFIG_0);
394
395
396 outb(0x00, ioaddr + CONFIG_1);
397 for (i = 0; i < 6; i++)
398 outb(dev->dev_addr[i], ioaddr + 8 + i);
399
400
401 outb(0x04, ioaddr + CONFIG_1);
402 for (i = 0; i < 8; i++)
403 outb(0x00, ioaddr + 8 + i);
404
405
406
407
408 outb(0x08, ioaddr + CONFIG_1);
409 outb(dev->if_port, ioaddr + MODE13);
410 outb(0x00, ioaddr + COL16CNTL);
411
412 if (net_debug)
413 printk(version);
414
415
416 dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
417 if (dev->priv == NULL) {
418 ret = -ENOMEM;
419 goto err_out;
420 }
421 memset(dev->priv, 0, sizeof(struct net_local));
422
423 dev->open = net_open;
424 dev->stop = net_close;
425 dev->hard_start_xmit = net_send_packet;
426 dev->get_stats = net_get_stats;
427 dev->set_multicast_list = &set_rx_mode;
428 dev->tx_timeout = net_tx_timeout;
429 dev->watchdog_timeo = TX_TIMEOUT;
430
431 lp = (struct net_local *)dev->priv;
432 lp->lock = SPIN_LOCK_UNLOCKED;
433
434
435 ether_setup(dev);
436
437 lp->jumpered = is_fmv18x;
438 lp->mca_slot = slot;
439
440 ret = request_irq(irq, &net_interrupt, 0, dev->name, dev);
441 if (ret) {
442 printk (" AT1700 at %#3x is unusable due to a conflict on"
443 "IRQ %d.\n", ioaddr, irq);
444 goto err_out_priv;
445 }
446
447 return 0;
448
449err_out_priv:
450 kfree(dev->priv);
451 dev->priv = NULL;
452err_out:
453 release_region(ioaddr, AT1700_IO_EXTENT);
454 return ret;
455}
456
457
458
459#define EE_SHIFT_CLK 0x40
460#define EE_CS 0x20
461#define EE_DATA_WRITE 0x80
462#define EE_DATA_READ 0x80
463
464
465#define eeprom_delay() do { } while (0)
466
467
468#define EE_WRITE_CMD (5 << 6)
469#define EE_READ_CMD (6 << 6)
470#define EE_ERASE_CMD (7 << 6)
471
472static int __init read_eeprom(long ioaddr, int location)
473{
474 int i;
475 unsigned short retval = 0;
476 long ee_addr = ioaddr + EEPROM_Ctrl;
477 long ee_daddr = ioaddr + EEPROM_Data;
478 int read_cmd = location | EE_READ_CMD;
479
480
481 for (i = 9; i >= 0; i--) {
482 short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
483 outb(EE_CS, ee_addr);
484 outb(dataval, ee_daddr);
485 eeprom_delay();
486 outb(EE_CS | EE_SHIFT_CLK, ee_addr);
487 eeprom_delay();
488 }
489 outb(EE_DATA_WRITE, ee_daddr);
490 for (i = 16; i > 0; i--) {
491 outb(EE_CS, ee_addr);
492 eeprom_delay();
493 outb(EE_CS | EE_SHIFT_CLK, ee_addr);
494 eeprom_delay();
495 retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
496 }
497
498
499 outb(EE_CS, ee_addr);
500 eeprom_delay();
501 outb(EE_SHIFT_CLK, ee_addr);
502 outb(0, ee_addr);
503 return retval;
504}
505
506
507
508static int net_open(struct net_device *dev)
509{
510 struct net_local *lp = (struct net_local *)dev->priv;
511 int ioaddr = dev->base_addr;
512
513
514
515 outb(0x5a, ioaddr + CONFIG_0);
516
517
518 outb(0xe8, ioaddr + CONFIG_1);
519
520 lp->tx_started = 0;
521 lp->tx_queue_ready = 1;
522 lp->rx_started = 0;
523 lp->tx_queue = 0;
524 lp->tx_queue_len = 0;
525
526
527 outb(0x82, ioaddr + TX_INTR);
528 outb(0x81, ioaddr + RX_INTR);
529
530
531 if (lp->jumpered) {
532 outb(0x80, ioaddr + IOCONFIG1);
533 }
534
535 netif_start_queue(dev);
536 return 0;
537}
538
539static void net_tx_timeout (struct net_device *dev)
540{
541 struct net_local *lp = (struct net_local *)dev->priv;
542 int ioaddr = dev->base_addr;
543
544 printk ("%s: transmit timed out with status %04x, %s?\n", dev->name,
545 inw (ioaddr + STATUS), inb (ioaddr + TX_STATUS) & 0x80
546 ? "IRQ conflict" : "network cable problem");
547 printk ("%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
548 dev->name, inw (ioaddr + 0), inw (ioaddr + 2), inw (ioaddr + 4),
549 inw (ioaddr + 6), inw (ioaddr + 8), inw (ioaddr + 10),
550 inw (ioaddr + 12), inw (ioaddr + 14));
551 lp->stats.tx_errors++;
552
553 outw (0xffff, ioaddr + 24);
554 outw (0xffff, ioaddr + TX_STATUS);
555 outb (0x5a, ioaddr + CONFIG_0);
556 outb (0xe8, ioaddr + CONFIG_1);
557 outw (0x8182, ioaddr + TX_INTR);
558 outb (0x00, ioaddr + TX_START);
559 outb (0x03, ioaddr + COL16CNTL);
560
561 dev->trans_start = jiffies;
562
563 lp->tx_started = 0;
564 lp->tx_queue_ready = 1;
565 lp->rx_started = 0;
566 lp->tx_queue = 0;
567 lp->tx_queue_len = 0;
568
569 netif_wake_queue(dev);
570}
571
572
573static int net_send_packet (struct sk_buff *skb, struct net_device *dev)
574{
575 struct net_local *lp = (struct net_local *) dev->priv;
576 int ioaddr = dev->base_addr;
577 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
578 unsigned char *buf = skb->data;
579
580 netif_stop_queue (dev);
581
582
583
584
585
586
587 lp->tx_queue_ready = 0;
588 {
589 outw (length, ioaddr + DATAPORT);
590 outsw (ioaddr + DATAPORT, buf, (length + 1) >> 1);
591
592 lp->tx_queue++;
593 lp->tx_queue_len += length + 2;
594 }
595 lp->tx_queue_ready = 1;
596
597 if (lp->tx_started == 0) {
598
599 outb (0x80 | lp->tx_queue, ioaddr + TX_START);
600 lp->tx_queue = 0;
601 lp->tx_queue_len = 0;
602 dev->trans_start = jiffies;
603 lp->tx_started = 1;
604 netif_start_queue (dev);
605 } else if (lp->tx_queue_len < 4096 - 1502)
606
607 netif_start_queue (dev);
608 dev_kfree_skb (skb);
609
610 return 0;
611}
612
613
614
615static void
616net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
617{
618 struct net_device *dev = dev_id;
619 struct net_local *lp;
620 int ioaddr, status;
621
622 if (dev == NULL) {
623 printk ("at1700_interrupt(): irq %d for unknown device.\n", irq);
624 return;
625 }
626
627 ioaddr = dev->base_addr;
628 lp = (struct net_local *)dev->priv;
629
630 spin_lock (&lp->lock);
631
632 status = inw(ioaddr + TX_STATUS);
633 outw(status, ioaddr + TX_STATUS);
634
635 if (net_debug > 4)
636 printk("%s: Interrupt with status %04x.\n", dev->name, status);
637 if (lp->rx_started == 0 &&
638 (status & 0xff00 || (inb(ioaddr + RX_MODE) & 0x40) == 0)) {
639
640
641
642
643
644
645 lp->rx_started = 1;
646 outb(0x00, ioaddr + RX_INTR);
647 net_rx(dev);
648 outb(0x81, ioaddr + RX_INTR);
649 lp->rx_started = 0;
650 }
651 if (status & 0x00ff) {
652 if (status & 0x02) {
653
654 if (net_debug > 4)
655 printk("%s: 16 Collision occur during Txing.\n", dev->name);
656
657 outb(0x03, ioaddr + COL16CNTL);
658 lp->stats.collisions++;
659 }
660 if (status & 0x82) {
661 lp->stats.tx_packets++;
662
663
664
665 if (lp->tx_queue && lp->tx_queue_ready) {
666 outb(0x80 | lp->tx_queue, ioaddr + TX_START);
667 lp->tx_queue = 0;
668 lp->tx_queue_len = 0;
669 dev->trans_start = jiffies;
670 netif_wake_queue (dev);
671 } else {
672 lp->tx_started = 0;
673 netif_wake_queue (dev);
674 }
675 }
676 }
677
678 spin_unlock (&lp->lock);
679 return;
680}
681
682
683static void
684net_rx(struct net_device *dev)
685{
686 struct net_local *lp = (struct net_local *)dev->priv;
687 int ioaddr = dev->base_addr;
688 int boguscount = 5;
689
690 while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
691 ushort status = inw(ioaddr + DATAPORT);
692 ushort pkt_len = inw(ioaddr + DATAPORT);
693
694 if (net_debug > 4)
695 printk("%s: Rxing packet mode %02x status %04x.\n",
696 dev->name, inb(ioaddr + RX_MODE), status);
697#ifndef final_version
698 if (status == 0) {
699 outb(0x05, ioaddr + 14);
700 break;
701 }
702#endif
703
704 if ((status & 0xF0) != 0x20) {
705 lp->stats.rx_errors++;
706 if (status & 0x08) lp->stats.rx_length_errors++;
707 if (status & 0x04) lp->stats.rx_frame_errors++;
708 if (status & 0x02) lp->stats.rx_crc_errors++;
709 if (status & 0x01) lp->stats.rx_over_errors++;
710 } else {
711
712 struct sk_buff *skb;
713
714 if (pkt_len > 1550) {
715 printk("%s: The AT1700 claimed a very large packet, size %d.\n",
716 dev->name, pkt_len);
717
718 inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
719 outb(0x05, ioaddr + 14);
720 lp->stats.rx_errors++;
721 break;
722 }
723 skb = dev_alloc_skb(pkt_len+3);
724 if (skb == NULL) {
725 printk("%s: Memory squeeze, dropping packet (len %d).\n",
726 dev->name, pkt_len);
727
728 inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
729 outb(0x05, ioaddr + 14);
730 lp->stats.rx_dropped++;
731 break;
732 }
733 skb->dev = dev;
734 skb_reserve(skb,2);
735
736 insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
737 skb->protocol=eth_type_trans(skb, dev);
738 netif_rx(skb);
739 dev->last_rx = jiffies;
740 lp->stats.rx_packets++;
741 lp->stats.rx_bytes += pkt_len;
742 }
743 if (--boguscount <= 0)
744 break;
745 }
746
747
748
749
750 {
751 int i;
752 for (i = 0; i < 20; i++) {
753 if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
754 break;
755 inw(ioaddr + DATAPORT);
756 outb(0x05, ioaddr + 14);
757 }
758
759 if (net_debug > 5)
760 printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
761 dev->name, inb(ioaddr + RX_MODE), i);
762 }
763 return;
764}
765
766
767static int net_close(struct net_device *dev)
768{
769 struct net_local *lp = (struct net_local *)dev->priv;
770 int ioaddr = dev->base_addr;
771
772 netif_stop_queue(dev);
773
774
775 outb(0xda, ioaddr + CONFIG_0);
776
777
778
779
780 if (lp->jumpered) {
781 outb(0x00, ioaddr + IOCONFIG1);
782 free_irq(dev->irq, dev);
783 }
784
785
786 outb(0x00, ioaddr + CONFIG_1);
787 return 0;
788}
789
790
791
792
793
794static struct net_device_stats *
795net_get_stats(struct net_device *dev)
796{
797 struct net_local *lp = (struct net_local *)dev->priv;
798 return &lp->stats;
799}
800
801
802
803
804
805static void
806set_rx_mode(struct net_device *dev)
807{
808 int ioaddr = dev->base_addr;
809 struct net_local *lp = (struct net_local *)dev->priv;
810 unsigned char mc_filter[8];
811 unsigned long flags;
812 int i;
813
814 if (dev->flags & IFF_PROMISC) {
815
816 printk("%s: Promiscuous mode enabled.\n", dev->name);
817 memset(mc_filter, 0xff, sizeof(mc_filter));
818 outb(3, ioaddr + RX_MODE);
819 } else if (dev->mc_count > MC_FILTERBREAK
820 || (dev->flags & IFF_ALLMULTI)) {
821
822 memset(mc_filter, 0xff, sizeof(mc_filter));
823 outb(2, ioaddr + RX_MODE);
824 } else if (dev->mc_count == 0) {
825 memset(mc_filter, 0x00, sizeof(mc_filter));
826 outb(1, ioaddr + RX_MODE);
827 } else {
828 struct dev_mc_list *mclist;
829 int i;
830
831 memset(mc_filter, 0, sizeof(mc_filter));
832 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
833 i++, mclist = mclist->next)
834 set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26,
835 mc_filter);
836 outb(0x02, ioaddr + RX_MODE);
837 }
838
839 save_flags(flags);
840 cli();
841 if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
842 int saved_bank = inw(ioaddr + CONFIG_0);
843
844 outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
845 for (i = 0; i < 8; i++)
846 outb(mc_filter[i], ioaddr + 8 + i);
847 memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
848 outw(saved_bank, ioaddr + CONFIG_0);
849 }
850 restore_flags(flags);
851 return;
852}
853
854#ifdef MODULE
855static struct net_device dev_at1700;
856static int io = 0x260;
857static int irq;
858
859MODULE_PARM(io, "i");
860MODULE_PARM(irq, "i");
861MODULE_PARM(net_debug, "i");
862MODULE_PARM_DESC(io, "AT1700/FMV18X I/O base address");
863MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number");
864MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)");
865
866int init_module(void)
867{
868 if (io == 0)
869 printk("at1700: You should not use auto-probing with insmod!\n");
870 dev_at1700.base_addr = io;
871 dev_at1700.irq = irq;
872 dev_at1700.init = at1700_probe;
873 if (register_netdev(&dev_at1700) != 0) {
874 printk("at1700: register_netdev() returned non-zero.\n");
875 return -EIO;
876 }
877 return 0;
878}
879
880void
881cleanup_module(void)
882{
883#ifdef CONFIG_MCA
884 struct net_local *lp = dev_at1700.priv;
885 if(lp->mca_slot)
886 {
887 mca_mark_as_unused(lp->mca_slot);
888 }
889#endif
890 unregister_netdev(&dev_at1700);
891 kfree(dev_at1700.priv);
892 dev_at1700.priv = NULL;
893
894
895 free_irq(dev_at1700.irq, NULL);
896 release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
897}
898#endif
899MODULE_LICENSE("GPL");
900
901
902
903
904
905
906
907
908
909
910
911
912