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