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