This source file includes following definitions.
- dec21040_init
- tulip_probe1
- tulip_open
- tulip_init_ring
- tulip_start_xmit
- tulip_interrupt
- tulip_rx
- tulip_close
- tulip_get_stats
- set_multicast_list
- set_mac_address
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 static char *version = "tulip.c:v0.05 1/20/95 becker@cesdis.gsfc.nasa.gov\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 <linux/pci.h>
29 #include <linux/bios32.h>
30 #include <asm/bitops.h>
31 #include <asm/io.h>
32 #include <asm/dma.h>
33
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
36 #include <linux/skbuff.h>
37
38
39 struct device *init_etherdev(struct device *dev, int sizeof_private,
40 unsigned long *mem_startp);
41
42
43
44 #define TULIP_TOTAL_SIZE 0x80
45
46 #ifdef HAVE_DEVLIST
47 struct netdev_entry tulip_drv =
48 {"Tulip", tulip_pci_probe, TULIP_TOTAL_SIZE, NULL};
49 #endif
50
51 #define TULIP_DEBUG 1
52 #ifdef TULIP_DEBUG
53 int tulip_debug = TULIP_DEBUG;
54 #else
55 int tulip_debug = 1;
56 #endif
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 #define DEC_VENDOR_ID 0x1011
114 #define DEC_21040_ID 0x0002
115
116
117 #define TX_RING_SIZE 4
118 #define RX_RING_SIZE 4
119 #define PKT_BUF_SZ 1536
120
121
122
123 enum tulip_offsets {
124 CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
125 CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
126 CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 };
127
128
129 struct tulip_rx_desc {
130 int status;
131 int length;
132 char *buffer1, *buffer2;
133 };
134
135 struct tulip_tx_desc {
136 int status;
137 int length;
138 char *buffer1, *buffer2;
139 };
140
141 struct tulip_private {
142 char devname[8];
143 struct tulip_rx_desc rx_ring[RX_RING_SIZE];
144 struct tulip_tx_desc tx_ring[TX_RING_SIZE];
145
146 struct sk_buff* tx_skbuff[TX_RING_SIZE];
147 long rx_buffs;
148 struct enet_statistics stats;
149 int setup_frame[48];
150 unsigned int cur_rx, cur_tx;
151 unsigned int dirty_rx, dirty_tx;
152 unsigned int tx_full:1;
153 int pad0, pad1;
154 };
155
156 static unsigned long tulip_probe1(unsigned long mem_start, int ioaddr,
157 int irq);
158 static int tulip_open(struct device *dev);
159 static void tulip_init_ring(struct device *dev);
160 static int tulip_start_xmit(struct sk_buff *skb, struct device *dev);
161 static int tulip_rx(struct device *dev);
162 static void tulip_interrupt(int irq, struct pt_regs *regs);
163 static int tulip_close(struct device *dev);
164 static struct enet_statistics *tulip_get_stats(struct device *dev);
165 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
166 static int set_mac_address(struct device *dev, void *addr);
167
168
169
170
171
172
173
174
175 unsigned long dec21040_init(unsigned long mem_start, unsigned long mem_end)
176 {
177
178 if (pcibios_present()) {
179 int pci_index;
180 for (pci_index = 0; pci_index < 8; pci_index++) {
181 unsigned char pci_bus, pci_device_fn, pci_irq_line;
182 unsigned long pci_ioaddr;
183
184 if (pcibios_find_device (DEC_VENDOR_ID, DEC_21040_ID, pci_index,
185 &pci_bus, &pci_device_fn) != 0)
186 break;
187 pcibios_read_config_byte(pci_bus, pci_device_fn,
188 PCI_INTERRUPT_LINE, &pci_irq_line);
189 pcibios_read_config_dword(pci_bus, pci_device_fn,
190 PCI_BASE_ADDRESS_0, &pci_ioaddr);
191
192 pci_ioaddr &= ~3;
193 if (tulip_debug > 2)
194 printk("Found DEC PCI Tulip at I/O %#lx, IRQ %d.\n",
195 pci_ioaddr, pci_irq_line);
196 mem_start = tulip_probe1(mem_start, pci_ioaddr, pci_irq_line);
197 }
198 }
199
200 return mem_start;
201 }
202
203 unsigned long tulip_probe1(unsigned long mem_start, int ioaddr, int irq)
204 {
205 static int did_version = 0;
206 struct device *dev;
207 struct tulip_private *tp;
208 int i;
209
210 if (tulip_debug > 0 && did_version++ == 0)
211 printk(version);
212
213 dev = init_etherdev(0, sizeof(struct tulip_private)
214 + PKT_BUF_SZ*RX_RING_SIZE,
215 &mem_start);
216
217 printk("%s: DEC 21040 Tulip at %#3x,", dev->name, ioaddr);
218
219
220 outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6);
221
222 inl(ioaddr + CSR8) & 0xffff;
223
224
225
226
227
228 outl(0, ioaddr + CSR9);
229 for (i = 0; i < 6; i++) {
230 int value, boguscnt = 100000;
231 do
232 value = inl(ioaddr + CSR9);
233 while (value < 0 && --boguscnt > 0);
234 printk(" %2.2x", dev->dev_addr[i] = value);
235 }
236 printk(", IRQ %d\n", irq);
237
238
239 request_region(ioaddr, TULIP_TOTAL_SIZE, "DEC Tulip Ethernet");
240
241 dev->base_addr = ioaddr;
242 dev->irq = irq;
243
244
245 dev->priv = (void *)(((int)dev->priv + 7) & ~7);
246 tp = (struct tulip_private *)dev->priv;
247 tp->rx_buffs = (long)dev->priv + sizeof(struct tulip_private);
248
249
250 dev->open = &tulip_open;
251 dev->hard_start_xmit = &tulip_start_xmit;
252 dev->stop = &tulip_close;
253 dev->get_stats = &tulip_get_stats;
254 #ifdef HAVE_MULTICAST
255 dev->set_multicast_list = &set_multicast_list;
256 #endif
257 #ifdef HAVE_SET_MAC_ADDR
258 dev->set_mac_address = &set_mac_address;
259 #endif
260
261 return mem_start;
262 }
263
264
265 static int
266 tulip_open(struct device *dev)
267 {
268 struct tulip_private *tp = (struct tulip_private *)dev->priv;
269 int ioaddr = dev->base_addr;
270
271
272 outl(0xfff80001, ioaddr + CSR0);
273 SLOW_DOWN_IO;
274
275
276
277
278
279
280
281
282 outl(0xfff84800, ioaddr + CSR0);
283
284 if (irq2dev_map[dev->irq] != NULL
285 || (irq2dev_map[dev->irq] = dev) == NULL
286 || dev->irq == 0
287 || request_irq(dev->irq, &tulip_interrupt, 0, "DEC 21040 Tulip")) {
288 return -EAGAIN;
289 }
290
291 if (tulip_debug > 1)
292 printk("%s: tulip_open() irq %d.\n", dev->name, dev->irq);
293
294 tulip_init_ring(dev);
295
296
297 {
298 unsigned short *eaddrs = (unsigned short *)dev->dev_addr;
299 int *setup_frm = tp->setup_frame, i;
300
301
302 *setup_frm++ = 0xffff;
303 *setup_frm++ = 0xffff;
304 *setup_frm++ = 0xffff;
305
306 for (i = 1; i < 16; i++) {
307 *setup_frm++ = eaddrs[0];
308 *setup_frm++ = eaddrs[1];
309 *setup_frm++ = eaddrs[2];
310 }
311
312 tp->tx_ring[0].length = 0x08000000 | 192;
313 tp->tx_ring[0].buffer1 = (char *)tp->setup_frame;
314 tp->tx_ring[0].buffer2 = 0;
315 tp->tx_ring[0].status = 0x80000000;
316
317 tp->cur_tx++, tp->dirty_tx++;
318 }
319
320 outl((int)tp->rx_ring, ioaddr + CSR3);
321 outl((int)tp->tx_ring, ioaddr + CSR4);
322
323
324 outl(0x00000000, ioaddr + CSR13);
325 outl(0x00000004, ioaddr + CSR13);
326
327
328 outl(0xfffe2002, ioaddr + CSR6);
329
330
331 outl(0, ioaddr + CSR1);
332
333 dev->tbusy = 0;
334 dev->interrupt = 0;
335 dev->start = 1;
336
337
338 outl(0xFFFFFFFF, ioaddr + CSR7);
339
340 if (tulip_debug > 2) {
341 printk("%s: Done tulip_open(), CSR0 %8.8x, CSR13 %8.8x.\n",
342 dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR13));
343 }
344 return 0;
345 }
346
347
348 static void
349 tulip_init_ring(struct device *dev)
350 {
351 struct tulip_private *tp = (struct tulip_private *)dev->priv;
352 int i;
353
354 tp->tx_full = 0;
355 tp->cur_rx = tp->cur_tx = 0;
356 tp->dirty_rx = tp->dirty_tx = 0;
357
358 for (i = 0; i < RX_RING_SIZE; i++) {
359 tp->rx_ring[i].status = 0x80000000;
360 tp->rx_ring[i].length = PKT_BUF_SZ;
361 tp->rx_ring[i].buffer1 = (char *)(tp->rx_buffs + i*PKT_BUF_SZ);
362 tp->rx_ring[i].buffer2 = (char *)&tp->rx_ring[i+1];
363 }
364
365 tp->rx_ring[i-1].length = PKT_BUF_SZ | 0x02000000;
366 tp->rx_ring[i-1].buffer2 = (char *)&tp->rx_ring[0];
367
368
369
370 for (i = 0; i < TX_RING_SIZE; i++) {
371 tp->tx_ring[i].status = 0x00000000;
372 }
373 }
374
375 static int
376 tulip_start_xmit(struct sk_buff *skb, struct device *dev)
377 {
378 struct tulip_private *tp = (struct tulip_private *)dev->priv;
379 int ioaddr = dev->base_addr;
380 int entry;
381
382
383 if (dev->tbusy) {
384 int tickssofar = jiffies - dev->trans_start;
385 int i;
386 if (tickssofar < 20)
387 return 1;
388 printk("%s: transmit timed out, status %8.8x, SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
389 dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12),
390 inl(ioaddr + CSR13), inl(ioaddr + CSR14), inl(ioaddr + CSR15));
391 printk(" Rx ring %8.8x: ", (int)tp->rx_ring);
392 for (i = 0; i < RX_RING_SIZE; i++)
393 printk(" %8.8x", (unsigned int)tp->rx_ring[i].status);
394 printk("\n Tx ring %8.8x: ", (int)tp->tx_ring);
395 for (i = 0; i < TX_RING_SIZE; i++)
396 printk(" %8.8x", (unsigned int)tp->tx_ring[i].status);
397 printk("\n");
398
399 tp->stats.tx_errors++;
400
401 dev->tbusy=0;
402 dev->trans_start = jiffies;
403 return 0;
404 }
405
406 if (skb == NULL || skb->len <= 0) {
407 printk("%s: Obsolete driver layer request made: skbuff==NULL.\n",
408 dev->name);
409 dev_tint(dev);
410 return 0;
411 }
412
413
414
415
416 if (set_bit(0, (void*)&dev->tbusy) != 0) {
417 printk("%s: Transmitter access conflict.\n", dev->name);
418 return 1;
419 }
420
421
422
423
424
425 entry = tp->cur_tx % TX_RING_SIZE;
426
427 tp->tx_full = 1;
428 tp->tx_skbuff[entry] = skb;
429 tp->tx_ring[entry].length = skb->len |
430 (entry == TX_RING_SIZE-1 ? 0xe2000000 : 0xe0000000);
431 tp->tx_ring[entry].buffer1 = skb->data;
432 tp->tx_ring[entry].buffer2 = 0;
433 tp->tx_ring[entry].status = 0x80000000;
434
435 tp->cur_tx++;
436
437
438 outl(0, ioaddr + CSR1);
439
440 dev->trans_start = jiffies;
441
442 return 0;
443 }
444
445
446
447 static void tulip_interrupt(int irq, struct pt_regs *regs)
448 {
449 struct device *dev = (struct device *)(irq2dev_map[irq]);
450 struct tulip_private *lp;
451 int csr5, ioaddr, boguscnt=10;
452
453 if (dev == NULL) {
454 printk ("tulip_interrupt(): irq %d for unknown device.\n", irq);
455 return;
456 }
457
458 ioaddr = dev->base_addr;
459 lp = (struct tulip_private *)dev->priv;
460 if (dev->interrupt)
461 printk("%s: Re-entering the interrupt handler.\n", dev->name);
462
463 dev->interrupt = 1;
464
465 do {
466 csr5 = inl(ioaddr + CSR5);
467
468 outl(csr5 & 0x0001ffff, ioaddr + CSR5);
469
470 if (tulip_debug > 4)
471 printk("%s: interrupt csr5=%#8.8x new csr5=%#8.8x.\n",
472 dev->name, csr5, inl(dev->base_addr + CSR5));
473
474 if ((csr5 & 0x00018000) == 0)
475 break;
476
477 if (csr5 & 0x0040)
478 tulip_rx(dev);
479
480 if (csr5 & 0x0001) {
481 int dirty_tx = lp->dirty_tx;
482
483 while (dirty_tx < lp->cur_tx) {
484 int entry = dirty_tx % TX_RING_SIZE;
485 int status = lp->tx_ring[entry].status;
486
487 if (status < 0)
488 break;
489
490 if (status & 0x8000) {
491
492 lp->stats.tx_errors++;
493 if (status & 0x4104) lp->stats.tx_aborted_errors++;
494 if (status & 0x0C00) lp->stats.tx_carrier_errors++;
495 if (status & 0x0200) lp->stats.tx_window_errors++;
496 if (status & 0x0002) lp->stats.tx_fifo_errors++;
497 if (status & 0x0080) lp->stats.tx_heartbeat_errors++;
498 #ifdef ETHER_STATS
499 if (status & 0x0100) lp->stats.collisions16++;
500 #endif
501 } else {
502 #ifdef ETHER_STATS
503 if (status & 0x0001) lp->stats.tx_deferred++;
504 #endif
505 lp->stats.collisions += (status >> 3) & 15;
506 lp->stats.tx_packets++;
507 }
508
509
510 dev_kfree_skb(lp->tx_skbuff[entry], FREE_WRITE);
511 dirty_tx++;
512 }
513
514 #ifndef final_version
515 if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
516 printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
517 dirty_tx, lp->cur_tx, lp->tx_full);
518 dirty_tx += TX_RING_SIZE;
519 }
520 #endif
521
522 if (lp->tx_full && dev->tbusy
523 && dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
524
525 lp->tx_full = 0;
526 dev->tbusy = 0;
527 mark_bh(NET_BH);
528 }
529
530 lp->dirty_tx = dirty_tx;
531 }
532
533
534 if (csr5 & 0x8000) {
535 if (csr5 & 0x0008) lp->stats.tx_errors++;
536 if (csr5 & 0x0100) {
537 lp->stats.rx_errors++;
538 lp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
539 }
540 if (csr5 & 0x0800) {
541 printk("%s: Something Wicked happened! %8.8x.\n",
542 dev->name, csr5);
543
544 }
545 }
546 if (--boguscnt < 0) {
547 printk("%s: Too much work at interrupt, csr5=0x%8.8x.\n",
548 dev->name, csr5);
549
550 outl(0x0001ffff, ioaddr + CSR5);
551 break;
552 }
553 } while (1);
554
555 if (tulip_debug > 3)
556 printk("%s: exiting interrupt, csr5=%#4.4x.\n",
557 dev->name, inl(ioaddr + CSR5));
558
559
560 {
561 static int stopit = 10;
562 if (dev->start == 0 && --stopit < 0) {
563 printk("%s: Emergency stop, looping startup interrupt.\n",
564 dev->name);
565 free_irq(irq);
566 }
567 }
568
569 dev->interrupt = 0;
570 return;
571 }
572
573 static int
574 tulip_rx(struct device *dev)
575 {
576 struct tulip_private *lp = (struct tulip_private *)dev->priv;
577 int entry = lp->cur_rx % RX_RING_SIZE;
578 int i;
579
580 if (tulip_debug > 4)
581 printk(" In tulip_rx().\n");
582
583 while (lp->rx_ring[entry].status >= 0) {
584 int status = lp->rx_ring[entry].status;
585
586 if (tulip_debug > 4)
587 printk(" tulip_rx() status was %8.8x.\n", status);
588 if ((status & 0x0300) != 0x0300) {
589 printk("%s: Ethernet frame spanned multiple buffers, status %8.8x!\n",
590 dev->name, status);
591 } else if (status & 0x8000) {
592
593 lp->stats.rx_errors++;
594 if (status & 0x0890) lp->stats.rx_length_errors++;
595 if (status & 0x0004) lp->stats.rx_frame_errors++;
596 if (status & 0x0002) lp->stats.rx_crc_errors++;
597 if (status & 0x0001) lp->stats.rx_fifo_errors++;
598 } else {
599
600 short pkt_len = lp->rx_ring[entry].status >> 16;
601 struct sk_buff *skb;
602
603 skb = dev_alloc_skb(pkt_len+2);
604 if (skb == NULL) {
605 printk("%s: Memory squeeze, deferring packet.\n", dev->name);
606
607
608 for (i=0; i < RX_RING_SIZE; i++)
609 if (lp->rx_ring[(entry+i) % RX_RING_SIZE].status < 0)
610 break;
611
612 if (i > RX_RING_SIZE -2) {
613 lp->stats.rx_dropped++;
614 lp->rx_ring[entry].status = 0x80000000;
615 lp->cur_rx++;
616 }
617 break;
618 }
619 skb->dev = dev;
620 skb_reserve(skb,2);
621 memcpy(skb_put(skb,pkt_len), lp->rx_ring[entry].buffer1, pkt_len);
622 skb->protocol=eth_type_trans(skb,dev);
623 netif_rx(skb);
624 lp->stats.rx_packets++;
625 }
626
627 lp->rx_ring[entry].status = 0x80000000;
628 entry = (++lp->cur_rx) % RX_RING_SIZE;
629 }
630
631 return 0;
632 }
633
634 static int
635 tulip_close(struct device *dev)
636 {
637 int ioaddr = dev->base_addr;
638 struct tulip_private *tp = (struct tulip_private *)dev->priv;
639
640 dev->start = 0;
641 dev->tbusy = 1;
642
643 if (tulip_debug > 1)
644 printk("%s: Shutting down ethercard, status was %2.2x.\n",
645 dev->name, inl(ioaddr + CSR5));
646
647
648 outl(0x00000000, ioaddr + CSR7);
649
650 outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6);
651
652 tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
653
654 free_irq(dev->irq);
655 irq2dev_map[dev->irq] = 0;
656
657 return 0;
658 }
659
660 static struct enet_statistics *
661 tulip_get_stats(struct device *dev)
662 {
663 struct tulip_private *tp = (struct tulip_private *)dev->priv;
664 short ioaddr = dev->base_addr;
665
666 tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
667
668 return &tp->stats;
669 }
670
671
672
673
674
675
676
677 static void
678 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
679 {
680 short ioaddr = dev->base_addr;
681 int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
682
683 if (num_addrs > 15) {
684
685 outl(csr6 | 0x0080, ioaddr + CSR6);
686 } else if (num_addrs < 0) {
687 outl(csr6 | 0x00C0, ioaddr + CSR6);
688
689 printk("%s: Promiscuous mode enabled.\n", dev->name);
690 } else {
691 struct tulip_private *tp = (struct tulip_private *)dev->priv;
692 int *setup_frm = tp->setup_frame;
693 unsigned short *eaddrs = addrs;
694 int i;
695
696
697
698
699 outl(csr6 | 0x0000, ioaddr + CSR6);
700 for(i = 0; i < num_addrs; i++) {
701 *setup_frm++ = *eaddrs++;
702 *setup_frm++ = *eaddrs++;
703 *setup_frm++ = *eaddrs++;
704 }
705
706 eaddrs = (unsigned short *)dev->dev_addr;
707 do {
708 *setup_frm++ = eaddrs[0];
709 *setup_frm++ = eaddrs[1];
710 *setup_frm++ = eaddrs[2];
711 } while (++i < 16);
712
713
714 }
715 }
716
717 static int
718 set_mac_address(struct device *dev, void *addr)
719 {
720 int i;
721 if (dev->start)
722 return -EBUSY;
723 printk("%s: Setting MAC address to ", dev->name);
724 for (i = 0; i < 6; i++)
725 printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
726 printk(".\n");
727 return 0;
728 }
729
730
731
732
733
734
735
736
737