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/3c505.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/3c505.c')
-rw-r--r-- | drivers/net/3c505.c | 1690 |
1 files changed, 1690 insertions, 0 deletions
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c new file mode 100644 index 000000000000..76fa8cc24085 --- /dev/null +++ b/drivers/net/3c505.c | |||
@@ -0,0 +1,1690 @@ | |||
1 | /* | ||
2 | * Linux Ethernet device driver for the 3Com Etherlink Plus (3C505) | ||
3 | * By Craig Southeren, Juha Laiho and Philip Blundell | ||
4 | * | ||
5 | * 3c505.c This module implements an interface to the 3Com | ||
6 | * Etherlink Plus (3c505) Ethernet card. Linux device | ||
7 | * driver interface reverse engineered from the Linux 3C509 | ||
8 | * device drivers. Some 3C505 information gleaned from | ||
9 | * the Crynwr packet driver. Still this driver would not | ||
10 | * be here without 3C505 technical reference provided by | ||
11 | * 3Com. | ||
12 | * | ||
13 | * $Id: 3c505.c,v 1.10 1996/04/16 13:06:27 phil Exp $ | ||
14 | * | ||
15 | * Authors: Linux 3c505 device driver by | ||
16 | * Craig Southeren, <craigs@ineluki.apana.org.au> | ||
17 | * Final debugging by | ||
18 | * Andrew Tridgell, <tridge@nimbus.anu.edu.au> | ||
19 | * Auto irq/address, tuning, cleanup and v1.1.4+ kernel mods by | ||
20 | * Juha Laiho, <jlaiho@ichaos.nullnet.fi> | ||
21 | * Linux 3C509 driver by | ||
22 | * Donald Becker, <becker@super.org> | ||
23 | * (Now at <becker@scyld.com>) | ||
24 | * Crynwr packet driver by | ||
25 | * Krishnan Gopalan and Gregg Stefancik, | ||
26 | * Clemson University Engineering Computer Operations. | ||
27 | * Portions of the code have been adapted from the 3c505 | ||
28 | * driver for NCSA Telnet by Bruce Orchard and later | ||
29 | * modified by Warren Van Houten and krus@diku.dk. | ||
30 | * 3C505 technical information provided by | ||
31 | * Terry Murphy, of 3Com Network Adapter Division | ||
32 | * Linux 1.3.0 changes by | ||
33 | * Alan Cox <Alan.Cox@linux.org> | ||
34 | * More debugging, DMA support, currently maintained by | ||
35 | * Philip Blundell <philb@gnu.org> | ||
36 | * Multicard/soft configurable dma channel/rev 2 hardware support | ||
37 | * by Christopher Collins <ccollins@pcug.org.au> | ||
38 | * Ethtool support (jgarzik), 11/17/2001 | ||
39 | */ | ||
40 | |||
41 | #define DRV_NAME "3c505" | ||
42 | #define DRV_VERSION "1.10a" | ||
43 | |||
44 | |||
45 | /* Theory of operation: | ||
46 | * | ||
47 | * The 3c505 is quite an intelligent board. All communication with it is done | ||
48 | * by means of Primary Command Blocks (PCBs); these are transferred using PIO | ||
49 | * through the command register. The card has 256k of on-board RAM, which is | ||
50 | * used to buffer received packets. It might seem at first that more buffers | ||
51 | * are better, but in fact this isn't true. From my tests, it seems that | ||
52 | * more than about 10 buffers are unnecessary, and there is a noticeable | ||
53 | * performance hit in having more active on the card. So the majority of the | ||
54 | * card's memory isn't, in fact, used. Sadly, the card only has one transmit | ||
55 | * buffer and, short of loading our own firmware into it (which is what some | ||
56 | * drivers resort to) there's nothing we can do about this. | ||
57 | * | ||
58 | * We keep up to 4 "receive packet" commands active on the board at a time. | ||
59 | * When a packet comes in, so long as there is a receive command active, the | ||
60 | * board will send us a "packet received" PCB and then add the data for that | ||
61 | * packet to the DMA queue. If a DMA transfer is not already in progress, we | ||
62 | * set one up to start uploading the data. We have to maintain a list of | ||
63 | * backlogged receive packets, because the card may decide to tell us about | ||
64 | * a newly-arrived packet at any time, and we may not be able to start a DMA | ||
65 | * transfer immediately (ie one may already be going on). We can't NAK the | ||
66 | * PCB, because then it would throw the packet away. | ||
67 | * | ||
68 | * Trying to send a PCB to the card at the wrong moment seems to have bad | ||
69 | * effects. If we send it a transmit PCB while a receive DMA is happening, | ||
70 | * it will just NAK the PCB and so we will have wasted our time. Worse, it | ||
71 | * sometimes seems to interrupt the transfer. The majority of the low-level | ||
72 | * code is protected by one huge semaphore -- "busy" -- which is set whenever | ||
73 | * it probably isn't safe to do anything to the card. The receive routine | ||
74 | * must gain a lock on "busy" before it can start a DMA transfer, and the | ||
75 | * transmit routine must gain a lock before it sends the first PCB to the card. | ||
76 | * The send_pcb() routine also has an internal semaphore to protect it against | ||
77 | * being re-entered (which would be disastrous) -- this is needed because | ||
78 | * several things can happen asynchronously (re-priming the receiver and | ||
79 | * asking the card for statistics, for example). send_pcb() will also refuse | ||
80 | * to talk to the card at all if a DMA upload is happening. The higher-level | ||
81 | * networking code will reschedule a later retry if some part of the driver | ||
82 | * is blocked. In practice, this doesn't seem to happen very often. | ||
83 | */ | ||
84 | |||
85 | /* This driver may now work with revision 2.x hardware, since all the read | ||
86 | * operations on the HCR have been removed (we now keep our own softcopy). | ||
87 | * But I don't have an old card to test it on. | ||
88 | * | ||
89 | * This has had the bad effect that the autoprobe routine is now a bit | ||
90 | * less friendly to other devices. However, it was never very good. | ||
91 | * before, so I doubt it will hurt anybody. | ||
92 | */ | ||
93 | |||
94 | /* The driver is a mess. I took Craig's and Juha's code, and hacked it firstly | ||
95 | * to make it more reliable, and secondly to add DMA mode. Many things could | ||
96 | * probably be done better; the concurrency protection is particularly awful. | ||
97 | */ | ||
98 | |||
99 | #include <linux/module.h> | ||
100 | #include <linux/kernel.h> | ||
101 | #include <linux/string.h> | ||
102 | #include <linux/interrupt.h> | ||
103 | #include <linux/errno.h> | ||
104 | #include <linux/in.h> | ||
105 | #include <linux/slab.h> | ||
106 | #include <linux/ioport.h> | ||
107 | #include <linux/spinlock.h> | ||
108 | #include <linux/ethtool.h> | ||
109 | #include <linux/delay.h> | ||
110 | #include <linux/bitops.h> | ||
111 | |||
112 | #include <asm/uaccess.h> | ||
113 | #include <asm/io.h> | ||
114 | #include <asm/dma.h> | ||
115 | |||
116 | #include <linux/netdevice.h> | ||
117 | #include <linux/etherdevice.h> | ||
118 | #include <linux/skbuff.h> | ||
119 | #include <linux/init.h> | ||
120 | |||
121 | #include "3c505.h" | ||
122 | |||
123 | /********************************************************* | ||
124 | * | ||
125 | * define debug messages here as common strings to reduce space | ||
126 | * | ||
127 | *********************************************************/ | ||
128 | |||
129 | static const char filename[] = __FILE__; | ||
130 | |||
131 | static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n"; | ||
132 | #define TIMEOUT_MSG(lineno) \ | ||
133 | printk(timeout_msg, filename,__FUNCTION__,(lineno)) | ||
134 | |||
135 | static const char invalid_pcb_msg[] = | ||
136 | "*** invalid pcb length %d at %s:%s (line %d) ***\n"; | ||
137 | #define INVALID_PCB_MSG(len) \ | ||
138 | printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__) | ||
139 | |||
140 | static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x..."; | ||
141 | |||
142 | static char stilllooking_msg[] __initdata = "still looking..."; | ||
143 | |||
144 | static char found_msg[] __initdata = "found.\n"; | ||
145 | |||
146 | static char notfound_msg[] __initdata = "not found (reason = %d)\n"; | ||
147 | |||
148 | static char couldnot_msg[] __initdata = KERN_INFO "%s: 3c505 not found\n"; | ||
149 | |||
150 | /********************************************************* | ||
151 | * | ||
152 | * various other debug stuff | ||
153 | * | ||
154 | *********************************************************/ | ||
155 | |||
156 | #ifdef ELP_DEBUG | ||
157 | static int elp_debug = ELP_DEBUG; | ||
158 | #else | ||
159 | static int elp_debug; | ||
160 | #endif | ||
161 | #define debug elp_debug | ||
162 | |||
163 | /* | ||
164 | * 0 = no messages (well, some) | ||
165 | * 1 = messages when high level commands performed | ||
166 | * 2 = messages when low level commands performed | ||
167 | * 3 = messages when interrupts received | ||
168 | */ | ||
169 | |||
170 | /***************************************************************** | ||
171 | * | ||
172 | * useful macros | ||
173 | * | ||
174 | *****************************************************************/ | ||
175 | |||
176 | #ifndef TRUE | ||
177 | #define TRUE 1 | ||
178 | #endif | ||
179 | |||
180 | #ifndef FALSE | ||
181 | #define FALSE 0 | ||
182 | #endif | ||
183 | |||
184 | |||
185 | /***************************************************************** | ||
186 | * | ||
187 | * List of I/O-addresses we try to auto-sense | ||
188 | * Last element MUST BE 0! | ||
189 | *****************************************************************/ | ||
190 | |||
191 | static int addr_list[] __initdata = {0x300, 0x280, 0x310, 0}; | ||
192 | |||
193 | /* Dma Memory related stuff */ | ||
194 | |||
195 | static unsigned long dma_mem_alloc(int size) | ||
196 | { | ||
197 | int order = get_order(size); | ||
198 | return __get_dma_pages(GFP_KERNEL, order); | ||
199 | } | ||
200 | |||
201 | |||
202 | /***************************************************************** | ||
203 | * | ||
204 | * Functions for I/O (note the inline !) | ||
205 | * | ||
206 | *****************************************************************/ | ||
207 | |||
208 | static inline unsigned char inb_status(unsigned int base_addr) | ||
209 | { | ||
210 | return inb(base_addr + PORT_STATUS); | ||
211 | } | ||
212 | |||
213 | static inline int inb_command(unsigned int base_addr) | ||
214 | { | ||
215 | return inb(base_addr + PORT_COMMAND); | ||
216 | } | ||
217 | |||
218 | static inline void outb_control(unsigned char val, struct net_device *dev) | ||
219 | { | ||
220 | outb(val, dev->base_addr + PORT_CONTROL); | ||
221 | ((elp_device *)(dev->priv))->hcr_val = val; | ||
222 | } | ||
223 | |||
224 | #define HCR_VAL(x) (((elp_device *)((x)->priv))->hcr_val) | ||
225 | |||
226 | static inline void outb_command(unsigned char val, unsigned int base_addr) | ||
227 | { | ||
228 | outb(val, base_addr + PORT_COMMAND); | ||
229 | } | ||
230 | |||
231 | static inline unsigned int backlog_next(unsigned int n) | ||
232 | { | ||
233 | return (n + 1) % BACKLOG_SIZE; | ||
234 | } | ||
235 | |||
236 | /***************************************************************** | ||
237 | * | ||
238 | * useful functions for accessing the adapter | ||
239 | * | ||
240 | *****************************************************************/ | ||
241 | |||
242 | /* | ||
243 | * use this routine when accessing the ASF bits as they are | ||
244 | * changed asynchronously by the adapter | ||
245 | */ | ||
246 | |||
247 | /* get adapter PCB status */ | ||
248 | #define GET_ASF(addr) \ | ||
249 | (get_status(addr)&ASF_PCB_MASK) | ||
250 | |||
251 | static inline int get_status(unsigned int base_addr) | ||
252 | { | ||
253 | unsigned long timeout = jiffies + 10*HZ/100; | ||
254 | register int stat1; | ||
255 | do { | ||
256 | stat1 = inb_status(base_addr); | ||
257 | } while (stat1 != inb_status(base_addr) && time_before(jiffies, timeout)); | ||
258 | if (time_after_eq(jiffies, timeout)) | ||
259 | TIMEOUT_MSG(__LINE__); | ||
260 | return stat1; | ||
261 | } | ||
262 | |||
263 | static inline void set_hsf(struct net_device *dev, int hsf) | ||
264 | { | ||
265 | elp_device *adapter = dev->priv; | ||
266 | unsigned long flags; | ||
267 | |||
268 | spin_lock_irqsave(&adapter->lock, flags); | ||
269 | outb_control((HCR_VAL(dev) & ~HSF_PCB_MASK) | hsf, dev); | ||
270 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
271 | } | ||
272 | |||
273 | static int start_receive(struct net_device *, pcb_struct *); | ||
274 | |||
275 | inline static void adapter_reset(struct net_device *dev) | ||
276 | { | ||
277 | unsigned long timeout; | ||
278 | elp_device *adapter = dev->priv; | ||
279 | unsigned char orig_hcr = adapter->hcr_val; | ||
280 | |||
281 | outb_control(0, dev); | ||
282 | |||
283 | if (inb_status(dev->base_addr) & ACRF) { | ||
284 | do { | ||
285 | inb_command(dev->base_addr); | ||
286 | timeout = jiffies + 2*HZ/100; | ||
287 | while (time_before_eq(jiffies, timeout) && !(inb_status(dev->base_addr) & ACRF)); | ||
288 | } while (inb_status(dev->base_addr) & ACRF); | ||
289 | set_hsf(dev, HSF_PCB_NAK); | ||
290 | } | ||
291 | outb_control(adapter->hcr_val | ATTN | DIR, dev); | ||
292 | mdelay(10); | ||
293 | outb_control(adapter->hcr_val & ~ATTN, dev); | ||
294 | mdelay(10); | ||
295 | outb_control(adapter->hcr_val | FLSH, dev); | ||
296 | mdelay(10); | ||
297 | outb_control(adapter->hcr_val & ~FLSH, dev); | ||
298 | mdelay(10); | ||
299 | |||
300 | outb_control(orig_hcr, dev); | ||
301 | if (!start_receive(dev, &adapter->tx_pcb)) | ||
302 | printk(KERN_ERR "%s: start receive command failed \n", dev->name); | ||
303 | } | ||
304 | |||
305 | /* Check to make sure that a DMA transfer hasn't timed out. This should | ||
306 | * never happen in theory, but seems to occur occasionally if the card gets | ||
307 | * prodded at the wrong time. | ||
308 | */ | ||
309 | static inline void check_3c505_dma(struct net_device *dev) | ||
310 | { | ||
311 | elp_device *adapter = dev->priv; | ||
312 | if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) { | ||
313 | unsigned long flags, f; | ||
314 | printk(KERN_ERR "%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma)); | ||
315 | spin_lock_irqsave(&adapter->lock, flags); | ||
316 | adapter->dmaing = 0; | ||
317 | adapter->busy = 0; | ||
318 | |||
319 | f=claim_dma_lock(); | ||
320 | disable_dma(dev->dma); | ||
321 | release_dma_lock(f); | ||
322 | |||
323 | if (adapter->rx_active) | ||
324 | adapter->rx_active--; | ||
325 | outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev); | ||
326 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | /* Primitive functions used by send_pcb() */ | ||
331 | static inline unsigned int send_pcb_slow(unsigned int base_addr, unsigned char byte) | ||
332 | { | ||
333 | unsigned long timeout; | ||
334 | outb_command(byte, base_addr); | ||
335 | for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) { | ||
336 | if (inb_status(base_addr) & HCRE) | ||
337 | return FALSE; | ||
338 | } | ||
339 | printk(KERN_WARNING "3c505: send_pcb_slow timed out\n"); | ||
340 | return TRUE; | ||
341 | } | ||
342 | |||
343 | static inline unsigned int send_pcb_fast(unsigned int base_addr, unsigned char byte) | ||
344 | { | ||
345 | unsigned int timeout; | ||
346 | outb_command(byte, base_addr); | ||
347 | for (timeout = 0; timeout < 40000; timeout++) { | ||
348 | if (inb_status(base_addr) & HCRE) | ||
349 | return FALSE; | ||
350 | } | ||
351 | printk(KERN_WARNING "3c505: send_pcb_fast timed out\n"); | ||
352 | return TRUE; | ||
353 | } | ||
354 | |||
355 | /* Check to see if the receiver needs restarting, and kick it if so */ | ||
356 | static inline void prime_rx(struct net_device *dev) | ||
357 | { | ||
358 | elp_device *adapter = dev->priv; | ||
359 | while (adapter->rx_active < ELP_RX_PCBS && netif_running(dev)) { | ||
360 | if (!start_receive(dev, &adapter->itx_pcb)) | ||
361 | break; | ||
362 | } | ||
363 | } | ||
364 | |||
365 | /***************************************************************** | ||
366 | * | ||
367 | * send_pcb | ||
368 | * Send a PCB to the adapter. | ||
369 | * | ||
370 | * output byte to command reg --<--+ | ||
371 | * wait until HCRE is non zero | | ||
372 | * loop until all bytes sent -->--+ | ||
373 | * set HSF1 and HSF2 to 1 | ||
374 | * output pcb length | ||
375 | * wait until ASF give ACK or NAK | ||
376 | * set HSF1 and HSF2 to 0 | ||
377 | * | ||
378 | *****************************************************************/ | ||
379 | |||
380 | /* This can be quite slow -- the adapter is allowed to take up to 40ms | ||
381 | * to respond to the initial interrupt. | ||
382 | * | ||
383 | * We run initially with interrupts turned on, but with a semaphore set | ||
384 | * so that nobody tries to re-enter this code. Once the first byte has | ||
385 | * gone through, we turn interrupts off and then send the others (the | ||
386 | * timeout is reduced to 500us). | ||
387 | */ | ||
388 | |||
389 | static int send_pcb(struct net_device *dev, pcb_struct * pcb) | ||
390 | { | ||
391 | int i; | ||
392 | unsigned long timeout; | ||
393 | elp_device *adapter = dev->priv; | ||
394 | unsigned long flags; | ||
395 | |||
396 | check_3c505_dma(dev); | ||
397 | |||
398 | if (adapter->dmaing && adapter->current_dma.direction == 0) | ||
399 | return FALSE; | ||
400 | |||
401 | /* Avoid contention */ | ||
402 | if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) { | ||
403 | if (elp_debug >= 3) { | ||
404 | printk(KERN_DEBUG "%s: send_pcb entered while threaded\n", dev->name); | ||
405 | } | ||
406 | return FALSE; | ||
407 | } | ||
408 | /* | ||
409 | * load each byte into the command register and | ||
410 | * wait for the HCRE bit to indicate the adapter | ||
411 | * had read the byte | ||
412 | */ | ||
413 | set_hsf(dev, 0); | ||
414 | |||
415 | if (send_pcb_slow(dev->base_addr, pcb->command)) | ||
416 | goto abort; | ||
417 | |||
418 | spin_lock_irqsave(&adapter->lock, flags); | ||
419 | |||
420 | if (send_pcb_fast(dev->base_addr, pcb->length)) | ||
421 | goto sti_abort; | ||
422 | |||
423 | for (i = 0; i < pcb->length; i++) { | ||
424 | if (send_pcb_fast(dev->base_addr, pcb->data.raw[i])) | ||
425 | goto sti_abort; | ||
426 | } | ||
427 | |||
428 | outb_control(adapter->hcr_val | 3, dev); /* signal end of PCB */ | ||
429 | outb_command(2 + pcb->length, dev->base_addr); | ||
430 | |||
431 | /* now wait for the acknowledgement */ | ||
432 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
433 | |||
434 | for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) { | ||
435 | switch (GET_ASF(dev->base_addr)) { | ||
436 | case ASF_PCB_ACK: | ||
437 | adapter->send_pcb_semaphore = 0; | ||
438 | return TRUE; | ||
439 | |||
440 | case ASF_PCB_NAK: | ||
441 | #ifdef ELP_DEBUG | ||
442 | printk(KERN_DEBUG "%s: send_pcb got NAK\n", dev->name); | ||
443 | #endif | ||
444 | goto abort; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | if (elp_debug >= 1) | ||
449 | printk(KERN_DEBUG "%s: timeout waiting for PCB acknowledge (status %02x)\n", dev->name, inb_status(dev->base_addr)); | ||
450 | goto abort; | ||
451 | |||
452 | sti_abort: | ||
453 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
454 | abort: | ||
455 | adapter->send_pcb_semaphore = 0; | ||
456 | return FALSE; | ||
457 | } | ||
458 | |||
459 | |||
460 | /***************************************************************** | ||
461 | * | ||
462 | * receive_pcb | ||
463 | * Read a PCB from the adapter | ||
464 | * | ||
465 | * wait for ACRF to be non-zero ---<---+ | ||
466 | * input a byte | | ||
467 | * if ASF1 and ASF2 were not both one | | ||
468 | * before byte was read, loop --->---+ | ||
469 | * set HSF1 and HSF2 for ack | ||
470 | * | ||
471 | *****************************************************************/ | ||
472 | |||
473 | static int receive_pcb(struct net_device *dev, pcb_struct * pcb) | ||
474 | { | ||
475 | int i, j; | ||
476 | int total_length; | ||
477 | int stat; | ||
478 | unsigned long timeout; | ||
479 | unsigned long flags; | ||
480 | |||
481 | elp_device *adapter = dev->priv; | ||
482 | |||
483 | set_hsf(dev, 0); | ||
484 | |||
485 | /* get the command code */ | ||
486 | timeout = jiffies + 2*HZ/100; | ||
487 | while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout)); | ||
488 | if (time_after_eq(jiffies, timeout)) { | ||
489 | TIMEOUT_MSG(__LINE__); | ||
490 | return FALSE; | ||
491 | } | ||
492 | pcb->command = inb_command(dev->base_addr); | ||
493 | |||
494 | /* read the data length */ | ||
495 | timeout = jiffies + 3*HZ/100; | ||
496 | while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout)); | ||
497 | if (time_after_eq(jiffies, timeout)) { | ||
498 | TIMEOUT_MSG(__LINE__); | ||
499 | printk(KERN_INFO "%s: status %02x\n", dev->name, stat); | ||
500 | return FALSE; | ||
501 | } | ||
502 | pcb->length = inb_command(dev->base_addr); | ||
503 | |||
504 | if (pcb->length > MAX_PCB_DATA) { | ||
505 | INVALID_PCB_MSG(pcb->length); | ||
506 | adapter_reset(dev); | ||
507 | return FALSE; | ||
508 | } | ||
509 | /* read the data */ | ||
510 | spin_lock_irqsave(&adapter->lock, flags); | ||
511 | i = 0; | ||
512 | do { | ||
513 | j = 0; | ||
514 | while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000); | ||
515 | pcb->data.raw[i++] = inb_command(dev->base_addr); | ||
516 | if (i > MAX_PCB_DATA) | ||
517 | INVALID_PCB_MSG(i); | ||
518 | } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000); | ||
519 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
520 | if (j >= 20000) { | ||
521 | TIMEOUT_MSG(__LINE__); | ||
522 | return FALSE; | ||
523 | } | ||
524 | /* woops, the last "data" byte was really the length! */ | ||
525 | total_length = pcb->data.raw[--i]; | ||
526 | |||
527 | /* safety check total length vs data length */ | ||
528 | if (total_length != (pcb->length + 2)) { | ||
529 | if (elp_debug >= 2) | ||
530 | printk(KERN_WARNING "%s: mangled PCB received\n", dev->name); | ||
531 | set_hsf(dev, HSF_PCB_NAK); | ||
532 | return FALSE; | ||
533 | } | ||
534 | |||
535 | if (pcb->command == CMD_RECEIVE_PACKET_COMPLETE) { | ||
536 | if (test_and_set_bit(0, (void *) &adapter->busy)) { | ||
537 | if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) { | ||
538 | set_hsf(dev, HSF_PCB_NAK); | ||
539 | printk(KERN_WARNING "%s: PCB rejected, transfer in progress and backlog full\n", dev->name); | ||
540 | pcb->command = 0; | ||
541 | return TRUE; | ||
542 | } else { | ||
543 | pcb->command = 0xff; | ||
544 | } | ||
545 | } | ||
546 | } | ||
547 | set_hsf(dev, HSF_PCB_ACK); | ||
548 | return TRUE; | ||
549 | } | ||
550 | |||
551 | /****************************************************** | ||
552 | * | ||
553 | * queue a receive command on the adapter so we will get an | ||
554 | * interrupt when a packet is received. | ||
555 | * | ||
556 | ******************************************************/ | ||
557 | |||
558 | static int start_receive(struct net_device *dev, pcb_struct * tx_pcb) | ||
559 | { | ||
560 | int status; | ||
561 | elp_device *adapter = dev->priv; | ||
562 | |||
563 | if (elp_debug >= 3) | ||
564 | printk(KERN_DEBUG "%s: restarting receiver\n", dev->name); | ||
565 | tx_pcb->command = CMD_RECEIVE_PACKET; | ||
566 | tx_pcb->length = sizeof(struct Rcv_pkt); | ||
567 | tx_pcb->data.rcv_pkt.buf_seg | ||
568 | = tx_pcb->data.rcv_pkt.buf_ofs = 0; /* Unused */ | ||
569 | tx_pcb->data.rcv_pkt.buf_len = 1600; | ||
570 | tx_pcb->data.rcv_pkt.timeout = 0; /* set timeout to zero */ | ||
571 | status = send_pcb(dev, tx_pcb); | ||
572 | if (status) | ||
573 | adapter->rx_active++; | ||
574 | return status; | ||
575 | } | ||
576 | |||
577 | /****************************************************** | ||
578 | * | ||
579 | * extract a packet from the adapter | ||
580 | * this routine is only called from within the interrupt | ||
581 | * service routine, so no cli/sti calls are needed | ||
582 | * note that the length is always assumed to be even | ||
583 | * | ||
584 | ******************************************************/ | ||
585 | |||
586 | static void receive_packet(struct net_device *dev, int len) | ||
587 | { | ||
588 | int rlen; | ||
589 | elp_device *adapter = dev->priv; | ||
590 | void *target; | ||
591 | struct sk_buff *skb; | ||
592 | unsigned long flags; | ||
593 | |||
594 | rlen = (len + 1) & ~1; | ||
595 | skb = dev_alloc_skb(rlen + 2); | ||
596 | |||
597 | if (!skb) { | ||
598 | printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name); | ||
599 | target = adapter->dma_buffer; | ||
600 | adapter->current_dma.target = NULL; | ||
601 | /* FIXME: stats */ | ||
602 | return; | ||
603 | } | ||
604 | |||
605 | skb_reserve(skb, 2); | ||
606 | target = skb_put(skb, rlen); | ||
607 | if ((unsigned long)(target + rlen) >= MAX_DMA_ADDRESS) { | ||
608 | adapter->current_dma.target = target; | ||
609 | target = adapter->dma_buffer; | ||
610 | } else { | ||
611 | adapter->current_dma.target = NULL; | ||
612 | } | ||
613 | |||
614 | /* if this happens, we die */ | ||
615 | if (test_and_set_bit(0, (void *) &adapter->dmaing)) | ||
616 | printk(KERN_ERR "%s: rx blocked, DMA in progress, dir %d\n", dev->name, adapter->current_dma.direction); | ||
617 | |||
618 | skb->dev = dev; | ||
619 | adapter->current_dma.direction = 0; | ||
620 | adapter->current_dma.length = rlen; | ||
621 | adapter->current_dma.skb = skb; | ||
622 | adapter->current_dma.start_time = jiffies; | ||
623 | |||
624 | outb_control(adapter->hcr_val | DIR | TCEN | DMAE, dev); | ||
625 | |||
626 | flags=claim_dma_lock(); | ||
627 | disable_dma(dev->dma); | ||
628 | clear_dma_ff(dev->dma); | ||
629 | set_dma_mode(dev->dma, 0x04); /* dma read */ | ||
630 | set_dma_addr(dev->dma, isa_virt_to_bus(target)); | ||
631 | set_dma_count(dev->dma, rlen); | ||
632 | enable_dma(dev->dma); | ||
633 | release_dma_lock(flags); | ||
634 | |||
635 | if (elp_debug >= 3) { | ||
636 | printk(KERN_DEBUG "%s: rx DMA transfer started\n", dev->name); | ||
637 | } | ||
638 | |||
639 | if (adapter->rx_active) | ||
640 | adapter->rx_active--; | ||
641 | |||
642 | if (!adapter->busy) | ||
643 | printk(KERN_WARNING "%s: receive_packet called, busy not set.\n", dev->name); | ||
644 | } | ||
645 | |||
646 | /****************************************************** | ||
647 | * | ||
648 | * interrupt handler | ||
649 | * | ||
650 | ******************************************************/ | ||
651 | |||
652 | static irqreturn_t elp_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) | ||
653 | { | ||
654 | int len; | ||
655 | int dlen; | ||
656 | int icount = 0; | ||
657 | struct net_device *dev; | ||
658 | elp_device *adapter; | ||
659 | unsigned long timeout; | ||
660 | |||
661 | dev = dev_id; | ||
662 | adapter = (elp_device *) dev->priv; | ||
663 | |||
664 | spin_lock(&adapter->lock); | ||
665 | |||
666 | do { | ||
667 | /* | ||
668 | * has a DMA transfer finished? | ||
669 | */ | ||
670 | if (inb_status(dev->base_addr) & DONE) { | ||
671 | if (!adapter->dmaing) { | ||
672 | printk(KERN_WARNING "%s: phantom DMA completed\n", dev->name); | ||
673 | } | ||
674 | if (elp_debug >= 3) { | ||
675 | printk(KERN_DEBUG "%s: %s DMA complete, status %02x\n", dev->name, adapter->current_dma.direction ? "tx" : "rx", inb_status(dev->base_addr)); | ||
676 | } | ||
677 | |||
678 | outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev); | ||
679 | if (adapter->current_dma.direction) { | ||
680 | dev_kfree_skb_irq(adapter->current_dma.skb); | ||
681 | } else { | ||
682 | struct sk_buff *skb = adapter->current_dma.skb; | ||
683 | if (skb) { | ||
684 | if (adapter->current_dma.target) { | ||
685 | /* have already done the skb_put() */ | ||
686 | memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length); | ||
687 | } | ||
688 | skb->protocol = eth_type_trans(skb,dev); | ||
689 | adapter->stats.rx_bytes += skb->len; | ||
690 | netif_rx(skb); | ||
691 | dev->last_rx = jiffies; | ||
692 | } | ||
693 | } | ||
694 | adapter->dmaing = 0; | ||
695 | if (adapter->rx_backlog.in != adapter->rx_backlog.out) { | ||
696 | int t = adapter->rx_backlog.length[adapter->rx_backlog.out]; | ||
697 | adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out); | ||
698 | if (elp_debug >= 2) | ||
699 | printk(KERN_DEBUG "%s: receiving backlogged packet (%d)\n", dev->name, t); | ||
700 | receive_packet(dev, t); | ||
701 | } else { | ||
702 | adapter->busy = 0; | ||
703 | } | ||
704 | } else { | ||
705 | /* has one timed out? */ | ||
706 | check_3c505_dma(dev); | ||
707 | } | ||
708 | |||
709 | /* | ||
710 | * receive a PCB from the adapter | ||
711 | */ | ||
712 | timeout = jiffies + 3*HZ/100; | ||
713 | while ((inb_status(dev->base_addr) & ACRF) != 0 && time_before(jiffies, timeout)) { | ||
714 | if (receive_pcb(dev, &adapter->irx_pcb)) { | ||
715 | switch (adapter->irx_pcb.command) | ||
716 | { | ||
717 | case 0: | ||
718 | break; | ||
719 | /* | ||
720 | * received a packet - this must be handled fast | ||
721 | */ | ||
722 | case 0xff: | ||
723 | case CMD_RECEIVE_PACKET_COMPLETE: | ||
724 | /* if the device isn't open, don't pass packets up the stack */ | ||
725 | if (!netif_running(dev)) | ||
726 | break; | ||
727 | len = adapter->irx_pcb.data.rcv_resp.pkt_len; | ||
728 | dlen = adapter->irx_pcb.data.rcv_resp.buf_len; | ||
729 | if (adapter->irx_pcb.data.rcv_resp.timeout != 0) { | ||
730 | printk(KERN_ERR "%s: interrupt - packet not received correctly\n", dev->name); | ||
731 | } else { | ||
732 | if (elp_debug >= 3) { | ||
733 | printk(KERN_DEBUG "%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen); | ||
734 | } | ||
735 | if (adapter->irx_pcb.command == 0xff) { | ||
736 | if (elp_debug >= 2) | ||
737 | printk(KERN_DEBUG "%s: adding packet to backlog (len = %d)\n", dev->name, dlen); | ||
738 | adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen; | ||
739 | adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in); | ||
740 | } else { | ||
741 | receive_packet(dev, dlen); | ||
742 | } | ||
743 | if (elp_debug >= 3) | ||
744 | printk(KERN_DEBUG "%s: packet received\n", dev->name); | ||
745 | } | ||
746 | break; | ||
747 | |||
748 | /* | ||
749 | * 82586 configured correctly | ||
750 | */ | ||
751 | case CMD_CONFIGURE_82586_RESPONSE: | ||
752 | adapter->got[CMD_CONFIGURE_82586] = 1; | ||
753 | if (elp_debug >= 3) | ||
754 | printk(KERN_DEBUG "%s: interrupt - configure response received\n", dev->name); | ||
755 | break; | ||
756 | |||
757 | /* | ||
758 | * Adapter memory configuration | ||
759 | */ | ||
760 | case CMD_CONFIGURE_ADAPTER_RESPONSE: | ||
761 | adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1; | ||
762 | if (elp_debug >= 3) | ||
763 | printk(KERN_DEBUG "%s: Adapter memory configuration %s.\n", dev->name, | ||
764 | adapter->irx_pcb.data.failed ? "failed" : "succeeded"); | ||
765 | break; | ||
766 | |||
767 | /* | ||
768 | * Multicast list loading | ||
769 | */ | ||
770 | case CMD_LOAD_MULTICAST_RESPONSE: | ||
771 | adapter->got[CMD_LOAD_MULTICAST_LIST] = 1; | ||
772 | if (elp_debug >= 3) | ||
773 | printk(KERN_DEBUG "%s: Multicast address list loading %s.\n", dev->name, | ||
774 | adapter->irx_pcb.data.failed ? "failed" : "succeeded"); | ||
775 | break; | ||
776 | |||
777 | /* | ||
778 | * Station address setting | ||
779 | */ | ||
780 | case CMD_SET_ADDRESS_RESPONSE: | ||
781 | adapter->got[CMD_SET_STATION_ADDRESS] = 1; | ||
782 | if (elp_debug >= 3) | ||
783 | printk(KERN_DEBUG "%s: Ethernet address setting %s.\n", dev->name, | ||
784 | adapter->irx_pcb.data.failed ? "failed" : "succeeded"); | ||
785 | break; | ||
786 | |||
787 | |||
788 | /* | ||
789 | * received board statistics | ||
790 | */ | ||
791 | case CMD_NETWORK_STATISTICS_RESPONSE: | ||
792 | adapter->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv; | ||
793 | adapter->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit; | ||
794 | adapter->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC; | ||
795 | adapter->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align; | ||
796 | adapter->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun; | ||
797 | adapter->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res; | ||
798 | adapter->got[CMD_NETWORK_STATISTICS] = 1; | ||
799 | if (elp_debug >= 3) | ||
800 | printk(KERN_DEBUG "%s: interrupt - statistics response received\n", dev->name); | ||
801 | break; | ||
802 | |||
803 | /* | ||
804 | * sent a packet | ||
805 | */ | ||
806 | case CMD_TRANSMIT_PACKET_COMPLETE: | ||
807 | if (elp_debug >= 3) | ||
808 | printk(KERN_DEBUG "%s: interrupt - packet sent\n", dev->name); | ||
809 | if (!netif_running(dev)) | ||
810 | break; | ||
811 | switch (adapter->irx_pcb.data.xmit_resp.c_stat) { | ||
812 | case 0xffff: | ||
813 | adapter->stats.tx_aborted_errors++; | ||
814 | printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name); | ||
815 | break; | ||
816 | case 0xfffe: | ||
817 | adapter->stats.tx_fifo_errors++; | ||
818 | printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name); | ||
819 | break; | ||
820 | } | ||
821 | netif_wake_queue(dev); | ||
822 | break; | ||
823 | |||
824 | /* | ||
825 | * some unknown PCB | ||
826 | */ | ||
827 | default: | ||
828 | printk(KERN_DEBUG "%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command); | ||
829 | break; | ||
830 | } | ||
831 | } else { | ||
832 | printk(KERN_WARNING "%s: failed to read PCB on interrupt\n", dev->name); | ||
833 | adapter_reset(dev); | ||
834 | } | ||
835 | } | ||
836 | |||
837 | } while (icount++ < 5 && (inb_status(dev->base_addr) & (ACRF | DONE))); | ||
838 | |||
839 | prime_rx(dev); | ||
840 | |||
841 | /* | ||
842 | * indicate no longer in interrupt routine | ||
843 | */ | ||
844 | spin_unlock(&adapter->lock); | ||
845 | return IRQ_HANDLED; | ||
846 | } | ||
847 | |||
848 | |||
849 | /****************************************************** | ||
850 | * | ||
851 | * open the board | ||
852 | * | ||
853 | ******************************************************/ | ||
854 | |||
855 | static int elp_open(struct net_device *dev) | ||
856 | { | ||
857 | elp_device *adapter; | ||
858 | int retval; | ||
859 | |||
860 | adapter = dev->priv; | ||
861 | |||
862 | if (elp_debug >= 3) | ||
863 | printk(KERN_DEBUG "%s: request to open device\n", dev->name); | ||
864 | |||
865 | /* | ||
866 | * make sure we actually found the device | ||
867 | */ | ||
868 | if (adapter == NULL) { | ||
869 | printk(KERN_ERR "%s: Opening a non-existent physical device\n", dev->name); | ||
870 | return -EAGAIN; | ||
871 | } | ||
872 | /* | ||
873 | * disable interrupts on the board | ||
874 | */ | ||
875 | outb_control(0, dev); | ||
876 | |||
877 | /* | ||
878 | * clear any pending interrupts | ||
879 | */ | ||
880 | inb_command(dev->base_addr); | ||
881 | adapter_reset(dev); | ||
882 | |||
883 | /* | ||
884 | * no receive PCBs active | ||
885 | */ | ||
886 | adapter->rx_active = 0; | ||
887 | |||
888 | adapter->busy = 0; | ||
889 | adapter->send_pcb_semaphore = 0; | ||
890 | adapter->rx_backlog.in = 0; | ||
891 | adapter->rx_backlog.out = 0; | ||
892 | |||
893 | spin_lock_init(&adapter->lock); | ||
894 | |||
895 | /* | ||
896 | * install our interrupt service routine | ||
897 | */ | ||
898 | if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) { | ||
899 | printk(KERN_ERR "%s: could not allocate IRQ%d\n", dev->name, dev->irq); | ||
900 | return retval; | ||
901 | } | ||
902 | if ((retval = request_dma(dev->dma, dev->name))) { | ||
903 | free_irq(dev->irq, dev); | ||
904 | printk(KERN_ERR "%s: could not allocate DMA%d channel\n", dev->name, dev->dma); | ||
905 | return retval; | ||
906 | } | ||
907 | adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE); | ||
908 | if (!adapter->dma_buffer) { | ||
909 | printk(KERN_ERR "%s: could not allocate DMA buffer\n", dev->name); | ||
910 | free_dma(dev->dma); | ||
911 | free_irq(dev->irq, dev); | ||
912 | return -ENOMEM; | ||
913 | } | ||
914 | adapter->dmaing = 0; | ||
915 | |||
916 | /* | ||
917 | * enable interrupts on the board | ||
918 | */ | ||
919 | outb_control(CMDE, dev); | ||
920 | |||
921 | /* | ||
922 | * configure adapter memory: we need 10 multicast addresses, default==0 | ||
923 | */ | ||
924 | if (elp_debug >= 3) | ||
925 | printk(KERN_DEBUG "%s: sending 3c505 memory configuration command\n", dev->name); | ||
926 | adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; | ||
927 | adapter->tx_pcb.data.memconf.cmd_q = 10; | ||
928 | adapter->tx_pcb.data.memconf.rcv_q = 20; | ||
929 | adapter->tx_pcb.data.memconf.mcast = 10; | ||
930 | adapter->tx_pcb.data.memconf.frame = 20; | ||
931 | adapter->tx_pcb.data.memconf.rcv_b = 20; | ||
932 | adapter->tx_pcb.data.memconf.progs = 0; | ||
933 | adapter->tx_pcb.length = sizeof(struct Memconf); | ||
934 | adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0; | ||
935 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
936 | printk(KERN_ERR "%s: couldn't send memory configuration command\n", dev->name); | ||
937 | else { | ||
938 | unsigned long timeout = jiffies + TIMEOUT; | ||
939 | while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout)); | ||
940 | if (time_after_eq(jiffies, timeout)) | ||
941 | TIMEOUT_MSG(__LINE__); | ||
942 | } | ||
943 | |||
944 | |||
945 | /* | ||
946 | * configure adapter to receive broadcast messages and wait for response | ||
947 | */ | ||
948 | if (elp_debug >= 3) | ||
949 | printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name); | ||
950 | adapter->tx_pcb.command = CMD_CONFIGURE_82586; | ||
951 | adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; | ||
952 | adapter->tx_pcb.length = 2; | ||
953 | adapter->got[CMD_CONFIGURE_82586] = 0; | ||
954 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
955 | printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name); | ||
956 | else { | ||
957 | unsigned long timeout = jiffies + TIMEOUT; | ||
958 | while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); | ||
959 | if (time_after_eq(jiffies, timeout)) | ||
960 | TIMEOUT_MSG(__LINE__); | ||
961 | } | ||
962 | |||
963 | /* enable burst-mode DMA */ | ||
964 | /* outb(0x1, dev->base_addr + PORT_AUXDMA); */ | ||
965 | |||
966 | /* | ||
967 | * queue receive commands to provide buffering | ||
968 | */ | ||
969 | prime_rx(dev); | ||
970 | if (elp_debug >= 3) | ||
971 | printk(KERN_DEBUG "%s: %d receive PCBs active\n", dev->name, adapter->rx_active); | ||
972 | |||
973 | /* | ||
974 | * device is now officially open! | ||
975 | */ | ||
976 | |||
977 | netif_start_queue(dev); | ||
978 | return 0; | ||
979 | } | ||
980 | |||
981 | |||
982 | /****************************************************** | ||
983 | * | ||
984 | * send a packet to the adapter | ||
985 | * | ||
986 | ******************************************************/ | ||
987 | |||
988 | static int send_packet(struct net_device *dev, struct sk_buff *skb) | ||
989 | { | ||
990 | elp_device *adapter = dev->priv; | ||
991 | unsigned long target; | ||
992 | unsigned long flags; | ||
993 | |||
994 | /* | ||
995 | * make sure the length is even and no shorter than 60 bytes | ||
996 | */ | ||
997 | unsigned int nlen = (((skb->len < 60) ? 60 : skb->len) + 1) & (~1); | ||
998 | |||
999 | if (test_and_set_bit(0, (void *) &adapter->busy)) { | ||
1000 | if (elp_debug >= 2) | ||
1001 | printk(KERN_DEBUG "%s: transmit blocked\n", dev->name); | ||
1002 | return FALSE; | ||
1003 | } | ||
1004 | |||
1005 | adapter->stats.tx_bytes += nlen; | ||
1006 | |||
1007 | /* | ||
1008 | * send the adapter a transmit packet command. Ignore segment and offset | ||
1009 | * and make sure the length is even | ||
1010 | */ | ||
1011 | adapter->tx_pcb.command = CMD_TRANSMIT_PACKET; | ||
1012 | adapter->tx_pcb.length = sizeof(struct Xmit_pkt); | ||
1013 | adapter->tx_pcb.data.xmit_pkt.buf_ofs | ||
1014 | = adapter->tx_pcb.data.xmit_pkt.buf_seg = 0; /* Unused */ | ||
1015 | adapter->tx_pcb.data.xmit_pkt.pkt_len = nlen; | ||
1016 | |||
1017 | if (!send_pcb(dev, &adapter->tx_pcb)) { | ||
1018 | adapter->busy = 0; | ||
1019 | return FALSE; | ||
1020 | } | ||
1021 | /* if this happens, we die */ | ||
1022 | if (test_and_set_bit(0, (void *) &adapter->dmaing)) | ||
1023 | printk(KERN_DEBUG "%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction); | ||
1024 | |||
1025 | adapter->current_dma.direction = 1; | ||
1026 | adapter->current_dma.start_time = jiffies; | ||
1027 | |||
1028 | if ((unsigned long)(skb->data + nlen) >= MAX_DMA_ADDRESS || nlen != skb->len) { | ||
1029 | memcpy(adapter->dma_buffer, skb->data, nlen); | ||
1030 | memset(adapter->dma_buffer+skb->len, 0, nlen-skb->len); | ||
1031 | target = isa_virt_to_bus(adapter->dma_buffer); | ||
1032 | } | ||
1033 | else { | ||
1034 | target = isa_virt_to_bus(skb->data); | ||
1035 | } | ||
1036 | adapter->current_dma.skb = skb; | ||
1037 | |||
1038 | flags=claim_dma_lock(); | ||
1039 | disable_dma(dev->dma); | ||
1040 | clear_dma_ff(dev->dma); | ||
1041 | set_dma_mode(dev->dma, 0x48); /* dma memory -> io */ | ||
1042 | set_dma_addr(dev->dma, target); | ||
1043 | set_dma_count(dev->dma, nlen); | ||
1044 | outb_control(adapter->hcr_val | DMAE | TCEN, dev); | ||
1045 | enable_dma(dev->dma); | ||
1046 | release_dma_lock(flags); | ||
1047 | |||
1048 | if (elp_debug >= 3) | ||
1049 | printk(KERN_DEBUG "%s: DMA transfer started\n", dev->name); | ||
1050 | |||
1051 | return TRUE; | ||
1052 | } | ||
1053 | |||
1054 | /* | ||
1055 | * The upper layer thinks we timed out | ||
1056 | */ | ||
1057 | |||
1058 | static void elp_timeout(struct net_device *dev) | ||
1059 | { | ||
1060 | elp_device *adapter = dev->priv; | ||
1061 | int stat; | ||
1062 | |||
1063 | stat = inb_status(dev->base_addr); | ||
1064 | printk(KERN_WARNING "%s: transmit timed out, lost %s?\n", dev->name, (stat & ACRF) ? "interrupt" : "command"); | ||
1065 | if (elp_debug >= 1) | ||
1066 | printk(KERN_DEBUG "%s: status %#02x\n", dev->name, stat); | ||
1067 | dev->trans_start = jiffies; | ||
1068 | adapter->stats.tx_dropped++; | ||
1069 | netif_wake_queue(dev); | ||
1070 | } | ||
1071 | |||
1072 | /****************************************************** | ||
1073 | * | ||
1074 | * start the transmitter | ||
1075 | * return 0 if sent OK, else return 1 | ||
1076 | * | ||
1077 | ******************************************************/ | ||
1078 | |||
1079 | static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
1080 | { | ||
1081 | unsigned long flags; | ||
1082 | elp_device *adapter = dev->priv; | ||
1083 | |||
1084 | spin_lock_irqsave(&adapter->lock, flags); | ||
1085 | check_3c505_dma(dev); | ||
1086 | |||
1087 | if (elp_debug >= 3) | ||
1088 | printk(KERN_DEBUG "%s: request to send packet of length %d\n", dev->name, (int) skb->len); | ||
1089 | |||
1090 | netif_stop_queue(dev); | ||
1091 | |||
1092 | /* | ||
1093 | * send the packet at skb->data for skb->len | ||
1094 | */ | ||
1095 | if (!send_packet(dev, skb)) { | ||
1096 | if (elp_debug >= 2) { | ||
1097 | printk(KERN_DEBUG "%s: failed to transmit packet\n", dev->name); | ||
1098 | } | ||
1099 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
1100 | return 1; | ||
1101 | } | ||
1102 | if (elp_debug >= 3) | ||
1103 | printk(KERN_DEBUG "%s: packet of length %d sent\n", dev->name, (int) skb->len); | ||
1104 | |||
1105 | /* | ||
1106 | * start the transmit timeout | ||
1107 | */ | ||
1108 | dev->trans_start = jiffies; | ||
1109 | |||
1110 | prime_rx(dev); | ||
1111 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
1112 | netif_start_queue(dev); | ||
1113 | return 0; | ||
1114 | } | ||
1115 | |||
1116 | /****************************************************** | ||
1117 | * | ||
1118 | * return statistics on the board | ||
1119 | * | ||
1120 | ******************************************************/ | ||
1121 | |||
1122 | static struct net_device_stats *elp_get_stats(struct net_device *dev) | ||
1123 | { | ||
1124 | elp_device *adapter = (elp_device *) dev->priv; | ||
1125 | |||
1126 | if (elp_debug >= 3) | ||
1127 | printk(KERN_DEBUG "%s: request for stats\n", dev->name); | ||
1128 | |||
1129 | /* If the device is closed, just return the latest stats we have, | ||
1130 | - we cannot ask from the adapter without interrupts */ | ||
1131 | if (!netif_running(dev)) | ||
1132 | return &adapter->stats; | ||
1133 | |||
1134 | /* send a get statistics command to the board */ | ||
1135 | adapter->tx_pcb.command = CMD_NETWORK_STATISTICS; | ||
1136 | adapter->tx_pcb.length = 0; | ||
1137 | adapter->got[CMD_NETWORK_STATISTICS] = 0; | ||
1138 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
1139 | printk(KERN_ERR "%s: couldn't send get statistics command\n", dev->name); | ||
1140 | else { | ||
1141 | unsigned long timeout = jiffies + TIMEOUT; | ||
1142 | while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout)); | ||
1143 | if (time_after_eq(jiffies, timeout)) { | ||
1144 | TIMEOUT_MSG(__LINE__); | ||
1145 | return &adapter->stats; | ||
1146 | } | ||
1147 | } | ||
1148 | |||
1149 | /* statistics are now up to date */ | ||
1150 | return &adapter->stats; | ||
1151 | } | ||
1152 | |||
1153 | |||
1154 | static void netdev_get_drvinfo(struct net_device *dev, | ||
1155 | struct ethtool_drvinfo *info) | ||
1156 | { | ||
1157 | strcpy(info->driver, DRV_NAME); | ||
1158 | strcpy(info->version, DRV_VERSION); | ||
1159 | sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); | ||
1160 | } | ||
1161 | |||
1162 | static u32 netdev_get_msglevel(struct net_device *dev) | ||
1163 | { | ||
1164 | return debug; | ||
1165 | } | ||
1166 | |||
1167 | static void netdev_set_msglevel(struct net_device *dev, u32 level) | ||
1168 | { | ||
1169 | debug = level; | ||
1170 | } | ||
1171 | |||
1172 | static struct ethtool_ops netdev_ethtool_ops = { | ||
1173 | .get_drvinfo = netdev_get_drvinfo, | ||
1174 | .get_msglevel = netdev_get_msglevel, | ||
1175 | .set_msglevel = netdev_set_msglevel, | ||
1176 | }; | ||
1177 | |||
1178 | /****************************************************** | ||
1179 | * | ||
1180 | * close the board | ||
1181 | * | ||
1182 | ******************************************************/ | ||
1183 | |||
1184 | static int elp_close(struct net_device *dev) | ||
1185 | { | ||
1186 | elp_device *adapter; | ||
1187 | |||
1188 | adapter = dev->priv; | ||
1189 | |||
1190 | if (elp_debug >= 3) | ||
1191 | printk(KERN_DEBUG "%s: request to close device\n", dev->name); | ||
1192 | |||
1193 | netif_stop_queue(dev); | ||
1194 | |||
1195 | /* Someone may request the device statistic information even when | ||
1196 | * the interface is closed. The following will update the statistics | ||
1197 | * structure in the driver, so we'll be able to give current statistics. | ||
1198 | */ | ||
1199 | (void) elp_get_stats(dev); | ||
1200 | |||
1201 | /* | ||
1202 | * disable interrupts on the board | ||
1203 | */ | ||
1204 | outb_control(0, dev); | ||
1205 | |||
1206 | /* | ||
1207 | * release the IRQ | ||
1208 | */ | ||
1209 | free_irq(dev->irq, dev); | ||
1210 | |||
1211 | free_dma(dev->dma); | ||
1212 | free_pages((unsigned long) adapter->dma_buffer, get_order(DMA_BUFFER_SIZE)); | ||
1213 | |||
1214 | return 0; | ||
1215 | } | ||
1216 | |||
1217 | |||
1218 | /************************************************************ | ||
1219 | * | ||
1220 | * Set multicast list | ||
1221 | * num_addrs==0: clear mc_list | ||
1222 | * num_addrs==-1: set promiscuous mode | ||
1223 | * num_addrs>0: set mc_list | ||
1224 | * | ||
1225 | ************************************************************/ | ||
1226 | |||
1227 | static void elp_set_mc_list(struct net_device *dev) | ||
1228 | { | ||
1229 | elp_device *adapter = (elp_device *) dev->priv; | ||
1230 | struct dev_mc_list *dmi = dev->mc_list; | ||
1231 | int i; | ||
1232 | unsigned long flags; | ||
1233 | |||
1234 | if (elp_debug >= 3) | ||
1235 | printk(KERN_DEBUG "%s: request to set multicast list\n", dev->name); | ||
1236 | |||
1237 | spin_lock_irqsave(&adapter->lock, flags); | ||
1238 | |||
1239 | if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) { | ||
1240 | /* send a "load multicast list" command to the board, max 10 addrs/cmd */ | ||
1241 | /* if num_addrs==0 the list will be cleared */ | ||
1242 | adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST; | ||
1243 | adapter->tx_pcb.length = 6 * dev->mc_count; | ||
1244 | for (i = 0; i < dev->mc_count; i++) { | ||
1245 | memcpy(adapter->tx_pcb.data.multicast[i], dmi->dmi_addr, 6); | ||
1246 | dmi = dmi->next; | ||
1247 | } | ||
1248 | adapter->got[CMD_LOAD_MULTICAST_LIST] = 0; | ||
1249 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
1250 | printk(KERN_ERR "%s: couldn't send set_multicast command\n", dev->name); | ||
1251 | else { | ||
1252 | unsigned long timeout = jiffies + TIMEOUT; | ||
1253 | while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout)); | ||
1254 | if (time_after_eq(jiffies, timeout)) { | ||
1255 | TIMEOUT_MSG(__LINE__); | ||
1256 | } | ||
1257 | } | ||
1258 | if (dev->mc_count) | ||
1259 | adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI; | ||
1260 | else /* num_addrs == 0 */ | ||
1261 | adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; | ||
1262 | } else | ||
1263 | adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC; | ||
1264 | /* | ||
1265 | * configure adapter to receive messages (as specified above) | ||
1266 | * and wait for response | ||
1267 | */ | ||
1268 | if (elp_debug >= 3) | ||
1269 | printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name); | ||
1270 | adapter->tx_pcb.command = CMD_CONFIGURE_82586; | ||
1271 | adapter->tx_pcb.length = 2; | ||
1272 | adapter->got[CMD_CONFIGURE_82586] = 0; | ||
1273 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
1274 | { | ||
1275 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
1276 | printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name); | ||
1277 | } | ||
1278 | else { | ||
1279 | unsigned long timeout = jiffies + TIMEOUT; | ||
1280 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
1281 | while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); | ||
1282 | if (time_after_eq(jiffies, timeout)) | ||
1283 | TIMEOUT_MSG(__LINE__); | ||
1284 | } | ||
1285 | } | ||
1286 | |||
1287 | /************************************************************ | ||
1288 | * | ||
1289 | * A couple of tests to see if there's 3C505 or not | ||
1290 | * Called only by elp_autodetect | ||
1291 | ************************************************************/ | ||
1292 | |||
1293 | static int __init elp_sense(struct net_device *dev) | ||
1294 | { | ||
1295 | int addr = dev->base_addr; | ||
1296 | const char *name = dev->name; | ||
1297 | byte orig_HSR; | ||
1298 | |||
1299 | if (!request_region(addr, ELP_IO_EXTENT, "3c505")) | ||
1300 | return -ENODEV; | ||
1301 | |||
1302 | orig_HSR = inb_status(addr); | ||
1303 | |||
1304 | if (elp_debug > 0) | ||
1305 | printk(search_msg, name, addr); | ||
1306 | |||
1307 | if (orig_HSR == 0xff) { | ||
1308 | if (elp_debug > 0) | ||
1309 | printk(notfound_msg, 1); | ||
1310 | goto out; | ||
1311 | } | ||
1312 | |||
1313 | /* Wait for a while; the adapter may still be booting up */ | ||
1314 | if (elp_debug > 0) | ||
1315 | printk(stilllooking_msg); | ||
1316 | |||
1317 | if (orig_HSR & DIR) { | ||
1318 | /* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */ | ||
1319 | outb(0, dev->base_addr + PORT_CONTROL); | ||
1320 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
1321 | schedule_timeout(30*HZ/100); | ||
1322 | if (inb_status(addr) & DIR) { | ||
1323 | if (elp_debug > 0) | ||
1324 | printk(notfound_msg, 2); | ||
1325 | goto out; | ||
1326 | } | ||
1327 | } else { | ||
1328 | /* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */ | ||
1329 | outb(DIR, dev->base_addr + PORT_CONTROL); | ||
1330 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
1331 | schedule_timeout(30*HZ/100); | ||
1332 | if (!(inb_status(addr) & DIR)) { | ||
1333 | if (elp_debug > 0) | ||
1334 | printk(notfound_msg, 3); | ||
1335 | goto out; | ||
1336 | } | ||
1337 | } | ||
1338 | /* | ||
1339 | * It certainly looks like a 3c505. | ||
1340 | */ | ||
1341 | if (elp_debug > 0) | ||
1342 | printk(found_msg); | ||
1343 | |||
1344 | return 0; | ||
1345 | out: | ||
1346 | release_region(addr, ELP_IO_EXTENT); | ||
1347 | return -ENODEV; | ||
1348 | } | ||
1349 | |||
1350 | /************************************************************* | ||
1351 | * | ||
1352 | * Search through addr_list[] and try to find a 3C505 | ||
1353 | * Called only by eplus_probe | ||
1354 | *************************************************************/ | ||
1355 | |||
1356 | static int __init elp_autodetect(struct net_device *dev) | ||
1357 | { | ||
1358 | int idx = 0; | ||
1359 | |||
1360 | /* if base address set, then only check that address | ||
1361 | otherwise, run through the table */ | ||
1362 | if (dev->base_addr != 0) { /* dev->base_addr == 0 ==> plain autodetect */ | ||
1363 | if (elp_sense(dev) == 0) | ||
1364 | return dev->base_addr; | ||
1365 | } else | ||
1366 | while ((dev->base_addr = addr_list[idx++])) { | ||
1367 | if (elp_sense(dev) == 0) | ||
1368 | return dev->base_addr; | ||
1369 | } | ||
1370 | |||
1371 | /* could not find an adapter */ | ||
1372 | if (elp_debug > 0) | ||
1373 | printk(couldnot_msg, dev->name); | ||
1374 | |||
1375 | return 0; /* Because of this, the layer above will return -ENODEV */ | ||
1376 | } | ||
1377 | |||
1378 | |||
1379 | /****************************************************** | ||
1380 | * | ||
1381 | * probe for an Etherlink Plus board at the specified address | ||
1382 | * | ||
1383 | ******************************************************/ | ||
1384 | |||
1385 | /* There are three situations we need to be able to detect here: | ||
1386 | |||
1387 | * a) the card is idle | ||
1388 | * b) the card is still booting up | ||
1389 | * c) the card is stuck in a strange state (some DOS drivers do this) | ||
1390 | * | ||
1391 | * In case (a), all is well. In case (b), we wait 10 seconds to see if the | ||
1392 | * card finishes booting, and carry on if so. In case (c), we do a hard reset, | ||
1393 | * loop round, and hope for the best. | ||
1394 | * | ||
1395 | * This is all very unpleasant, but hopefully avoids the problems with the old | ||
1396 | * probe code (which had a 15-second delay if the card was idle, and didn't | ||
1397 | * work at all if it was in a weird state). | ||
1398 | */ | ||
1399 | |||
1400 | static int __init elplus_setup(struct net_device *dev) | ||
1401 | { | ||
1402 | elp_device *adapter = dev->priv; | ||
1403 | int i, tries, tries1, okay; | ||
1404 | unsigned long timeout; | ||
1405 | unsigned long cookie = 0; | ||
1406 | int err = -ENODEV; | ||
1407 | |||
1408 | SET_MODULE_OWNER(dev); | ||
1409 | |||
1410 | /* | ||
1411 | * setup adapter structure | ||
1412 | */ | ||
1413 | |||
1414 | dev->base_addr = elp_autodetect(dev); | ||
1415 | if (!dev->base_addr) | ||
1416 | return -ENODEV; | ||
1417 | |||
1418 | adapter->send_pcb_semaphore = 0; | ||
1419 | |||
1420 | for (tries1 = 0; tries1 < 3; tries1++) { | ||
1421 | outb_control((adapter->hcr_val | CMDE) & ~DIR, dev); | ||
1422 | /* First try to write just one byte, to see if the card is | ||
1423 | * responding at all normally. | ||
1424 | */ | ||
1425 | timeout = jiffies + 5*HZ/100; | ||
1426 | okay = 0; | ||
1427 | while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); | ||
1428 | if ((inb_status(dev->base_addr) & HCRE)) { | ||
1429 | outb_command(0, dev->base_addr); /* send a spurious byte */ | ||
1430 | timeout = jiffies + 5*HZ/100; | ||
1431 | while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); | ||
1432 | if (inb_status(dev->base_addr) & HCRE) | ||
1433 | okay = 1; | ||
1434 | } | ||
1435 | if (!okay) { | ||
1436 | /* Nope, it's ignoring the command register. This means that | ||
1437 | * either it's still booting up, or it's died. | ||
1438 | */ | ||
1439 | printk(KERN_ERR "%s: command register wouldn't drain, ", dev->name); | ||
1440 | if ((inb_status(dev->base_addr) & 7) == 3) { | ||
1441 | /* If the adapter status is 3, it *could* still be booting. | ||
1442 | * Give it the benefit of the doubt for 10 seconds. | ||
1443 | */ | ||
1444 | printk("assuming 3c505 still starting\n"); | ||
1445 | timeout = jiffies + 10*HZ; | ||
1446 | while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7)); | ||
1447 | if (inb_status(dev->base_addr) & 7) { | ||
1448 | printk(KERN_ERR "%s: 3c505 failed to start\n", dev->name); | ||
1449 | } else { | ||
1450 | okay = 1; /* It started */ | ||
1451 | } | ||
1452 | } else { | ||
1453 | /* Otherwise, it must just be in a strange | ||
1454 | * state. We probably need to kick it. | ||
1455 | */ | ||
1456 | printk("3c505 is sulking\n"); | ||
1457 | } | ||
1458 | } | ||
1459 | for (tries = 0; tries < 5 && okay; tries++) { | ||
1460 | |||
1461 | /* | ||
1462 | * Try to set the Ethernet address, to make sure that the board | ||
1463 | * is working. | ||
1464 | */ | ||
1465 | adapter->tx_pcb.command = CMD_STATION_ADDRESS; | ||
1466 | adapter->tx_pcb.length = 0; | ||
1467 | cookie = probe_irq_on(); | ||
1468 | if (!send_pcb(dev, &adapter->tx_pcb)) { | ||
1469 | printk(KERN_ERR "%s: could not send first PCB\n", dev->name); | ||
1470 | probe_irq_off(cookie); | ||
1471 | continue; | ||
1472 | } | ||
1473 | if (!receive_pcb(dev, &adapter->rx_pcb)) { | ||
1474 | printk(KERN_ERR "%s: could not read first PCB\n", dev->name); | ||
1475 | probe_irq_off(cookie); | ||
1476 | continue; | ||
1477 | } | ||
1478 | if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) || | ||
1479 | (adapter->rx_pcb.length != 6)) { | ||
1480 | printk(KERN_ERR "%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length); | ||
1481 | probe_irq_off(cookie); | ||
1482 | continue; | ||
1483 | } | ||
1484 | goto okay; | ||
1485 | } | ||
1486 | /* It's broken. Do a hard reset to re-initialise the board, | ||
1487 | * and try again. | ||
1488 | */ | ||
1489 | printk(KERN_INFO "%s: resetting adapter\n", dev->name); | ||
1490 | outb_control(adapter->hcr_val | FLSH | ATTN, dev); | ||
1491 | outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev); | ||
1492 | } | ||
1493 | printk(KERN_ERR "%s: failed to initialise 3c505\n", dev->name); | ||
1494 | goto out; | ||
1495 | |||
1496 | okay: | ||
1497 | if (dev->irq) { /* Is there a preset IRQ? */ | ||
1498 | int rpt = probe_irq_off(cookie); | ||
1499 | if (dev->irq != rpt) { | ||
1500 | printk(KERN_WARNING "%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt); | ||
1501 | } | ||
1502 | /* if dev->irq == probe_irq_off(cookie), all is well */ | ||
1503 | } else /* No preset IRQ; just use what we can detect */ | ||
1504 | dev->irq = probe_irq_off(cookie); | ||
1505 | switch (dev->irq) { /* Legal, sane? */ | ||
1506 | case 0: | ||
1507 | printk(KERN_ERR "%s: IRQ probe failed: check 3c505 jumpers.\n", | ||
1508 | dev->name); | ||
1509 | goto out; | ||
1510 | case 1: | ||
1511 | case 6: | ||
1512 | case 8: | ||
1513 | case 13: | ||
1514 | printk(KERN_ERR "%s: Impossible IRQ %d reported by probe_irq_off().\n", | ||
1515 | dev->name, dev->irq); | ||
1516 | goto out; | ||
1517 | } | ||
1518 | /* | ||
1519 | * Now we have the IRQ number so we can disable the interrupts from | ||
1520 | * the board until the board is opened. | ||
1521 | */ | ||
1522 | outb_control(adapter->hcr_val & ~CMDE, dev); | ||
1523 | |||
1524 | /* | ||
1525 | * copy Ethernet address into structure | ||
1526 | */ | ||
1527 | for (i = 0; i < 6; i++) | ||
1528 | dev->dev_addr[i] = adapter->rx_pcb.data.eth_addr[i]; | ||
1529 | |||
1530 | /* find a DMA channel */ | ||
1531 | if (!dev->dma) { | ||
1532 | if (dev->mem_start) { | ||
1533 | dev->dma = dev->mem_start & 7; | ||
1534 | } | ||
1535 | else { | ||
1536 | printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name); | ||
1537 | dev->dma = ELP_DMA; | ||
1538 | } | ||
1539 | } | ||
1540 | |||
1541 | /* | ||
1542 | * print remainder of startup message | ||
1543 | */ | ||
1544 | printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, ", | ||
1545 | dev->name, dev->base_addr, dev->irq, dev->dma); | ||
1546 | printk("addr %02x:%02x:%02x:%02x:%02x:%02x, ", | ||
1547 | dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], | ||
1548 | dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); | ||
1549 | |||
1550 | /* | ||
1551 | * read more information from the adapter | ||
1552 | */ | ||
1553 | |||
1554 | adapter->tx_pcb.command = CMD_ADAPTER_INFO; | ||
1555 | adapter->tx_pcb.length = 0; | ||
1556 | if (!send_pcb(dev, &adapter->tx_pcb) || | ||
1557 | !receive_pcb(dev, &adapter->rx_pcb) || | ||
1558 | (adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) || | ||
1559 | (adapter->rx_pcb.length != 10)) { | ||
1560 | printk("not responding to second PCB\n"); | ||
1561 | } | ||
1562 | printk("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz); | ||
1563 | |||
1564 | /* | ||
1565 | * reconfigure the adapter memory to better suit our purposes | ||
1566 | */ | ||
1567 | adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; | ||
1568 | adapter->tx_pcb.length = 12; | ||
1569 | adapter->tx_pcb.data.memconf.cmd_q = 8; | ||
1570 | adapter->tx_pcb.data.memconf.rcv_q = 8; | ||
1571 | adapter->tx_pcb.data.memconf.mcast = 10; | ||
1572 | adapter->tx_pcb.data.memconf.frame = 10; | ||
1573 | adapter->tx_pcb.data.memconf.rcv_b = 10; | ||
1574 | adapter->tx_pcb.data.memconf.progs = 0; | ||
1575 | if (!send_pcb(dev, &adapter->tx_pcb) || | ||
1576 | !receive_pcb(dev, &adapter->rx_pcb) || | ||
1577 | (adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) || | ||
1578 | (adapter->rx_pcb.length != 2)) { | ||
1579 | printk(KERN_ERR "%s: could not configure adapter memory\n", dev->name); | ||
1580 | } | ||
1581 | if (adapter->rx_pcb.data.configure) { | ||
1582 | printk(KERN_ERR "%s: adapter configuration failed\n", dev->name); | ||
1583 | } | ||
1584 | |||
1585 | dev->open = elp_open; /* local */ | ||
1586 | dev->stop = elp_close; /* local */ | ||
1587 | dev->get_stats = elp_get_stats; /* local */ | ||
1588 | dev->hard_start_xmit = elp_start_xmit; /* local */ | ||
1589 | dev->tx_timeout = elp_timeout; /* local */ | ||
1590 | dev->watchdog_timeo = 10*HZ; | ||
1591 | dev->set_multicast_list = elp_set_mc_list; /* local */ | ||
1592 | dev->ethtool_ops = &netdev_ethtool_ops; /* local */ | ||
1593 | |||
1594 | memset(&(adapter->stats), 0, sizeof(struct net_device_stats)); | ||
1595 | dev->mem_start = dev->mem_end = 0; | ||
1596 | |||
1597 | err = register_netdev(dev); | ||
1598 | if (err) | ||
1599 | goto out; | ||
1600 | |||
1601 | return 0; | ||
1602 | out: | ||
1603 | release_region(dev->base_addr, ELP_IO_EXTENT); | ||
1604 | return err; | ||
1605 | } | ||
1606 | |||
1607 | #ifndef MODULE | ||
1608 | struct net_device * __init elplus_probe(int unit) | ||
1609 | { | ||
1610 | struct net_device *dev = alloc_etherdev(sizeof(elp_device)); | ||
1611 | int err; | ||
1612 | if (!dev) | ||
1613 | return ERR_PTR(-ENOMEM); | ||
1614 | |||
1615 | sprintf(dev->name, "eth%d", unit); | ||
1616 | netdev_boot_setup_check(dev); | ||
1617 | |||
1618 | err = elplus_setup(dev); | ||
1619 | if (err) { | ||
1620 | free_netdev(dev); | ||
1621 | return ERR_PTR(err); | ||
1622 | } | ||
1623 | return dev; | ||
1624 | } | ||
1625 | |||
1626 | #else | ||
1627 | static struct net_device *dev_3c505[ELP_MAX_CARDS]; | ||
1628 | static int io[ELP_MAX_CARDS]; | ||
1629 | static int irq[ELP_MAX_CARDS]; | ||
1630 | static int dma[ELP_MAX_CARDS]; | ||
1631 | module_param_array(io, int, NULL, 0); | ||
1632 | module_param_array(irq, int, NULL, 0); | ||
1633 | module_param_array(dma, int, NULL, 0); | ||
1634 | MODULE_PARM_DESC(io, "EtherLink Plus I/O base address(es)"); | ||
1635 | MODULE_PARM_DESC(irq, "EtherLink Plus IRQ number(s) (assigned)"); | ||
1636 | MODULE_PARM_DESC(dma, "EtherLink Plus DMA channel(s)"); | ||
1637 | |||
1638 | int init_module(void) | ||
1639 | { | ||
1640 | int this_dev, found = 0; | ||
1641 | |||
1642 | for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) { | ||
1643 | struct net_device *dev = alloc_etherdev(sizeof(elp_device)); | ||
1644 | if (!dev) | ||
1645 | break; | ||
1646 | |||
1647 | dev->irq = irq[this_dev]; | ||
1648 | dev->base_addr = io[this_dev]; | ||
1649 | if (dma[this_dev]) { | ||
1650 | dev->dma = dma[this_dev]; | ||
1651 | } else { | ||
1652 | dev->dma = ELP_DMA; | ||
1653 | printk(KERN_WARNING "3c505.c: warning, using default DMA channel,\n"); | ||
1654 | } | ||
1655 | if (io[this_dev] == 0) { | ||
1656 | if (this_dev) { | ||
1657 | free_netdev(dev); | ||
1658 | break; | ||
1659 | } | ||
1660 | printk(KERN_NOTICE "3c505.c: module autoprobe not recommended, give io=xx.\n"); | ||
1661 | } | ||
1662 | if (elplus_setup(dev) != 0) { | ||
1663 | printk(KERN_WARNING "3c505.c: Failed to register card at 0x%x.\n", io[this_dev]); | ||
1664 | free_netdev(dev); | ||
1665 | break; | ||
1666 | } | ||
1667 | dev_3c505[this_dev] = dev; | ||
1668 | found++; | ||
1669 | } | ||
1670 | if (!found) | ||
1671 | return -ENODEV; | ||
1672 | return 0; | ||
1673 | } | ||
1674 | |||
1675 | void cleanup_module(void) | ||
1676 | { | ||
1677 | int this_dev; | ||
1678 | |||
1679 | for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) { | ||
1680 | struct net_device *dev = dev_3c505[this_dev]; | ||
1681 | if (dev) { | ||
1682 | unregister_netdev(dev); | ||
1683 | release_region(dev->base_addr, ELP_IO_EXTENT); | ||
1684 | free_netdev(dev); | ||
1685 | } | ||
1686 | } | ||
1687 | } | ||
1688 | |||
1689 | #endif /* MODULE */ | ||
1690 | MODULE_LICENSE("GPL"); | ||