This source file includes following definitions.
- lance_init
- lance_probe1
- lance_open
- lance_init_ring
- lance_start_xmit
- lance_interrupt
- lance_rx
- lance_close
- lance_get_stats
- set_multicast_list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 static char *version = "lance.c:v0.14g 12/21/93 becker@super.org\n";
18
19 #include <linux/config.h>
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/string.h>
23 #include <linux/ptrace.h>
24 #include <linux/errno.h>
25 #include <linux/ioport.h>
26 #include <linux/malloc.h>
27 #include <linux/interrupt.h>
28 #include <asm/bitops.h>
29 #include <asm/io.h>
30 #include <asm/dma.h>
31
32 #include <linux/netdevice.h>
33 #include <linux/etherdevice.h>
34 #include <linux/skbuff.h>
35
36 #ifndef HAVE_PORTRESERVE
37 #define check_region(addr, size) 0
38 #define snarf_region(addr, size) do ; while(0)
39 #endif
40
41 struct device *init_etherdev(struct device *dev, int sizeof_private,
42 unsigned long *mem_startp);
43
44 #ifdef LANCE_DEBUG
45 int lance_debug = LANCE_DEBUG;
46 #else
47 int lance_debug = 1;
48 #endif
49
50 #ifndef LANCE_DMA
51 #define LANCE_DMA 5
52 #endif
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 #ifndef LANCE_LOG_TX_BUFFERS
141 #define LANCE_LOG_TX_BUFFERS 4
142 #define LANCE_LOG_RX_BUFFERS 4
143 #endif
144
145 #define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS))
146 #define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
147 #define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
148
149 #define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
150 #define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
151 #define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
152
153 #define PKT_BUF_SZ 1544
154
155
156 #define LANCE_DATA 0x10
157 #define LANCE_ADDR 0x12
158 #define LANCE_RESET 0x14
159 #define LANCE_BUS_IF 0x16
160 #define LANCE_TOTAL_SIZE 0x18
161
162
163 struct lance_rx_head {
164 int base;
165 short buf_length;
166 short msg_length;
167 };
168
169 struct lance_tx_head {
170 int base;
171 short length;
172 short misc;
173 };
174
175
176 struct lance_init_block {
177 unsigned short mode;
178 unsigned char phys_addr[6];
179 unsigned filter[2];
180
181 unsigned rx_ring;
182 unsigned tx_ring;
183 };
184
185 struct lance_private {
186 char devname[8];
187
188 struct lance_rx_head rx_ring[RX_RING_SIZE];
189 struct lance_tx_head tx_ring[TX_RING_SIZE];
190 struct lance_init_block init_block;
191 long rx_buffs;
192
193 char (*tx_bounce_buffs)[PKT_BUF_SZ];
194 int cur_rx, cur_tx;
195 int dirty_rx, dirty_tx;
196 int dma;
197 struct enet_statistics stats;
198 char old_lance;
199 char lock;
200 int pad0, pad1;
201 };
202
203 unsigned long lance_probe1(short ioaddr, unsigned long mem_start);
204 static int lance_open(struct device *dev);
205 static void lance_init_ring(struct device *dev);
206 static int lance_start_xmit(struct sk_buff *skb, struct device *dev);
207 static int lance_rx(struct device *dev);
208 static void lance_interrupt(int reg_ptr);
209 static int lance_close(struct device *dev);
210 static struct enet_statistics *lance_get_stats(struct device *dev);
211 #ifdef HAVE_MULTICAST
212 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
213 #endif
214
215
216
217 unsigned long lance_init(unsigned long mem_start, unsigned long mem_end)
218 {
219 int *port, ports[] = {0x300, 0x320, 0x340, 0x360, 0};
220
221 for (port = &ports[0]; *port; port++) {
222 int ioaddr = *port;
223
224 if ( check_region(ioaddr, LANCE_TOTAL_SIZE) == 0
225 && inb(ioaddr + 14) == 0x57
226 && inb(ioaddr + 15) == 0x57) {
227 mem_start = lance_probe1(ioaddr, mem_start);
228 }
229 }
230
231 return mem_start;
232 }
233
234 unsigned long lance_probe1(short ioaddr, unsigned long mem_start)
235 {
236 struct device *dev;
237 struct lance_private *lp;
238 int hpJ2405A = 0;
239 int i, reset_val;
240
241 hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00
242 && inb(ioaddr+2) == 0x09);
243
244
245 reset_val = inw(ioaddr+LANCE_RESET);
246
247
248
249 if (!hpJ2405A)
250 outw(reset_val, ioaddr+LANCE_RESET);
251
252 outw(0x0000, ioaddr+LANCE_ADDR);
253 if (inw(ioaddr+LANCE_DATA) != 0x0004)
254 return mem_start;
255
256 dev = init_etherdev(0, sizeof(struct lance_private)
257 + PKT_BUF_SZ*(RX_RING_SIZE + TX_RING_SIZE),
258 &mem_start);
259
260 printk("%s: LANCE at %#3x,", dev->name, ioaddr);
261
262
263
264 for (i = 0; i < 6; i++)
265 printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
266
267 dev->base_addr = ioaddr;
268 snarf_region(ioaddr, LANCE_TOTAL_SIZE);
269
270
271 dev->priv = (void *)(((int)dev->priv + 7) & ~7);
272 lp = (struct lance_private *)dev->priv;
273 lp->rx_buffs = (long)dev->priv + sizeof(struct lance_private);
274 lp->tx_bounce_buffs = (char (*)[PKT_BUF_SZ])
275 (lp->rx_buffs + PKT_BUF_SZ*RX_RING_SIZE);
276
277 #ifndef final_version
278
279 if ((int)(lp->rx_ring) & 0x07) {
280 printk(" **ERROR** LANCE Rx and Tx rings not on even boundary.\n");
281 return mem_start;
282 }
283 #endif
284
285 outw(88, ioaddr+LANCE_ADDR);
286 lp->old_lance = (inw(ioaddr+LANCE_DATA) != 0x3003);
287
288 #if defined(notdef)
289 printk(lp->old_lance ? " original LANCE (%04x)" : " PCnet-ISA LANCE (%04x)",
290 inw(ioaddr+LANCE_DATA));
291 #endif
292
293 lp->init_block.mode = 0x0003;
294 for (i = 0; i < 6; i++)
295 lp->init_block.phys_addr[i] = dev->dev_addr[i];
296 lp->init_block.filter[0] = 0x00000000;
297 lp->init_block.filter[1] = 0x00000000;
298 lp->init_block.rx_ring = (int)lp->rx_ring | RX_RING_LEN_BITS;
299 lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
300
301 outw(0x0001, ioaddr+LANCE_ADDR);
302 outw((short) (int) &lp->init_block, ioaddr+LANCE_DATA);
303 outw(0x0002, ioaddr+LANCE_ADDR);
304 outw(((int)&lp->init_block) >> 16, ioaddr+LANCE_DATA);
305 outw(0x0000, ioaddr+LANCE_ADDR);
306
307 if (hpJ2405A) {
308 char dma_tbl[4] = {3, 5, 6, 7};
309 char irq_tbl[8] = {3, 4, 5, 9, 10, 11, 12, 15};
310 short reset_val = inw(ioaddr+LANCE_RESET);
311 dev->dma = dma_tbl[(reset_val >> 2) & 3];
312 dev->irq = irq_tbl[(reset_val >> 4) & 7];
313 printk(" HP J2405A IRQ %d DMA %d.\n", dev->irq, dev->dma);
314 } else {
315
316 if (dev->mem_start & 0x07)
317 dev->dma = dev->mem_start & 0x07;
318 else if (dev->dma == 0)
319 dev->dma = LANCE_DMA;
320
321
322
323 if (dev->irq < 2) {
324
325 autoirq_setup(0);
326
327
328 outw(0x0041, ioaddr+LANCE_DATA);
329
330 dev->irq = autoirq_report(1);
331 if (dev->irq)
332 printk(", probed IRQ %d, fixed at DMA %d.\n",
333 dev->irq, dev->dma);
334 else {
335 printk(", failed to detect IRQ line.\n");
336 return mem_start;
337 }
338 } else
339 printk(" assigned IRQ %d DMA %d.\n", dev->irq, dev->dma);
340 }
341
342 if (! lp->old_lance) {
343
344
345 outw(0x0002, ioaddr+LANCE_ADDR);
346 outw(0x0002, ioaddr+LANCE_BUS_IF);
347 }
348
349 if (lance_debug > 0)
350 printk(version);
351
352
353 dev->open = &lance_open;
354 dev->hard_start_xmit = &lance_start_xmit;
355 dev->stop = &lance_close;
356 dev->get_stats = &lance_get_stats;
357 dev->set_multicast_list = &set_multicast_list;
358
359 return mem_start;
360 }
361
362
363 static int
364 lance_open(struct device *dev)
365 {
366 struct lance_private *lp = (struct lance_private *)dev->priv;
367 int ioaddr = dev->base_addr;
368 int i;
369
370 if (request_irq(dev->irq, &lance_interrupt)) {
371 return -EAGAIN;
372 }
373
374 if (request_dma(dev->dma)) {
375 free_irq(dev->irq);
376 return -EAGAIN;
377 }
378 irq2dev_map[dev->irq] = dev;
379
380
381 inw(ioaddr+LANCE_RESET);
382
383
384 enable_dma(dev->dma);
385 set_dma_mode(dev->dma, DMA_MODE_CASCADE);
386
387
388 if (lp->old_lance)
389 outw(0, ioaddr+LANCE_RESET);
390
391 if (! lp->old_lance) {
392
393 outw(0x0002, ioaddr+LANCE_ADDR);
394 outw(0x0002, ioaddr+LANCE_BUS_IF);
395 }
396
397 if (lance_debug > 1)
398 printk("%s: lance_open() irq %d dma %d tx/rx rings %#x/%#x init %#x.\n",
399 dev->name, dev->irq, dev->dma, (int) lp->tx_ring, (int) lp->rx_ring,
400 (int) &lp->init_block);
401
402 lance_init_ring(dev);
403
404 outw(0x0001, ioaddr+LANCE_ADDR);
405 outw((short) (int) &lp->init_block, ioaddr+LANCE_DATA);
406 outw(0x0002, ioaddr+LANCE_ADDR);
407 outw(((int)&lp->init_block) >> 16, ioaddr+LANCE_DATA);
408
409 outw(0x0004, ioaddr+LANCE_ADDR);
410 outw(0x0d15, ioaddr+LANCE_DATA);
411
412 outw(0x0000, ioaddr+LANCE_ADDR);
413 outw(0x0001, ioaddr+LANCE_DATA);
414
415 dev->tbusy = 0;
416 dev->interrupt = 0;
417 dev->start = 1;
418 i = 0;
419 while (i++ < 100)
420 if (inw(ioaddr+LANCE_DATA) & 0x0100)
421 break;
422 outw(0x0142, ioaddr+LANCE_DATA);
423
424 if (lance_debug > 2)
425 printk("%s: LANCE open after %d ticks, init block %#x csr0 %4.4x.\n",
426 dev->name, i, (int) &lp->init_block, inw(ioaddr+LANCE_DATA));
427
428 return 0;
429 }
430
431
432 static void
433 lance_init_ring(struct device *dev)
434 {
435 struct lance_private *lp = (struct lance_private *)dev->priv;
436 int i;
437
438 lp->lock = 0;
439 lp->cur_rx = lp->cur_tx = 0;
440 lp->dirty_rx = lp->dirty_tx = 0;
441
442 for (i = 0; i < RX_RING_SIZE; i++) {
443 lp->rx_ring[i].base = (lp->rx_buffs + i*PKT_BUF_SZ) | 0x80000000;
444 lp->rx_ring[i].buf_length = -PKT_BUF_SZ;
445 }
446
447
448 for (i = 0; i < TX_RING_SIZE; i++) {
449 lp->tx_ring[i].base = 0;
450 }
451
452 lp->init_block.mode = 0x0000;
453 for (i = 0; i < 6; i++)
454 lp->init_block.phys_addr[i] = dev->dev_addr[i];
455 lp->init_block.filter[0] = 0x00000000;
456 lp->init_block.filter[1] = 0x00000000;
457 lp->init_block.rx_ring = (int)lp->rx_ring | RX_RING_LEN_BITS;
458 lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
459 }
460
461 static int
462 lance_start_xmit(struct sk_buff *skb, struct device *dev)
463 {
464 struct lance_private *lp = (struct lance_private *)dev->priv;
465 int ioaddr = dev->base_addr;
466 int entry;
467
468
469 if (dev->tbusy) {
470 int tickssofar = jiffies - dev->trans_start;
471 if (tickssofar < 10)
472 return 1;
473 outw(0, ioaddr+LANCE_ADDR);
474 printk("%s: transmit timed out, status %4.4x, resetting.\n",
475 dev->name, inw(ioaddr+LANCE_DATA));
476 outw(0x0001, ioaddr+LANCE_DATA);
477 lp->stats.tx_errors++;
478 #ifndef final_version
479 {
480 int i;
481 printk(" Ring data dump: dirty_tx %d cur_tx %d cur_rx %d.",
482 lp->dirty_tx, lp->cur_tx, lp->cur_rx);
483 for (i = 0 ; i < RX_RING_SIZE; i++)
484 printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
485 lp->rx_ring[i].base, -lp->rx_ring[i].buf_length,
486 lp->rx_ring[i].msg_length);
487 for (i = 0 ; i < TX_RING_SIZE; i++)
488 printk(" %s%08x %04x %04x", i & 0x3 ? "" : "\n ",
489 lp->tx_ring[i].base, -lp->tx_ring[i].length,
490 lp->tx_ring[i].misc);
491 printk("\n");
492 }
493 #endif
494 lance_init_ring(dev);
495 outw(0x0043, ioaddr+LANCE_DATA);
496
497 dev->tbusy=0;
498 dev->trans_start = jiffies;
499
500 return 0;
501 }
502
503 if (skb == NULL) {
504 dev_tint(dev);
505 return 0;
506 }
507
508 if (skb->len <= 0)
509 return 0;
510
511 if (lance_debug > 3) {
512 outw(0x0000, ioaddr+LANCE_ADDR);
513 printk("%s: lance_start_xmit() called, csr0 %4.4x.\n", dev->name,
514 inw(ioaddr+LANCE_DATA));
515 outw(0x0000, ioaddr+LANCE_DATA);
516 }
517
518
519
520 if (set_bit(0, (void*)&dev->tbusy) != 0) {
521 printk("%s: Transmitter access conflict.\n", dev->name);
522 return 1;
523 }
524
525 if (set_bit(0, (void*)&lp->lock) != 0) {
526 if (lance_debug > 2)
527 printk("%s: tx queue lock!.\n", dev->name);
528
529 return 1;
530 }
531
532
533
534
535 entry = lp->cur_tx & TX_RING_MOD_MASK;
536
537
538
539
540
541 if (lp->old_lance) {
542 lp->tx_ring[entry].length =
543 -(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
544 } else
545 lp->tx_ring[entry].length = -skb->len;
546
547 lp->tx_ring[entry].misc = 0x0000;
548
549
550
551 if ((int)(skb->data) + skb->len > 0x01000000) {
552 if (lance_debug > 5)
553 printk("%s: bouncing a high-memory packet (%#x).\n",
554 dev->name, (int)(skb->data));
555 memcpy(&lp->tx_bounce_buffs[entry], skb->data, skb->len);
556 lp->tx_ring[entry].base =
557 (int)(lp->tx_bounce_buffs + entry) | 0x83000000;
558 dev_kfree_skb (skb, FREE_WRITE);
559 } else {
560 lp->tx_ring[entry].base = (int)(skb->data) | 0x83000000;
561 }
562 lp->cur_tx++;
563
564
565 outw(0x0000, ioaddr+LANCE_ADDR);
566 outw(0x0048, ioaddr+LANCE_DATA);
567
568 dev->trans_start = jiffies;
569
570 cli();
571 lp->lock = 0;
572 if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
573 dev->tbusy=0;
574 sti();
575
576 return 0;
577 }
578
579
580 static void
581 lance_interrupt(int reg_ptr)
582 {
583 int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
584 struct device *dev = (struct device *)(irq2dev_map[irq]);
585 struct lance_private *lp;
586 int csr0, ioaddr;
587
588 if (dev == NULL) {
589 printk ("lance_interrupt(): irq %d for unknown device.\n", irq);
590 return;
591 }
592
593 ioaddr = dev->base_addr;
594 lp = (struct lance_private *)dev->priv;
595 if (dev->interrupt)
596 printk("%s: Re-entering the interrupt handler.\n", dev->name);
597
598 dev->interrupt = 1;
599
600 outw(0x00, dev->base_addr + LANCE_ADDR);
601 csr0 = inw(dev->base_addr + LANCE_DATA);
602
603
604 outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA);
605
606 if (lance_debug > 5)
607 printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n",
608 dev->name, csr0, inw(dev->base_addr + LANCE_DATA));
609
610 if (csr0 & 0x0400)
611 lance_rx(dev);
612
613 if (csr0 & 0x0200) {
614 int dirty_tx = lp->dirty_tx;
615
616 while (dirty_tx < lp->cur_tx) {
617 int entry = dirty_tx & TX_RING_MOD_MASK;
618 int status = lp->tx_ring[entry].base;
619 void *databuff;
620
621 if (status < 0)
622 break;
623
624 lp->tx_ring[entry].base = 0;
625 databuff = (void*)(status & 0x00ffffff);
626
627 if (status & 0x40000000) {
628 int err_status = lp->tx_ring[entry].misc;
629 lp->stats.tx_errors++;
630 if (err_status & 0x0400) lp->stats.tx_aborted_errors++;
631 if (err_status & 0x0800) lp->stats.tx_carrier_errors++;
632 if (err_status & 0x1000) lp->stats.tx_window_errors++;
633 if (err_status & 0x4000) lp->stats.tx_fifo_errors++;
634
635 } else {
636 if (status & 0x18000000)
637 lp->stats.collisions++;
638 lp->stats.tx_packets++;
639 }
640
641
642
643
644 if (databuff >= (void*)(&lp->tx_bounce_buffs[TX_RING_SIZE])
645 || databuff < (void*)(lp->tx_bounce_buffs)) {
646 struct sk_buff *skb = ((struct sk_buff *)databuff) - 1;
647 dev_kfree_skb(skb,FREE_WRITE);
648
649
650
651 }
652 dirty_tx++;
653 }
654
655 #ifndef final_version
656 if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
657 printk("out-of-sync dirty pointer, %d vs. %d.\n",
658 dirty_tx, lp->cur_tx);
659 dirty_tx += TX_RING_SIZE;
660 }
661 #endif
662
663 if (dev->tbusy && dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
664
665 dev->tbusy = 0;
666 mark_bh(NET_BH);
667 }
668
669 lp->dirty_tx = dirty_tx;
670 }
671
672 if (csr0 & 0x8000) {
673 if (csr0 & 0x4000) lp->stats.tx_errors++;
674 if (csr0 & 0x1000) lp->stats.rx_errors++;
675 }
676
677
678 outw(0x0000, dev->base_addr + LANCE_ADDR);
679 outw(0x7f40, dev->base_addr + LANCE_DATA);
680
681 if (lance_debug > 4)
682 printk("%s: exiting interrupt, csr%d=%#4.4x.\n",
683 dev->name, inw(ioaddr + LANCE_ADDR),
684 inw(dev->base_addr + LANCE_DATA));
685
686 dev->interrupt = 0;
687 return;
688 }
689
690 static int
691 lance_rx(struct device *dev)
692 {
693 struct lance_private *lp = (struct lance_private *)dev->priv;
694 int entry = lp->cur_rx & RX_RING_MOD_MASK;
695 int i;
696
697
698 while (lp->rx_ring[entry].base >= 0) {
699 int status = lp->rx_ring[entry].base >> 24;
700
701 if (status != 0x03) {
702
703
704
705
706 if (status & 0x01)
707 lp->stats.rx_errors++;
708 if (status & 0x20) lp->stats.rx_frame_errors++;
709 if (status & 0x10) lp->stats.rx_over_errors++;
710 if (status & 0x08) lp->stats.rx_crc_errors++;
711 if (status & 0x04) lp->stats.rx_fifo_errors++;
712 lp->rx_ring[entry].base &= 0x03ffffff;
713 } else {
714
715 short pkt_len = lp->rx_ring[entry].msg_length;
716 struct sk_buff *skb;
717
718 skb = alloc_skb(pkt_len, GFP_ATOMIC);
719 if (skb == NULL) {
720 printk("%s: Memory squeeze, deferring packet.\n", dev->name);
721 for (i=0; i < RX_RING_SIZE; i++)
722 if (lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].base < 0)
723 break;
724
725 if (i > RX_RING_SIZE -2) {
726 lp->stats.rx_dropped++;
727 lp->rx_ring[entry].base |= 0x80000000;
728 lp->cur_rx++;
729 }
730 break;
731 }
732 skb->len = pkt_len;
733 skb->dev = dev;
734 memcpy(skb->data,
735 (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
736 pkt_len);
737 netif_rx(skb);
738 lp->stats.rx_packets++;
739 }
740
741 lp->rx_ring[entry].base |= 0x80000000;
742 entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
743 }
744
745
746
747
748 return 0;
749 }
750
751 static int
752 lance_close(struct device *dev)
753 {
754 int ioaddr = dev->base_addr;
755 struct lance_private *lp = (struct lance_private *)dev->priv;
756
757 dev->start = 0;
758 dev->tbusy = 1;
759
760 outw(112, ioaddr+LANCE_ADDR);
761 lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
762
763 outw(0, ioaddr+LANCE_ADDR);
764
765 if (lance_debug > 1)
766 printk("%s: Shutting down ethercard, status was %2.2x.\n",
767 dev->name, inw(ioaddr+LANCE_DATA));
768
769
770
771 outw(0x0004, ioaddr+LANCE_DATA);
772
773 disable_dma(dev->dma);
774
775 free_irq(dev->irq);
776 free_dma(dev->dma);
777
778 irq2dev_map[dev->irq] = 0;
779
780 return 0;
781 }
782
783 static struct enet_statistics *
784 lance_get_stats(struct device *dev)
785 {
786 struct lance_private *lp = (struct lance_private *)dev->priv;
787 short ioaddr = dev->base_addr;
788 short saved_addr;
789
790 cli();
791 saved_addr = inw(ioaddr+LANCE_ADDR);
792 outw(112, ioaddr+LANCE_ADDR);
793 lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
794 outw(saved_addr, ioaddr+LANCE_ADDR);
795 sti();
796
797 return &lp->stats;
798 }
799
800
801
802
803
804
805
806 static void
807 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
808 {
809 short ioaddr = dev->base_addr;
810
811
812 outw(0, ioaddr+LANCE_ADDR);
813 outw(0x0004, ioaddr+LANCE_DATA);
814
815 outw(15, ioaddr+LANCE_ADDR);
816 if (num_addrs >= 0) {
817 short multicast_table[4];
818 int i;
819
820 memset(multicast_table, (num_addrs == 0) ? 0 : -1, sizeof(multicast_table));
821 for (i = 0; i < 4; i++) {
822 outw(8 + i, ioaddr+LANCE_ADDR);
823 outw(multicast_table[i], ioaddr+LANCE_DATA);
824 }
825 outw(0x0000, ioaddr+LANCE_DATA);
826 } else {
827 outw(0x8000, ioaddr+LANCE_DATA);
828 }
829
830 outw(0, ioaddr+LANCE_ADDR);
831 outw(0x0142, ioaddr+LANCE_DATA);
832 }
833
834 #ifdef HAVE_DEVLIST
835 static unsigned int lance_portlist[] = {0x300, 0x320, 0x340, 0x360, 0};
836 struct netdev_entry lance_drv =
837 {"lance", lance_probe1, LANCE_TOTAL_SIZE, lance_portlist};
838 #endif
839
840
841
842
843
844