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->data, 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->data) + skb->len > 0x01000000) {
557 if (lance_debug > 5)
558 printk("%s: bouncing a high-memory packet (%#x).\n",
559 dev->name, (int)(skb->data));
560 memcpy(&lp->tx_bounce_buffs[entry], skb->data, 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->data) | 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 }
661 dirty_tx++;
662 }
663
664 #ifndef final_version
665 if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
666 printk("out-of-sync dirty pointer, %d vs. %d.\n",
667 dirty_tx, lp->cur_tx);
668 dirty_tx += TX_RING_SIZE;
669 }
670 #endif
671
672 if (dev->tbusy && dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
673
674 dev->tbusy = 0;
675 mark_bh(INET_BH);
676 }
677
678 lp->dirty_tx = dirty_tx;
679 }
680
681 if (csr0 & 0x8000) {
682 if (csr0 & 0x4000) lp->stats.tx_errors++;
683 if (csr0 & 0x1000) lp->stats.rx_errors++;
684 }
685
686
687 outw(0x0000, dev->base_addr + LANCE_ADDR);
688 outw(0x7f40, dev->base_addr + LANCE_DATA);
689
690 if (lance_debug > 4)
691 printk("%s: exiting interrupt, csr%d=%#4.4x.\n",
692 dev->name, inw(ioaddr + LANCE_ADDR),
693 inw(dev->base_addr + LANCE_DATA));
694
695 dev->interrupt = 0;
696 return;
697 }
698
699 static int
700 lance_rx(struct device *dev)
701 {
702 struct lance_private *lp = (struct lance_private *)dev->priv;
703 int entry = lp->cur_rx & RX_RING_MOD_MASK;
704
705
706 while (lp->rx_ring[entry].base >= 0) {
707 int status = lp->rx_ring[entry].base >> 24;
708
709 if (status != 0x03) {
710
711
712
713
714 if (status & 0x01)
715 lp->stats.rx_errors++;
716 if (status & 0x20) lp->stats.rx_frame_errors++;
717 if (status & 0x10) lp->stats.rx_over_errors++;
718 if (status & 0x08) lp->stats.rx_crc_errors++;
719 if (status & 0x04) lp->stats.rx_fifo_errors++;
720 } else {
721
722 short pkt_len = lp->rx_ring[entry].msg_length;
723 int sksize = sizeof(struct sk_buff) + pkt_len;
724 struct sk_buff *skb;
725
726 skb = alloc_skb(sksize, GFP_ATOMIC);
727 if (skb == NULL) {
728 printk("%s: Memory squeeze, deferring packet.\n", dev->name);
729 lp->stats.rx_dropped++;
730 break;
731 }
732 skb->mem_len = sksize;
733 skb->mem_addr = skb;
734 skb->len = pkt_len;
735 skb->dev = dev;
736 memcpy(skb->data,
737 (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
738 pkt_len);
739 #ifdef HAVE_NETIF_RX
740 netif_rx(skb);
741 #else
742 skb->lock = 0;
743 if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
744 kfree_skbmem(skb, sksize);
745 lp->stats.rx_dropped++;
746 break;
747 }
748 #endif
749 lp->stats.rx_packets++;
750 }
751
752 lp->rx_ring[entry].base |= 0x80000000;
753 entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
754 }
755
756
757
758
759 return 0;
760 }
761
762 static int
763 lance_close(struct device *dev)
764 {
765 int ioaddr = dev->base_addr;
766 struct lance_private *lp = (struct lance_private *)dev->priv;
767
768 dev->start = 0;
769 dev->tbusy = 1;
770
771 outw(112, ioaddr+LANCE_ADDR);
772 lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
773
774 outw(0, ioaddr+LANCE_ADDR);
775
776 if (lance_debug > 1)
777 printk("%s: Shutting down ethercard, status was %2.2x.\n",
778 dev->name, inw(ioaddr+LANCE_DATA));
779
780
781
782 outw(0x0004, ioaddr+LANCE_DATA);
783
784 disable_dma(dev->dma);
785
786 free_irq(dev->irq);
787 free_dma(dev->dma);
788
789 irq2dev_map[dev->irq] = 0;
790
791 return 0;
792 }
793
794 static struct enet_statistics *
795 lance_get_stats(struct device *dev)
796 {
797 struct lance_private *lp = (struct lance_private *)dev->priv;
798 short ioaddr = dev->base_addr;
799 short saved_addr;
800
801 cli();
802 saved_addr = inw(ioaddr+LANCE_ADDR);
803 outw(112, ioaddr+LANCE_ADDR);
804 lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
805 outw(saved_addr, ioaddr+LANCE_ADDR);
806 sti();
807
808 return &lp->stats;
809 }
810
811 #ifdef HAVE_MULTICAST
812
813
814
815
816
817
818 static void
819 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
820 {
821 short ioaddr = dev->base_addr;
822
823
824 outw(0, ioaddr+LANCE_ADDR);
825 outw(0x0004, ioaddr+LANCE_DATA);
826
827 outw(15, ioaddr+LANCE_ADDR);
828 if (num_addrs >= 0) {
829 short multicast_table[4];
830 int i;
831
832 memset(multicast_table, (num_addrs == 0) ? 0 : -1, sizeof(multicast_table));
833 for (i = 0; i < 4; i++) {
834 outw(8 + i, ioaddr+LANCE_ADDR);
835 outw(multicast_table[i], ioaddr+LANCE_DATA);
836 }
837 outw(0x0000, ioaddr+LANCE_DATA);
838 } else {
839 outw(0x8000, ioaddr+LANCE_DATA);
840 }
841
842 outw(0, ioaddr+LANCE_ADDR);
843 outw(0x0142, ioaddr+LANCE_DATA);
844 }
845 #endif
846
847 #ifdef HAVE_DEVLIST
848 static unsigned int lance_portlist[] = {0x300, 0x320, 0x340, 0x360, 0};
849 struct netdev_entry lance_drv =
850 {"lance", lance_probe1, LANCE_TOTAL_SIZE, lance_portlist};
851 #endif
852
853
854
855
856
857