xref: /openbmc/linux/drivers/net/ethernet/amd/atarilance.c (revision b955f6ca776f3bab3d1e2c5fb1d247b203cbda14)
1*b955f6caSJeff Kirsher /* atarilance.c: Ethernet driver for VME Lance cards on the Atari */
2*b955f6caSJeff Kirsher /*
3*b955f6caSJeff Kirsher 	Written 1995/96 by Roman Hodek (Roman.Hodek@informatik.uni-erlangen.de)
4*b955f6caSJeff Kirsher 
5*b955f6caSJeff Kirsher 	This software may be used and distributed according to the terms
6*b955f6caSJeff Kirsher 	of the GNU General Public License, incorporated herein by reference.
7*b955f6caSJeff Kirsher 
8*b955f6caSJeff Kirsher 	This drivers was written with the following sources of reference:
9*b955f6caSJeff Kirsher 	 - The driver for the Riebl Lance card by the TU Vienna.
10*b955f6caSJeff Kirsher 	 - The modified TUW driver for PAM's VME cards
11*b955f6caSJeff Kirsher 	 - The PC-Linux driver for Lance cards (but this is for bus master
12*b955f6caSJeff Kirsher        cards, not the shared memory ones)
13*b955f6caSJeff Kirsher 	 - The Amiga Ariadne driver
14*b955f6caSJeff Kirsher 
15*b955f6caSJeff Kirsher 	v1.0: (in 1.2.13pl4/0.9.13)
16*b955f6caSJeff Kirsher 	      Initial version
17*b955f6caSJeff Kirsher 	v1.1: (in 1.2.13pl5)
18*b955f6caSJeff Kirsher 	      more comments
19*b955f6caSJeff Kirsher 		  deleted some debugging stuff
20*b955f6caSJeff Kirsher 		  optimized register access (keep AREG pointing to CSR0)
21*b955f6caSJeff Kirsher 		  following AMD, CSR0_STRT should be set only after IDON is detected
22*b955f6caSJeff Kirsher 		  use memcpy() for data transfers, that also employs long word moves
23*b955f6caSJeff Kirsher 		  better probe procedure for 24-bit systems
24*b955f6caSJeff Kirsher           non-VME-RieblCards need extra delays in memcpy
25*b955f6caSJeff Kirsher 		  must also do write test, since 0xfxe00000 may hit ROM
26*b955f6caSJeff Kirsher 		  use 8/32 tx/rx buffers, which should give better NFS performance;
27*b955f6caSJeff Kirsher 		    this is made possible by shifting the last packet buffer after the
28*b955f6caSJeff Kirsher 		    RieblCard reserved area
29*b955f6caSJeff Kirsher     v1.2: (in 1.2.13pl8)
30*b955f6caSJeff Kirsher 	      again fixed probing for the Falcon; 0xfe01000 hits phys. 0x00010000
31*b955f6caSJeff Kirsher 		  and thus RAM, in case of no Lance found all memory contents have to
32*b955f6caSJeff Kirsher 		  be restored!
33*b955f6caSJeff Kirsher 		  Now possible to compile as module.
34*b955f6caSJeff Kirsher 	v1.3: 03/30/96 Jes Sorensen, Roman (in 1.3)
35*b955f6caSJeff Kirsher 	      Several little 1.3 adaptions
36*b955f6caSJeff Kirsher 		  When the lance is stopped it jumps back into little-endian
37*b955f6caSJeff Kirsher 		  mode. It is therefore necessary to put it back where it
38*b955f6caSJeff Kirsher 		  belongs, in big endian mode, in order to make things work.
39*b955f6caSJeff Kirsher 		  This might be the reason why multicast-mode didn't work
40*b955f6caSJeff Kirsher 		  before, but I'm not able to test it as I only got an Amiga
41*b955f6caSJeff Kirsher 		  (we had similar problems with the A2065 driver).
42*b955f6caSJeff Kirsher 
43*b955f6caSJeff Kirsher */
44*b955f6caSJeff Kirsher 
45*b955f6caSJeff Kirsher static char version[] = "atarilance.c: v1.3 04/04/96 "
46*b955f6caSJeff Kirsher 					   "Roman.Hodek@informatik.uni-erlangen.de\n";
47*b955f6caSJeff Kirsher 
48*b955f6caSJeff Kirsher #include <linux/netdevice.h>
49*b955f6caSJeff Kirsher #include <linux/etherdevice.h>
50*b955f6caSJeff Kirsher #include <linux/module.h>
51*b955f6caSJeff Kirsher #include <linux/stddef.h>
52*b955f6caSJeff Kirsher #include <linux/kernel.h>
53*b955f6caSJeff Kirsher #include <linux/string.h>
54*b955f6caSJeff Kirsher #include <linux/errno.h>
55*b955f6caSJeff Kirsher #include <linux/skbuff.h>
56*b955f6caSJeff Kirsher #include <linux/interrupt.h>
57*b955f6caSJeff Kirsher #include <linux/init.h>
58*b955f6caSJeff Kirsher #include <linux/bitops.h>
59*b955f6caSJeff Kirsher 
60*b955f6caSJeff Kirsher #include <asm/setup.h>
61*b955f6caSJeff Kirsher #include <asm/irq.h>
62*b955f6caSJeff Kirsher #include <asm/atarihw.h>
63*b955f6caSJeff Kirsher #include <asm/atariints.h>
64*b955f6caSJeff Kirsher #include <asm/io.h>
65*b955f6caSJeff Kirsher 
66*b955f6caSJeff Kirsher /* Debug level:
67*b955f6caSJeff Kirsher  *  0 = silent, print only serious errors
68*b955f6caSJeff Kirsher  *  1 = normal, print error messages
69*b955f6caSJeff Kirsher  *  2 = debug, print debug infos
70*b955f6caSJeff Kirsher  *  3 = debug, print even more debug infos (packet data)
71*b955f6caSJeff Kirsher  */
72*b955f6caSJeff Kirsher 
73*b955f6caSJeff Kirsher #define	LANCE_DEBUG	1
74*b955f6caSJeff Kirsher 
75*b955f6caSJeff Kirsher #ifdef LANCE_DEBUG
76*b955f6caSJeff Kirsher static int lance_debug = LANCE_DEBUG;
77*b955f6caSJeff Kirsher #else
78*b955f6caSJeff Kirsher static int lance_debug = 1;
79*b955f6caSJeff Kirsher #endif
80*b955f6caSJeff Kirsher module_param(lance_debug, int, 0);
81*b955f6caSJeff Kirsher MODULE_PARM_DESC(lance_debug, "atarilance debug level (0-3)");
82*b955f6caSJeff Kirsher MODULE_LICENSE("GPL");
83*b955f6caSJeff Kirsher 
84*b955f6caSJeff Kirsher /* Print debug messages on probing? */
85*b955f6caSJeff Kirsher #undef LANCE_DEBUG_PROBE
86*b955f6caSJeff Kirsher 
87*b955f6caSJeff Kirsher #define	DPRINTK(n,a)							\
88*b955f6caSJeff Kirsher 	do {										\
89*b955f6caSJeff Kirsher 		if (lance_debug >= n)					\
90*b955f6caSJeff Kirsher 			printk a;							\
91*b955f6caSJeff Kirsher 	} while( 0 )
92*b955f6caSJeff Kirsher 
93*b955f6caSJeff Kirsher #ifdef LANCE_DEBUG_PROBE
94*b955f6caSJeff Kirsher # define PROBE_PRINT(a)	printk a
95*b955f6caSJeff Kirsher #else
96*b955f6caSJeff Kirsher # define PROBE_PRINT(a)
97*b955f6caSJeff Kirsher #endif
98*b955f6caSJeff Kirsher 
99*b955f6caSJeff Kirsher /* These define the number of Rx and Tx buffers as log2. (Only powers
100*b955f6caSJeff Kirsher  * of two are valid)
101*b955f6caSJeff Kirsher  * Much more rx buffers (32) are reserved than tx buffers (8), since receiving
102*b955f6caSJeff Kirsher  * is more time critical then sending and packets may have to remain in the
103*b955f6caSJeff Kirsher  * board's memory when main memory is low.
104*b955f6caSJeff Kirsher  */
105*b955f6caSJeff Kirsher 
106*b955f6caSJeff Kirsher #define TX_LOG_RING_SIZE			3
107*b955f6caSJeff Kirsher #define RX_LOG_RING_SIZE			5
108*b955f6caSJeff Kirsher 
109*b955f6caSJeff Kirsher /* These are the derived values */
110*b955f6caSJeff Kirsher 
111*b955f6caSJeff Kirsher #define TX_RING_SIZE			(1 << TX_LOG_RING_SIZE)
112*b955f6caSJeff Kirsher #define TX_RING_LEN_BITS		(TX_LOG_RING_SIZE << 5)
113*b955f6caSJeff Kirsher #define	TX_RING_MOD_MASK		(TX_RING_SIZE - 1)
114*b955f6caSJeff Kirsher 
115*b955f6caSJeff Kirsher #define RX_RING_SIZE			(1 << RX_LOG_RING_SIZE)
116*b955f6caSJeff Kirsher #define RX_RING_LEN_BITS		(RX_LOG_RING_SIZE << 5)
117*b955f6caSJeff Kirsher #define	RX_RING_MOD_MASK		(RX_RING_SIZE - 1)
118*b955f6caSJeff Kirsher 
119*b955f6caSJeff Kirsher #define TX_TIMEOUT	(HZ/5)
120*b955f6caSJeff Kirsher 
121*b955f6caSJeff Kirsher /* The LANCE Rx and Tx ring descriptors. */
122*b955f6caSJeff Kirsher struct lance_rx_head {
123*b955f6caSJeff Kirsher 	unsigned short			base;		/* Low word of base addr */
124*b955f6caSJeff Kirsher 	volatile unsigned char	flag;
125*b955f6caSJeff Kirsher 	unsigned char			base_hi;	/* High word of base addr (unused) */
126*b955f6caSJeff Kirsher 	short					buf_length;	/* This length is 2s complement! */
127*b955f6caSJeff Kirsher 	volatile short			msg_length;	/* This length is "normal". */
128*b955f6caSJeff Kirsher };
129*b955f6caSJeff Kirsher 
130*b955f6caSJeff Kirsher struct lance_tx_head {
131*b955f6caSJeff Kirsher 	unsigned short			base;		/* Low word of base addr */
132*b955f6caSJeff Kirsher 	volatile unsigned char	flag;
133*b955f6caSJeff Kirsher 	unsigned char			base_hi;	/* High word of base addr (unused) */
134*b955f6caSJeff Kirsher 	short					length;		/* Length is 2s complement! */
135*b955f6caSJeff Kirsher 	volatile short			misc;
136*b955f6caSJeff Kirsher };
137*b955f6caSJeff Kirsher 
138*b955f6caSJeff Kirsher struct ringdesc {
139*b955f6caSJeff Kirsher 	unsigned short	adr_lo;		/* Low 16 bits of address */
140*b955f6caSJeff Kirsher 	unsigned char	len;		/* Length bits */
141*b955f6caSJeff Kirsher 	unsigned char	adr_hi;		/* High 8 bits of address (unused) */
142*b955f6caSJeff Kirsher };
143*b955f6caSJeff Kirsher 
144*b955f6caSJeff Kirsher /* The LANCE initialization block, described in databook. */
145*b955f6caSJeff Kirsher struct lance_init_block {
146*b955f6caSJeff Kirsher 	unsigned short	mode;		/* Pre-set mode */
147*b955f6caSJeff Kirsher 	unsigned char	hwaddr[6];	/* Physical ethernet address */
148*b955f6caSJeff Kirsher 	unsigned		filter[2];	/* Multicast filter (unused). */
149*b955f6caSJeff Kirsher 	/* Receive and transmit ring base, along with length bits. */
150*b955f6caSJeff Kirsher 	struct ringdesc	rx_ring;
151*b955f6caSJeff Kirsher 	struct ringdesc	tx_ring;
152*b955f6caSJeff Kirsher };
153*b955f6caSJeff Kirsher 
154*b955f6caSJeff Kirsher /* The whole layout of the Lance shared memory */
155*b955f6caSJeff Kirsher struct lance_memory {
156*b955f6caSJeff Kirsher 	struct lance_init_block	init;
157*b955f6caSJeff Kirsher 	struct lance_tx_head	tx_head[TX_RING_SIZE];
158*b955f6caSJeff Kirsher 	struct lance_rx_head	rx_head[RX_RING_SIZE];
159*b955f6caSJeff Kirsher 	char					packet_area[0];	/* packet data follow after the
160*b955f6caSJeff Kirsher 											 * init block and the ring
161*b955f6caSJeff Kirsher 											 * descriptors and are located
162*b955f6caSJeff Kirsher 											 * at runtime */
163*b955f6caSJeff Kirsher };
164*b955f6caSJeff Kirsher 
165*b955f6caSJeff Kirsher /* RieblCard specifics:
166*b955f6caSJeff Kirsher  * The original TOS driver for these cards reserves the area from offset
167*b955f6caSJeff Kirsher  * 0xee70 to 0xeebb for storing configuration data. Of interest to us is the
168*b955f6caSJeff Kirsher  * Ethernet address there, and the magic for verifying the data's validity.
169*b955f6caSJeff Kirsher  * The reserved area isn't touch by packet buffers. Furthermore, offset 0xfffe
170*b955f6caSJeff Kirsher  * is reserved for the interrupt vector number.
171*b955f6caSJeff Kirsher  */
172*b955f6caSJeff Kirsher #define	RIEBL_RSVD_START	0xee70
173*b955f6caSJeff Kirsher #define	RIEBL_RSVD_END		0xeec0
174*b955f6caSJeff Kirsher #define RIEBL_MAGIC			0x09051990
175*b955f6caSJeff Kirsher #define RIEBL_MAGIC_ADDR	((unsigned long *)(((char *)MEM) + 0xee8a))
176*b955f6caSJeff Kirsher #define RIEBL_HWADDR_ADDR	((unsigned char *)(((char *)MEM) + 0xee8e))
177*b955f6caSJeff Kirsher #define RIEBL_IVEC_ADDR		((unsigned short *)(((char *)MEM) + 0xfffe))
178*b955f6caSJeff Kirsher 
179*b955f6caSJeff Kirsher /* This is a default address for the old RieblCards without a battery
180*b955f6caSJeff Kirsher  * that have no ethernet address at boot time. 00:00:36:04 is the
181*b955f6caSJeff Kirsher  * prefix for Riebl cards, the 00:00 at the end is arbitrary.
182*b955f6caSJeff Kirsher  */
183*b955f6caSJeff Kirsher 
184*b955f6caSJeff Kirsher static unsigned char OldRieblDefHwaddr[6] = {
185*b955f6caSJeff Kirsher 	0x00, 0x00, 0x36, 0x04, 0x00, 0x00
186*b955f6caSJeff Kirsher };
187*b955f6caSJeff Kirsher 
188*b955f6caSJeff Kirsher 
189*b955f6caSJeff Kirsher /* I/O registers of the Lance chip */
190*b955f6caSJeff Kirsher 
191*b955f6caSJeff Kirsher struct lance_ioreg {
192*b955f6caSJeff Kirsher /* base+0x0 */	volatile unsigned short	data;
193*b955f6caSJeff Kirsher /* base+0x2 */	volatile unsigned short	addr;
194*b955f6caSJeff Kirsher 				unsigned char			_dummy1[3];
195*b955f6caSJeff Kirsher /* base+0x7 */	volatile unsigned char	ivec;
196*b955f6caSJeff Kirsher 				unsigned char			_dummy2[5];
197*b955f6caSJeff Kirsher /* base+0xd */	volatile unsigned char	eeprom;
198*b955f6caSJeff Kirsher 				unsigned char			_dummy3;
199*b955f6caSJeff Kirsher /* base+0xf */	volatile unsigned char	mem;
200*b955f6caSJeff Kirsher };
201*b955f6caSJeff Kirsher 
202*b955f6caSJeff Kirsher /* Types of boards this driver supports */
203*b955f6caSJeff Kirsher 
204*b955f6caSJeff Kirsher enum lance_type {
205*b955f6caSJeff Kirsher 	OLD_RIEBL,		/* old Riebl card without battery */
206*b955f6caSJeff Kirsher 	NEW_RIEBL,		/* new Riebl card with battery */
207*b955f6caSJeff Kirsher 	PAM_CARD		/* PAM card with EEPROM */
208*b955f6caSJeff Kirsher };
209*b955f6caSJeff Kirsher 
210*b955f6caSJeff Kirsher static char *lance_names[] = {
211*b955f6caSJeff Kirsher 	"Riebl-Card (without battery)",
212*b955f6caSJeff Kirsher 	"Riebl-Card (with battery)",
213*b955f6caSJeff Kirsher 	"PAM intern card"
214*b955f6caSJeff Kirsher };
215*b955f6caSJeff Kirsher 
216*b955f6caSJeff Kirsher /* The driver's private device structure */
217*b955f6caSJeff Kirsher 
218*b955f6caSJeff Kirsher struct lance_private {
219*b955f6caSJeff Kirsher 	enum lance_type		cardtype;
220*b955f6caSJeff Kirsher 	struct lance_ioreg	*iobase;
221*b955f6caSJeff Kirsher 	struct lance_memory	*mem;
222*b955f6caSJeff Kirsher 	int		 	cur_rx, cur_tx;	/* The next free ring entry */
223*b955f6caSJeff Kirsher 	int			dirty_tx;		/* Ring entries to be freed. */
224*b955f6caSJeff Kirsher 				/* copy function */
225*b955f6caSJeff Kirsher 	void			*(*memcpy_f)( void *, const void *, size_t );
226*b955f6caSJeff Kirsher /* This must be long for set_bit() */
227*b955f6caSJeff Kirsher 	long			tx_full;
228*b955f6caSJeff Kirsher 	spinlock_t		devlock;
229*b955f6caSJeff Kirsher };
230*b955f6caSJeff Kirsher 
231*b955f6caSJeff Kirsher /* I/O register access macros */
232*b955f6caSJeff Kirsher 
233*b955f6caSJeff Kirsher #define	MEM		lp->mem
234*b955f6caSJeff Kirsher #define	DREG	IO->data
235*b955f6caSJeff Kirsher #define	AREG	IO->addr
236*b955f6caSJeff Kirsher #define	REGA(a)	(*( AREG = (a), &DREG ))
237*b955f6caSJeff Kirsher 
238*b955f6caSJeff Kirsher /* Definitions for packet buffer access: */
239*b955f6caSJeff Kirsher #define PKT_BUF_SZ		1544
240*b955f6caSJeff Kirsher /* Get the address of a packet buffer corresponding to a given buffer head */
241*b955f6caSJeff Kirsher #define	PKTBUF_ADDR(head)	(((unsigned char *)(MEM)) + (head)->base)
242*b955f6caSJeff Kirsher 
243*b955f6caSJeff Kirsher /* Possible memory/IO addresses for probing */
244*b955f6caSJeff Kirsher 
245*b955f6caSJeff Kirsher static struct lance_addr {
246*b955f6caSJeff Kirsher 	unsigned long	memaddr;
247*b955f6caSJeff Kirsher 	unsigned long	ioaddr;
248*b955f6caSJeff Kirsher 	int				slow_flag;
249*b955f6caSJeff Kirsher } lance_addr_list[] = {
250*b955f6caSJeff Kirsher 	{ 0xfe010000, 0xfe00fff0, 0 },	/* RieblCard VME in TT */
251*b955f6caSJeff Kirsher 	{ 0xffc10000, 0xffc0fff0, 0 },	/* RieblCard VME in MegaSTE
252*b955f6caSJeff Kirsher 									   (highest byte stripped) */
253*b955f6caSJeff Kirsher 	{ 0xffe00000, 0xffff7000, 1 },	/* RieblCard in ST
254*b955f6caSJeff Kirsher 									   (highest byte stripped) */
255*b955f6caSJeff Kirsher 	{ 0xffd00000, 0xffff7000, 1 },	/* RieblCard in ST with hw modif. to
256*b955f6caSJeff Kirsher 									   avoid conflict with ROM
257*b955f6caSJeff Kirsher 									   (highest byte stripped) */
258*b955f6caSJeff Kirsher 	{ 0xffcf0000, 0xffcffff0, 0 },	/* PAMCard VME in TT and MSTE
259*b955f6caSJeff Kirsher 									   (highest byte stripped) */
260*b955f6caSJeff Kirsher 	{ 0xfecf0000, 0xfecffff0, 0 },	/* Rhotron's PAMCard VME in TT and MSTE
261*b955f6caSJeff Kirsher 									   (highest byte stripped) */
262*b955f6caSJeff Kirsher };
263*b955f6caSJeff Kirsher 
264*b955f6caSJeff Kirsher #define	N_LANCE_ADDR	ARRAY_SIZE(lance_addr_list)
265*b955f6caSJeff Kirsher 
266*b955f6caSJeff Kirsher 
267*b955f6caSJeff Kirsher /* Definitions for the Lance */
268*b955f6caSJeff Kirsher 
269*b955f6caSJeff Kirsher /* tx_head flags */
270*b955f6caSJeff Kirsher #define TMD1_ENP		0x01	/* end of packet */
271*b955f6caSJeff Kirsher #define TMD1_STP		0x02	/* start of packet */
272*b955f6caSJeff Kirsher #define TMD1_DEF		0x04	/* deferred */
273*b955f6caSJeff Kirsher #define TMD1_ONE		0x08	/* one retry needed */
274*b955f6caSJeff Kirsher #define TMD1_MORE		0x10	/* more than one retry needed */
275*b955f6caSJeff Kirsher #define TMD1_ERR		0x40	/* error summary */
276*b955f6caSJeff Kirsher #define TMD1_OWN 		0x80	/* ownership (set: chip owns) */
277*b955f6caSJeff Kirsher 
278*b955f6caSJeff Kirsher #define TMD1_OWN_CHIP	TMD1_OWN
279*b955f6caSJeff Kirsher #define TMD1_OWN_HOST	0
280*b955f6caSJeff Kirsher 
281*b955f6caSJeff Kirsher /* tx_head misc field */
282*b955f6caSJeff Kirsher #define TMD3_TDR		0x03FF	/* Time Domain Reflectometry counter */
283*b955f6caSJeff Kirsher #define TMD3_RTRY		0x0400	/* failed after 16 retries */
284*b955f6caSJeff Kirsher #define TMD3_LCAR		0x0800	/* carrier lost */
285*b955f6caSJeff Kirsher #define TMD3_LCOL		0x1000	/* late collision */
286*b955f6caSJeff Kirsher #define TMD3_UFLO		0x4000	/* underflow (late memory) */
287*b955f6caSJeff Kirsher #define TMD3_BUFF		0x8000	/* buffering error (no ENP) */
288*b955f6caSJeff Kirsher 
289*b955f6caSJeff Kirsher /* rx_head flags */
290*b955f6caSJeff Kirsher #define RMD1_ENP		0x01	/* end of packet */
291*b955f6caSJeff Kirsher #define RMD1_STP		0x02	/* start of packet */
292*b955f6caSJeff Kirsher #define RMD1_BUFF		0x04	/* buffer error */
293*b955f6caSJeff Kirsher #define RMD1_CRC		0x08	/* CRC error */
294*b955f6caSJeff Kirsher #define RMD1_OFLO		0x10	/* overflow */
295*b955f6caSJeff Kirsher #define RMD1_FRAM		0x20	/* framing error */
296*b955f6caSJeff Kirsher #define RMD1_ERR		0x40	/* error summary */
297*b955f6caSJeff Kirsher #define RMD1_OWN 		0x80	/* ownership (set: ship owns) */
298*b955f6caSJeff Kirsher 
299*b955f6caSJeff Kirsher #define RMD1_OWN_CHIP	RMD1_OWN
300*b955f6caSJeff Kirsher #define RMD1_OWN_HOST	0
301*b955f6caSJeff Kirsher 
302*b955f6caSJeff Kirsher /* register names */
303*b955f6caSJeff Kirsher #define CSR0	0		/* mode/status */
304*b955f6caSJeff Kirsher #define CSR1	1		/* init block addr (low) */
305*b955f6caSJeff Kirsher #define CSR2	2		/* init block addr (high) */
306*b955f6caSJeff Kirsher #define CSR3	3		/* misc */
307*b955f6caSJeff Kirsher #define CSR8	8	  	/* address filter */
308*b955f6caSJeff Kirsher #define CSR15	15		/* promiscuous mode */
309*b955f6caSJeff Kirsher 
310*b955f6caSJeff Kirsher /* CSR0 */
311*b955f6caSJeff Kirsher /* (R=readable, W=writeable, S=set on write, C=clear on write) */
312*b955f6caSJeff Kirsher #define CSR0_INIT	0x0001		/* initialize (RS) */
313*b955f6caSJeff Kirsher #define CSR0_STRT	0x0002		/* start (RS) */
314*b955f6caSJeff Kirsher #define CSR0_STOP	0x0004		/* stop (RS) */
315*b955f6caSJeff Kirsher #define CSR0_TDMD	0x0008		/* transmit demand (RS) */
316*b955f6caSJeff Kirsher #define CSR0_TXON	0x0010		/* transmitter on (R) */
317*b955f6caSJeff Kirsher #define CSR0_RXON	0x0020		/* receiver on (R) */
318*b955f6caSJeff Kirsher #define CSR0_INEA	0x0040		/* interrupt enable (RW) */
319*b955f6caSJeff Kirsher #define CSR0_INTR	0x0080		/* interrupt active (R) */
320*b955f6caSJeff Kirsher #define CSR0_IDON	0x0100		/* initialization done (RC) */
321*b955f6caSJeff Kirsher #define CSR0_TINT	0x0200		/* transmitter interrupt (RC) */
322*b955f6caSJeff Kirsher #define CSR0_RINT	0x0400		/* receiver interrupt (RC) */
323*b955f6caSJeff Kirsher #define CSR0_MERR	0x0800		/* memory error (RC) */
324*b955f6caSJeff Kirsher #define CSR0_MISS	0x1000		/* missed frame (RC) */
325*b955f6caSJeff Kirsher #define CSR0_CERR	0x2000		/* carrier error (no heartbeat :-) (RC) */
326*b955f6caSJeff Kirsher #define CSR0_BABL	0x4000		/* babble: tx-ed too many bits (RC) */
327*b955f6caSJeff Kirsher #define CSR0_ERR	0x8000		/* error (RC) */
328*b955f6caSJeff Kirsher 
329*b955f6caSJeff Kirsher /* CSR3 */
330*b955f6caSJeff Kirsher #define CSR3_BCON	0x0001		/* byte control */
331*b955f6caSJeff Kirsher #define CSR3_ACON	0x0002		/* ALE control */
332*b955f6caSJeff Kirsher #define CSR3_BSWP	0x0004		/* byte swap (1=big endian) */
333*b955f6caSJeff Kirsher 
334*b955f6caSJeff Kirsher 
335*b955f6caSJeff Kirsher 
336*b955f6caSJeff Kirsher /***************************** Prototypes *****************************/
337*b955f6caSJeff Kirsher 
338*b955f6caSJeff Kirsher static unsigned long lance_probe1( struct net_device *dev, struct lance_addr
339*b955f6caSJeff Kirsher                                    *init_rec );
340*b955f6caSJeff Kirsher static int lance_open( struct net_device *dev );
341*b955f6caSJeff Kirsher static void lance_init_ring( struct net_device *dev );
342*b955f6caSJeff Kirsher static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
343*b955f6caSJeff Kirsher static irqreturn_t lance_interrupt( int irq, void *dev_id );
344*b955f6caSJeff Kirsher static int lance_rx( struct net_device *dev );
345*b955f6caSJeff Kirsher static int lance_close( struct net_device *dev );
346*b955f6caSJeff Kirsher static void set_multicast_list( struct net_device *dev );
347*b955f6caSJeff Kirsher static int lance_set_mac_address( struct net_device *dev, void *addr );
348*b955f6caSJeff Kirsher static void lance_tx_timeout (struct net_device *dev);
349*b955f6caSJeff Kirsher 
350*b955f6caSJeff Kirsher /************************* End of Prototypes **************************/
351*b955f6caSJeff Kirsher 
352*b955f6caSJeff Kirsher 
353*b955f6caSJeff Kirsher 
354*b955f6caSJeff Kirsher 
355*b955f6caSJeff Kirsher 
356*b955f6caSJeff Kirsher static void *slow_memcpy( void *dst, const void *src, size_t len )
357*b955f6caSJeff Kirsher 
358*b955f6caSJeff Kirsher {	char *cto = dst;
359*b955f6caSJeff Kirsher 	const char *cfrom = src;
360*b955f6caSJeff Kirsher 
361*b955f6caSJeff Kirsher 	while( len-- ) {
362*b955f6caSJeff Kirsher 		*cto++ = *cfrom++;
363*b955f6caSJeff Kirsher 		MFPDELAY();
364*b955f6caSJeff Kirsher 	}
365*b955f6caSJeff Kirsher 	return dst;
366*b955f6caSJeff Kirsher }
367*b955f6caSJeff Kirsher 
368*b955f6caSJeff Kirsher 
369*b955f6caSJeff Kirsher struct net_device * __init atarilance_probe(int unit)
370*b955f6caSJeff Kirsher {
371*b955f6caSJeff Kirsher 	int i;
372*b955f6caSJeff Kirsher 	static int found;
373*b955f6caSJeff Kirsher 	struct net_device *dev;
374*b955f6caSJeff Kirsher 	int err = -ENODEV;
375*b955f6caSJeff Kirsher 
376*b955f6caSJeff Kirsher 	if (!MACH_IS_ATARI || found)
377*b955f6caSJeff Kirsher 		/* Assume there's only one board possible... That seems true, since
378*b955f6caSJeff Kirsher 		 * the Riebl/PAM board's address cannot be changed. */
379*b955f6caSJeff Kirsher 		return ERR_PTR(-ENODEV);
380*b955f6caSJeff Kirsher 
381*b955f6caSJeff Kirsher 	dev = alloc_etherdev(sizeof(struct lance_private));
382*b955f6caSJeff Kirsher 	if (!dev)
383*b955f6caSJeff Kirsher 		return ERR_PTR(-ENOMEM);
384*b955f6caSJeff Kirsher 	if (unit >= 0) {
385*b955f6caSJeff Kirsher 		sprintf(dev->name, "eth%d", unit);
386*b955f6caSJeff Kirsher 		netdev_boot_setup_check(dev);
387*b955f6caSJeff Kirsher 	}
388*b955f6caSJeff Kirsher 
389*b955f6caSJeff Kirsher 	for( i = 0; i < N_LANCE_ADDR; ++i ) {
390*b955f6caSJeff Kirsher 		if (lance_probe1( dev, &lance_addr_list[i] )) {
391*b955f6caSJeff Kirsher 			found = 1;
392*b955f6caSJeff Kirsher 			err = register_netdev(dev);
393*b955f6caSJeff Kirsher 			if (!err)
394*b955f6caSJeff Kirsher 				return dev;
395*b955f6caSJeff Kirsher 			free_irq(dev->irq, dev);
396*b955f6caSJeff Kirsher 			break;
397*b955f6caSJeff Kirsher 		}
398*b955f6caSJeff Kirsher 	}
399*b955f6caSJeff Kirsher 	free_netdev(dev);
400*b955f6caSJeff Kirsher 	return ERR_PTR(err);
401*b955f6caSJeff Kirsher }
402*b955f6caSJeff Kirsher 
403*b955f6caSJeff Kirsher 
404*b955f6caSJeff Kirsher /* Derived from hwreg_present() in atari/config.c: */
405*b955f6caSJeff Kirsher 
406*b955f6caSJeff Kirsher static noinline int __init addr_accessible(volatile void *regp, int wordflag,
407*b955f6caSJeff Kirsher 					   int writeflag)
408*b955f6caSJeff Kirsher {
409*b955f6caSJeff Kirsher 	int		ret;
410*b955f6caSJeff Kirsher 	unsigned long	flags;
411*b955f6caSJeff Kirsher 	long	*vbr, save_berr;
412*b955f6caSJeff Kirsher 
413*b955f6caSJeff Kirsher 	local_irq_save(flags);
414*b955f6caSJeff Kirsher 
415*b955f6caSJeff Kirsher 	__asm__ __volatile__ ( "movec	%/vbr,%0" : "=r" (vbr) : );
416*b955f6caSJeff Kirsher 	save_berr = vbr[2];
417*b955f6caSJeff Kirsher 
418*b955f6caSJeff Kirsher 	__asm__ __volatile__
419*b955f6caSJeff Kirsher 	(	"movel	%/sp,%/d1\n\t"
420*b955f6caSJeff Kirsher 		"movel	#Lberr,%2@\n\t"
421*b955f6caSJeff Kirsher 		"moveq	#0,%0\n\t"
422*b955f6caSJeff Kirsher 		"tstl   %3\n\t"
423*b955f6caSJeff Kirsher 		"bne	1f\n\t"
424*b955f6caSJeff Kirsher 		"moveb	%1@,%/d0\n\t"
425*b955f6caSJeff Kirsher 		"nop	\n\t"
426*b955f6caSJeff Kirsher 		"bra	2f\n"
427*b955f6caSJeff Kirsher "1:		 movew	%1@,%/d0\n\t"
428*b955f6caSJeff Kirsher 		"nop	\n"
429*b955f6caSJeff Kirsher "2:		 tstl   %4\n\t"
430*b955f6caSJeff Kirsher 		"beq	2f\n\t"
431*b955f6caSJeff Kirsher 		"tstl	%3\n\t"
432*b955f6caSJeff Kirsher 		"bne	1f\n\t"
433*b955f6caSJeff Kirsher 		"clrb	%1@\n\t"
434*b955f6caSJeff Kirsher 		"nop	\n\t"
435*b955f6caSJeff Kirsher 		"moveb	%/d0,%1@\n\t"
436*b955f6caSJeff Kirsher 		"nop	\n\t"
437*b955f6caSJeff Kirsher 		"bra	2f\n"
438*b955f6caSJeff Kirsher "1:		 clrw	%1@\n\t"
439*b955f6caSJeff Kirsher 		"nop	\n\t"
440*b955f6caSJeff Kirsher 		"movew	%/d0,%1@\n\t"
441*b955f6caSJeff Kirsher 		"nop	\n"
442*b955f6caSJeff Kirsher "2:		 moveq	#1,%0\n"
443*b955f6caSJeff Kirsher "Lberr:	 movel	%/d1,%/sp"
444*b955f6caSJeff Kirsher 		: "=&d" (ret)
445*b955f6caSJeff Kirsher 		: "a" (regp), "a" (&vbr[2]), "rm" (wordflag), "rm" (writeflag)
446*b955f6caSJeff Kirsher 		: "d0", "d1", "memory"
447*b955f6caSJeff Kirsher 	);
448*b955f6caSJeff Kirsher 
449*b955f6caSJeff Kirsher 	vbr[2] = save_berr;
450*b955f6caSJeff Kirsher 	local_irq_restore(flags);
451*b955f6caSJeff Kirsher 
452*b955f6caSJeff Kirsher 	return ret;
453*b955f6caSJeff Kirsher }
454*b955f6caSJeff Kirsher 
455*b955f6caSJeff Kirsher static const struct net_device_ops lance_netdev_ops = {
456*b955f6caSJeff Kirsher 	.ndo_open		= lance_open,
457*b955f6caSJeff Kirsher 	.ndo_stop		= lance_close,
458*b955f6caSJeff Kirsher 	.ndo_start_xmit		= lance_start_xmit,
459*b955f6caSJeff Kirsher 	.ndo_set_multicast_list	= set_multicast_list,
460*b955f6caSJeff Kirsher 	.ndo_set_mac_address	= lance_set_mac_address,
461*b955f6caSJeff Kirsher 	.ndo_tx_timeout		= lance_tx_timeout,
462*b955f6caSJeff Kirsher 	.ndo_validate_addr	= eth_validate_addr,
463*b955f6caSJeff Kirsher 	.ndo_change_mtu		= eth_change_mtu,
464*b955f6caSJeff Kirsher };
465*b955f6caSJeff Kirsher 
466*b955f6caSJeff Kirsher static unsigned long __init lance_probe1( struct net_device *dev,
467*b955f6caSJeff Kirsher 					   struct lance_addr *init_rec )
468*b955f6caSJeff Kirsher {
469*b955f6caSJeff Kirsher 	volatile unsigned short *memaddr =
470*b955f6caSJeff Kirsher 		(volatile unsigned short *)init_rec->memaddr;
471*b955f6caSJeff Kirsher 	volatile unsigned short *ioaddr =
472*b955f6caSJeff Kirsher 		(volatile unsigned short *)init_rec->ioaddr;
473*b955f6caSJeff Kirsher 	struct lance_private	*lp;
474*b955f6caSJeff Kirsher 	struct lance_ioreg		*IO;
475*b955f6caSJeff Kirsher 	int 					i;
476*b955f6caSJeff Kirsher 	static int 				did_version;
477*b955f6caSJeff Kirsher 	unsigned short			save1, save2;
478*b955f6caSJeff Kirsher 
479*b955f6caSJeff Kirsher 	PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n",
480*b955f6caSJeff Kirsher 				  (long)memaddr, (long)ioaddr ));
481*b955f6caSJeff Kirsher 
482*b955f6caSJeff Kirsher 	/* Test whether memory readable and writable */
483*b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing memory to be accessible\n" ));
484*b955f6caSJeff Kirsher 	if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail;
485*b955f6caSJeff Kirsher 
486*b955f6caSJeff Kirsher 	/* Written values should come back... */
487*b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing memory to be writable (1)\n" ));
488*b955f6caSJeff Kirsher 	save1 = *memaddr;
489*b955f6caSJeff Kirsher 	*memaddr = 0x0001;
490*b955f6caSJeff Kirsher 	if (*memaddr != 0x0001) goto probe_fail;
491*b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing memory to be writable (2)\n" ));
492*b955f6caSJeff Kirsher 	*memaddr = 0x0000;
493*b955f6caSJeff Kirsher 	if (*memaddr != 0x0000) goto probe_fail;
494*b955f6caSJeff Kirsher 	*memaddr = save1;
495*b955f6caSJeff Kirsher 
496*b955f6caSJeff Kirsher 	/* First port should be readable and writable */
497*b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing ioport to be accessible\n" ));
498*b955f6caSJeff Kirsher 	if (!addr_accessible( ioaddr, 1, 1 )) goto probe_fail;
499*b955f6caSJeff Kirsher 
500*b955f6caSJeff Kirsher 	/* and written values should be readable */
501*b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing ioport to be writeable\n" ));
502*b955f6caSJeff Kirsher 	save2 = ioaddr[1];
503*b955f6caSJeff Kirsher 	ioaddr[1] = 0x0001;
504*b955f6caSJeff Kirsher 	if (ioaddr[1] != 0x0001) goto probe_fail;
505*b955f6caSJeff Kirsher 
506*b955f6caSJeff Kirsher 	/* The CSR0_INIT bit should not be readable */
507*b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing CSR0 register function (1)\n" ));
508*b955f6caSJeff Kirsher 	save1 = ioaddr[0];
509*b955f6caSJeff Kirsher 	ioaddr[1] = CSR0;
510*b955f6caSJeff Kirsher 	ioaddr[0] = CSR0_INIT | CSR0_STOP;
511*b955f6caSJeff Kirsher 	if (ioaddr[0] != CSR0_STOP) {
512*b955f6caSJeff Kirsher 		ioaddr[0] = save1;
513*b955f6caSJeff Kirsher 		ioaddr[1] = save2;
514*b955f6caSJeff Kirsher 		goto probe_fail;
515*b955f6caSJeff Kirsher 	}
516*b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing CSR0 register function (2)\n" ));
517*b955f6caSJeff Kirsher 	ioaddr[0] = CSR0_STOP;
518*b955f6caSJeff Kirsher 	if (ioaddr[0] != CSR0_STOP) {
519*b955f6caSJeff Kirsher 		ioaddr[0] = save1;
520*b955f6caSJeff Kirsher 		ioaddr[1] = save2;
521*b955f6caSJeff Kirsher 		goto probe_fail;
522*b955f6caSJeff Kirsher 	}
523*b955f6caSJeff Kirsher 
524*b955f6caSJeff Kirsher 	/* Now ok... */
525*b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: Lance card detected\n" ));
526*b955f6caSJeff Kirsher 	goto probe_ok;
527*b955f6caSJeff Kirsher 
528*b955f6caSJeff Kirsher   probe_fail:
529*b955f6caSJeff Kirsher 	return 0;
530*b955f6caSJeff Kirsher 
531*b955f6caSJeff Kirsher   probe_ok:
532*b955f6caSJeff Kirsher 	lp = netdev_priv(dev);
533*b955f6caSJeff Kirsher 	MEM = (struct lance_memory *)memaddr;
534*b955f6caSJeff Kirsher 	IO = lp->iobase = (struct lance_ioreg *)ioaddr;
535*b955f6caSJeff Kirsher 	dev->base_addr = (unsigned long)ioaddr; /* informational only */
536*b955f6caSJeff Kirsher 	lp->memcpy_f = init_rec->slow_flag ? slow_memcpy : memcpy;
537*b955f6caSJeff Kirsher 
538*b955f6caSJeff Kirsher 	REGA( CSR0 ) = CSR0_STOP;
539*b955f6caSJeff Kirsher 
540*b955f6caSJeff Kirsher 	/* Now test for type: If the eeprom I/O port is readable, it is a
541*b955f6caSJeff Kirsher 	 * PAM card */
542*b955f6caSJeff Kirsher 	if (addr_accessible( &(IO->eeprom), 0, 0 )) {
543*b955f6caSJeff Kirsher 		/* Switch back to Ram */
544*b955f6caSJeff Kirsher 		i = IO->mem;
545*b955f6caSJeff Kirsher 		lp->cardtype = PAM_CARD;
546*b955f6caSJeff Kirsher 	}
547*b955f6caSJeff Kirsher 	else if (*RIEBL_MAGIC_ADDR == RIEBL_MAGIC) {
548*b955f6caSJeff Kirsher 		lp->cardtype = NEW_RIEBL;
549*b955f6caSJeff Kirsher 	}
550*b955f6caSJeff Kirsher 	else
551*b955f6caSJeff Kirsher 		lp->cardtype = OLD_RIEBL;
552*b955f6caSJeff Kirsher 
553*b955f6caSJeff Kirsher 	if (lp->cardtype == PAM_CARD ||
554*b955f6caSJeff Kirsher 		memaddr == (unsigned short *)0xffe00000) {
555*b955f6caSJeff Kirsher 		/* PAMs card and Riebl on ST use level 5 autovector */
556*b955f6caSJeff Kirsher 		if (request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO,
557*b955f6caSJeff Kirsher 		            "PAM,Riebl-ST Ethernet", dev)) {
558*b955f6caSJeff Kirsher 			printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 );
559*b955f6caSJeff Kirsher 			return 0;
560*b955f6caSJeff Kirsher 		}
561*b955f6caSJeff Kirsher 		dev->irq = (unsigned short)IRQ_AUTO_5;
562*b955f6caSJeff Kirsher 	}
563*b955f6caSJeff Kirsher 	else {
564*b955f6caSJeff Kirsher 		/* For VME-RieblCards, request a free VME int;
565*b955f6caSJeff Kirsher 		 * (This must be unsigned long, since dev->irq is short and the
566*b955f6caSJeff Kirsher 		 * IRQ_MACHSPEC bit would be cut off...)
567*b955f6caSJeff Kirsher 		 */
568*b955f6caSJeff Kirsher 		unsigned long irq = atari_register_vme_int();
569*b955f6caSJeff Kirsher 		if (!irq) {
570*b955f6caSJeff Kirsher 			printk( "Lance: request for VME interrupt failed\n" );
571*b955f6caSJeff Kirsher 			return 0;
572*b955f6caSJeff Kirsher 		}
573*b955f6caSJeff Kirsher 		if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
574*b955f6caSJeff Kirsher 		            "Riebl-VME Ethernet", dev)) {
575*b955f6caSJeff Kirsher 			printk( "Lance: request for irq %ld failed\n", irq );
576*b955f6caSJeff Kirsher 			return 0;
577*b955f6caSJeff Kirsher 		}
578*b955f6caSJeff Kirsher 		dev->irq = irq;
579*b955f6caSJeff Kirsher 	}
580*b955f6caSJeff Kirsher 
581*b955f6caSJeff Kirsher 	printk("%s: %s at io %#lx, mem %#lx, irq %d%s, hwaddr ",
582*b955f6caSJeff Kirsher 		   dev->name, lance_names[lp->cardtype],
583*b955f6caSJeff Kirsher 		   (unsigned long)ioaddr,
584*b955f6caSJeff Kirsher 		   (unsigned long)memaddr,
585*b955f6caSJeff Kirsher 		   dev->irq,
586*b955f6caSJeff Kirsher 		   init_rec->slow_flag ? " (slow memcpy)" : "" );
587*b955f6caSJeff Kirsher 
588*b955f6caSJeff Kirsher 	/* Get the ethernet address */
589*b955f6caSJeff Kirsher 	switch( lp->cardtype ) {
590*b955f6caSJeff Kirsher 	  case OLD_RIEBL:
591*b955f6caSJeff Kirsher 		/* No ethernet address! (Set some default address) */
592*b955f6caSJeff Kirsher 		memcpy( dev->dev_addr, OldRieblDefHwaddr, 6 );
593*b955f6caSJeff Kirsher 		break;
594*b955f6caSJeff Kirsher 	  case NEW_RIEBL:
595*b955f6caSJeff Kirsher 		lp->memcpy_f( dev->dev_addr, RIEBL_HWADDR_ADDR, 6 );
596*b955f6caSJeff Kirsher 		break;
597*b955f6caSJeff Kirsher 	  case PAM_CARD:
598*b955f6caSJeff Kirsher 		i = IO->eeprom;
599*b955f6caSJeff Kirsher 		for( i = 0; i < 6; ++i )
600*b955f6caSJeff Kirsher 			dev->dev_addr[i] =
601*b955f6caSJeff Kirsher 				((((unsigned short *)MEM)[i*2] & 0x0f) << 4) |
602*b955f6caSJeff Kirsher 				((((unsigned short *)MEM)[i*2+1] & 0x0f));
603*b955f6caSJeff Kirsher 		i = IO->mem;
604*b955f6caSJeff Kirsher 		break;
605*b955f6caSJeff Kirsher 	}
606*b955f6caSJeff Kirsher 	printk("%pM\n", dev->dev_addr);
607*b955f6caSJeff Kirsher 	if (lp->cardtype == OLD_RIEBL) {
608*b955f6caSJeff Kirsher 		printk( "%s: Warning: This is a default ethernet address!\n",
609*b955f6caSJeff Kirsher 				dev->name );
610*b955f6caSJeff Kirsher 		printk( "      Use \"ifconfig hw ether ...\" to set the address.\n" );
611*b955f6caSJeff Kirsher 	}
612*b955f6caSJeff Kirsher 
613*b955f6caSJeff Kirsher 	spin_lock_init(&lp->devlock);
614*b955f6caSJeff Kirsher 
615*b955f6caSJeff Kirsher 	MEM->init.mode = 0x0000;		/* Disable Rx and Tx. */
616*b955f6caSJeff Kirsher 	for( i = 0; i < 6; i++ )
617*b955f6caSJeff Kirsher 		MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
618*b955f6caSJeff Kirsher 	MEM->init.filter[0] = 0x00000000;
619*b955f6caSJeff Kirsher 	MEM->init.filter[1] = 0x00000000;
620*b955f6caSJeff Kirsher 	MEM->init.rx_ring.adr_lo = offsetof( struct lance_memory, rx_head );
621*b955f6caSJeff Kirsher 	MEM->init.rx_ring.adr_hi = 0;
622*b955f6caSJeff Kirsher 	MEM->init.rx_ring.len    = RX_RING_LEN_BITS;
623*b955f6caSJeff Kirsher 	MEM->init.tx_ring.adr_lo = offsetof( struct lance_memory, tx_head );
624*b955f6caSJeff Kirsher 	MEM->init.tx_ring.adr_hi = 0;
625*b955f6caSJeff Kirsher 	MEM->init.tx_ring.len    = TX_RING_LEN_BITS;
626*b955f6caSJeff Kirsher 
627*b955f6caSJeff Kirsher 	if (lp->cardtype == PAM_CARD)
628*b955f6caSJeff Kirsher 		IO->ivec = IRQ_SOURCE_TO_VECTOR(dev->irq);
629*b955f6caSJeff Kirsher 	else
630*b955f6caSJeff Kirsher 		*RIEBL_IVEC_ADDR = IRQ_SOURCE_TO_VECTOR(dev->irq);
631*b955f6caSJeff Kirsher 
632*b955f6caSJeff Kirsher 	if (did_version++ == 0)
633*b955f6caSJeff Kirsher 		DPRINTK( 1, ( version ));
634*b955f6caSJeff Kirsher 
635*b955f6caSJeff Kirsher 	dev->netdev_ops = &lance_netdev_ops;
636*b955f6caSJeff Kirsher 
637*b955f6caSJeff Kirsher 	/* XXX MSch */
638*b955f6caSJeff Kirsher 	dev->watchdog_timeo = TX_TIMEOUT;
639*b955f6caSJeff Kirsher 
640*b955f6caSJeff Kirsher 	return 1;
641*b955f6caSJeff Kirsher }
642*b955f6caSJeff Kirsher 
643*b955f6caSJeff Kirsher 
644*b955f6caSJeff Kirsher static int lance_open( struct net_device *dev )
645*b955f6caSJeff Kirsher {
646*b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
647*b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
648*b955f6caSJeff Kirsher 	int i;
649*b955f6caSJeff Kirsher 
650*b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: lance_open()\n", dev->name ));
651*b955f6caSJeff Kirsher 
652*b955f6caSJeff Kirsher 	lance_init_ring(dev);
653*b955f6caSJeff Kirsher 	/* Re-initialize the LANCE, and start it when done. */
654*b955f6caSJeff Kirsher 
655*b955f6caSJeff Kirsher 	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
656*b955f6caSJeff Kirsher 	REGA( CSR2 ) = 0;
657*b955f6caSJeff Kirsher 	REGA( CSR1 ) = 0;
658*b955f6caSJeff Kirsher 	REGA( CSR0 ) = CSR0_INIT;
659*b955f6caSJeff Kirsher 	/* From now on, AREG is kept to point to CSR0 */
660*b955f6caSJeff Kirsher 
661*b955f6caSJeff Kirsher 	i = 1000000;
662*b955f6caSJeff Kirsher 	while (--i > 0)
663*b955f6caSJeff Kirsher 		if (DREG & CSR0_IDON)
664*b955f6caSJeff Kirsher 			break;
665*b955f6caSJeff Kirsher 	if (i <= 0 || (DREG & CSR0_ERR)) {
666*b955f6caSJeff Kirsher 		DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
667*b955f6caSJeff Kirsher 					  dev->name, i, DREG ));
668*b955f6caSJeff Kirsher 		DREG = CSR0_STOP;
669*b955f6caSJeff Kirsher 		return -EIO;
670*b955f6caSJeff Kirsher 	}
671*b955f6caSJeff Kirsher 	DREG = CSR0_IDON;
672*b955f6caSJeff Kirsher 	DREG = CSR0_STRT;
673*b955f6caSJeff Kirsher 	DREG = CSR0_INEA;
674*b955f6caSJeff Kirsher 
675*b955f6caSJeff Kirsher 	netif_start_queue (dev);
676*b955f6caSJeff Kirsher 
677*b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
678*b955f6caSJeff Kirsher 
679*b955f6caSJeff Kirsher 	return 0;
680*b955f6caSJeff Kirsher }
681*b955f6caSJeff Kirsher 
682*b955f6caSJeff Kirsher 
683*b955f6caSJeff Kirsher /* Initialize the LANCE Rx and Tx rings. */
684*b955f6caSJeff Kirsher 
685*b955f6caSJeff Kirsher static void lance_init_ring( struct net_device *dev )
686*b955f6caSJeff Kirsher {
687*b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
688*b955f6caSJeff Kirsher 	int i;
689*b955f6caSJeff Kirsher 	unsigned offset;
690*b955f6caSJeff Kirsher 
691*b955f6caSJeff Kirsher 	lp->tx_full = 0;
692*b955f6caSJeff Kirsher 	lp->cur_rx = lp->cur_tx = 0;
693*b955f6caSJeff Kirsher 	lp->dirty_tx = 0;
694*b955f6caSJeff Kirsher 
695*b955f6caSJeff Kirsher 	offset = offsetof( struct lance_memory, packet_area );
696*b955f6caSJeff Kirsher 
697*b955f6caSJeff Kirsher /* If the packet buffer at offset 'o' would conflict with the reserved area
698*b955f6caSJeff Kirsher  * of RieblCards, advance it */
699*b955f6caSJeff Kirsher #define	CHECK_OFFSET(o)														 \
700*b955f6caSJeff Kirsher 	do {																	 \
701*b955f6caSJeff Kirsher 		if (lp->cardtype == OLD_RIEBL || lp->cardtype == NEW_RIEBL) {		 \
702*b955f6caSJeff Kirsher 			if (((o) < RIEBL_RSVD_START) ? (o)+PKT_BUF_SZ > RIEBL_RSVD_START \
703*b955f6caSJeff Kirsher 										 : (o) < RIEBL_RSVD_END)			 \
704*b955f6caSJeff Kirsher 				(o) = RIEBL_RSVD_END;										 \
705*b955f6caSJeff Kirsher 		}																	 \
706*b955f6caSJeff Kirsher 	} while(0)
707*b955f6caSJeff Kirsher 
708*b955f6caSJeff Kirsher 	for( i = 0; i < TX_RING_SIZE; i++ ) {
709*b955f6caSJeff Kirsher 		CHECK_OFFSET(offset);
710*b955f6caSJeff Kirsher 		MEM->tx_head[i].base = offset;
711*b955f6caSJeff Kirsher 		MEM->tx_head[i].flag = TMD1_OWN_HOST;
712*b955f6caSJeff Kirsher  		MEM->tx_head[i].base_hi = 0;
713*b955f6caSJeff Kirsher 		MEM->tx_head[i].length = 0;
714*b955f6caSJeff Kirsher 		MEM->tx_head[i].misc = 0;
715*b955f6caSJeff Kirsher 		offset += PKT_BUF_SZ;
716*b955f6caSJeff Kirsher 	}
717*b955f6caSJeff Kirsher 
718*b955f6caSJeff Kirsher 	for( i = 0; i < RX_RING_SIZE; i++ ) {
719*b955f6caSJeff Kirsher 		CHECK_OFFSET(offset);
720*b955f6caSJeff Kirsher 		MEM->rx_head[i].base = offset;
721*b955f6caSJeff Kirsher 		MEM->rx_head[i].flag = TMD1_OWN_CHIP;
722*b955f6caSJeff Kirsher 		MEM->rx_head[i].base_hi = 0;
723*b955f6caSJeff Kirsher 		MEM->rx_head[i].buf_length = -PKT_BUF_SZ;
724*b955f6caSJeff Kirsher 		MEM->rx_head[i].msg_length = 0;
725*b955f6caSJeff Kirsher 		offset += PKT_BUF_SZ;
726*b955f6caSJeff Kirsher 	}
727*b955f6caSJeff Kirsher }
728*b955f6caSJeff Kirsher 
729*b955f6caSJeff Kirsher 
730*b955f6caSJeff Kirsher /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
731*b955f6caSJeff Kirsher 
732*b955f6caSJeff Kirsher 
733*b955f6caSJeff Kirsher static void lance_tx_timeout (struct net_device *dev)
734*b955f6caSJeff Kirsher {
735*b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
736*b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
737*b955f6caSJeff Kirsher 
738*b955f6caSJeff Kirsher 	AREG = CSR0;
739*b955f6caSJeff Kirsher 	DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
740*b955f6caSJeff Kirsher 			  dev->name, DREG ));
741*b955f6caSJeff Kirsher 	DREG = CSR0_STOP;
742*b955f6caSJeff Kirsher 	/*
743*b955f6caSJeff Kirsher 	 * Always set BSWP after a STOP as STOP puts it back into
744*b955f6caSJeff Kirsher 	 * little endian mode.
745*b955f6caSJeff Kirsher 	 */
746*b955f6caSJeff Kirsher 	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
747*b955f6caSJeff Kirsher 	dev->stats.tx_errors++;
748*b955f6caSJeff Kirsher #ifndef final_version
749*b955f6caSJeff Kirsher 		{	int i;
750*b955f6caSJeff Kirsher 			DPRINTK( 2, ( "Ring data: dirty_tx %d cur_tx %d%s cur_rx %d\n",
751*b955f6caSJeff Kirsher 						  lp->dirty_tx, lp->cur_tx,
752*b955f6caSJeff Kirsher 						  lp->tx_full ? " (full)" : "",
753*b955f6caSJeff Kirsher 						  lp->cur_rx ));
754*b955f6caSJeff Kirsher 			for( i = 0 ; i < RX_RING_SIZE; i++ )
755*b955f6caSJeff Kirsher 				DPRINTK( 2, ( "rx #%d: base=%04x blen=%04x mlen=%04x\n",
756*b955f6caSJeff Kirsher 							  i, MEM->rx_head[i].base,
757*b955f6caSJeff Kirsher 							  -MEM->rx_head[i].buf_length,
758*b955f6caSJeff Kirsher 							  MEM->rx_head[i].msg_length ));
759*b955f6caSJeff Kirsher 			for( i = 0 ; i < TX_RING_SIZE; i++ )
760*b955f6caSJeff Kirsher 				DPRINTK( 2, ( "tx #%d: base=%04x len=%04x misc=%04x\n",
761*b955f6caSJeff Kirsher 							  i, MEM->tx_head[i].base,
762*b955f6caSJeff Kirsher 							  -MEM->tx_head[i].length,
763*b955f6caSJeff Kirsher 							  MEM->tx_head[i].misc ));
764*b955f6caSJeff Kirsher 		}
765*b955f6caSJeff Kirsher #endif
766*b955f6caSJeff Kirsher 	/* XXX MSch: maybe purge/reinit ring here */
767*b955f6caSJeff Kirsher 	/* lance_restart, essentially */
768*b955f6caSJeff Kirsher 	lance_init_ring(dev);
769*b955f6caSJeff Kirsher 	REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
770*b955f6caSJeff Kirsher 	dev->trans_start = jiffies; /* prevent tx timeout */
771*b955f6caSJeff Kirsher 	netif_wake_queue(dev);
772*b955f6caSJeff Kirsher }
773*b955f6caSJeff Kirsher 
774*b955f6caSJeff Kirsher /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
775*b955f6caSJeff Kirsher 
776*b955f6caSJeff Kirsher static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
777*b955f6caSJeff Kirsher {
778*b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
779*b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
780*b955f6caSJeff Kirsher 	int entry, len;
781*b955f6caSJeff Kirsher 	struct lance_tx_head *head;
782*b955f6caSJeff Kirsher 	unsigned long flags;
783*b955f6caSJeff Kirsher 
784*b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
785*b955f6caSJeff Kirsher 				  dev->name, DREG ));
786*b955f6caSJeff Kirsher 
787*b955f6caSJeff Kirsher 
788*b955f6caSJeff Kirsher 	/* The old LANCE chips doesn't automatically pad buffers to min. size. */
789*b955f6caSJeff Kirsher 	len = skb->len;
790*b955f6caSJeff Kirsher 	if (len < ETH_ZLEN)
791*b955f6caSJeff Kirsher 		len = ETH_ZLEN;
792*b955f6caSJeff Kirsher 	/* PAM-Card has a bug: Can only send packets with even number of bytes! */
793*b955f6caSJeff Kirsher 	else if (lp->cardtype == PAM_CARD && (len & 1))
794*b955f6caSJeff Kirsher 		++len;
795*b955f6caSJeff Kirsher 
796*b955f6caSJeff Kirsher 	if (len > skb->len) {
797*b955f6caSJeff Kirsher 		if (skb_padto(skb, len))
798*b955f6caSJeff Kirsher 			return NETDEV_TX_OK;
799*b955f6caSJeff Kirsher 	}
800*b955f6caSJeff Kirsher 
801*b955f6caSJeff Kirsher 	netif_stop_queue (dev);
802*b955f6caSJeff Kirsher 
803*b955f6caSJeff Kirsher 	/* Fill in a Tx ring entry */
804*b955f6caSJeff Kirsher 	if (lance_debug >= 3) {
805*b955f6caSJeff Kirsher 		printk( "%s: TX pkt type 0x%04x from %pM to %pM"
806*b955f6caSJeff Kirsher 				" data at 0x%08x len %d\n",
807*b955f6caSJeff Kirsher 				dev->name, ((u_short *)skb->data)[6],
808*b955f6caSJeff Kirsher 				&skb->data[6], skb->data,
809*b955f6caSJeff Kirsher 				(int)skb->data, (int)skb->len );
810*b955f6caSJeff Kirsher 	}
811*b955f6caSJeff Kirsher 
812*b955f6caSJeff Kirsher 	/* We're not prepared for the int until the last flags are set/reset. And
813*b955f6caSJeff Kirsher 	 * the int may happen already after setting the OWN_CHIP... */
814*b955f6caSJeff Kirsher 	spin_lock_irqsave (&lp->devlock, flags);
815*b955f6caSJeff Kirsher 
816*b955f6caSJeff Kirsher 	/* Mask to ring buffer boundary. */
817*b955f6caSJeff Kirsher 	entry = lp->cur_tx & TX_RING_MOD_MASK;
818*b955f6caSJeff Kirsher 	head  = &(MEM->tx_head[entry]);
819*b955f6caSJeff Kirsher 
820*b955f6caSJeff Kirsher 	/* Caution: the write order is important here, set the "ownership" bits
821*b955f6caSJeff Kirsher 	 * last.
822*b955f6caSJeff Kirsher 	 */
823*b955f6caSJeff Kirsher 
824*b955f6caSJeff Kirsher 
825*b955f6caSJeff Kirsher 	head->length = -len;
826*b955f6caSJeff Kirsher 	head->misc = 0;
827*b955f6caSJeff Kirsher 	lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len );
828*b955f6caSJeff Kirsher 	head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP;
829*b955f6caSJeff Kirsher 	dev->stats.tx_bytes += skb->len;
830*b955f6caSJeff Kirsher 	dev_kfree_skb( skb );
831*b955f6caSJeff Kirsher 	lp->cur_tx++;
832*b955f6caSJeff Kirsher 	while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) {
833*b955f6caSJeff Kirsher 		lp->cur_tx -= TX_RING_SIZE;
834*b955f6caSJeff Kirsher 		lp->dirty_tx -= TX_RING_SIZE;
835*b955f6caSJeff Kirsher 	}
836*b955f6caSJeff Kirsher 
837*b955f6caSJeff Kirsher 	/* Trigger an immediate send poll. */
838*b955f6caSJeff Kirsher 	DREG = CSR0_INEA | CSR0_TDMD;
839*b955f6caSJeff Kirsher 
840*b955f6caSJeff Kirsher 	if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
841*b955f6caSJeff Kirsher 		TMD1_OWN_HOST)
842*b955f6caSJeff Kirsher 		netif_start_queue (dev);
843*b955f6caSJeff Kirsher 	else
844*b955f6caSJeff Kirsher 		lp->tx_full = 1;
845*b955f6caSJeff Kirsher 	spin_unlock_irqrestore (&lp->devlock, flags);
846*b955f6caSJeff Kirsher 
847*b955f6caSJeff Kirsher 	return NETDEV_TX_OK;
848*b955f6caSJeff Kirsher }
849*b955f6caSJeff Kirsher 
850*b955f6caSJeff Kirsher /* The LANCE interrupt handler. */
851*b955f6caSJeff Kirsher 
852*b955f6caSJeff Kirsher static irqreturn_t lance_interrupt( int irq, void *dev_id )
853*b955f6caSJeff Kirsher {
854*b955f6caSJeff Kirsher 	struct net_device *dev = dev_id;
855*b955f6caSJeff Kirsher 	struct lance_private *lp;
856*b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO;
857*b955f6caSJeff Kirsher 	int csr0, boguscnt = 10;
858*b955f6caSJeff Kirsher 	int handled = 0;
859*b955f6caSJeff Kirsher 
860*b955f6caSJeff Kirsher 	if (dev == NULL) {
861*b955f6caSJeff Kirsher 		DPRINTK( 1, ( "lance_interrupt(): interrupt for unknown device.\n" ));
862*b955f6caSJeff Kirsher 		return IRQ_NONE;
863*b955f6caSJeff Kirsher 	}
864*b955f6caSJeff Kirsher 
865*b955f6caSJeff Kirsher 	lp = netdev_priv(dev);
866*b955f6caSJeff Kirsher 	IO = lp->iobase;
867*b955f6caSJeff Kirsher 	spin_lock (&lp->devlock);
868*b955f6caSJeff Kirsher 
869*b955f6caSJeff Kirsher 	AREG = CSR0;
870*b955f6caSJeff Kirsher 
871*b955f6caSJeff Kirsher 	while( ((csr0 = DREG) & (CSR0_ERR | CSR0_TINT | CSR0_RINT)) &&
872*b955f6caSJeff Kirsher 		   --boguscnt >= 0) {
873*b955f6caSJeff Kirsher 		handled = 1;
874*b955f6caSJeff Kirsher 		/* Acknowledge all of the current interrupt sources ASAP. */
875*b955f6caSJeff Kirsher 		DREG = csr0 & ~(CSR0_INIT | CSR0_STRT | CSR0_STOP |
876*b955f6caSJeff Kirsher 									CSR0_TDMD | CSR0_INEA);
877*b955f6caSJeff Kirsher 
878*b955f6caSJeff Kirsher 		DPRINTK( 2, ( "%s: interrupt  csr0=%04x new csr=%04x.\n",
879*b955f6caSJeff Kirsher 					  dev->name, csr0, DREG ));
880*b955f6caSJeff Kirsher 
881*b955f6caSJeff Kirsher 		if (csr0 & CSR0_RINT)			/* Rx interrupt */
882*b955f6caSJeff Kirsher 			lance_rx( dev );
883*b955f6caSJeff Kirsher 
884*b955f6caSJeff Kirsher 		if (csr0 & CSR0_TINT) {			/* Tx-done interrupt */
885*b955f6caSJeff Kirsher 			int dirty_tx = lp->dirty_tx;
886*b955f6caSJeff Kirsher 
887*b955f6caSJeff Kirsher 			while( dirty_tx < lp->cur_tx) {
888*b955f6caSJeff Kirsher 				int entry = dirty_tx & TX_RING_MOD_MASK;
889*b955f6caSJeff Kirsher 				int status = MEM->tx_head[entry].flag;
890*b955f6caSJeff Kirsher 
891*b955f6caSJeff Kirsher 				if (status & TMD1_OWN_CHIP)
892*b955f6caSJeff Kirsher 					break;			/* It still hasn't been Txed */
893*b955f6caSJeff Kirsher 
894*b955f6caSJeff Kirsher 				MEM->tx_head[entry].flag = 0;
895*b955f6caSJeff Kirsher 
896*b955f6caSJeff Kirsher 				if (status & TMD1_ERR) {
897*b955f6caSJeff Kirsher 					/* There was an major error, log it. */
898*b955f6caSJeff Kirsher 					int err_status = MEM->tx_head[entry].misc;
899*b955f6caSJeff Kirsher 					dev->stats.tx_errors++;
900*b955f6caSJeff Kirsher 					if (err_status & TMD3_RTRY) dev->stats.tx_aborted_errors++;
901*b955f6caSJeff Kirsher 					if (err_status & TMD3_LCAR) dev->stats.tx_carrier_errors++;
902*b955f6caSJeff Kirsher 					if (err_status & TMD3_LCOL) dev->stats.tx_window_errors++;
903*b955f6caSJeff Kirsher 					if (err_status & TMD3_UFLO) {
904*b955f6caSJeff Kirsher 						/* Ackk!  On FIFO errors the Tx unit is turned off! */
905*b955f6caSJeff Kirsher 						dev->stats.tx_fifo_errors++;
906*b955f6caSJeff Kirsher 						/* Remove this verbosity later! */
907*b955f6caSJeff Kirsher 						DPRINTK( 1, ( "%s: Tx FIFO error! Status %04x\n",
908*b955f6caSJeff Kirsher 									  dev->name, csr0 ));
909*b955f6caSJeff Kirsher 						/* Restart the chip. */
910*b955f6caSJeff Kirsher 						DREG = CSR0_STRT;
911*b955f6caSJeff Kirsher 					}
912*b955f6caSJeff Kirsher 				} else {
913*b955f6caSJeff Kirsher 					if (status & (TMD1_MORE | TMD1_ONE | TMD1_DEF))
914*b955f6caSJeff Kirsher 						dev->stats.collisions++;
915*b955f6caSJeff Kirsher 					dev->stats.tx_packets++;
916*b955f6caSJeff Kirsher 				}
917*b955f6caSJeff Kirsher 
918*b955f6caSJeff Kirsher 				/* XXX MSch: free skb?? */
919*b955f6caSJeff Kirsher 				dirty_tx++;
920*b955f6caSJeff Kirsher 			}
921*b955f6caSJeff Kirsher 
922*b955f6caSJeff Kirsher #ifndef final_version
923*b955f6caSJeff Kirsher 			if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
924*b955f6caSJeff Kirsher 				DPRINTK( 0, ( "out-of-sync dirty pointer,"
925*b955f6caSJeff Kirsher 							  " %d vs. %d, full=%ld.\n",
926*b955f6caSJeff Kirsher 							  dirty_tx, lp->cur_tx, lp->tx_full ));
927*b955f6caSJeff Kirsher 				dirty_tx += TX_RING_SIZE;
928*b955f6caSJeff Kirsher 			}
929*b955f6caSJeff Kirsher #endif
930*b955f6caSJeff Kirsher 
931*b955f6caSJeff Kirsher 			if (lp->tx_full && (netif_queue_stopped(dev)) &&
932*b955f6caSJeff Kirsher 				dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
933*b955f6caSJeff Kirsher 				/* The ring is no longer full, clear tbusy. */
934*b955f6caSJeff Kirsher 				lp->tx_full = 0;
935*b955f6caSJeff Kirsher 				netif_wake_queue (dev);
936*b955f6caSJeff Kirsher 			}
937*b955f6caSJeff Kirsher 
938*b955f6caSJeff Kirsher 			lp->dirty_tx = dirty_tx;
939*b955f6caSJeff Kirsher 		}
940*b955f6caSJeff Kirsher 
941*b955f6caSJeff Kirsher 		/* Log misc errors. */
942*b955f6caSJeff Kirsher 		if (csr0 & CSR0_BABL) dev->stats.tx_errors++; /* Tx babble. */
943*b955f6caSJeff Kirsher 		if (csr0 & CSR0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */
944*b955f6caSJeff Kirsher 		if (csr0 & CSR0_MERR) {
945*b955f6caSJeff Kirsher 			DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), "
946*b955f6caSJeff Kirsher 						  "status %04x.\n", dev->name, csr0 ));
947*b955f6caSJeff Kirsher 			/* Restart the chip. */
948*b955f6caSJeff Kirsher 			DREG = CSR0_STRT;
949*b955f6caSJeff Kirsher 		}
950*b955f6caSJeff Kirsher 	}
951*b955f6caSJeff Kirsher 
952*b955f6caSJeff Kirsher     /* Clear any other interrupt, and set interrupt enable. */
953*b955f6caSJeff Kirsher 	DREG = CSR0_BABL | CSR0_CERR | CSR0_MISS | CSR0_MERR |
954*b955f6caSJeff Kirsher 		   CSR0_IDON | CSR0_INEA;
955*b955f6caSJeff Kirsher 
956*b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: exiting interrupt, csr0=%#04x.\n",
957*b955f6caSJeff Kirsher 				  dev->name, DREG ));
958*b955f6caSJeff Kirsher 
959*b955f6caSJeff Kirsher 	spin_unlock (&lp->devlock);
960*b955f6caSJeff Kirsher 	return IRQ_RETVAL(handled);
961*b955f6caSJeff Kirsher }
962*b955f6caSJeff Kirsher 
963*b955f6caSJeff Kirsher 
964*b955f6caSJeff Kirsher static int lance_rx( struct net_device *dev )
965*b955f6caSJeff Kirsher {
966*b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
967*b955f6caSJeff Kirsher 	int entry = lp->cur_rx & RX_RING_MOD_MASK;
968*b955f6caSJeff Kirsher 	int i;
969*b955f6caSJeff Kirsher 
970*b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name,
971*b955f6caSJeff Kirsher 				  MEM->rx_head[entry].flag ));
972*b955f6caSJeff Kirsher 
973*b955f6caSJeff Kirsher 	/* If we own the next entry, it's a new packet. Send it up. */
974*b955f6caSJeff Kirsher 	while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
975*b955f6caSJeff Kirsher 		struct lance_rx_head *head = &(MEM->rx_head[entry]);
976*b955f6caSJeff Kirsher 		int status = head->flag;
977*b955f6caSJeff Kirsher 
978*b955f6caSJeff Kirsher 		if (status != (RMD1_ENP|RMD1_STP)) {		/* There was an error. */
979*b955f6caSJeff Kirsher 			/* There is a tricky error noted by John Murphy,
980*b955f6caSJeff Kirsher 			   <murf@perftech.com> to Russ Nelson: Even with full-sized
981*b955f6caSJeff Kirsher 			   buffers it's possible for a jabber packet to use two
982*b955f6caSJeff Kirsher 			   buffers, with only the last correctly noting the error. */
983*b955f6caSJeff Kirsher 			if (status & RMD1_ENP)	/* Only count a general error at the */
984*b955f6caSJeff Kirsher 				dev->stats.rx_errors++; /* end of a packet.*/
985*b955f6caSJeff Kirsher 			if (status & RMD1_FRAM) dev->stats.rx_frame_errors++;
986*b955f6caSJeff Kirsher 			if (status & RMD1_OFLO) dev->stats.rx_over_errors++;
987*b955f6caSJeff Kirsher 			if (status & RMD1_CRC) dev->stats.rx_crc_errors++;
988*b955f6caSJeff Kirsher 			if (status & RMD1_BUFF) dev->stats.rx_fifo_errors++;
989*b955f6caSJeff Kirsher 			head->flag &= (RMD1_ENP|RMD1_STP);
990*b955f6caSJeff Kirsher 		} else {
991*b955f6caSJeff Kirsher 			/* Malloc up new buffer, compatible with net-3. */
992*b955f6caSJeff Kirsher 			short pkt_len = head->msg_length & 0xfff;
993*b955f6caSJeff Kirsher 			struct sk_buff *skb;
994*b955f6caSJeff Kirsher 
995*b955f6caSJeff Kirsher 			if (pkt_len < 60) {
996*b955f6caSJeff Kirsher 				printk( "%s: Runt packet!\n", dev->name );
997*b955f6caSJeff Kirsher 				dev->stats.rx_errors++;
998*b955f6caSJeff Kirsher 			}
999*b955f6caSJeff Kirsher 			else {
1000*b955f6caSJeff Kirsher 				skb = dev_alloc_skb( pkt_len+2 );
1001*b955f6caSJeff Kirsher 				if (skb == NULL) {
1002*b955f6caSJeff Kirsher 					DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
1003*b955f6caSJeff Kirsher 								  dev->name ));
1004*b955f6caSJeff Kirsher 					for( i = 0; i < RX_RING_SIZE; i++ )
1005*b955f6caSJeff Kirsher 						if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag &
1006*b955f6caSJeff Kirsher 							RMD1_OWN_CHIP)
1007*b955f6caSJeff Kirsher 							break;
1008*b955f6caSJeff Kirsher 
1009*b955f6caSJeff Kirsher 					if (i > RX_RING_SIZE - 2) {
1010*b955f6caSJeff Kirsher 						dev->stats.rx_dropped++;
1011*b955f6caSJeff Kirsher 						head->flag |= RMD1_OWN_CHIP;
1012*b955f6caSJeff Kirsher 						lp->cur_rx++;
1013*b955f6caSJeff Kirsher 					}
1014*b955f6caSJeff Kirsher 					break;
1015*b955f6caSJeff Kirsher 				}
1016*b955f6caSJeff Kirsher 
1017*b955f6caSJeff Kirsher 				if (lance_debug >= 3) {
1018*b955f6caSJeff Kirsher 					u_char *data = PKTBUF_ADDR(head);
1019*b955f6caSJeff Kirsher 
1020*b955f6caSJeff Kirsher 					printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %pM to %pM "
1021*b955f6caSJeff Kirsher 						   "data %02x %02x %02x %02x %02x %02x %02x %02x "
1022*b955f6caSJeff Kirsher 						   "len %d\n",
1023*b955f6caSJeff Kirsher 						   dev->name, ((u_short *)data)[6],
1024*b955f6caSJeff Kirsher 						   &data[6], data,
1025*b955f6caSJeff Kirsher 						   data[15], data[16], data[17], data[18],
1026*b955f6caSJeff Kirsher 						   data[19], data[20], data[21], data[22],
1027*b955f6caSJeff Kirsher 						   pkt_len);
1028*b955f6caSJeff Kirsher 				}
1029*b955f6caSJeff Kirsher 
1030*b955f6caSJeff Kirsher 				skb_reserve( skb, 2 );	/* 16 byte align */
1031*b955f6caSJeff Kirsher 				skb_put( skb, pkt_len );	/* Make room */
1032*b955f6caSJeff Kirsher 				lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len );
1033*b955f6caSJeff Kirsher 				skb->protocol = eth_type_trans( skb, dev );
1034*b955f6caSJeff Kirsher 				netif_rx( skb );
1035*b955f6caSJeff Kirsher 				dev->stats.rx_packets++;
1036*b955f6caSJeff Kirsher 				dev->stats.rx_bytes += pkt_len;
1037*b955f6caSJeff Kirsher 			}
1038*b955f6caSJeff Kirsher 		}
1039*b955f6caSJeff Kirsher 
1040*b955f6caSJeff Kirsher 		head->flag |= RMD1_OWN_CHIP;
1041*b955f6caSJeff Kirsher 		entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
1042*b955f6caSJeff Kirsher 	}
1043*b955f6caSJeff Kirsher 	lp->cur_rx &= RX_RING_MOD_MASK;
1044*b955f6caSJeff Kirsher 
1045*b955f6caSJeff Kirsher 	/* From lance.c (Donald Becker): */
1046*b955f6caSJeff Kirsher 	/* We should check that at least two ring entries are free.	 If not,
1047*b955f6caSJeff Kirsher 	   we should free one and mark stats->rx_dropped++. */
1048*b955f6caSJeff Kirsher 
1049*b955f6caSJeff Kirsher 	return 0;
1050*b955f6caSJeff Kirsher }
1051*b955f6caSJeff Kirsher 
1052*b955f6caSJeff Kirsher 
1053*b955f6caSJeff Kirsher static int lance_close( struct net_device *dev )
1054*b955f6caSJeff Kirsher {
1055*b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
1056*b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
1057*b955f6caSJeff Kirsher 
1058*b955f6caSJeff Kirsher 	netif_stop_queue (dev);
1059*b955f6caSJeff Kirsher 
1060*b955f6caSJeff Kirsher 	AREG = CSR0;
1061*b955f6caSJeff Kirsher 
1062*b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: Shutting down ethercard, status was %2.2x.\n",
1063*b955f6caSJeff Kirsher 				  dev->name, DREG ));
1064*b955f6caSJeff Kirsher 
1065*b955f6caSJeff Kirsher 	/* We stop the LANCE here -- it occasionally polls
1066*b955f6caSJeff Kirsher 	   memory if we don't. */
1067*b955f6caSJeff Kirsher 	DREG = CSR0_STOP;
1068*b955f6caSJeff Kirsher 
1069*b955f6caSJeff Kirsher 	return 0;
1070*b955f6caSJeff Kirsher }
1071*b955f6caSJeff Kirsher 
1072*b955f6caSJeff Kirsher 
1073*b955f6caSJeff Kirsher /* Set or clear the multicast filter for this adaptor.
1074*b955f6caSJeff Kirsher    num_addrs == -1		Promiscuous mode, receive all packets
1075*b955f6caSJeff Kirsher    num_addrs == 0		Normal mode, clear multicast list
1076*b955f6caSJeff Kirsher    num_addrs > 0		Multicast mode, receive normal and MC packets, and do
1077*b955f6caSJeff Kirsher 						best-effort filtering.
1078*b955f6caSJeff Kirsher  */
1079*b955f6caSJeff Kirsher 
1080*b955f6caSJeff Kirsher static void set_multicast_list( struct net_device *dev )
1081*b955f6caSJeff Kirsher {
1082*b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
1083*b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
1084*b955f6caSJeff Kirsher 
1085*b955f6caSJeff Kirsher 	if (netif_running(dev))
1086*b955f6caSJeff Kirsher 		/* Only possible if board is already started */
1087*b955f6caSJeff Kirsher 		return;
1088*b955f6caSJeff Kirsher 
1089*b955f6caSJeff Kirsher 	/* We take the simple way out and always enable promiscuous mode. */
1090*b955f6caSJeff Kirsher 	DREG = CSR0_STOP; /* Temporarily stop the lance. */
1091*b955f6caSJeff Kirsher 
1092*b955f6caSJeff Kirsher 	if (dev->flags & IFF_PROMISC) {
1093*b955f6caSJeff Kirsher 		/* Log any net taps. */
1094*b955f6caSJeff Kirsher 		DPRINTK( 2, ( "%s: Promiscuous mode enabled.\n", dev->name ));
1095*b955f6caSJeff Kirsher 		REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
1096*b955f6caSJeff Kirsher 	} else {
1097*b955f6caSJeff Kirsher 		short multicast_table[4];
1098*b955f6caSJeff Kirsher 		int num_addrs = netdev_mc_count(dev);
1099*b955f6caSJeff Kirsher 		int i;
1100*b955f6caSJeff Kirsher 		/* We don't use the multicast table, but rely on upper-layer
1101*b955f6caSJeff Kirsher 		 * filtering. */
1102*b955f6caSJeff Kirsher 		memset( multicast_table, (num_addrs == 0) ? 0 : -1,
1103*b955f6caSJeff Kirsher 				sizeof(multicast_table) );
1104*b955f6caSJeff Kirsher 		for( i = 0; i < 4; i++ )
1105*b955f6caSJeff Kirsher 			REGA( CSR8+i ) = multicast_table[i];
1106*b955f6caSJeff Kirsher 		REGA( CSR15 ) = 0; /* Unset promiscuous mode */
1107*b955f6caSJeff Kirsher 	}
1108*b955f6caSJeff Kirsher 
1109*b955f6caSJeff Kirsher 	/*
1110*b955f6caSJeff Kirsher 	 * Always set BSWP after a STOP as STOP puts it back into
1111*b955f6caSJeff Kirsher 	 * little endian mode.
1112*b955f6caSJeff Kirsher 	 */
1113*b955f6caSJeff Kirsher 	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
1114*b955f6caSJeff Kirsher 
1115*b955f6caSJeff Kirsher 	/* Resume normal operation and reset AREG to CSR0 */
1116*b955f6caSJeff Kirsher 	REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT;
1117*b955f6caSJeff Kirsher }
1118*b955f6caSJeff Kirsher 
1119*b955f6caSJeff Kirsher 
1120*b955f6caSJeff Kirsher /* This is needed for old RieblCards and possible for new RieblCards */
1121*b955f6caSJeff Kirsher 
1122*b955f6caSJeff Kirsher static int lance_set_mac_address( struct net_device *dev, void *addr )
1123*b955f6caSJeff Kirsher {
1124*b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
1125*b955f6caSJeff Kirsher 	struct sockaddr *saddr = addr;
1126*b955f6caSJeff Kirsher 	int i;
1127*b955f6caSJeff Kirsher 
1128*b955f6caSJeff Kirsher 	if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL)
1129*b955f6caSJeff Kirsher 		return -EOPNOTSUPP;
1130*b955f6caSJeff Kirsher 
1131*b955f6caSJeff Kirsher 	if (netif_running(dev)) {
1132*b955f6caSJeff Kirsher 		/* Only possible while card isn't started */
1133*b955f6caSJeff Kirsher 		DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n",
1134*b955f6caSJeff Kirsher 					  dev->name ));
1135*b955f6caSJeff Kirsher 		return -EIO;
1136*b955f6caSJeff Kirsher 	}
1137*b955f6caSJeff Kirsher 
1138*b955f6caSJeff Kirsher 	memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len );
1139*b955f6caSJeff Kirsher 	for( i = 0; i < 6; i++ )
1140*b955f6caSJeff Kirsher 		MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
1141*b955f6caSJeff Kirsher 	lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 );
1142*b955f6caSJeff Kirsher 	/* set also the magic for future sessions */
1143*b955f6caSJeff Kirsher 	*RIEBL_MAGIC_ADDR = RIEBL_MAGIC;
1144*b955f6caSJeff Kirsher 
1145*b955f6caSJeff Kirsher 	return 0;
1146*b955f6caSJeff Kirsher }
1147*b955f6caSJeff Kirsher 
1148*b955f6caSJeff Kirsher 
1149*b955f6caSJeff Kirsher #ifdef MODULE
1150*b955f6caSJeff Kirsher static struct net_device *atarilance_dev;
1151*b955f6caSJeff Kirsher 
1152*b955f6caSJeff Kirsher static int __init atarilance_module_init(void)
1153*b955f6caSJeff Kirsher {
1154*b955f6caSJeff Kirsher 	atarilance_dev = atarilance_probe(-1);
1155*b955f6caSJeff Kirsher 	if (IS_ERR(atarilance_dev))
1156*b955f6caSJeff Kirsher 		return PTR_ERR(atarilance_dev);
1157*b955f6caSJeff Kirsher 	return 0;
1158*b955f6caSJeff Kirsher }
1159*b955f6caSJeff Kirsher 
1160*b955f6caSJeff Kirsher static void __exit atarilance_module_exit(void)
1161*b955f6caSJeff Kirsher {
1162*b955f6caSJeff Kirsher 	unregister_netdev(atarilance_dev);
1163*b955f6caSJeff Kirsher 	free_irq(atarilance_dev->irq, atarilance_dev);
1164*b955f6caSJeff Kirsher 	free_netdev(atarilance_dev);
1165*b955f6caSJeff Kirsher }
1166*b955f6caSJeff Kirsher module_init(atarilance_module_init);
1167*b955f6caSJeff Kirsher module_exit(atarilance_module_exit);
1168*b955f6caSJeff Kirsher #endif /* MODULE */
1169*b955f6caSJeff Kirsher 
1170*b955f6caSJeff Kirsher 
1171*b955f6caSJeff Kirsher /*
1172*b955f6caSJeff Kirsher  * Local variables:
1173*b955f6caSJeff Kirsher  *  c-indent-level: 4
1174*b955f6caSJeff Kirsher  *  tab-width: 4
1175*b955f6caSJeff Kirsher  * End:
1176*b955f6caSJeff Kirsher  */
1177