diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/sunlance.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/net/sunlance.c')
-rw-r--r-- | drivers/net/sunlance.c | 1614 |
1 files changed, 1614 insertions, 0 deletions
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c new file mode 100644 index 000000000000..62d464c7ef51 --- /dev/null +++ b/drivers/net/sunlance.c | |||
@@ -0,0 +1,1614 @@ | |||
1 | /* $Id: sunlance.c,v 1.112 2002/01/15 06:48:55 davem Exp $ | ||
2 | * lance.c: Linux/Sparc/Lance driver | ||
3 | * | ||
4 | * Written 1995, 1996 by Miguel de Icaza | ||
5 | * Sources: | ||
6 | * The Linux depca driver | ||
7 | * The Linux lance driver. | ||
8 | * The Linux skeleton driver. | ||
9 | * The NetBSD Sparc/Lance driver. | ||
10 | * Theo de Raadt (deraadt@openbsd.org) | ||
11 | * NCR92C990 Lan Controller manual | ||
12 | * | ||
13 | * 1.4: | ||
14 | * Added support to run with a ledma on the Sun4m | ||
15 | * | ||
16 | * 1.5: | ||
17 | * Added multiple card detection. | ||
18 | * | ||
19 | * 4/17/96: Burst sizes and tpe selection on sun4m by Eddie C. Dost | ||
20 | * (ecd@skynet.be) | ||
21 | * | ||
22 | * 5/15/96: auto carrier detection on sun4m by Eddie C. Dost | ||
23 | * (ecd@skynet.be) | ||
24 | * | ||
25 | * 5/17/96: lebuffer on scsi/ether cards now work David S. Miller | ||
26 | * (davem@caip.rutgers.edu) | ||
27 | * | ||
28 | * 5/29/96: override option 'tpe-link-test?', if it is 'false', as | ||
29 | * this disables auto carrier detection on sun4m. Eddie C. Dost | ||
30 | * (ecd@skynet.be) | ||
31 | * | ||
32 | * 1.7: | ||
33 | * 6/26/96: Bug fix for multiple ledmas, miguel. | ||
34 | * | ||
35 | * 1.8: | ||
36 | * Stole multicast code from depca.c, fixed lance_tx. | ||
37 | * | ||
38 | * 1.9: | ||
39 | * 8/21/96: Fixed the multicast code (Pedro Roque) | ||
40 | * | ||
41 | * 8/28/96: Send fake packet in lance_open() if auto_select is true, | ||
42 | * so we can detect the carrier loss condition in time. | ||
43 | * Eddie C. Dost (ecd@skynet.be) | ||
44 | * | ||
45 | * 9/15/96: Align rx_buf so that eth_copy_and_sum() won't cause an | ||
46 | * MNA trap during chksum_partial_copy(). (ecd@skynet.be) | ||
47 | * | ||
48 | * 11/17/96: Handle LE_C0_MERR in lance_interrupt(). (ecd@skynet.be) | ||
49 | * | ||
50 | * 12/22/96: Don't loop forever in lance_rx() on incomplete packets. | ||
51 | * This was the sun4c killer. Shit, stupid bug. | ||
52 | * (ecd@skynet.be) | ||
53 | * | ||
54 | * 1.10: | ||
55 | * 1/26/97: Modularize driver. (ecd@skynet.be) | ||
56 | * | ||
57 | * 1.11: | ||
58 | * 12/27/97: Added sun4d support. (jj@sunsite.mff.cuni.cz) | ||
59 | * | ||
60 | * 1.12: | ||
61 | * 11/3/99: Fixed SMP race in lance_start_xmit found by davem. | ||
62 | * Anton Blanchard (anton@progsoc.uts.edu.au) | ||
63 | * 2.00: 11/9/99: Massive overhaul and port to new SBUS driver interfaces. | ||
64 | * David S. Miller (davem@redhat.com) | ||
65 | * 2.01: | ||
66 | * 11/08/01: Use library crc32 functions (Matt_Domsch@dell.com) | ||
67 | * | ||
68 | */ | ||
69 | |||
70 | #undef DEBUG_DRIVER | ||
71 | |||
72 | static char version[] = | ||
73 | "sunlance.c:v2.02 24/Aug/03 Miguel de Icaza (miguel@nuclecu.unam.mx)\n"; | ||
74 | |||
75 | static char lancestr[] = "LANCE"; | ||
76 | |||
77 | #include <linux/config.h> | ||
78 | #include <linux/module.h> | ||
79 | #include <linux/kernel.h> | ||
80 | #include <linux/types.h> | ||
81 | #include <linux/fcntl.h> | ||
82 | #include <linux/interrupt.h> | ||
83 | #include <linux/ioport.h> | ||
84 | #include <linux/in.h> | ||
85 | #include <linux/slab.h> | ||
86 | #include <linux/string.h> | ||
87 | #include <linux/delay.h> | ||
88 | #include <linux/init.h> | ||
89 | #include <linux/crc32.h> | ||
90 | #include <linux/errno.h> | ||
91 | #include <linux/socket.h> /* Used for the temporal inet entries and routing */ | ||
92 | #include <linux/route.h> | ||
93 | #include <linux/netdevice.h> | ||
94 | #include <linux/etherdevice.h> | ||
95 | #include <linux/skbuff.h> | ||
96 | #include <linux/ethtool.h> | ||
97 | #include <linux/bitops.h> | ||
98 | |||
99 | #include <asm/system.h> | ||
100 | #include <asm/io.h> | ||
101 | #include <asm/dma.h> | ||
102 | #include <asm/pgtable.h> | ||
103 | #include <asm/byteorder.h> /* Used by the checksum routines */ | ||
104 | #include <asm/idprom.h> | ||
105 | #include <asm/sbus.h> | ||
106 | #include <asm/openprom.h> | ||
107 | #include <asm/oplib.h> | ||
108 | #include <asm/auxio.h> /* For tpe-link-test? setting */ | ||
109 | #include <asm/irq.h> | ||
110 | |||
111 | /* Define: 2^4 Tx buffers and 2^4 Rx buffers */ | ||
112 | #ifndef LANCE_LOG_TX_BUFFERS | ||
113 | #define LANCE_LOG_TX_BUFFERS 4 | ||
114 | #define LANCE_LOG_RX_BUFFERS 4 | ||
115 | #endif | ||
116 | |||
117 | #define LE_CSR0 0 | ||
118 | #define LE_CSR1 1 | ||
119 | #define LE_CSR2 2 | ||
120 | #define LE_CSR3 3 | ||
121 | |||
122 | #define LE_MO_PROM 0x8000 /* Enable promiscuous mode */ | ||
123 | |||
124 | #define LE_C0_ERR 0x8000 /* Error: set if BAB, SQE, MISS or ME is set */ | ||
125 | #define LE_C0_BABL 0x4000 /* BAB: Babble: tx timeout. */ | ||
126 | #define LE_C0_CERR 0x2000 /* SQE: Signal quality error */ | ||
127 | #define LE_C0_MISS 0x1000 /* MISS: Missed a packet */ | ||
128 | #define LE_C0_MERR 0x0800 /* ME: Memory error */ | ||
129 | #define LE_C0_RINT 0x0400 /* Received interrupt */ | ||
130 | #define LE_C0_TINT 0x0200 /* Transmitter Interrupt */ | ||
131 | #define LE_C0_IDON 0x0100 /* IFIN: Init finished. */ | ||
132 | #define LE_C0_INTR 0x0080 /* Interrupt or error */ | ||
133 | #define LE_C0_INEA 0x0040 /* Interrupt enable */ | ||
134 | #define LE_C0_RXON 0x0020 /* Receiver on */ | ||
135 | #define LE_C0_TXON 0x0010 /* Transmitter on */ | ||
136 | #define LE_C0_TDMD 0x0008 /* Transmitter demand */ | ||
137 | #define LE_C0_STOP 0x0004 /* Stop the card */ | ||
138 | #define LE_C0_STRT 0x0002 /* Start the card */ | ||
139 | #define LE_C0_INIT 0x0001 /* Init the card */ | ||
140 | |||
141 | #define LE_C3_BSWP 0x4 /* SWAP */ | ||
142 | #define LE_C3_ACON 0x2 /* ALE Control */ | ||
143 | #define LE_C3_BCON 0x1 /* Byte control */ | ||
144 | |||
145 | /* Receive message descriptor 1 */ | ||
146 | #define LE_R1_OWN 0x80 /* Who owns the entry */ | ||
147 | #define LE_R1_ERR 0x40 /* Error: if FRA, OFL, CRC or BUF is set */ | ||
148 | #define LE_R1_FRA 0x20 /* FRA: Frame error */ | ||
149 | #define LE_R1_OFL 0x10 /* OFL: Frame overflow */ | ||
150 | #define LE_R1_CRC 0x08 /* CRC error */ | ||
151 | #define LE_R1_BUF 0x04 /* BUF: Buffer error */ | ||
152 | #define LE_R1_SOP 0x02 /* Start of packet */ | ||
153 | #define LE_R1_EOP 0x01 /* End of packet */ | ||
154 | #define LE_R1_POK 0x03 /* Packet is complete: SOP + EOP */ | ||
155 | |||
156 | #define LE_T1_OWN 0x80 /* Lance owns the packet */ | ||
157 | #define LE_T1_ERR 0x40 /* Error summary */ | ||
158 | #define LE_T1_EMORE 0x10 /* Error: more than one retry needed */ | ||
159 | #define LE_T1_EONE 0x08 /* Error: one retry needed */ | ||
160 | #define LE_T1_EDEF 0x04 /* Error: deferred */ | ||
161 | #define LE_T1_SOP 0x02 /* Start of packet */ | ||
162 | #define LE_T1_EOP 0x01 /* End of packet */ | ||
163 | #define LE_T1_POK 0x03 /* Packet is complete: SOP + EOP */ | ||
164 | |||
165 | #define LE_T3_BUF 0x8000 /* Buffer error */ | ||
166 | #define LE_T3_UFL 0x4000 /* Error underflow */ | ||
167 | #define LE_T3_LCOL 0x1000 /* Error late collision */ | ||
168 | #define LE_T3_CLOS 0x0800 /* Error carrier loss */ | ||
169 | #define LE_T3_RTY 0x0400 /* Error retry */ | ||
170 | #define LE_T3_TDR 0x03ff /* Time Domain Reflectometry counter */ | ||
171 | |||
172 | #define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS)) | ||
173 | #define TX_RING_MOD_MASK (TX_RING_SIZE - 1) | ||
174 | #define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29) | ||
175 | #define TX_NEXT(__x) (((__x)+1) & TX_RING_MOD_MASK) | ||
176 | |||
177 | #define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS)) | ||
178 | #define RX_RING_MOD_MASK (RX_RING_SIZE - 1) | ||
179 | #define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29) | ||
180 | #define RX_NEXT(__x) (((__x)+1) & RX_RING_MOD_MASK) | ||
181 | |||
182 | #define PKT_BUF_SZ 1544 | ||
183 | #define RX_BUFF_SIZE PKT_BUF_SZ | ||
184 | #define TX_BUFF_SIZE PKT_BUF_SZ | ||
185 | |||
186 | struct lance_rx_desc { | ||
187 | u16 rmd0; /* low address of packet */ | ||
188 | u8 rmd1_bits; /* descriptor bits */ | ||
189 | u8 rmd1_hadr; /* high address of packet */ | ||
190 | s16 length; /* This length is 2s complement (negative)! | ||
191 | * Buffer length | ||
192 | */ | ||
193 | u16 mblength; /* This is the actual number of bytes received */ | ||
194 | }; | ||
195 | |||
196 | struct lance_tx_desc { | ||
197 | u16 tmd0; /* low address of packet */ | ||
198 | u8 tmd1_bits; /* descriptor bits */ | ||
199 | u8 tmd1_hadr; /* high address of packet */ | ||
200 | s16 length; /* Length is 2s complement (negative)! */ | ||
201 | u16 misc; | ||
202 | }; | ||
203 | |||
204 | /* The LANCE initialization block, described in databook. */ | ||
205 | /* On the Sparc, this block should be on a DMA region */ | ||
206 | struct lance_init_block { | ||
207 | u16 mode; /* Pre-set mode (reg. 15) */ | ||
208 | u8 phys_addr[6]; /* Physical ethernet address */ | ||
209 | u32 filter[2]; /* Multicast filter. */ | ||
210 | |||
211 | /* Receive and transmit ring base, along with extra bits. */ | ||
212 | u16 rx_ptr; /* receive descriptor addr */ | ||
213 | u16 rx_len; /* receive len and high addr */ | ||
214 | u16 tx_ptr; /* transmit descriptor addr */ | ||
215 | u16 tx_len; /* transmit len and high addr */ | ||
216 | |||
217 | /* The Tx and Rx ring entries must aligned on 8-byte boundaries. */ | ||
218 | struct lance_rx_desc brx_ring[RX_RING_SIZE]; | ||
219 | struct lance_tx_desc btx_ring[TX_RING_SIZE]; | ||
220 | |||
221 | u8 tx_buf [TX_RING_SIZE][TX_BUFF_SIZE]; | ||
222 | u8 pad[2]; /* align rx_buf for copy_and_sum(). */ | ||
223 | u8 rx_buf [RX_RING_SIZE][RX_BUFF_SIZE]; | ||
224 | }; | ||
225 | |||
226 | #define libdesc_offset(rt, elem) \ | ||
227 | ((__u32)(((unsigned long)(&(((struct lance_init_block *)0)->rt[elem]))))) | ||
228 | |||
229 | #define libbuff_offset(rt, elem) \ | ||
230 | ((__u32)(((unsigned long)(&(((struct lance_init_block *)0)->rt[elem][0]))))) | ||
231 | |||
232 | struct lance_private { | ||
233 | void __iomem *lregs; /* Lance RAP/RDP regs. */ | ||
234 | void __iomem *dregs; /* DMA controller regs. */ | ||
235 | struct lance_init_block __iomem *init_block_iomem; | ||
236 | struct lance_init_block *init_block_mem; | ||
237 | |||
238 | spinlock_t lock; | ||
239 | |||
240 | int rx_new, tx_new; | ||
241 | int rx_old, tx_old; | ||
242 | |||
243 | struct net_device_stats stats; | ||
244 | struct sbus_dma *ledma; /* If set this points to ledma */ | ||
245 | char tpe; /* cable-selection is TPE */ | ||
246 | char auto_select; /* cable-selection by carrier */ | ||
247 | char burst_sizes; /* ledma SBus burst sizes */ | ||
248 | char pio_buffer; /* init block in PIO space? */ | ||
249 | |||
250 | unsigned short busmaster_regval; | ||
251 | |||
252 | void (*init_ring)(struct net_device *); | ||
253 | void (*rx)(struct net_device *); | ||
254 | void (*tx)(struct net_device *); | ||
255 | |||
256 | char *name; | ||
257 | dma_addr_t init_block_dvma; | ||
258 | struct net_device *dev; /* Backpointer */ | ||
259 | struct lance_private *next_module; | ||
260 | struct sbus_dev *sdev; | ||
261 | struct timer_list multicast_timer; | ||
262 | }; | ||
263 | |||
264 | #define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\ | ||
265 | lp->tx_old+TX_RING_MOD_MASK-lp->tx_new:\ | ||
266 | lp->tx_old - lp->tx_new-1) | ||
267 | |||
268 | /* Lance registers. */ | ||
269 | #define RDP 0x00UL /* register data port */ | ||
270 | #define RAP 0x02UL /* register address port */ | ||
271 | #define LANCE_REG_SIZE 0x04UL | ||
272 | |||
273 | #define STOP_LANCE(__lp) \ | ||
274 | do { void __iomem *__base = (__lp)->lregs; \ | ||
275 | sbus_writew(LE_CSR0, __base + RAP); \ | ||
276 | sbus_writew(LE_C0_STOP, __base + RDP); \ | ||
277 | } while (0) | ||
278 | |||
279 | int sparc_lance_debug = 2; | ||
280 | |||
281 | /* The Lance uses 24 bit addresses */ | ||
282 | /* On the Sun4c the DVMA will provide the remaining bytes for us */ | ||
283 | /* On the Sun4m we have to instruct the ledma to provide them */ | ||
284 | /* Even worse, on scsi/ether SBUS cards, the init block and the | ||
285 | * transmit/receive buffers are addresses as offsets from absolute | ||
286 | * zero on the lebuffer PIO area. -DaveM | ||
287 | */ | ||
288 | |||
289 | #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) | ||
290 | |||
291 | static struct lance_private *root_lance_dev; | ||
292 | |||
293 | /* Load the CSR registers */ | ||
294 | static void load_csrs(struct lance_private *lp) | ||
295 | { | ||
296 | u32 leptr; | ||
297 | |||
298 | if (lp->pio_buffer) | ||
299 | leptr = 0; | ||
300 | else | ||
301 | leptr = LANCE_ADDR(lp->init_block_dvma); | ||
302 | |||
303 | sbus_writew(LE_CSR1, lp->lregs + RAP); | ||
304 | sbus_writew(leptr & 0xffff, lp->lregs + RDP); | ||
305 | sbus_writew(LE_CSR2, lp->lregs + RAP); | ||
306 | sbus_writew(leptr >> 16, lp->lregs + RDP); | ||
307 | sbus_writew(LE_CSR3, lp->lregs + RAP); | ||
308 | sbus_writew(lp->busmaster_regval, lp->lregs + RDP); | ||
309 | |||
310 | /* Point back to csr0 */ | ||
311 | sbus_writew(LE_CSR0, lp->lregs + RAP); | ||
312 | } | ||
313 | |||
314 | /* Setup the Lance Rx and Tx rings */ | ||
315 | static void lance_init_ring_dvma(struct net_device *dev) | ||
316 | { | ||
317 | struct lance_private *lp = netdev_priv(dev); | ||
318 | struct lance_init_block *ib = lp->init_block_mem; | ||
319 | dma_addr_t aib = lp->init_block_dvma; | ||
320 | __u32 leptr; | ||
321 | int i; | ||
322 | |||
323 | /* Lock out other processes while setting up hardware */ | ||
324 | netif_stop_queue(dev); | ||
325 | lp->rx_new = lp->tx_new = 0; | ||
326 | lp->rx_old = lp->tx_old = 0; | ||
327 | |||
328 | /* Copy the ethernet address to the lance init block | ||
329 | * Note that on the sparc you need to swap the ethernet address. | ||
330 | */ | ||
331 | ib->phys_addr [0] = dev->dev_addr [1]; | ||
332 | ib->phys_addr [1] = dev->dev_addr [0]; | ||
333 | ib->phys_addr [2] = dev->dev_addr [3]; | ||
334 | ib->phys_addr [3] = dev->dev_addr [2]; | ||
335 | ib->phys_addr [4] = dev->dev_addr [5]; | ||
336 | ib->phys_addr [5] = dev->dev_addr [4]; | ||
337 | |||
338 | /* Setup the Tx ring entries */ | ||
339 | for (i = 0; i <= TX_RING_SIZE; i++) { | ||
340 | leptr = LANCE_ADDR(aib + libbuff_offset(tx_buf, i)); | ||
341 | ib->btx_ring [i].tmd0 = leptr; | ||
342 | ib->btx_ring [i].tmd1_hadr = leptr >> 16; | ||
343 | ib->btx_ring [i].tmd1_bits = 0; | ||
344 | ib->btx_ring [i].length = 0xf000; /* The ones required by tmd2 */ | ||
345 | ib->btx_ring [i].misc = 0; | ||
346 | } | ||
347 | |||
348 | /* Setup the Rx ring entries */ | ||
349 | for (i = 0; i < RX_RING_SIZE; i++) { | ||
350 | leptr = LANCE_ADDR(aib + libbuff_offset(rx_buf, i)); | ||
351 | |||
352 | ib->brx_ring [i].rmd0 = leptr; | ||
353 | ib->brx_ring [i].rmd1_hadr = leptr >> 16; | ||
354 | ib->brx_ring [i].rmd1_bits = LE_R1_OWN; | ||
355 | ib->brx_ring [i].length = -RX_BUFF_SIZE | 0xf000; | ||
356 | ib->brx_ring [i].mblength = 0; | ||
357 | } | ||
358 | |||
359 | /* Setup the initialization block */ | ||
360 | |||
361 | /* Setup rx descriptor pointer */ | ||
362 | leptr = LANCE_ADDR(aib + libdesc_offset(brx_ring, 0)); | ||
363 | ib->rx_len = (LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16); | ||
364 | ib->rx_ptr = leptr; | ||
365 | |||
366 | /* Setup tx descriptor pointer */ | ||
367 | leptr = LANCE_ADDR(aib + libdesc_offset(btx_ring, 0)); | ||
368 | ib->tx_len = (LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16); | ||
369 | ib->tx_ptr = leptr; | ||
370 | } | ||
371 | |||
372 | static void lance_init_ring_pio(struct net_device *dev) | ||
373 | { | ||
374 | struct lance_private *lp = netdev_priv(dev); | ||
375 | struct lance_init_block __iomem *ib = lp->init_block_iomem; | ||
376 | u32 leptr; | ||
377 | int i; | ||
378 | |||
379 | /* Lock out other processes while setting up hardware */ | ||
380 | netif_stop_queue(dev); | ||
381 | lp->rx_new = lp->tx_new = 0; | ||
382 | lp->rx_old = lp->tx_old = 0; | ||
383 | |||
384 | /* Copy the ethernet address to the lance init block | ||
385 | * Note that on the sparc you need to swap the ethernet address. | ||
386 | */ | ||
387 | sbus_writeb(dev->dev_addr[1], &ib->phys_addr[0]); | ||
388 | sbus_writeb(dev->dev_addr[0], &ib->phys_addr[1]); | ||
389 | sbus_writeb(dev->dev_addr[3], &ib->phys_addr[2]); | ||
390 | sbus_writeb(dev->dev_addr[2], &ib->phys_addr[3]); | ||
391 | sbus_writeb(dev->dev_addr[5], &ib->phys_addr[4]); | ||
392 | sbus_writeb(dev->dev_addr[4], &ib->phys_addr[5]); | ||
393 | |||
394 | /* Setup the Tx ring entries */ | ||
395 | for (i = 0; i <= TX_RING_SIZE; i++) { | ||
396 | leptr = libbuff_offset(tx_buf, i); | ||
397 | sbus_writew(leptr, &ib->btx_ring [i].tmd0); | ||
398 | sbus_writeb(leptr >> 16,&ib->btx_ring [i].tmd1_hadr); | ||
399 | sbus_writeb(0, &ib->btx_ring [i].tmd1_bits); | ||
400 | |||
401 | /* The ones required by tmd2 */ | ||
402 | sbus_writew(0xf000, &ib->btx_ring [i].length); | ||
403 | sbus_writew(0, &ib->btx_ring [i].misc); | ||
404 | } | ||
405 | |||
406 | /* Setup the Rx ring entries */ | ||
407 | for (i = 0; i < RX_RING_SIZE; i++) { | ||
408 | leptr = libbuff_offset(rx_buf, i); | ||
409 | |||
410 | sbus_writew(leptr, &ib->brx_ring [i].rmd0); | ||
411 | sbus_writeb(leptr >> 16,&ib->brx_ring [i].rmd1_hadr); | ||
412 | sbus_writeb(LE_R1_OWN, &ib->brx_ring [i].rmd1_bits); | ||
413 | sbus_writew(-RX_BUFF_SIZE|0xf000, | ||
414 | &ib->brx_ring [i].length); | ||
415 | sbus_writew(0, &ib->brx_ring [i].mblength); | ||
416 | } | ||
417 | |||
418 | /* Setup the initialization block */ | ||
419 | |||
420 | /* Setup rx descriptor pointer */ | ||
421 | leptr = libdesc_offset(brx_ring, 0); | ||
422 | sbus_writew((LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16), | ||
423 | &ib->rx_len); | ||
424 | sbus_writew(leptr, &ib->rx_ptr); | ||
425 | |||
426 | /* Setup tx descriptor pointer */ | ||
427 | leptr = libdesc_offset(btx_ring, 0); | ||
428 | sbus_writew((LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16), | ||
429 | &ib->tx_len); | ||
430 | sbus_writew(leptr, &ib->tx_ptr); | ||
431 | } | ||
432 | |||
433 | static void init_restart_ledma(struct lance_private *lp) | ||
434 | { | ||
435 | u32 csr = sbus_readl(lp->dregs + DMA_CSR); | ||
436 | |||
437 | if (!(csr & DMA_HNDL_ERROR)) { | ||
438 | /* E-Cache draining */ | ||
439 | while (sbus_readl(lp->dregs + DMA_CSR) & DMA_FIFO_ISDRAIN) | ||
440 | barrier(); | ||
441 | } | ||
442 | |||
443 | csr = sbus_readl(lp->dregs + DMA_CSR); | ||
444 | csr &= ~DMA_E_BURSTS; | ||
445 | if (lp->burst_sizes & DMA_BURST32) | ||
446 | csr |= DMA_E_BURST32; | ||
447 | else | ||
448 | csr |= DMA_E_BURST16; | ||
449 | |||
450 | csr |= (DMA_DSBL_RD_DRN | DMA_DSBL_WR_INV | DMA_FIFO_INV); | ||
451 | |||
452 | if (lp->tpe) | ||
453 | csr |= DMA_EN_ENETAUI; | ||
454 | else | ||
455 | csr &= ~DMA_EN_ENETAUI; | ||
456 | udelay(20); | ||
457 | sbus_writel(csr, lp->dregs + DMA_CSR); | ||
458 | udelay(200); | ||
459 | } | ||
460 | |||
461 | static int init_restart_lance(struct lance_private *lp) | ||
462 | { | ||
463 | u16 regval = 0; | ||
464 | int i; | ||
465 | |||
466 | if (lp->dregs) | ||
467 | init_restart_ledma(lp); | ||
468 | |||
469 | sbus_writew(LE_CSR0, lp->lregs + RAP); | ||
470 | sbus_writew(LE_C0_INIT, lp->lregs + RDP); | ||
471 | |||
472 | /* Wait for the lance to complete initialization */ | ||
473 | for (i = 0; i < 100; i++) { | ||
474 | regval = sbus_readw(lp->lregs + RDP); | ||
475 | |||
476 | if (regval & (LE_C0_ERR | LE_C0_IDON)) | ||
477 | break; | ||
478 | barrier(); | ||
479 | } | ||
480 | if (i == 100 || (regval & LE_C0_ERR)) { | ||
481 | printk(KERN_ERR "LANCE unopened after %d ticks, csr0=%4.4x.\n", | ||
482 | i, regval); | ||
483 | if (lp->dregs) | ||
484 | printk("dcsr=%8.8x\n", sbus_readl(lp->dregs + DMA_CSR)); | ||
485 | return -1; | ||
486 | } | ||
487 | |||
488 | /* Clear IDON by writing a "1", enable interrupts and start lance */ | ||
489 | sbus_writew(LE_C0_IDON, lp->lregs + RDP); | ||
490 | sbus_writew(LE_C0_INEA | LE_C0_STRT, lp->lregs + RDP); | ||
491 | |||
492 | if (lp->dregs) { | ||
493 | u32 csr = sbus_readl(lp->dregs + DMA_CSR); | ||
494 | |||
495 | csr |= DMA_INT_ENAB; | ||
496 | sbus_writel(csr, lp->dregs + DMA_CSR); | ||
497 | } | ||
498 | |||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static void lance_rx_dvma(struct net_device *dev) | ||
503 | { | ||
504 | struct lance_private *lp = netdev_priv(dev); | ||
505 | struct lance_init_block *ib = lp->init_block_mem; | ||
506 | struct lance_rx_desc *rd; | ||
507 | u8 bits; | ||
508 | int len, entry = lp->rx_new; | ||
509 | struct sk_buff *skb; | ||
510 | |||
511 | for (rd = &ib->brx_ring [entry]; | ||
512 | !((bits = rd->rmd1_bits) & LE_R1_OWN); | ||
513 | rd = &ib->brx_ring [entry]) { | ||
514 | |||
515 | /* We got an incomplete frame? */ | ||
516 | if ((bits & LE_R1_POK) != LE_R1_POK) { | ||
517 | lp->stats.rx_over_errors++; | ||
518 | lp->stats.rx_errors++; | ||
519 | } else if (bits & LE_R1_ERR) { | ||
520 | /* Count only the end frame as a rx error, | ||
521 | * not the beginning | ||
522 | */ | ||
523 | if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; | ||
524 | if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; | ||
525 | if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; | ||
526 | if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; | ||
527 | if (bits & LE_R1_EOP) lp->stats.rx_errors++; | ||
528 | } else { | ||
529 | len = (rd->mblength & 0xfff) - 4; | ||
530 | skb = dev_alloc_skb(len + 2); | ||
531 | |||
532 | if (skb == NULL) { | ||
533 | printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", | ||
534 | dev->name); | ||
535 | lp->stats.rx_dropped++; | ||
536 | rd->mblength = 0; | ||
537 | rd->rmd1_bits = LE_R1_OWN; | ||
538 | lp->rx_new = RX_NEXT(entry); | ||
539 | return; | ||
540 | } | ||
541 | |||
542 | lp->stats.rx_bytes += len; | ||
543 | |||
544 | skb->dev = dev; | ||
545 | skb_reserve(skb, 2); /* 16 byte align */ | ||
546 | skb_put(skb, len); /* make room */ | ||
547 | eth_copy_and_sum(skb, | ||
548 | (unsigned char *)&(ib->rx_buf [entry][0]), | ||
549 | len, 0); | ||
550 | skb->protocol = eth_type_trans(skb, dev); | ||
551 | netif_rx(skb); | ||
552 | dev->last_rx = jiffies; | ||
553 | lp->stats.rx_packets++; | ||
554 | } | ||
555 | |||
556 | /* Return the packet to the pool */ | ||
557 | rd->mblength = 0; | ||
558 | rd->rmd1_bits = LE_R1_OWN; | ||
559 | entry = RX_NEXT(entry); | ||
560 | } | ||
561 | |||
562 | lp->rx_new = entry; | ||
563 | } | ||
564 | |||
565 | static void lance_tx_dvma(struct net_device *dev) | ||
566 | { | ||
567 | struct lance_private *lp = netdev_priv(dev); | ||
568 | struct lance_init_block *ib = lp->init_block_mem; | ||
569 | int i, j; | ||
570 | |||
571 | spin_lock(&lp->lock); | ||
572 | |||
573 | j = lp->tx_old; | ||
574 | for (i = j; i != lp->tx_new; i = j) { | ||
575 | struct lance_tx_desc *td = &ib->btx_ring [i]; | ||
576 | u8 bits = td->tmd1_bits; | ||
577 | |||
578 | /* If we hit a packet not owned by us, stop */ | ||
579 | if (bits & LE_T1_OWN) | ||
580 | break; | ||
581 | |||
582 | if (bits & LE_T1_ERR) { | ||
583 | u16 status = td->misc; | ||
584 | |||
585 | lp->stats.tx_errors++; | ||
586 | if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; | ||
587 | if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; | ||
588 | |||
589 | if (status & LE_T3_CLOS) { | ||
590 | lp->stats.tx_carrier_errors++; | ||
591 | if (lp->auto_select) { | ||
592 | lp->tpe = 1 - lp->tpe; | ||
593 | printk(KERN_NOTICE "%s: Carrier Lost, trying %s\n", | ||
594 | dev->name, lp->tpe?"TPE":"AUI"); | ||
595 | STOP_LANCE(lp); | ||
596 | lp->init_ring(dev); | ||
597 | load_csrs(lp); | ||
598 | init_restart_lance(lp); | ||
599 | goto out; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | /* Buffer errors and underflows turn off the | ||
604 | * transmitter, restart the adapter. | ||
605 | */ | ||
606 | if (status & (LE_T3_BUF|LE_T3_UFL)) { | ||
607 | lp->stats.tx_fifo_errors++; | ||
608 | |||
609 | printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, restarting\n", | ||
610 | dev->name); | ||
611 | STOP_LANCE(lp); | ||
612 | lp->init_ring(dev); | ||
613 | load_csrs(lp); | ||
614 | init_restart_lance(lp); | ||
615 | goto out; | ||
616 | } | ||
617 | } else if ((bits & LE_T1_POK) == LE_T1_POK) { | ||
618 | /* | ||
619 | * So we don't count the packet more than once. | ||
620 | */ | ||
621 | td->tmd1_bits = bits & ~(LE_T1_POK); | ||
622 | |||
623 | /* One collision before packet was sent. */ | ||
624 | if (bits & LE_T1_EONE) | ||
625 | lp->stats.collisions++; | ||
626 | |||
627 | /* More than one collision, be optimistic. */ | ||
628 | if (bits & LE_T1_EMORE) | ||
629 | lp->stats.collisions += 2; | ||
630 | |||
631 | lp->stats.tx_packets++; | ||
632 | } | ||
633 | |||
634 | j = TX_NEXT(j); | ||
635 | } | ||
636 | lp->tx_old = j; | ||
637 | out: | ||
638 | if (netif_queue_stopped(dev) && | ||
639 | TX_BUFFS_AVAIL > 0) | ||
640 | netif_wake_queue(dev); | ||
641 | |||
642 | spin_unlock(&lp->lock); | ||
643 | } | ||
644 | |||
645 | static void lance_piocopy_to_skb(struct sk_buff *skb, void __iomem *piobuf, int len) | ||
646 | { | ||
647 | u16 *p16 = (u16 *) skb->data; | ||
648 | u32 *p32; | ||
649 | u8 *p8; | ||
650 | void __iomem *pbuf = piobuf; | ||
651 | |||
652 | /* We know here that both src and dest are on a 16bit boundary. */ | ||
653 | *p16++ = sbus_readw(pbuf); | ||
654 | p32 = (u32 *) p16; | ||
655 | pbuf += 2; | ||
656 | len -= 2; | ||
657 | |||
658 | while (len >= 4) { | ||
659 | *p32++ = sbus_readl(pbuf); | ||
660 | pbuf += 4; | ||
661 | len -= 4; | ||
662 | } | ||
663 | p8 = (u8 *) p32; | ||
664 | if (len >= 2) { | ||
665 | p16 = (u16 *) p32; | ||
666 | *p16++ = sbus_readw(pbuf); | ||
667 | pbuf += 2; | ||
668 | len -= 2; | ||
669 | p8 = (u8 *) p16; | ||
670 | } | ||
671 | if (len >= 1) | ||
672 | *p8 = sbus_readb(pbuf); | ||
673 | } | ||
674 | |||
675 | static void lance_rx_pio(struct net_device *dev) | ||
676 | { | ||
677 | struct lance_private *lp = netdev_priv(dev); | ||
678 | struct lance_init_block __iomem *ib = lp->init_block_iomem; | ||
679 | struct lance_rx_desc __iomem *rd; | ||
680 | unsigned char bits; | ||
681 | int len, entry; | ||
682 | struct sk_buff *skb; | ||
683 | |||
684 | entry = lp->rx_new; | ||
685 | for (rd = &ib->brx_ring [entry]; | ||
686 | !((bits = sbus_readb(&rd->rmd1_bits)) & LE_R1_OWN); | ||
687 | rd = &ib->brx_ring [entry]) { | ||
688 | |||
689 | /* We got an incomplete frame? */ | ||
690 | if ((bits & LE_R1_POK) != LE_R1_POK) { | ||
691 | lp->stats.rx_over_errors++; | ||
692 | lp->stats.rx_errors++; | ||
693 | } else if (bits & LE_R1_ERR) { | ||
694 | /* Count only the end frame as a rx error, | ||
695 | * not the beginning | ||
696 | */ | ||
697 | if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; | ||
698 | if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; | ||
699 | if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; | ||
700 | if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; | ||
701 | if (bits & LE_R1_EOP) lp->stats.rx_errors++; | ||
702 | } else { | ||
703 | len = (sbus_readw(&rd->mblength) & 0xfff) - 4; | ||
704 | skb = dev_alloc_skb(len + 2); | ||
705 | |||
706 | if (skb == NULL) { | ||
707 | printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", | ||
708 | dev->name); | ||
709 | lp->stats.rx_dropped++; | ||
710 | sbus_writew(0, &rd->mblength); | ||
711 | sbus_writeb(LE_R1_OWN, &rd->rmd1_bits); | ||
712 | lp->rx_new = RX_NEXT(entry); | ||
713 | return; | ||
714 | } | ||
715 | |||
716 | lp->stats.rx_bytes += len; | ||
717 | |||
718 | skb->dev = dev; | ||
719 | skb_reserve (skb, 2); /* 16 byte align */ | ||
720 | skb_put(skb, len); /* make room */ | ||
721 | lance_piocopy_to_skb(skb, &(ib->rx_buf[entry][0]), len); | ||
722 | skb->protocol = eth_type_trans(skb, dev); | ||
723 | netif_rx(skb); | ||
724 | dev->last_rx = jiffies; | ||
725 | lp->stats.rx_packets++; | ||
726 | } | ||
727 | |||
728 | /* Return the packet to the pool */ | ||
729 | sbus_writew(0, &rd->mblength); | ||
730 | sbus_writeb(LE_R1_OWN, &rd->rmd1_bits); | ||
731 | entry = RX_NEXT(entry); | ||
732 | } | ||
733 | |||
734 | lp->rx_new = entry; | ||
735 | } | ||
736 | |||
737 | static void lance_tx_pio(struct net_device *dev) | ||
738 | { | ||
739 | struct lance_private *lp = netdev_priv(dev); | ||
740 | struct lance_init_block __iomem *ib = lp->init_block_iomem; | ||
741 | int i, j; | ||
742 | |||
743 | spin_lock(&lp->lock); | ||
744 | |||
745 | j = lp->tx_old; | ||
746 | for (i = j; i != lp->tx_new; i = j) { | ||
747 | struct lance_tx_desc __iomem *td = &ib->btx_ring [i]; | ||
748 | u8 bits = sbus_readb(&td->tmd1_bits); | ||
749 | |||
750 | /* If we hit a packet not owned by us, stop */ | ||
751 | if (bits & LE_T1_OWN) | ||
752 | break; | ||
753 | |||
754 | if (bits & LE_T1_ERR) { | ||
755 | u16 status = sbus_readw(&td->misc); | ||
756 | |||
757 | lp->stats.tx_errors++; | ||
758 | if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; | ||
759 | if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; | ||
760 | |||
761 | if (status & LE_T3_CLOS) { | ||
762 | lp->stats.tx_carrier_errors++; | ||
763 | if (lp->auto_select) { | ||
764 | lp->tpe = 1 - lp->tpe; | ||
765 | printk(KERN_NOTICE "%s: Carrier Lost, trying %s\n", | ||
766 | dev->name, lp->tpe?"TPE":"AUI"); | ||
767 | STOP_LANCE(lp); | ||
768 | lp->init_ring(dev); | ||
769 | load_csrs(lp); | ||
770 | init_restart_lance(lp); | ||
771 | goto out; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | /* Buffer errors and underflows turn off the | ||
776 | * transmitter, restart the adapter. | ||
777 | */ | ||
778 | if (status & (LE_T3_BUF|LE_T3_UFL)) { | ||
779 | lp->stats.tx_fifo_errors++; | ||
780 | |||
781 | printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, restarting\n", | ||
782 | dev->name); | ||
783 | STOP_LANCE(lp); | ||
784 | lp->init_ring(dev); | ||
785 | load_csrs(lp); | ||
786 | init_restart_lance(lp); | ||
787 | goto out; | ||
788 | } | ||
789 | } else if ((bits & LE_T1_POK) == LE_T1_POK) { | ||
790 | /* | ||
791 | * So we don't count the packet more than once. | ||
792 | */ | ||
793 | sbus_writeb(bits & ~(LE_T1_POK), &td->tmd1_bits); | ||
794 | |||
795 | /* One collision before packet was sent. */ | ||
796 | if (bits & LE_T1_EONE) | ||
797 | lp->stats.collisions++; | ||
798 | |||
799 | /* More than one collision, be optimistic. */ | ||
800 | if (bits & LE_T1_EMORE) | ||
801 | lp->stats.collisions += 2; | ||
802 | |||
803 | lp->stats.tx_packets++; | ||
804 | } | ||
805 | |||
806 | j = TX_NEXT(j); | ||
807 | } | ||
808 | lp->tx_old = j; | ||
809 | |||
810 | if (netif_queue_stopped(dev) && | ||
811 | TX_BUFFS_AVAIL > 0) | ||
812 | netif_wake_queue(dev); | ||
813 | out: | ||
814 | spin_unlock(&lp->lock); | ||
815 | } | ||
816 | |||
817 | static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
818 | { | ||
819 | struct net_device *dev = (struct net_device *)dev_id; | ||
820 | struct lance_private *lp = netdev_priv(dev); | ||
821 | int csr0; | ||
822 | |||
823 | sbus_writew(LE_CSR0, lp->lregs + RAP); | ||
824 | csr0 = sbus_readw(lp->lregs + RDP); | ||
825 | |||
826 | /* Acknowledge all the interrupt sources ASAP */ | ||
827 | sbus_writew(csr0 & (LE_C0_INTR | LE_C0_TINT | LE_C0_RINT), | ||
828 | lp->lregs + RDP); | ||
829 | |||
830 | if ((csr0 & LE_C0_ERR) != 0) { | ||
831 | /* Clear the error condition */ | ||
832 | sbus_writew((LE_C0_BABL | LE_C0_ERR | LE_C0_MISS | | ||
833 | LE_C0_CERR | LE_C0_MERR), | ||
834 | lp->lregs + RDP); | ||
835 | } | ||
836 | |||
837 | if (csr0 & LE_C0_RINT) | ||
838 | lp->rx(dev); | ||
839 | |||
840 | if (csr0 & LE_C0_TINT) | ||
841 | lp->tx(dev); | ||
842 | |||
843 | if (csr0 & LE_C0_BABL) | ||
844 | lp->stats.tx_errors++; | ||
845 | |||
846 | if (csr0 & LE_C0_MISS) | ||
847 | lp->stats.rx_errors++; | ||
848 | |||
849 | if (csr0 & LE_C0_MERR) { | ||
850 | if (lp->dregs) { | ||
851 | u32 addr = sbus_readl(lp->dregs + DMA_ADDR); | ||
852 | |||
853 | printk(KERN_ERR "%s: Memory error, status %04x, addr %06x\n", | ||
854 | dev->name, csr0, addr & 0xffffff); | ||
855 | } else { | ||
856 | printk(KERN_ERR "%s: Memory error, status %04x\n", | ||
857 | dev->name, csr0); | ||
858 | } | ||
859 | |||
860 | sbus_writew(LE_C0_STOP, lp->lregs + RDP); | ||
861 | |||
862 | if (lp->dregs) { | ||
863 | u32 dma_csr = sbus_readl(lp->dregs + DMA_CSR); | ||
864 | |||
865 | dma_csr |= DMA_FIFO_INV; | ||
866 | sbus_writel(dma_csr, lp->dregs + DMA_CSR); | ||
867 | } | ||
868 | |||
869 | lp->init_ring(dev); | ||
870 | load_csrs(lp); | ||
871 | init_restart_lance(lp); | ||
872 | netif_wake_queue(dev); | ||
873 | } | ||
874 | |||
875 | sbus_writew(LE_C0_INEA, lp->lregs + RDP); | ||
876 | |||
877 | return IRQ_HANDLED; | ||
878 | } | ||
879 | |||
880 | /* Build a fake network packet and send it to ourselves. */ | ||
881 | static void build_fake_packet(struct lance_private *lp) | ||
882 | { | ||
883 | struct net_device *dev = lp->dev; | ||
884 | int i, entry; | ||
885 | |||
886 | entry = lp->tx_new & TX_RING_MOD_MASK; | ||
887 | if (lp->pio_buffer) { | ||
888 | struct lance_init_block __iomem *ib = lp->init_block_iomem; | ||
889 | u16 __iomem *packet = (u16 __iomem *) &(ib->tx_buf[entry][0]); | ||
890 | struct ethhdr __iomem *eth = (struct ethhdr __iomem *) packet; | ||
891 | for (i = 0; i < (ETH_ZLEN / sizeof(u16)); i++) | ||
892 | sbus_writew(0, &packet[i]); | ||
893 | for (i = 0; i < 6; i++) { | ||
894 | sbus_writeb(dev->dev_addr[i], ð->h_dest[i]); | ||
895 | sbus_writeb(dev->dev_addr[i], ð->h_source[i]); | ||
896 | } | ||
897 | sbus_writew((-ETH_ZLEN) | 0xf000, &ib->btx_ring[entry].length); | ||
898 | sbus_writew(0, &ib->btx_ring[entry].misc); | ||
899 | sbus_writeb(LE_T1_POK|LE_T1_OWN, &ib->btx_ring[entry].tmd1_bits); | ||
900 | } else { | ||
901 | struct lance_init_block *ib = lp->init_block_mem; | ||
902 | u16 *packet = (u16 *) &(ib->tx_buf[entry][0]); | ||
903 | struct ethhdr *eth = (struct ethhdr *) packet; | ||
904 | memset(packet, 0, ETH_ZLEN); | ||
905 | for (i = 0; i < 6; i++) { | ||
906 | eth->h_dest[i] = dev->dev_addr[i]; | ||
907 | eth->h_source[i] = dev->dev_addr[i]; | ||
908 | } | ||
909 | ib->btx_ring[entry].length = (-ETH_ZLEN) | 0xf000; | ||
910 | ib->btx_ring[entry].misc = 0; | ||
911 | ib->btx_ring[entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN); | ||
912 | } | ||
913 | lp->tx_new = TX_NEXT(entry); | ||
914 | } | ||
915 | |||
916 | struct net_device *last_dev; | ||
917 | |||
918 | static int lance_open(struct net_device *dev) | ||
919 | { | ||
920 | struct lance_private *lp = netdev_priv(dev); | ||
921 | int status = 0; | ||
922 | |||
923 | last_dev = dev; | ||
924 | |||
925 | STOP_LANCE(lp); | ||
926 | |||
927 | if (request_irq(dev->irq, &lance_interrupt, SA_SHIRQ, | ||
928 | lancestr, (void *) dev)) { | ||
929 | printk(KERN_ERR "Lance: Can't get irq %s\n", __irq_itoa(dev->irq)); | ||
930 | return -EAGAIN; | ||
931 | } | ||
932 | |||
933 | /* On the 4m, setup the ledma to provide the upper bits for buffers */ | ||
934 | if (lp->dregs) { | ||
935 | u32 regval = lp->init_block_dvma & 0xff000000; | ||
936 | |||
937 | sbus_writel(regval, lp->dregs + DMA_TEST); | ||
938 | } | ||
939 | |||
940 | /* Set mode and clear multicast filter only at device open, | ||
941 | * so that lance_init_ring() called at any error will not | ||
942 | * forget multicast filters. | ||
943 | * | ||
944 | * BTW it is common bug in all lance drivers! --ANK | ||
945 | */ | ||
946 | if (lp->pio_buffer) { | ||
947 | struct lance_init_block __iomem *ib = lp->init_block_iomem; | ||
948 | sbus_writew(0, &ib->mode); | ||
949 | sbus_writel(0, &ib->filter[0]); | ||
950 | sbus_writel(0, &ib->filter[1]); | ||
951 | } else { | ||
952 | struct lance_init_block *ib = lp->init_block_mem; | ||
953 | ib->mode = 0; | ||
954 | ib->filter [0] = 0; | ||
955 | ib->filter [1] = 0; | ||
956 | } | ||
957 | |||
958 | lp->init_ring(dev); | ||
959 | load_csrs(lp); | ||
960 | |||
961 | netif_start_queue(dev); | ||
962 | |||
963 | status = init_restart_lance(lp); | ||
964 | if (!status && lp->auto_select) { | ||
965 | build_fake_packet(lp); | ||
966 | sbus_writew(LE_C0_INEA | LE_C0_TDMD, lp->lregs + RDP); | ||
967 | } | ||
968 | |||
969 | return status; | ||
970 | } | ||
971 | |||
972 | static int lance_close(struct net_device *dev) | ||
973 | { | ||
974 | struct lance_private *lp = netdev_priv(dev); | ||
975 | |||
976 | netif_stop_queue(dev); | ||
977 | del_timer_sync(&lp->multicast_timer); | ||
978 | |||
979 | STOP_LANCE(lp); | ||
980 | |||
981 | free_irq(dev->irq, (void *) dev); | ||
982 | return 0; | ||
983 | } | ||
984 | |||
985 | static int lance_reset(struct net_device *dev) | ||
986 | { | ||
987 | struct lance_private *lp = netdev_priv(dev); | ||
988 | int status; | ||
989 | |||
990 | STOP_LANCE(lp); | ||
991 | |||
992 | /* On the 4m, reset the dma too */ | ||
993 | if (lp->dregs) { | ||
994 | u32 csr, addr; | ||
995 | |||
996 | printk(KERN_ERR "resetting ledma\n"); | ||
997 | csr = sbus_readl(lp->dregs + DMA_CSR); | ||
998 | sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR); | ||
999 | udelay(200); | ||
1000 | sbus_writel(csr & ~DMA_RST_ENET, lp->dregs + DMA_CSR); | ||
1001 | |||
1002 | addr = lp->init_block_dvma & 0xff000000; | ||
1003 | sbus_writel(addr, lp->dregs + DMA_TEST); | ||
1004 | } | ||
1005 | lp->init_ring(dev); | ||
1006 | load_csrs(lp); | ||
1007 | dev->trans_start = jiffies; | ||
1008 | status = init_restart_lance(lp); | ||
1009 | return status; | ||
1010 | } | ||
1011 | |||
1012 | static void lance_piocopy_from_skb(void __iomem *dest, unsigned char *src, int len) | ||
1013 | { | ||
1014 | void __iomem *piobuf = dest; | ||
1015 | u32 *p32; | ||
1016 | u16 *p16; | ||
1017 | u8 *p8; | ||
1018 | |||
1019 | switch ((unsigned long)src & 0x3) { | ||
1020 | case 0: | ||
1021 | p32 = (u32 *) src; | ||
1022 | while (len >= 4) { | ||
1023 | sbus_writel(*p32, piobuf); | ||
1024 | p32++; | ||
1025 | piobuf += 4; | ||
1026 | len -= 4; | ||
1027 | } | ||
1028 | src = (char *) p32; | ||
1029 | break; | ||
1030 | case 1: | ||
1031 | case 3: | ||
1032 | p8 = (u8 *) src; | ||
1033 | while (len >= 4) { | ||
1034 | u32 val; | ||
1035 | |||
1036 | val = p8[0] << 24; | ||
1037 | val |= p8[1] << 16; | ||
1038 | val |= p8[2] << 8; | ||
1039 | val |= p8[3]; | ||
1040 | sbus_writel(val, piobuf); | ||
1041 | p8 += 4; | ||
1042 | piobuf += 4; | ||
1043 | len -= 4; | ||
1044 | } | ||
1045 | src = (char *) p8; | ||
1046 | break; | ||
1047 | case 2: | ||
1048 | p16 = (u16 *) src; | ||
1049 | while (len >= 4) { | ||
1050 | u32 val = p16[0]<<16 | p16[1]; | ||
1051 | sbus_writel(val, piobuf); | ||
1052 | p16 += 2; | ||
1053 | piobuf += 4; | ||
1054 | len -= 4; | ||
1055 | } | ||
1056 | src = (char *) p16; | ||
1057 | break; | ||
1058 | }; | ||
1059 | if (len >= 2) { | ||
1060 | u16 val = src[0] << 8 | src[1]; | ||
1061 | sbus_writew(val, piobuf); | ||
1062 | src += 2; | ||
1063 | piobuf += 2; | ||
1064 | len -= 2; | ||
1065 | } | ||
1066 | if (len >= 1) | ||
1067 | sbus_writeb(src[0], piobuf); | ||
1068 | } | ||
1069 | |||
1070 | static void lance_piozero(void __iomem *dest, int len) | ||
1071 | { | ||
1072 | void __iomem *piobuf = dest; | ||
1073 | |||
1074 | if ((unsigned long)piobuf & 1) { | ||
1075 | sbus_writeb(0, piobuf); | ||
1076 | piobuf += 1; | ||
1077 | len -= 1; | ||
1078 | if (len == 0) | ||
1079 | return; | ||
1080 | } | ||
1081 | if (len == 1) { | ||
1082 | sbus_writeb(0, piobuf); | ||
1083 | return; | ||
1084 | } | ||
1085 | if ((unsigned long)piobuf & 2) { | ||
1086 | sbus_writew(0, piobuf); | ||
1087 | piobuf += 2; | ||
1088 | len -= 2; | ||
1089 | if (len == 0) | ||
1090 | return; | ||
1091 | } | ||
1092 | while (len >= 4) { | ||
1093 | sbus_writel(0, piobuf); | ||
1094 | piobuf += 4; | ||
1095 | len -= 4; | ||
1096 | } | ||
1097 | if (len >= 2) { | ||
1098 | sbus_writew(0, piobuf); | ||
1099 | piobuf += 2; | ||
1100 | len -= 2; | ||
1101 | } | ||
1102 | if (len >= 1) | ||
1103 | sbus_writeb(0, piobuf); | ||
1104 | } | ||
1105 | |||
1106 | static void lance_tx_timeout(struct net_device *dev) | ||
1107 | { | ||
1108 | struct lance_private *lp = netdev_priv(dev); | ||
1109 | |||
1110 | printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n", | ||
1111 | dev->name, sbus_readw(lp->lregs + RDP)); | ||
1112 | lance_reset(dev); | ||
1113 | netif_wake_queue(dev); | ||
1114 | } | ||
1115 | |||
1116 | static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
1117 | { | ||
1118 | struct lance_private *lp = netdev_priv(dev); | ||
1119 | int entry, skblen, len; | ||
1120 | |||
1121 | skblen = skb->len; | ||
1122 | |||
1123 | len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen; | ||
1124 | |||
1125 | spin_lock_irq(&lp->lock); | ||
1126 | |||
1127 | lp->stats.tx_bytes += len; | ||
1128 | |||
1129 | entry = lp->tx_new & TX_RING_MOD_MASK; | ||
1130 | if (lp->pio_buffer) { | ||
1131 | struct lance_init_block __iomem *ib = lp->init_block_iomem; | ||
1132 | sbus_writew((-len) | 0xf000, &ib->btx_ring[entry].length); | ||
1133 | sbus_writew(0, &ib->btx_ring[entry].misc); | ||
1134 | lance_piocopy_from_skb(&ib->tx_buf[entry][0], skb->data, skblen); | ||
1135 | if (len != skblen) | ||
1136 | lance_piozero(&ib->tx_buf[entry][skblen], len - skblen); | ||
1137 | sbus_writeb(LE_T1_POK | LE_T1_OWN, &ib->btx_ring[entry].tmd1_bits); | ||
1138 | } else { | ||
1139 | struct lance_init_block *ib = lp->init_block_mem; | ||
1140 | ib->btx_ring [entry].length = (-len) | 0xf000; | ||
1141 | ib->btx_ring [entry].misc = 0; | ||
1142 | memcpy((char *)&ib->tx_buf [entry][0], skb->data, skblen); | ||
1143 | if (len != skblen) | ||
1144 | memset((char *) &ib->tx_buf [entry][skblen], 0, len - skblen); | ||
1145 | ib->btx_ring [entry].tmd1_bits = (LE_T1_POK | LE_T1_OWN); | ||
1146 | } | ||
1147 | |||
1148 | lp->tx_new = TX_NEXT(entry); | ||
1149 | |||
1150 | if (TX_BUFFS_AVAIL <= 0) | ||
1151 | netif_stop_queue(dev); | ||
1152 | |||
1153 | /* Kick the lance: transmit now */ | ||
1154 | sbus_writew(LE_C0_INEA | LE_C0_TDMD, lp->lregs + RDP); | ||
1155 | |||
1156 | /* Read back CSR to invalidate the E-Cache. | ||
1157 | * This is needed, because DMA_DSBL_WR_INV is set. | ||
1158 | */ | ||
1159 | if (lp->dregs) | ||
1160 | sbus_readw(lp->lregs + RDP); | ||
1161 | |||
1162 | spin_unlock_irq(&lp->lock); | ||
1163 | |||
1164 | dev->trans_start = jiffies; | ||
1165 | dev_kfree_skb(skb); | ||
1166 | |||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | static struct net_device_stats *lance_get_stats(struct net_device *dev) | ||
1171 | { | ||
1172 | struct lance_private *lp = netdev_priv(dev); | ||
1173 | |||
1174 | return &lp->stats; | ||
1175 | } | ||
1176 | |||
1177 | /* taken from the depca driver */ | ||
1178 | static void lance_load_multicast(struct net_device *dev) | ||
1179 | { | ||
1180 | struct lance_private *lp = netdev_priv(dev); | ||
1181 | struct dev_mc_list *dmi = dev->mc_list; | ||
1182 | char *addrs; | ||
1183 | int i; | ||
1184 | u32 crc; | ||
1185 | u32 val; | ||
1186 | |||
1187 | /* set all multicast bits */ | ||
1188 | if (dev->flags & IFF_ALLMULTI) | ||
1189 | val = ~0; | ||
1190 | else | ||
1191 | val = 0; | ||
1192 | |||
1193 | if (lp->pio_buffer) { | ||
1194 | struct lance_init_block __iomem *ib = lp->init_block_iomem; | ||
1195 | sbus_writel(val, &ib->filter[0]); | ||
1196 | sbus_writel(val, &ib->filter[1]); | ||
1197 | } else { | ||
1198 | struct lance_init_block *ib = lp->init_block_mem; | ||
1199 | ib->filter [0] = val; | ||
1200 | ib->filter [1] = val; | ||
1201 | } | ||
1202 | |||
1203 | if (dev->flags & IFF_ALLMULTI) | ||
1204 | return; | ||
1205 | |||
1206 | /* Add addresses */ | ||
1207 | for (i = 0; i < dev->mc_count; i++) { | ||
1208 | addrs = dmi->dmi_addr; | ||
1209 | dmi = dmi->next; | ||
1210 | |||
1211 | /* multicast address? */ | ||
1212 | if (!(*addrs & 1)) | ||
1213 | continue; | ||
1214 | crc = ether_crc_le(6, addrs); | ||
1215 | crc = crc >> 26; | ||
1216 | if (lp->pio_buffer) { | ||
1217 | struct lance_init_block __iomem *ib = lp->init_block_iomem; | ||
1218 | u16 __iomem *mcast_table = (u16 __iomem *) &ib->filter; | ||
1219 | u16 tmp = sbus_readw(&mcast_table[crc>>4]); | ||
1220 | tmp |= 1 << (crc & 0xf); | ||
1221 | sbus_writew(tmp, &mcast_table[crc>>4]); | ||
1222 | } else { | ||
1223 | struct lance_init_block *ib = lp->init_block_mem; | ||
1224 | u16 *mcast_table = (u16 *) &ib->filter; | ||
1225 | mcast_table [crc >> 4] |= 1 << (crc & 0xf); | ||
1226 | } | ||
1227 | } | ||
1228 | } | ||
1229 | |||
1230 | static void lance_set_multicast(struct net_device *dev) | ||
1231 | { | ||
1232 | struct lance_private *lp = netdev_priv(dev); | ||
1233 | struct lance_init_block *ib_mem = lp->init_block_mem; | ||
1234 | struct lance_init_block __iomem *ib_iomem = lp->init_block_iomem; | ||
1235 | u16 mode; | ||
1236 | |||
1237 | if (!netif_running(dev)) | ||
1238 | return; | ||
1239 | |||
1240 | if (lp->tx_old != lp->tx_new) { | ||
1241 | mod_timer(&lp->multicast_timer, jiffies + 4); | ||
1242 | netif_wake_queue(dev); | ||
1243 | return; | ||
1244 | } | ||
1245 | |||
1246 | netif_stop_queue(dev); | ||
1247 | |||
1248 | STOP_LANCE(lp); | ||
1249 | lp->init_ring(dev); | ||
1250 | |||
1251 | if (lp->pio_buffer) | ||
1252 | mode = sbus_readw(&ib_iomem->mode); | ||
1253 | else | ||
1254 | mode = ib_mem->mode; | ||
1255 | if (dev->flags & IFF_PROMISC) { | ||
1256 | mode |= LE_MO_PROM; | ||
1257 | if (lp->pio_buffer) | ||
1258 | sbus_writew(mode, &ib_iomem->mode); | ||
1259 | else | ||
1260 | ib_mem->mode = mode; | ||
1261 | } else { | ||
1262 | mode &= ~LE_MO_PROM; | ||
1263 | if (lp->pio_buffer) | ||
1264 | sbus_writew(mode, &ib_iomem->mode); | ||
1265 | else | ||
1266 | ib_mem->mode = mode; | ||
1267 | lance_load_multicast(dev); | ||
1268 | } | ||
1269 | load_csrs(lp); | ||
1270 | init_restart_lance(lp); | ||
1271 | netif_wake_queue(dev); | ||
1272 | } | ||
1273 | |||
1274 | static void lance_set_multicast_retry(unsigned long _opaque) | ||
1275 | { | ||
1276 | struct net_device *dev = (struct net_device *) _opaque; | ||
1277 | |||
1278 | lance_set_multicast(dev); | ||
1279 | } | ||
1280 | |||
1281 | static void lance_free_hwresources(struct lance_private *lp) | ||
1282 | { | ||
1283 | if (lp->lregs) | ||
1284 | sbus_iounmap(lp->lregs, LANCE_REG_SIZE); | ||
1285 | if (lp->init_block_iomem) { | ||
1286 | sbus_iounmap(lp->init_block_iomem, | ||
1287 | sizeof(struct lance_init_block)); | ||
1288 | } else if (lp->init_block_mem) { | ||
1289 | sbus_free_consistent(lp->sdev, | ||
1290 | sizeof(struct lance_init_block), | ||
1291 | lp->init_block_mem, | ||
1292 | lp->init_block_dvma); | ||
1293 | } | ||
1294 | } | ||
1295 | |||
1296 | /* Ethtool support... */ | ||
1297 | static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
1298 | { | ||
1299 | struct lance_private *lp = netdev_priv(dev); | ||
1300 | |||
1301 | strcpy(info->driver, "sunlance"); | ||
1302 | strcpy(info->version, "2.02"); | ||
1303 | sprintf(info->bus_info, "SBUS:%d", | ||
1304 | lp->sdev->slot); | ||
1305 | } | ||
1306 | |||
1307 | static u32 sparc_lance_get_link(struct net_device *dev) | ||
1308 | { | ||
1309 | /* We really do not keep track of this, but this | ||
1310 | * is better than not reporting anything at all. | ||
1311 | */ | ||
1312 | return 1; | ||
1313 | } | ||
1314 | |||
1315 | static struct ethtool_ops sparc_lance_ethtool_ops = { | ||
1316 | .get_drvinfo = sparc_lance_get_drvinfo, | ||
1317 | .get_link = sparc_lance_get_link, | ||
1318 | }; | ||
1319 | |||
1320 | static int __init sparc_lance_init(struct sbus_dev *sdev, | ||
1321 | struct sbus_dma *ledma, | ||
1322 | struct sbus_dev *lebuffer) | ||
1323 | { | ||
1324 | static unsigned version_printed; | ||
1325 | struct net_device *dev; | ||
1326 | struct lance_private *lp; | ||
1327 | int i; | ||
1328 | |||
1329 | dev = alloc_etherdev(sizeof(struct lance_private) + 8); | ||
1330 | if (!dev) | ||
1331 | return -ENOMEM; | ||
1332 | |||
1333 | lp = netdev_priv(dev); | ||
1334 | memset(lp, 0, sizeof(*lp)); | ||
1335 | |||
1336 | if (sparc_lance_debug && version_printed++ == 0) | ||
1337 | printk (KERN_INFO "%s", version); | ||
1338 | |||
1339 | spin_lock_init(&lp->lock); | ||
1340 | |||
1341 | /* Copy the IDPROM ethernet address to the device structure, later we | ||
1342 | * will copy the address in the device structure to the lance | ||
1343 | * initialization block. | ||
1344 | */ | ||
1345 | for (i = 0; i < 6; i++) | ||
1346 | dev->dev_addr[i] = idprom->id_ethaddr[i]; | ||
1347 | |||
1348 | /* Get the IO region */ | ||
1349 | lp->lregs = sbus_ioremap(&sdev->resource[0], 0, | ||
1350 | LANCE_REG_SIZE, lancestr); | ||
1351 | if (!lp->lregs) { | ||
1352 | printk(KERN_ERR "SunLance: Cannot map registers.\n"); | ||
1353 | goto fail; | ||
1354 | } | ||
1355 | |||
1356 | lp->sdev = sdev; | ||
1357 | if (lebuffer) { | ||
1358 | /* sanity check */ | ||
1359 | if (lebuffer->resource[0].start & 7) { | ||
1360 | printk(KERN_ERR "SunLance: ERROR: Rx and Tx rings not on even boundary.\n"); | ||
1361 | goto fail; | ||
1362 | } | ||
1363 | lp->init_block_iomem = | ||
1364 | sbus_ioremap(&lebuffer->resource[0], 0, | ||
1365 | sizeof(struct lance_init_block), "lebuffer"); | ||
1366 | if (!lp->init_block_iomem) { | ||
1367 | printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n"); | ||
1368 | goto fail; | ||
1369 | } | ||
1370 | lp->init_block_dvma = 0; | ||
1371 | lp->pio_buffer = 1; | ||
1372 | lp->init_ring = lance_init_ring_pio; | ||
1373 | lp->rx = lance_rx_pio; | ||
1374 | lp->tx = lance_tx_pio; | ||
1375 | } else { | ||
1376 | lp->init_block_mem = | ||
1377 | sbus_alloc_consistent(sdev, sizeof(struct lance_init_block), | ||
1378 | &lp->init_block_dvma); | ||
1379 | if (!lp->init_block_mem || lp->init_block_dvma == 0) { | ||
1380 | printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n"); | ||
1381 | goto fail; | ||
1382 | } | ||
1383 | lp->pio_buffer = 0; | ||
1384 | lp->init_ring = lance_init_ring_dvma; | ||
1385 | lp->rx = lance_rx_dvma; | ||
1386 | lp->tx = lance_tx_dvma; | ||
1387 | } | ||
1388 | lp->busmaster_regval = prom_getintdefault(sdev->prom_node, | ||
1389 | "busmaster-regval", | ||
1390 | (LE_C3_BSWP | LE_C3_ACON | | ||
1391 | LE_C3_BCON)); | ||
1392 | |||
1393 | lp->name = lancestr; | ||
1394 | lp->ledma = ledma; | ||
1395 | |||
1396 | lp->burst_sizes = 0; | ||
1397 | if (lp->ledma) { | ||
1398 | char prop[6]; | ||
1399 | unsigned int sbmask; | ||
1400 | u32 csr; | ||
1401 | |||
1402 | /* Find burst-size property for ledma */ | ||
1403 | lp->burst_sizes = prom_getintdefault(ledma->sdev->prom_node, | ||
1404 | "burst-sizes", 0); | ||
1405 | |||
1406 | /* ledma may be capable of fast bursts, but sbus may not. */ | ||
1407 | sbmask = prom_getintdefault(ledma->sdev->bus->prom_node, | ||
1408 | "burst-sizes", DMA_BURSTBITS); | ||
1409 | lp->burst_sizes &= sbmask; | ||
1410 | |||
1411 | /* Get the cable-selection property */ | ||
1412 | memset(prop, 0, sizeof(prop)); | ||
1413 | prom_getstring(ledma->sdev->prom_node, "cable-selection", | ||
1414 | prop, sizeof(prop)); | ||
1415 | if (prop[0] == 0) { | ||
1416 | int topnd, nd; | ||
1417 | |||
1418 | printk(KERN_INFO "SunLance: using auto-carrier-detection.\n"); | ||
1419 | |||
1420 | /* Is this found at /options .attributes in all | ||
1421 | * Prom versions? XXX | ||
1422 | */ | ||
1423 | topnd = prom_getchild(prom_root_node); | ||
1424 | |||
1425 | nd = prom_searchsiblings(topnd, "options"); | ||
1426 | if (!nd) | ||
1427 | goto no_link_test; | ||
1428 | |||
1429 | if (!prom_node_has_property(nd, "tpe-link-test?")) | ||
1430 | goto no_link_test; | ||
1431 | |||
1432 | memset(prop, 0, sizeof(prop)); | ||
1433 | prom_getstring(nd, "tpe-link-test?", prop, | ||
1434 | sizeof(prop)); | ||
1435 | |||
1436 | if (strcmp(prop, "true")) { | ||
1437 | printk(KERN_NOTICE "SunLance: warning: overriding option " | ||
1438 | "'tpe-link-test?'\n"); | ||
1439 | printk(KERN_NOTICE "SunLance: warning: mail any problems " | ||
1440 | "to ecd@skynet.be\n"); | ||
1441 | auxio_set_lte(AUXIO_LTE_ON); | ||
1442 | } | ||
1443 | no_link_test: | ||
1444 | lp->auto_select = 1; | ||
1445 | lp->tpe = 0; | ||
1446 | } else if (!strcmp(prop, "aui")) { | ||
1447 | lp->auto_select = 0; | ||
1448 | lp->tpe = 0; | ||
1449 | } else { | ||
1450 | lp->auto_select = 0; | ||
1451 | lp->tpe = 1; | ||
1452 | } | ||
1453 | |||
1454 | lp->dregs = ledma->regs; | ||
1455 | |||
1456 | /* Reset ledma */ | ||
1457 | csr = sbus_readl(lp->dregs + DMA_CSR); | ||
1458 | sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR); | ||
1459 | udelay(200); | ||
1460 | sbus_writel(csr & ~DMA_RST_ENET, lp->dregs + DMA_CSR); | ||
1461 | } else | ||
1462 | lp->dregs = NULL; | ||
1463 | |||
1464 | lp->dev = dev; | ||
1465 | SET_MODULE_OWNER(dev); | ||
1466 | dev->open = &lance_open; | ||
1467 | dev->stop = &lance_close; | ||
1468 | dev->hard_start_xmit = &lance_start_xmit; | ||
1469 | dev->tx_timeout = &lance_tx_timeout; | ||
1470 | dev->watchdog_timeo = 5*HZ; | ||
1471 | dev->get_stats = &lance_get_stats; | ||
1472 | dev->set_multicast_list = &lance_set_multicast; | ||
1473 | dev->ethtool_ops = &sparc_lance_ethtool_ops; | ||
1474 | |||
1475 | dev->irq = sdev->irqs[0]; | ||
1476 | |||
1477 | dev->dma = 0; | ||
1478 | |||
1479 | /* We cannot sleep if the chip is busy during a | ||
1480 | * multicast list update event, because such events | ||
1481 | * can occur from interrupts (ex. IPv6). So we | ||
1482 | * use a timer to try again later when necessary. -DaveM | ||
1483 | */ | ||
1484 | init_timer(&lp->multicast_timer); | ||
1485 | lp->multicast_timer.data = (unsigned long) dev; | ||
1486 | lp->multicast_timer.function = &lance_set_multicast_retry; | ||
1487 | |||
1488 | if (register_netdev(dev)) { | ||
1489 | printk(KERN_ERR "SunLance: Cannot register device.\n"); | ||
1490 | goto fail; | ||
1491 | } | ||
1492 | |||
1493 | lp->next_module = root_lance_dev; | ||
1494 | root_lance_dev = lp; | ||
1495 | |||
1496 | printk(KERN_INFO "%s: LANCE ", dev->name); | ||
1497 | |||
1498 | for (i = 0; i < 6; i++) | ||
1499 | printk("%2.2x%c", dev->dev_addr[i], | ||
1500 | i == 5 ? ' ': ':'); | ||
1501 | printk("\n"); | ||
1502 | |||
1503 | return 0; | ||
1504 | |||
1505 | fail: | ||
1506 | lance_free_hwresources(lp); | ||
1507 | free_netdev(dev); | ||
1508 | return -ENODEV; | ||
1509 | } | ||
1510 | |||
1511 | /* On 4m, find the associated dma for the lance chip */ | ||
1512 | static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev) | ||
1513 | { | ||
1514 | struct sbus_dma *p; | ||
1515 | |||
1516 | for_each_dvma(p) { | ||
1517 | if (p->sdev == sdev) | ||
1518 | return p; | ||
1519 | } | ||
1520 | return NULL; | ||
1521 | } | ||
1522 | |||
1523 | #ifdef CONFIG_SUN4 | ||
1524 | |||
1525 | #include <asm/sun4paddr.h> | ||
1526 | #include <asm/machines.h> | ||
1527 | |||
1528 | /* Find all the lance cards on the system and initialize them */ | ||
1529 | static int __init sparc_lance_probe(void) | ||
1530 | { | ||
1531 | static struct sbus_dev sdev; | ||
1532 | static int called; | ||
1533 | |||
1534 | root_lance_dev = NULL; | ||
1535 | |||
1536 | if (called) | ||
1537 | return -ENODEV; | ||
1538 | called++; | ||
1539 | |||
1540 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || | ||
1541 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { | ||
1542 | memset(&sdev, 0, sizeof(sdev)); | ||
1543 | sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; | ||
1544 | sdev.irqs[0] = 6; | ||
1545 | return sparc_lance_init(&sdev, NULL, NULL); | ||
1546 | } | ||
1547 | return -ENODEV; | ||
1548 | } | ||
1549 | |||
1550 | #else /* !CONFIG_SUN4 */ | ||
1551 | |||
1552 | /* Find all the lance cards on the system and initialize them */ | ||
1553 | static int __init sparc_lance_probe(void) | ||
1554 | { | ||
1555 | struct sbus_bus *bus; | ||
1556 | struct sbus_dev *sdev = NULL; | ||
1557 | struct sbus_dma *ledma = NULL; | ||
1558 | static int called; | ||
1559 | int cards = 0, v; | ||
1560 | |||
1561 | root_lance_dev = NULL; | ||
1562 | |||
1563 | if (called) | ||
1564 | return -ENODEV; | ||
1565 | called++; | ||
1566 | |||
1567 | for_each_sbus (bus) { | ||
1568 | for_each_sbusdev (sdev, bus) { | ||
1569 | if (strcmp(sdev->prom_name, "le") == 0) { | ||
1570 | cards++; | ||
1571 | if ((v = sparc_lance_init(sdev, NULL, NULL))) | ||
1572 | return v; | ||
1573 | continue; | ||
1574 | } | ||
1575 | if (strcmp(sdev->prom_name, "ledma") == 0) { | ||
1576 | cards++; | ||
1577 | ledma = find_ledma(sdev); | ||
1578 | if ((v = sparc_lance_init(sdev->child, | ||
1579 | ledma, NULL))) | ||
1580 | return v; | ||
1581 | continue; | ||
1582 | } | ||
1583 | if (strcmp(sdev->prom_name, "lebuffer") == 0){ | ||
1584 | cards++; | ||
1585 | if ((v = sparc_lance_init(sdev->child, | ||
1586 | NULL, sdev))) | ||
1587 | return v; | ||
1588 | continue; | ||
1589 | } | ||
1590 | } /* for each sbusdev */ | ||
1591 | } /* for each sbus */ | ||
1592 | if (!cards) | ||
1593 | return -ENODEV; | ||
1594 | return 0; | ||
1595 | } | ||
1596 | #endif /* !CONFIG_SUN4 */ | ||
1597 | |||
1598 | static void __exit sparc_lance_cleanup(void) | ||
1599 | { | ||
1600 | struct lance_private *lp; | ||
1601 | |||
1602 | while (root_lance_dev) { | ||
1603 | lp = root_lance_dev->next_module; | ||
1604 | |||
1605 | unregister_netdev(root_lance_dev->dev); | ||
1606 | lance_free_hwresources(root_lance_dev); | ||
1607 | free_netdev(root_lance_dev->dev); | ||
1608 | root_lance_dev = lp; | ||
1609 | } | ||
1610 | } | ||
1611 | |||
1612 | module_init(sparc_lance_probe); | ||
1613 | module_exit(sparc_lance_cleanup); | ||
1614 | MODULE_LICENSE("GPL"); | ||