File: /usr/src/linux/drivers/net/ariadne.c

1     /*
2      *  Amiga Linux/m68k Ariadne Ethernet Driver
3      *
4      *  © Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org)
5      *			Peter De Schrijver
6      *		       (Peter.DeSchrijver@linux.cc.kuleuven.ac.be)
7      *
8      *  ---------------------------------------------------------------------------
9      *
10      *  This program is based on
11      *
12      *	lance.c:	An AMD LANCE ethernet driver for linux.
13      *			Written 1993-94 by Donald Becker.
14      *
15      *	Am79C960:	PCnet(tm)-ISA Single-Chip Ethernet Controller
16      *			Advanced Micro Devices
17      *			Publication #16907, Rev. B, Amendment/0, May 1994
18      *
19      *	MC68230:	Parallel Interface/Timer (PI/T)
20      *			Motorola Semiconductors, December, 1983
21      *
22      *  ---------------------------------------------------------------------------
23      *
24      *  This file is subject to the terms and conditions of the GNU General Public
25      *  License.  See the file COPYING in the main directory of the Linux
26      *  distribution for more details.
27      *
28      *  ---------------------------------------------------------------------------
29      *
30      *  The Ariadne is a Zorro-II board made by Village Tronic. It contains:
31      *
32      *	- an Am79C960 PCnet-ISA Single-Chip Ethernet Controller with both
33      *	  10BASE-2 (thin coax) and 10BASE-T (UTP) connectors
34      *
35      *	- an MC68230 Parallel Interface/Timer configured as 2 parallel ports
36      */
37     
38     #include <linux/module.h>
39     #include <linux/stddef.h>
40     #include <linux/kernel.h>
41     #include <linux/sched.h>
42     #include <linux/string.h>
43     #include <linux/ptrace.h>
44     #include <linux/errno.h>
45     #include <linux/ioport.h>
46     #include <linux/slab.h>
47     #include <linux/netdevice.h>
48     #include <linux/etherdevice.h>
49     #include <linux/interrupt.h>
50     #include <linux/skbuff.h>
51     #include <linux/init.h>
52     
53     #include <asm/bitops.h>
54     #include <asm/amigaints.h>
55     #include <asm/amigahw.h>
56     #include <linux/zorro.h>
57     #include <asm/io.h>
58     #include <asm/irq.h>
59     
60     #include "ariadne.h"
61     
62     
63     #ifdef ARIADNE_DEBUG
64     int ariadne_debug = ARIADNE_DEBUG;
65     #else
66     int ariadne_debug = 1;
67     #endif
68     
69     
70         /*
71          *	Macros to Fix Endianness problems
72          */
73     
74     				/* Swap the Bytes in a WORD */
75     #define swapw(x)	(((x>>8)&0x00ff)|((x<<8)&0xff00))
76     				/* Get the Low BYTE in a WORD */
77     #define lowb(x)		(x&0xff)
78     				/* Get the Swapped High WORD in a LONG */
79     #define swhighw(x)	((((x)>>8)&0xff00)|(((x)>>24)&0x00ff))
80     				/* Get the Swapped Low WORD in a LONG */
81     #define swloww(x)	((((x)<<8)&0xff00)|(((x)>>8)&0x00ff))
82     
83     
84         /*
85          *	Transmit/Receive Ring Definitions
86          */
87     
88     #define TX_RING_SIZE	5
89     #define RX_RING_SIZE	16
90     
91     #define PKT_BUF_SIZE	1520
92     
93     
94         /*
95          *	Private Device Data
96          */
97     
98     struct ariadne_private {
99         volatile struct TDRE *tx_ring[TX_RING_SIZE];
100         volatile struct RDRE *rx_ring[RX_RING_SIZE];
101         volatile u_short *tx_buff[TX_RING_SIZE];
102         volatile u_short *rx_buff[RX_RING_SIZE];
103         int cur_tx, cur_rx;			/* The next free ring entry */
104         int dirty_tx;			/* The ring entries to be free()ed. */
105         struct net_device_stats stats;
106         char tx_full;
107         struct net_device *dev;		/* Backpointer */
108         struct ariadne_private *next_module;
109     };
110     
111     
112         /*
113          *	Structure Created in the Ariadne's RAM Buffer
114          */
115     
116     struct lancedata {
117         struct TDRE tx_ring[TX_RING_SIZE];
118         struct RDRE rx_ring[RX_RING_SIZE];
119         u_short tx_buff[TX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)];
120         u_short rx_buff[RX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)];
121     };
122     
123     #ifdef MODULE
124     static struct ariadne_private *root_ariadne_dev;
125     #endif
126     
127     static int ariadne_open(struct net_device *dev);
128     static void ariadne_init_ring(struct net_device *dev);
129     static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev);
130     static void ariadne_tx_timeout(struct net_device *dev);
131     static int ariadne_rx(struct net_device *dev);
132     static void ariadne_reset(struct net_device *dev);
133     static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp);
134     static int ariadne_close(struct net_device *dev);
135     static struct net_device_stats *ariadne_get_stats(struct net_device *dev);
136     #ifdef HAVE_MULTICAST
137     static void set_multicast_list(struct net_device *dev);
138     #endif
139     
140     
141     static void memcpyw(volatile u_short *dest, u_short *src, int len)
142     {
143         while (len >= 2) {
144     	*(dest++) = *(src++);
145     	len -= 2;
146         }
147         if (len == 1)
148     	*dest = (*(u_char *)src)<<8;
149     }
150     
151     
152     static int __init ariadne_probe(void)
153     {
154         struct zorro_dev *z = NULL;
155         struct net_device *dev;
156         struct ariadne_private *priv;
157         int res = -ENODEV;
158     
159         while ((z = zorro_find_device(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE, z))) {
160     	unsigned long board = z->resource.start;
161     	unsigned long base_addr = board+ARIADNE_LANCE;
162     	unsigned long mem_start = board+ARIADNE_RAM;
163     	struct resource *r1, *r2;
164     
165     	r1 = request_mem_region(base_addr, sizeof(struct Am79C960),
166     		    		"Am79C960");
167     	if (!r1) continue;
168     	r2 = request_mem_region(mem_start, ARIADNE_RAM_SIZE, "RAM");
169     	if (!r2) {
170     	    release_resource(r1);
171     	    continue;
172     	}
173     
174     	dev = init_etherdev(NULL, sizeof(struct ariadne_private));
175     
176     	if (dev == NULL) {
177     	    release_resource(r1);
178     	    release_resource(r2);
179     	    return -ENOMEM;
180     	}
181     	SET_MODULE_OWNER(dev);
182     	priv = dev->priv;
183     
184     	r1->name = dev->name;
185     	r2->name = dev->name;
186     
187     	priv->dev = dev;
188     	dev->dev_addr[0] = 0x00;
189     	dev->dev_addr[1] = 0x60;
190     	dev->dev_addr[2] = 0x30;
191     	dev->dev_addr[3] = (z->rom.er_SerialNumber>>16) & 0xff;
192     	dev->dev_addr[4] = (z->rom.er_SerialNumber>>8) & 0xff;
193     	dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff;
194     	printk("%s: Ariadne at 0x%08lx, Ethernet Address "
195     	       "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board,
196     	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
197     	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
198     
199     	dev->base_addr = ZTWO_VADDR(base_addr);
200     	dev->mem_start = ZTWO_VADDR(mem_start);
201     	dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE;
202     
203     	dev->open = &ariadne_open;
204     	dev->stop = &ariadne_close;
205     	dev->hard_start_xmit = &ariadne_start_xmit;
206     	dev->tx_timeout = &ariadne_tx_timeout;
207     	dev->watchdog_timeo = 5*HZ;
208     	dev->get_stats = &ariadne_get_stats;
209     	dev->set_multicast_list = &set_multicast_list;
210     
211     #ifdef MODULE
212     	priv->next_module = root_ariadne_dev;
213     	root_ariadne_dev = priv;
214     #endif
215     	res = 0;
216         }
217         return res;
218     }
219     
220     
221     static int ariadne_open(struct net_device *dev)
222     {
223         volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
224         u_short in;
225         u_long version;
226         int i;
227     
228         /* Reset the LANCE */
229         in = lance->Reset;
230     
231         /* Stop the LANCE */
232         lance->RAP = CSR0;		/* PCnet-ISA Controller Status */
233         lance->RDP = STOP;
234     
235         /* Check the LANCE version */
236         lance->RAP = CSR88;		/* Chip ID */
237         version = swapw(lance->RDP);
238         lance->RAP = CSR89;		/* Chip ID */
239         version |= swapw(lance->RDP)<<16;
240         if ((version & 0x00000fff) != 0x00000003) {
241     	printk("ariadne_open: Couldn't find AMD Ethernet Chip\n");
242     	return -EAGAIN;
243         }
244         if ((version & 0x0ffff000) != 0x00003000) {
245     	printk("ariadne_open: Couldn't find Am79C960 (Wrong part number = %ld)\n",
246     	       (version & 0x0ffff000)>>12);
247     	return -EAGAIN;
248         }
249     #if 0
250         printk("ariadne_open: Am79C960 (PCnet-ISA) Revision %ld\n",
251     	   (version & 0xf0000000)>>28);
252     #endif
253     
254         ariadne_init_ring(dev);
255     
256         /* Miscellaneous Stuff */
257         lance->RAP = CSR3;		/* Interrupt Masks and Deferral Control */
258         lance->RDP = 0x0000;
259         lance->RAP = CSR4;		/* Test and Features Control */
260         lance->RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM;
261     
262         /* Set the Multicast Table */
263         lance->RAP = CSR8;		/* Logical Address Filter, LADRF[15:0] */
264         lance->RDP = 0x0000;
265         lance->RAP = CSR9;		/* Logical Address Filter, LADRF[31:16] */
266         lance->RDP = 0x0000;
267         lance->RAP = CSR10;		/* Logical Address Filter, LADRF[47:32] */
268         lance->RDP = 0x0000;
269         lance->RAP = CSR11;		/* Logical Address Filter, LADRF[63:48] */
270         lance->RDP = 0x0000;
271     
272         /* Set the Ethernet Hardware Address */
273         lance->RAP = CSR12;		/* Physical Address Register, PADR[15:0] */
274         lance->RDP = ((u_short *)&dev->dev_addr[0])[0];
275         lance->RAP = CSR13;		/* Physical Address Register, PADR[31:16] */
276         lance->RDP = ((u_short *)&dev->dev_addr[0])[1];
277         lance->RAP = CSR14;		/* Physical Address Register, PADR[47:32] */
278         lance->RDP = ((u_short *)&dev->dev_addr[0])[2];
279     
280         /* Set the Init Block Mode */
281         lance->RAP = CSR15;		/* Mode Register */
282         lance->RDP = 0x0000;
283     
284         /* Set the Transmit Descriptor Ring Pointer */
285         lance->RAP = CSR30;		/* Base Address of Transmit Ring */
286         lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_ring));
287         lance->RAP = CSR31;		/* Base Address of transmit Ring */
288         lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_ring));
289     
290         /* Set the Receive Descriptor Ring Pointer */
291         lance->RAP = CSR24;		/* Base Address of Receive Ring */
292         lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_ring));
293         lance->RAP = CSR25;		/* Base Address of Receive Ring */
294         lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_ring));
295     
296         /* Set the Number of RX and TX Ring Entries */
297         lance->RAP = CSR76;		/* Receive Ring Length */
298         lance->RDP = swapw(((u_short)-RX_RING_SIZE));
299         lance->RAP = CSR78;		/* Transmit Ring Length */
300         lance->RDP = swapw(((u_short)-TX_RING_SIZE));
301     
302         /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */
303         lance->RAP = ISACSR2;	/* Miscellaneous Configuration */
304         lance->IDP = ASEL;
305     
306         /* LED Control */
307         lance->RAP = ISACSR5;	/* LED1 Status */
308         lance->IDP = PSE|XMTE;
309         lance->RAP = ISACSR6;	/* LED2 Status */
310         lance->IDP = PSE|COLE;
311         lance->RAP = ISACSR7;	/* LED3 Status */
312         lance->IDP = PSE|RCVE;
313     
314         netif_start_queue(dev);
315     
316         i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, SA_SHIRQ,
317                         dev->name, dev);
318         if (i) return i;
319     
320         lance->RAP = CSR0;		/* PCnet-ISA Controller Status */
321         lance->RDP = INEA|STRT;
322     
323         return 0;
324     }
325     
326     
327     static void ariadne_init_ring(struct net_device *dev)
328     {
329         struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
330         volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start;
331         int i;
332     
333         netif_stop_queue(dev);
334     
335         priv->tx_full = 0;
336         priv->cur_rx = priv->cur_tx = 0;
337         priv->dirty_tx = 0;
338     
339         /* Set up TX Ring */
340         for (i = 0; i < TX_RING_SIZE; i++) {
341     	volatile struct TDRE *t = &lancedata->tx_ring[i];
342     	t->TMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i]));
343     	t->TMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])) |
344     		  TF_STP | TF_ENP;
345     	t->TMD2 = swapw((u_short)-PKT_BUF_SIZE);
346     	t->TMD3 = 0;
347     	priv->tx_ring[i] = &lancedata->tx_ring[i];
348     	priv->tx_buff[i] = lancedata->tx_buff[i];
349     #if 0
350     	printk("TX Entry %2d at %p, Buf at %p\n", i, &lancedata->tx_ring[i],
351     	       lancedata->tx_buff[i]);
352     #endif
353         }
354     
355         /* Set up RX Ring */
356         for (i = 0; i < RX_RING_SIZE; i++) {
357     	volatile struct RDRE *r = &lancedata->rx_ring[i];
358     	r->RMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i]));
359     	r->RMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])) |
360     		  RF_OWN;
361     	r->RMD2 = swapw((u_short)-PKT_BUF_SIZE);
362     	r->RMD3 = 0x0000;
363     	priv->rx_ring[i] = &lancedata->rx_ring[i];
364     	priv->rx_buff[i] = lancedata->rx_buff[i];
365     #if 0
366     	printk("RX Entry %2d at %p, Buf at %p\n", i, &lancedata->rx_ring[i],
367     	       lancedata->rx_buff[i]);
368     #endif
369         }
370     }
371     
372     
373     static int ariadne_close(struct net_device *dev)
374     {
375         struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
376         volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
377     
378         netif_stop_queue(dev);
379     
380         lance->RAP = CSR112;	/* Missed Frame Count */
381         priv->stats.rx_missed_errors = swapw(lance->RDP);
382         lance->RAP = CSR0;		/* PCnet-ISA Controller Status */
383     
384         if (ariadne_debug > 1) {
385     	printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name,
386     	       lance->RDP);
387     	printk("%s: %lu packets missed\n", dev->name,
388     	       priv->stats.rx_missed_errors);
389         }
390     
391         /* We stop the LANCE here -- it occasionally polls memory if we don't. */
392         lance->RDP = STOP;
393     
394         free_irq(IRQ_AMIGA_PORTS, dev);
395     
396         return 0;
397     }
398     
399     
400     static inline void ariadne_reset(struct net_device *dev)
401     {
402         volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
403     
404         lance->RAP = CSR0;	/* PCnet-ISA Controller Status */
405         lance->RDP = STOP;
406         ariadne_init_ring(dev);
407         lance->RDP = INEA|STRT;
408         netif_start_queue(dev);
409     }
410     
411     
412     static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp)
413     {
414         struct net_device *dev = (struct net_device *)data;
415         volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
416         struct ariadne_private *priv;
417         int csr0, boguscnt;
418     
419         if (dev == NULL) {
420     	printk("ariadne_interrupt(): irq for unknown device.\n");
421     	return;
422         }
423     
424         lance->RAP = CSR0;			/* PCnet-ISA Controller Status */
425     
426         if (!(lance->RDP & INTR))		/* Check if any interrupt has been */
427     	return;				/* generated by the board. */
428     
429         priv = (struct ariadne_private *)dev->priv;
430     
431         boguscnt = 10;
432         while ((csr0 = lance->RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) {
433     	/* Acknowledge all of the current interrupt sources ASAP. */
434     	lance->RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT);
435     
436     #if 0
437     	if (ariadne_debug > 5) {
438     	    printk("%s: interrupt  csr0=%#2.2x new csr=%#2.2x.", dev->name,
439     		   csr0, lance->RDP);
440     	    printk("[");
441     	    if (csr0 & INTR)
442     		printk(" INTR");
443     	    if (csr0 & INEA)
444     		printk(" INEA");
445     	    if (csr0 & RXON)
446     		printk(" RXON");
447     	    if (csr0 & TXON)
448     		printk(" TXON");
449     	    if (csr0 & TDMD)
450     		printk(" TDMD");
451     	    if (csr0 & STOP)
452     		printk(" STOP");
453     	    if (csr0 & STRT)
454     		printk(" STRT");
455     	    if (csr0 & INIT)
456     		printk(" INIT");
457     	    if (csr0 & ERR)
458     		printk(" ERR");
459     	    if (csr0 & BABL)
460     		printk(" BABL");
461     	    if (csr0 & CERR)
462     		printk(" CERR");
463     	    if (csr0 & MISS)
464     		printk(" MISS");
465     	    if (csr0 & MERR)
466     		printk(" MERR");
467     	    if (csr0 & RINT)
468     		printk(" RINT");
469     	    if (csr0 & TINT)
470     		printk(" TINT");
471     	    if (csr0 & IDON)
472     		printk(" IDON");
473     	    printk(" ]\n");
474     	}
475     #endif
476     
477     	if (csr0 & RINT)	/* Rx interrupt */
478     	    ariadne_rx(dev);
479     
480     	if (csr0 & TINT) {	/* Tx-done interrupt */
481     	    int dirty_tx = priv->dirty_tx;
482     
483     	    while (dirty_tx < priv->cur_tx) {
484     		int entry = dirty_tx % TX_RING_SIZE;
485     		int status = lowb(priv->tx_ring[entry]->TMD1);
486     
487     		if (status & TF_OWN)
488     		    break;	/* It still hasn't been Txed */
489     
490     		priv->tx_ring[entry]->TMD1 &= 0xff00;
491     
492     		if (status & TF_ERR) {
493     		    /* There was an major error, log it. */
494     		    int err_status = priv->tx_ring[entry]->TMD3;
495     		    priv->stats.tx_errors++;
496     		    if (err_status & EF_RTRY)
497     			priv->stats.tx_aborted_errors++;
498     		    if (err_status & EF_LCAR)
499     			priv->stats.tx_carrier_errors++;
500     		    if (err_status & EF_LCOL)
501     			priv->stats.tx_window_errors++;
502     		    if (err_status & EF_UFLO) {
503     			/* Ackk!  On FIFO errors the Tx unit is turned off! */
504     			priv->stats.tx_fifo_errors++;
505     			/* Remove this verbosity later! */
506     			printk("%s: Tx FIFO error! Status %4.4x.\n", dev->name,
507     			       csr0);
508     			/* Restart the chip. */
509     			lance->RDP = STRT;
510     		    }
511     		} else {
512     		    if (status & (TF_MORE|TF_ONE))
513     			priv->stats.collisions++;
514     		    priv->stats.tx_packets++;
515     		}
516     		dirty_tx++;
517     	    }
518     
519     #ifndef final_version
520     	    if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) {
521     		printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
522     		       dirty_tx, priv->cur_tx, priv->tx_full);
523     		dirty_tx += TX_RING_SIZE;
524     	    }
525     #endif
526     
527     	    if (priv->tx_full && netif_queue_stopped(dev) &&
528     		dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) {
529     		/* The ring is no longer full. */
530     		priv->tx_full = 0;
531     		netif_wake_queue(dev);
532     	    }
533     
534     	    priv->dirty_tx = dirty_tx;
535     	}
536     
537     	/* Log misc errors. */
538     	if (csr0 & BABL)
539     	    priv->stats.tx_errors++;	/* Tx babble. */
540     	if (csr0 & MISS)
541     	    priv->stats.rx_errors++;	/* Missed a Rx frame. */
542     	if (csr0 & MERR) {
543     	    printk("%s: Bus master arbitration failure, status %4.4x.\n",
544     		   dev->name, csr0);
545     	    /* Restart the chip. */
546     	    lance->RDP = STRT;
547     	}
548         }
549     
550         /* Clear any other interrupt, and set interrupt enable. */
551         lance->RAP = CSR0;		/* PCnet-ISA Controller Status */
552         lance->RDP = INEA|BABL|CERR|MISS|MERR|IDON;
553     
554     #if 0
555         if (ariadne_debug > 4)
556     	printk("%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name, lance->RAP,
557     	       lance->RDP);
558     #endif
559         return;
560     }
561     
562     
563     static void ariadne_tx_timeout(struct net_device *dev)
564     {
565         volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
566     
567         printk(KERN_ERR "%s: transmit timed out, status %4.4x, resetting.\n",
568     	   dev->name, lance->RDP);
569         ariadne_reset(dev);
570         netif_wake_queue(dev);
571     }
572     
573     
574     static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
575     {
576         struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
577         volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
578         int entry;
579         unsigned long flags;
580     
581     #if 0
582         if (ariadne_debug > 3) {
583     	lance->RAP = CSR0;	/* PCnet-ISA Controller Status */
584     	printk("%s: ariadne_start_xmit() called, csr0 %4.4x.\n", dev->name,
585     	       lance->RDP);
586     	lance->RDP = 0x0000;
587         }
588     #endif
589     
590         /* Fill in a Tx ring entry */
591     
592     #if 0
593         printk("TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]);
594         {
595     	int i;
596     	u_char *ptr = &((u_char *)skb->data)[6];
597     	for (i = 0; i < 6; i++)
598     	    printk("%02x", ptr[i]);
599         }
600         printk(" to ");
601         {
602     	int i;
603     	u_char *ptr = (u_char *)skb->data;
604     	for (i = 0; i < 6; i++)
605     	    printk("%02x", ptr[i]);
606         }
607         printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len);
608     #endif
609     
610         save_flags(flags);
611         cli();
612     
613         entry = priv->cur_tx % TX_RING_SIZE;
614     
615         /* Caution: the write order is important here, set the base address with
616     		the "ownership" bits last. */
617     
618         priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len);
619         priv->tx_ring[entry]->TMD3 = 0x0000;
620         memcpyw(priv->tx_buff[entry], (u_short *)skb->data,
621     	    skb->len <= ETH_ZLEN ? ETH_ZLEN : skb->len);
622     
623     #if 0
624         {
625     	int i, len;
626     
627     	len = skb->len > 64 ? 64 : skb->len;
628     	len >>= 1;
629     	for (i = 0; i < len; i += 8) {
630     	    int j;
631     	    printk("%04x:", i);
632     	    for (j = 0; (j < 8) && ((i+j) < len); j++) {
633     		if (!(j & 1))
634     		    printk(" ");
635     		printk("%04x", priv->tx_buff[entry][i+j]);
636     	    }
637     	    printk("\n");
638     	}
639         }
640     #endif
641     
642         priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1&0xff00)|TF_OWN|TF_STP|TF_ENP;
643     
644         dev_kfree_skb(skb);
645     
646         priv->cur_tx++;
647         if ((priv->cur_tx >= TX_RING_SIZE) && (priv->dirty_tx >= TX_RING_SIZE)) {
648     
649     #if 0
650     	printk("*** Subtracting TX_RING_SIZE from cur_tx (%d) and dirty_tx (%d)\n",
651     	       priv->cur_tx, priv->dirty_tx);
652     #endif
653     
654     	priv->cur_tx -= TX_RING_SIZE;
655     	priv->dirty_tx -= TX_RING_SIZE;
656         }
657     
658         /* Trigger an immediate send poll. */
659         lance->RAP = CSR0;		/* PCnet-ISA Controller Status */
660         lance->RDP = INEA|TDMD;
661     
662         dev->trans_start = jiffies;
663     
664         if (lowb(priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1) != 0) {
665     	netif_stop_queue(dev);
666     	priv->tx_full = 1;
667         }
668         restore_flags(flags);
669     
670         return 0;
671     }
672     
673     
674     static int ariadne_rx(struct net_device *dev)
675     {
676         struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
677         int entry = priv->cur_rx % RX_RING_SIZE;
678         int i;
679     
680         /* If we own the next entry, it's a new packet. Send it up. */
681         while (!(lowb(priv->rx_ring[entry]->RMD1) & RF_OWN)) {
682     	int status = lowb(priv->rx_ring[entry]->RMD1);
683     
684     	if (status != (RF_STP|RF_ENP)) {	/* There was an error. */
685     	    /* There is a tricky error noted by John Murphy,
686     		<murf@perftech.com> to Russ Nelson: Even with full-sized
687     		buffers it's possible for a jabber packet to use two
688     		buffers, with only the last correctly noting the error. */
689     	    if (status & RF_ENP)
690     		/* Only count a general error at the end of a packet.*/
691     		priv->stats.rx_errors++;
692     	    if (status & RF_FRAM)
693     		priv->stats.rx_frame_errors++;
694     	    if (status & RF_OFLO)
695     		priv->stats.rx_over_errors++;
696     	    if (status & RF_CRC)
697     		priv->stats.rx_crc_errors++;
698     	    if (status & RF_BUFF)
699     		priv->stats.rx_fifo_errors++;
700     	    priv->rx_ring[entry]->RMD1 &= 0xff00|RF_STP|RF_ENP;
701     	} else {
702     	    /* Malloc up new buffer, compatible with net-3. */
703     	    short pkt_len = swapw(priv->rx_ring[entry]->RMD3);
704     	    struct sk_buff *skb;
705     
706     	    skb = dev_alloc_skb(pkt_len+2);
707     	    if (skb == NULL) {
708     		printk("%s: Memory squeeze, deferring packet.\n", dev->name);
709     		for (i = 0; i < RX_RING_SIZE; i++)
710     		    if (lowb(priv->rx_ring[(entry+i) % RX_RING_SIZE]->RMD1) & RF_OWN)
711     			break;
712     
713     		if (i > RX_RING_SIZE-2) {
714     		    priv->stats.rx_dropped++;
715     		    priv->rx_ring[entry]->RMD1 |= RF_OWN;
716     		    priv->cur_rx++;
717     		}
718     		break;
719     	    }
720     
721     
722     	    skb->dev = dev;
723     	    skb_reserve(skb,2);		/* 16 byte align */
724     	    skb_put(skb,pkt_len);	/* Make room */
725     	    eth_copy_and_sum(skb, (char *)priv->rx_buff[entry], pkt_len,0);
726     	    skb->protocol=eth_type_trans(skb,dev);
727     #if 0
728     	    printk("RX pkt type 0x%04x from ", ((u_short *)skb->data)[6]);
729     	    {
730     		int i;
731     		u_char *ptr = &((u_char *)skb->data)[6];
732     		for (i = 0; i < 6; i++)
733     		    printk("%02x", ptr[i]);
734     	    }
735     	    printk(" to ");
736     	    {
737     		int i;
738     		u_char *ptr = (u_char *)skb->data;
739     		for (i = 0; i < 6; i++)
740     		    printk("%02x", ptr[i]);
741     	    }
742     	    printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len);
743     #endif
744     
745     	    netif_rx(skb);
746     	    dev->last_rx = jiffies;
747     	    priv->stats.rx_packets++;
748     	    priv->stats.rx_bytes += pkt_len;
749     	}
750     
751     	priv->rx_ring[entry]->RMD1 |= RF_OWN;
752     	entry = (++priv->cur_rx) % RX_RING_SIZE;
753         }
754     
755         priv->cur_rx = priv->cur_rx % RX_RING_SIZE;
756     
757         /* We should check that at least two ring entries are free.	 If not,
758            we should free one and mark stats->rx_dropped++. */
759     
760         return 0;
761     }
762     
763     
764     static struct net_device_stats *ariadne_get_stats(struct net_device *dev)
765     {
766         struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
767         volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
768         short saved_addr;
769         unsigned long flags;
770     
771         save_flags(flags);
772         cli();
773         saved_addr = lance->RAP;
774         lance->RAP = CSR112;		/* Missed Frame Count */
775         priv->stats.rx_missed_errors = swapw(lance->RDP);
776         lance->RAP = saved_addr;
777         restore_flags(flags);
778     
779         return &priv->stats;
780     }
781     
782     
783     /* Set or clear the multicast filter for this adaptor.
784         num_addrs == -1	Promiscuous mode, receive all packets
785         num_addrs == 0	Normal mode, clear multicast list
786         num_addrs > 0	Multicast mode, receive normal and MC packets, and do
787     			best-effort filtering.
788      */
789     static void set_multicast_list(struct net_device *dev)
790     {
791         volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
792     
793         if (!netif_running(dev))
794     	return;
795     
796         netif_stop_queue(dev);
797     
798         /* We take the simple way out and always enable promiscuous mode. */
799         lance->RAP = CSR0;			/* PCnet-ISA Controller Status */
800         lance->RDP = STOP;			/* Temporarily stop the lance. */
801         ariadne_init_ring(dev);
802     
803         if (dev->flags & IFF_PROMISC) {
804     	/* Log any net taps. */
805     	printk("%s: Promiscuous mode enabled.\n", dev->name);
806     	lance->RAP = CSR15;		/* Mode Register */
807     	lance->RDP = PROM;		/* Set promiscuous mode */
808         } else {
809     	short multicast_table[4];
810     	int num_addrs = dev->mc_count;
811     	int i;
812     	/* We don't use the multicast table, but rely on upper-layer filtering. */
813     	memset(multicast_table, (num_addrs == 0) ? 0 : -1,
814     	       sizeof(multicast_table));
815     	for (i = 0; i < 4; i++) {
816     	    lance->RAP = CSR8+(i<<8);	/* Logical Address Filter */
817     	    lance->RDP = swapw(multicast_table[i]);
818     	}
819     	lance->RAP = CSR15;		/* Mode Register */
820     	lance->RDP = 0x0000;		/* Unset promiscuous mode */
821         }
822     
823         lance->RAP = CSR0;			/* PCnet-ISA Controller Status */
824         lance->RDP = INEA|STRT|IDON;	/* Resume normal operation. */
825     
826         netif_wake_queue(dev);
827     }
828     
829     
830     static void __exit ariadne_cleanup(void)
831     {
832     #ifdef MODULE
833         struct ariadne_private *next;
834         struct net_device *dev;
835     
836         while (root_ariadne_dev) {
837     	next = root_ariadne_dev->next_module;
838     	dev = root_ariadne_dev->dev;
839     	unregister_netdev(dev);
840     	release_mem_region(ZTWO_PADDR(dev->base_addr), sizeof(struct Am79C960));
841     	release_mem_region(ZTWO_PADDR(dev->mem_start), ARIADNE_RAM_SIZE);
842     	kfree(dev);
843     	root_ariadne_dev = next;
844         }
845     #endif
846     }
847     
848     module_init(ariadne_probe);
849     module_exit(ariadne_cleanup);
850