xref: /openbmc/linux/drivers/net/ethernet/amd/atarilance.c (revision e179d78ee11a70e2675bc572f9f4e33d97233b23)
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];
159c2dfc7d2SGustavo 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 
370*e179d78eSArnd Bergmann struct net_device * __init atarilance_probe(void)
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 
386b955f6caSJeff Kirsher 	for( i = 0; i < N_LANCE_ADDR; ++i ) {
387b955f6caSJeff Kirsher 		if (lance_probe1( dev, &lance_addr_list[i] )) {
388b955f6caSJeff Kirsher 			found = 1;
389b955f6caSJeff Kirsher 			err = register_netdev(dev);
390b955f6caSJeff Kirsher 			if (!err)
391b955f6caSJeff Kirsher 				return dev;
392b955f6caSJeff Kirsher 			free_irq(dev->irq, dev);
393b955f6caSJeff Kirsher 			break;
394b955f6caSJeff Kirsher 		}
395b955f6caSJeff Kirsher 	}
396b955f6caSJeff Kirsher 	free_netdev(dev);
397b955f6caSJeff Kirsher 	return ERR_PTR(err);
398b955f6caSJeff Kirsher }
399b955f6caSJeff Kirsher 
400b955f6caSJeff Kirsher 
401b955f6caSJeff Kirsher /* Derived from hwreg_present() in atari/config.c: */
402b955f6caSJeff Kirsher 
403b955f6caSJeff Kirsher static noinline int __init addr_accessible(volatile void *regp, int wordflag,
404b955f6caSJeff Kirsher 					   int writeflag)
405b955f6caSJeff Kirsher {
406b955f6caSJeff Kirsher 	int		ret;
407b955f6caSJeff Kirsher 	unsigned long	flags;
408b955f6caSJeff Kirsher 	long	*vbr, save_berr;
409b955f6caSJeff Kirsher 
410b955f6caSJeff Kirsher 	local_irq_save(flags);
411b955f6caSJeff Kirsher 
412b955f6caSJeff Kirsher 	__asm__ __volatile__ ( "movec	%/vbr,%0" : "=r" (vbr) : );
413b955f6caSJeff Kirsher 	save_berr = vbr[2];
414b955f6caSJeff Kirsher 
415b955f6caSJeff Kirsher 	__asm__ __volatile__
416b955f6caSJeff Kirsher 	(	"movel	%/sp,%/d1\n\t"
417b955f6caSJeff Kirsher 		"movel	#Lberr,%2@\n\t"
418b955f6caSJeff Kirsher 		"moveq	#0,%0\n\t"
419b955f6caSJeff Kirsher 		"tstl   %3\n\t"
420b955f6caSJeff Kirsher 		"bne	1f\n\t"
421b955f6caSJeff Kirsher 		"moveb	%1@,%/d0\n\t"
422b955f6caSJeff Kirsher 		"nop	\n\t"
423b955f6caSJeff Kirsher 		"bra	2f\n"
424b955f6caSJeff Kirsher "1:		 movew	%1@,%/d0\n\t"
425b955f6caSJeff Kirsher 		"nop	\n"
426b955f6caSJeff Kirsher "2:		 tstl   %4\n\t"
427b955f6caSJeff Kirsher 		"beq	2f\n\t"
428b955f6caSJeff Kirsher 		"tstl	%3\n\t"
429b955f6caSJeff Kirsher 		"bne	1f\n\t"
430b955f6caSJeff Kirsher 		"clrb	%1@\n\t"
431b955f6caSJeff Kirsher 		"nop	\n\t"
432b955f6caSJeff Kirsher 		"moveb	%/d0,%1@\n\t"
433b955f6caSJeff Kirsher 		"nop	\n\t"
434b955f6caSJeff Kirsher 		"bra	2f\n"
435b955f6caSJeff Kirsher "1:		 clrw	%1@\n\t"
436b955f6caSJeff Kirsher 		"nop	\n\t"
437b955f6caSJeff Kirsher 		"movew	%/d0,%1@\n\t"
438b955f6caSJeff Kirsher 		"nop	\n"
439b955f6caSJeff Kirsher "2:		 moveq	#1,%0\n"
440b955f6caSJeff Kirsher "Lberr:	 movel	%/d1,%/sp"
441b955f6caSJeff Kirsher 		: "=&d" (ret)
442b955f6caSJeff Kirsher 		: "a" (regp), "a" (&vbr[2]), "rm" (wordflag), "rm" (writeflag)
443b955f6caSJeff Kirsher 		: "d0", "d1", "memory"
444b955f6caSJeff Kirsher 	);
445b955f6caSJeff Kirsher 
446b955f6caSJeff Kirsher 	vbr[2] = save_berr;
447b955f6caSJeff Kirsher 	local_irq_restore(flags);
448b955f6caSJeff Kirsher 
449b955f6caSJeff Kirsher 	return ret;
450b955f6caSJeff Kirsher }
451b955f6caSJeff Kirsher 
452b955f6caSJeff Kirsher static const struct net_device_ops lance_netdev_ops = {
453b955f6caSJeff Kirsher 	.ndo_open		= lance_open,
454b955f6caSJeff Kirsher 	.ndo_stop		= lance_close,
455b955f6caSJeff Kirsher 	.ndo_start_xmit		= lance_start_xmit,
456afc4b13dSJiri Pirko 	.ndo_set_rx_mode	= set_multicast_list,
457b955f6caSJeff Kirsher 	.ndo_set_mac_address	= lance_set_mac_address,
458b955f6caSJeff Kirsher 	.ndo_tx_timeout		= lance_tx_timeout,
459b955f6caSJeff Kirsher 	.ndo_validate_addr	= eth_validate_addr,
460b955f6caSJeff Kirsher };
461b955f6caSJeff Kirsher 
462b955f6caSJeff Kirsher static unsigned long __init lance_probe1( struct net_device *dev,
463b955f6caSJeff Kirsher 					   struct lance_addr *init_rec )
464b955f6caSJeff Kirsher {
465b955f6caSJeff Kirsher 	volatile unsigned short *memaddr =
466b955f6caSJeff Kirsher 		(volatile unsigned short *)init_rec->memaddr;
467b955f6caSJeff Kirsher 	volatile unsigned short *ioaddr =
468b955f6caSJeff Kirsher 		(volatile unsigned short *)init_rec->ioaddr;
469b955f6caSJeff Kirsher 	struct lance_private	*lp;
470b955f6caSJeff Kirsher 	struct lance_ioreg		*IO;
471b955f6caSJeff Kirsher 	int 					i;
472b955f6caSJeff Kirsher 	static int 				did_version;
473b955f6caSJeff Kirsher 	unsigned short			save1, save2;
474b955f6caSJeff Kirsher 
475b955f6caSJeff Kirsher 	PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n",
476b955f6caSJeff Kirsher 				  (long)memaddr, (long)ioaddr ));
477b955f6caSJeff Kirsher 
478b955f6caSJeff Kirsher 	/* Test whether memory readable and writable */
479b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing memory to be accessible\n" ));
480b955f6caSJeff Kirsher 	if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail;
481b955f6caSJeff Kirsher 
482b955f6caSJeff Kirsher 	/* Written values should come back... */
483b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing memory to be writable (1)\n" ));
484b955f6caSJeff Kirsher 	save1 = *memaddr;
485b955f6caSJeff Kirsher 	*memaddr = 0x0001;
486b955f6caSJeff Kirsher 	if (*memaddr != 0x0001) goto probe_fail;
487b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing memory to be writable (2)\n" ));
488b955f6caSJeff Kirsher 	*memaddr = 0x0000;
489b955f6caSJeff Kirsher 	if (*memaddr != 0x0000) goto probe_fail;
490b955f6caSJeff Kirsher 	*memaddr = save1;
491b955f6caSJeff Kirsher 
492b955f6caSJeff Kirsher 	/* First port should be readable and writable */
493b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing ioport to be accessible\n" ));
494b955f6caSJeff Kirsher 	if (!addr_accessible( ioaddr, 1, 1 )) goto probe_fail;
495b955f6caSJeff Kirsher 
496b955f6caSJeff Kirsher 	/* and written values should be readable */
497b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing ioport to be writeable\n" ));
498b955f6caSJeff Kirsher 	save2 = ioaddr[1];
499b955f6caSJeff Kirsher 	ioaddr[1] = 0x0001;
500b955f6caSJeff Kirsher 	if (ioaddr[1] != 0x0001) goto probe_fail;
501b955f6caSJeff Kirsher 
502b955f6caSJeff Kirsher 	/* The CSR0_INIT bit should not be readable */
503b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing CSR0 register function (1)\n" ));
504b955f6caSJeff Kirsher 	save1 = ioaddr[0];
505b955f6caSJeff Kirsher 	ioaddr[1] = CSR0;
506b955f6caSJeff Kirsher 	ioaddr[0] = CSR0_INIT | CSR0_STOP;
507b955f6caSJeff Kirsher 	if (ioaddr[0] != CSR0_STOP) {
508b955f6caSJeff Kirsher 		ioaddr[0] = save1;
509b955f6caSJeff Kirsher 		ioaddr[1] = save2;
510b955f6caSJeff Kirsher 		goto probe_fail;
511b955f6caSJeff Kirsher 	}
512b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: testing CSR0 register function (2)\n" ));
513b955f6caSJeff Kirsher 	ioaddr[0] = CSR0_STOP;
514b955f6caSJeff Kirsher 	if (ioaddr[0] != CSR0_STOP) {
515b955f6caSJeff Kirsher 		ioaddr[0] = save1;
516b955f6caSJeff Kirsher 		ioaddr[1] = save2;
517b955f6caSJeff Kirsher 		goto probe_fail;
518b955f6caSJeff Kirsher 	}
519b955f6caSJeff Kirsher 
520b955f6caSJeff Kirsher 	/* Now ok... */
521b955f6caSJeff Kirsher 	PROBE_PRINT(( "lance_probe1: Lance card detected\n" ));
522b955f6caSJeff Kirsher 	goto probe_ok;
523b955f6caSJeff Kirsher 
524b955f6caSJeff Kirsher   probe_fail:
525b955f6caSJeff Kirsher 	return 0;
526b955f6caSJeff Kirsher 
527b955f6caSJeff Kirsher   probe_ok:
528b955f6caSJeff Kirsher 	lp = netdev_priv(dev);
529b955f6caSJeff Kirsher 	MEM = (struct lance_memory *)memaddr;
530b955f6caSJeff Kirsher 	IO = lp->iobase = (struct lance_ioreg *)ioaddr;
531b955f6caSJeff Kirsher 	dev->base_addr = (unsigned long)ioaddr; /* informational only */
532b955f6caSJeff Kirsher 	lp->memcpy_f = init_rec->slow_flag ? slow_memcpy : memcpy;
533b955f6caSJeff Kirsher 
534b955f6caSJeff Kirsher 	REGA( CSR0 ) = CSR0_STOP;
535b955f6caSJeff Kirsher 
536b955f6caSJeff Kirsher 	/* Now test for type: If the eeprom I/O port is readable, it is a
537b955f6caSJeff Kirsher 	 * PAM card */
538b955f6caSJeff Kirsher 	if (addr_accessible( &(IO->eeprom), 0, 0 )) {
539b955f6caSJeff Kirsher 		/* Switch back to Ram */
540b955f6caSJeff Kirsher 		i = IO->mem;
541b955f6caSJeff Kirsher 		lp->cardtype = PAM_CARD;
542b955f6caSJeff Kirsher 	}
543b955f6caSJeff Kirsher 	else if (*RIEBL_MAGIC_ADDR == RIEBL_MAGIC) {
544b955f6caSJeff Kirsher 		lp->cardtype = NEW_RIEBL;
545b955f6caSJeff Kirsher 	}
546b955f6caSJeff Kirsher 	else
547b955f6caSJeff Kirsher 		lp->cardtype = OLD_RIEBL;
548b955f6caSJeff Kirsher 
549b955f6caSJeff Kirsher 	if (lp->cardtype == PAM_CARD ||
550b955f6caSJeff Kirsher 		memaddr == (unsigned short *)0xffe00000) {
551b955f6caSJeff Kirsher 		/* PAMs card and Riebl on ST use level 5 autovector */
5528f2bfe5fSGeert Uytterhoeven 		if (request_irq(IRQ_AUTO_5, lance_interrupt, 0,
553b955f6caSJeff Kirsher 				"PAM,Riebl-ST Ethernet", dev)) {
554b955f6caSJeff Kirsher 			printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 );
555b955f6caSJeff Kirsher 			return 0;
556b955f6caSJeff Kirsher 		}
55744883eb0SGeert Uytterhoeven 		dev->irq = IRQ_AUTO_5;
558b955f6caSJeff Kirsher 	}
559b955f6caSJeff Kirsher 	else {
56044883eb0SGeert Uytterhoeven 		/* For VME-RieblCards, request a free VME int */
56144883eb0SGeert Uytterhoeven 		unsigned int irq = atari_register_vme_int();
562b955f6caSJeff Kirsher 		if (!irq) {
563b955f6caSJeff Kirsher 			printk( "Lance: request for VME interrupt failed\n" );
564b955f6caSJeff Kirsher 			return 0;
565b955f6caSJeff Kirsher 		}
5668f2bfe5fSGeert Uytterhoeven 		if (request_irq(irq, lance_interrupt, 0, "Riebl-VME Ethernet",
5678f2bfe5fSGeert Uytterhoeven 				dev)) {
56844883eb0SGeert Uytterhoeven 			printk( "Lance: request for irq %u failed\n", irq );
569b955f6caSJeff Kirsher 			return 0;
570b955f6caSJeff Kirsher 		}
571b955f6caSJeff Kirsher 		dev->irq = irq;
572b955f6caSJeff Kirsher 	}
573b955f6caSJeff Kirsher 
574b955f6caSJeff Kirsher 	printk("%s: %s at io %#lx, mem %#lx, irq %d%s, hwaddr ",
575b955f6caSJeff Kirsher 		   dev->name, lance_names[lp->cardtype],
576b955f6caSJeff Kirsher 		   (unsigned long)ioaddr,
577b955f6caSJeff Kirsher 		   (unsigned long)memaddr,
578b955f6caSJeff Kirsher 		   dev->irq,
579b955f6caSJeff Kirsher 		   init_rec->slow_flag ? " (slow memcpy)" : "" );
580b955f6caSJeff Kirsher 
581b955f6caSJeff Kirsher 	/* Get the ethernet address */
582b955f6caSJeff Kirsher 	switch( lp->cardtype ) {
583b955f6caSJeff Kirsher 	  case OLD_RIEBL:
584b955f6caSJeff Kirsher 		/* No ethernet address! (Set some default address) */
585d458cdf7SJoe Perches 		memcpy(dev->dev_addr, OldRieblDefHwaddr, ETH_ALEN);
586b955f6caSJeff Kirsher 		break;
587b955f6caSJeff Kirsher 	  case NEW_RIEBL:
588d458cdf7SJoe Perches 		lp->memcpy_f(dev->dev_addr, RIEBL_HWADDR_ADDR, ETH_ALEN);
589b955f6caSJeff Kirsher 		break;
590b955f6caSJeff Kirsher 	  case PAM_CARD:
591b955f6caSJeff Kirsher 		i = IO->eeprom;
592b955f6caSJeff Kirsher 		for( i = 0; i < 6; ++i )
593b955f6caSJeff Kirsher 			dev->dev_addr[i] =
594b955f6caSJeff Kirsher 				((((unsigned short *)MEM)[i*2] & 0x0f) << 4) |
595b955f6caSJeff Kirsher 				((((unsigned short *)MEM)[i*2+1] & 0x0f));
596b955f6caSJeff Kirsher 		i = IO->mem;
597b955f6caSJeff Kirsher 		break;
598b955f6caSJeff Kirsher 	}
599b955f6caSJeff Kirsher 	printk("%pM\n", dev->dev_addr);
600b955f6caSJeff Kirsher 	if (lp->cardtype == OLD_RIEBL) {
601b955f6caSJeff Kirsher 		printk( "%s: Warning: This is a default ethernet address!\n",
602b955f6caSJeff Kirsher 				dev->name );
603b955f6caSJeff Kirsher 		printk( "      Use \"ifconfig hw ether ...\" to set the address.\n" );
604b955f6caSJeff Kirsher 	}
605b955f6caSJeff Kirsher 
606b955f6caSJeff Kirsher 	spin_lock_init(&lp->devlock);
607b955f6caSJeff Kirsher 
608b955f6caSJeff Kirsher 	MEM->init.mode = 0x0000;		/* Disable Rx and Tx. */
609b955f6caSJeff Kirsher 	for( i = 0; i < 6; i++ )
610b955f6caSJeff Kirsher 		MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
611b955f6caSJeff Kirsher 	MEM->init.filter[0] = 0x00000000;
612b955f6caSJeff Kirsher 	MEM->init.filter[1] = 0x00000000;
613b955f6caSJeff Kirsher 	MEM->init.rx_ring.adr_lo = offsetof( struct lance_memory, rx_head );
614b955f6caSJeff Kirsher 	MEM->init.rx_ring.adr_hi = 0;
615b955f6caSJeff Kirsher 	MEM->init.rx_ring.len    = RX_RING_LEN_BITS;
616b955f6caSJeff Kirsher 	MEM->init.tx_ring.adr_lo = offsetof( struct lance_memory, tx_head );
617b955f6caSJeff Kirsher 	MEM->init.tx_ring.adr_hi = 0;
618b955f6caSJeff Kirsher 	MEM->init.tx_ring.len    = TX_RING_LEN_BITS;
619b955f6caSJeff Kirsher 
620b955f6caSJeff Kirsher 	if (lp->cardtype == PAM_CARD)
621b955f6caSJeff Kirsher 		IO->ivec = IRQ_SOURCE_TO_VECTOR(dev->irq);
622b955f6caSJeff Kirsher 	else
623b955f6caSJeff Kirsher 		*RIEBL_IVEC_ADDR = IRQ_SOURCE_TO_VECTOR(dev->irq);
624b955f6caSJeff Kirsher 
625b955f6caSJeff Kirsher 	if (did_version++ == 0)
626b955f6caSJeff Kirsher 		DPRINTK( 1, ( version ));
627b955f6caSJeff Kirsher 
628b955f6caSJeff Kirsher 	dev->netdev_ops = &lance_netdev_ops;
629b955f6caSJeff Kirsher 
630b955f6caSJeff Kirsher 	/* XXX MSch */
631b955f6caSJeff Kirsher 	dev->watchdog_timeo = TX_TIMEOUT;
632b955f6caSJeff Kirsher 
633b955f6caSJeff Kirsher 	return 1;
634b955f6caSJeff Kirsher }
635b955f6caSJeff Kirsher 
636b955f6caSJeff Kirsher 
637b955f6caSJeff Kirsher static int lance_open( struct net_device *dev )
638b955f6caSJeff Kirsher {
639b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
640b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
641b955f6caSJeff Kirsher 	int i;
642b955f6caSJeff Kirsher 
643b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: lance_open()\n", dev->name ));
644b955f6caSJeff Kirsher 
645b955f6caSJeff Kirsher 	lance_init_ring(dev);
646b955f6caSJeff Kirsher 	/* Re-initialize the LANCE, and start it when done. */
647b955f6caSJeff Kirsher 
648b955f6caSJeff Kirsher 	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
649b955f6caSJeff Kirsher 	REGA( CSR2 ) = 0;
650b955f6caSJeff Kirsher 	REGA( CSR1 ) = 0;
651b955f6caSJeff Kirsher 	REGA( CSR0 ) = CSR0_INIT;
652b955f6caSJeff Kirsher 	/* From now on, AREG is kept to point to CSR0 */
653b955f6caSJeff Kirsher 
654b955f6caSJeff Kirsher 	i = 1000000;
655b955f6caSJeff Kirsher 	while (--i > 0)
656b955f6caSJeff Kirsher 		if (DREG & CSR0_IDON)
657b955f6caSJeff Kirsher 			break;
658b955f6caSJeff Kirsher 	if (i <= 0 || (DREG & CSR0_ERR)) {
659b955f6caSJeff Kirsher 		DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
660b955f6caSJeff Kirsher 					  dev->name, i, DREG ));
661b955f6caSJeff Kirsher 		DREG = CSR0_STOP;
662b955f6caSJeff Kirsher 		return -EIO;
663b955f6caSJeff Kirsher 	}
664b955f6caSJeff Kirsher 	DREG = CSR0_IDON;
665b955f6caSJeff Kirsher 	DREG = CSR0_STRT;
666b955f6caSJeff Kirsher 	DREG = CSR0_INEA;
667b955f6caSJeff Kirsher 
668b955f6caSJeff Kirsher 	netif_start_queue (dev);
669b955f6caSJeff Kirsher 
670b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
671b955f6caSJeff Kirsher 
672b955f6caSJeff Kirsher 	return 0;
673b955f6caSJeff Kirsher }
674b955f6caSJeff Kirsher 
675b955f6caSJeff Kirsher 
676b955f6caSJeff Kirsher /* Initialize the LANCE Rx and Tx rings. */
677b955f6caSJeff Kirsher 
678b955f6caSJeff Kirsher static void lance_init_ring( struct net_device *dev )
679b955f6caSJeff Kirsher {
680b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
681b955f6caSJeff Kirsher 	int i;
682b955f6caSJeff Kirsher 	unsigned offset;
683b955f6caSJeff Kirsher 
684b955f6caSJeff Kirsher 	lp->tx_full = 0;
685b955f6caSJeff Kirsher 	lp->cur_rx = lp->cur_tx = 0;
686b955f6caSJeff Kirsher 	lp->dirty_tx = 0;
687b955f6caSJeff Kirsher 
688b955f6caSJeff Kirsher 	offset = offsetof( struct lance_memory, packet_area );
689b955f6caSJeff Kirsher 
690b955f6caSJeff Kirsher /* If the packet buffer at offset 'o' would conflict with the reserved area
691b955f6caSJeff Kirsher  * of RieblCards, advance it */
692b955f6caSJeff Kirsher #define	CHECK_OFFSET(o)														 \
693b955f6caSJeff Kirsher 	do {																	 \
694b955f6caSJeff Kirsher 		if (lp->cardtype == OLD_RIEBL || lp->cardtype == NEW_RIEBL) {		 \
695b955f6caSJeff Kirsher 			if (((o) < RIEBL_RSVD_START) ? (o)+PKT_BUF_SZ > RIEBL_RSVD_START \
696b955f6caSJeff Kirsher 										 : (o) < RIEBL_RSVD_END)			 \
697b955f6caSJeff Kirsher 				(o) = RIEBL_RSVD_END;										 \
698b955f6caSJeff Kirsher 		}																	 \
699b955f6caSJeff Kirsher 	} while(0)
700b955f6caSJeff Kirsher 
701b955f6caSJeff Kirsher 	for( i = 0; i < TX_RING_SIZE; i++ ) {
702b955f6caSJeff Kirsher 		CHECK_OFFSET(offset);
703b955f6caSJeff Kirsher 		MEM->tx_head[i].base = offset;
704b955f6caSJeff Kirsher 		MEM->tx_head[i].flag = TMD1_OWN_HOST;
705b955f6caSJeff Kirsher 		MEM->tx_head[i].base_hi = 0;
706b955f6caSJeff Kirsher 		MEM->tx_head[i].length = 0;
707b955f6caSJeff Kirsher 		MEM->tx_head[i].misc = 0;
708b955f6caSJeff Kirsher 		offset += PKT_BUF_SZ;
709b955f6caSJeff Kirsher 	}
710b955f6caSJeff Kirsher 
711b955f6caSJeff Kirsher 	for( i = 0; i < RX_RING_SIZE; i++ ) {
712b955f6caSJeff Kirsher 		CHECK_OFFSET(offset);
713b955f6caSJeff Kirsher 		MEM->rx_head[i].base = offset;
714b955f6caSJeff Kirsher 		MEM->rx_head[i].flag = TMD1_OWN_CHIP;
715b955f6caSJeff Kirsher 		MEM->rx_head[i].base_hi = 0;
716b955f6caSJeff Kirsher 		MEM->rx_head[i].buf_length = -PKT_BUF_SZ;
717b955f6caSJeff Kirsher 		MEM->rx_head[i].msg_length = 0;
718b955f6caSJeff Kirsher 		offset += PKT_BUF_SZ;
719b955f6caSJeff Kirsher 	}
720b955f6caSJeff Kirsher }
721b955f6caSJeff Kirsher 
722b955f6caSJeff Kirsher 
723b955f6caSJeff Kirsher /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
724b955f6caSJeff Kirsher 
725b955f6caSJeff Kirsher 
7260290bd29SMichael S. Tsirkin static void lance_tx_timeout (struct net_device *dev, unsigned int txqueue)
727b955f6caSJeff Kirsher {
728b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
729b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
730b955f6caSJeff Kirsher 
731b955f6caSJeff Kirsher 	AREG = CSR0;
732b955f6caSJeff Kirsher 	DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
733b955f6caSJeff Kirsher 			  dev->name, DREG ));
734b955f6caSJeff Kirsher 	DREG = CSR0_STOP;
735b955f6caSJeff Kirsher 	/*
736b955f6caSJeff Kirsher 	 * Always set BSWP after a STOP as STOP puts it back into
737b955f6caSJeff Kirsher 	 * little endian mode.
738b955f6caSJeff Kirsher 	 */
739b955f6caSJeff Kirsher 	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
740b955f6caSJeff Kirsher 	dev->stats.tx_errors++;
741b955f6caSJeff Kirsher #ifndef final_version
742b955f6caSJeff Kirsher 		{	int i;
743b955f6caSJeff Kirsher 			DPRINTK( 2, ( "Ring data: dirty_tx %d cur_tx %d%s cur_rx %d\n",
744b955f6caSJeff Kirsher 						  lp->dirty_tx, lp->cur_tx,
745b955f6caSJeff Kirsher 						  lp->tx_full ? " (full)" : "",
746b955f6caSJeff Kirsher 						  lp->cur_rx ));
747b955f6caSJeff Kirsher 			for( i = 0 ; i < RX_RING_SIZE; i++ )
748b955f6caSJeff Kirsher 				DPRINTK( 2, ( "rx #%d: base=%04x blen=%04x mlen=%04x\n",
749b955f6caSJeff Kirsher 							  i, MEM->rx_head[i].base,
750b955f6caSJeff Kirsher 							  -MEM->rx_head[i].buf_length,
751b955f6caSJeff Kirsher 							  MEM->rx_head[i].msg_length ));
752b955f6caSJeff Kirsher 			for( i = 0 ; i < TX_RING_SIZE; i++ )
753b955f6caSJeff Kirsher 				DPRINTK( 2, ( "tx #%d: base=%04x len=%04x misc=%04x\n",
754b955f6caSJeff Kirsher 							  i, MEM->tx_head[i].base,
755b955f6caSJeff Kirsher 							  -MEM->tx_head[i].length,
756b955f6caSJeff Kirsher 							  MEM->tx_head[i].misc ));
757b955f6caSJeff Kirsher 		}
758b955f6caSJeff Kirsher #endif
759b955f6caSJeff Kirsher 	/* XXX MSch: maybe purge/reinit ring here */
760b955f6caSJeff Kirsher 	/* lance_restart, essentially */
761b955f6caSJeff Kirsher 	lance_init_ring(dev);
762b955f6caSJeff Kirsher 	REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
763860e9538SFlorian Westphal 	netif_trans_update(dev); /* prevent tx timeout */
764b955f6caSJeff Kirsher 	netif_wake_queue(dev);
765b955f6caSJeff Kirsher }
766b955f6caSJeff Kirsher 
767b955f6caSJeff Kirsher /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
768b955f6caSJeff Kirsher 
769fe72352eSYueHaibing static netdev_tx_t
770fe72352eSYueHaibing lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
771b955f6caSJeff Kirsher {
772b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
773b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
774b955f6caSJeff Kirsher 	int entry, len;
775b955f6caSJeff Kirsher 	struct lance_tx_head *head;
776b955f6caSJeff Kirsher 	unsigned long flags;
777b955f6caSJeff Kirsher 
778b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
779b955f6caSJeff Kirsher 				  dev->name, DREG ));
780b955f6caSJeff Kirsher 
781b955f6caSJeff Kirsher 
782b955f6caSJeff Kirsher 	/* The old LANCE chips doesn't automatically pad buffers to min. size. */
783b955f6caSJeff Kirsher 	len = skb->len;
784b955f6caSJeff Kirsher 	if (len < ETH_ZLEN)
785b955f6caSJeff Kirsher 		len = ETH_ZLEN;
786b955f6caSJeff Kirsher 	/* PAM-Card has a bug: Can only send packets with even number of bytes! */
787b955f6caSJeff Kirsher 	else if (lp->cardtype == PAM_CARD && (len & 1))
788b955f6caSJeff Kirsher 		++len;
789b955f6caSJeff Kirsher 
790b955f6caSJeff Kirsher 	if (len > skb->len) {
791b955f6caSJeff Kirsher 		if (skb_padto(skb, len))
792b955f6caSJeff Kirsher 			return NETDEV_TX_OK;
793b955f6caSJeff Kirsher 	}
794b955f6caSJeff Kirsher 
795b955f6caSJeff Kirsher 	netif_stop_queue (dev);
796b955f6caSJeff Kirsher 
797b955f6caSJeff Kirsher 	/* Fill in a Tx ring entry */
798b955f6caSJeff Kirsher 	if (lance_debug >= 3) {
799b955f6caSJeff Kirsher 		printk( "%s: TX pkt type 0x%04x from %pM to %pM"
800b955f6caSJeff Kirsher 				" data at 0x%08x len %d\n",
801b955f6caSJeff Kirsher 				dev->name, ((u_short *)skb->data)[6],
802b955f6caSJeff Kirsher 				&skb->data[6], skb->data,
803b955f6caSJeff Kirsher 				(int)skb->data, (int)skb->len );
804b955f6caSJeff Kirsher 	}
805b955f6caSJeff Kirsher 
806b955f6caSJeff Kirsher 	/* We're not prepared for the int until the last flags are set/reset. And
807b955f6caSJeff Kirsher 	 * the int may happen already after setting the OWN_CHIP... */
808b955f6caSJeff Kirsher 	spin_lock_irqsave (&lp->devlock, flags);
809b955f6caSJeff Kirsher 
810b955f6caSJeff Kirsher 	/* Mask to ring buffer boundary. */
811b955f6caSJeff Kirsher 	entry = lp->cur_tx & TX_RING_MOD_MASK;
812b955f6caSJeff Kirsher 	head  = &(MEM->tx_head[entry]);
813b955f6caSJeff Kirsher 
814b955f6caSJeff Kirsher 	/* Caution: the write order is important here, set the "ownership" bits
815b955f6caSJeff Kirsher 	 * last.
816b955f6caSJeff Kirsher 	 */
817b955f6caSJeff Kirsher 
818b955f6caSJeff Kirsher 
819b955f6caSJeff Kirsher 	head->length = -len;
820b955f6caSJeff Kirsher 	head->misc = 0;
821b955f6caSJeff Kirsher 	lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len );
822b955f6caSJeff Kirsher 	head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP;
823b955f6caSJeff Kirsher 	dev->stats.tx_bytes += skb->len;
824b955f6caSJeff Kirsher 	dev_kfree_skb( skb );
825b955f6caSJeff Kirsher 	lp->cur_tx++;
826b955f6caSJeff Kirsher 	while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) {
827b955f6caSJeff Kirsher 		lp->cur_tx -= TX_RING_SIZE;
828b955f6caSJeff Kirsher 		lp->dirty_tx -= TX_RING_SIZE;
829b955f6caSJeff Kirsher 	}
830b955f6caSJeff Kirsher 
831b955f6caSJeff Kirsher 	/* Trigger an immediate send poll. */
832b955f6caSJeff Kirsher 	DREG = CSR0_INEA | CSR0_TDMD;
833b955f6caSJeff Kirsher 
834b955f6caSJeff Kirsher 	if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
835b955f6caSJeff Kirsher 		TMD1_OWN_HOST)
836b955f6caSJeff Kirsher 		netif_start_queue (dev);
837b955f6caSJeff Kirsher 	else
838b955f6caSJeff Kirsher 		lp->tx_full = 1;
839b955f6caSJeff Kirsher 	spin_unlock_irqrestore (&lp->devlock, flags);
840b955f6caSJeff Kirsher 
841b955f6caSJeff Kirsher 	return NETDEV_TX_OK;
842b955f6caSJeff Kirsher }
843b955f6caSJeff Kirsher 
844b955f6caSJeff Kirsher /* The LANCE interrupt handler. */
845b955f6caSJeff Kirsher 
846b955f6caSJeff Kirsher static irqreturn_t lance_interrupt( int irq, void *dev_id )
847b955f6caSJeff Kirsher {
848b955f6caSJeff Kirsher 	struct net_device *dev = dev_id;
849b955f6caSJeff Kirsher 	struct lance_private *lp;
850b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO;
851b955f6caSJeff Kirsher 	int csr0, boguscnt = 10;
852b955f6caSJeff Kirsher 	int handled = 0;
853b955f6caSJeff Kirsher 
854b955f6caSJeff Kirsher 	if (dev == NULL) {
855b955f6caSJeff Kirsher 		DPRINTK( 1, ( "lance_interrupt(): interrupt for unknown device.\n" ));
856b955f6caSJeff Kirsher 		return IRQ_NONE;
857b955f6caSJeff Kirsher 	}
858b955f6caSJeff Kirsher 
859b955f6caSJeff Kirsher 	lp = netdev_priv(dev);
860b955f6caSJeff Kirsher 	IO = lp->iobase;
861b955f6caSJeff Kirsher 	spin_lock (&lp->devlock);
862b955f6caSJeff Kirsher 
863b955f6caSJeff Kirsher 	AREG = CSR0;
864b955f6caSJeff Kirsher 
865b955f6caSJeff Kirsher 	while( ((csr0 = DREG) & (CSR0_ERR | CSR0_TINT | CSR0_RINT)) &&
866b955f6caSJeff Kirsher 		   --boguscnt >= 0) {
867b955f6caSJeff Kirsher 		handled = 1;
868b955f6caSJeff Kirsher 		/* Acknowledge all of the current interrupt sources ASAP. */
869b955f6caSJeff Kirsher 		DREG = csr0 & ~(CSR0_INIT | CSR0_STRT | CSR0_STOP |
870b955f6caSJeff Kirsher 									CSR0_TDMD | CSR0_INEA);
871b955f6caSJeff Kirsher 
872b955f6caSJeff Kirsher 		DPRINTK( 2, ( "%s: interrupt  csr0=%04x new csr=%04x.\n",
873b955f6caSJeff Kirsher 					  dev->name, csr0, DREG ));
874b955f6caSJeff Kirsher 
875b955f6caSJeff Kirsher 		if (csr0 & CSR0_RINT)			/* Rx interrupt */
876b955f6caSJeff Kirsher 			lance_rx( dev );
877b955f6caSJeff Kirsher 
878b955f6caSJeff Kirsher 		if (csr0 & CSR0_TINT) {			/* Tx-done interrupt */
879b955f6caSJeff Kirsher 			int dirty_tx = lp->dirty_tx;
880b955f6caSJeff Kirsher 
881b955f6caSJeff Kirsher 			while( dirty_tx < lp->cur_tx) {
882b955f6caSJeff Kirsher 				int entry = dirty_tx & TX_RING_MOD_MASK;
883b955f6caSJeff Kirsher 				int status = MEM->tx_head[entry].flag;
884b955f6caSJeff Kirsher 
885b955f6caSJeff Kirsher 				if (status & TMD1_OWN_CHIP)
886b955f6caSJeff Kirsher 					break;			/* It still hasn't been Txed */
887b955f6caSJeff Kirsher 
888b955f6caSJeff Kirsher 				MEM->tx_head[entry].flag = 0;
889b955f6caSJeff Kirsher 
890b955f6caSJeff Kirsher 				if (status & TMD1_ERR) {
891b955f6caSJeff Kirsher 					/* There was an major error, log it. */
892b955f6caSJeff Kirsher 					int err_status = MEM->tx_head[entry].misc;
893b955f6caSJeff Kirsher 					dev->stats.tx_errors++;
894b955f6caSJeff Kirsher 					if (err_status & TMD3_RTRY) dev->stats.tx_aborted_errors++;
895b955f6caSJeff Kirsher 					if (err_status & TMD3_LCAR) dev->stats.tx_carrier_errors++;
896b955f6caSJeff Kirsher 					if (err_status & TMD3_LCOL) dev->stats.tx_window_errors++;
897b955f6caSJeff Kirsher 					if (err_status & TMD3_UFLO) {
898b955f6caSJeff Kirsher 						/* Ackk!  On FIFO errors the Tx unit is turned off! */
899b955f6caSJeff Kirsher 						dev->stats.tx_fifo_errors++;
900b955f6caSJeff Kirsher 						/* Remove this verbosity later! */
901b955f6caSJeff Kirsher 						DPRINTK( 1, ( "%s: Tx FIFO error! Status %04x\n",
902b955f6caSJeff Kirsher 									  dev->name, csr0 ));
903b955f6caSJeff Kirsher 						/* Restart the chip. */
904b955f6caSJeff Kirsher 						DREG = CSR0_STRT;
905b955f6caSJeff Kirsher 					}
906b955f6caSJeff Kirsher 				} else {
907b955f6caSJeff Kirsher 					if (status & (TMD1_MORE | TMD1_ONE | TMD1_DEF))
908b955f6caSJeff Kirsher 						dev->stats.collisions++;
909b955f6caSJeff Kirsher 					dev->stats.tx_packets++;
910b955f6caSJeff Kirsher 				}
911b955f6caSJeff Kirsher 
912b955f6caSJeff Kirsher 				/* XXX MSch: free skb?? */
913b955f6caSJeff Kirsher 				dirty_tx++;
914b955f6caSJeff Kirsher 			}
915b955f6caSJeff Kirsher 
916b955f6caSJeff Kirsher #ifndef final_version
917b955f6caSJeff Kirsher 			if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
918b955f6caSJeff Kirsher 				DPRINTK( 0, ( "out-of-sync dirty pointer,"
919b955f6caSJeff Kirsher 							  " %d vs. %d, full=%ld.\n",
920b955f6caSJeff Kirsher 							  dirty_tx, lp->cur_tx, lp->tx_full ));
921b955f6caSJeff Kirsher 				dirty_tx += TX_RING_SIZE;
922b955f6caSJeff Kirsher 			}
923b955f6caSJeff Kirsher #endif
924b955f6caSJeff Kirsher 
925b955f6caSJeff Kirsher 			if (lp->tx_full && (netif_queue_stopped(dev)) &&
926b955f6caSJeff Kirsher 				dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
927b955f6caSJeff Kirsher 				/* The ring is no longer full, clear tbusy. */
928b955f6caSJeff Kirsher 				lp->tx_full = 0;
929b955f6caSJeff Kirsher 				netif_wake_queue (dev);
930b955f6caSJeff Kirsher 			}
931b955f6caSJeff Kirsher 
932b955f6caSJeff Kirsher 			lp->dirty_tx = dirty_tx;
933b955f6caSJeff Kirsher 		}
934b955f6caSJeff Kirsher 
935b955f6caSJeff Kirsher 		/* Log misc errors. */
936b955f6caSJeff Kirsher 		if (csr0 & CSR0_BABL) dev->stats.tx_errors++; /* Tx babble. */
937b955f6caSJeff Kirsher 		if (csr0 & CSR0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */
938b955f6caSJeff Kirsher 		if (csr0 & CSR0_MERR) {
939b955f6caSJeff Kirsher 			DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), "
940b955f6caSJeff Kirsher 						  "status %04x.\n", dev->name, csr0 ));
941b955f6caSJeff Kirsher 			/* Restart the chip. */
942b955f6caSJeff Kirsher 			DREG = CSR0_STRT;
943b955f6caSJeff Kirsher 		}
944b955f6caSJeff Kirsher 	}
945b955f6caSJeff Kirsher 
946b955f6caSJeff Kirsher     /* Clear any other interrupt, and set interrupt enable. */
947b955f6caSJeff Kirsher 	DREG = CSR0_BABL | CSR0_CERR | CSR0_MISS | CSR0_MERR |
948b955f6caSJeff Kirsher 		   CSR0_IDON | CSR0_INEA;
949b955f6caSJeff Kirsher 
950b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: exiting interrupt, csr0=%#04x.\n",
951b955f6caSJeff Kirsher 				  dev->name, DREG ));
952b955f6caSJeff Kirsher 
953b955f6caSJeff Kirsher 	spin_unlock (&lp->devlock);
954b955f6caSJeff Kirsher 	return IRQ_RETVAL(handled);
955b955f6caSJeff Kirsher }
956b955f6caSJeff Kirsher 
957b955f6caSJeff Kirsher 
958b955f6caSJeff Kirsher static int lance_rx( struct net_device *dev )
959b955f6caSJeff Kirsher {
960b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
961b955f6caSJeff Kirsher 	int entry = lp->cur_rx & RX_RING_MOD_MASK;
962b955f6caSJeff Kirsher 	int i;
963b955f6caSJeff Kirsher 
964b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name,
965b955f6caSJeff Kirsher 				  MEM->rx_head[entry].flag ));
966b955f6caSJeff Kirsher 
967b955f6caSJeff Kirsher 	/* If we own the next entry, it's a new packet. Send it up. */
968b955f6caSJeff Kirsher 	while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
969b955f6caSJeff Kirsher 		struct lance_rx_head *head = &(MEM->rx_head[entry]);
970b955f6caSJeff Kirsher 		int status = head->flag;
971b955f6caSJeff Kirsher 
972b955f6caSJeff Kirsher 		if (status != (RMD1_ENP|RMD1_STP)) {		/* There was an error. */
973b955f6caSJeff Kirsher 			/* There is a tricky error noted by John Murphy,
974b955f6caSJeff Kirsher 			   <murf@perftech.com> to Russ Nelson: Even with full-sized
975b955f6caSJeff Kirsher 			   buffers it's possible for a jabber packet to use two
976b955f6caSJeff Kirsher 			   buffers, with only the last correctly noting the error. */
977b955f6caSJeff Kirsher 			if (status & RMD1_ENP)	/* Only count a general error at the */
978b955f6caSJeff Kirsher 				dev->stats.rx_errors++; /* end of a packet.*/
979b955f6caSJeff Kirsher 			if (status & RMD1_FRAM) dev->stats.rx_frame_errors++;
980b955f6caSJeff Kirsher 			if (status & RMD1_OFLO) dev->stats.rx_over_errors++;
981b955f6caSJeff Kirsher 			if (status & RMD1_CRC) dev->stats.rx_crc_errors++;
982b955f6caSJeff Kirsher 			if (status & RMD1_BUFF) dev->stats.rx_fifo_errors++;
983b955f6caSJeff Kirsher 			head->flag &= (RMD1_ENP|RMD1_STP);
984b955f6caSJeff Kirsher 		} else {
985b955f6caSJeff Kirsher 			/* Malloc up new buffer, compatible with net-3. */
986b955f6caSJeff Kirsher 			short pkt_len = head->msg_length & 0xfff;
987b955f6caSJeff Kirsher 			struct sk_buff *skb;
988b955f6caSJeff Kirsher 
989b955f6caSJeff Kirsher 			if (pkt_len < 60) {
990b955f6caSJeff Kirsher 				printk( "%s: Runt packet!\n", dev->name );
991b955f6caSJeff Kirsher 				dev->stats.rx_errors++;
992b955f6caSJeff Kirsher 			}
993b955f6caSJeff Kirsher 			else {
9941d266430SPradeep A Dalvi 				skb = netdev_alloc_skb(dev, pkt_len + 2);
995b955f6caSJeff Kirsher 				if (skb == NULL) {
996b955f6caSJeff Kirsher 					for( i = 0; i < RX_RING_SIZE; i++ )
997b955f6caSJeff Kirsher 						if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag &
998b955f6caSJeff Kirsher 							RMD1_OWN_CHIP)
999b955f6caSJeff Kirsher 							break;
1000b955f6caSJeff Kirsher 
1001b955f6caSJeff Kirsher 					if (i > RX_RING_SIZE - 2) {
1002b955f6caSJeff Kirsher 						dev->stats.rx_dropped++;
1003b955f6caSJeff Kirsher 						head->flag |= RMD1_OWN_CHIP;
1004b955f6caSJeff Kirsher 						lp->cur_rx++;
1005b955f6caSJeff Kirsher 					}
1006b955f6caSJeff Kirsher 					break;
1007b955f6caSJeff Kirsher 				}
1008b955f6caSJeff Kirsher 
1009b955f6caSJeff Kirsher 				if (lance_debug >= 3) {
1010b955f6caSJeff Kirsher 					u_char *data = PKTBUF_ADDR(head);
1011b955f6caSJeff Kirsher 
1012b955f6caSJeff Kirsher 					printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %pM to %pM "
1013b14945acSRasmus Villemoes 						   "data %8ph len %d\n",
1014b955f6caSJeff Kirsher 						   dev->name, ((u_short *)data)[6],
1015b14945acSRasmus Villemoes 						   &data[6], data, &data[15], pkt_len);
1016b955f6caSJeff Kirsher 				}
1017b955f6caSJeff Kirsher 
1018b955f6caSJeff Kirsher 				skb_reserve( skb, 2 );	/* 16 byte align */
1019b955f6caSJeff Kirsher 				skb_put( skb, pkt_len );	/* Make room */
1020b955f6caSJeff Kirsher 				lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len );
1021b955f6caSJeff Kirsher 				skb->protocol = eth_type_trans( skb, dev );
1022b955f6caSJeff Kirsher 				netif_rx( skb );
1023b955f6caSJeff Kirsher 				dev->stats.rx_packets++;
1024b955f6caSJeff Kirsher 				dev->stats.rx_bytes += pkt_len;
1025b955f6caSJeff Kirsher 			}
1026b955f6caSJeff Kirsher 		}
1027b955f6caSJeff Kirsher 
1028b955f6caSJeff Kirsher 		head->flag |= RMD1_OWN_CHIP;
1029b955f6caSJeff Kirsher 		entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
1030b955f6caSJeff Kirsher 	}
1031b955f6caSJeff Kirsher 	lp->cur_rx &= RX_RING_MOD_MASK;
1032b955f6caSJeff Kirsher 
1033b955f6caSJeff Kirsher 	/* From lance.c (Donald Becker): */
1034b955f6caSJeff Kirsher 	/* We should check that at least two ring entries are free.	 If not,
1035b955f6caSJeff Kirsher 	   we should free one and mark stats->rx_dropped++. */
1036b955f6caSJeff Kirsher 
1037b955f6caSJeff Kirsher 	return 0;
1038b955f6caSJeff Kirsher }
1039b955f6caSJeff Kirsher 
1040b955f6caSJeff Kirsher 
1041b955f6caSJeff Kirsher static int lance_close( struct net_device *dev )
1042b955f6caSJeff Kirsher {
1043b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
1044b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
1045b955f6caSJeff Kirsher 
1046b955f6caSJeff Kirsher 	netif_stop_queue (dev);
1047b955f6caSJeff Kirsher 
1048b955f6caSJeff Kirsher 	AREG = CSR0;
1049b955f6caSJeff Kirsher 
1050b955f6caSJeff Kirsher 	DPRINTK( 2, ( "%s: Shutting down ethercard, status was %2.2x.\n",
1051b955f6caSJeff Kirsher 				  dev->name, DREG ));
1052b955f6caSJeff Kirsher 
1053b955f6caSJeff Kirsher 	/* We stop the LANCE here -- it occasionally polls
1054b955f6caSJeff Kirsher 	   memory if we don't. */
1055b955f6caSJeff Kirsher 	DREG = CSR0_STOP;
1056b955f6caSJeff Kirsher 
1057b955f6caSJeff Kirsher 	return 0;
1058b955f6caSJeff Kirsher }
1059b955f6caSJeff Kirsher 
1060b955f6caSJeff Kirsher 
1061b955f6caSJeff Kirsher /* Set or clear the multicast filter for this adaptor.
1062b955f6caSJeff Kirsher    num_addrs == -1		Promiscuous mode, receive all packets
1063b955f6caSJeff Kirsher    num_addrs == 0		Normal mode, clear multicast list
1064b955f6caSJeff Kirsher    num_addrs > 0		Multicast mode, receive normal and MC packets, and do
1065b955f6caSJeff Kirsher 						best-effort filtering.
1066b955f6caSJeff Kirsher  */
1067b955f6caSJeff Kirsher 
1068b955f6caSJeff Kirsher static void set_multicast_list( struct net_device *dev )
1069b955f6caSJeff Kirsher {
1070b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
1071b955f6caSJeff Kirsher 	struct lance_ioreg	 *IO = lp->iobase;
1072b955f6caSJeff Kirsher 
1073b955f6caSJeff Kirsher 	if (netif_running(dev))
1074b955f6caSJeff Kirsher 		/* Only possible if board is already started */
1075b955f6caSJeff Kirsher 		return;
1076b955f6caSJeff Kirsher 
1077b955f6caSJeff Kirsher 	/* We take the simple way out and always enable promiscuous mode. */
1078b955f6caSJeff Kirsher 	DREG = CSR0_STOP; /* Temporarily stop the lance. */
1079b955f6caSJeff Kirsher 
1080b955f6caSJeff Kirsher 	if (dev->flags & IFF_PROMISC) {
1081b955f6caSJeff Kirsher 		/* Log any net taps. */
1082b955f6caSJeff Kirsher 		DPRINTK( 2, ( "%s: Promiscuous mode enabled.\n", dev->name ));
1083b955f6caSJeff Kirsher 		REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
1084b955f6caSJeff Kirsher 	} else {
1085b955f6caSJeff Kirsher 		short multicast_table[4];
1086b955f6caSJeff Kirsher 		int num_addrs = netdev_mc_count(dev);
1087b955f6caSJeff Kirsher 		int i;
1088b955f6caSJeff Kirsher 		/* We don't use the multicast table, but rely on upper-layer
1089b955f6caSJeff Kirsher 		 * filtering. */
1090b955f6caSJeff Kirsher 		memset( multicast_table, (num_addrs == 0) ? 0 : -1,
1091b955f6caSJeff Kirsher 				sizeof(multicast_table) );
1092b955f6caSJeff Kirsher 		for( i = 0; i < 4; i++ )
1093b955f6caSJeff Kirsher 			REGA( CSR8+i ) = multicast_table[i];
1094b955f6caSJeff Kirsher 		REGA( CSR15 ) = 0; /* Unset promiscuous mode */
1095b955f6caSJeff Kirsher 	}
1096b955f6caSJeff Kirsher 
1097b955f6caSJeff Kirsher 	/*
1098b955f6caSJeff Kirsher 	 * Always set BSWP after a STOP as STOP puts it back into
1099b955f6caSJeff Kirsher 	 * little endian mode.
1100b955f6caSJeff Kirsher 	 */
1101b955f6caSJeff Kirsher 	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
1102b955f6caSJeff Kirsher 
1103b955f6caSJeff Kirsher 	/* Resume normal operation and reset AREG to CSR0 */
1104b955f6caSJeff Kirsher 	REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT;
1105b955f6caSJeff Kirsher }
1106b955f6caSJeff Kirsher 
1107b955f6caSJeff Kirsher 
1108b955f6caSJeff Kirsher /* This is needed for old RieblCards and possible for new RieblCards */
1109b955f6caSJeff Kirsher 
1110b955f6caSJeff Kirsher static int lance_set_mac_address( struct net_device *dev, void *addr )
1111b955f6caSJeff Kirsher {
1112b955f6caSJeff Kirsher 	struct lance_private *lp = netdev_priv(dev);
1113b955f6caSJeff Kirsher 	struct sockaddr *saddr = addr;
1114b955f6caSJeff Kirsher 	int i;
1115b955f6caSJeff Kirsher 
1116b955f6caSJeff Kirsher 	if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL)
1117b955f6caSJeff Kirsher 		return -EOPNOTSUPP;
1118b955f6caSJeff Kirsher 
1119b955f6caSJeff Kirsher 	if (netif_running(dev)) {
1120b955f6caSJeff Kirsher 		/* Only possible while card isn't started */
1121b955f6caSJeff Kirsher 		DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n",
1122b955f6caSJeff Kirsher 					  dev->name ));
1123b955f6caSJeff Kirsher 		return -EIO;
1124b955f6caSJeff Kirsher 	}
1125b955f6caSJeff Kirsher 
1126b955f6caSJeff Kirsher 	memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len );
1127b955f6caSJeff Kirsher 	for( i = 0; i < 6; i++ )
1128b955f6caSJeff Kirsher 		MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
1129b955f6caSJeff Kirsher 	lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 );
1130b955f6caSJeff Kirsher 	/* set also the magic for future sessions */
1131b955f6caSJeff Kirsher 	*RIEBL_MAGIC_ADDR = RIEBL_MAGIC;
1132b955f6caSJeff Kirsher 
1133b955f6caSJeff Kirsher 	return 0;
1134b955f6caSJeff Kirsher }
1135b955f6caSJeff Kirsher 
1136b955f6caSJeff Kirsher static struct net_device *atarilance_dev;
1137b955f6caSJeff Kirsher 
1138b955f6caSJeff Kirsher static int __init atarilance_module_init(void)
1139b955f6caSJeff Kirsher {
1140*e179d78eSArnd Bergmann 	atarilance_dev = atarilance_probe();
11418c6ffba0SRusty Russell 	return PTR_ERR_OR_ZERO(atarilance_dev);
1142b955f6caSJeff Kirsher }
1143b955f6caSJeff Kirsher 
1144b955f6caSJeff Kirsher static void __exit atarilance_module_exit(void)
1145b955f6caSJeff Kirsher {
1146b955f6caSJeff Kirsher 	unregister_netdev(atarilance_dev);
1147b955f6caSJeff Kirsher 	free_irq(atarilance_dev->irq, atarilance_dev);
1148b955f6caSJeff Kirsher 	free_netdev(atarilance_dev);
1149b955f6caSJeff Kirsher }
1150b955f6caSJeff Kirsher module_init(atarilance_module_init);
1151b955f6caSJeff Kirsher module_exit(atarilance_module_exit);
1152