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