This source file includes following definitions.
- memcpyw
- ariadne_probe
- ariadne_open
- ariadne_init_ring
- ariadne_close
- ariadne_interrupt
- ariadne_start_xmit
- ariadne_rx
- ariadne_get_stats
- set_multicast_list
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
39 #include <stddef.h>
40
41 #include <linux/kernel.h>
42 #include <linux/sched.h>
43 #include <linux/string.h>
44 #include <linux/ptrace.h>
45 #include <linux/errno.h>
46 #include <linux/ioport.h>
47 #include <linux/malloc.h>
48 #include <linux/netdevice.h>
49 #include <linux/etherdevice.h>
50 #include <linux/interrupt.h>
51 #include <linux/skbuff.h>
52
53 #include <asm/bitops.h>
54 #include <asm/amigaints.h>
55 #include <asm/amigahw.h>
56 #include <asm/zorro.h>
57 #include <asm/bootinfo.h>
58 #include <asm/io.h>
59 #include <asm/irq.h>
60
61 #include "ariadne.h"
62
63
64 #ifdef ARIADNE_DEBUG
65 int ariadne_debug = ARIADNE_DEBUG;
66 #else
67 int ariadne_debug = 1;
68 #endif
69
70
71
72
73
74
75
76 #define swapw(x) (((x>>8)&0x00ff)|((x<<8)&0xff00))
77
78 #define lowb(x) (x&0xff)
79
80 #define swhighw(x) ((((x)>>8)&0xff00)|(((x)>>24)&0x00ff))
81
82 #define swloww(x) ((((x)<<8)&0xff00)|(((x)>>8)&0x00ff))
83
84
85
86
87
88
89 #define TX_RING_SIZE 5
90 #define RX_RING_SIZE 16
91
92 #define PKT_BUF_SIZE 1520
93
94
95
96
97
98
99 struct ariadne_private {
100 struct AriadneBoard *board;
101 struct TDRE *tx_ring[TX_RING_SIZE];
102 struct RDRE *rx_ring[RX_RING_SIZE];
103 u_short *tx_buff[TX_RING_SIZE];
104 u_short *rx_buff[RX_RING_SIZE];
105 int cur_tx, cur_rx;
106 int dirty_tx;
107 struct enet_statistics stats;
108 char tx_full;
109 unsigned long lock;
110 };
111
112
113
114
115
116
117 struct lancedata {
118 struct TDRE tx_ring[TX_RING_SIZE];
119 struct RDRE rx_ring[RX_RING_SIZE];
120 u_short tx_buff[TX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)];
121 u_short rx_buff[RX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)];
122 };
123
124
125 static int ariadne_open(struct device *dev);
126 static void ariadne_init_ring(struct device *dev);
127 static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev);
128 static int ariadne_rx(struct device *dev);
129 static void ariadne_interrupt(int irq, struct pt_regs *fp, void *data);
130 static int ariadne_close(struct device *dev);
131 static struct enet_statistics *ariadne_get_stats(struct device *dev);
132 #ifdef HAVE_MULTICAST
133 static void set_multicast_list(struct device *dev);
134 #endif
135
136
137 static void memcpyw(u_short *dest, u_short *src, int len)
138 {
139 while (len >= 2) {
140 *(dest++) = *(src++);
141 len -= 2;
142 }
143 if (len == 1)
144 *dest = (*(u_char *)src)<<8;
145 }
146
147
148 int long ariadne_probe(struct device *dev)
149 {
150 int key;
151 struct ConfigDev *cd;
152 u_long board;
153 struct ariadne_private *priv;
154
155
156 if ((key = zorro_find(MANUF_VILLAGE_TRONIC, PROD_ARIADNE, 0, 0))) {
157 cd = zorro_get_board(key);
158 if ((board = (u_long)cd->cd_BoardAddr)) {
159 dev->dev_addr[0] = 0x00;
160 dev->dev_addr[1] = 0x60;
161 dev->dev_addr[2] = 0x30;
162 dev->dev_addr[3] = (cd->cd_Rom.er_SerialNumber>>16)&0xff;
163 dev->dev_addr[4] = (cd->cd_Rom.er_SerialNumber>>8)&0xff;
164 dev->dev_addr[5] = cd->cd_Rom.er_SerialNumber&0xff;
165 printk("%s: Ariadne at 0x%08lx, Ethernet Address "
166 "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board,
167 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
168 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
169
170 init_etherdev(dev, 0);
171
172 dev->priv = kmalloc(sizeof(struct ariadne_private), GFP_KERNEL);
173 priv = (struct ariadne_private *)dev->priv;
174 memset(priv, 0, sizeof(struct ariadne_private));
175
176 priv->board = (struct AriadneBoard *)ZTWO_VADDR(board);
177
178 dev->open = &ariadne_open;
179 dev->stop = &ariadne_close;
180 dev->hard_start_xmit = &ariadne_start_xmit;
181 dev->get_stats = &ariadne_get_stats;
182 dev->set_multicast_list = &set_multicast_list;
183
184 zorro_config_board(key, 0);
185 return(0);
186 }
187 }
188 return(ENODEV);
189 }
190
191
192 static int ariadne_open(struct device *dev)
193 {
194 struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
195 struct AriadneBoard *board = priv->board;
196 static int interruptinstalled = 0;
197 struct lancedata *lancedata;
198 u_short in;
199 u_long version;
200
201
202 in = board->Lance.Reset;
203
204
205 board->Lance.RAP = CSR0;
206 board->Lance.RDP = STOP;
207
208
209 board->Lance.RAP = CSR88;
210 version = swapw(board->Lance.RDP);
211 board->Lance.RAP = CSR89;
212 version |= swapw(board->Lance.RDP)<<16;
213 if ((version & 0x00000fff) != 0x00000003) {
214 printk("ariadne_open: Couldn't find AMD Ethernet Chip\n");
215 return(-EAGAIN);
216 }
217 if ((version & 0x0ffff000) != 0x00003000) {
218 printk("ariadne_open: Couldn't find Am79C960 (Wrong part number = %ld)\n",
219 (version & 0x0ffff000)>>12);
220 return(-EAGAIN);
221 }
222 #if 0
223 printk("ariadne_open: Am79C960 (PCnet-ISA) Revision %ld\n",
224 (version & 0xf0000000)>>28);
225 #endif
226
227 ariadne_init_ring(dev);
228
229
230 board->Lance.RAP = CSR3;
231 board->Lance.RDP = 0x0000;
232 board->Lance.RAP = CSR4;
233 board->Lance.RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM;
234
235
236 board->Lance.RAP = CSR8;
237 board->Lance.RDP = 0x0000;
238 board->Lance.RAP = CSR9;
239 board->Lance.RDP = 0x0000;
240 board->Lance.RAP = CSR10;
241 board->Lance.RDP = 0x0000;
242 board->Lance.RAP = CSR11;
243 board->Lance.RDP = 0x0000;
244
245
246 board->Lance.RAP = CSR12;
247 board->Lance.RDP = ((u_short *)&dev->dev_addr[0])[0];
248 board->Lance.RAP = CSR13;
249 board->Lance.RDP = ((u_short *)&dev->dev_addr[0])[1];
250 board->Lance.RAP = CSR14;
251 board->Lance.RDP = ((u_short *)&dev->dev_addr[0])[2];
252
253
254 board->Lance.RAP = CSR15;
255 board->Lance.RDP = 0x0000;
256
257 lancedata = (struct lancedata *)offsetof(struct AriadneBoard, RAM);
258
259
260 board->Lance.RAP = CSR30;
261 board->Lance.RDP = swloww((u_long)&lancedata->tx_ring);
262 board->Lance.RAP = CSR31;
263 board->Lance.RDP = swhighw((u_long)&lancedata->tx_ring);
264
265
266 board->Lance.RAP = CSR24;
267 board->Lance.RDP = swloww((u_long)&lancedata->rx_ring);
268 board->Lance.RAP = CSR25;
269 board->Lance.RDP = swhighw((u_long)&lancedata->rx_ring);
270
271
272 board->Lance.RAP = CSR76;
273 board->Lance.RDP = swapw(((u_short)-RX_RING_SIZE));
274 board->Lance.RAP = CSR78;
275 board->Lance.RDP = swapw(((u_short)-TX_RING_SIZE));
276
277
278 board->Lance.RAP = ISACSR2;
279 board->Lance.IDP = ASEL;
280
281
282 board->Lance.RAP = ISACSR5;
283 board->Lance.IDP = PSE|XMTE;
284 board->Lance.RAP = ISACSR6;
285 board->Lance.IDP = PSE|COLE;
286 board->Lance.RAP = ISACSR7;
287 board->Lance.IDP = PSE|RCVE;
288
289 dev->tbusy = 0;
290 dev->interrupt = 0;
291 dev->start = 1;
292
293 if (!interruptinstalled) {
294 if (!add_isr(IRQ_AMIGA_PORTS, ariadne_interrupt, 0, dev,
295 "Ariadne Ethernet"))
296 return(-EAGAIN);
297 interruptinstalled = 1;
298 }
299
300 board->Lance.RAP = CSR0;
301 board->Lance.RDP = INEA|STRT;
302
303 return(0);
304 }
305
306
307 static void ariadne_init_ring(struct device *dev)
308 {
309 struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
310 struct AriadneBoard *board = priv->board;
311 struct lancedata *lancedata;
312 struct lancedata *alancedata;
313 int i;
314
315 priv->lock = 0, priv->tx_full = 0;
316 priv->cur_rx = priv->cur_tx = 0;
317 priv->dirty_tx = 0;
318
319 lancedata = (struct lancedata *)offsetof(struct AriadneBoard, RAM);
320 alancedata = (struct lancedata *)board->RAM;
321
322
323 for (i = 0; i < TX_RING_SIZE; i++) {
324 alancedata->tx_ring[i].TMD0 = swloww((u_long)lancedata->tx_buff[i]);
325 alancedata->tx_ring[i].TMD1 = swhighw((u_long)lancedata->tx_buff[i])|TF_STP|TF_ENP;
326 alancedata->tx_ring[i].TMD2 = swapw((u_short)-PKT_BUF_SIZE);
327 alancedata->tx_ring[i].TMD3 = 0;
328 priv->tx_ring[i] = &alancedata->tx_ring[i];
329 priv->tx_buff[i] = alancedata->tx_buff[i];
330 #if 0
331 printk("TX Entry %2d @ 0x%08x (LANCE 0x%08x), Buf @ 0x%08x (LANCE 0x%08x)\n",
332 i, (int)&alancedata->tx_ring[i], (int)&lancedata->tx_ring[i],
333 (int)alancedata->tx_buff[i], (int)lancedata->tx_buff[i]);
334 #endif
335 }
336
337
338 for (i = 0; i < RX_RING_SIZE; i++) {
339 alancedata->rx_ring[i].RMD0 = swloww((u_long)lancedata->rx_buff[i]);
340 alancedata->rx_ring[i].RMD1 = swhighw((u_long)lancedata->rx_buff[i])|RF_OWN;
341 alancedata->rx_ring[i].RMD2 = swapw((u_short)-PKT_BUF_SIZE);
342 alancedata->rx_ring[i].RMD3 = 0x0000;
343 priv->rx_ring[i] = &alancedata->rx_ring[i];
344 priv->rx_buff[i] = alancedata->rx_buff[i];
345 #if 0
346 printk("RX Entry %2d @ 0x%08x (LANCE 0x%08x), Buf @ 0x%08x (LANCE 0x%08x)\n",
347 i, (int)&alancedata->rx_ring[i], (int)&lancedata->rx_ring[i],
348 (int)alancedata->rx_buff[i], (int)lancedata->rx_buff[i]);
349 #endif
350 }
351 }
352
353
354 static int ariadne_close(struct device *dev)
355 {
356 struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
357 struct AriadneBoard *board = priv->board;
358
359 dev->start = 0;
360 dev->tbusy = 1;
361
362 board->Lance.RAP = CSR112;
363 priv->stats.rx_missed_errors = swapw(board->Lance.RDP);
364 board->Lance.RAP = CSR0;
365
366 if (ariadne_debug > 1) {
367 printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name,
368 board->Lance.RDP);
369 printk("%s: %d packets missed\n", dev->name,
370 priv->stats.rx_missed_errors);
371 }
372
373
374 board->Lance.RDP = STOP;
375
376 return(0);
377 }
378
379
380 static void ariadne_interrupt(int irq, struct pt_regs *fp, void *data)
381 {
382 struct device *dev = (struct device *)data;
383 struct ariadne_private *priv;
384 struct AriadneBoard *board;
385 int csr0, boguscnt = 10;
386
387 if (dev == NULL) {
388 printk("ariadne_interrupt(): irq for unknown device.\n");
389 return;
390 }
391
392 priv = (struct ariadne_private *)dev->priv;
393 board = priv->board;
394
395 board->Lance.RAP = CSR0;
396
397 if (!(board->Lance.RDP & INTR))
398
399
400 if (dev->interrupt)
401 printk("%s: Re-entering the interrupt handler.\n", dev->name);
402
403 dev->interrupt = 1;
404
405 while ((csr0 = board->Lance.RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) {
406
407 board->Lance.RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT);
408
409 #if 0
410 if (ariadne_debug > 5) {
411 printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.", dev->name,
412 csr0, board->Lance.RDP);
413 printk("[");
414 if (csr0 & INTR)
415 printk(" INTR");
416 if (csr0 & INEA)
417 printk(" INEA");
418 if (csr0 & RXON)
419 printk(" RXON");
420 if (csr0 & TXON)
421 printk(" TXON");
422 if (csr0 & TDMD)
423 printk(" TDMD");
424 if (csr0 & STOP)
425 printk(" STOP");
426 if (csr0 & STRT)
427 printk(" STRT");
428 if (csr0 & INIT)
429 printk(" INIT");
430 if (csr0 & ERR)
431 printk(" ERR");
432 if (csr0 & BABL)
433 printk(" BABL");
434 if (csr0 & CERR)
435 printk(" CERR");
436 if (csr0 & MISS)
437 printk(" MISS");
438 if (csr0 & MERR)
439 printk(" MERR");
440 if (csr0 & RINT)
441 printk(" RINT");
442 if (csr0 & TINT)
443 printk(" TINT");
444 if (csr0 & IDON)
445 printk(" IDON");
446 printk(" ]\n");
447 }
448 #endif
449
450 if (csr0 & RINT)
451 ariadne_rx(dev);
452
453 if (csr0 & TINT) {
454 int dirty_tx = priv->dirty_tx;
455
456 while (dirty_tx < priv->cur_tx) {
457 int entry = dirty_tx % TX_RING_SIZE;
458 int status = lowb(priv->tx_ring[entry]->TMD1);
459
460 if (status & TF_OWN)
461 break;
462
463 priv->tx_ring[entry]->TMD1 &= 0xff00;
464
465 if (status & TF_ERR) {
466
467 int err_status = priv->tx_ring[entry]->TMD3;
468 priv->stats.tx_errors++;
469 if (err_status & EF_RTRY)
470 priv->stats.tx_aborted_errors++;
471 if (err_status & EF_LCAR)
472 priv->stats.tx_carrier_errors++;
473 if (err_status & EF_LCOL)
474 priv->stats.tx_window_errors++;
475 if (err_status & EF_UFLO) {
476
477 priv->stats.tx_fifo_errors++;
478
479 printk("%s: Tx FIFO error! Status %4.4x.\n", dev->name,
480 csr0);
481
482 board->Lance.RDP = STRT;
483 }
484 } else {
485 if (status & (TF_MORE|TF_ONE))
486 priv->stats.collisions++;
487 priv->stats.tx_packets++;
488 }
489 dirty_tx++;
490 }
491
492 #ifndef final_version
493 if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) {
494 printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
495 dirty_tx, priv->cur_tx, priv->tx_full);
496 dirty_tx += TX_RING_SIZE;
497 }
498 #endif
499
500 if (priv->tx_full && dev->tbusy &&
501 dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) {
502
503 priv->tx_full = 0;
504 dev->tbusy = 0;
505 mark_bh(NET_BH);
506 }
507
508 priv->dirty_tx = dirty_tx;
509 }
510
511
512 if (csr0 & BABL)
513 priv->stats.tx_errors++;
514 if (csr0 & MISS)
515 priv->stats.rx_errors++;
516 if (csr0 & MERR) {
517 printk("%s: Bus master arbitration failure, status %4.4x.\n",
518 dev->name, csr0);
519
520 board->Lance.RDP = STRT;
521 }
522 }
523
524
525 board->Lance.RAP = CSR0;
526 board->Lance.RDP = INEA|BABL|CERR|MISS|MERR|IDON;
527
528 #if 0
529 if (ariadne_debug > 4)
530 printk("%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name,
531 board->Lance.RAP, board->Lance.RDP);
532 #endif
533
534 dev->interrupt = 0;
535 return;
536 }
537
538
539 static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev)
540 {
541 struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
542 struct AriadneBoard *board = priv->board;
543 int entry;
544
545
546 if (dev->tbusy) {
547 int tickssofar = jiffies - dev->trans_start;
548 if (tickssofar < 20)
549 return(1);
550 board->Lance.RAP = CSR0;
551 printk("%s: transmit timed out, status %4.4x, resetting.\n", dev->name,
552 board->Lance.RDP);
553 board->Lance.RDP = STOP;
554 priv->stats.tx_errors++;
555 #ifndef final_version
556 {
557 int i;
558 printk(" Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
559 priv->dirty_tx, priv->cur_tx, priv->tx_full ? " (full)" : "",
560 priv->cur_rx);
561 for (i = 0 ; i < RX_RING_SIZE; i++)
562 printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
563 (swapw((priv->rx_ring[i]->RMD1))<<16)|swapw(priv->rx_ring[i]->RMD0),
564 swapw(-priv->rx_ring[i]->RMD2), swapw(priv->rx_ring[i]->RMD3));
565 for (i = 0 ; i < TX_RING_SIZE; i++)
566 printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
567 (swapw((priv->tx_ring[i]->TMD1))<<16)|swapw(priv->tx_ring[i]->TMD0),
568 swapw(-priv->tx_ring[i]->TMD2), priv->tx_ring[i]->TMD3);
569 printk("\n");
570 }
571 #endif
572 ariadne_init_ring(dev);
573 board->Lance.RDP = INEA|STRT;
574
575 dev->tbusy = 0;
576 dev->trans_start = jiffies;
577
578 return(0);
579 }
580
581 if (skb == NULL) {
582 dev_tint(dev);
583 return(0);
584 }
585
586 if (skb->len <= 0)
587 return(0);
588
589 #if 0
590 if (ariadne_debug > 3) {
591 board->Lance.RAP = CSR0;
592 printk("%s: ariadne_start_xmit() called, csr0 %4.4x.\n", dev->name,
593 board->Lance.RDP);
594 board->Lance.RDP = 0x0000;
595 }
596 #endif
597
598
599
600 if (set_bit(0, (void*)&dev->tbusy) != 0) {
601 printk("%s: Transmitter access conflict.\n", dev->name);
602 return(1);
603 }
604
605 if (set_bit(0, (void*)&priv->lock) != 0) {
606 if (ariadne_debug > 0)
607 printk("%s: tx queue lock!.\n", dev->name);
608
609 return(1);
610 }
611
612
613
614 #if 0
615 printk("TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]);
616 {
617 int i;
618 u_char *ptr = &((u_char *)skb->data)[6];
619 for (i = 0; i < 6; i++)
620 printk("%02x", ptr[i]);
621 }
622 printk(" to ");
623 {
624 int i;
625 u_char *ptr = (u_char *)skb->data;
626 for (i = 0; i < 6; i++)
627 printk("%02x", ptr[i]);
628 }
629 printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len);
630 #endif
631
632 entry = priv->cur_tx % TX_RING_SIZE;
633
634
635
636
637 priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len);
638 priv->tx_ring[entry]->TMD3 = 0x0000;
639 memcpyw(priv->tx_buff[entry], (u_short *)skb->data, skb->len);
640
641 #if 0
642 {
643 int i, len;
644
645 len = skb->len > 64 ? 64 : skb->len;
646 len >>= 1;
647 for (i = 0; i < len; i += 8) {
648 int j;
649 printk("%04x:", i);
650 for (j = 0; (j < 8) && ((i+j) < len); j++) {
651 if (!(j & 1))
652 printk(" ");
653 printk("%04x", priv->tx_buff[entry][i+j]);
654 }
655 printk("\n");
656 }
657 }
658 #endif
659
660 priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1&0xff00)|TF_OWN|TF_STP|TF_ENP;
661
662 dev_kfree_skb(skb, FREE_WRITE);
663
664 priv->cur_tx++;
665 if ((priv->cur_tx >= TX_RING_SIZE) && (priv->dirty_tx >= TX_RING_SIZE)) {
666
667 #if 0
668 printk("*** Subtracting TX_RING_SIZE from cur_tx (%d) and dirty_tx (%d)\n",
669 priv->cur_tx, priv->dirty_tx);
670 #endif
671
672 priv->cur_tx -= TX_RING_SIZE;
673 priv->dirty_tx -= TX_RING_SIZE;
674 }
675
676
677 board->Lance.RAP = CSR0;
678 board->Lance.RDP = INEA|TDMD;
679
680 dev->trans_start = jiffies;
681
682 cli();
683 priv->lock = 0;
684 if (lowb(priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1) == 0)
685 dev->tbusy = 0;
686 else
687 priv->tx_full = 1;
688 sti();
689
690 return(0);
691 }
692
693
694 static int ariadne_rx(struct device *dev)
695 {
696 struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
697 int entry = priv->cur_rx % RX_RING_SIZE;
698 int i;
699
700
701 while (!(lowb(priv->rx_ring[entry]->RMD1) & RF_OWN)) {
702 int status = lowb(priv->rx_ring[entry]->RMD1);
703
704 if (status != (RF_STP|RF_ENP)) {
705
706
707
708
709 if (status & RF_ENP)
710
711 priv->stats.rx_errors++;
712 if (status & RF_FRAM)
713 priv->stats.rx_frame_errors++;
714 if (status & RF_OFLO)
715 priv->stats.rx_over_errors++;
716 if (status & RF_CRC)
717 priv->stats.rx_crc_errors++;
718 if (status & RF_BUFF)
719 priv->stats.rx_fifo_errors++;
720 priv->rx_ring[entry]->RMD1 &= 0xff00|RF_STP|RF_ENP;
721 } else {
722
723 short pkt_len = swapw(priv->rx_ring[entry]->RMD3);
724 struct sk_buff *skb;
725
726 skb = dev_alloc_skb(pkt_len+2);
727 if (skb == NULL) {
728 printk("%s: Memory squeeze, deferring packet.\n", dev->name);
729 for (i = 0; i < RX_RING_SIZE; i++)
730 if (lowb(priv->rx_ring[(entry+i) % RX_RING_SIZE]->RMD1) & RF_OWN)
731 break;
732
733 if (i > RX_RING_SIZE-2) {
734 priv->stats.rx_dropped++;
735 priv->rx_ring[entry]->RMD1 |= RF_OWN;
736 priv->cur_rx++;
737 }
738 break;
739 }
740
741
742 skb->dev = dev;
743 skb_reserve(skb,2);
744 skb_put(skb,pkt_len);
745 eth_copy_and_sum(skb, (char *)priv->rx_buff[entry], pkt_len,0);
746 skb->protocol=eth_type_trans(skb,dev);
747 #if 0
748 printk("RX pkt type 0x%04x from ", ((u_short *)skb->data)[6]);
749 {
750 int i;
751 u_char *ptr = &((u_char *)skb->data)[6];
752 for (i = 0; i < 6; i++)
753 printk("%02x", ptr[i]);
754 }
755 printk(" to ");
756 {
757 int i;
758 u_char *ptr = (u_char *)skb->data;
759 for (i = 0; i < 6; i++)
760 printk("%02x", ptr[i]);
761 }
762 printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len);
763 #endif
764
765 netif_rx(skb);
766 priv->stats.rx_packets++;
767 }
768
769 priv->rx_ring[entry]->RMD1 |= RF_OWN;
770 entry = (++priv->cur_rx) % RX_RING_SIZE;
771 }
772
773 priv->cur_rx = priv->cur_rx % RX_RING_SIZE;
774
775
776
777
778 return(0);
779 }
780
781
782 static struct enet_statistics *ariadne_get_stats(struct device *dev)
783 {
784 struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
785 struct AriadneBoard *board = priv->board;
786 short saved_addr;
787
788 cli();
789 saved_addr = board->Lance.RAP;
790 board->Lance.RAP = CSR112;
791 priv->stats.rx_missed_errors = swapw(board->Lance.RDP);
792 board->Lance.RAP = saved_addr;
793 sti();
794
795 return(&priv->stats);
796 }
797
798
799
800
801
802
803
804
805 static void set_multicast_list(struct device *dev)
806 {
807 struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
808 struct AriadneBoard *board = priv->board;
809
810
811 board->Lance.RAP = CSR0;
812 board->Lance.RDP = STOP;
813
814 if (dev->flags & IFF_PROMISC) {
815
816 printk("%s: Promiscuous mode enabled.\n", dev->name);
817 board->Lance.RAP = CSR15;
818 board->Lance.RDP = PROM;
819 } else {
820 short multicast_table[4];
821 int num_addrs = dev->mc_count;
822 int i;
823
824 memset(multicast_table, (num_addrs == 0) ? 0 : -1,
825 sizeof(multicast_table));
826 for (i = 0; i < 4; i++) {
827 board->Lance.RAP = CSR8+(i<<8);
828 board->Lance.RDP = swapw(multicast_table[i]);
829 }
830 board->Lance.RAP = CSR15;
831 board->Lance.RDP = 0x0000;
832 }
833
834 board->Lance.RAP = CSR0;
835 board->Lance.RDP = INEA|STRT|IDON;
836 }